]> git.sesse.net Git - kdenlive/blobdiff - src/trackview.cpp
Fix several title clips problems, including:
[kdenlive] / src / trackview.cpp
index 67cf01cd92c2581440b67401367a0787e62b0250..9d8f42b39389776d1692bb2ee3392ebd0b673464 100644 (file)
  ***************************************************************************/
 
 
-#include <QScrollBar>
-
-#include <KDebug>
-#include <KMessageBox>
-
+#include "trackview.h"
 #include "definitions.h"
 #include "headertrack.h"
-#include "trackview.h"
 #include "clipitem.h"
 #include "transition.h"
 #include "kdenlivesettings.h"
 #include "customtrackview.h"
 #include "initeffects.h"
 
-TrackView::TrackView(KdenliveDoc *doc, QWidget *parent)
-        : QWidget(parent), m_doc(doc), m_scale(1.0), m_projectTracks(0) {
+#include <KDebug>
+#include <KMessageBox>
+
+#include <QScrollBar>
+
+TrackView::TrackView(KdenliveDoc *doc, QWidget *parent) :
+        QWidget(parent),
+        m_scale(1.0),
+        m_projectTracks(0),
+        m_doc(doc)
+{
 
     view = new Ui::TimeLine_UI();
     view->setupUi(this);
@@ -90,39 +94,48 @@ TrackView::TrackView(KdenliveDoc *doc, QWidget *parent)
 }
 
 
-int TrackView::duration() const {
+int TrackView::duration() const
+{
     return m_trackview->duration();
 }
 
-int TrackView::tracksNumber() const {
+int TrackView::tracksNumber() const
+{
     return m_projectTracks - 1;
 }
 
-int TrackView::inPoint() const {
+int TrackView::inPoint() const
+{
     return m_ruler->inPoint();
 }
 
-int TrackView::outPoint() const {
+int TrackView::outPoint() const
+{
     return m_ruler->outPoint();
 }
 
-void TrackView::slotSetZone(QPoint p) {
+void TrackView::slotSetZone(QPoint p)
+{
     m_ruler->setZone(p);
 }
 
-void TrackView::slotTransitionItemSelected(Transition *t, bool update) {
+void TrackView::slotTransitionItemSelected(Transition *t, bool update)
+{
     emit transitionItemSelected(t, update);
 }
 
-void TrackView::setDuration(int dur) {
+void TrackView::setDuration(int dur)
+{
     m_trackview->setDuration(dur);
     m_ruler->setDuration(dur);
 }
 
-void TrackView::parseDocument(QDomDocument doc) {
-    int cursorPos = 0;
-    m_documentErrors = QString();
-    // kDebug() << "//// DOCUMENT: " << doc.toString();
+void TrackView::parseDocument(QDomDocument doc)
+{
+    //int cursorPos = 0;
+    m_documentErrors.clear();
+
+    //kDebug() << "//// DOCUMENT: " << doc.toString();
     /*QDomNode props = doc.elementsByTagName("properties").item(0);
     if (!props.isNull()) {
         cursorPos = props.toElement().attribute("timeline_position").toInt();
@@ -139,7 +152,40 @@ void TrackView::parseDocument(QDomDocument doc) {
     QDomElement p;
 
     int pos = m_projectTracks - 1;
-
+    m_invalidProducers.clear();
+    QDomNodeList producers = doc.elementsByTagName("producer");
+    for (int i = 0; i < producers.count(); i++) {
+        // Check for invalid producers
+        QDomNode n = producers.item(i);
+        e = n.toElement();
+
+        /*
+        // Check for invalid markup
+        QDomNodeList params = e.elementsByTagName("property");
+        for (int j = 0; j < params.count(); j++) {
+            QDomElement p = params.item(j).toElement();
+            if (p.attribute("name") == "markup") {
+         QString val = p.text().toUtf8().data();
+         kDebug()<<"//FOUND MARKUP, VAL: "<<val;
+         //e.setAttribute("value", value);
+         n.removeChild(params.item(j));
+         break;
+            }
+        }
+        */
+
+        if (e.hasAttribute("in") == false && e.hasAttribute("out") == false) continue;
+        int in = e.attribute("in").toInt();
+        int out = e.attribute("out").toInt();
+        if (in > out || in == out) {
+            // invalid producer, remove it
+            QString id = e.attribute("id");
+            m_invalidProducers.append(id);
+            m_documentErrors.append(i18n("Invalid clip producer %1\n", id));
+            doc.documentElement().removeChild(producers.at(i));
+            i--;
+        }
+    }
 
     for (int i = 0; i < m_projectTracks; i++) {
         e = tracks.item(i).toElement();
@@ -162,6 +208,7 @@ void TrackView::parseDocument(QDomDocument doc) {
                 m_doc->switchTrackVideo(i - 1, true);
                 m_doc->switchTrackAudio(i - 1, true);
             }
+
             trackduration = slotAddProjectTrack(pos, p, m_doc->isTrackLocked(i - 1));
             pos--;
             //kDebug() << " PRO DUR: " << trackduration << ", TRACK DUR: " << duration;
@@ -217,8 +264,7 @@ void TrackView::parseDocument(QDomDocument doc) {
             QString transitionId;
             if (mlt_service == "composite") {
                 // When adding composite transition, check if it is a wipe transition
-                if (mlt_geometry == "0%,0%:100%x100%") transitionId = "alphatransparency";
-                else if (mlt_geometry.count(';') == 1) {
+                if (mlt_geometry.count(';') == 1) {
                     mlt_geometry.remove(QChar('%'), Qt::CaseInsensitive);
                     mlt_geometry.replace(QChar('x'), QChar(','), Qt::CaseInsensitive);
                     QString start = mlt_geometry.section(';', 0, 0);
@@ -285,7 +331,7 @@ void TrackView::parseDocument(QDomDocument doc) {
                 Transition *tr = new Transition(transitionInfo, a_track, m_doc->fps(), base, isAutomatic);
                 if (forceTrack) tr->setForcedTrack(true, a_track);
                 m_scene->addItem(tr);
-                if (m_doc->isTrackLocked(b_track - 1)) {
+                if (b_track > 0 && m_doc->isTrackLocked(b_track - 1)) {
                     tr->setItemLocked(true);
                 }
             }
@@ -301,6 +347,10 @@ void TrackView::parseDocument(QDomDocument doc) {
         m_trackview->addGuide(pos, comment);
     }
 
+    // Rebuild groups
+    QDomNodeList groups = doc.elementsByTagName("group");
+    m_trackview->loadGroups(groups);
+
     m_trackview->setDuration(duration);
     kDebug() << "///////////  TOTAL PROJECT DURATION: " << duration;
     slotRebuildTrackHeaders();
@@ -309,26 +359,31 @@ void TrackView::parseDocument(QDomDocument doc) {
     //m_scrollBox->setGeometry(0, 0, 300 * zoomFactor(), m_scrollArea->height());
 }
 
-void TrackView::slotDeleteClip(const QString &clipId) {
+void TrackView::slotDeleteClip(const QString &clipId)
+{
     m_trackview->deleteClip(clipId);
 }
 
-void TrackView::setCursorPos(int pos) {
+void TrackView::setCursorPos(int pos)
+{
     m_trackview->setCursorPos(pos);
 }
 
-void TrackView::moveCursorPos(int pos) {
+void TrackView::moveCursorPos(int pos)
+{
     m_trackview->setCursorPos(pos, false);
 }
 
-void TrackView::slotChangeZoom(int factor) {
+void TrackView::slotChangeZoom(int factor)
+{
     m_doc->setZoom(factor);
     m_ruler->setPixelPerMark(factor);
     m_scale = (double) FRAME_SIZE / m_ruler->comboScale[factor]; // m_ruler->comboScale[m_currentZoom] /
     m_trackview->setScale(m_scale);
 }
 
-int TrackView::fitZoom() const {
+int TrackView::fitZoom() const
+{
     int zoom = (int)((duration() + 20 / m_scale) * FRAME_SIZE / m_trackview->width());
     int i;
     for (i = 0; i < 13; i++)
@@ -336,25 +391,20 @@ int TrackView::fitZoom() const {
     return i;
 }
 
-const double TrackView::zoomFactor() const {
-    return m_scale;
-}
-
-const int TrackView::mapLocalToValue(int x) const {
-    return (int)(x * zoomFactor());
-}
-
-KdenliveDoc *TrackView::document() {
+KdenliveDoc *TrackView::document()
+{
     return m_doc;
 }
 
-void TrackView::refresh() {
+void TrackView::refresh()
+{
     m_trackview->viewport()->update();
 }
 
-void TrackView::slotRebuildTrackHeaders() {
+void TrackView::slotRebuildTrackHeaders()
+{
     QList <TrackInfo> list = m_doc->tracksList();
-    QList<HeaderTrack *> widgets = this->findChildren<HeaderTrack *>();
+    QList<HeaderTrack *> widgets = findChildren<HeaderTrack *>();
     for (int i = 0; i < widgets.count(); i++)
         delete widgets.at(i);
     int max = list.count();
@@ -373,11 +423,13 @@ void TrackView::slotRebuildTrackHeaders() {
 }
 
 
-int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked) {
-    int trackTop = KdenliveSettings::trackheight() * ix;
+int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked)
+{
     // parse track
     int position = 0;
-    for (QDomNode n = xml.firstChild(); !n.isNull(); n = n.nextSibling()) {
+    QDomNodeList children = xml.childNodes();
+    for (int nodeindex = 0; nodeindex < children.count(); nodeindex++) {
+        QDomNode n = children.item(nodeindex);
         QDomElement elem = n.toElement();
         if (elem.tagName() == "blank") {
             position += elem.attribute("length").toInt();
@@ -387,16 +439,18 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked) {
             // Found a clip
             int in = elem.attribute("in").toInt();
             int out = elem.attribute("out").toInt();
-            if (in > out || in == out) {
+            if (in > out || in == out || m_invalidProducers.contains(elem.attribute("producer"))) {
                 m_documentErrors.append(i18n("Invalid clip removed from track %1 at %2\n", ix, position));
+                xml.removeChild(children.at(nodeindex));
+                nodeindex--;
                 continue;
             }
             QString idString = elem.attribute("producer");
             QString id = idString;
             double speed = 1.0;
             if (idString.startsWith("slowmotion")) {
-                id = idString.section(":", 1, 1);
-                speed = idString.section(":", 2, 2).toDouble();
+                id = idString.section(':', 1, 1);
+                speed = idString.section(':', 2, 2).toDouble();
             } else id = id.section('_', 0, 0);
             DocClipBase *clip = m_doc->clipManager()->getClipById(id);
             if (clip != NULL) {
@@ -407,6 +461,8 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked) {
                 clipinfo.track = ix;
                 //kDebug() << "// INSERTING CLIP: " << in << "x" << out << ", track: " << ix << ", ID: " << id << ", SCALE: " << m_scale << ", FPS: " << m_doc->fps();
                 ClipItem *item = new ClipItem(clip, clipinfo, m_doc->fps(), speed, false);
+                if (idString.endsWith("_video")) item->setVideoOnly(true);
+                else if (idString.endsWith("_audio")) item->setAudioOnly(true);
                 m_scene->addItem(item);
                 if (locked) item->setItemLocked(true);
                 clip->addReference();
@@ -461,7 +517,7 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked) {
                             if (MainWindow::videoEffects.hasKeyFrames(currenteffect)) {
                                 //kDebug() << " * * * * * * * * * * ** CLIP EFF WITH KFR FND  * * * * * * * * * * *";
                                 // effect is key-framable, read all effects to retrieve keyframes
-                                double factor;
+                                double factor = 0;
                                 QString starttag;
                                 QString endtag;
                                 QDomNodeList params = currenteffect.elementsByTagName("parameter");
@@ -477,8 +533,8 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked) {
                                 QString keyframes;
                                 int effectin = effect.attribute("in").toInt();
                                 int effectout = effect.attribute("out").toInt();
-                                double startvalue;
-                                double endvalue;
+                                double startvalue = 0;
+                                double endvalue = 0;
                                 for (QDomNode n3 = effect.firstChild(); !n3.isNull(); n3 = n3.nextSibling()) {
                                     // parse effect parameters
                                     QDomElement effectparam = n3.toElement();
@@ -488,7 +544,7 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked) {
                                         endvalue = effectparam.text().toDouble() * factor;
                                 }
                                 // add first keyframe
-                                keyframes.append(QString::number(effectin) + ":" + QString::number(startvalue) + ";" + QString::number(effectout) + ":" + QString::number(endvalue) + ";");
+                                keyframes.append(QString::number(effectin) + ':' + QString::number(startvalue) + ';' + QString::number(effectout) + ':' + QString::number(endvalue) + ';');
                                 QDomNode lastParsedEffect;
                                 ix++;
                                 QDomNode n2 = effects.at(ix);
@@ -513,7 +569,7 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked) {
                                         }
                                     }
                                     if (continueParsing) {
-                                        keyframes.append(QString::number(effectout) + ":" + QString::number(endvalue) + ";");
+                                        keyframes.append(QString::number(effectout) + ':' + QString::number(endvalue) + ';');
                                         ix++;
                                     }
                                 }
@@ -616,8 +672,9 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked) {
     //track->show();
 }
 
-DocClipBase *TrackView::getMissingProducer(const QString id) const {
-    QDomElement missingXml = QDomElement();
+DocClipBase *TrackView::getMissingProducer(const QString id) const
+{
+    QDomElement missingXml;
     QDomDocument doc = m_doc->toXml();
     QString docRoot = doc.documentElement().attribute("root");
     if (!docRoot.endsWith('/')) docRoot.append('/');
@@ -651,24 +708,29 @@ DocClipBase *TrackView::getMissingProducer(const QString id) const {
     return missingClip;
 }
 
-QGraphicsScene *TrackView::projectScene() {
+QGraphicsScene *TrackView::projectScene()
+{
     return m_scene;
 }
 
-CustomTrackView *TrackView::projectView() {
+CustomTrackView *TrackView::projectView()
+{
     return m_trackview;
 }
 
-void TrackView::setEditMode(const QString & editMode) {
+void TrackView::setEditMode(const QString & editMode)
+{
     m_editMode = editMode;
 }
 
-const QString & TrackView::editMode() const {
+const QString & TrackView::editMode() const
+{
     return m_editMode;
 }
 
-void TrackView::slotChangeTrackLock(int ix, bool lock) {
-    QList<HeaderTrack *> widgets = this->findChildren<HeaderTrack *>();
+void TrackView::slotChangeTrackLock(int ix, bool lock)
+{
+    QList<HeaderTrack *> widgets = findChildren<HeaderTrack *>();
     widgets.at(ix)->setLock(lock);
 }