X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fdocclipbase.cpp;h=938cdb7eac00f470c70ddaef524eac27a1cb3572;hb=3b8469402b87f4af7176e470536364f25af63618;hp=5f2f01a19d8a27248dcc4cc89b9e95e9d742c6c7;hpb=71e41ad0c197e2e2eb033dff7800427f64d3428f;p=kdenlive diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index 5f2f01a1..938cdb7e 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -32,12 +32,14 @@ #include #include +#include #include #include #include #include +#include DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QString &id) : QObject(), @@ -62,10 +64,16 @@ DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QStrin for (int i = 0; i < attributes.count(); i++) { QString name = attributes.item(i).nodeName(); if (name.startsWith("meta.attr.")) { - m_metadata.insert(name.section('.', 2, 3), attributes.item(i).nodeValue()); + m_metadata.insert(name.section('.', 2), QStringList() << attributes.item(i).nodeValue()); } else m_properties.insert(name, attributes.item(i).nodeValue()); } - + QDomNodeList metas = xml.elementsByTagName("metaproperty"); + for (int i = 0; i < metas.count(); i++) { + QDomElement e = metas.item(i).toElement(); + if (!e.isNull()) { + m_metadata.insert(e.attribute("name").section('.', 2), QStringList() << e.firstChild().nodeValue() << e.attribute("tool")); + } + } if (xml.hasAttribute("cutzones")) { QStringList cuts = xml.attribute("cutzones").split(';', QString::SkipEmptyParts); for (int i = 0; i < cuts.count(); i++) { @@ -88,7 +96,7 @@ DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QStrin } else { int out = xml.attribute("out").toInt(); int in = xml.attribute("in").toInt(); - setDuration(GenTime(out - in, KdenliveSettings::project_fps())); + if (out > in) setDuration(GenTime(out - in + 1, KdenliveSettings::project_fps())); } if (!m_properties.contains("name")) m_properties.insert("name", url.fileName()); @@ -253,6 +261,21 @@ QDomElement DocClipBase::toXML(bool hideTemporaryProperties) const if (hideTemporaryProperties && i.key().startsWith('_')) continue; if (!i.value().isEmpty()) clip.setAttribute(i.key(), i.value()); } + + QMapIterator j(m_metadata); + // Metadata name can have special chars so we cannot pass it as simple attribute + while (j.hasNext()) { + j.next(); + if (!j.value().isEmpty()) { + QDomElement property = doc.createElement("metaproperty"); + property.setAttribute("name", "meta.attr." + j.key()); + QStringList values = j.value(); + QDomText value = doc.createTextNode(values.at(0)); + if (values.count() > 1) property.setAttribute("tool", values.at(1)); + property.appendChild(value); + clip.appendChild(property); + } + } doc.appendChild(clip); if (!m_cutZones.isEmpty()) { QStringList cuts; @@ -276,6 +299,57 @@ QDomElement DocClipBase::toXML(bool hideTemporaryProperties) const return doc.documentElement(); } +const QString DocClipBase::shortInfo() const +{ + + QString info; + if (m_clipType == AV || m_clipType == VIDEO || m_clipType == IMAGE || m_clipType == PLAYLIST) { + info = m_properties.value("frame_size") + " "; + if (m_properties.contains("fps")) { + info.append(i18n("%1 fps", m_properties.value("fps").left(5))); + } + if (!info.simplified().isEmpty()) info.prepend(" - "); + } + else if (m_clipType == AUDIO) { + info = " - " + m_properties.value("frequency") + i18n("Hz"); + } + QString tip = ""; + switch (m_clipType) { + case AUDIO: + tip.append(i18n("Audio clip") + "" + info + "
" + fileURL().path()); + break; + case VIDEO: + tip.append(i18n("Mute video clip") + "" + info + "
" + fileURL().path()); + break; + case AV: + tip.append(i18n("Video clip") + "" + info + "
" + fileURL().path()); + break; + case COLOR: + tip.append(i18n("Color clip")); + break; + case IMAGE: + tip.append(i18n("Image clip") + "" + info + "
" + fileURL().path()); + break; + case TEXT: + if (!fileURL().isEmpty() && getProperty("xmldata").isEmpty()) tip.append(i18n("Template text clip") + "
" + fileURL().path()); + else tip.append(i18n("Text clip") + "
" + fileURL().path()); + break; + case SLIDESHOW: + tip.append(i18n("Slideshow clip") + "
" + fileURL().directory()); + break; + case VIRTUAL: + tip.append(i18n("Virtual clip")); + break; + case PLAYLIST: + tip.append(i18n("Playlist clip") + "" + info + "
" + fileURL().path()); + break; + default: + tip.append(i18n("Unknown clip")); + break; + } + return tip; +} + void DocClipBase::setAudioThumbCreated(bool isDone) { @@ -293,7 +367,6 @@ void DocClipBase::updateAudioThumbnail(const audioByteArray& data) QList < GenTime > DocClipBase::snapMarkers() const { QList < GenTime > markers; - for (int count = 0; count < m_snapMarkers.count(); ++count) { markers.append(m_snapMarkers.at(count).time()); } @@ -975,7 +1048,7 @@ void DocClipBase::setProperties(QMap properties) if (refreshProducer) slotRefreshProducer(); } -void DocClipBase::setMetadata(QMap properties) +void DocClipBase::setMetadata(QMap properties, QString tool) { QMapIterator i(properties); while (i.hasNext()) { @@ -983,12 +1056,12 @@ void DocClipBase::setMetadata(QMap properties) if (i.value().isEmpty() && m_metadata.contains(i.key())) { m_metadata.remove(i.key()); } else { - m_metadata.insert(i.key(), i.value()); + m_metadata.insert(i.key(), QStringList() << i.value() << tool); } } } -QMap DocClipBase::metadata() const +QMap DocClipBase::metadata() const { return m_metadata; } @@ -1083,8 +1156,10 @@ void DocClipBase::setProperty(const QString &key, const QString &value) if (key == "resource") { getFileHash(value); if (m_thumbProd) m_thumbProd->updateClipUrl(KUrl(value), m_properties.value("file_hash")); - } else if (key == "out") setDuration(GenTime(value.toInt(), KdenliveSettings::project_fps())); //else if (key == "transparency") m_clipProducer->set("transparency", value.toInt()); + } else if (key == "out") { + setDuration(GenTime(value.toInt() + 1, KdenliveSettings::project_fps())); + } else if (key == "colour") { setProducerProperty("colour", value.toUtf8().data()); } else if (key == "templatetext") { @@ -1276,21 +1351,56 @@ QImage DocClipBase::extractImage(int frame, int width, int height) return m_thumbProd->extractImage(frame, width, height); } -void DocClipBase::setAnalysisData(const QString &name, const QString &data) +void DocClipBase::setAnalysisData(const QString &name, const QString &data, int offset) { if (data.isEmpty()) m_analysisdata.remove(name); else { if (m_analysisdata.contains(name)) { - int i = 1; - QString newname = name + " " + QString::number(i); - while (m_analysisdata.contains(newname)) { - i++; - newname = name + " " + QString::number(i); + if (KMessageBox::questionYesNo(kapp->activeWindow(), i18n("Clip already contains analysis data %1", name), QString(), KGuiItem(i18n("Merge")), KGuiItem(i18n("Add"))) == KMessageBox::Yes) { + // Merge data + Mlt::Profile *profile = m_baseTrackProducers.at(0)->profile(); + Mlt::Geometry geometry(m_analysisdata.value(name).toUtf8().data(), m_properties.value("duration").toInt(), profile->width(), profile->height()); + Mlt::Geometry newGeometry(data.toUtf8().data(), m_properties.value("duration").toInt(), profile->width(), profile->height()); + Mlt::GeometryItem item; + int pos = 0; + while (!newGeometry.next_key(&item, pos)) { + pos = item.frame(); + item.frame(pos + offset); + pos++; + geometry.insert(item); + } + m_analysisdata.insert(name, geometry.serialise()); + } + else { + // Add data with another name + int i = 1; + QString newname = name + " " + QString::number(i); + while (m_analysisdata.contains(newname)) { + i++; + newname = name + " " + QString::number(i); + } + m_analysisdata.insert(newname, geometryWithOffset(data, offset)); } - m_analysisdata.insert(newname, data); } - else m_analysisdata.insert(name, data); + else m_analysisdata.insert(name, geometryWithOffset(data, offset)); + } +} + +const QString DocClipBase::geometryWithOffset(QString data, int offset) +{ + if (offset == 0) return data; + Mlt::Profile *profile = m_baseTrackProducers.at(0)->profile(); + Mlt::Geometry geometry(data.toUtf8().data(), m_properties.value("duration").toInt(), profile->width(), profile->height()); + Mlt::Geometry newgeometry(NULL, m_properties.value("duration").toInt(), profile->width(), profile->height()); + Mlt::GeometryItem item; + int pos = 0; + while (!geometry.next_key(&item, pos)) { + pos = item.frame(); + item.frame(pos + offset); + pos++; + newgeometry.insert(item); } + return newgeometry.serialise(); } QMap DocClipBase::analysisData() const