+QDomDocument initEffects::createDescriptionFromMlt(Mlt::Repository* repository, const QString& /*type*/, const QString& filtername)
+{
+
+ QDomDocument ret;
+ Mlt::Properties *metadata = repository->metadata(filter_type, filtername.toAscii().data());
+ //kDebug() << filtername;
+ if (metadata && metadata->is_valid()) {
+ if (metadata->get("title") && metadata->get("identifier")) {
+ QDomElement eff = ret.createElement("effect");
+ eff.setAttribute("tag", metadata->get("identifier"));
+ eff.setAttribute("id", metadata->get("identifier"));
+
+ QDomElement name = ret.createElement("name");
+ name.appendChild(ret.createTextNode(metadata->get("title")));
+
+ QDomElement desc = ret.createElement("description");
+ desc.appendChild(ret.createTextNode(metadata->get("description")));
+
+ QDomElement author = ret.createElement("author");
+ author.appendChild(ret.createTextNode(metadata->get("creator")));
+
+ eff.appendChild(name);
+ eff.appendChild(author);
+ eff.appendChild(desc);
+
+ Mlt::Properties param_props((mlt_properties) metadata->get_data("parameters"));
+ for (int j = 0; param_props.is_valid() && j < param_props.count(); j++) {
+ QDomElement params = ret.createElement("parameter");
+
+ Mlt::Properties paramdesc((mlt_properties) param_props.get_data(param_props.get_name(j)));
+
+ params.setAttribute("name", paramdesc.get("identifier"));
+
+ if (paramdesc.get("maximum")) params.setAttribute("max", paramdesc.get("maximum"));
+ if (paramdesc.get("minimum")) params.setAttribute("min", paramdesc.get("minimum"));
+ if (QString(paramdesc.get("type")) == "integer")
+ params.setAttribute("type", "constant");
+ if (QString(paramdesc.get("type")) == "float") {
+ params.setAttribute("type", "constant");
+ params.setAttribute("factor", "1000");
+ if (paramdesc.get("maximum")) params.setAttribute("max", QString(paramdesc.get("maximum")).toFloat()*1000.0);
+ if (paramdesc.get("minimum")) params.setAttribute("min", QString(paramdesc.get("minimum")).toFloat()*1000.0);
+ }
+ if (QString(paramdesc.get("type")) == "boolean")
+ params.setAttribute("type", "bool");
+ if (!QString(paramdesc.get("format")).isEmpty() && QString(paramdesc.get("type")) != "geometry") {
+ params.setAttribute("type", "geometry");
+ params.setAttribute("format", paramdesc.get("format"));
+ }
+ if (!QString(paramdesc.get("format")).isEmpty() && QString(paramdesc.get("type")) == "geometry") {
+ params.setAttribute("type", "geometry");
+ //params.setAttribute("format", paramdesc.get("format"));
+ }
+ if (paramdesc.get("default")) params.setAttribute("default", paramdesc.get("default"));
+ if (paramdesc.get("value")) {
+ params.setAttribute("value", paramdesc.get("value"));
+ } else {
+ params.setAttribute("value", paramdesc.get("default"));
+ }
+
+
+ QDomElement pname = ret.createElement("name");
+ pname.appendChild(ret.createTextNode(paramdesc.get("title")));
+ params.appendChild(pname);
+
+ eff.appendChild(params);
+ }
+ ret.appendChild(eff);
+ }
+ }
+ delete metadata;
+ metadata = 0;
+ /* QString outstr;
+ QTextStream str(&outstr);
+ ret.save(str, 2);
+ kDebug() << outstr;*/
+ return ret;
+}
+
+void initEffects::fillTransitionsList(Mlt::Repository *repository, EffectsList *transitions, QStringList names)
+{
+ // Remove transitions that are not implemented.
+ int pos = names.indexOf("mix");
+ if (pos != -1)
+ names.takeAt(pos);
+
+ QStringList imagenamelist = QStringList() << i18n("None");
+ QStringList imagefiles = QStringList() << QString();
+ QStringList filters;
+ filters << "*.pgm" << "*.png";
+ QStringList customLumas = KGlobal::dirs()->findDirs("appdata", "lumas");
+ foreach(QString folder, customLumas) {
+ if (!folder.endsWith('/'))
+ folder.append('/');
+ QStringList filesnames = QDir(folder).entryList(filters, QDir::Files);
+ foreach(const QString &fname, filesnames) {
+ imagenamelist.append(fname);
+ imagefiles.append(folder + fname);
+ }
+ }
+
+ // Check for MLT luma files.
+ KUrl folder(mlt_environment("MLT_DATA"));
+ folder.addPath("lumas");
+ folder.addPath(mlt_environment("MLT_NORMALISATION"));
+ QDir lumafolder(folder.path());
+ QStringList filesnames = lumafolder.entryList(filters, QDir::Files);
+ foreach(const QString &fname, filesnames) {
+ imagenamelist.append(fname);
+ KUrl path(folder);
+ path.addPath(fname);
+ imagefiles.append(path.toLocalFile());
+ }
+
+ foreach(const QString &name, names) {
+ QDomDocument ret;
+ QDomElement ktrans = ret.createElement("ktransition");
+ ret.appendChild(ktrans);
+ ktrans.setAttribute("tag", name);
+
+ QDomElement tname = ret.createElement("name");
+ QDomElement desc = ret.createElement("description");
+ ktrans.appendChild(tname);
+ ktrans.appendChild(desc);
+ Mlt::Properties *metadata = repository->metadata(transition_type, name.toUtf8().data());
+ if (metadata && metadata->is_valid()) {
+ // If possible, set name and description.
+ if (metadata->get("title") && metadata->get("identifier"))
+ tname.appendChild(ret.createTextNode(metadata->get("title")));
+ desc.appendChild(ret.createTextNode(metadata->get("description")));
+
+ Mlt::Properties param_props((mlt_properties) metadata->get_data("parameters"));
+ for (int i = 0; param_props.is_valid() && i < param_props.count(); ++i) {
+ QDomElement params = ret.createElement("parameter");
+
+ Mlt::Properties paramdesc((mlt_properties) param_props.get_data(param_props.get_name(i)));
+
+ params.setAttribute("name", paramdesc.get("identifier"));
+
+ if (paramdesc.get("maximum"))
+ params.setAttribute("max", paramdesc.get("maximum"));
+ if (paramdesc.get("minimum"))
+ params.setAttribute("min", paramdesc.get("minimum"));
+ if (QString(paramdesc.get("type")) == "integer") {
+ params.setAttribute("type", "constant");
+ params.setAttribute("factor", "100");
+ }
+ if (QString(paramdesc.get("type")) == "boolean")
+ params.setAttribute("type", "bool");
+ if (!QString(paramdesc.get("format")).isEmpty()) {
+ params.setAttribute("type", "complex");
+ params.setAttribute("format", paramdesc.get("format"));
+ }
+ if (paramdesc.get("default"))
+ params.setAttribute("default", paramdesc.get("default"));
+ if (paramdesc.get("value"))
+ params.setAttribute("value", paramdesc.get("value"));
+ else
+ params.setAttribute("value", paramdesc.get("default"));
+
+ QDomElement pname = ret.createElement("name");
+ pname.appendChild(ret.createTextNode(paramdesc.get("title")));
+ params.appendChild(pname);
+ ktrans.appendChild(params);
+ }
+ delete metadata;
+ metadata = 0;
+ } else {
+ /*
+ * Check for Kdenlive installed luma files, add empty string at
+ * start for no luma file.
+ */
+
+ // Implement default transitions.
+ QList<QDomElement> paramList;
+ if (name == "luma") {
+ ktrans.setAttribute("id", name);
+ tname.appendChild(ret.createTextNode(i18n("Wipe")));
+ desc.appendChild(ret.createTextNode(i18n("Applies a stationary transition between the current and next frames.")));
+
+ paramList.append(quickParameterFill(ret, i18n("Softness"), "softness", "double", "0", "0", "100", "", "", "100"));
+ paramList.append(quickParameterFill(ret, i18n("Invert"), "invert", "bool", "0", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Image File"), "resource", "list", "", "", "", imagefiles.join(","), imagenamelist.join(",")));
+ paramList.append(quickParameterFill(ret, i18n("Reverse Transition"), "reverse", "bool", "0", "0", "1"));
+ //thumbnailer.prepareThumbnailsCall(imagelist);
+ } else if (name == "composite") {
+ ktrans.setAttribute("id", name);
+ tname.appendChild(ret.createTextNode(i18n("Composite")));
+ desc.appendChild(ret.createTextNode(i18n("A key-framable alpha-channel compositor for two frames.")));
+ paramList.append(quickParameterFill(ret, i18n("Geometry"), "geometry", "geometry", "0%,0%:100%x100%:100", "-500;-500;-500;-500;0", "500;500;500;500;100"));
+ paramList.append(quickParameterFill(ret, i18n("Alpha Channel Operation"), "operator", "list", "over", "", "", "over,and,or,xor", "over,and,or,xor"));
+ paramList.append(quickParameterFill(ret, i18n("Align"), "aligned", "bool", "1", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Fill"), "fill", "bool", "1", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Distort"), "distort", "bool", "0", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Wipe File"), "luma", "list", "", "", "", imagefiles.join(","), imagenamelist.join(",")));
+ paramList.append(quickParameterFill(ret, i18n("Wipe Softness"), "softness", "double", "0", "0", "100", "", "", "100"));
+ paramList.append(quickParameterFill(ret, i18n("Wipe Invert"), "luma_invert", "bool", "0", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Force Progressive Rendering"), "progressive", "bool", "1", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Force Deinterlace Overlay"), "deinterlace", "bool", "0", "0", "1"));
+ } else if (name == "affine") {
+ tname.appendChild(ret.createTextNode(i18n("Affine")));
+ paramList.append(quickParameterFill(ret, i18n("Rotate Y"), "rotate_y", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Rotate X"), "rotate_x", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Rotate Z"), "rotate_z", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Fix Rotate Y"), "fix_rotate_y", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Fix Rotate X"), "fix_rotate_x", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Fix Rotate Z"), "fix_rotate_z", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Shear Y"), "shear_y", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Shear X"), "shear_x", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Shear Z"), "shear_z", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Fix Shear Y"), "fix_shear_y", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Fix Shear X"), "fix_shear_x", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Fix Shear Z"), "fix_shear_z", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Geometry"), "geometry", "geometry", "0,0,100%,100%,100%", "0,0,100%,100%,100%", "0,0,100%,100%,100%", "", "", "", "", "", "false"));
+ } else if (name == "mix") {
+ tname.appendChild(ret.createTextNode(i18n("Mix")));
+ } else if (name == "region") {
+ ktrans.setAttribute("id", name);
+ tname.appendChild(ret.createTextNode(i18n("Region")));
+ desc.appendChild(ret.createTextNode(i18n("Use alpha channel of another clip to create a transition.")));
+ paramList.append(quickParameterFill(ret, i18n("Transparency clip"), "resource", "url", "", "", "", "", "", ""));
+ paramList.append(quickParameterFill(ret, i18n("Geometry"), "composite.geometry", "geometry", "0%,0%:100%x100%:100", "-500;-500;-500;-500;0", "500;500;500;500;100"));
+ paramList.append(quickParameterFill(ret, i18n("Alpha Channel Operation"), "composite.operator", "list", "over", "", "", "over,and,or,xor", "over,and,or,xor"));
+ paramList.append(quickParameterFill(ret, i18n("Align"), "composite.aligned", "bool", "1", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Fill"), "composite.fill", "bool", "1", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Distort"), "composite.distort", "bool", "0", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Wipe File"), "composite.luma", "list", "", "", "", imagefiles.join(","), imagenamelist.join(",")));
+ paramList.append(quickParameterFill(ret, i18n("Wipe Softness"), "composite.softness", "double", "0", "0", "100", "", "", "100"));
+ paramList.append(quickParameterFill(ret, i18n("Wipe Invert"), "composite.luma_invert", "bool", "0", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Force Progressive Rendering"), "composite.progressive", "bool", "1", "0", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Force Deinterlace Overlay"), "composite.deinterlace", "bool", "0", "0", "1"));
+ }
+ foreach(const QDomElement &e, paramList)
+ ktrans.appendChild(e);
+ }
+
+ // Add the transition to the global list.
+ transitions->append(ret.documentElement());
+ //kDebug() << ret.toString();
+ }
+
+ // Add some virtual transitions.
+ QString slidetrans = "<ktransition tag=\"composite\" id=\"slide\"><name>" + i18n("Slide") + "</name><description>" + i18n("Slide image from one side to another.") + "</description><parameter tag=\"geometry\" type=\"wipe\" default=\"-100%,0%:100%x100%;-1=0%,0%:100%x100%\" name=\"geometry\"><name>" + i18n("Direction") + "</name> </parameter><parameter tag=\"aligned\" default=\"0\" type=\"bool\" name=\"aligned\" ><name>" + i18n("Align") + "</name></parameter><parameter tag=\"progressive\" default=\"1\" type=\"bool\" name=\"progressive\" ><name>" + i18n("Force Progressive Rendering") + "</name></parameter><parameter tag=\"deinterlace\" default=\"0\" type=\"bool\" name=\"deinterlace\" ><name>" + i18n("Force Deinterlace Overlay") + "</name></parameter><parameter tag=\"invert\" default=\"0\" type=\"bool\" name=\"invert\" ><name>" + i18n("Invert") + "</name></parameter></ktransition>";
+ QDomDocument ret;
+ ret.setContent(slidetrans);
+ transitions->append(ret.documentElement());
+
+ QString dissolve = "<ktransition tag=\"luma\" id=\"dissolve\"><name>" + i18n("Dissolve") + "</name><description>" + i18n("Fade out one video while fading in the other video.") + "</description><parameter tag=\"reverse\" default=\"0\" type=\"bool\" name=\"reverse\" ><name>" + i18n("Reverse") + "</name></parameter></ktransition>";
+ ret.setContent(dissolve);
+ transitions->append(ret.documentElement());