]> git.sesse.net Git - kdenlive/commitdiff
New: allow user to modifiy a clip by saying if he wants to keep only video or only...
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 20 Mar 2009 13:20:52 +0000 (13:20 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 20 Mar 2009 13:20:52 +0000 (13:20 +0000)
svn path=/trunk/kdenlive/; revision=3166

12 files changed:
src/CMakeLists.txt
src/changecliptypecommand.cpp [new file with mode: 0644]
src/changecliptypecommand.h [new file with mode: 0644]
src/clipitem.cpp
src/clipitem.h
src/customtrackview.cpp
src/customtrackview.h
src/docclipbase.cpp
src/docclipbase.h
src/kdenliveui.rc
src/mainwindow.cpp
src/mainwindow.h

index a2004419b20519a1890ef6dc48e1e6ee073ea839..ba2203b26510e15d5d85e5a95b8460678a4c1876 100644 (file)
@@ -152,6 +152,7 @@ set(kdenlive_SRCS
   locktrackcommand.cpp
   groupclipscommand.cpp
   splitaudiocommand.cpp
+  changecliptypecommand.cpp
 )
 
 add_definitions( ${KDE4_DEFINITIONS} )
diff --git a/src/changecliptypecommand.cpp b/src/changecliptypecommand.cpp
new file mode 100644 (file)
index 0000000..51dc10f
--- /dev/null
@@ -0,0 +1,43 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+
+#include "changecliptypecommand.h"
+#include "customtrackview.h"
+
+#include <KLocale>
+
+ChangeClipTypeCommand::ChangeClipTypeCommand(CustomTrackView *view, const int track, const GenTime &pos, bool videoOnly, bool audioOnly, bool originalVideo, bool originalAudio, bool doIt, QUndoCommand * parent) : QUndoCommand(parent), m_view(view), m_track(track), m_pos(pos), m_videoOnly(videoOnly), m_audioOnly(audioOnly), m_originalVideoOnly(originalVideo), m_originalAudioOnly(originalAudio), m_doIt(doIt) {
+    setText(i18n("Change clip type"));
+}
+
+// virtual
+void ChangeClipTypeCommand::undo() {
+// kDebug()<<"----  undoing action";
+    m_doIt = true;
+    m_view->doChangeClipType(m_pos, m_track, m_originalVideoOnly, m_originalAudioOnly);
+}
+// virtual
+void ChangeClipTypeCommand::redo() {
+    kDebug() << "----  redoing action";
+    if (m_doIt)
+        m_view->doChangeClipType(m_pos, m_track, m_videoOnly, m_audioOnly);
+    m_doIt = true;
+}
+
diff --git a/src/changecliptypecommand.h b/src/changecliptypecommand.h
new file mode 100644 (file)
index 0000000..86174ae
--- /dev/null
@@ -0,0 +1,52 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+
+#ifndef CHANGECLIPTYPECOMMAND_H
+#define CHANGECLIPTYPECOMMAND_H
+
+#include <QUndoCommand>
+#include <QGraphicsView>
+#include <QPointF>
+
+#include <KDebug>
+#include "definitions.h"
+
+class GenTime;
+class CustomTrackView;
+
+class ChangeClipTypeCommand : public QUndoCommand {
+public:
+    ChangeClipTypeCommand(CustomTrackView *view, const int track, const GenTime &pos, bool videoOnly, bool audioOnly, bool originalVideo, bool originalAudio, bool doIt, QUndoCommand * parent = 0);
+    virtual void undo();
+    virtual void redo();
+
+private:
+    CustomTrackView *m_view;
+    const GenTime m_pos;
+    const int m_track;
+    bool m_videoOnly;
+    bool m_audioOnly;
+    bool m_originalVideoOnly;
+    bool m_originalAudioOnly;
+    bool m_doIt;
+};
+
+#endif
+
index 749aa6698046a1671561376586d7258e0fa88430..87927087eb019da6369b724d67513e05caef1507 100644 (file)
 #include <QGraphicsScene>
 #include <QMimeData>
 
-
 ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, bool generateThumbs)
         : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_startThumbRequested(false), m_endThumbRequested(false), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(speed), framePixelWidth(0), m_startPix(QPixmap()), m_endPix(QPixmap()), m_videoOnly(false), m_audioOnly(false)  {
     setZValue(1);
     setRect(0, 0, (info.endPos - info.startPos).frames(fps) - 0.02, (double)(KdenliveSettings::trackheight() - 2));
     setPos(info.startPos.frames(fps), (double)(info.track * KdenliveSettings::trackheight()) + 1);
 
+    m_videoPix = KIcon("video-x-generic").pixmap(QSize(15, 15));
+    m_audioPix = KIcon("audio-x-generic").pixmap(QSize(15, 15));
+
     if (m_speed == 1.0) m_clipName = clip->name();
     else {
         m_clipName = clip->name() + " - " + QString::number(m_speed * 100, 'f', 0) + '%';
@@ -721,9 +723,9 @@ void ClipItem::paint(QPainter *painter,
     //painter->setPen(QColor(0, 0, 0, 180));
     //painter->drawText(txtBounding, Qt::AlignCenter, m_clipName);
     if (m_videoOnly) {
-        painter->drawPixmap(txtBounding.topLeft() - QPointF(17, -1), KIcon("video-x-generic").pixmap(QSize(15, 15)));
+        painter->drawPixmap(txtBounding.topLeft() - QPointF(17, -1), m_videoPix);
     } else if (m_audioOnly) {
-        painter->drawPixmap(txtBounding.topLeft() - QPointF(17, -1), KIcon("audio-x-generic").pixmap(QSize(15, 15)));
+        painter->drawPixmap(txtBounding.topLeft() - QPointF(17, -1), m_audioPix);
     }
     txtBounding.translate(QPointF(1, 1));
     painter->setPen(QColor(255, 255, 255, 255));
@@ -1403,6 +1405,15 @@ void ClipItem::setAudioOnly(bool force) {
     m_audioOnly = force;
 }
 
+bool ClipItem::isAudioOnly() const {
+    return m_audioOnly;
+}
+
+bool ClipItem::isVideoOnly() const {
+    return m_videoOnly;
+}
+
+
 // virtual
 /*
 void CustomTrackView::mousePressEvent ( QMouseEvent * event )
index 5817193973470702bcb0178d94da9dba316dbc6a..f2d10f77f90dd024bdcbb626bb2b4e2f39a7d625 100644 (file)
@@ -106,6 +106,8 @@ public:
     QPixmap endThumb() const;
     void setVideoOnly(bool force);
     void setAudioOnly(bool force);
+    bool isVideoOnly() const;
+    bool isAudioOnly() const;
 
 protected:
     //virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
@@ -154,6 +156,8 @@ private:
     QMap<int, QPainterPath > channelPaths;
     /** Called when clip start is resized, adjust keyframes values */
     void checkEffectsKeyframesPos(const int previous, const int current, bool fromStart);
+    QPixmap m_videoPix;
+    QPixmap m_audioPix;
 
 private slots:
     void slotFetchThumbs();
index 8f36d8c1e07c4d3f9fbc676805cfd0a39c7bea16..93daf3774395708d5390455ce508f0ce2a4dce81 100644 (file)
@@ -56,6 +56,7 @@
 #include "locktrackcommand.h"
 #include "groupclipscommand.h"
 #include "splitaudiocommand.h"
+#include "changecliptypecommand.h"
 
 #include <KDebug>
 #include <KLocale>
@@ -1685,7 +1686,11 @@ void CustomTrackView::addTrack(TrackInfo type, int ix) {
                 ClipItem *clip = static_cast <ClipItem *>(item);
                 // We add a move clip command so that we get the correct producer for new track number
                 if (clip->clipType() == AV || clip->clipType() == AUDIO) {
-                    m_document->renderer()->mltUpdateClipProducer((int)(m_document->tracksCount() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), clip->baseClip()->producer(clipinfo.track));
+                    Mlt::Producer *prod;
+                    if (clip->isAudioOnly()) prod = clip->baseClip()->audioProducer(clipinfo.track);
+                    else if (clip->isVideoOnly()) prod = clip->baseClip()->videoProducer();
+                    else prod = clip->baseClip()->producer(clipinfo.track);
+                    m_document->renderer()->mltUpdateClipProducer((int)(m_document->tracksCount() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), prod);
                     kDebug() << "// UPDATING CLIP TO TRACK PROD: " << clipinfo.track;
                 }
             } else if (item->type() == TRANSITIONWIDGET) {
@@ -1745,8 +1750,13 @@ void CustomTrackView::removeTrack(int ix) {
             ItemInfo clipinfo = clip->info();
             kDebug() << "// CLIP TRK IS: " << clipinfo.track;
             // We add a move clip command so that we get the correct producer for new track number
-            if (clip->clipType() == AV || clip->clipType() == AUDIO)
-                m_document->renderer()->mltUpdateClipProducer((int)(m_document->tracksCount() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), clip->baseClip()->producer(clipinfo.track));
+            if (clip->clipType() == AV || clip->clipType() == AUDIO) {
+                Mlt::Producer *prod;
+                if (clip->isAudioOnly()) prod = clip->baseClip()->audioProducer(clipinfo.track);
+                else if (clip->isVideoOnly()) prod = clip->baseClip()->videoProducer();
+                else prod = clip->baseClip()->producer(clipinfo.track);
+                m_document->renderer()->mltUpdateClipProducer((int)(m_document->tracksCount() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), prod);
+            }
         } else if (children.at(i)->type() == TRANSITIONWIDGET) {
             Transition *tr = static_cast <Transition *>(children.at(i));
             tr->updateItem();
@@ -2099,7 +2109,11 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
             // we are moving one clip, easy
             if (m_dragItem->type() == AVWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) {
                 ClipItem *item = static_cast <ClipItem *>(m_dragItem);
-                bool success = m_document->renderer()->mltMoveClip((int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps())), item->baseClip()->producer(info.track));
+                Mlt::Producer *prod;
+                if (item->isAudioOnly()) prod = item->baseClip()->audioProducer(m_dragItemInfo.track);
+                else if (item->isVideoOnly()) prod = item->baseClip()->videoProducer();
+                else prod = item->baseClip()->producer(m_dragItemInfo.track);
+                bool success = m_document->renderer()->mltMoveClip((int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps())), prod);
                 if (success) {
                     int tracknumber = m_document->tracksCount() - item->track() - 1;
                     bool isLocked = m_document->trackInfoAt(tracknumber).isLocked;
@@ -2251,7 +2265,11 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) {
                     if (item->type() == AVWIDGET) {
                         ClipItem *clip = static_cast <ClipItem*>(item);
                         info.track = m_document->tracksCount() - info.track;
-                        m_document->renderer()->mltInsertClip(info, clip->xml(), clip->baseClip()->producer(info.track));
+                        Mlt::Producer *prod;
+                        if (clip->isAudioOnly()) prod = clip->baseClip()->audioProducer(info.track);
+                        else if (clip->isVideoOnly()) prod = clip->baseClip()->videoProducer();
+                        else prod = clip->baseClip()->producer(info.track);
+                        m_document->renderer()->mltInsertClip(info, clip->xml(), prod);
                         for (int i = 0; i < clip->effectsCount(); i++) {
                             m_document->renderer()->mltAddEffect(info.track, info.startPos, clip->getEffectArgs(clip->effectAt(i)), false);
                         }
@@ -2699,7 +2717,11 @@ void CustomTrackView::addClip(QDomElement xml, const QString &clipId, ItemInfo i
     baseclip->addReference();
     m_document->updateClip(baseclip->getId());
     info.track = m_document->tracksCount() - info.track;
-    m_document->renderer()->mltInsertClip(info, xml, baseclip->producer(info.track));
+    Mlt::Producer *prod;
+    if (item->isAudioOnly()) prod = baseclip->audioProducer(info.track);
+    else if (item->isVideoOnly()) prod = baseclip->videoProducer();
+    else prod = baseclip->producer(info.track);
+    m_document->renderer()->mltInsertClip(info, xml, prod);
     for (int i = 0; i < item->effectsCount(); i++) {
         m_document->renderer()->mltAddEffect(info.track, info.startPos, item->getEffectArgs(item->effectAt(i)), false);
     }
@@ -2818,7 +2840,12 @@ void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end) {
         kDebug() << "----------------  ERROR, CANNOT find clip to move at.. ";
         return;
     }
-    bool success = m_document->renderer()->mltMoveClip((int)(m_document->tracksCount() - start.track), (int)(m_document->tracksCount() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps()), item->baseClip()->producer(end.track));
+    Mlt::Producer *prod;
+    if (item->isAudioOnly()) prod = item->baseClip()->audioProducer(end.track);
+    else if (item->isVideoOnly()) prod = item->baseClip()->videoProducer();
+    else prod = item->baseClip()->producer(end.track);
+
+    bool success = m_document->renderer()->mltMoveClip((int)(m_document->tracksCount() - start.track), (int)(m_document->tracksCount() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps()), prod);
     if (success) {
         bool snap = KdenliveSettings::snaptopoints();
         KdenliveSettings::setSnaptopoints(false);
@@ -2921,7 +2948,11 @@ void CustomTrackView::moveGroup(QList <ItemInfo> startClip, QList <ItemInfo> sta
             if (item->type() == AVWIDGET) {
                 ClipItem *clip = static_cast <ClipItem*>(item);
                 info.track = m_document->tracksCount() - info.track;
-                m_document->renderer()->mltInsertClip(info, clip->xml(), clip->baseClip()->producer(info.track));
+                Mlt::Producer *prod;
+                if (clip->isAudioOnly()) prod = clip->baseClip()->audioProducer(info.track);
+                else if (clip->isVideoOnly()) prod = clip->baseClip()->videoProducer();
+                else prod = clip->baseClip()->producer(info.track);
+                m_document->renderer()->mltInsertClip(info, clip->xml(), prod);
             } else {
                 Transition *tr = static_cast <Transition*>(item);
                 int newTrack = tr->transitionEndTrack();
@@ -4046,7 +4077,7 @@ void CustomTrackView::doSplitAudio(const GenTime &pos, int track, bool split) {
             if (audioClip) {
                 clip->setVideoOnly(true);
                 m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - track, start, clip->baseClip()->videoProducer());
-                m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - info.track, start, clip->baseClip()->audioProducer());
+                m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - info.track, start, clip->baseClip()->audioProducer(info.track));
                 audioClip->setSelected(true);
                 audioClip->setAudioOnly(true);
                 groupSelectedItems(false, true);
@@ -4055,4 +4086,77 @@ void CustomTrackView::doSplitAudio(const GenTime &pos, int track, bool split) {
     }
 }
 
+void CustomTrackView::videoOnly() {
+    resetSelectionGroup();
+    QList<QGraphicsItem *> selection = scene()->selectedItems();
+    if (selection.isEmpty()) {
+        emit displayMessage(i18n("You must select one clip for this action"), ErrorMessage);
+        return;
+    }
+    QUndoCommand *videoCommand = new QUndoCommand();
+    videoCommand->setText(i18n("Video only"));
+    for (int i = 0; i < selection.count(); i++) {
+        if (selection.at(i)->type() == AVWIDGET) {
+            ClipItem *clip = static_cast <ClipItem *>(selection.at(i));
+            if (clip->clipType() == AV || clip->clipType() == PLAYLIST) {
+                if (clip->parentItem()) {
+                    emit displayMessage(i18n("Cannot change grouped clips"), ErrorMessage);
+                } else {
+                    new ChangeClipTypeCommand(this, clip->track(), clip->startPos(), true, false, clip->isVideoOnly(), clip->isAudioOnly(), true, videoCommand);
+                }
+            }
+        }
+    }
+    m_commandStack->push(videoCommand);
+}
+
+void CustomTrackView::audioOnly() {
+    resetSelectionGroup();
+    QList<QGraphicsItem *> selection = scene()->selectedItems();
+    if (selection.isEmpty()) {
+        emit displayMessage(i18n("You must select one clip for this action"), ErrorMessage);
+        return;
+    }
+    QUndoCommand *videoCommand = new QUndoCommand();
+    videoCommand->setText(i18n("Audio only"));
+    for (int i = 0; i < selection.count(); i++) {
+        if (selection.at(i)->type() == AVWIDGET) {
+            ClipItem *clip = static_cast <ClipItem *>(selection.at(i));
+            if (clip->clipType() == AV || clip->clipType() == PLAYLIST) {
+                if (clip->parentItem()) {
+                    emit displayMessage(i18n("Cannot change grouped clips"), ErrorMessage);
+                } else {
+                    new ChangeClipTypeCommand(this, clip->track(), clip->startPos(), false, true, clip->isVideoOnly(), clip->isAudioOnly(), true, videoCommand);
+                }
+            }
+        }
+    }
+    m_commandStack->push(videoCommand);
+}
+
+void CustomTrackView::doChangeClipType(const GenTime &pos, int track, bool videoOnly, bool audioOnly) {
+    ClipItem *clip = getClipItemAt(pos, track);
+    if (clip == NULL) {
+        kDebug() << "// Cannot find clip to split!!!";
+        return;
+    }
+    if (videoOnly) {
+        int start = pos.frames(m_document->fps());
+        clip->setVideoOnly(true);
+        clip->setAudioOnly(false);
+        m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - track, start, clip->baseClip()->videoProducer());
+    } else if (audioOnly) {
+        int start = pos.frames(m_document->fps());
+        clip->setAudioOnly(true);
+        clip->setVideoOnly(false);
+        m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - track, start, clip->baseClip()->audioProducer(track));
+    } else {
+        int start = pos.frames(m_document->fps());
+        clip->setAudioOnly(false);
+        clip->setVideoOnly(false);
+        m_document->renderer()->mltUpdateClipProducer(m_document->tracksCount() - track, start, clip->baseClip()->producer(track));
+    }
+    clip->update();
+}
+
 #include "customtrackview.moc"
index 84c2483f7aa36fbb0cc641d95bd9903135aa5fe7..5f44deec8ad0490167cc77eac9d87744dc577a57 100644 (file)
@@ -115,6 +115,9 @@ public:
     void loadGroups(const QDomNodeList groups);
     void splitAudio();
     void doSplitAudio(const GenTime &pos, int track, bool split);
+    void videoOnly();
+    void audioOnly();
+    void doChangeClipType(const GenTime &pos, int track, bool videoOnly, bool audioOnly);
 
 public slots:
     void setCursorPos(int pos, bool seek = true);
index e5cc8760294083b2f47b85c90555559ae7b010a6..db6cd892d47cdf76f04ca75f143977308d1835ae 100644 (file)
@@ -34,7 +34,7 @@
 #include <QCryptographicHash>
 
 DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QString &id):
-        m_id(id), m_description(QString()), m_refcount(0), m_audioThumbCreated(false), m_duration(GenTime()), m_thumbProd(NULL), m_audioTimer(NULL), m_properties(QMap <QString, QString> ()), audioFrameChache(QMap<int, QMap<int, QByteArray> > ()), m_baseTrackProducers(QList <Mlt::Producer *>()), m_snapMarkers(QList < CommentedTime > ()), m_videoOnlyProducer(NULL), m_audioOnlyProducer(NULL)  {
+        m_id(id), m_description(QString()), m_refcount(0), m_audioThumbCreated(false), m_duration(GenTime()), m_thumbProd(NULL), m_audioTimer(NULL), m_properties(QMap <QString, QString> ()), audioFrameChache(QMap<int, QMap<int, QByteArray> > ()), m_baseTrackProducers(QList <Mlt::Producer *>()), m_snapMarkers(QList < CommentedTime > ()), m_videoOnlyProducer(NULL), m_audioTrackProducers(QList <Mlt::Producer *>())  {
     int type = xml.attribute("type").toInt();
     m_clipType = (CLIPTYPE) type;
 
@@ -360,12 +360,18 @@ void DocClipBase::setProducer(Mlt::Producer *producer) {
     QString id = producer->get("id");
     if (id.contains('_')) {
         // this is a subtrack producer, insert it at correct place
-        id = id.section('_', 1, 1);
-        if (id == "audio") {
-            m_audioOnlyProducer = producer;
+        id = id.section('_', 1);
+        if (id.endsWith("audio")) {
+            int pos = id.section('_', 0, 0).toInt();
+            if (pos >= m_audioTrackProducers.count()) {
+                while (m_audioTrackProducers.count() - 1 < pos) {
+                    m_audioTrackProducers.append(NULL);
+                }
+            }
+            if (m_audioTrackProducers.at(pos) == NULL) m_audioTrackProducers[pos] = producer;
             return;
         }
-        if (id == "video") {
+        if (id.endsWith("video")) {
             m_videoOnlyProducer = producer;
             return;
         }
@@ -385,22 +391,24 @@ void DocClipBase::setProducer(Mlt::Producer *producer) {
     if (m_thumbProd && !m_thumbProd->hasProducer()) m_thumbProd->setProducer(producer);
 }
 
-Mlt::Producer *DocClipBase::audioProducer() {
-    if (m_audioOnlyProducer == NULL) {
-        int i;
-        for (i = 0; i < m_baseTrackProducers.count(); i++)
-            if (m_baseTrackProducers.at(i) != NULL) break;
-        if (i >= m_baseTrackProducers.count()) return NULL;
-        m_audioOnlyProducer = new Mlt::Producer(*m_baseTrackProducers.at(i)->profile(), m_baseTrackProducers.at(i)->get("resource"));
-        if (m_properties.contains("force_aspect_ratio")) m_audioOnlyProducer->set("force_aspect_ratio", m_properties.value("force_aspect_ratio").toDouble());
-        if (m_properties.contains("threads")) m_audioOnlyProducer->set("threads", m_properties.value("threads").toInt());
-        m_audioOnlyProducer->set("video_index", -1);
-        if (m_properties.contains("audio_index")) m_audioOnlyProducer->set("audio_index", m_properties.value("audio_index").toInt());
-        char *tmp = (char *) qstrdup(QString(getId() + "_audio").toUtf8().data());
-        m_audioOnlyProducer->set("id", tmp);
+Mlt::Producer *DocClipBase::audioProducer(int track) {
+    if (m_audioTrackProducers.count() <= track) {
+        while (m_audioTrackProducers.count() - 1 < track) {
+            m_audioTrackProducers.append(NULL);
+        }
+    }
+    if (m_audioTrackProducers.at(track) == NULL) {
+        Mlt::Producer *base = producer();
+        m_audioTrackProducers[track] = new Mlt::Producer(*(base->profile()), base->get("resource"));
+        if (m_properties.contains("force_aspect_ratio")) m_audioTrackProducers.at(track)->set("force_aspect_ratio", m_properties.value("force_aspect_ratio").toDouble());
+        if (m_properties.contains("threads")) m_audioTrackProducers.at(track)->set("threads", m_properties.value("threads").toInt());
+        m_audioTrackProducers.at(track)->set("video_index", -1);
+        if (m_properties.contains("audio_index")) m_audioTrackProducers.at(track)->set("audio_index", m_properties.value("audio_index").toInt());
+        char *tmp = (char *) qstrdup(QString(getId() + '_' + QString::number(track) + "_audio").toUtf8().data());
+        m_audioTrackProducers.at(track)->set("id", tmp);
         delete[] tmp;
     }
-    return m_audioOnlyProducer;
+    return m_audioTrackProducers.at(track);
 }
 
 Mlt::Producer *DocClipBase::videoProducer() {
index fc9ed3eecb9f7a6d368f8d4ebff987b0c08ff0e5..d951da503a0e55ec643001441f17e8f13fc09467 100644 (file)
@@ -114,7 +114,7 @@ Q_OBJECT public:
     /** Retrieve the producer that shows only video */
     Mlt::Producer *videoProducer();
     /** Retrieve the producer that shows only audio */
-    Mlt::Producer *audioProducer();
+    Mlt::Producer *audioProducer(int track);
 
     /** Returns true if this clip is a project clip, false otherwise. Overridden in DocClipProject,
      * where it returns true. */
@@ -186,7 +186,7 @@ private:   // Private attributes
      * that exist. */
     uint m_refcount;
     QList <Mlt::Producer *> m_baseTrackProducers;
-    Mlt::Producer *m_audioOnlyProducer;
+    QList <Mlt::Producer *> m_audioTrackProducers;
     Mlt::Producer *m_videoOnlyProducer;
     CLIPTYPE m_clipType;
 
index e30707a53f3f2b6ddee39161a181f6afb0d743a0..ea9294adc9e6de2cc21a3bf9436d97043865495d 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<gui name="kdenlive" version="38">
+<gui name="kdenlive" version="39">
   <ToolBar name="extraToolBar" >
     <text>Extra Toolbar</text>
        <Action name="project_render" />
@@ -55,7 +55,9 @@
          </Menu>
          <Action name="auto_transition" />
          <Action name="split_audio" />
-    </Menu>
+         <Action name="clip_audio_only" />
+         <Action name="clip_video_only" />
+</Menu>
 
     <Menu name="timeline" ><text>Timeline</text>
       <Action name="cut_timeline_clip" />
index cfcd776f1df7bc239c4133c8787fbe85c7fb2f58..7ea848b84f719236eee79a070718e7dc4327f569 100644 (file)
@@ -938,6 +938,14 @@ void MainWindow::setupActions() {
     collection->addAction("split_audio", splitAudio);
     connect(splitAudio, SIGNAL(triggered(bool)), this, SLOT(slotSplitAudio()));
 
+    KAction* audioOnly = new KAction(KIcon("document-new"), i18n("Audio Only"), this);
+    collection->addAction("clip_audio_only", audioOnly);
+    connect(audioOnly, SIGNAL(triggered(bool)), this, SLOT(slotAudioOnly()));
+
+    KAction* videoOnly = new KAction(KIcon("document-new"), i18n("Video Only"), this);
+    collection->addAction("clip_video_only", videoOnly);
+    connect(videoOnly, SIGNAL(triggered(bool)), this, SLOT(slotVideoOnly()));
+
     KAction *insertSpace = new KAction(KIcon(), i18n("Insert Space"), this);
     collection->addAction("insert_space", insertSpace);
     connect(insertSpace, SIGNAL(triggered()), this, SLOT(slotInsertSpace()));
@@ -2390,6 +2398,14 @@ void MainWindow::slotSplitAudio() {
     if (m_activeTimeline) m_activeTimeline->projectView()->splitAudio();
 }
 
+void MainWindow::slotAudioOnly() {
+    if (m_activeTimeline) m_activeTimeline->projectView()->audioOnly();
+}
+
+void MainWindow::slotVideoOnly() {
+    if (m_activeTimeline) m_activeTimeline->projectView()->videoOnly();
+}
+
 void MainWindow::slotDvdWizard(const QString &url, const QString &profile) {
     DvdWizard *w = new DvdWizard(url, profile, this);
     w->exec();
index a260f6840ea8d06dcbb29b90b84103fd61464768..2f3a865d7e57106b39efc4317bcd339160168c32 100644 (file)
@@ -295,6 +295,8 @@ private slots:
     void slotGroupClips();
     void slotUnGroupClips();
     void slotSplitAudio();
+    void slotVideoOnly();
+    void slotAudioOnly();
 
 signals:
     Q_SCRIPTABLE void abortRenderJob(const QString &url);