[SCM] kdenlive packaging branch, kubuntu_xenial_archive, updated. ubuntu/4%15.08.2-0ubuntu1-561-gb8d8ab5

Scarlett Clark sgclark-guest at moszumanska.debian.org
Thu Feb 18 19:31:23 UTC 2016


Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/kdenlive.git;a=commitdiff;h=168af5e

The following commit has been merged in the kubuntu_xenial_archive branch:
commit 168af5e1596398a87b0ac38703ac8d9d8eb95230
Author: the-me <the-me at f1c9c430-f51a-44e6-a298-6f72677f57b2>
Date:   Wed Dec 16 10:21:10 2015 +0000

    * Add upstream patch 01-crash-when-deleting-tracks.
      Closes: #807978
    
    
    git-svn-id: https://svn.linux-dev.org/svn/pkg/kdenlive/trunk/debian@6442 f1c9c430-f51a-44e6-a298-6f72677f57b2
---
 changelog                                  |   7 +
 patches/01-crash-when-deleting-tracks.diff | 404 +++++++++++++++++++++++++++++
 patches/series                             |   1 +
 3 files changed, 412 insertions(+)

diff --git a/changelog b/changelog
index 34621ed..673c54f 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,10 @@
+kdenlive (15.08.3-2) UNRELEASED; urgency=medium
+
+  * Add upstream patch 01-crash-when-deleting-tracks.
+    Closes: #807978
+
+ -- Patrick Matthäi <pmatthaei at debian.org>  Wed, 16 Dec 2015 11:20:45 +0100
+
 kdenlive (15.08.3-1) unstable; urgency=medium
 
   * New upstream release.
