#include "mainwindow.h"
#include "documentchecker.h"
#include "documentvalidator.h"
-#include "kdenlive-config.h"
+#include "config-kdenlive.h"
#include "initeffects.h"
#include <KDebug>
#include <KFileDialog>
#include <KIO/NetAccess>
#include <KIO/CopyJob>
+#include <KIO/JobUiDelegate>
#include <KApplication>
#include <KGlobal>
#include <KBookmarkManager>
#include <mlt++/Mlt.h>
-const double DOCUMENTVERSION = 0.86;
+#include "locale.h"
-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) :
+
+const double DOCUMENTVERSION = 0.88;
+
+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),
m_modified(false),
m_projectFolder(projectFolder)
{
+ // init m_profile struct
+ m_profile.frame_rate_num = 0;
+ m_profile.frame_rate_den = 0;
+ m_profile.width = 0;
+ m_profile.height = 0;
+ m_profile.progressive = 0;
+ m_profile.sample_aspect_num = 0;
+ m_profile.sample_aspect_den = 0;
+ m_profile.display_aspect_num = 0;
+ m_profile.display_aspect_den = 0;
+ m_profile.colorspace = 0;
+
m_clipManager = new ClipManager(this);
m_autoSaveTimer = new QTimer(this);
m_autoSaveTimer->setSingleShot(true);
+ connect(m_clipManager, SIGNAL(displayMessage(QString, int)), parent, SLOT(slotGotProgressInfo(QString,int)));
bool success = false;
// init default document properties
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, "");
+ QLocale systemLocale = QLocale::system();
+ systemLocale.setNumberOptions(QLocale::OmitGroupSeparator);
+ QLocale::setDefault(systemLocale);
+ // locale conversion might need to be redone
+ initEffects::parseEffectFiles();
+ }
*openBackup = false;
else {
QFile file(tmpFile);
QString errorMsg;
- QDomImplementation impl;
- impl.setInvalidDataPolicy(QDomImplementation::DropInvalidChars);
+ QDomImplementation::setInvalidDataPolicy(QDomImplementation::DropInvalidChars);
success = m_document.setContent(&file, false, &errorMsg);
file.close();
KIO::NetAccess::removeTempFile(tmpFile);
else {
parent->slotGotProgressInfo(i18n("Validating"), 0);
qApp->processEvents();
- DocumentValidator validator(m_document);
+ DocumentValidator validator(m_document, url);
success = validator.isProject();
if (!success) {
// It is not a project file
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();
// Make sure that the necessary folders exist
KStandardDirs::makeDir(m_projectFolder.path(KUrl::AddTrailingSlash) + "titles/");
KStandardDirs::makeDir(m_projectFolder.path(KUrl::AddTrailingSlash) + "thumbs/");
- KStandardDirs::makeDir(m_projectFolder.path(KUrl::AddTrailingSlash) + "ladspa/");
KStandardDirs::makeDir(m_projectFolder.path(KUrl::AddTrailingSlash) + "proxy/");
updateProjectFolderPlacesEntry();
// Creating new document
QDomDocument doc;
QDomElement mlt = doc.createElement("mlt");
+ mlt.setAttribute("LC_NUMERIC", "");
doc.appendChild(mlt);
// Create black producer
property = doc.createElement("property");
property.setAttribute("name", "aspect_ratio");
- value = doc.createTextNode(QString::number(0.0));
+ value = doc.createTextNode(QString::number(0));
property.appendChild(value);
blk.appendChild(property);
return QPoint(m_documentProperties.value("zonein").toInt(), m_documentProperties.value("zoneout").toInt());
}
-QDomDocument KdenliveDoc::xmlSceneList(const QString &scene, const QStringList expandedFolders)
+QDomDocument KdenliveDoc::xmlSceneList(const QString &scene, const QStringList &expandedFolders)
{
QDomDocument sceneList;
sceneList.setContent(scene, true);
return sceneList;
}
+ // Set playlist audio volume to 100%
+ QDomElement tractor = mlt.firstChildElement("tractor");
+ if (!tractor.isNull()) {
+ QDomNodeList props = tractor.elementsByTagName("property");
+ for (int i = 0; i < props.count(); i++) {
+ if (props.at(i).toElement().attribute("name") == "meta.volume") {
+ props.at(i).firstChild().setNodeValue("1");
+ break;
+ }
+ }
+ }
+
QDomElement addedXml = sceneList.createElement("kdenlivedoc");
mlt.appendChild(addedXml);
}
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());
QDomElement e;
QList <DocClipBase*> list = m_clipManager->documentClipList();
for (int i = 0; i < list.count(); i++) {
- e = list.at(i)->toXML();
+ e = list.at(i)->toXML(true);
e.setTagName("kdenlive_producer");
addedXml.appendChild(sceneList.importNode(e, true));
QList < CommentedTime > marks = list.at(i)->commentedSnapMarkers();
return sceneList;
}
-bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene, const QStringList expandedFolders, bool autosave)
+bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene, const QStringList &expandedFolders, bool autosave)
{
QDomDocument sceneList = xmlSceneList(scene, expandedFolders);
if (sceneList.isNull()) {
void KdenliveDoc::moveProjectData(KUrl url)
{
QList <DocClipBase*> list = m_clipManager->documentClipList();
- //TODO: Also move ladspa effects files
+ KUrl::List cacheUrls;
for (int i = 0; i < list.count(); i++) {
DocClipBase *clip = list.at(i);
if (clip->clipType() == TEXT) {
KUrl oldVideoThumbUrl = KUrl(m_projectFolder.path(KUrl::AddTrailingSlash) + "thumbs/" + hash + ".png");
KUrl oldAudioThumbUrl = KUrl(m_projectFolder.path(KUrl::AddTrailingSlash) + "thumbs/" + hash + ".thumb");
if (KIO::NetAccess::exists(oldVideoThumbUrl, KIO::NetAccess::SourceSide, 0)) {
- KUrl newUrl = KUrl(url.path(KUrl::AddTrailingSlash) + "thumbs/" + hash + ".png");
- KIO::Job *job = KIO::copy(oldVideoThumbUrl, newUrl);
- KIO::NetAccess::synchronousRun(job, 0);
+ cacheUrls << oldVideoThumbUrl;
}
if (KIO::NetAccess::exists(oldAudioThumbUrl, KIO::NetAccess::SourceSide, 0)) {
- KUrl newUrl = KUrl(url.path(KUrl::AddTrailingSlash) + "thumbs/" + hash + ".thumb");
- KIO::Job *job = KIO::copy(oldAudioThumbUrl, newUrl);
- if (KIO::NetAccess::synchronousRun(job, 0)) clip->refreshThumbUrl();
+ cacheUrls << oldAudioThumbUrl;
}
}
+ if (!cacheUrls.isEmpty()) {
+ KIO::Job *job = KIO::copy(cacheUrls, KUrl(url.path(KUrl::AddTrailingSlash) + "thumbs/"));
+ job->ui()->setWindow(kapp->activeWindow());
+ KIO::NetAccess::synchronousRun(job, 0);
+ }
}
const QString &KdenliveDoc::profilePath() const
return m_render;
}
-void KdenliveDoc::updateClip(const QString id)
+void KdenliveDoc::updateClip(const QString &id)
{
emit updateClipDisplay(id);
}
extension = KUrl(path).fileName();
path = KUrl(path).directory();
}
-
- if (path.isEmpty() == false && QFile::exists(path) == false && elem.attribute("type").toInt() != TEXT && !elem.hasAttribute("placeholder")) {
+ if (elem.hasAttribute("_missingsource")) {
+ // Clip has proxy but missing original source
+ }
+ else if (path.isEmpty() == false && QFile::exists(path) == false && elem.attribute("type").toInt() != TEXT && !elem.hasAttribute("placeholder")) {
kDebug() << "// FOUND MISSING CLIP: " << path << ", TYPE: " << elem.attribute("type").toInt();
const QString size = elem.attribute("file_size");
const QString hash = elem.attribute("file_hash");
emit signalDeleteProjectClip(clipId);
}
-void KdenliveDoc::slotAddClipList(const KUrl::List urls, const QString group, const QString &groupId)
+void KdenliveDoc::slotAddClipList(const KUrl::List urls, const QString &group, const QString &groupId)
{
m_clipManager->slotAddClipList(urls, group, groupId);
//emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
}
-void KdenliveDoc::slotAddClipFile(const KUrl url, const QString group, const QString &groupId)
+void KdenliveDoc::slotAddClipFile(const KUrl &url, const QString &group, const QString &groupId, const QString &comment)
{
- m_clipManager->slotAddClipFile(url, group, groupId);
+ m_clipManager->slotAddClipFile(url, group, groupId, comment);
emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
setModified(true);
}
emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
}
-void KdenliveDoc::slotCreateSlideshowClipFile(const QString name, const QString path, int count, const QString duration,
- const bool loop, const bool crop, const bool fade,
- const QString &luma_duration, const QString &luma_file, const int softness,
- const QString &animation, QString group, const QString &groupId)
+void KdenliveDoc::slotCreateSlideshowClipFile(QMap <QString, QString> properties, QString group, const QString &groupId)
{
- m_clipManager->slotAddSlideshowClipFile(name, path, count, duration, loop,
- crop, fade, luma_duration,
- luma_file, softness,
- animation, group, groupId);
+ m_clipManager->slotAddSlideshowClipFile(properties, group, groupId);
setModified(true);
emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
}
return QPoint(video, audio);
}
-void KdenliveDoc::cachePixmap(const QString &fileId, const QPixmap &pix) const
+void KdenliveDoc::cacheImage(const QString &fileId, const QImage &img) const
{
- pix.save(m_projectFolder.path(KUrl::AddTrailingSlash) + "thumbs/" + fileId + ".png");
-}
-
-QString KdenliveDoc::getLadspaFile() const
-{
- int ct = 0;
- QString counter = QString::number(ct).rightJustified(5, '0', false);
- while (QFile::exists(m_projectFolder.path(KUrl::AddTrailingSlash) + "ladspa/" + counter + ".ladspa")) {
- ct++;
- counter = QString::number(ct).rightJustified(5, '0', false);
- }
- return m_projectFolder.path(KUrl::AddTrailingSlash) + "ladspa/" + counter + ".ladspa";
+ img.save(m_projectFolder.path(KUrl::AddTrailingSlash) + "thumbs/" + fileId + ".png");
}
bool KdenliveDoc::checkDocumentClips(QDomNodeList infoproducers)
QDomElement e = params.item(i).toElement();
// Check if this effect has a variable parameter
- if (e.attribute("default").startsWith('%')) {
+ if (e.attribute("default").contains('%')) {
double evaluatedValue = ProfilesDialog::getStringEval(m_profile, e.attribute("default"));
e.setAttribute("default", evaluatedValue);
if (e.hasAttribute("value") && e.attribute("value").startsWith('%')) {
const QString file = KStandardDirs::locateLocal("data", "kfileplaces/bookmarks.xml");
KBookmarkManager *bookmarkManager = KBookmarkManager::managerForFile(file, "kfilePlaces");
+ if (!bookmarkManager) return;
KBookmarkGroup root = bookmarkManager->root();
+
KBookmark bookmark = root.first();
QString kdenliveName = KGlobal::mainComponent().componentName();
}
}
+const QMap <QString, QString> KdenliveDoc::metadata() const
+{
+ return m_documentMetadata;
+}
+
+void KdenliveDoc::setMetadata(const QMap <QString, QString> meta)
+{
+ m_documentMetadata = meta;
+}
+
#include "kdenlivedoc.moc"