+QMap <QString, QString> KdenliveDoc::getRenderProperties() const
+{
+ QMap <QString, QString> renderProperties;
+ QMapIterator<QString, QString> i(m_documentProperties);
+ while (i.hasNext()) {
+ i.next();
+ if (i.key().startsWith("render")) renderProperties.insert(i.key(), i.value());
+ }
+ return renderProperties;
+}
+
+void KdenliveDoc::addTrackEffect(int ix, QDomElement effect)
+{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "Add Track effect outisde of range";
+ return;
+ }
+ effect.setAttribute("kdenlive_ix", m_tracksList.at(ix).effectsList.count() + 1);
+
+ // Init parameter value & keyframes if required
+ QDomNodeList params = effect.elementsByTagName("parameter");
+ for (int i = 0; i < params.count(); i++) {
+ QDomElement e = params.item(i).toElement();
+
+ // Check if this effect has a variable parameter
+ if (e.attribute("default").startsWith('%')) {
+ double evaluatedValue = ProfilesDialog::getStringEval(m_profile, e.attribute("default"));
+ e.setAttribute("default", evaluatedValue);
+ if (e.hasAttribute("value") && e.attribute("value").startsWith('%')) {
+ e.setAttribute("value", evaluatedValue);
+ }
+ }
+
+ if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe")) {
+ QString def = e.attribute("default");
+ // Effect has a keyframe type parameter, we need to set the values
+ if (e.attribute("keyframes").isEmpty()) {
+ e.setAttribute("keyframes", "0:" + def + ';');
+ kDebug() << "///// EFFECT KEYFRAMES INITED: " << e.attribute("keyframes");
+ //break;
+ }
+ }
+
+ if (effect.attribute("id") == "crop") {
+ // default use_profile to 1 for clips with proxies to avoid problems when rendering
+ if (e.attribute("name") == "use_profile" && getDocumentProperty("enableproxy") == "1")
+ e.setAttribute("value", "1");
+ }
+ }
+
+ m_tracksList[ix].effectsList.append(effect);
+}
+
+void KdenliveDoc::removeTrackEffect(int ix, QDomElement effect)
+{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "Remove Track effect outisde of range";
+ return;
+ }
+ QString index;
+ QString toRemove = effect.attribute("kdenlive_ix");
+ for (int i = 0; i < m_tracksList.at(ix).effectsList.count(); ++i) {
+ index = m_tracksList.at(ix).effectsList.at(i).attribute("kdenlive_ix");
+ 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);
+ }
+ }
+}
+
+void KdenliveDoc::setTrackEffect(int trackIndex, int effectIndex, QDomElement effect)
+{
+ if (trackIndex < 0 || trackIndex >= m_tracksList.count()) {
+ kWarning() << "Set Track effect outisde of range";
+ return;
+ }
+ if (effectIndex < 0 || effectIndex > (m_tracksList.at(trackIndex).effectsList.count() - 1) || effect.isNull()) {
+ kDebug() << "Invalid effect index: " << effectIndex;
+ return;
+ }
+ effect.setAttribute("kdenlive_ix", effectIndex + 1);
+ m_tracksList[trackIndex].effectsList.replace(effectIndex, effect);
+}
+
+const EffectsList KdenliveDoc::getTrackEffects(int ix)
+{
+ if (ix < 0 || ix >= m_tracksList.count()) {
+ kWarning() << "Get Track effects outisde of range";
+ return EffectsList();
+ }
+ return m_tracksList.at(ix).effectsList;
+}
+
+QDomElement KdenliveDoc::getTrackEffect(int trackIndex, int effectIndex) const
+{
+ if (trackIndex < 0 || trackIndex >= m_tracksList.count()) {
+ kWarning() << "Get Track effect outisde of range";
+ 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();
+}
+
+bool KdenliveDoc::saveCustomEffects(QDomNodeList customeffects)
+{
+ QDomElement e;
+ QStringList importedEffects;
+ int maxchild = customeffects.count();
+ for (int i = 0; i < maxchild; i++) {
+ e = customeffects.at(i).toElement();
+ QString id = e.attribute("id");
+ QString tag = e.attribute("tag");
+ if (!id.isEmpty()) {
+ // Check if effect exists or save it
+ if (MainWindow::customEffects.hasEffect(tag, id) == -1) {
+ QDomDocument doc;
+ doc.appendChild(doc.importNode(e, true));
+ QString path = KStandardDirs::locateLocal("appdata", "effects/", true);
+ path += id + ".xml";
+ if (!QFile::exists(path)) {
+ importedEffects << id;
+ QFile file(path);
+ if (file.open(QFile::WriteOnly | QFile::Truncate)) {
+ QTextStream out(&file);
+ out << doc.toString();
+ }
+ }
+ }
+ }
+ }
+ if (!importedEffects.isEmpty()) KMessageBox::informationList(kapp->activeWindow(), i18n("The following effects were imported from the project:"), importedEffects);
+ return (!importedEffects.isEmpty());
+}
+
+void KdenliveDoc::updateProjectFolderPlacesEntry()
+{
+ /*
+ * For similar and more code have a look at kfileplacesmodel.cpp and the included files:
+ * http://websvn.kde.org/trunk/KDE/kdelibs/kfile/kfileplacesmodel.cpp?view=markup
+ */
+
+ const QString file = KStandardDirs::locateLocal("data", "kfileplaces/bookmarks.xml");
+ KBookmarkManager *bookmarkManager = KBookmarkManager::managerForFile(file, "kfilePlaces");
+ KBookmarkGroup root = bookmarkManager->root();
+ KBookmark bookmark = root.first();
+
+ QString kdenliveName = KGlobal::mainComponent().componentName();
+ KUrl documentLocation = m_projectFolder;
+
+ bool exists = false;
+
+ while (!bookmark.isNull()) {
+ // UDI not empty indicates a device
+ QString udi = bookmark.metaDataItem("UDI");
+ QString appName = bookmark.metaDataItem("OnlyInApp");
+
+ if (udi.isEmpty() && appName == kdenliveName && bookmark.text() == i18n("Project Folder")) {
+ if (bookmark.url() != documentLocation) {
+ bookmark.setUrl(documentLocation);
+ bookmarkManager->emitChanged(root);
+ }
+ exists = true;
+ break;
+ }
+
+ bookmark = root.next(bookmark);
+ }
+
+ // if entry does not exist yet (was not found), well, create it then
+ if (!exists) {
+ bookmark = root.addBookmark(i18n("Project Folder"), documentLocation, "folder-favorites");
+ // Make this user selectable ?
+ bookmark.setMetaDataItem("OnlyInApp", kdenliveName);
+ bookmarkManager->emitChanged(root);
+ }
+}
+
+QStringList KdenliveDoc::getExpandedFolders()
+{
+ QStringList result = m_documentProperties.value("expandedfolders").split(';');
+ // this property is only needed once when opening project, so clear it now
+ m_documentProperties.remove("expandedfolders");
+ return result;
+}
+
+// static
+double KdenliveDoc::getDisplayRatio(const QString &path)
+{
+ QFile file(path);
+ QDomDocument doc;
+ if (!file.open(QIODevice::ReadOnly)) {
+ kWarning() << "ERROR, CANNOT READ: " << path;
+ return 0;
+ }
+ if (!doc.setContent(&file)) {
+ kWarning() << "ERROR, CANNOT READ: " << path;
+ file.close();
+ return 0;
+ }
+ file.close();
+ QDomNodeList list = doc.elementsByTagName("profile");
+ if (list.isEmpty()) return 0;
+ QDomElement profile = list.at(0).toElement();
+ double den = profile.attribute("display_aspect_den").toDouble();
+ if (den > 0) return profile.attribute("display_aspect_num").toDouble() / den;
+ return 0;
+}
+
+void KdenliveDoc::backupLastSavedVersion(const QString &path)
+{
+ // Ensure backup folder exists
+ if (path.isEmpty()) return;
+ QFile file(path);
+ KUrl backupFile = m_projectFolder;
+ backupFile.addPath(".backup/");
+ 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(info.lastModified().toString("-yyyy-MM-dd-hh-mm"));
+ fileName.append(".kdenlive");
+ backupFile.addPath(fileName);
+
+ if (file.exists()) {
+ // delete previous backup if it was done less than 60 seconds ago
+ QFile::remove(backupFile.path());
+ if (!QFile::copy(path, backupFile.path())) {
+ KMessageBox::information(kapp->activeWindow(), i18n("Cannot create backup copy:\n%1", backupFile.path()));
+ }
+ }
+}
+
+void KdenliveDoc::cleanupBackupFiles()
+{
+ KUrl backupFile = m_projectFolder;
+ backupFile.addPath(".backup/");
+ QDir dir(backupFile.path());
+ QString projectFile = url().fileName().section('.', 0, -2);
+ projectFile.append("-" + m_documentProperties.value("documentid"));
+ projectFile.append("-??");
+ projectFile.append("??");
+ projectFile.append("-??");
+ projectFile.append("-??");
+ projectFile.append("-??");
+ projectFile.append("-??.kdenlive");
+
+ QStringList filter;
+ backupFile.addPath(projectFile);
+ filter << projectFile;
+ dir.setNameFilters(filter);
+ QFileInfoList resultList = dir.entryInfoList(QDir::Files, QDir::Time);
+
+ QDateTime d = QDateTime::currentDateTime();
+ QStringList hourList;
+ QStringList dayList;
+ QStringList weekList;
+ QStringList oldList;
+ for (int i = 0; i < resultList.count(); i++) {
+ if (d.secsTo(resultList.at(i).lastModified()) < 3600) {
+ // files created in the last hour
+ hourList.append(resultList.at(i).absoluteFilePath());
+ }
+ else if (d.secsTo(resultList.at(i).lastModified()) < 43200) {
+ // files created in the day
+ dayList.append(resultList.at(i).absoluteFilePath());
+ }
+ else if (d.daysTo(resultList.at(i).lastModified()) < 8) {
+ // files created in the week
+ weekList.append(resultList.at(i).absoluteFilePath());
+ }
+ else {
+ // older files
+ oldList.append(resultList.at(i).absoluteFilePath());
+ }
+ }
+ if (hourList.count() > 20) {
+ int step = hourList.count() / 10;
+ for (int i = 0; i < hourList.count(); i += step) {
+ kDebug()<<"REMOVE AT: "<<i<<", COUNT: "<<hourList.count();
+ hourList.removeAt(i);
+ i--;
+ }
+ } else hourList.clear();
+ if (dayList.count() > 20) {
+ int step = dayList.count() / 10;
+ for (int i = 0; i < dayList.count(); i += step) {
+ dayList.removeAt(i);
+ i--;
+ }
+ } else dayList.clear();
+ if (weekList.count() > 20) {
+ int step = weekList.count() / 10;
+ for (int i = 0; i < weekList.count(); i += step) {
+ weekList.removeAt(i);
+ i--;
+ }
+ } else weekList.clear();
+ if (oldList.count() > 20) {
+ int step = oldList.count() / 10;
+ for (int i = 0; i < oldList.count(); i += step) {
+ oldList.removeAt(i);
+ i--;
+ }
+ } else oldList.clear();
+
+ QString f;
+ while (hourList.count() > 0) {
+ f = hourList.takeFirst();
+ QFile::remove(f);
+ QFile::remove(f + ".png");
+ }
+ while (dayList.count() > 0) {
+ f = dayList.takeFirst();
+ QFile::remove(f);
+ QFile::remove(f + ".png");
+ }
+ while (weekList.count() > 0) {
+ f = weekList.takeFirst();
+ QFile::remove(f);
+ QFile::remove(f + ".png");
+ }
+ while (oldList.count() > 0) {
+ f = oldList.takeFirst();
+ QFile::remove(f);
+ QFile::remove(f + ".png");
+ }
+}
+