X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fkdenlivedoc.cpp;h=f3591cc82af6695ac2d9b1afea26aa5e5760ec0e;hb=7d1f818376b25f793ad6e8960b73a24a39605945;hp=34286682f9a0f86207658464ec8a8c411bd0ee47;hpb=d82d4bd756b93f81af94edbeb33f74e74016c650;p=kdenlive diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index 34286682..f3591cc8 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -45,28 +45,31 @@ #include -const double DOCUMENTVERSION = 0.83; +const double DOCUMENTVERSION = 0.84; 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_zoom(7), - 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_zoneStart(0), - m_zoneEnd(100) + m_abortLoading(false) { m_clipManager = new ClipManager(this); m_autoSaveTimer = new QTimer(this); m_autoSaveTimer->setSingleShot(true); bool success = false; + + // init default document properties + m_documentProperties["zoom"] = "7"; + m_documentProperties["verticalzoom"] = "1"; + m_documentProperties["zonein"] = "0"; + m_documentProperties["zoneout"] = "100"; + if (!url.isEmpty()) { QString tmpFile; success = KIO::NetAccess::download(url.path(), tmpFile, parent); @@ -78,6 +81,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup success = m_document.setContent(&file, false, &errorMsg); file.close(); KIO::NetAccess::removeTempFile(tmpFile); + if (!success) // It is corrupted KMessageBox::error(parent, errorMsg); else { @@ -93,18 +97,16 @@ 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()); 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_zoom = infoXml.attribute("zoom", "7").toInt(); - m_zoneStart = infoXml.attribute("zonein", "0").toInt(); - m_zoneEnd = infoXml.attribute("zoneout", "100").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"); @@ -120,6 +122,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); } } @@ -170,7 +173,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup 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(); @@ -191,20 +194,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 @@ -214,13 +221,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())); @@ -228,8 +235,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(); @@ -237,22 +247,22 @@ KdenliveDoc::~KdenliveDoc() } } -void KdenliveDoc::setSceneList() +int KdenliveDoc::setSceneList() { - m_render->setSceneList(m_document.toString(), m_startPos); + m_render->resetProfile(); + 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; @@ -265,6 +275,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"); @@ -272,9 +348,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"); @@ -287,20 +368,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++) { @@ -385,25 +462,26 @@ void KdenliveDoc::slotAutoSave() } } -void KdenliveDoc::setZoom(int factor) +void KdenliveDoc::setZoom(int horizontal, int vertical) { - m_zoom = factor; + m_documentProperties["zoom"] = QString::number(horizontal); + m_documentProperties["verticalzoom"] = QString::number(vertical); } -int KdenliveDoc::zoom() const +QPoint KdenliveDoc::zoom() const { - return m_zoom; + return QPoint(m_documentProperties.value("zoom").toInt(), m_documentProperties.value("verticalzoom").toInt()); } void KdenliveDoc::setZone(int start, int end) { - m_zoneStart = start; - m_zoneEnd = end; + m_documentProperties["zonein"] = QString::number(start); + m_documentProperties["zoneout"] = QString::number(end); } QPoint KdenliveDoc::zone() const { - return QPoint(m_zoneStart, m_zoneEnd); + return QPoint(m_documentProperties.value("zonein").toInt(), m_documentProperties.value("zoneout").toInt()); } bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene) @@ -418,11 +496,16 @@ 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("zonein", m_zoneStart); - addedXml.setAttribute("zoneout", m_zoneEnd); addedXml.setAttribute("projectfolder", m_projectFolder.path()); - addedXml.setAttribute("zoom", m_zoom); + + QDomElement docproperties = sceneList.createElement("documentproperties"); + QMapIterator i(m_documentProperties); + while (i.hasNext()) { + i.next(); + docproperties.setAttribute(i.key(), i.value()); + } + docproperties.setAttribute("position", m_render->seekPosition().frames(m_fps)); + addedXml.appendChild(docproperties); // Add profile info QDomElement profileinfo = sceneList.createElement("profileinfo"); @@ -446,6 +529,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); @@ -521,8 +605,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; } @@ -536,20 +620,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(); } @@ -566,11 +650,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(); @@ -621,8 +706,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() @@ -665,53 +751,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() @@ -719,14 +768,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) @@ -828,29 +877,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")) { @@ -908,7 +934,7 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem) if (createClipItem) { emit addProjectClip(clip); qApp->processEvents(); - m_render->getFileProperties(clip->toXML(), clip->getId()); + m_render->getFileProperties(clip->toXML(), clip->getId(), true); } } @@ -1017,7 +1043,6 @@ void KdenliveDoc::deleteProjectClip(QList ids) 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) @@ -1030,7 +1055,6 @@ void KdenliveDoc::slotAddClipList(const KUrl::List urls, const QString group, co void KdenliveDoc::slotAddClipFile(const KUrl url, const QString group, const QString &groupId) { - //kDebug() << "///////// DOCUM, ADD CLP: " << url; m_clipManager->slotAddClipFile(url, group, groupId); emit selectLastAddedClip(QString::number(m_clipManager->lastClipId())); setModified(true); @@ -1046,22 +1070,48 @@ DocClipBase *KdenliveDoc::getBaseClip(const QString &clipId) return m_clipManager->getClipById(clipId); } -void KdenliveDoc::slotCreateTextClip(QString /*group*/, const QString &/*groupId*/) +void KdenliveDoc::slotCreateColorClip(const QString &name, const QString &color, const QString &duration, QString group, const QString &groupId) +{ + m_clipManager->slotAddColorClipFile(name, color, duration, group, groupId); + 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 fade, const QString &luma_duration, const QString &luma_file, const int softness, QString group, const QString &groupId) +{ + m_clipManager->slotAddSlideshowClipFile(name, path, count, duration, loop, fade, luma_duration, luma_file, softness, group, groupId); + setModified(true); + emit selectLastAddedClip(QString::number(m_clipManager->lastClipId())); +} + +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(KUrl(), 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(), QString(), QString()); + m_clipManager->slotAddTextClipFile(i18n("Title clip"), dia_ui->duration(), dia_ui->xml().toString(), group, groupId); setModified(true); + emit selectLastAddedClip(QString::number(m_clipManager->lastClipId())); } delete dia_ui; } +void KdenliveDoc::slotCreateTextTemplateClip(QString group, const QString &groupId, KUrl path) +{ + 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; + + //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())); +} + int KdenliveDoc::tracksCount() const { return m_tracksList.count(); @@ -1109,6 +1159,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 @@ -1129,18 +1180,18 @@ 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) @@ -1153,13 +1204,23 @@ bool KdenliveDoc::checkDocumentClips(QDomNodeList infoproducers) for (int i = 0; i < infoproducers.count(); i++) { e = infoproducers.item(i).toElement(); clipType = e.attribute("type").toInt(); - if (clipType == TEXT || clipType == COLOR) continue; + 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; @@ -1167,6 +1228,15 @@ bool KdenliveDoc::checkDocumentClips(QDomNodeList infoproducers) return (d.exec() == QDialog::Accepted); } +void KdenliveDoc::setDocumentProperty(const QString &name, const QString &value) +{ + m_documentProperties[name] = value; +} + +const QString KdenliveDoc::getDocumentProperty(const QString &name) const +{ + return m_documentProperties.value(name); +} #include "kdenlivedoc.moc"