From 11a50a78e6d3c8bc7e1d189ec01233c4a33b7387 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Wed, 13 Oct 2010 23:02:25 +0000 Subject: [PATCH] When adding an existing kdenlive title clip to the project , detach embedded images: http://kdenlive.org/mantis/view.php?id=1841 svn path=/trunk/kdenlive/; revision=4992 --- src/clipmanager.cpp | 35 +++++++++---- src/titledocument.cpp | 112 ++++++++++++++++++++++-------------------- src/titledocument.h | 8 +-- 3 files changed, 89 insertions(+), 66 deletions(-) diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp index dd9ffb7d..6b464814 100644 --- a/src/clipmanager.cpp +++ b/src/clipmanager.cpp @@ -25,6 +25,7 @@ #include "kdenlivedoc.h" #include "abstractclipitem.h" #include "abstractgroupitem.h" +#include "titledocument.h" #include @@ -39,10 +40,10 @@ #include ClipManager::ClipManager(KdenliveDoc *doc) : - QObject(), - m_audioThumbsQueue(), - m_doc(doc), - m_generatingAudioId() + QObject(), + m_audioThumbsQueue(), + m_doc(doc), + m_generatingAudioId() { m_clipIdCounter = 1; m_folderIdCounter = 1; @@ -272,7 +273,7 @@ void ClipManager::slotAddClipList(const KUrl::List urls, const QString group, co { QUndoCommand *addClips = new QUndoCommand(); - foreach(const KUrl &file, urls) { + foreach(const KUrl & file, urls) { if (KIO::NetAccess::exists(file, KIO::NetAccess::SourceSide, NULL)) { if (!getClipByResource(file.path()).empty()) { if (KMessageBox::warningContinueCancel(kapp->activeWindow(), i18n("Clip %1
already exists in project, what do you want to do?", file.path()), i18n("Clip already exists")) == KMessageBox::Cancel) @@ -298,7 +299,7 @@ void ClipManager::slotAddClipList(const KUrl::List urls, const QString group, co if (type->is("image/jpeg")) { KFileMetaInfo metaInfo(file.path(), QString("image/jpeg"), KFileMetaInfo::TechnicalInfo); const QHash metaInfoItems = metaInfo.items(); - foreach(const KFileMetaInfoItem& metaInfoItem, metaInfoItems) { + foreach(const KFileMetaInfoItem & metaInfoItem, metaInfoItems) { prod.setAttribute("meta.attr." + metaInfoItem.name().section("#", 1), metaInfoItem.value().toString()); } } @@ -309,7 +310,21 @@ void ClipManager::slotAddClipList(const KUrl::List urls, const QString group, co if (txtfile.open(QIODevice::ReadOnly) && txtdoc.setContent(&txtfile)) { txtfile.close(); prod.setAttribute("type", (int) TEXT); - prod.setAttribute("xmldata", txtdoc.toString()); + // extract embeded images + QDomNodeList items = txtdoc.elementsByTagName("content"); + for (int i = 0; i < items.count() ; i++) { + QDomElement content = items.item(i).toElement(); + if (content.hasAttribute("base64")) { + QString titlesFolder = m_doc->projectFolder().path(KUrl::AddTrailingSlash) + "titles/"; + QString path = TitleDocument::extractBase64Image(titlesFolder, content.attribute("base64")); + if (!path.isEmpty()) { + content.setAttribute("url", path); + content.removeAttribute("base64"); + } + } + } + QString titleData = txtdoc.toString(); + prod.setAttribute("xmldata", titleData); prod.setAttribute("transparency", 1); prod.setAttribute("in", 0); int out = txtdoc.documentElement().attribute("out").toInt(); @@ -373,9 +388,9 @@ void ClipManager::slotAddColorClipFile(const QString name, const QString color, } void ClipManager::slotAddSlideshowClipFile(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) + 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) { QDomDocument doc; QDomElement prod = doc.createElement("producer"); diff --git a/src/titledocument.cpp b/src/titledocument.cpp index e41abc27..8c360d7d 100644 --- a/src/titledocument.cpp +++ b/src/titledocument.cpp @@ -47,9 +47,8 @@ QByteArray fileToByteArray(const QString& filename) { QByteArray ret; QFile file(filename); - if (file.open(QIODevice::ReadOnly)) - { - while (!file.atEnd()){ + if (file.open(QIODevice::ReadOnly)) { + while (!file.atEnd()) { ret.append(file.readLine()); } } @@ -70,43 +69,50 @@ void TitleDocument::setScene(QGraphicsScene* _scene, int width, int height) int TitleDocument::base64ToUrl(QGraphicsItem* item, QDomElement& content, bool embed) { - if (embed) - { - if (!item->data(Qt::UserRole+1).toString().isEmpty()) - { - content.setAttribute("base64",item->data(Qt::UserRole+1).toString()); - } else if (!item->data(Qt::UserRole).toString().isEmpty() ) - { - content.setAttribute("base64",fileToByteArray( item->data(Qt::UserRole).toString() ).toBase64().data()); - } - content.removeAttribute("url"); - }else{ - // save for project files to disk - QString base64=item->data(Qt::UserRole+1).toString(); - if (!base64.isEmpty()){ - QString titlePath; - if (!m_projectPath.isEmpty()) - { - titlePath=m_projectPath; - }else{ - titlePath="/tmp/titles"; - } - QString filename=titlePath+QString( QCryptographicHash::hash(base64.toAscii(), QCryptographicHash::Md5).toHex().append(".titlepart")); - KStandardDirs::makeDir(titlePath); - QFile f(filename); - if (f.open(QIODevice::WriteOnly)){ - f.write(QByteArray::fromBase64(base64.toAscii()) ) ; - f.close(); - content.setAttribute("url",filename); - content.removeAttribute("base64"); - } - - } else { - return 1; - } + if (embed) { + if (!item->data(Qt::UserRole + 1).toString().isEmpty()) { + content.setAttribute("base64", item->data(Qt::UserRole + 1).toString()); + } else if (!item->data(Qt::UserRole).toString().isEmpty()) { + content.setAttribute("base64", fileToByteArray(item->data(Qt::UserRole).toString()).toBase64().data()); + } + content.removeAttribute("url"); + } else { + // save for project files to disk + QString base64 = item->data(Qt::UserRole + 1).toString(); + if (!base64.isEmpty()) { + QString titlePath; + if (!m_projectPath.isEmpty()) { + titlePath = m_projectPath; + } else { + titlePath = "/tmp/titles"; } - return 0; -} + QString filename = extractBase64Image(titlePath, base64); + if (!filename.isEmpty()) { + content.setAttribute("url", filename); + content.removeAttribute("base64"); + } + + } else { + return 1; + } + } + return 0; +} + + +//static +const QString TitleDocument::extractBase64Image(const QString &titlePath, const QString &data) +{ + QString filename = titlePath + QString(QCryptographicHash::hash(data.toAscii(), QCryptographicHash::Md5).toHex().append(".titlepart")); + KStandardDirs::makeDir(titlePath); + QFile f(filename); + if (f.open(QIODevice::WriteOnly)) { + f.write(QByteArray::fromBase64(data.toAscii())) ; + f.close(); + return filename; + } + return QString(); +} QDomDocument TitleDocument::xml(QGraphicsRectItem* startv, QGraphicsRectItem* endv, bool embed) { @@ -117,7 +123,7 @@ QDomDocument TitleDocument::xml(QGraphicsRectItem* startv, QGraphicsRectItem* en main.setAttribute("height", m_height); doc.appendChild(main); - foreach(QGraphicsItem* item, m_scene->items()) { + foreach(QGraphicsItem * item, m_scene->items()) { QDomElement e = doc.createElement("item"); QDomElement content = doc.createElement("content"); QFont font; @@ -127,12 +133,12 @@ QDomDocument TitleDocument::xml(QGraphicsRectItem* startv, QGraphicsRectItem* en case 7: e.setAttribute("type", "QGraphicsPixmapItem"); content.setAttribute("url", item->data(Qt::UserRole).toString()); - base64ToUrl (item, content, embed ); + base64ToUrl(item, content, embed); break; case 13: e.setAttribute("type", "QGraphicsSvgItem"); content.setAttribute("url", item->data(Qt::UserRole).toString()); - base64ToUrl (item, content, embed ); + base64ToUrl(item, content, embed); break; case 3: e.setAttribute("type", "QGraphicsRectItem"); @@ -292,7 +298,7 @@ bool TitleDocument::saveDocument(const KUrl& url, QGraphicsRectItem* startv, QGr int TitleDocument::loadFromXml(QDomDocument doc, QGraphicsRectItem* startv, QGraphicsRectItem* endv, int *out, const QString& projectpath) { - m_projectPath=projectpath; + m_projectPath = projectpath; QDomNodeList titles = doc.elementsByTagName("kdenlivetitle"); //TODO: Check if the opened title size is equal to project size, otherwise warn user and rescale if (doc.documentElement().hasAttribute("width") && doc.documentElement().hasAttribute("height")) { @@ -408,35 +414,35 @@ int TitleDocument::loadFromXml(QDomDocument doc, QGraphicsRectItem* startv, QGra QString url = items.item(i).namedItem("content").attributes().namedItem("url").nodeValue(); QString base64 = items.item(i).namedItem("content").attributes().namedItem("base64").nodeValue(); QPixmap pix; - if (base64.isEmpty()){ + if (base64.isEmpty()) { pix.load(url); - }else{ + } else { pix.loadFromData(QByteArray::fromBase64(base64.toAscii())); } QGraphicsPixmapItem *rec = m_scene->addPixmap(pix); rec->setData(Qt::UserRole, url); - if (!base64.isEmpty()){ - rec->setData(Qt::UserRole+1, base64); + if (!base64.isEmpty()) { + rec->setData(Qt::UserRole + 1, base64); } gitem = rec; } else if (items.item(i).attributes().namedItem("type").nodeValue() == "QGraphicsSvgItem") { QString url = items.item(i).namedItem("content").attributes().namedItem("url").nodeValue(); QString base64 = items.item(i).namedItem("content").attributes().namedItem("base64").nodeValue(); QGraphicsSvgItem *rec = NULL; - if (base64.isEmpty()){ + if (base64.isEmpty()) { rec = new QGraphicsSvgItem(url); - }else{ + } else { rec = new QGraphicsSvgItem(); - QSvgRenderer *renderer= new QSvgRenderer(QByteArray::fromBase64(base64.toAscii()), rec ); + QSvgRenderer *renderer = new QSvgRenderer(QByteArray::fromBase64(base64.toAscii()), rec); rec->setSharedRenderer(renderer); //QString elem=rec->elementId(); //QRectF bounds = renderer->boundsOnElement(elem); } - if (rec){ + if (rec) { m_scene->addItem(rec); rec->setData(Qt::UserRole, url); - if (!base64.isEmpty()){ - rec->setData(Qt::UserRole+1, base64); + if (!base64.isEmpty()) { + rec->setData(Qt::UserRole + 1, base64); } gitem = rec; } diff --git a/src/titledocument.h b/src/titledocument.h index ca5e92bc..a00c8b7d 100644 --- a/src/titledocument.h +++ b/src/titledocument.h @@ -34,14 +34,16 @@ class TitleDocument public: TitleDocument(); void setScene(QGraphicsScene* scene, int width, int height); - bool saveDocument(const KUrl& url, QGraphicsRectItem* startv, QGraphicsRectItem* endv, int out, bool embed_images = false ); - QDomDocument xml(QGraphicsRectItem* startv, QGraphicsRectItem* endv, bool embed_images = false ); - int loadFromXml(QDomDocument doc, QGraphicsRectItem* startv, QGraphicsRectItem* endv, int *out,const QString& projectpath=""); + bool saveDocument(const KUrl& url, QGraphicsRectItem* startv, QGraphicsRectItem* endv, int out, bool embed_images = false); + QDomDocument xml(QGraphicsRectItem* startv, QGraphicsRectItem* endv, bool embed_images = false); + int loadFromXml(QDomDocument doc, QGraphicsRectItem* startv, QGraphicsRectItem* endv, int *out, const QString& projectpath = ""); /** \brief Get the background color (incl. alpha) from the document, if possibly * \returns The background color of the document, inclusive alpha. If none found, returns (0,0,0,0) */ QColor getBackgroundColor(); int frameWidth() const; int frameHeight() const; + /** \brief Extract embeded images in project titles folder. */ + static const QString extractBase64Image(const QString &titlePath, const QString &data); enum ItemOrigin {OriginXLeft = 0, OriginYTop = 1}; enum AxisPosition {AxisDefault = 0, AxisInverted = 1}; -- 2.39.2