From 099cce018342e4c3d8888142f8e1521de057970e Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Tue, 3 Jan 2012 18:38:28 +0100 Subject: [PATCH] Initial support for project metadata (that can be embedded in rendered files) --- src/kdenlivedoc.cpp | 31 +++++++- src/kdenlivedoc.h | 7 +- src/mainwindow.cpp | 13 ++-- src/projectsettings.cpp | 38 ++++++++- src/projectsettings.h | 3 +- src/renderwidget.cpp | 11 ++- src/renderwidget.h | 2 +- src/utils/resourcewidget.cpp | 17 ----- src/widgets/projectsettings_ui.ui | 123 ++++++++++++++++++------------ src/widgets/renderwidget_ui.ui | 11 ++- 10 files changed, 178 insertions(+), 78 deletions(-) diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index fe263601..fa243560 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -58,7 +58,7 @@ const double DOCUMENTVERSION = 0.88; -KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, QString profileName, QMap properties, const QPoint &tracks, Render *render, KTextEdit *notes, bool *openBackup, MainWindow *parent, KProgressDialog *progressDialog) : +KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, QString profileName, QMap properties, QMap metadata, const QPoint &tracks, Render *render, KTextEdit *notes, bool *openBackup, MainWindow *parent, KProgressDialog *progressDialog) : QObject(parent), m_autosave(NULL), m_url(url), @@ -111,6 +111,13 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup i.next(); m_documentProperties[i.key()] = i.value(); } + + // Load metadata + QMapIterator j(metadata); + while (j.hasNext()) { + j.next(); + m_documentMetadata[j.key()] = j.value(); + } if (QLocale().decimalPoint() != QLocale::system().decimalPoint()) { setlocale(LC_NUMERIC, ""); @@ -286,6 +293,10 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup QDomNamedNodeMap props = docproperties.attributes(); for (int i = 0; i < props.count(); i++) m_documentProperties.insert(props.item(i).nodeName(), props.item(i).nodeValue()); + docproperties = infoXml.firstChildElement("documentmetadata"); + props = docproperties.attributes(); + for (int i = 0; i < props.count(); i++) + m_documentMetadata.insert(props.item(i).nodeName(), props.item(i).nodeValue()); if (validator.isModified()) setModified(true); kDebug() << "Reading file: " << url.path() << ", found clips: " << producers.count(); @@ -644,6 +655,14 @@ QDomDocument KdenliveDoc::xmlSceneList(const QString &scene, const QStringList & } docproperties.setAttribute("position", m_render->seekPosition().frames(m_fps)); addedXml.appendChild(docproperties); + + QDomElement docmetadata = sceneList.createElement("documentmetadata"); + QMapIterator j(m_documentMetadata); + while (j.hasNext()) { + j.next(); + docmetadata.setAttribute(j.key(), j.value()); + } + addedXml.appendChild(docmetadata); QDomElement docnotes = sceneList.createElement("documentnotes"); QDomText value = sceneList.createTextNode(m_notesWidget->toHtml()); @@ -1762,5 +1781,15 @@ void KdenliveDoc::cleanupBackupFiles() } } +const QMap KdenliveDoc::metadata() const +{ + return m_documentMetadata; +} + +void KdenliveDoc::setMetadata(const QMap meta) +{ + m_documentMetadata = meta; +} + #include "kdenlivedoc.moc" diff --git a/src/kdenlivedoc.h b/src/kdenlivedoc.h index f88939bf..006b6007 100644 --- a/src/kdenlivedoc.h +++ b/src/kdenlivedoc.h @@ -52,7 +52,7 @@ class KdenliveDoc: public QObject { Q_OBJECT public: - KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, QString profileName, QMap properties, const QPoint &tracks, Render *render, KTextEdit *notes, bool *openBackup, MainWindow *parent = 0, KProgressDialog *progressDialog = 0); + KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, QString profileName, QMap properties, QMap metadata, const QPoint &tracks, Render *render, KTextEdit *notes, bool *openBackup, MainWindow *parent = 0, KProgressDialog *progressDialog = 0); ~KdenliveDoc(); QDomNodeList producersList(); double fps() const; @@ -161,6 +161,10 @@ Q_OBJECT public: static double getDisplayRatio(const QString &path); /** @brief Backup the project file */ void backupLastSavedVersion(const QString &path); + /** @brief Returns the document metadata (author, copyright, ...) */ + const QMap metadata() const; + /** @brief Set the document metadata (author, copyright, ...) */ + void setMetadata(const QMap meta); private: KUrl m_url; @@ -183,6 +187,7 @@ private: /** @brief The project folder, used to store project files (titles, effects...). */ KUrl m_projectFolder; QMap m_documentProperties; + QMap m_documentMetadata; QList m_tracksList; void setNewClipResource(const QString &id, const QString &path); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3f24cada..76e8ba25 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1847,13 +1847,14 @@ void MainWindow::newFile(bool showProjectSettings, bool force) QString profileName = KdenliveSettings::default_profile(); KUrl projectFolder = KdenliveSettings::defaultprojectfolder(); QMap documentProperties; + QMap documentMetadata; QPoint projectTracks(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()); if (!showProjectSettings) { if (!KdenliveSettings::activatetabs()) if (!closeCurrentDocument()) return; } else { - ProjectSettings *w = new ProjectSettings(NULL, QStringList(), projectTracks.x(), projectTracks.y(), KdenliveSettings::defaultprojectfolder(), false, true, this); + ProjectSettings *w = new ProjectSettings(NULL, QMap (), QStringList(), projectTracks.x(), projectTracks.y(), KdenliveSettings::defaultprojectfolder(), false, true, this); if (w->exec() != QDialog::Accepted) return; if (!KdenliveSettings::activatetabs()) @@ -1873,12 +1874,13 @@ void MainWindow::newFile(bool showProjectSettings, bool force) documentProperties.insert("proxyextension", w->proxyExtension()); documentProperties.insert("generateimageproxy", QString::number((int) w->generateImageProxy())); documentProperties.insert("proxyimageminsize", QString::number(w->proxyImageMinSize())); + documentMetadata = w->metadata(); delete w; } m_timelineArea->setEnabled(true); m_projectList->setEnabled(true); bool openBackup; - KdenliveDoc *doc = new KdenliveDoc(KUrl(), projectFolder, m_commandStack, profileName, documentProperties, projectTracks, m_projectMonitor->render, m_notesWidget, &openBackup, this); + KdenliveDoc *doc = new KdenliveDoc(KUrl(), projectFolder, m_commandStack, profileName, documentProperties, documentMetadata, projectTracks, m_projectMonitor->render, m_notesWidget, &openBackup, this); doc->m_autosave = new KAutoSaveFile(KUrl(), doc); bool ok; TrackView *trackView = new TrackView(doc, &ok, this); @@ -2111,7 +2113,7 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale) qApp->processEvents(); bool openBackup; - KdenliveDoc *doc = new KdenliveDoc(url, KdenliveSettings::defaultprojectfolder(), m_commandStack, KdenliveSettings::default_profile(), QMap (), QPoint(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()), m_projectMonitor->render, m_notesWidget, &openBackup, this, &progressDialog); + KdenliveDoc *doc = new KdenliveDoc(url, KdenliveSettings::defaultprojectfolder(), m_commandStack, KdenliveSettings::default_profile(), QMap (), QMap (), QPoint(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()), m_projectMonitor->render, m_notesWidget, &openBackup, this, &progressDialog); progressDialog.progressBar()->setValue(1); progressDialog.progressBar()->setMaximum(4); @@ -2279,7 +2281,7 @@ void MainWindow::slotDetectAudioDriver() void MainWindow::slotEditProjectSettings() { QPoint p = m_activeDocument->getTracksCount(); - ProjectSettings *w = new ProjectSettings(m_projectList, m_activeTimeline->projectView()->extractTransitionsLumas(), p.x(), p.y(), m_activeDocument->projectFolder().path(), true, !m_activeDocument->isModified(), this); + ProjectSettings *w = new ProjectSettings(m_projectList, m_activeDocument->metadata(), m_activeTimeline->projectView()->extractTransitionsLumas(), p.x(), p.y(), m_activeDocument->projectFolder().path(), true, !m_activeDocument->isModified(), this); connect(w, SIGNAL(disableProxies()), this, SLOT(slotDisableProxies())); if (w->exec() == QDialog::Accepted) { @@ -2325,6 +2327,7 @@ void MainWindow::slotEditProjectSettings() m_activeDocument->setModified(); slotUpdateProxySettings(); } + m_activeDocument->setMetadata(w->metadata()); } delete w; } @@ -4079,7 +4082,7 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS return; } file.close(); - m_renderWidget->slotExport(scriptExport, m_activeTimeline->inPoint(), m_activeTimeline->outPoint(), playlistPath, scriptPath, exportAudio); + m_renderWidget->slotExport(scriptExport, m_activeTimeline->inPoint(), m_activeTimeline->outPoint(), m_activeDocument->metadata(), playlistPath, scriptPath, exportAudio); } void MainWindow::slotUpdateTimecodeFormat(int ix) diff --git a/src/projectsettings.cpp b/src/projectsettings.cpp index 0504ba82..2e33ae3f 100644 --- a/src/projectsettings.cpp +++ b/src/projectsettings.cpp @@ -35,7 +35,7 @@ #include #include -ProjectSettings::ProjectSettings(ProjectList *projectlist, QStringList lumas, int videotracks, int audiotracks, const QString projectPath, bool readOnlyTracks, bool savedProject, QWidget * parent) : +ProjectSettings::ProjectSettings(ProjectList *projectlist, QMap metadata, QStringList lumas, int videotracks, int audiotracks, const QString projectPath, bool readOnlyTracks, bool savedProject, QWidget * parent) : QDialog(parent), m_savedProject(savedProject), m_projectList(projectlist), m_lumas(lumas) { setupUi(this); @@ -130,6 +130,26 @@ ProjectSettings::ProjectSettings(ProjectList *projectlist, QStringList lumas, in video_tracks->setEnabled(false); audio_tracks->setEnabled(false); } + + + // Metadata list + QTreeWidgetItem *item = new QTreeWidgetItem(metadata_list, QStringList() << i18n("Title")); + item->setData(0, Qt::UserRole, QString("meta.attr.title.markup")); + if (metadata.contains("meta.attr.title.markup")) item->setText(1, metadata.value("meta.attr.title.markup")); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item = new QTreeWidgetItem(metadata_list, QStringList() << i18n("Author")); + item->setData(0, Qt::UserRole, QString("meta.attr.author.markup")); + if (metadata.contains("meta.attr.author.markup")) item->setText(1, metadata.value("meta.attr.author.markup")); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item = new QTreeWidgetItem(metadata_list, QStringList() << i18n("Copyright")); + item->setData(0, Qt::UserRole, QString("meta.attr.copyright.markup")); + if (metadata.contains("meta.attr.copyright.markup")) item->setText(1, metadata.value("meta.attr.copyright.markup")); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item = new QTreeWidgetItem(metadata_list, QStringList() << i18n("Year")); + item->setData(0, Qt::UserRole, QString("meta.attr.year.markup")); + if (metadata.contains("meta.attr.year.markup")) item->setText(1, metadata.value("meta.attr.year.markup")); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + slotUpdateDisplay(); if (m_projectList != NULL) { slotUpdateFiles(); @@ -536,6 +556,22 @@ void ProjectSettings::slotUpdateProxyParams() proxyparams->setPlainText(params.section(';', 0, 0)); } +const QMap ProjectSettings::metadata() const +{ + QMap metadata; + for (int i = 0; i < metadata_list->topLevelItemCount(); i++) + { + QTreeWidgetItem *item = metadata_list->topLevelItem(i); + if (!item->text(1).simplified().isEmpty()) { + // Insert metadata entry + QString key = item->data(0, Qt::UserRole).toString(); + QString value = item->text(1); + metadata.insert(key, value); + } + } + return metadata; +} + #include "projectsettings.moc" diff --git a/src/projectsettings.h b/src/projectsettings.h index 5a0a93b1..04f5881b 100644 --- a/src/projectsettings.h +++ b/src/projectsettings.h @@ -32,7 +32,7 @@ class ProjectSettings : public QDialog, public Ui::ProjectSettings_UI Q_OBJECT public: - ProjectSettings(ProjectList *projectlist, QStringList lumas, int videotracks, int audiotracks, const QString projectPath, bool readOnlyTracks, bool unsavedProject, QWidget * parent = 0); + ProjectSettings(ProjectList *projectlist, QMap metadata, QStringList lumas, int videotracks, int audiotracks, const QString projectPath, bool readOnlyTracks, bool unsavedProject, QWidget * parent = 0); QString selectedProfile() const; KUrl selectedFolder() const; QPoint tracks(); @@ -45,6 +45,7 @@ public: int proxyImageMinSize() const; QString proxyParams() const; QString proxyExtension() const; + const QMap metadata() const; static QStringList extractPlaylistUrls(QString path); static QStringList extractSlideshowUrls(KUrl url); diff --git a/src/renderwidget.cpp b/src/renderwidget.cpp index ebb4ab3f..c54be5f8 100644 --- a/src/renderwidget.cpp +++ b/src/renderwidget.cpp @@ -824,7 +824,7 @@ void RenderWidget::slotPrepareExport(bool scriptExport) } -void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut, const QString &playlistPath, const QString &scriptPath, bool exportAudio) +void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut, const QMap metadata, const QString &playlistPath, const QString &scriptPath, bool exportAudio) { QListWidgetItem *item = m_view.size_list->currentItem(); if (!item) return; @@ -890,6 +890,15 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut, const else render_process_args << "-"; QString renderArgs = m_view.advanced_params->toPlainText().simplified(); + + // Project metadata + if (m_view.export_meta->isChecked()) { + QMap::const_iterator i = metadata.constBegin(); + while (i != metadata.constEnd()) { + renderArgs.append(QString(" %1=\"%2\"").arg(i.key()).arg(i.value())); + ++i; + } + } // Adjust frame scale int width; diff --git a/src/renderwidget.h b/src/renderwidget.h index 4c4f0a4b..dcaa4612 100644 --- a/src/renderwidget.h +++ b/src/renderwidget.h @@ -140,7 +140,7 @@ protected: virtual QSize sizeHint() const; public slots: - void slotExport(bool scriptExport, int zoneIn, int zoneOut, const QString &playlistPath, const QString &scriptPath, bool exportAudio); + void slotExport(bool scriptExport, int zoneIn, int zoneOut, const QMap metadata, const QString &playlistPath, const QString &scriptPath, bool exportAudio); private slots: void slotUpdateButtons(KUrl url); diff --git a/src/utils/resourcewidget.cpp b/src/utils/resourcewidget.cpp index 60d6fc2c..4db1a3c5 100644 --- a/src/utils/resourcewidget.cpp +++ b/src/utils/resourcewidget.cpp @@ -99,24 +99,10 @@ ResourceWidget::~ResourceWidget() void ResourceWidget::slotStartSearch(int page) { - /*m_currentPreview.clear(); - m_currentUrl.clear();*/ page_number->blockSignals(true); page_number->setValue(page); page_number->blockSignals(false); m_currentService->slotStartSearch(search_text->text(), page); - /*QString uri; - if (m_service == FREESOUND) { - uri = "http://www.freesound.org/api/sounds/search/?q="; - uri.append(search_text->text()); - if (page > 1) uri.append("&p=" + QString::number(page)); - uri.append("&api_key=a1772c8236e945a4bee30a64058dabf8"); - } - else if (m_service == OPENCLIPART) { - uri = "http://openclipart.org/api/search/?query="; - uri.append(search_text->text()); - if (page > 1) uri.append("&page=" + QString::number(page)); - }*/ } void ResourceWidget::slotUpdateCurrentSound() @@ -131,9 +117,6 @@ void ResourceWidget::slotUpdateCurrentSound() return; } m_currentInfo = m_currentService->displayItemDetails(item); - /*m_currentPreview = item->data(previewRole).toString(); - m_currentUrl = item->data(downloadRole).toString(); - m_currentId = item->data(idRole).toInt();*/ if (sound_autoplay->isChecked()) m_currentService->startItemPreview(item); sound_box->setEnabled(true); diff --git a/src/widgets/projectsettings_ui.ui b/src/widgets/projectsettings_ui.ui index 2b4bbf3c..c55ebb35 100644 --- a/src/widgets/projectsettings_ui.ui +++ b/src/widgets/projectsettings_ui.ui @@ -6,24 +6,38 @@ 0 0 - 337 - 523 + 345 + 524 Project Settings - - 0 - - - 0 - - - 0 - - + + + + Qt::Vertical + + + + 334 + 484 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + 0 @@ -35,7 +49,7 @@ Settings - + @@ -328,28 +342,41 @@ - - - - Qt::Horizontal + + + + + Metadata + + + + + + true - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + false - - - - - - Qt::Vertical + + true - - - 20 - 40 - + + 2 - + + false + + + + 1 + + + + + 2 + + + @@ -533,19 +560,14 @@ - KIntSpinBox - QSpinBox -
knuminput.h
-
- - KUrlRequester - QFrame -
kurlrequester.h
+ KComboBox + QComboBox +
kcombobox.h
- KTreeWidgetSearchLine - KLineEdit -
ktreewidgetsearchline.h
+ KLineEdit + QLineEdit +
klineedit.h
KPushButton @@ -553,14 +575,19 @@
kpushbutton.h
- KLineEdit - QLineEdit -
klineedit.h
+ KIntSpinBox + QSpinBox +
knuminput.h
- KComboBox - QComboBox -
kcombobox.h
+ KTreeWidgetSearchLine + KLineEdit +
ktreewidgetsearchline.h
+
+ + KUrlRequester + QFrame +
kurlrequester.h
diff --git a/src/widgets/renderwidget_ui.ui b/src/widgets/renderwidget_ui.ui index 605d2057..866db026 100644 --- a/src/widgets/renderwidget_ui.ui +++ b/src/widgets/renderwidget_ui.ui @@ -6,8 +6,8 @@ 0 0 - 456 - 677 + 406 + 668 @@ -297,6 +297,13 @@ + + + + Export metadata + + + -- 2.39.2