Initial support for project metadata (that can be embedded in rendered files)

parent 84cc45b7
......@@ -58,7 +58,7 @@
const double DOCUMENTVERSION = 0.88;
KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, QString profileName, QMap <QString, QString> 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 <QString, QString> properties, QMap <QString, QString> 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<QString, QString> 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<QString, QString> 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 <QString, QString> KdenliveDoc::metadata() const
{
return m_documentMetadata;
}
void KdenliveDoc::setMetadata(const QMap <QString, QString> meta)
{
m_documentMetadata = meta;
}
#include "kdenlivedoc.moc"
......@@ -52,7 +52,7 @@ class KdenliveDoc: public QObject
{
Q_OBJECT public:
KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, QString profileName, QMap <QString, QString> 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 <QString, QString> properties, QMap <QString, QString> 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 <QString, QString> metadata() const;
/** @brief Set the document metadata (author, copyright, ...) */
void setMetadata(const QMap <QString, QString> 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 <QString, QString> m_documentProperties;
QMap <QString, QString> m_documentMetadata;
QList <TrackInfo> m_tracksList;
void setNewClipResource(const QString &id, const QString &path);
......
......@@ -1847,13 +1847,14 @@ void MainWindow::newFile(bool showProjectSettings, bool force)
QString profileName = KdenliveSettings::default_profile();
KUrl projectFolder = KdenliveSettings::defaultprojectfolder();
QMap <QString, QString> documentProperties;
QMap <QString, QString> 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 <QString, QString> (), 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 <QString, QString> (), 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 <QString, QString> (), QMap <QString, QString> (), 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)
......
......@@ -35,7 +35,7 @@
#include <QDir>
#include <kmessagebox.h>
ProjectSettings::ProjectSettings(ProjectList *projectlist, QStringList lumas, int videotracks, int audiotracks, const QString projectPath, bool readOnlyTracks, bool savedProject, QWidget * parent) :
ProjectSettings::ProjectSettings(ProjectList *projectlist, QMap <QString, QString> 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 <QString, QString> ProjectSettings::metadata() const
{
QMap <QString, QString> 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"
......@@ -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 <QString, QString> 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 <QString, QString> metadata() const;
static QStringList extractPlaylistUrls(QString path);
static QStringList extractSlideshowUrls(KUrl url);
......
......@@ -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 <QString, QString> 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<QString, QString>::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;
......
......@@ -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 <QString, QString> metadata, const QString &playlistPath, const QString &scriptPath, bool exportAudio);
private slots:
void slotUpdateButtons(KUrl url);
......
......@@ -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);
......
......@@ -6,24 +6,38 @@
<rect>
<x>0</x>
<y>0</y>
<width>337</width>
<height>523</height>
<width>345</width>
<height>524</height>
</rect>
</property>
<property name="windowTitle">
<string>Project Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0" colspan="2">
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>334</width>
<height>484</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
......@@ -35,7 +49,7 @@
<attribute name="title">
<string>Settings</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
......@@ -328,28 +342,41 @@
</layout>
</widget>
</item>
<item row="6" column="0" colspan="4">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Metadata</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QTreeWidget" name="metadata_list">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
</widget>
</item>
<item row="5" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
<property name="columnCount">
<number>2</number>
</property>
</spacer>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>1</string>
</property>
</column>
<column>
<property name="text">
<string>2</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
......@@ -533,19 +560,14 @@
</widget>
<customwidgets>
<customwidget>
<class>KIntSpinBox</class>
<extends>QSpinBox</extends>
<header>knuminput.h</header>
</customwidget>
<customwidget>
<class>KUrlRequester</class>
<extends>QFrame</extends>
<header>kurlrequester.h</header>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
<customwidget>
<class>KTreeWidgetSearchLine</class>
<extends>KLineEdit</extends>
<header>ktreewidgetsearchline.h</header>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
<customwidget>
<class>KPushButton</class>
......@@ -553,14 +575,19 @@
<header>kpushbutton.h</header>
</customwidget>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
<class>KIntSpinBox</class>
<extends>QSpinBox</extends>
<header>knuminput.h</header>
</customwidget>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
<class>KTreeWidgetSearchLine</class>
<extends>KLineEdit</extends>
<header>ktreewidgetsearchline.h</header>
</customwidget>
<customwidget>
<class>KUrlRequester</class>
<extends>QFrame</extends>
<header>kurlrequester.h</header>
</customwidget>
</customwidgets>
<resources/>
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>456</width>
<height>677</height>
<width>406</width>
<height>668</height>
</rect>
</property>
<property name="windowTitle">
......@@ -297,6 +297,13 @@
</item>
<item row="13" column="0" colspan="5">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QCheckBox" name="export_meta">
<property name="text">
<string>Export metadata</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="tc_overlay">
<property name="sizePolicy">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment