X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fkdenlivedoc.cpp;h=cc327d44b1db1f43a084119b42043bfda0320c56;hb=81f2be58c126f412014dd13cdc52459a3e345211;hp=26dc37ad594881ae7e9343b1f77c78c8dfd18c5d;hpb=ce2a5cc26ac1f035b2f4687c16b329d80c8ea7bb;p=kdenlive diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index 26dc37ad..cc327d44 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -87,9 +87,9 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup bool success = false; // init default document properties - m_documentProperties["zoom"] = "7"; - m_documentProperties["verticalzoom"] = "1"; - m_documentProperties["zonein"] = "0"; + m_documentProperties["zoom"] = '7'; + m_documentProperties["verticalzoom"] = '1'; + m_documentProperties["zonein"] = '0'; m_documentProperties["zoneout"] = "100"; m_documentProperties["enableproxy"] = QString::number((int) KdenliveSettings::enableproxy()); m_documentProperties["proxyparams"] = KdenliveSettings::proxyparams(); @@ -125,7 +125,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup systemLocale.setNumberOptions(QLocale::OmitGroupSeparator); QLocale::setDefault(systemLocale); // locale conversion might need to be redone - initEffects::parseEffectFiles(); + initEffects::parseEffectFiles(setlocale(LC_NUMERIC, NULL)); } *openBackup = false; @@ -143,19 +143,52 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup else { QFile file(tmpFile); QString errorMsg; + int line; + int col; QDomImplementation::setInvalidDataPolicy(QDomImplementation::DropInvalidChars); - success = m_document.setContent(&file, false, &errorMsg); - file.close(); - KIO::NetAccess::removeTempFile(tmpFile); + success = m_document.setContent(&file, false, &errorMsg, &line, &col); + file.close(); if (!success) { // It is corrupted - if (KMessageBox::warningContinueCancel(parent, i18n("Cannot open the project file, error is:\n%1\nDo you want to open a backup file?", errorMsg), i18n("Error opening file"), KGuiItem(i18n("Open Backup"))) == KMessageBox::Continue) { - *openBackup = true; - } - //KMessageBox::error(parent, errorMsg); + int answer = KMessageBox::warningYesNoCancel (parent, i18n("Cannot open the project file, error is:\n%1 (line %2, col %3)\nDo you want to open a backup file?", errorMsg, line, col), i18n("Error opening file"), KGuiItem(i18n("Open Backup")), KGuiItem(i18n("Recover"))); + if (answer == KMessageBox::Yes) { + *openBackup = true; + } + else if (answer == KMessageBox::No) { + // Try to recover broken file produced by Kdenlive 0.9.4 + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + int correction = 0; + QString playlist = file.readAll(); + while (!success && correction < 2) { + int errorPos = 0; + line--; + col = col - 2; + for (int j = 0; j < line && errorPos < playlist.length(); j++) { + errorPos = playlist.indexOf("\n", errorPos); + errorPos++; + } + errorPos += col; + if (errorPos >= playlist.length()) break; + playlist.remove(errorPos, 1); + line = 0; + col = 0; + success = m_document.setContent(playlist, false, &errorMsg, &line, &col); + correction++; + } + if (!success) { + KMessageBox::sorry(parent, i18n("Cannot recover this project file")); + } + else { + // Document was modified, ask for backup + QDomElement mlt = m_document.documentElement(); + QDomElement info = mlt.firstChildElement("kdenlivedoc"); + if (!info.isNull()) info.setAttribute("modified", 1); + } + } + } } - else { + if (success) { parent->slotGotProgressInfo(i18n("Validating"), 0); qApp->processEvents(); DocumentValidator validator(m_document, url); @@ -217,6 +250,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup projectTrack.isBlind = e.attribute("blind").toInt(); projectTrack.isLocked = e.attribute("locked").toInt(); projectTrack.trackName = e.attribute("trackname"); + projectTrack.effectsList = EffectsList(true); m_tracksList.append(projectTrack); } } @@ -281,8 +315,12 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup int maxchild = markerslist.count(); for (int k = 0; k < maxchild; k++) { e = markerslist.at(k).toElement(); - if (e.tagName() == "marker") - m_clipManager->getClipById(e.attribute("id"))->addSnapMarker(GenTime(e.attribute("time").toDouble()), e.attribute("comment")); + if (e.tagName() == "marker") { + CommentedTime marker(GenTime(e.attribute("time").toDouble()), e.attribute("comment"), e.attribute("type").toInt()); + DocClipBase *baseClip = m_clipManager->getClipById(e.attribute("id")); + if (baseClip) baseClip->addSnapMarker(marker); + else kDebug()<< " / / Warning, missing clip: "<< e.attribute("id"); + } } infoXml.removeChild(markers); } @@ -304,6 +342,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup } } } + KIO::NetAccess::removeTempFile(tmpFile); } } @@ -341,6 +380,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup //kDebug() << "// SETTING SCENE LIST:\n\n" << m_document.toString(); connect(m_autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave())); + connect(m_render, SIGNAL(addClip(const KUrl &, stringMap)), this, SLOT(slotAddClipFile(const KUrl &, stringMap))); } KdenliveDoc::~KdenliveDoc() @@ -385,6 +425,7 @@ QDomDocument KdenliveDoc::createEmptyDocument(int videotracks, int audiotracks) audioTrack.isLocked = false; audioTrack.trackName = QString("Audio ") + QString::number(audiotracks - i); audioTrack.duration = 0; + audioTrack.effectsList = EffectsList(true); m_tracksList.append(audioTrack); } @@ -396,6 +437,7 @@ QDomDocument KdenliveDoc::createEmptyDocument(int videotracks, int audiotracks) videoTrack.isLocked = false; videoTrack.trackName = QString("Video ") + QString::number(videotracks - i); videoTrack.duration = 0; + videoTrack.effectsList = EffectsList(true); m_tracksList.append(videoTrack); } return createEmptyDocument(m_tracksList); @@ -721,6 +763,7 @@ QDomDocument KdenliveDoc::xmlSceneList(const QString &scene, const QStringList & marker.setAttribute("time", marks.at(j).time().ms() / 1000); marker.setAttribute("comment", marks.at(j).comment()); marker.setAttribute("id", e.attribute("id")); + marker.setAttribute("type", marks.at(j).markerType()); markers.appendChild(marker); } } @@ -766,7 +809,7 @@ bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene, const cleanupBackupFiles(); QFileInfo info(file); QString fileName = KUrl(path).fileName().section('.', 0, -2); - fileName.append("-" + m_documentProperties.value("documentid")); + fileName.append('-' + m_documentProperties.value("documentid")); fileName.append(info.lastModified().toString("-yyyy-MM-dd-hh-mm")); fileName.append(".kdenlive.png"); KUrl backupFile = m_projectFolder; @@ -795,7 +838,7 @@ void KdenliveDoc::setProjectFolder(KUrl url) KStandardDirs::makeDir(url.path()); KStandardDirs::makeDir(url.path(KUrl::AddTrailingSlash) + "titles/"); KStandardDirs::makeDir(url.path(KUrl::AddTrailingSlash) + "thumbs/"); - if (KMessageBox::questionYesNo(kapp->activeWindow(), i18n("You have changed the project folder. Do you want to copy the cached data from %1 to the new folder %2?").arg(m_projectFolder.path(), url.path())) == KMessageBox::Yes) moveProjectData(url); + if (KMessageBox::questionYesNo(kapp->activeWindow(), i18n("You have changed the project folder. Do you want to copy the cached data from %1 to the new folder %2?", m_projectFolder.path(), url.path())) == KMessageBox::Yes) moveProjectData(url); m_projectFolder = url; updateProjectFolderPlacesEntry(); @@ -1183,9 +1226,9 @@ bool KdenliveDoc::addClipInfo(QDomElement elem, QDomElement orig, QString clipId QDomNamedNodeMap attributes = elem.attributes(); for (int i = 0; i < attributes.count(); i++) { QString attrname = attributes.item(i).nodeName(); - if (attrname != "resource") + if (attrname != "resource") properties.insert(attrname, attributes.item(i).nodeValue()); - kDebug() << attrname << " = " << attributes.item(i).nodeValue(); + //kDebug() << attrname << " = " << attributes.item(i).nodeValue(); } clip->setProperties(properties); emit addProjectClip(clip, false); @@ -1194,8 +1237,10 @@ bool KdenliveDoc::addClipInfo(QDomElement elem, QDomElement orig, QString clipId QMap meta; for (QDomNode m = orig.firstChild(); !m.isNull(); m = m.nextSibling()) { QString name = m.toElement().attribute("name"); - if (name.startsWith("meta.attr")) - meta.insert(name.section('.', 2, 3), m.firstChild().nodeValue()); + if (name.startsWith("meta.attr")) { + if (name.endsWith(".markup")) name = name.section('.', 0, -2); + meta.insert(name.section('.', 2, -1), m.firstChild().nodeValue()); + } } if (!meta.isEmpty()) { if (clip == NULL) @@ -1213,17 +1258,17 @@ void KdenliveDoc::deleteClip(const QString &clipId) emit signalDeleteProjectClip(clipId); } -void KdenliveDoc::slotAddClipList(const KUrl::List urls, const QString &group, const QString &groupId) +void KdenliveDoc::slotAddClipList(const KUrl::List urls, stringMap data) { - m_clipManager->slotAddClipList(urls, group, groupId); + m_clipManager->slotAddClipList(urls, data); //emit selectLastAddedClip(QString::number(m_clipManager->lastClipId())); setModified(true); } -void KdenliveDoc::slotAddClipFile(const KUrl &url, const QString &group, const QString &groupId, const QString &comment) +void KdenliveDoc::slotAddClipFile(const KUrl &url, stringMap data) { - m_clipManager->slotAddClipFile(url, group, groupId, comment); + m_clipManager->slotAddClipFile(url, data); emit selectLastAddedClip(QString::number(m_clipManager->lastClipId())); setModified(true); } @@ -1252,15 +1297,9 @@ void KdenliveDoc::slotCreateColorClip(const QString &name, const QString &color, 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 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())); } @@ -1269,9 +1308,9 @@ void KdenliveDoc::slotCreateTextClip(QString group, const QString &groupId, cons { QString titlesFolder = projectFolder().path(KUrl::AddTrailingSlash) + "titles/"; KStandardDirs::makeDir(titlesFolder); - TitleWidget *dia_ui = new TitleWidget(templatePath, m_timecode, titlesFolder, m_render, kapp->activeWindow()); + QPointer dia_ui = new TitleWidget(templatePath, m_timecode, titlesFolder, m_render, kapp->activeWindow()); if (dia_ui->exec() == QDialog::Accepted) { - m_clipManager->slotAddTextClipFile(i18n("Title clip"), dia_ui->outPoint(), dia_ui->xml().toString(), group, groupId); + m_clipManager->slotAddTextClipFile(i18n("Title clip"), dia_ui->duration(), dia_ui->xml().toString(), group, groupId); setModified(true); emit selectLastAddedClip(QString::number(m_clipManager->lastClipId())); } @@ -1508,15 +1547,13 @@ void KdenliveDoc::removeTrackEffect(int ix, QDomElement effect) kWarning() << "Remove Track effect outisde of range"; return; } - QString index; - QString toRemove = effect.attribute("kdenlive_ix"); + int index; + int toRemove = effect.attribute("kdenlive_ix").toInt(); for (int i = 0; i < m_tracksList.at(ix).effectsList.count(); ++i) { - index = m_tracksList.at(ix).effectsList.at(i).attribute("kdenlive_ix"); + index = m_tracksList.at(ix).effectsList.at(i).attribute("kdenlive_ix").toInt(); if (toRemove == index) { - m_tracksList[ix].effectsList.removeAt(i); - i--; - } else if (index.toInt() > toRemove.toInt()) { - m_tracksList[ix].effectsList.item(i).setAttribute("kdenlive_ix", index.toInt() - 1); + m_tracksList[ix].effectsList.removeAt(toRemove); + break; } } } @@ -1527,12 +1564,28 @@ void KdenliveDoc::setTrackEffect(int trackIndex, int effectIndex, QDomElement ef kWarning() << "Set Track effect outisde of range"; return; } - if (effectIndex < 0 || effectIndex > (m_tracksList.at(trackIndex).effectsList.count() - 1) || effect.isNull()) { + if (effectIndex <= 0 || effectIndex > (m_tracksList.at(trackIndex).effectsList.count()) || effect.isNull()) { kDebug() << "Invalid effect index: " << effectIndex; return; } - effect.setAttribute("kdenlive_ix", effectIndex + 1); - m_tracksList[trackIndex].effectsList.replace(effectIndex, effect); + m_tracksList[trackIndex].effectsList.removeAt(effect.attribute("kdenlive_ix").toInt()); + effect.setAttribute("kdenlive_ix", effectIndex); + m_tracksList[trackIndex].effectsList.insert(effect); + //m_tracksList[trackIndex].effectsList.updateEffect(effect); +} + +void KdenliveDoc::enableTrackEffects(int trackIndex, QList effectIndexes, bool disable) +{ + if (trackIndex < 0 || trackIndex >= m_tracksList.count()) { + kWarning() << "Set Track effect outisde of range"; + return; + } + EffectsList list = m_tracksList.at(trackIndex).effectsList; + QDomElement effect; + for (int i = 0; i < effectIndexes.count(); i++) { + effect = list.itemFromIndex(effectIndexes.at(i)); + if (!effect.isNull()) effect.setAttribute("disable", (int) disable); + } } const EffectsList KdenliveDoc::getTrackEffects(int ix) @@ -1551,8 +1604,18 @@ QDomElement KdenliveDoc::getTrackEffect(int trackIndex, int effectIndex) const return QDomElement(); } EffectsList list = m_tracksList.at(trackIndex).effectsList; - if (effectIndex > list.count() - 1 || effectIndex < 0 || list.at(effectIndex).isNull()) return QDomElement(); - return list.at(effectIndex).cloneNode().toElement(); + if (effectIndex > list.count() || effectIndex < 1 || list.itemFromIndex(effectIndex).isNull()) return QDomElement(); + return list.itemFromIndex(effectIndex).cloneNode().toElement(); +} + +int KdenliveDoc::hasTrackEffect(int trackIndex, const QString &tag, const QString &id) const +{ + if (trackIndex < 0 || trackIndex >= m_tracksList.count()) { + kWarning() << "Get Track effect outisde of range"; + return -1; + } + EffectsList list = m_tracksList.at(trackIndex).effectsList; + return list.hasEffect(tag, id); } bool KdenliveDoc::saveCustomEffects(QDomNodeList customeffects) @@ -1672,7 +1735,7 @@ void KdenliveDoc::backupLastSavedVersion(const QString &path) KIO::NetAccess::mkdir(backupFile, kapp->activeWindow()); QString fileName = KUrl(path).fileName().section('.', 0, -2); QFileInfo info(file); - fileName.append("-" + m_documentProperties.value("documentid")); + fileName.append('-' + m_documentProperties.value("documentid")); fileName.append(info.lastModified().toString("-yyyy-MM-dd-hh-mm")); fileName.append(".kdenlive"); backupFile.addPath(fileName); @@ -1692,7 +1755,7 @@ void KdenliveDoc::cleanupBackupFiles() backupFile.addPath(".backup/"); QDir dir(backupFile.path()); QString projectFile = url().fileName().section('.', 0, -2); - projectFile.append("-" + m_documentProperties.value("documentid")); + projectFile.append('-' + m_documentProperties.value("documentid")); projectFile.append("-??"); projectFile.append("??"); projectFile.append("-??"); @@ -1789,6 +1852,7 @@ const QMap KdenliveDoc::metadata() const void KdenliveDoc::setMetadata(const QMap meta) { + setModified(true); m_documentMetadata = meta; }