+ if (version <= 0.83) {
+ // Replace point size with pixel size in text titles
+ if (m_doc.toString().contains("font-size")) {
+ KMessageBox::ButtonCode convert = KMessageBox::Continue;
+ QDomNodeList kproducerNodes = m_doc.elementsByTagName("kdenlive_producer");
+ for (int i = 0; i < kproducerNodes.count() && convert != KMessageBox::No; ++i) {
+ QDomElement kproducer = kproducerNodes.at(i).toElement();
+ if (kproducer.attribute("type").toInt() == TEXT) {
+ QDomDocument data;
+ data.setContent(kproducer.attribute("xmldata"));
+ QDomNodeList items = data.firstChild().childNodes();
+ for (int j = 0; j < items.count() && convert != KMessageBox::No; ++j) {
+ if (items.at(j).attributes().namedItem("type").nodeValue() == "QGraphicsTextItem") {
+ QDomNamedNodeMap textProperties = items.at(j).namedItem("content").attributes();
+ if (textProperties.namedItem("font-pixel-size").isNull() && !textProperties.namedItem("font-size").isNull()) {
+ // Ask the user if he wants to convert
+ if (convert != KMessageBox::Yes && convert != KMessageBox::No)
+ convert = (KMessageBox::ButtonCode)KMessageBox::warningYesNo(kapp->activeWindow(), i18n("Some of your text clips were saved with size in points, which means different sizes on different displays. Do you want to convert them to pixel size, making them portable? It is recommended you do this on the computer they were first created on, or you could have to adjust their size."), i18n("Update Text Clips"));
+ if (convert == KMessageBox::Yes) {
+ QFont font;
+ font.setPointSize(textProperties.namedItem("font-size").nodeValue().toInt());
+ QDomElement content = items.at(j).namedItem("content").toElement();
+ content.setAttribute("font-pixel-size", QFontInfo(font).pixelSize());
+ content.removeAttribute("font-size");
+ kproducer.setAttribute("xmldata", data.toString());
+ /*
+ * You may be tempted to delete the preview file
+ * to force its recreation: bad idea (see
+ * http://www.kdenlive.org/mantis/view.php?id=749)
+ */
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Fill the <documentproperties /> element
+ QDomElement docProperties = infoXml.firstChildElement("documentproperties");
+ if (docProperties.isNull()) {
+ docProperties = m_doc.createElement("documentproperties");
+ docProperties.setAttribute("zonein", infoXml.attribute("zonein"));
+ docProperties.setAttribute("zoneout", infoXml.attribute("zoneout"));
+ docProperties.setAttribute("zoom", infoXml.attribute("zoom"));
+ docProperties.setAttribute("position", infoXml.attribute("position"));
+ infoXml.appendChild(docProperties);
+ }
+ }
+
+ if (version <= 0.84) {
+ // update the title clips to use the new MLT kdenlivetitle producer
+ QDomNodeList kproducerNodes = m_doc.elementsByTagName("kdenlive_producer");
+ for (int i = 0; i < kproducerNodes.count(); ++i) {
+ QDomElement kproducer = kproducerNodes.at(i).toElement();
+ if (kproducer.attribute("type").toInt() == TEXT) {
+ QString data = kproducer.attribute("xmldata");
+ QString datafile = kproducer.attribute("resource");
+ if (!datafile.endsWith(".kdenlivetitle")) {
+ datafile = QString();
+ kproducer.setAttribute("resource", QString());
+ }
+ QString id = kproducer.attribute("id");
+ QDomNodeList mltproducers = m_doc.elementsByTagName("producer");
+ bool foundData = false;
+ bool foundResource = false;
+ bool foundService = false;
+ for (int j = 0; j < mltproducers.count(); j++) {
+ QDomElement wproducer = mltproducers.at(j).toElement();
+ if (wproducer.attribute("id") == id) {
+ QDomNodeList props = wproducer.childNodes();
+ for (int k = 0; k < props.count(); k++) {
+ if (props.at(k).toElement().attribute("name") == "xmldata") {
+ props.at(k).firstChild().setNodeValue(data);
+ foundData = true;
+ } else if (props.at(k).toElement().attribute("name") == "mlt_service") {
+ props.at(k).firstChild().setNodeValue("kdenlivetitle");
+ foundService = true;
+ } else if (props.at(k).toElement().attribute("name") == "resource") {
+ props.at(k).firstChild().setNodeValue(datafile);
+ foundResource = true;
+ }
+ }
+ if (!foundData) {
+ QDomElement e = m_doc.createElement("property");
+ e.setAttribute("name", "xmldata");
+ QDomText value = m_doc.createTextNode(data);
+ e.appendChild(value);
+ wproducer.appendChild(e);
+ }
+ if (!foundService) {
+ QDomElement e = m_doc.createElement("property");
+ e.setAttribute("name", "mlt_service");
+ QDomText value = m_doc.createTextNode("kdenlivetitle");
+ e.appendChild(value);
+ wproducer.appendChild(e);
+ }
+ if (!foundResource) {
+ QDomElement e = m_doc.createElement("property");
+ e.setAttribute("name", "resource");
+ QDomText value = m_doc.createTextNode(datafile);
+ e.appendChild(value);
+ wproducer.appendChild(e);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (version <= 0.85) {
+ // update the LADSPA effects to use the new ladspa.id format instead of external xml file
+ QDomNodeList effectNodes = m_doc.elementsByTagName("filter");
+ for (int i = 0; i < effectNodes.count(); ++i) {
+ QDomElement effect = effectNodes.at(i).toElement();
+ if (EffectsList::property(effect, "mlt_service") == "ladspa") {
+ // Needs to be converted
+ QStringList info = getInfoFromEffectName(EffectsList::property(effect, "kdenlive_id"));
+ if (info.isEmpty()) continue;
+ // info contains the correct ladspa.id from kdenlive effect name, and a list of parameter's old and new names
+ EffectsList::setProperty(effect, "kdenlive_id", info.at(0));
+ EffectsList::setProperty(effect, "tag", info.at(0));
+ EffectsList::setProperty(effect, "mlt_service", info.at(0));
+ EffectsList::removeProperty(effect, "src");
+ for (int j = 1; j < info.size(); j++) {
+ QString value = EffectsList::property(effect, info.at(j).section('=', 0, 0));
+ if (!value.isEmpty()) {
+ // update parameter name
+ EffectsList::renameProperty(effect, info.at(j).section('=', 0, 0), info.at(j).section('=', 1, 1));
+ }
+ }
+ }
+ }
+ }
+
+ if (version <= 0.86) {
+ // Make sure we don't have avformat-novalidate producers, since it caused crashes
+ QDomNodeList producers = m_doc.elementsByTagName("producer");
+ int max = producers.count();
+ for (int i = 0; i < max; ++i) {
+ QDomElement prod = producers.at(i).toElement();
+ if (EffectsList::property(prod, "mlt_service") == "avformat-novalidate")
+ EffectsList::setProperty(prod, "mlt_service", "avformat");
+ }
+
+ // There was a mistake in Geometry transitions where the last keyframe was created one frame after the end of transition, so fix it and move last keyframe to real end of transition
+
+ // Get profile info (width / height)
+ int profileWidth;
+ int profileHeight;
+ QDomElement profile = m_doc.firstChildElement("profile");
+ if (profile.isNull()) profile = infoXml.firstChildElement("profileinfo");
+ if (profile.isNull()) {
+ // could not find profile info, set PAL
+ profileWidth = 720;
+ profileHeight = 576;
+ }
+ else {
+ profileWidth = profile.attribute("width").toInt();
+ profileHeight = profile.attribute("height").toInt();
+ }
+ QDomNodeList transitions = m_doc.elementsByTagName("transition");
+ max = transitions.count();
+ int out;
+ for (int i = 0; i < max; ++i) {
+ QDomElement trans = transitions.at(i).toElement();
+ out = trans.attribute("out").toInt() - trans.attribute("in").toInt();
+ QString geom = EffectsList::property(trans, "geometry");
+ Mlt::Geometry *g = new Mlt::Geometry(geom.toUtf8().data(), out, profileWidth, profileHeight);
+ Mlt::GeometryItem item;
+ if (g->next_key(&item, out) == 0) {
+ // We have a keyframe just after last frame, try to move it to last frame
+ if (item.frame() == out + 1) {
+ item.frame(out);
+ g->insert(item);
+ g->remove(out + 1);
+ EffectsList::setProperty(trans, "geometry", g->serialise());
+ }
+ }
+ delete g;
+ }
+ }
+
+ if (version <= 0.87) {
+ if (!m_doc.firstChildElement("mlt").hasAttribute("LC_NUMERIC")) {
+ m_doc.firstChildElement("mlt").setAttribute("LC_NUMERIC", "C");
+ }
+ }
+