diff --git a/patches/01-crash-when-deleting-tracks.diff b/patches/01-crash-when-deleting-tracks.diff
new file mode 100644
index 0000000..89d2159
--- /dev/null
+++ b/patches/01-crash-when-deleting-tracks.diff
@@ -0,0 +1,404 @@
+commit 0d5e32ad224d399425b098db0a27e7caa7e0f27b
+Author: Jean-Baptiste Mardelle <jb at kdenlive.org>
+Date:   Sun Dec 6 12:40:05 2015 +0100
+
+    Fix crash on delete track with grouped clips, and another track deletion crash
+    BUG: 356313
+
+diff --git a/src/doc/kdenlivedoc.cpp b/src/doc/kdenlivedoc.cpp
+index 56e9c9f..bb51d18 100644
+--- a/src/doc/kdenlivedoc.cpp
++++ b/src/doc/kdenlivedoc.cpp
+@@ -145,7 +145,6 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QUrl &projectFolder, QUndoGroup
+     }
+ 
+     *openBackup = false;
+-    
+     if (url.isValid()) {
+         QFile file(url.toLocalFile());
+         if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+diff --git a/src/project/clipmanager.cpp b/src/project/clipmanager.cpp
+index 7fd25ce..1e6e35a 100644
+--- a/src/project/clipmanager.cpp
++++ b/src/project/clipmanager.cpp
+@@ -343,6 +343,11 @@ void ClipManager::removeGroup(AbstractGroupItem *group)
+     m_groupsList.removeAll(group);
+ }
+ 
++void ClipManager::resetGroups()
++{
++    m_groupsList.clear();
++}
++
+ QString ClipManager::groupsXml() const
+ {
+     QDomDocument doc;
+diff --git a/src/project/clipmanager.h b/src/project/clipmanager.h
+index d633864..bf9143a 100644
+--- a/src/project/clipmanager.h
++++ b/src/project/clipmanager.h
+@@ -82,6 +82,8 @@ Q_OBJECT public:
+     void clearCache();
+     AbstractGroupItem *createGroup();
+     void removeGroup(AbstractGroupItem *group);
++    /** @brief Delete groups list, prepare for a reload. */
++    void resetGroups();
+     QString groupsXml() const;
+     /** @brief remove a clip id from the queue list. */
+     void stopThumbs(const QString &id);
+@@ -98,8 +100,7 @@ private slots:
+     void slotAddCopiedClip(KIO::Job*, const QUrl&, const QUrl &dst);
+ 
+ private:   // Private attributes
+-    /** the list of clips in the document */
+-    /** the list of groups in the document */
++    /** @brief the list of groups in the document */
+     QList <AbstractGroupItem *> m_groupsList;
+     QMap <QString, QString> m_folderList;
+     QList <QString> m_audioThumbsQueue;
+diff --git a/src/timeline/customtrackview.cpp b/src/timeline/customtrackview.cpp
+index 8fd4d29..9d72813 100644
+--- a/src/timeline/customtrackview.cpp
++++ b/src/timeline/customtrackview.cpp
+@@ -3140,6 +3140,30 @@ void CustomTrackView::addTrack(const TrackInfo &type, int ix)
+         ix = m_timeline->tracksCount() + 1;
+     }
+ 
++    // Prepare groups for reload
++    QDomDocument doc;
++    doc.setContent(m_document->groupsXml());
++    QDomNodeList groups;
++    if (!doc.isNull()) {
++        groups = doc.documentElement().elementsByTagName("group");
++        for (int nodeindex = 0; nodeindex < groups.count(); ++nodeindex) {
++            QDomNode grp = groups.item(nodeindex);
++            QDomNodeList nodes = grp.childNodes();
++            for (int itemindex = 0; itemindex < nodes.count(); ++itemindex) {
++                QDomElement elem = nodes.item(itemindex).toElement();
++                if (!elem.hasAttribute("track")) continue;
++                int track = elem.attribute("track").toInt();
++                if (track <= ix) {
++                    // No change
++                    continue;
++                }
++                else {
++                    elem.setAttribute("track", track + 1);
++                }
++            }
++        }
++    }
++
+     // insert track in MLT's playlist
+     transitionInfos = m_document->renderer()->mltInsertTrack(ix,  type.trackName, type.type == VideoTrack);
+     Mlt::Tractor *tractor = m_document->renderer()->lockService();
+@@ -3156,6 +3180,7 @@ void CustomTrackView::addTrack(const TrackInfo &type, int ix)
+     m_document->renderer()->unlockService(tractor);
+     // Reload timeline and m_tracks structure from MLT's playlist
+     reloadTimeline();
++    loadGroups(groups);
+ }
+ 
+ void CustomTrackView::checkCompositeTransitions(Mlt::Tractor *tractor)
+@@ -3235,67 +3260,41 @@ void CustomTrackView::removeTrack(int ix)
+             field->disconnect_service(*mixTr.data());
+         }
+     }
++    // Prepare groups for reload
++    QDomDocument doc;
++    doc.setContent(m_document->groupsXml());
++    QDomNodeList groups;
++    if (!doc.isNull()) {
++        groups = doc.documentElement().elementsByTagName("group");
++        for (int nodeindex = 0; nodeindex < groups.count(); ++nodeindex) {
++            QDomNode grp = groups.item(nodeindex);
++            QDomNodeList nodes = grp.childNodes();
++            for (int itemindex = 0; itemindex < nodes.count(); ++itemindex) {
++                QDomElement elem = nodes.item(itemindex).toElement();
++                if (!elem.hasAttribute("track")) continue;
++                int track = elem.attribute("track").toInt();
++                if (track < ix) {
++                    // No change
++                    continue;
++                }
++                else if (track > ix) {
++                    elem.setAttribute("track", track - 1);
++                }
++                else {
++                    // track == ix
++                    // A grouped item was on deleted track, remove it from group
++                    elem.setAttribute("track", -1);
++                }
++            }
++        }
++    }
++
+     // Delete track in MLT playlist
+     tractor->remove_track(ix);
+     checkCompositeTransitions(tractor);
+     m_document->renderer()->unlockService(tractor);
+     reloadTimeline();
+-    /*
+-    double startY = ix * (m_tracksHeight + 1) + m_tracksHeight / 2;
+-    QRectF r(0, startY, sceneRect().width(), sceneRect().height() - startY);
+-    QList<QGraphicsItem *> selection = m_scene->items(r);
+-    m_selectionMutex.lock();
+-    m_selectionGroup = new AbstractGroupItem(m_document->fps());
+-    scene()->addItem(m_selectionGroup);
+-    for (int i = 0; i < selection.count(); ++i) {
+-        if ((selection.at(i) && !selection.at(i)->parentItem() && selection.at(i)->isEnabled()) && (selection.at(i)->type() == AVWidget || selection.at(i)->type() == TransitionWidget || selection.at(i)->type() == GroupWidget)) {
+-            m_selectionGroup->addItem(selection.at(i));
+-        }
+-    }
+-    // Move graphic items
+-    qreal ydiff = 0 - (int) m_tracksHeight;
+-    m_selectionGroup->setTransform(QTransform::fromTranslate(0, ydiff), true);
+-    Mlt::Tractor *tractor = m_document->renderer()->lockService();
+-
+-    // adjust track number
+-    QList<QGraphicsItem *> children = m_selectionGroup->childItems();
+-    ////qDebug() << "// FOUND CLIPS TO MOVE: " << children.count();
+-    for (int i = 0; i < children.count(); ++i) {
+-        if (children.at(i)->type() == GroupWidget) {
+-            AbstractGroupItem *grp = static_cast<AbstractGroupItem*>(children.at(i));
+-            children << grp->childItems();
+-            continue;
+-        }
+-        if (children.at(i)->type() == AVWidget) {
+-            ClipItem *clip = static_cast <ClipItem *>(children.at(i));
+-            clip->updateItem();
+-        } else if (children.at(i)->type() == TransitionWidget) {
+-            Transition *tr = static_cast <Transition *>(children.at(i));
+-            tr->updateItem();
+-            int track = tr->transitionEndTrack();
+-            if (track >= ix) {
+-                ItemInfo clipinfo = tr->info();
+-                tr->updateTransitionEndTrack(getPreviousVideoTrack(clipinfo.track));
+-            }
+-        }
+-    }
+-    m_selectionMutex.unlock();
+-    resetSelectionGroup(false);
+-    m_document->renderer()->unlockService(tractor);
+-
+-    int maxHeight = m_tracksHeight * m_timeline->tracksCount() * matrix().m22();
+-    for (int i = 0; i < m_guides.count(); ++i) {
+-        m_guides.at(i)->setLine(0, 0, 0, maxHeight - 1);
+-    }
+-    m_cursorLine->setLine(0, 0, 0, maxHeight - 1);
+-    setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_timeline->tracksCount());
+-
+-    m_selectedTrack = qMin(m_selectedTrack, m_timeline->tracksCount() - 1);
+-    viewport()->update();
+-
+-    updateTrackNames(ix, false);
+-    //QTimer::singleShot(500, this, SIGNAL(()));
+-    */
++    loadGroups(groups);
+ }
+ 
+ void CustomTrackView::configTracks(const QList < TrackInfo > &trackInfos)
+@@ -6687,6 +6686,7 @@ void CustomTrackView::getTransitionAvailableSpace(AbstractClipItem *item, GenTim
+ 
+ void CustomTrackView::loadGroups(const QDomNodeList &groups)
+ {
++    m_document->clipManager()->resetGroups();
+     for (int i = 0; i < groups.count(); ++i) {
+         QDomNodeList children = groups.at(i).childNodes();
+         scene()->clearSelection();
+@@ -6695,6 +6695,8 @@ void CustomTrackView::loadGroups(const QDomNodeList &groups)
+             QDomElement elem = children.item(nodeindex).toElement();
+             int pos = elem.attribute("position").toInt();
+             int track = elem.attribute("track").toInt();
++            // Ignore items removed after track deletion
++            if (track == -1) continue;
+             if (elem.tagName() == "clipitem") {
+                 ClipItem *clip = getClipItemAtStart(GenTime(pos, m_document->fps()), track);
+                 if (clip) list.append(clip);//clip->setSelected(true);
+diff --git a/src/timeline/headertrack.cpp b/src/timeline/headertrack.cpp
+index 14f1246..42342fa 100644
+--- a/src/timeline/headertrack.cpp
++++ b/src/timeline/headertrack.cpp
+@@ -36,8 +36,8 @@
+ #include <QDomDocument>
+ #include <QMimeData>
+ 
+-HeaderTrack::HeaderTrack(TrackInfo info, const QList <QAction *> &actions, Track *parent) :
+-        QWidget(0),
++HeaderTrack::HeaderTrack(TrackInfo info, const QList <QAction *> &actions, Track *parent, QWidget *parentWidget) :
++        QWidget(parentWidget),
+         m_type(info.type),
+         m_parentTrack(parent),
+         m_isSelected(false),
+@@ -107,7 +107,7 @@ HeaderTrack::HeaderTrack(TrackInfo info, const QList <QAction *> &actions, Track
+ 
+ HeaderTrack::~HeaderTrack()
+ {
+-    //qDebug()<<" - --DEL: "<<m_name;
++    //qDebug()<<" - --DEL TK HEAD: "<<m_name;
+ }
+ 
+ bool HeaderTrack::eventFilter(QObject *obj, QEvent *event)
+diff --git a/src/timeline/headertrack.h b/src/timeline/headertrack.h
+index d6f0313..cb27283 100644
+--- a/src/timeline/headertrack.h
++++ b/src/timeline/headertrack.h
+@@ -34,7 +34,7 @@ class HeaderTrack : public QWidget, public Ui::TrackHeader_UI
+     Q_OBJECT
+ 
+ public:
+-    HeaderTrack(TrackInfo info, const QList <QAction *>& actions, Track *parent);
++    HeaderTrack(TrackInfo info, const QList <QAction *>& actions, Track *parent, QWidget *parentWidget);
+     virtual ~HeaderTrack();
+     void setTrackHeight(int height);
+     void setLock(bool lock);
+diff --git a/src/timeline/timeline.cpp b/src/timeline/timeline.cpp
+index 8c53a10..76764f4 100644
+--- a/src/timeline/timeline.cpp
++++ b/src/timeline/timeline.cpp
+@@ -225,13 +225,7 @@ int Timeline::getTracks() {
+     QVBoxLayout *headerLayout = qobject_cast< QVBoxLayout* >(headers_container->layout());
+     QLayoutItem *child;
+     while ((child = headerLayout->takeAt(0)) != 0) {
+-        QWidget *wid = child->widget();
+         delete child;
+-        if (wid) {
+-            // We need to change parent or the headers are still here when processing getTransitions()
+-            wid->setParent(0);
+-            wid->deleteLater();
+-        }
+     }
+     int clipsCount = 0;
+     for (int i = 0; i < m_tractor->count(); ++i) {
+@@ -250,6 +244,7 @@ int Timeline::getTracks() {
+         QScopedPointer<Mlt::Producer> track(m_tractor->track(i));
+         QString playlist_name = track->get("id");
+         if (playlist_name == "playlistmain") continue;
++        bool isBackgroundBlackTrack = playlist_name == "black_track";
+         // check track effects
+         Mlt::Playlist playlist(*track);
+         int trackduration;
+@@ -260,16 +255,16 @@ int Timeline::getTracks() {
+         frame->setFrameStyle(QFrame::HLine);
+         frame->setFixedHeight(1);
+         headerLayout->insertWidget(0, frame);
+-        Track *tk = new Track(i, m_trackActions, playlist, audio == 1 ? AudioTrack : VideoTrack, m_doc->fps());
++        Track *tk = new Track(i, m_trackActions, playlist, audio == 1 ? AudioTrack : VideoTrack, m_doc->fps(), this);
+         m_tracks.append(tk);
+-        if (audio == 0) {
++        if (audio == 0 && !isBackgroundBlackTrack) {
+             // Check if we have a composite transition for this track
+             QScopedPointer<Mlt::Transition> transition(transitionHandler->getTransition(KdenliveSettings::gpu_accel() ? "movit.overlay" : "frei0r.cairoblend", i, -1, true));
+             if (!transition) {
+                 tk->trackHeader->disableComposite();
+             }
+         }
+-        if (playlist_name != "black_track") {
++        if (!isBackgroundBlackTrack) {
+             tk->trackHeader->setTrackHeight(height);
+             int currentWidth = tk->trackHeader->minimumWidth();
+             if (currentWidth > headerWidth) headerWidth = currentWidth;
+@@ -284,13 +279,13 @@ int Timeline::getTracks() {
+             connect(tk->trackHeader, SIGNAL(renameTrack(int,QString)), this, SLOT(slotRenameTrack(int,QString)));
+             connect(tk->trackHeader, SIGNAL(configTrack()), this, SIGNAL(configTrack()));
+             connect(tk->trackHeader, SIGNAL(addTrackEffect(QDomElement,int)), m_trackview, SLOT(slotAddTrackEffect(QDomElement,int)));
++            if (playlist.filter_count()) {
++                getEffects(playlist, NULL, i);
++                slotUpdateTrackEffectState(i);
++            }
++            connect(tk, &Track::newTrackDuration, this, &Timeline::checkDuration);
++            connect(tk, SIGNAL(storeSlowMotion(QString,Mlt::Producer *)), m_doc->renderer(), SLOT(storeSlowmotionProducer(QString,Mlt::Producer *)));
+         }
+-        if (playlist.filter_count()) {
+-            getEffects(playlist, NULL, i);
+-            slotUpdateTrackEffectState(i);
+-        }
+-        connect(tk, &Track::newTrackDuration, this, &Timeline::checkDuration);
+-	connect(tk, SIGNAL(storeSlowMotion(QString,Mlt::Producer *)), m_doc->renderer(), SLOT(storeSlowmotionProducer(QString,Mlt::Producer *)));
+     }
+     headers_container->setFixedWidth(headerWidth);
+     updatePalette();
+@@ -697,7 +692,7 @@ void Timeline::switchTrackVideo(int ix, bool hide)
+ 
+ void Timeline::slotSwitchTrackComposite(int trackIndex, bool enable)
+ {
+-    if (trackIndex < 0 || trackIndex > m_tracks.count()) return;
++    if (trackIndex < 1 || trackIndex > m_tracks.count()) return;
+     QScopedPointer<Mlt::Transition> transition(transitionHandler->getTransition(KdenliveSettings::gpu_accel() ? "movit.overlay" : "frei0r.cairoblend", trackIndex, -1, true));
+     if (transition) {
+         transition->set("disable", enable);
+@@ -1138,6 +1133,7 @@ void Timeline::slotRenameTrack(int ix, const QString &name)
+ 
+ void Timeline::renameTrack(int ix, const QString &name)
+ {
++    if (ix < 1) return;
+     Track *tk = track(ix);
+     if (!tk) return;
+     tk->setProperty("kdenlive:track_name", name);
+@@ -1165,6 +1161,7 @@ void Timeline::slotShowTrackEffects(int ix)
+ 
+ void Timeline::slotUpdateTrackEffectState(int ix)
+ {
++    if (ix < 1) return;
+     Track *tk = track(ix);
+     if (!tk) return;
+     tk->trackHeader->updateEffectLabel(tk->effectsList.effectNames());
+diff --git a/src/timeline/track.cpp b/src/timeline/track.cpp
+index c1e21ed..93851e3 100644
+--- a/src/timeline/track.cpp
++++ b/src/timeline/track.cpp
+@@ -28,18 +28,24 @@
+ #include <QDebug>
+ #include <math.h>
+ 
+-Track::Track(int index, const QList<QAction *> &actions, Mlt::Playlist &playlist, TrackType type, qreal fps) :
++Track::Track(int index, const QList<QAction *> &actions, Mlt::Playlist &playlist, TrackType type, qreal fps, QWidget *parent) :
+     effectsList(EffectsList(true)),
+     type(type),
++    trackHeader(NULL),
+     m_index(index),
+     m_playlist(playlist),
+     m_fps(fps)
+ {
+-    trackHeader = new HeaderTrack(info(), actions, this);
++    QString playlist_name = playlist.get("id");
++    if (playlist_name != "black_track") {
++        trackHeader = new HeaderTrack(info(), actions, this, parent);
++    }
+ }
+ 
+ Track::~Track()
+ {
++    //qDebug()<<"// DELETING TRAK: "<<m_playlist.get("id");
++    trackHeader->deleteLater();
+ }
+ 
+ // members access
+@@ -267,6 +273,7 @@ bool Track::needsDuplicate(const QString &service) const
+ 
+ void Track::lockTrack(bool locked)
+ {
++    if (!trackHeader) return;
+     setProperty("kdenlive:locked_track", locked ? 1 : 0);
+     trackHeader->setLock(locked);
+ }
+@@ -531,6 +538,7 @@ TrackInfo Track::info()
+ 
+ void Track::setInfo(TrackInfo info)
+ {
++    if (!trackHeader) return;
+     m_playlist.set("kdenlive:track_name", info.trackName.toUtf8().constData());
+     m_playlist.set("kdenlive:locked_track", info.isLocked ? 1 : 0);
+     m_playlist.set("kdenlive:composite", info.composite ? 1 : 0);
+diff --git a/src/timeline/track.h b/src/timeline/track.h
+index 547229a..8dbe707 100644
+--- a/src/timeline/track.h
++++ b/src/timeline/track.h
+@@ -53,7 +53,7 @@ public:
+     /** @brief Track constructor
+      * @param playlist is the MLT object used for monitor/render
+      * @param fps is the read speed (frames per seconds) */
+-    explicit Track(int index, const QList<QAction *> &actions, Mlt::Playlist &playlist, TrackType type, qreal fps);
++    explicit Track(int index, const QList<QAction *> &actions, Mlt::Playlist &playlist, TrackType type, qreal fps, QWidget *parent = 0);
+     ~Track();
+ 
+     /// Property access function
diff --git a/patches/series b/patches/series
new file mode 100644
index 0000000..d45ae89
--- /dev/null
+++ b/patches/series
@@ -0,0 +1 @@
+01-crash-when-deleting-tracks.diff

-- 
kdenlive packaging



More information about the pkg-kde-commits mailing list