X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fkdenlivedoc.cpp;h=97467f462cc8c29b040f42dc57782435d7655b34;hb=0e46ae5f66587c3a503c065bd1e1ee12a07c2261;hp=ab517a6cdcdb3b1e0c8b8b1ca6f4a3ad0d9dcc1a;hpb=31e84d6bd7f7b1ac64d942a9171d98ad8d0f7d62;p=kdenlive diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index ab517a6c..97467f46 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -42,22 +42,20 @@ #include #include #include +#include #include -const double DOCUMENTVERSION = 0.83; +const double DOCUMENTVERSION = 0.85; KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, QString profileName, const QPoint tracks, Render *render, MainWindow *parent) : QObject(parent), m_autosave(NULL), m_url(url), - m_startPos(0), m_render(render), m_commandStack(new QUndoStack(undoGroup)), m_modified(false), m_projectFolder(projectFolder), - m_documentLoadingStep(0.0), - m_documentLoadingProgress(0), m_abortLoading(false) { m_clipManager = new ClipManager(this); @@ -67,6 +65,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup // init default document properties m_documentProperties["zoom"] = "7"; + m_documentProperties["verticalzoom"] = "1"; m_documentProperties["zonein"] = "0"; m_documentProperties["zoneout"] = "100"; @@ -78,17 +77,22 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup else { QFile file(tmpFile); QString errorMsg; + QDomImplementation impl; + impl.setInvalidDataPolicy(QDomImplementation::DropInvalidChars); success = m_document.setContent(&file, false, &errorMsg); file.close(); KIO::NetAccess::removeTempFile(tmpFile); + if (!success) // It is corrupted KMessageBox::error(parent, errorMsg); else { + parent->slotGotProgressInfo(i18n("Validating"), 0); DocumentValidator validator(m_document); success = validator.isProject(); - if (!success) // It is not a project file - parent->slotGotProgressInfo(i18n("File %1 is not a Kdenlive project file.", m_url.path()), 100); - else { + if (!success) { + // It is not a project file + parent->slotGotProgressInfo(i18n("File %1 is not a Kdenlive project file", m_url.path()), 0); + } else { /* * Validate the file against the current version (upgrade * and recover it if needed). It is NOT a passive operation @@ -96,20 +100,17 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup // TODO: backup the document or alert the user? success = validator.validate(DOCUMENTVERSION); if (success) { // Let the validator handle error messages - setModified(validator.isModified()); + parent->slotGotProgressInfo(i18n("Loading"), 0); QDomElement mlt = m_document.firstChildElement("mlt"); QDomElement infoXml = mlt.firstChildElement("kdenlivedoc"); profileName = infoXml.attribute("profile"); - m_projectFolder = infoXml.attribute("projectfolder"); - m_startPos = infoXml.attribute("position").toInt(); - + m_projectFolder = KUrl(infoXml.attribute("projectfolder")); QDomElement docproperties = infoXml.firstChildElement("documentproperties"); QDomNamedNodeMap props = docproperties.attributes(); for (int i = 0; i < props.count(); i++) { m_documentProperties.insert(props.item(i).nodeName(), props.item(i).nodeValue()); } - // Build tracks QDomElement e; QDomElement tracksinfo = infoXml.firstChildElement("tracksinfo"); @@ -125,6 +126,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup projectTrack.isMute = e.attribute("mute").toInt(); projectTrack.isBlind = e.attribute("blind").toInt(); projectTrack.isLocked = e.attribute("locked").toInt(); + projectTrack.trackName = e.attribute("trackname"); m_tracksList.append(projectTrack); } } @@ -132,29 +134,19 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup } QDomNodeList producers = m_document.elementsByTagName("producer"); QDomNodeList infoproducers = m_document.elementsByTagName("kdenlive_producer"); + parent->slotGotProgressInfo(i18n("Check missing clips"), 0); if (checkDocumentClips(infoproducers) == false) m_abortLoading = true; const int max = producers.count(); const int infomax = infoproducers.count(); - QDomNodeList folders = m_document.elementsByTagName("folder"); + QDomNodeList folders = m_document.elementsByTagName("folder"); for (int i = 0; i < folders.count(); i++) { e = folders.item(i).cloneNode().toElement(); m_clipManager->addFolder(e.attribute("id"), e.attribute("name")); } - if (max > 0) { - m_documentLoadingStep = 100.0 / (max + infomax + m_document.elementsByTagName("entry").count()); - parent->slotGotProgressInfo(i18n("Loading project clips"), (int) m_documentLoadingProgress); - } - - for (int i = 0; i < infomax && !m_abortLoading; i++) { e = infoproducers.item(i).cloneNode().toElement(); - if (m_documentLoadingStep > 0) { - m_documentLoadingProgress += m_documentLoadingStep; - parent->slotGotProgressInfo(QString(), (int) m_documentLoadingProgress); - //qApp->processEvents(); - } QString prodId = e.attribute("id"); if (!e.isNull() && prodId != "black" && !prodId.startsWith("slowmotion") && !m_abortLoading) { e.setTagName("producer"); @@ -169,13 +161,12 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup } } addClipInfo(e, orig, prodId); - kDebug() << "// KDENLIVE PRODUCER: " << prodId; } } if (m_abortLoading) { //parent->slotGotProgressInfo(i18n("File %1 is not a Kdenlive project file."), 100); emit resetProjectList(); - m_startPos = 0; + m_documentProperties.remove("position"); m_url = KUrl(); m_tracksList.clear(); kWarning() << "Aborted loading of: " << url.path(); @@ -196,20 +187,24 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup infoXml.removeChild(markers); } setProfilePath(profileName); + setModified(validator.isModified()); kDebug() << "Reading file: " << url.path() << ", found clips: " << producers.count(); } } } } } - } else setProfilePath(profileName); + } // Something went wrong, or a new file was requested: create a new project if (!success) { + setProfilePath(profileName); m_url = KUrl(); m_document = createEmptyDocument(tracks.x(), tracks.y()); } + KdenliveSettings::setCurrent_profile(profilePath()); + // Set the video profile (empty == default) // Make sure the project folder is usable @@ -219,13 +214,13 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup } // Make sure that the necessary folders exist - KStandardDirs::makeDir(m_projectFolder.path() + "/titles/"); - KStandardDirs::makeDir(m_projectFolder.path() + "/thumbs/"); - KStandardDirs::makeDir(m_projectFolder.path() + "/ladspa/"); + KStandardDirs::makeDir(m_projectFolder.path(KUrl::AddTrailingSlash) + "titles/"); + KStandardDirs::makeDir(m_projectFolder.path(KUrl::AddTrailingSlash) + "thumbs/"); + KStandardDirs::makeDir(m_projectFolder.path(KUrl::AddTrailingSlash) + "ladspa/"); kDebug() << "Kdenlive document, init timecode: " << m_fps; - if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(30, true); - else m_timecode.setFormat((int) m_fps); + if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(m_fps, true); + else m_timecode.setFormat(m_fps); //kDebug() << "// SETTING SCENE LIST:\n\n" << m_document.toString(); connect(m_autoSaveTimer, SIGNAL(timeout()), this, SLOT(slotAutoSave())); @@ -233,8 +228,11 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup KdenliveDoc::~KdenliveDoc() { + m_autoSaveTimer->stop(); delete m_commandStack; + kDebug() << "// DEL CLP MAN"; delete m_clipManager; + kDebug() << "// DEL CLP MAN done"; delete m_autoSaveTimer; if (m_autosave) { if (!m_autosave->fileName().isEmpty()) m_autosave->remove(); @@ -242,22 +240,21 @@ KdenliveDoc::~KdenliveDoc() } } -void KdenliveDoc::setSceneList() +int KdenliveDoc::setSceneList() { - m_render->setSceneList(m_document.toString(), m_startPos); + m_render->resetProfile(KdenliveSettings::current_profile()); + if (m_render->setSceneList(m_document.toString(), m_documentProperties.value("position").toInt()) == -1) { + // INVALID MLT Consumer, something is wrong + return -1; + } + m_documentProperties.remove("position"); // m_document xml is now useless, clear it m_document.clear(); - checkProjectClips(); + return 0; } -QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int audiotracks) +QDomDocument KdenliveDoc::createEmptyDocument(int videotracks, int audiotracks) { - // Creating new document - QDomDocument doc; - QDomElement mlt = doc.createElement("mlt"); - doc.appendChild(mlt); - - TrackInfo videoTrack; videoTrack.type = VIDEOTRACK; videoTrack.isMute = false; @@ -270,6 +267,72 @@ QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int a audioTrack.isBlind = true; audioTrack.isLocked = false; + m_tracksList.clear(); + + for (int i = 0; i < audiotracks; i++) { + m_tracksList.append(audioTrack); + } + for (int i = 0; i < videotracks; i++) { + m_tracksList.append(videoTrack); + } + return createEmptyDocument(m_tracksList); +} + +QDomDocument KdenliveDoc::createEmptyDocument(QList tracks) +{ + // Creating new document + QDomDocument doc; + QDomElement mlt = doc.createElement("mlt"); + doc.appendChild(mlt); + + + // Create black producer + // For some unknown reason, we have to build the black producer here and not in renderer.cpp, otherwise + // the composite transitions with the black track are corrupted. + QDomElement blk = doc.createElement("producer"); + blk.setAttribute("in", 0); + blk.setAttribute("out", 500); + blk.setAttribute("id", "black"); + + QDomElement property = doc.createElement("property"); + property.setAttribute("name", "mlt_type"); + QDomText value = doc.createTextNode("producer"); + property.appendChild(value); + blk.appendChild(property); + + property = doc.createElement("property"); + property.setAttribute("name", "aspect_ratio"); + value = doc.createTextNode(QString::number(0.0)); + property.appendChild(value); + blk.appendChild(property); + + property = doc.createElement("property"); + property.setAttribute("name", "length"); + value = doc.createTextNode(QString::number(15000)); + property.appendChild(value); + blk.appendChild(property); + + property = doc.createElement("property"); + property.setAttribute("name", "eof"); + value = doc.createTextNode("pause"); + property.appendChild(value); + blk.appendChild(property); + + property = doc.createElement("property"); + property.setAttribute("name", "resource"); + value = doc.createTextNode("black"); + property.appendChild(value); + blk.appendChild(property); + + property = doc.createElement("property"); + property.setAttribute("name", "mlt_service"); + value = doc.createTextNode("colour"); + property.appendChild(value); + blk.appendChild(property); + + mlt.appendChild(blk); + + QDomElement tractor = doc.createElement("tractor"); tractor.setAttribute("id", "maintractor"); QDomElement multitrack = doc.createElement("multitrack"); @@ -277,9 +340,14 @@ QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int a playlist.setAttribute("id", "black_track"); mlt.appendChild(playlist); + QDomElement blank0 = doc.createElement("entry"); + blank0.setAttribute("in", "0"); + blank0.setAttribute("out", "0"); + blank0.setAttribute("producer", "black"); + playlist.appendChild(blank0); // create playlists - int total = audiotracks + videotracks + 1; + int total = tracks.count() + 1; for (int i = 1; i < total; i++) { QDomElement playlist = doc.createElement("playlist"); @@ -292,20 +360,16 @@ QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int a tractor.appendChild(track0); // create audio tracks - for (int i = 1; i < audiotracks + 1; i++) { - QDomElement track = doc.createElement("track"); - track.setAttribute("producer", "playlist" + QString::number(i)); - track.setAttribute("hide", "video"); - tractor.appendChild(track); - m_tracksList.append(audioTrack); - } - - // create video tracks - for (int i = audiotracks + 1; i < total; i++) { + for (int i = 1; i < total; i++) { QDomElement track = doc.createElement("track"); track.setAttribute("producer", "playlist" + QString::number(i)); + if (tracks.at(i - 1).type == AUDIOTRACK) + track.setAttribute("hide", "video"); + else if (tracks.at(i - 1).isBlind) + track.setAttribute("hide", "video"); + if (tracks.at(i - 1).isMute) + track.setAttribute("hide", "audio"); tractor.appendChild(track); - m_tracksList.append(videoTrack); } for (int i = 2; i < total ; i++) { @@ -390,14 +454,15 @@ void KdenliveDoc::slotAutoSave() } } -void KdenliveDoc::setZoom(int factor) +void KdenliveDoc::setZoom(int horizontal, int vertical) { - m_documentProperties["zoom"] = QString::number(factor); + m_documentProperties["zoom"] = QString::number(horizontal); + m_documentProperties["verticalzoom"] = QString::number(vertical); } -int KdenliveDoc::zoom() const +QPoint KdenliveDoc::zoom() const { - return m_documentProperties.value("zoom").toInt(); + return QPoint(m_documentProperties.value("zoom").toInt(), m_documentProperties.value("verticalzoom").toInt()); } void KdenliveDoc::setZone(int start, int end) @@ -423,7 +488,6 @@ bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene) addedXml.setAttribute("version", DOCUMENTVERSION); addedXml.setAttribute("kdenliveversion", VERSION); addedXml.setAttribute("profile", profilePath()); - addedXml.setAttribute("position", m_render->seekPosition().frames(m_fps)); addedXml.setAttribute("projectfolder", m_projectFolder.path()); QDomElement docproperties = sceneList.createElement("documentproperties"); @@ -432,6 +496,7 @@ bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene) i.next(); docproperties.setAttribute(i.key(), i.value()); } + docproperties.setAttribute("position", m_render->seekPosition().frames(m_fps)); addedXml.appendChild(docproperties); // Add profile info @@ -456,6 +521,7 @@ bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene) trackinfo.setAttribute("mute", info.isMute); trackinfo.setAttribute("blind", info.isBlind); trackinfo.setAttribute("locked", info.isLocked); + trackinfo.setAttribute("trackname", info.trackName); tracksinfo.appendChild(trackinfo); } addedXml.appendChild(tracksinfo); @@ -531,8 +597,8 @@ void KdenliveDoc::setProjectFolder(KUrl url) if (url == m_projectFolder) return; setModified(true); KStandardDirs::makeDir(url.path()); - KStandardDirs::makeDir(url.path() + "/titles/"); - KStandardDirs::makeDir(url.path() + "/thumbs/"); + 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); m_projectFolder = url; } @@ -546,20 +612,20 @@ void KdenliveDoc::moveProjectData(KUrl url) if (clip->clipType() == TEXT) { // the image for title clip must be moved KUrl oldUrl = clip->fileURL(); - KUrl newUrl = KUrl(url.path() + "/titles/" + oldUrl.fileName()); + KUrl newUrl = KUrl(url.path(KUrl::AddTrailingSlash) + "titles/" + oldUrl.fileName()); KIO::Job *job = KIO::copy(oldUrl, newUrl); if (KIO::NetAccess::synchronousRun(job, 0)) clip->setProperty("resource", newUrl.path()); } QString hash = clip->getClipHash(); - KUrl oldVideoThumbUrl = KUrl(m_projectFolder.path() + "/thumbs/" + hash + ".png"); - KUrl oldAudioThumbUrl = KUrl(m_projectFolder.path() + "/thumbs/" + hash + ".thumb"); + 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() + "/thumbs/" + hash + ".png"); + KUrl newUrl = KUrl(url.path(KUrl::AddTrailingSlash) + "thumbs/" + hash + ".png"); KIO::Job *job = KIO::copy(oldVideoThumbUrl, newUrl); KIO::NetAccess::synchronousRun(job, 0); } if (KIO::NetAccess::exists(oldAudioThumbUrl, KIO::NetAccess::SourceSide, 0)) { - KUrl newUrl = KUrl(url.path() + "/thumbs/" + hash + ".thumb"); + 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(); } @@ -576,11 +642,12 @@ MltVideoProfile KdenliveDoc::mltProfile() const return m_profile; } -void KdenliveDoc::setProfilePath(QString path) +bool KdenliveDoc::setProfilePath(QString path) { if (path.isEmpty()) path = KdenliveSettings::default_profile(); if (path.isEmpty()) path = "dv_pal"; m_profile = ProfilesDialog::getVideoProfile(path); + bool current_fps = m_fps; if (m_profile.path.isEmpty()) { // Profile not found, use embedded profile QDomElement profileInfo = m_document.elementsByTagName("profileinfo").at(0).toElement(); @@ -631,8 +698,9 @@ void KdenliveDoc::setProfilePath(QString path) m_width = m_profile.width; m_height = m_profile.height; kDebug() << "Kdenlive document, init timecode from path: " << path << ", " << m_fps; - if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(30, true); - else m_timecode.setFormat((int) m_fps); + if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(m_fps, true); + else m_timecode.setFormat(m_fps); + return (current_fps != m_fps); } double KdenliveDoc::dar() @@ -645,12 +713,6 @@ void KdenliveDoc::setThumbsProgress(const QString &message, int progress) emit progressInfo(message, progress); } -void KdenliveDoc::loadingProgressed() -{ - m_documentLoadingProgress += m_documentLoadingStep; - emit progressInfo(QString(), (int) m_documentLoadingProgress); -} - QUndoStack *KdenliveDoc::commandStack() { return m_commandStack; @@ -675,53 +737,16 @@ void KdenliveDoc::checkProjectClips() kDebug() << "+++++++++++++ + + + + CHK PCLIPS"; if (m_render == NULL) return; m_clipManager->resetProducersList(m_render->producersList()); - return; - - // Useless now... - QList prods = m_render->producersList(); - QString id ; - QString prodId ; - QString prodTrack ; - for (int i = 0; i < prods.count(); i++) { - id = prods.at(i)->get("id"); - prodId = id.section('_', 0, 0); - prodTrack = id.section('_', 1, 1); - DocClipBase *clip = m_clipManager->getClipById(prodId); - if (clip) clip->setProducer(prods.at(i)); - if (clip && clip->clipType() == TEXT && !QFile::exists(clip->fileURL().path())) { - // regenerate text clip image if required - //kDebug() << "// TITLE: " << clip->getProperty("titlename") << " Preview file: " << clip->getProperty("resource") << " DOES NOT EXIST"; - QString titlename = clip->getProperty("name"); - QString titleresource; - if (titlename.isEmpty()) { - QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder()); - titlename = titleInfo.at(0); - titleresource = titleInfo.at(1); - clip->setProperty("name", titlename); - kDebug() << "// New title set to: " << titlename; - } else { - titleresource = TitleWidget::getFreeTitleInfo(projectFolder()).at(1); - //titleresource = TitleWidget::getTitleResourceFromName(projectFolder(), titlename); - } - TitleWidget *dia_ui = new TitleWidget(KUrl(), KUrl(titleresource).directory(), m_render, kapp->activeWindow()); - QDomDocument doc; - doc.setContent(clip->getProperty("xmldata")); - dia_ui->setXml(doc); - QImage pix = dia_ui->renderedPixmap(); - pix.save(titleresource); - clip->setProperty("resource", titleresource); - delete dia_ui; - clip->producer()->set("force_reload", 1); - } - } } void KdenliveDoc::updatePreviewSettings() { m_clipManager->updatePreviewSettings(); m_render->updatePreviewSettings(); + QList prods = m_render->producersList(); m_clipManager->resetProducersList(m_render->producersList()); - + qDeleteAll(prods); + prods.clear(); } Render *KdenliveDoc::renderer() @@ -729,14 +754,14 @@ Render *KdenliveDoc::renderer() return m_render; } -void KdenliveDoc::updateClip(const QString &id) +void KdenliveDoc::updateClip(const QString id) { emit updateClipDisplay(id); } int KdenliveDoc::getFramePos(QString duration) { - return m_timecode.getFrameCount(duration, m_fps); + return m_timecode.getFrameCount(duration); } QString KdenliveDoc::producerName(const QString &id) @@ -838,29 +863,6 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem) if (elem.attribute("type").toInt() == SLIDESHOW) { extension = KUrl(path).fileName(); path = KUrl(path).directory(); - } else if (elem.attribute("type").toInt() == TEXT && QFile::exists(path) == false) { - kDebug() << "// TITLE: " << elem.attribute("name") << " Preview file: " << elem.attribute("resource") << " DOES NOT EXIST"; - QString titlename = elem.attribute("name"); - QString titleresource; - if (titlename.isEmpty()) { - QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder()); - titlename = titleInfo.at(0); - titleresource = titleInfo.at(1); - elem.setAttribute("name", titlename); - kDebug() << "// New title set to: " << titlename; - } else { - titleresource = TitleWidget::getFreeTitleInfo(projectFolder()).at(1); - //titleresource = TitleWidget::getTitleResourceFromName(projectFolder(), titlename); - } - TitleWidget *dia_ui = new TitleWidget(KUrl(), KUrl(titleresource).directory(), m_render, kapp->activeWindow()); - QDomDocument doc; - doc.setContent(elem.attribute("xmldata")); - dia_ui->setXml(doc); - QImage pix = dia_ui->renderedPixmap(); - pix.save(titleresource); - elem.setAttribute("resource", titleresource); - setNewClipResource(clipId, titleresource); - delete dia_ui; } if (path.isEmpty() == false && QFile::exists(path) == false && elem.attribute("type").toInt() != TEXT && !elem.hasAttribute("placeholder")) { @@ -917,12 +919,10 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem) if (createClipItem) { emit addProjectClip(clip); - qApp->processEvents(); - m_render->getFileProperties(clip->toXML(), clip->getId(), false); + //qApp->processEvents(); } } - void KdenliveDoc::setNewClipResource(const QString &id, const QString &path) { QDomNodeList prods = m_document.elementsByTagName("producer"); @@ -1015,25 +1015,24 @@ void KdenliveDoc::addClipInfo(QDomElement elem, QDomElement orig, QString clipId } } -void KdenliveDoc::deleteProjectClip(QList ids) +void KdenliveDoc::deleteProjectClip(QStringList ids) { for (int i = 0; i < ids.size(); ++i) { emit deleteTimelineClip(ids.at(i)); - m_clipManager->slotDeleteClip(ids.at(i)); } + m_clipManager->slotDeleteClips(ids); setModified(true); } void KdenliveDoc::deleteClip(const QString &clipId) { emit signalDeleteProjectClip(clipId); - m_clipManager->deleteClip(clipId); } 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())); + //emit selectLastAddedClip(QString::number(m_clipManager->lastClipId())); setModified(true); } @@ -1071,15 +1070,11 @@ void KdenliveDoc::slotCreateSlideshowClipFile(const QString name, const QString void KdenliveDoc::slotCreateTextClip(QString group, const QString &groupId, const QString &templatePath) { - QString titlesFolder = projectFolder().path() + "/titles/"; + QString titlesFolder = projectFolder().path(KUrl::AddTrailingSlash) + "titles/"; KStandardDirs::makeDir(titlesFolder); - TitleWidget *dia_ui = new TitleWidget(templatePath, titlesFolder, m_render, kapp->activeWindow()); + TitleWidget *dia_ui = new TitleWidget(templatePath, m_timecode, titlesFolder, m_render, kapp->activeWindow()); if (dia_ui->exec() == QDialog::Accepted) { - QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder()); - QImage pix = dia_ui->renderedPixmap(); - pix.save(titleInfo.at(1)); - //dia_ui->saveTitle(path + ".kdenlivetitle"); - m_clipManager->slotAddTextClipFile(titleInfo.at(0), titleInfo.at(1), 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())); } @@ -1088,20 +1083,15 @@ void KdenliveDoc::slotCreateTextClip(QString group, const QString &groupId, cons void KdenliveDoc::slotCreateTextTemplateClip(QString group, const QString &groupId, KUrl path) { - QString titlesFolder = projectFolder().path() + "/titles/"; + QString titlesFolder = projectFolder().path(KUrl::AddTrailingSlash) + "titles/"; if (path.isEmpty()) { path = KFileDialog::getOpenUrl(KUrl(titlesFolder), "*.kdenlivetitle", kapp->activeWindow(), i18n("Enter Template Path")); } if (path.isEmpty()) return; - QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder()); - - TitleWidget *dia_ui = new TitleWidget(path, titlesFolder, m_render, kapp->activeWindow()); - QImage pix = dia_ui->renderedPixmap(); - pix.save(titleInfo.at(1)); - delete dia_ui; - m_clipManager->slotAddTextTemplateClip(titleInfo.at(0), titleInfo.at(1), path, group, groupId); + //TODO: rewrite with new title system (just set resource) + m_clipManager->slotAddTextTemplateClip(i18n("Template title clip"), path, group, groupId); setModified(true); emit selectLastAddedClip(QString::number(m_clipManager->lastClipId())); } @@ -1153,6 +1143,7 @@ void KdenliveDoc::setTrackType(int ix, TrackInfo type) m_tracksList[ix].isMute = type.isMute; m_tracksList[ix].isBlind = type.isBlind; m_tracksList[ix].isLocked = type.isLocked; + m_tracksList[ix].trackName = type.trackName; } const QList KdenliveDoc::tracksList() const @@ -1173,42 +1164,55 @@ QPoint KdenliveDoc::getTracksCount() const void KdenliveDoc::cachePixmap(const QString &fileId, const QPixmap &pix) const { - pix.save(m_projectFolder.path() + "/thumbs/" + fileId + ".png"); + 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() + "/ladspa/" + counter + ".ladspa")) { + while (QFile::exists(m_projectFolder.path(KUrl::AddTrailingSlash) + "ladspa/" + counter + ".ladspa")) { ct++; counter = QString::number(ct).rightJustified(5, '0', false); } - return m_projectFolder.path() + "/ladspa/" + counter + ".ladspa"; + return m_projectFolder.path(KUrl::AddTrailingSlash) + "ladspa/" + counter + ".ladspa"; } bool KdenliveDoc::checkDocumentClips(QDomNodeList infoproducers) { - int clipType; - QDomElement e; - QString id; - QString resource; - QList missingClips; - for (int i = 0; i < infoproducers.count(); i++) { - e = infoproducers.item(i).toElement(); - clipType = e.attribute("type").toInt(); - if (clipType == TEXT || clipType == COLOR) continue; - id = e.attribute("id"); - resource = e.attribute("resource"); - if (clipType == SLIDESHOW) resource = KUrl(resource).directory(); - if (!KIO::NetAccess::exists(KUrl(resource), KIO::NetAccess::SourceSide, 0)) { - // Missing clip found - missingClips.append(e); + DocumentChecker d(infoproducers, m_document); + return (d.hasMissingClips() == false); + + /* int clipType; + QDomElement e; + QString id; + QString resource; + QList missingClips; + for (int i = 0; i < infoproducers.count(); i++) { + e = infoproducers.item(i).toElement(); + clipType = e.attribute("type").toInt(); + if (clipType == COLOR) continue; + if (clipType == TEXT) { + //TODO: Check is clip template is missing (xmltemplate) or hash changed + continue; + } + id = e.attribute("id"); + resource = e.attribute("resource"); + if (clipType == SLIDESHOW) resource = KUrl(resource).directory(); + if (!KIO::NetAccess::exists(KUrl(resource), KIO::NetAccess::SourceSide, 0)) { + // Missing clip found + missingClips.append(e); + } else { + // Check if the clip has changed + if (clipType != SLIDESHOW && e.hasAttribute("file_hash")) { + if (e.attribute("file_hash") != DocClipBase::getHash(e.attribute("resource"))) + e.removeAttribute("file_hash"); + } + } } - } - if (missingClips.isEmpty()) return true; - DocumentChecker d(missingClips, m_document); - return (d.exec() == QDialog::Accepted); + if (missingClips.isEmpty()) return true; + DocumentChecker d(missingClips, m_document); + return (d.exec() == QDialog::Accepted);*/ } void KdenliveDoc::setDocumentProperty(const QString &name, const QString &value)