]> git.sesse.net Git - kdenlive/commitdiff
Update for new titler module, turn clip speed into an effect, mem leaks and more
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 28 Jul 2009 12:34:59 +0000 (12:34 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 28 Jul 2009 12:34:59 +0000 (12:34 +0000)
svn path=/trunk/kdenlive/; revision=3771

31 files changed:
effects/CMakeLists.txt
effects/speed.xml
src/changespeedcommand.cpp
src/changespeedcommand.h
src/clipitem.cpp
src/clipitem.h
src/clipmanager.cpp
src/clipmanager.h
src/customtrackview.cpp
src/customtrackview.h
src/docclipbase.cpp
src/effectstackedit.cpp
src/effectstackedit.h
src/geometryval.cpp
src/kdenlivedoc.cpp
src/kdenliveui.rc
src/mainwindow.cpp
src/mainwindow.h
src/mimetypes/kdenlive.xml
src/monitor.cpp
src/projectlist.cpp
src/projectlistview.cpp
src/renderer.cpp
src/renderer.h
src/statusbarmessagelabel.cpp
src/statusbarmessagelabel.h
src/titledocument.cpp
src/titledocument.h
src/titlewidget.cpp
src/titlewidget.h
src/trackview.cpp

index 62ee2d6afd5ca27596d9cce623a85422680f7c25..53999135603473abdfbef9719db7089a3e86c1a4 100644 (file)
@@ -56,5 +56,6 @@ frei0r_saturat0r.xml
 gain.xml
 fade_from_black.xml
 fade_to_black.xml
+speed.xml
 
 DESTINATION ${DATA_INSTALL_DIR}/kdenlive/effects)
index b00b86b54a536ab28b0a57359b1a929febd27160..cfe7ae59c62fa9fb8d0be8df7645f89aeec29315 100644 (file)
@@ -1,10 +1,9 @@
 <!DOCTYPE kpartgui>
-<effect tag="framebuffer">
+<effect tag="framebuffer" id="speed" type="video" unique="1">
        <name>Speed</name>
-       <description>Make clip play faster slowly</description>
+       <description>Make clip play faster or slower</description>
        <author>Jean-Baptiste Mardelle</author>
-       <properties id="speed" tag="framebuffer"/>
-       <parameter type="constant" name="_speed" max="300" min="1" default="100" factor="100">
+       <parameter type="constant" name="speed" max="1000" min="1" default="100" factor="100" suffix="%">
                <name>Speed</name>
        </parameter>
        <parameter type="constant" name="strobe" max="100" min="1" default="1">
index 394faa907d11f0b3b007cb505f510387be875124..db488077cca0971833f7be66ad27e490f2406a51 100644 (file)
 
 #include <KLocale>
 
-ChangeSpeedCommand::ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, double old_speed, double new_speed, const QString &clipId, QUndoCommand * parent) :
+ChangeSpeedCommand::ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, double old_speed, double new_speed, int old_strobe, int new_strobe, const QString &clipId, QUndoCommand * parent) :
         QUndoCommand(parent),
         m_view(view),
         m_clipInfo(info),
         m_clipId(clipId),
         m_old_speed(old_speed),
-        m_new_speed(new_speed)
+        m_new_speed(new_speed),
+        m_old_strobe(old_strobe),
+        m_new_strobe(new_strobe)
 {
     setText(i18n("Adjust clip length"));
 }
@@ -38,12 +40,12 @@ ChangeSpeedCommand::ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, dou
 // virtual
 void ChangeSpeedCommand::undo()
 {
-    m_view->doChangeClipSpeed(m_clipInfo, m_old_speed, m_new_speed, m_clipId);
+    m_view->doChangeClipSpeed(m_clipInfo, m_old_speed, m_new_speed, m_old_strobe, m_clipId);
 }
 // virtual
 void ChangeSpeedCommand::redo()
 {
-    m_view->doChangeClipSpeed(m_clipInfo, m_new_speed, m_old_speed, m_clipId);
+    m_view->doChangeClipSpeed(m_clipInfo, m_new_speed, m_old_speed, m_new_strobe, m_clipId);
 }
 
 
index ab1c5b41d579c74b05862ccefee8871c20808b2e..3f54c8fbe9cf85ce98e6edbe4697b5edad79a9bf 100644 (file)
@@ -33,7 +33,7 @@ class CustomTrackView;
 class ChangeSpeedCommand : public QUndoCommand
 {
 public:
-    ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, double old_speed, double new_speed, const QString &clipId, QUndoCommand * parent = 0);
+    ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, double old_speed, double new_speed, int old_strobe, int new_strobe, const QString &clipId, QUndoCommand * parent = 0);
     virtual void undo();
     virtual void redo();
 
@@ -43,6 +43,8 @@ private:
     QString m_clipId;
     double m_old_speed;
     double m_new_speed;
+    int m_old_strobe;
+    int m_new_strobe;
 };
 
 #endif
index 8d76725d3f0b584641ae2e9b44c86d5ddd4d535b..c03356452ac27db01501bf9ef9228a703d4eec56 100644 (file)
@@ -37,7 +37,7 @@
 #include <QGraphicsScene>
 #include <QMimeData>
 
-ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, bool generateThumbs) :
+ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, int strobe, bool generateThumbs) :
         AbstractClipItem(info, QRectF(), fps),
         m_clip(clip),
         m_startFade(0),
@@ -47,14 +47,13 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, b
         m_startPix(QPixmap()),
         m_endPix(QPixmap()),
         m_hasThumbs(false),
-        m_startThumbTimer(NULL),
-        m_endThumbTimer(NULL),
         m_selectedEffect(-1),
         m_timeLine(0),
         m_startThumbRequested(false),
         m_endThumbRequested(false),
         //m_hover(false),
         m_speed(speed),
+        m_strobe(strobe),
         m_framePixelWidth(0)
 {
     setZValue(2);
@@ -83,12 +82,10 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, b
     if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW || m_clipType == PLAYLIST) {
         setBrush(QColor(141, 166, 215));
         m_hasThumbs = true;
-        m_startThumbTimer = new QTimer(this);
-        m_startThumbTimer->setSingleShot(true);
-        connect(m_startThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetStartThumb()));
-        m_endThumbTimer = new QTimer(this);
-        m_endThumbTimer->setSingleShot(true);
-        connect(m_endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb()));
+        m_startThumbTimer.setSingleShot(true);
+        connect(&m_startThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetStartThumb()));
+        m_endThumbTimer.setSingleShot(true);
+        connect(&m_endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb()));
 
         connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(extractImage(int, int)));
         //connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(getVideoThumbs(int, int)));
@@ -122,14 +119,12 @@ ClipItem::~ClipItem()
         disconnect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));
         disconnect(m_clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData()));
     }
-    delete m_startThumbTimer;
-    delete m_endThumbTimer;
     delete m_timeLine;
 }
 
 ClipItem *ClipItem::clone(ItemInfo info) const
 {
-    ClipItem *duplicate = new ClipItem(m_clip, info, m_fps, m_speed);
+    ClipItem *duplicate = new ClipItem(m_clip, info, m_fps, m_speed, m_strobe);
     if (m_clipType == IMAGE || m_clipType == TEXT) duplicate->slotSetStartThumb(m_startPix);
     else {
         if (info.cropStart == m_cropStart) duplicate->slotSetStartThumb(m_startPix);
@@ -591,6 +586,7 @@ QDomElement ClipItem::xml() const
 {
     QDomElement xml = m_clip->toXML();
     if (m_speed != 1.0) xml.setAttribute("speed", m_speed);
+    if (m_strobe > 1) xml.setAttribute("strobe", m_strobe);
     if (m_audioOnly) xml.setAttribute("audio_only", 1);
     else if (m_videoOnly) xml.setAttribute("video_only", 1);
     return xml;
@@ -1123,7 +1119,7 @@ void ClipItem::resizeStart(int posx, double /*speed*/)
         checkEffectsKeyframesPos(previous, cropStart().frames(m_fps), true);
         if (m_hasThumbs && KdenliveSettings::videothumbnails()) {
             /*connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));*/
-            m_startThumbTimer->start(150);
+            m_startThumbTimer.start(150);
         }
     }
 }
@@ -1140,7 +1136,7 @@ void ClipItem::resizeEnd(int posx, double /*speed*/, bool updateKeyFrames)
         if (updateKeyFrames) checkEffectsKeyframesPos(previous, (cropStart() + cropDuration()).frames(m_fps), false);
         if (m_hasThumbs && KdenliveSettings::videothumbnails()) {
             /*connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));*/
-            m_endThumbTimer->start(150);
+            m_endThumbTimer.start(150);
         }
     }
 }
@@ -1501,9 +1497,15 @@ double ClipItem::speed() const
     return m_speed;
 }
 
-void ClipItem::setSpeed(const double speed)
+int ClipItem::strobe() const
+{
+    return m_strobe;
+}
+
+void ClipItem::setSpeed(const double speed, const int strobe)
 {
     m_speed = speed;
+    m_strobe = strobe;
     if (m_speed == 1.0) m_clipName = baseClip()->name();
     else m_clipName = baseClip()->name() + " - " + QString::number(speed * 100, 'f', 0) + '%';
     //update();
index 31efc3ae30a0eb486c1f43ab8824a05cc444a4f3..8d0feafd1e03e940b1a1927c5a9d5371d738f6ad 100644 (file)
@@ -41,7 +41,7 @@ class ClipItem : public AbstractClipItem
     Q_OBJECT
 
 public:
-    ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, bool generateThumbs = true);
+    ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, int strobe, bool generateThumbs = true);
     virtual ~ ClipItem();
     virtual void paint(QPainter *painter,
                        const QStyleOptionGraphicsItem *option,
@@ -95,8 +95,9 @@ public:
     QString keyframes(const int index);
     void setKeyframes(const int ix, const QString keyframes);
     void setEffectList(const EffectsList effectList);
-    void setSpeed(const double speed);
+    void setSpeed(const double speed, int strobe);
     double speed() const;
+    int strobe() const;
     GenTime maxDuration() const;
     GenTime cropStart() const;
     GenTime endPos() const;
@@ -133,8 +134,8 @@ private:
     QPixmap m_startPix;
     QPixmap m_endPix;
     bool m_hasThumbs;
-    QTimer *m_startThumbTimer;
-    QTimer *m_endThumbTimer;
+    QTimer m_startThumbTimer;
+    QTimer m_endThumbTimer;
 
     int m_selectedEffect;
     QTimeLine *m_timeLine;
@@ -142,6 +143,7 @@ private:
     bool m_endThumbRequested;
     //bool m_hover;
     double m_speed;
+    int m_strobe;
 
     EffectsList m_effectList;
     QList <Transition*> m_transitionsList;
index 4764a6504fe1740ce0ffb515a0d175ce7ec28553..fc33da1dd33e8934aecdf05aab62fa3d01fdc0cf 100644 (file)
@@ -48,6 +48,7 @@ ClipManager::ClipManager(KdenliveDoc *doc) :
 
 ClipManager::~ClipManager()
 {
+    kDebug() << "\n\n 2222222222222222222222222  CLOSE CM 22222222222";
     qDeleteAll(m_clipList);
 }
 
@@ -257,8 +258,23 @@ void ClipManager::slotAddClipList(const KUrl::List urls, const QString group, co
             KMimeType::Ptr type = KMimeType::findByUrl(file);
             if (type->name().startsWith("image/")) {
                 prod.setAttribute("type", (int) IMAGE);
-                prod.setAttribute("in", "0");
+                prod.setAttribute("in", 0);
                 prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::image_duration()) - 1);
+            } else if (type->name() == "application/x-kdenlivetitle") {
+                // opening a title file
+                QDomDocument txtdoc("titledocument");
+                QFile txtfile(file.path());
+                if (txtfile.open(QIODevice::ReadOnly) && txtdoc.setContent(&txtfile)) {
+                    txtfile.close();
+                    prod.setAttribute("type", (int) TEXT);
+                    prod.setAttribute("resource", QString());
+                    prod.setAttribute("xmldata", txtdoc.toString());
+                    GenTime outPos(txtdoc.documentElement().attribute("out").toDouble() / 1000.0);
+                    prod.setAttribute("transparency", 1);
+                    prod.setAttribute("in", 0);
+                    int out = (int) outPos.frames(m_doc->fps());
+                    if (out > 0) prod.setAttribute("out", out);
+                } else txtfile.close();
             }
             new AddClipCommand(m_doc, doc.documentElement(), QString::number(id), true, addClips);
         }
@@ -284,6 +300,21 @@ void ClipManager::slotAddClipFile(const KUrl url, const QString group, const QSt
         prod.setAttribute("type", (int) IMAGE);
         prod.setAttribute("in", "0");
         prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::image_duration()) - 1);
+    } else if (type->name() == "application/x-kdenlivetitle") {
+        // opening a title file
+        QDomDocument txtdoc("titledocument");
+        QFile txtfile(url.path());
+        if (txtfile.open(QIODevice::ReadOnly) && txtdoc.setContent(&txtfile)) {
+            txtfile.close();
+            prod.setAttribute("type", (int) TEXT);
+            prod.setAttribute("resource", QString());
+            prod.setAttribute("xmldata", txtdoc.toString());
+            GenTime outPos(txtdoc.documentElement().attribute("out").toDouble() / 1000.0);
+            prod.setAttribute("transparency", 1);
+            prod.setAttribute("in", 0);
+            int out = (int) outPos.frames(m_doc->fps());
+            if (out > 0) prod.setAttribute("out", out);
+        } else txtfile.close();
     }
     AddClipCommand *command = new AddClipCommand(m_doc, doc.documentElement(), QString::number(id), true);
     m_doc->commandStack()->push(command);
@@ -338,12 +369,12 @@ void ClipManager::slotAddSlideshowClipFile(const QString name, const QString pat
 
 
 
-void ClipManager::slotAddTextClipFile(const QString titleName, const QString imagePath, const QString xml, const QString group, const QString &groupId)
+void ClipManager::slotAddTextClipFile(const QString titleName, int out, const QString xml, const QString group, const QString &groupId)
 {
     QDomDocument doc;
     QDomElement prod = doc.createElement("producer");
     doc.appendChild(prod);
-    prod.setAttribute("resource", imagePath);
+    //prod.setAttribute("resource", imagePath);
     prod.setAttribute("name", titleName);
     prod.setAttribute("xmldata", xml);
     uint id = m_clipIdCounter++;
@@ -355,7 +386,7 @@ void ClipManager::slotAddTextClipFile(const QString titleName, const QString ima
     prod.setAttribute("type", (int) TEXT);
     prod.setAttribute("transparency", "1");
     prod.setAttribute("in", "0");
-    prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::image_duration()) - 1);
+    prod.setAttribute("out", out);
     AddClipCommand *command = new AddClipCommand(m_doc, doc.documentElement(), QString::number(id), true);
     m_doc->commandStack()->push(command);
 }
index 4a7850f7b97dfecf80c7165d1c37f2ea61ec8df3..6eca717a67bd9ca322574d834c29fbd6f2c5765a 100644 (file)
@@ -57,7 +57,7 @@ Q_OBJECT public:
     void deleteClip(const QString &clipId);
     void slotAddClipFile(const KUrl url, const QString group, const QString &groupId);
     void slotAddClipList(const KUrl::List urls, const QString group, const QString &groupId);
-    void slotAddTextClipFile(const QString titleName, const QString imagePath, const QString xml, const QString group, const QString &groupId);
+    void slotAddTextClipFile(const QString titleName, int out, const QString xml, const QString group, const QString &groupId);
     void slotAddTextTemplateClip(QString titleName, const QString imagePath, const KUrl path, const QString group, const QString &groupId);
     void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const QString &groupId);
     void slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, const bool loop, const bool fade, const QString &luma_duration, const QString &luma_file, const int softness, const QString group, const QString &groupId);
index 25bdd97e01c34f11fb2610f299d04d777acb0a08..f72109dffc31de7de4bc2c0176f0f92846ae76a2 100644 (file)
@@ -98,7 +98,6 @@ CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscen
         m_animation(NULL),
         m_clickPoint(),
         m_autoScroll(KdenliveSettings::autoscroll()),
-        m_changeSpeedAction(NULL),
         m_pasteEffectsAction(NULL),
         m_ungroupAction(NULL),
         m_scrollOffset(0),
@@ -165,8 +164,7 @@ void CustomTrackView::setContextMenu(QMenu *timeline, QMenu *clip, QMenu *transi
     m_clipTypeGroup = clipTypeGroup;
     QList <QAction *> list = m_timelineContextClipMenu->actions();
     for (int i = 0; i < list.count(); i++) {
-        if (list.at(i)->data().toString() == "change_speed") m_changeSpeedAction = list.at(i);
-        else if (list.at(i)->data().toString() == "paste_effects") m_pasteEffectsAction = list.at(i);
+        if (list.at(i)->data().toString() == "paste_effects") m_pasteEffectsAction = list.at(i);
         else if (list.at(i)->data().toString() == "ungroup_clip") m_ungroupAction = list.at(i);
     }
 
@@ -411,9 +409,9 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event)
             return;
         } else {
             if (m_visualTip) {
+                m_animationTimer->stop();
                 delete m_animation;
                 m_animation = NULL;
-                m_animationTimer->stop();
                 delete m_visualTip;
                 m_visualTip = NULL;
             }
@@ -567,8 +565,8 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event)
         setCursor(Qt::SplitHCursor);
     } else {
         if (m_visualTip) {
-            delete m_animation;
             m_animationTimer->stop();
+            delete m_animation;
             m_animation = NULL;
             delete m_visualTip;
             m_visualTip = NULL;
@@ -817,7 +815,6 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event)
         groupSelectedItems();
         ClipItem *clip = static_cast <ClipItem *>(m_dragItem);
         updateClipTypeActions(dragGroup == NULL ? clip : NULL);
-        m_changeSpeedAction->setEnabled(clip->clipType() == AV || clip->clipType() == VIDEO);
         m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
     }
 
@@ -1111,7 +1108,6 @@ void CustomTrackView::displayContextMenu(QPoint pos, AbstractClipItem *clip, Abs
     m_editGuide->setEnabled(m_dragGuide != NULL);
     if (clip == NULL) m_timelineContextMenu->popup(pos);
     else if (group != NULL) {
-        m_changeSpeedAction->setEnabled(false);
         m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
         m_ungroupAction->setEnabled(true);
         updateClipTypeActions(NULL);
@@ -1121,7 +1117,6 @@ void CustomTrackView::displayContextMenu(QPoint pos, AbstractClipItem *clip, Abs
         if (clip->type() == AVWIDGET) {
             ClipItem *item = static_cast <ClipItem*>(clip);
             updateClipTypeActions(item);
-            m_changeSpeedAction->setEnabled(item->clipType() == AV || item->clipType() == VIDEO);
             m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
             m_timelineContextClipMenu->popup(pos);
         } else if (clip->type() == TRANSITIONWIDGET) m_timelineContextTransitionMenu->popup(pos);
@@ -1148,7 +1143,7 @@ void CustomTrackView::dragEnterEvent(QDragEnterEvent * event)
         info.cropStart = GenTime(list.at(1).toInt(), m_document->fps());
         info.endPos = GenTime(list.at(2).toInt() - list.at(1).toInt(), m_document->fps());
         info.track = (int)(1 / m_tracksHeight);
-        ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0);
+        ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1);
         m_selectionGroup->addToGroup(item);
         item->setFlags(QGraphicsItem::ItemIsSelectable);
         //TODO: check if we do not overlap another clip when first dropping in timeline
@@ -1175,7 +1170,7 @@ void CustomTrackView::dragEnterEvent(QDragEnterEvent * event)
             info.startPos = start;
             info.endPos = info.startPos + clip->duration();
             info.track = (int)(1 / m_tracksHeight);
-            ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, false);
+            ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1, false);
             start += clip->duration();
             offsetList.append(start);
             m_selectionGroup->addToGroup(item);
@@ -1268,6 +1263,22 @@ void CustomTrackView::addEffect(int track, GenTime pos, QDomElement effect)
 {
     ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_document->tracksCount() - track);
     if (clip) {
+        // Special case: speed effect
+        if (effect.attribute("id") == "speed") {
+            if (clip->clipType() != VIDEO && clip->clipType() != AV && clip->clipType() != PLAYLIST) {
+                emit displayMessage(i18n("Problem adding effect to clip"), ErrorMessage);
+                return;
+            }
+            ItemInfo info = clip->info();
+            double speed = EffectsList::parameter(effect, "speed").toDouble() / 100.0;
+            int strobe = EffectsList::parameter(effect, "strobe").toInt();
+            if (strobe == 0) strobe = 1;
+            doChangeClipSpeed(info, speed, 1.0, strobe, clip->baseClip()->getId());
+            clip->addEffect(effect);
+            emit clipItemSelected(clip);
+            return;
+        }
+
         if (!m_document->renderer()->mltAddEffect(track, pos, clip->addEffect(effect)))
             emit displayMessage(i18n("Problem adding effect to clip"), ErrorMessage);
         emit clipItemSelected(clip);
@@ -1277,6 +1288,17 @@ void CustomTrackView::addEffect(int track, GenTime pos, QDomElement effect)
 void CustomTrackView::deleteEffect(int track, GenTime pos, QDomElement effect)
 {
     QString index = effect.attribute("kdenlive_ix");
+    // Special case: speed effect
+    if (effect.attribute("id") == "speed") {
+        ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_document->tracksCount() - track);
+        if (clip) {
+            ItemInfo info = clip->info();
+            doChangeClipSpeed(info, 1.0, clip->speed(), 1, clip->baseClip()->getId());
+            clip->deleteEffect(index);
+            emit clipItemSelected(clip);
+            return;
+        }
+    }
     if (!m_document->renderer()->mltRemoveEffect(track, pos, index, true) && effect.attribute("disabled") != "1") {
         kDebug() << "// ERROR REMOV EFFECT: " << index << ", DISABLE: " << effect.attribute("disabled");
         emit displayMessage(i18n("Problem deleting effect"), ErrorMessage);
@@ -1400,6 +1422,25 @@ void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement effect, i
 {
     ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_document->tracksCount() - track);
     if (clip) {
+
+
+        // Special case: speed effect
+        if (effect.attribute("id") == "speed") {
+            ItemInfo info = clip->info();
+            double speed = EffectsList::parameter(effect, "speed").toDouble() / 100.0;
+            int strobe = EffectsList::parameter(effect, "strobe").toInt();
+            if (strobe == 0) strobe = 1;
+            doChangeClipSpeed(info, speed, clip->speed(), strobe, clip->baseClip()->getId());
+            clip->setEffectAt(ix, effect);
+            if (ix == clip->selectedEffectIndex()) {
+                clip->setSelectedEffect(ix);
+            }
+            return;
+        }
+
+
+
+
         EffectsParameterList effectParams = clip->getEffectArgs(effect);
         if (effect.attribute("tag") == "ladspa") {
             // Update the ladspa affect file
@@ -1455,6 +1496,21 @@ void CustomTrackView::slotChangeEffectState(ClipItem *clip, int effectPos, bool
 {
     QDomElement effect = clip->effectAt(effectPos);
     QDomElement oldEffect = effect.cloneNode().toElement();
+
+    if (effect.attribute("id") == "speed") {
+        if (clip) {
+            ItemInfo info = clip->info();
+            effect.setAttribute("disabled", disable);
+            if (disable) doChangeClipSpeed(info, 1.0, clip->speed(), 1, clip->baseClip()->getId());
+            else {
+                double speed = EffectsList::parameter(effect, "speed").toDouble() / 100.0;
+                int strobe = EffectsList::parameter(effect, "strobe").toInt();
+                if (strobe == 0) strobe = 1;
+                doChangeClipSpeed(info, speed, 1.0, strobe, clip->baseClip()->getId());
+            }
+            return;
+        }
+    }
     effect.setAttribute("disabled", disable);
     EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), oldEffect, effect, effectPos, true);
     m_commandStack->push(command);
@@ -1779,19 +1835,21 @@ void CustomTrackView::dropEvent(QDropEvent * event)
             bool isLocked = m_document->trackInfoAt(tracknumber).isLocked;
             if (isLocked) item->setItemLocked(true);
 
-            if (item->baseClip()->isTransparent() && getTransitionItemAtStart(info.startPos, info.track) == NULL) {
+            /*if (item->baseClip()->isTransparent() && getTransitionItemAtStart(info.startPos, info.track) == NULL) {
                 // add transparency transition
-                new AddTransitionCommand(this, info, getPreviousVideoTrack(info.track), MainWindow::transitions.getEffectByTag("composite", "composite"), false, true, addCommand);
-            }
+            QDomElement trans = MainWindow::transitions.getEffectByTag("composite", "composite").cloneNode().toElement();
+                new AddTransitionCommand(this, info, getPreviousVideoTrack(info.track), trans, false, true, addCommand);
+            }*/
             info.track = m_document->tracksCount() - item->track();
             m_document->renderer()->mltInsertClip(info, item->xml(), item->baseClip()->producer(item->track()));
             item->setSelected(true);
         }
         m_commandStack->push(addCommand);
         setDocumentModified();
-        m_changeSpeedAction->setEnabled(hasVideoClip);
         m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
         if (items.count() > 1) groupSelectedItems(true);
+        event->setDropAction(Qt::MoveAction);
+        event->accept();
     } else QGraphicsView::dropEvent(event);
     setFocus();
 }
@@ -2349,6 +2407,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
                 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) {
                     kDebug() << "// get trans info";
                     int tracknumber = m_document->tracksCount() - item->track() - 1;
@@ -2874,7 +2933,7 @@ void CustomTrackView::changeClipSpeed()
             double speed = (double) percent / 100.0;
             if (item->speed() != speed && (item->clipType() == VIDEO || item->clipType() == AV)) {
                 count++;
-                new ChangeSpeedCommand(this, info, item->speed(), speed, item->clipProducer(), changeSelected);
+                //new ChangeSpeedCommand(this, info, item->speed(), speed, item->clipProducer(), changeSelected);
             }
         }
     }
@@ -2882,7 +2941,7 @@ void CustomTrackView::changeClipSpeed()
     else delete changeSelected;
 }
 
-void CustomTrackView::doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, const QString &id)
+void CustomTrackView::doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, int strobe, const QString &id)
 {
     DocClipBase *baseclip = m_document->clipManager()->getClipById(id);
     ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()), info.track);
@@ -2892,9 +2951,9 @@ void CustomTrackView::doChangeClipSpeed(ItemInfo info, const double speed, const
         return;
     }
     info.track = m_document->tracksCount() - item->track();
-    int endPos = m_document->renderer()->mltChangeClipSpeed(info, speed, oldspeed, baseclip->producer());
+    int endPos = m_document->renderer()->mltChangeClipSpeed(info, speed, oldspeed, strobe, baseclip->producer());
     if (endPos >= 0) {
-        item->setSpeed(speed);
+        item->setSpeed(speed, strobe);
         item->updateRectGeometry();
         if (item->cropDuration().frames(m_document->fps()) > endPos)
             item->AbstractClipItem::resizeEnd(info.startPos.frames(m_document->fps()) + endPos, speed);
@@ -3003,7 +3062,7 @@ void CustomTrackView::addClip(QDomElement xml, const QString &clipId, ItemInfo i
         emit displayMessage(i18n("No clip copied"), ErrorMessage);
         return;
     }
-    ClipItem *item = new ClipItem(baseclip, info, m_document->fps(), xml.attribute("speed", "1").toDouble());
+    ClipItem *item = new ClipItem(baseclip, info, m_document->fps(), xml.attribute("speed", "1").toDouble(), xml.attribute("strobe", "1").toInt());
     item->setEffectList(effects);
     if (xml.hasAttribute("audio_only")) item->setAudioOnly(true);
     else if (xml.hasAttribute("video_only")) item->setVideoOnly(true);
index 86c1b8b1a179275f0409b6fd5bb5653ea5bc49b4..4f23d5b7e048dcbeb3b3ab47f3412e9c1ac702bd 100644 (file)
@@ -96,7 +96,7 @@ public:
     void clipStart();
     void clipEnd();
     void changeClipSpeed();
-    void doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, const QString &id);
+    void doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, int strobe, const QString &id);
     void setDocumentModified();
     void setInPoint();
     void setOutPoint();
@@ -209,7 +209,6 @@ private:
     QMenu *m_timelineContextClipMenu;
     QMenu *m_timelineContextTransitionMenu;
     QAction *m_autoTransition;
-    QAction *m_changeSpeedAction;
     QAction *m_pasteEffectsAction;
     QAction *m_ungroupAction;
     QAction *m_editGuide;
index 10d5df4a609e39f229be3db00cd158f436c863b3..02008ccb925b478868ef4e6be494faeaeeb59b5e 100644 (file)
@@ -92,11 +92,14 @@ DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QStrin
 
 DocClipBase::~DocClipBase()
 {
+    kDebug() << "CLIP " << m_id << " DELETED******************************";
     delete m_thumbProd;
     if (m_audioTimer) {
         m_audioTimer->stop();
         delete m_audioTimer;
     }
+    /*kDebug() <<" * * *CNT "<<m_baseTrackProducers.count();
+    if (m_baseTrackProducers.count() > 0) kDebug()<<"YOYO: "<<m_baseTrackProducers.at(0)->get_out()<<", CUT: "<<m_baseTrackProducers.at(0)->is_cut();*/
     qDeleteAll(m_baseTrackProducers);
     m_baseTrackProducers.clear();
     qDeleteAll(m_audioTrackProducers);
@@ -752,8 +755,16 @@ void DocClipBase::setProperty(const QString &key, const QString &value)
         char *tmp = (char *) qstrdup(value.toUtf8().data());
         setProducerProperty("colour", tmp);
         delete[] tmp;
-    } else if (key == "xmldata") {
+    } else if (key == "templatetext") {
+        char *tmp = (char *) qstrdup(value.toUtf8().data());
+        setProducerProperty("templatetext", tmp);
+        delete[] tmp;
         setProducerProperty("force_reload", 1);
+    } else if (key == "xmldata") {
+        char *tmp = (char *) qstrdup(value.toUtf8().data());
+        setProducerProperty("xmldata", tmp);
+        delete[] tmp;
+        //setProducerProperty("force_reload", 1);
     } else if (key == "force_aspect_ratio") {
         if (value.isEmpty()) {
             m_properties.remove("force_aspect_ratio");
index aa9d9ffadbdd5cc266e0f320cdb1a648bd4e70f2..30b32772580747e8c446084b1cc4cc76bff912d8 100644 (file)
@@ -177,7 +177,7 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int in, int out)
             if (pa.attribute("max").startsWith('%')) {
                 max = (int) ProfilesDialog::getStringEval(m_profile, pa.attribute("max"));
             } else max = pa.attribute("max").toInt();
-            createSliderItem(paramName, (int)(value.toDouble() + 0.5) , min, max);
+            createSliderItem(paramName, (int)(value.toDouble() + 0.5) , min, max, pa.attribute("suffix", QString()));
             delete toFillin;
             toFillin = NULL;
         } else if (type == "list") {
@@ -505,13 +505,14 @@ void EffectStackEdit::collectAllParameters()
     emit parameterChanged(oldparam, m_params);
 }
 
-void EffectStackEdit::createSliderItem(const QString& name, int val , int min, int max)
+void EffectStackEdit::createSliderItem(const QString& name, int val , int min, int max, const QString suffix)
 {
     QWidget* toFillin = new QWidget;
     Constval *ctval = new Constval;
     ctval->setupUi(toFillin);
     ctval->horizontalSlider->setMinimum(min);
     ctval->horizontalSlider->setMaximum(max);
+    if (!suffix.isEmpty()) ctval->spinBox->setSuffix(suffix);
     ctval->spinBox->setMinimum(min);
     ctval->spinBox->setMaximum(max);
     ctval->horizontalSlider->setPageStep((int)(max - min) / 10);
index 2e6d16e6865099bc7a29e9709f03321a361ecf3e..2a595dfeabf46212da3bd2565c85e8146336723a 100644 (file)
@@ -63,7 +63,7 @@ private:
     QList<UiItem*> m_uiItems;
     QDomElement m_params;
     QMap<QString, void*> m_valueItems;
-    void createSliderItem(const QString& name, int val , int min, int max);
+    void createSliderItem(const QString& name, int val , int min, int max, const QString);
     wipeInfo getWipeInfo(QString value);
     QString getWipeString(wipeInfo info);
     MltVideoProfile m_profile;
index 6b3323ddfad46c8d0f12289f9377cd0b712151a6..d6e277829d7e84a4164ddb6b791e3a92556847d6 100644 (file)
@@ -375,7 +375,7 @@ void Geometryval::slotDeleteFrame(int pos)
 
 void Geometryval::slotAddFrame(int pos)
 {
-    if (pos == -1) pos = m_ui.spinPos->value();
+    if (pos = -1) pos = m_ui.spinPos->value();
     Mlt::GeometryItem item;
     item.frame(pos);
     item.x(m_paramRect->pos().x());
index ab33a5fb86dd23f3a97c0136df5c3dadddf78c99..0b56aa9494d3a5e90b993e25d7bcb4fbaf3baec0 100644 (file)
@@ -231,8 +231,11 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
 
 KdenliveDoc::~KdenliveDoc()
 {
+    m_autoSaveTimer->stop();
     delete m_commandStack;
+    kDebug() << "// DEL CLP MAN";
     delete m_clipManager;
+    kDebug() << "// DEL CLP MAN done";
     delete m_autoSaveTimer;
     if (m_autosave) {
         if (!m_autosave->fileName().isEmpty()) m_autosave->remove();
@@ -803,7 +806,7 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem)
         if (elem.attribute("type").toInt() == SLIDESHOW) {
             extension = KUrl(path).fileName();
             path = KUrl(path).directory();
-        } else if (elem.attribute("type").toInt() == TEXT && QFile::exists(path) == false) {
+        } /*else if (elem.attribute("type").toInt() == TEXT && QFile::exists(path) == false) {
             kDebug() << "// TITLE: " << elem.attribute("name") << " Preview file: " << elem.attribute("resource") << " DOES NOT EXIST";
             QString titlename = elem.attribute("name");
             QString titleresource;
@@ -826,7 +829,7 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem)
             elem.setAttribute("resource", titleresource);
             setNewClipResource(clipId, titleresource);
             delete dia_ui;
-        }
+        }*/
 
         if (path.isEmpty() == false && QFile::exists(path) == false && elem.attribute("type").toInt() != TEXT && !elem.hasAttribute("placeholder")) {
             kDebug() << "// FOUND MISSING CLIP: " << path << ", TYPE: " << elem.attribute("type").toInt();
@@ -1037,13 +1040,13 @@ void KdenliveDoc::slotCreateTextClip(QString group, const QString &groupId, cons
 {
     QString titlesFolder = projectFolder().path(KUrl::AddTrailingSlash) + "titles/";
     KStandardDirs::makeDir(titlesFolder);
-    TitleWidget *dia_ui = new TitleWidget(templatePath, titlesFolder, m_render, kapp->activeWindow());
+    TitleWidget *dia_ui = new TitleWidget(templatePath, m_timecode, titlesFolder, m_render, kapp->activeWindow());
     if (dia_ui->exec() == QDialog::Accepted) {
-        QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder());
+        /*QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder());
         QImage pix = dia_ui->renderedPixmap();
-        pix.save(titleInfo.at(1));
+        pix.save(titleInfo.at(1));*/
         //dia_ui->saveTitle(path + ".kdenlivetitle");
-        m_clipManager->slotAddTextClipFile(titleInfo.at(0), titleInfo.at(1), dia_ui->xml().toString(), group, groupId);
+        m_clipManager->slotAddTextClipFile(i18n("Title clip"), dia_ui->duration(), dia_ui->xml().toString(), group, groupId);
         setModified(true);
         emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
     }
@@ -1061,12 +1064,13 @@ void KdenliveDoc::slotCreateTextTemplateClip(QString group, const QString &group
 
     QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder(), true);
 
-    TitleWidget *dia_ui = new TitleWidget(path, titlesFolder, m_render, kapp->activeWindow());
+    //TODO: rewrite with new title system (just set resource)
+    /*TitleWidget *dia_ui = new TitleWidget(path, titlesFolder, m_render, kapp->activeWindow());
     QImage pix = dia_ui->renderedPixmap();
     pix.save(titleInfo.at(1));
     delete dia_ui;
     m_clipManager->slotAddTextTemplateClip(titleInfo.at(0), titleInfo.at(1), path, group, groupId);
-    setModified(true);
+    setModified(true);*/
     emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
 }
 
index e36ca100449aa002ffa07b56ba67a0e1a43af2f3..b099be387ac2681010f957ad73b39b076d203915 100644 (file)
@@ -68,7 +68,6 @@
     <Menu name="timeline" ><text>Timeline</text>
       <Action name="cut_timeline_clip" />
       <Action name="delete_timeline_clip" />
-      <Action name="change_clip_speed" />
       <Menu name="guide_menu" ><text>Guides</text>
                <Action name="add_guide" />
                <Action name="edit_guide" />
index 43d32f02eec08cf3c388f7e14321f0755424ea48..488975e9079595698f7b17a6e5be87f367c7a665 100644 (file)
@@ -328,7 +328,6 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
     m_timelineContextMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Paste)));
 
     m_timelineContextClipMenu->addAction(actionCollection()->action("delete_timeline_clip"));
-    m_timelineContextClipMenu->addAction(actionCollection()->action("change_clip_speed"));
     m_timelineContextClipMenu->addAction(actionCollection()->action("group_clip"));
     m_timelineContextClipMenu->addAction(actionCollection()->action("ungroup_clip"));
     m_timelineContextClipMenu->addAction(actionCollection()->action("cut_timeline_clip"));
@@ -381,11 +380,20 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
 
 void MainWindow::queryQuit()
 {
-    kDebug() << "----- SAVING CONFUIG";
-    if (queryClose()) {
-        Mlt::Factory::close();
-        kapp->quit();
-    }
+    delete m_effectStack;
+    delete m_activeTimeline;
+    delete m_projectMonitor;
+    kDebug() << "// DEL MON 1 done";
+    delete m_clipMonitor;
+    kDebug() << "// DEL MON 2 done";
+    delete m_activeDocument;
+    Mlt::Factory::close();
+    qApp->quit();
+    /*
+       if (queryClose()) {
+           Mlt::Factory::close();
+           kapp->quit();
+       }*/
 }
 
 //virtual
@@ -946,10 +954,10 @@ void MainWindow::setupActions()
     collection->addAction("delete_timeline_clip", deleteTimelineClip);
     connect(deleteTimelineClip, SIGNAL(triggered(bool)), this, SLOT(slotDeleteTimelineClip()));
 
-    KAction* editTimelineClipSpeed = new KAction(i18n("Change Clip Speed"), this);
+    /*KAction* editTimelineClipSpeed = new KAction(i18n("Change Clip Speed"), this);
     collection->addAction("change_clip_speed", editTimelineClipSpeed);
     editTimelineClipSpeed->setData("change_speed");
-    connect(editTimelineClipSpeed, SIGNAL(triggered(bool)), this, SLOT(slotChangeClipSpeed()));
+    connect(editTimelineClipSpeed, SIGNAL(triggered(bool)), this, SLOT(slotChangeClipSpeed()));*/
 
     KAction *stickTransition = collection->addAction("auto_transition");
     stickTransition->setData(QString("auto"));
@@ -1950,13 +1958,6 @@ void MainWindow::slotDeleteTimelineClip()
     }
 }
 
-void MainWindow::slotChangeClipSpeed()
-{
-    if (m_activeTimeline) {
-        m_activeTimeline->projectView()->changeClipSpeed();
-    }
-}
-
 void MainWindow::slotAddClipMarker()
 {
     DocClipBase *clip = NULL;
@@ -2291,7 +2292,7 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip)
             return;
         }
         QString path = clip->getProperty("resource");
-        TitleWidget *dia_ui = new TitleWidget(KUrl(), titlepath, m_projectMonitor->render, this);
+        TitleWidget *dia_ui = new TitleWidget(KUrl(), m_activeDocument->timecode(), titlepath, m_projectMonitor->render, this);
         QDomDocument doc;
         doc.setContent(clip->getProperty("xmldata"));
         dia_ui->setXml(doc);
@@ -2299,6 +2300,7 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip)
             QRect rect = dia_ui->renderedRect();
             QMap <QString, QString> newprops;
             newprops.insert("xmldata", dia_ui->xml().toString());
+            newprops.insert("out", QString::number(dia_ui->duration()));
             newprops.insert("frame_size", QString::number(rect.width()) + 'x' + QString::number(rect.height()));
             EditClipCommand *command = new EditClipCommand(m_projectList, clip->getId(), clip->properties(), newprops, true);
             m_activeDocument->commandStack()->push(command);
index d031f0b21a5227cd3dcdb30920a873dea8c5190f..9133655fcc352c0d5703e74cc74cce1ab2e8cf1d 100644 (file)
@@ -272,7 +272,6 @@ private slots:
     void slotPaste();
     void slotPasteEffects();
     void slotReloadEffects();
-    void slotChangeClipSpeed();
 
     void slotAdjustClipMonitor();
     void slotAdjustProjectMonitor();
index 7e3b6803c6dbab8c4123e37726338d26eaf01285..e4445c59b5bf0b481e743c68ff4f3f2de45ea494 100644 (file)
@@ -5,4 +5,9 @@
     <sub-class-of type="video/mlt-playlist"/>
     <glob pattern="*.kdenlive"/>
   </mime-type>
+  <mime-type type="application/x-kdenlivetitle">
+    <comment>Kdenlive video title</comment>
+    <sub-class-of type="application/xml"/>
+    <glob pattern="*.kdenlivetitle"/>
+  </mime-type>
 </mime-info>
index b0f7991ec5e23277014aa32f1e5caa0f945a47bc..0c12a74df5c20e0e6c5ff9ba4686ac6e8ea13fef 100644 (file)
@@ -150,6 +150,7 @@ Monitor::~Monitor()
     delete m_timePos;
     delete m_overlay;
     delete m_monitorRefresh;
+    delete render;
 }
 
 QString Monitor::name() const
index bb5f18f012666ca2ecd0c7ddc9d682f06ef8d218..2fc16122af197408bdde8fbcc78f6c5bc3ceac23 100644 (file)
@@ -275,7 +275,7 @@ void ProjectList::slotUpdateClipProperties(const QString &id, QMap <QString, QSt
     ProjectItem *item = getItemById(id);
     if (item) {
         slotUpdateClipProperties(item, properties);
-        if (properties.contains("colour") || properties.contains("resource") || properties.contains("xmldata") || properties.contains("force_aspect_ratio")) {
+        if (properties.contains("colour") || properties.contains("resource") || properties.contains("xmldata") || properties.contains("force_aspect_ratio") || properties.contains("templatetext")) {
             slotRefreshClipThumbnail(item);
             emit refreshClip();
         }
@@ -287,7 +287,7 @@ void ProjectList::slotUpdateClipProperties(ProjectItem *clip, QMap <QString, QSt
 {
     if (!clip) return;
     if (!clip->isGroup()) clip->setProperties(properties);
-    if (properties.contains("xmldata")) regenerateTemplateImage(clip);
+    //if (properties.contains("xmldata")) regenerateTemplateImage(clip);
     if (properties.contains("name")) {
         m_listView->blockSignals(true);
         clip->setText(1, properties.value("name"));
@@ -318,10 +318,12 @@ void ProjectList::slotItemEdited(QTreeWidgetItem *item, int column)
             oldprops["description"] = clip->referencedClip()->getProperty("description");
             newprops["description"] = item->text(2);
 
-            if (clip->clipType() == TEXT && !clip->referencedClip()->getProperty("xmltemplate").isEmpty()) {
+            if (clip->clipType() == TEXT && !clip->referencedClip()->getProperty("xmldata").isEmpty()) {
                 // This is a text template clip, update the image
-                oldprops.insert("xmldata", clip->referencedClip()->getProperty("xmldata"));
-                newprops.insert("xmldata", generateTemplateXml(clip->referencedClip()->getProperty("xmltemplate"), item->text(2)).toString());
+                /*oldprops.insert("xmldata", clip->referencedClip()->getProperty("xmldata"));
+                newprops.insert("xmldata", generateTemplateXml(clip->referencedClip()->getProperty("xmltemplate"), item->text(2)).toString());*/
+                oldprops.insert("templatetext", clip->referencedClip()->getProperty("templatetext"));
+                newprops.insert("templatetext", item->text(2));
             }
 
             slotUpdateClipProperties(clip->clipId(), newprops);
@@ -583,7 +585,7 @@ void ProjectList::updateAllClips()
         ProjectItem *item = static_cast <ProjectItem *>(*it);
         if (!item->isGroup()) {
             DocClipBase *clip = item->referencedClip();
-            if (clip->clipType() == TEXT && !QFile::exists(clip->fileURL().path())) {
+            /*if (clip->clipType() == TEXT && !QFile::exists(clip->fileURL().path())) {
                 // regenerate text clip image if required
                 TitleWidget *dia_ui = new TitleWidget(KUrl(), QString(), m_render, this);
                 QDomDocument doc;
@@ -592,7 +594,7 @@ void ProjectList::updateAllClips()
                 QImage pix = dia_ui->renderedPixmap();
                 pix.save(clip->fileURL().path());
                 delete dia_ui;
-            }
+            }*/
 
             if (item->referencedClip()->producer() == NULL) {
                 if (clip->isPlaceHolder() == false) requestClipInfo(clip->toXML(), clip->getId());
@@ -623,7 +625,7 @@ void ProjectList::slotAddClip(const QList <QUrl> givenList, const QString &group
     KUrl::List list;
     if (givenList.isEmpty()) {
         // Build list of mime types
-        QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/x-matroska" << "video/mlt-playlist" << "video/mpeg" << "video/ogg" << "video/x-ms-wmv" << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "application/ogg" << "video/mp4" << "video/quicktime" << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr";
+        QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "application/x-kdenlivetitle" << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/x-matroska" << "video/mlt-playlist" << "video/mpeg" << "video/ogg" << "video/x-ms-wmv" << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "application/ogg" << "video/mp4" << "video/quicktime" << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr";
 
         QString allExtensions;
         foreach(const QString& mimeType, mimeTypes) {
@@ -970,28 +972,30 @@ void ProjectList::regenerateTemplate(const QString &id)
 
 void ProjectList::regenerateTemplate(ProjectItem *clip)
 {
+    //TODO: remove this unused method, only force_reload is necessary
     // Generate image for template clip
-    const QString comment = clip->referencedClip()->getProperty("description");
-    const QString path = clip->referencedClip()->getProperty("xmltemplate");
+    /*const QString comment = clip->referencedClip()->getProperty("description");
+    const QString path = clip->referencedClip()->getProperty("resource");
     QDomDocument doc = generateTemplateXml(path, comment);
     TitleWidget *dia_ui = new TitleWidget(KUrl(), QString(), m_render, this);
     dia_ui->setXml(doc);
     QImage pix = dia_ui->renderedPixmap();
     pix.save(clip->clipUrl().path());
-    delete dia_ui;
+    delete dia_ui;*/
     clip->referencedClip()->producer()->set("force_reload", 1);
 }
 
 void ProjectList::regenerateTemplateImage(ProjectItem *clip)
 {
+    //TODO: remove this unused method
     // Generate image for template clip
-    TitleWidget *dia_ui = new TitleWidget(KUrl(), QString(), m_render, this);
+    /*TitleWidget *dia_ui = new TitleWidget(KUrl(), QString(), m_render, this);
     QDomDocument doc;
     doc.setContent(clip->referencedClip()->getProperty("xmldata"));
     dia_ui->setXml(doc);
     QImage pix = dia_ui->renderedPixmap();
     pix.save(clip->clipUrl().path());
-    delete dia_ui;
+    delete dia_ui;*/
 }
 
 QDomDocument ProjectList::generateTemplateXml(QString path, const QString &replaceString)
index fabe6a23d2356ac40bdde9354ec20337d6ca9608..d96f6a7b2145246144432a7617ce42af35689e5a 100644 (file)
@@ -154,6 +154,9 @@ void ProjectListView::dropEvent(QDropEvent *event)
             }
         }
         emit addClip(event->mimeData()->urls(), groupName, groupId);
+        event->setDropAction(Qt::CopyAction);
+        event->accept();
+        return;
     } else if (event->mimeData()->hasFormat("kdenlive/producerslist")) {
         ProjectItem *item = static_cast <ProjectItem *>(itemAt(event->pos()));
         if (item) {
@@ -258,7 +261,7 @@ void ProjectListView::mouseMoveEvent(QMouseEvent *event)
             drag->setMimeData(mimeData);
             drag->setPixmap(clickItem->icon(0).pixmap(iconSize()));
             drag->setHotSpot(QPoint(0, 50));
-            drag->exec(Qt::MoveAction);
+            drag->exec();
         }
         //event->accept();
     }
@@ -267,8 +270,7 @@ void ProjectListView::mouseMoveEvent(QMouseEvent *event)
 // virtual
 void ProjectListView::dragMoveEvent(QDragMoveEvent * event)
 {
-    event->setDropAction(Qt::IgnoreAction);
-    event->setDropAction(Qt::MoveAction);
+    //event->setDropAction(Qt::MoveAction);
     if (event->mimeData()->hasText()) {
         event->acceptProposedAction();
     }
index 05fc9c62868fef253382477cf17801e5793d8c01..cb5c8e2508700fc15cf37d8ad7618c848d4893e6 100644 (file)
@@ -77,13 +77,11 @@ Render::Render(const QString & rendererName, int winid, int /* extid */, QWidget
         m_winid(winid)
 {
     kDebug() << "//////////  USING PROFILE: " << (char*)KdenliveSettings::current_profile().toUtf8().data();
-    m_refreshTimer = new QTimer(this);
-    connect(m_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
 
     /*if (rendererName == "project") m_monitorId = 10000;
     else m_monitorId = 10001;*/
-    m_osdTimer = new QTimer(this);
-    connect(m_osdTimer, SIGNAL(timeout()), this, SLOT(slotOsdTimeout()));
+    /*m_osdTimer = new QTimer(this);
+    connect(m_osdTimer, SIGNAL(timeout()), this, SLOT(slotOsdTimeout()));*/
 
     buildConsumer();
 
@@ -101,8 +99,22 @@ Render::~Render()
 
 void Render::closeMlt()
 {
-    delete m_osdTimer;
-    delete m_refreshTimer;
+    //delete m_osdTimer;
+
+    Mlt::Service service(m_mltProducer->get_service());
+    if (service.type() == tractor_type) {
+        Mlt::Tractor tractor(service);
+        int trackNb = tractor.count();
+
+        while (trackNb > 1) {
+            Mlt::Producer trackProducer(tractor.track(trackNb - 1));
+            Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+            trackPlaylist.clear();
+            trackNb--;
+        }
+    }
+
+    kDebug() << "// // // CLOSE RENDERER";
     delete m_mltConsumer;
     delete m_mltProducer;
     delete m_blackClip;
@@ -512,14 +524,23 @@ void Render::getFileProperties(const QDomElement &xml, const QString &clipId, bo
 {
     KUrl url = KUrl(xml.attribute("resource", QString()));
     Mlt::Producer *producer = NULL;
-    if (xml.attribute("type").toInt() == TEXT && !QFile::exists(url.path())) {
+    /*if (xml.attribute("type").toInt() == TEXT && !QFile::exists(url.path())) {
         emit replyGetFileProperties(clipId, producer, QMap < QString, QString >(), QMap < QString, QString >(), replaceProducer);
         return;
-    }
+    }*/
     if (xml.attribute("type").toInt() == COLOR) {
         char *tmp = decodedString("colour:" + xml.attribute("colour"));
         producer = new Mlt::Producer(*m_mltProfile, 0, tmp);
         delete[] tmp;
+    } else if (xml.attribute("type").toInt() == TEXT) {
+        char *tmp = decodedString("kdenlivetitle:" + xml.attribute("resource"));
+        producer = new Mlt::Producer(*m_mltProfile, 0, tmp);
+        delete[] tmp;
+        if (xml.hasAttribute("xmldata")) {
+            char *tmp = decodedString(xml.attribute("xmldata"));
+            producer->set("xmldata", tmp);
+            delete[] tmp;
+        }
     } else if (url.isEmpty()) {
         QDomDocument doc;
         QDomElement mlt = doc.createElement("mlt");
@@ -956,6 +977,7 @@ void Render::saveZone(KUrl url, QString desc, QPoint zone)
         tmppath = decodedString(desc);
         Mlt::Playlist list;
         list.insert_at(0, prod, 0);
+        delete prod;
         list.set("title", tmppath);
         delete[] tmppath;
         xmlConsumer.connect(list);
@@ -1037,7 +1059,7 @@ void Render::setVolume(double /*volume*/)
      if (m_mltProducer->attach(*m_osdInfo) == 1) kDebug()<<"////// error attaching filter";
     }*/
     refresh();
-    m_osdTimer->setSingleShot(2500);
+    //m_osdTimer->setSingleShot(2500);
 }
 
 void Render::slotOsdTimeout()
@@ -1247,12 +1269,6 @@ void Render::seekToFrameDiff(int diff)
     refresh();
 }
 
-void Render::askForRefresh()
-{
-    // Use a Timer so that we don't refresh too much
-    m_refreshTimer->start(300);
-}
-
 void Render::doRefresh()
 {
     // Use a Timer so that we don't refresh too much
@@ -1263,7 +1279,6 @@ void Render::refresh()
 {
     if (!m_mltProducer || m_isBlocked)
         return;
-    m_refreshTimer->stop();
     if (m_mltConsumer) {
         m_mltConsumer->set("refresh", 1);
     }
@@ -1434,19 +1449,23 @@ void Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *pr
     Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
     //kDebug()<<"/// INSERT cLIP: "<<info.cropStart.frames(m_fps)<<", "<<info.startPos.frames(m_fps)<<"-"<<info.endPos.frames(m_fps);
 
-    if (element.attribute("speed", "1.0").toDouble() != 1.0) {
+    if (element.attribute("speed", "1.0").toDouble() != 1.0 || element.attribute("strobe", "1").toInt() > 1) {
         // We want a slowmotion producer
         double speed = element.attribute("speed", "1.0").toDouble();
+        int strobe = element.attribute("strobe", "1").toInt();
         QString url = QString::fromUtf8(prod->get("resource"));
         url.append('?' + QString::number(speed));
+        if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
         Mlt::Producer *slowprod = m_slowmotionProducers.value(url);
         if (!slowprod || slowprod->get_producer() == NULL) {
             char *tmp = decodedString(url);
             slowprod = new Mlt::Producer(*m_mltProfile, "framebuffer", tmp);
+            if (strobe > 1) slowprod->set("strobe", strobe);
             delete[] tmp;
             QString id = prod->get("id");
             if (id.contains('_')) id = id.section('_', 0, 0);
             QString producerid = "slowmotion:" + id + ':' + QString::number(speed);
+            if (strobe > 1) producerid.append(':' + QString::number(strobe));
             tmp = decodedString(producerid);
             slowprod->set("id", tmp);
             delete[] tmp;
@@ -1456,8 +1475,8 @@ void Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *pr
     }
 
     Mlt::Producer *clip = prod->cut((int) info.cropStart.frames(m_fps), (int)(info.endPos - info.startPos + info.cropStart).frames(m_fps) - 1);
-    int newIndex = trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *clip, 1);
-
+    int newIndex = trackPlaylist.insert_at((int) info.startPos.frames(m_fps), clip, 1);
+    delete clip;
     /*if (QString(prod->get("transparency")).toInt() == 1)
         mltAddClipTransparency(info, info.track - 1, QString(prod->get("id")).toInt());*/
 
@@ -1514,6 +1533,8 @@ void Render::mltCutClip(int track, GenTime position)
     }
     Mlt::Service clipService(original->get_service());
     Mlt::Service dupService(clip->get_service());
+    delete original;
+    delete clip;
     int ct = 0;
     Mlt::Filter *filter = clipService.filter(ct);
     while (filter) {
@@ -1582,7 +1603,8 @@ bool Render::mltRemoveClip(int track, GenTime position)
     }
     //kDebug()<<"////  Deleting at: "<< (int) position.frames(m_fps) <<" --------------------------------------";
     m_isBlocked = true;
-    trackPlaylist.replace_with_blank(clipIndex);
+    Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
+    delete clip;
     trackPlaylist.consolidate_blanks(0);
     /*if (QString(clip.parent().get("transparency")).toInt() == 1)
         mltDeleteTransparency((int) position.frames(m_fps), track, QString(clip.parent().get("id")).toInt());*/
@@ -1679,11 +1701,11 @@ void Render::mltInsertSpace(QMap <int, int> trackClipStartList, QMap <int, int>
                 if (!trackPlaylist.is_blank(clipIndex)) clipIndex --;
                 if (!trackPlaylist.is_blank(clipIndex)) kDebug() << "//// ERROR TRYING TO DELETE SPACE FROM " << insertPos;
                 int position = trackPlaylist.clip_start(clipIndex);
-                int blankDuration = trackPlaylist.clip_length(clipIndex) - 1;
+                int blankDuration = trackPlaylist.clip_length(clipIndex);
                 diff = -diff;
-                if (blankDuration - diff == 1)
+                if (blankDuration - diff == 0)
                     trackPlaylist.remove(clipIndex);
-                else trackPlaylist.remove_region(position, diff - 1);
+                else trackPlaylist.remove_region(position, diff);
             }
             trackPlaylist.consolidate_blanks(0);
         }
@@ -1740,10 +1762,10 @@ void Render::mltInsertSpace(QMap <int, int> trackClipStartList, QMap <int, int>
                     if (!trackPlaylist.is_blank(clipIndex)) clipIndex --;
                     if (!trackPlaylist.is_blank(clipIndex)) kDebug() << "//// ERROR TRYING TO DELETE SPACE FROM " << insertPos;
                     int position = trackPlaylist.clip_start(clipIndex);
-                    int blankDuration = trackPlaylist.clip_length(clipIndex) - 1;
-                    if (diff + blankDuration == 1)
+                    int blankDuration = trackPlaylist.clip_length(clipIndex);
+                    if (diff + blankDuration == 0)
                         trackPlaylist.remove(clipIndex);
-                    else trackPlaylist.remove_region(position, - diff - 1);
+                    else trackPlaylist.remove_region(position, - diff);
                 }
                 trackPlaylist.consolidate_blanks(0);
             }
@@ -1798,7 +1820,7 @@ void Render::mltPasteEffects(Mlt::Producer *source, Mlt::Producer *dest)
     }
 }
 
-int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt::Producer *prod)
+int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, int strobe, Mlt::Producer *prod)
 {
     m_isBlocked = true;
     int newLength = 0;
@@ -1831,22 +1853,26 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
     QString serv = clipparent.get("mlt_service");
     QString id = clipparent.get("id");
     //kDebug() << "CLIP SERVICE: " << serv;
-    if (serv == "avformat" && speed != 1.0) {
+    if (serv == "avformat" && (speed != 1.0 || strobe > 1)) {
         mlt_service_lock(service.get_service());
         QString url = QString::fromUtf8(clipparent.get("resource"));
         url.append('?' + QString::number(speed));
+        if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
         Mlt::Producer *slowprod = m_slowmotionProducers.value(url);
         if (!slowprod || slowprod->get_producer() == NULL) {
             char *tmp = decodedString(url);
             slowprod = new Mlt::Producer(*m_mltProfile, "framebuffer", tmp);
+            if (strobe > 1) slowprod->set("strobe", strobe);
             delete[] tmp;
             QString producerid = "slowmotion:" + id + ':' + QString::number(speed);
+            if (strobe > 1) producerid.append(':' + QString::number(strobe));
             tmp = decodedString(producerid);
             slowprod->set("id", tmp);
             delete[] tmp;
             m_slowmotionProducers.insert(url, slowprod);
         }
-        trackPlaylist.replace_with_blank(clipIndex);
+        Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
+        delete clip;
         trackPlaylist.consolidate_blanks(0);
         // Check that the blank space is long enough for our new duration
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
@@ -1860,14 +1886,16 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
         // move all effects to the correct producer
         mltPasteEffects(clip, cut);
 
-        trackPlaylist.insert_at(startPos, *cut, 1);
+        trackPlaylist.insert_at(startPos, cut, 1);
+        delete cut;
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
         newLength = trackPlaylist.clip_length(clipIndex);
         mlt_service_unlock(service.get_service());
-    } else if (speed == 1.0) {
+    } else if (speed == 1.0 && strobe < 2) {
         mlt_service_lock(service.get_service());
 
-        trackPlaylist.replace_with_blank(clipIndex);
+        Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
+        delete clip;
         trackPlaylist.consolidate_blanks(0);
 
         // Check that the blank space is long enough for our new duration
@@ -1885,7 +1913,8 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
         // move all effects to the correct producer
         mltPasteEffects(clip, cut);
 
-        trackPlaylist.insert_at(startPos, *cut, 1);
+        trackPlaylist.insert_at(startPos, cut, 1);
+        delete cut;
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
         newLength = trackPlaylist.clip_length(clipIndex);
         mlt_service_unlock(service.get_service());
@@ -1895,22 +1924,26 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
         QString url = QString::fromUtf8(clipparent.get("resource"));
         url = url.section('?', 0, 0);
         url.append('?' + QString::number(speed));
+        if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
         Mlt::Producer *slowprod = m_slowmotionProducers.value(url);
         if (!slowprod || slowprod->get_producer() == NULL) {
             char *tmp = decodedString(url);
             slowprod = new Mlt::Producer(*m_mltProfile, "framebuffer", tmp);
             delete[] tmp;
+            slowprod->set("strobe", strobe);
             QString producerid = "slowmotion:" + id.section(':', 1, 1) + ':' + QString::number(speed);
+            if (strobe > 1) producerid.append(':' + QString::number(strobe));
             tmp = decodedString(producerid);
             slowprod->set("id", tmp);
             delete[] tmp;
             m_slowmotionProducers.insert(url, slowprod);
         }
-        trackPlaylist.replace_with_blank(clipIndex);
+        Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
+        delete clip;
         trackPlaylist.consolidate_blanks(0);
 
         GenTime oldDuration = GenTime(clipLength, m_fps);
-        GenTime newDuration = oldDuration * oldspeed / speed;
+        GenTime newDuration = oldDuration * (oldspeed / speed);
 
         // Check that the blank space is long enough for our new duration
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
@@ -1925,7 +1958,8 @@ int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt
         // move all effects to the correct producer
         mltPasteEffects(clip, cut);
 
-        trackPlaylist.insert_at(startPos, *cut, 1);
+        trackPlaylist.insert_at(startPos, cut, 1);
+        delete cut;
         clipIndex = trackPlaylist.get_clip_index_at(startPos);
         newLength = trackPlaylist.clip_length(clipIndex);
 
@@ -1952,6 +1986,7 @@ bool Render::mltRemoveEffect(int track, GenTime position, QString index, bool up
         return success;
     }
     Mlt::Service clipService(clip->get_service());
+    delete clip;
 //    if (tag.startsWith("ladspa")) tag = "ladspa";
     m_isBlocked = true;
     int ct = 0;
@@ -1988,7 +2023,7 @@ bool Render::mltAddEffect(int track, GenTime position, EffectsParameterList para
     }
     Mlt::Service clipService(clip->get_service());
     m_isBlocked = true;
-
+    delete clip;
     // temporarily remove all effects after insert point
     QList <Mlt::Filter *> filtersList;
     const int filter_ix = params.paramValue("kdenlive_ix").toInt();
@@ -2136,6 +2171,7 @@ bool Render::mltEditEffect(int track, GenTime position, EffectsParameterList par
         return false;
     }
     Mlt::Service clipService(clip->get_service());
+    delete clip;
     m_isBlocked = true;
     int ct = 0;
     Mlt::Filter *filter = clipService.filter(ct);
@@ -2200,6 +2236,7 @@ void Render::mltMoveEffect(int track, GenTime position, int oldPos, int newPos)
         return;
     }
     Mlt::Service clipService(clip->get_service());
+    delete clip;
     m_isBlocked = true;
     int ct = 0;
     QList <Mlt::Filter *> filtersList;
@@ -2306,11 +2343,11 @@ bool Render::mltResizeClipEnd(ItemInfo info, GenTime clipDuration)
             // If this is not the last clip in playlist
             if (trackPlaylist.is_blank(clipIndex)) {
                 int blankStart = trackPlaylist.clip_start(clipIndex);
-                int blankDuration = trackPlaylist.clip_length(clipIndex) - 1;
+                int blankDuration = trackPlaylist.clip_length(clipIndex);
                 if (diff > blankDuration) kDebug() << "// ERROR blank clip is not large enough to get back required space!!!";
-                if (diff - blankDuration == 1) {
+                if (diff - blankDuration == 0) {
                     trackPlaylist.remove(clipIndex);
-                } else trackPlaylist.remove_region(blankStart, diff - 1);
+                } else trackPlaylist.remove_region(blankStart, diff);
             } else {
                 kDebug() << "/// RESIZE ERROR, NXT CLIP IS NOT BLK: " << clipIndex;
             }
@@ -2462,19 +2499,21 @@ void Render::mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod)
     Mlt::Producer trackProducer(tractor.track(track));
     Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
     int clipIndex = trackPlaylist.get_clip_index_at(pos + 1);
-    Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
-    if (clipProducer.is_blank()) {
+    Mlt::Producer *clipProducer = trackPlaylist.replace_with_blank(clipIndex);
+    if (clipProducer->is_blank()) {
         kDebug() << "// ERROR UPDATING CLIP PROD";
+        delete clipProducer;
         mlt_service_unlock(m_mltConsumer->get_service());
         m_isBlocked--;
         return;
     }
-    Mlt::Producer *clip = prod->cut(clipProducer.get_in(), clipProducer.get_out());
+    Mlt::Producer *clip = prod->cut(clipProducer->get_in(), clipProducer->get_out());
 
     // move all effects to the correct producer
-    mltPasteEffects(&clipProducer, clip);
-
+    mltPasteEffects(clipProducer, clip);
     trackPlaylist.insert_at(pos, clip, 1);
+    delete clip;
+    delete clipProducer;
     mlt_service_unlock(m_mltConsumer->get_service());
     m_isBlocked--;
 }
@@ -2494,10 +2533,11 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
     kDebug() << "//////  LOOKING FOR CLIP TO MOVE, INDEX: " << clipIndex;
     bool checkLength = false;
     if (endTrack == startTrack) {
-        Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
-        if (!trackPlaylist.is_blank_at(moveEnd) || clipProducer.is_blank()) {
+        Mlt::Producer *clipProducer = trackPlaylist.replace_with_blank(clipIndex);
+        if (!trackPlaylist.is_blank_at(moveEnd) || clipProducer->is_blank()) {
             // error, destination is not empty
             if (!trackPlaylist.is_blank_at(moveEnd)) trackPlaylist.insert_at(moveStart, clipProducer, 1);
+            delete clipProducer;
             //int ix = trackPlaylist.get_clip_index_at(moveEnd);
             kDebug() << "// ERROR MOVING CLIP TO : " << moveEnd;
             mlt_service_unlock(service.get_service());
@@ -2506,6 +2546,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
         } else {
             trackPlaylist.consolidate_blanks(0);
             int newIndex = trackPlaylist.insert_at(moveEnd, clipProducer, 1);
+            delete clipProducer;
             /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
             mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt());
             }*/
@@ -2521,10 +2562,11 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
             m_isBlocked--;
             return false;
         } else {
-            Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
-            if (clipProducer.is_blank()) {
+            Mlt::Producer *clipProducer = trackPlaylist.replace_with_blank(clipIndex);
+            if (clipProducer->is_blank()) {
                 // error, destination is not empty
                 //int ix = trackPlaylist.get_clip_index_at(moveEnd);
+                delete clipProducer;
                 kDebug() << "// ERROR MOVING CLIP TO : " << moveEnd;
                 mlt_service_unlock(service.get_service());
                 m_isBlocked--;
@@ -2534,24 +2576,27 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn
             destTrackPlaylist.consolidate_blanks(1);
             Mlt::Producer *clip;
             // check if we are moving a slowmotion producer
-            QString serv = clipProducer.parent().get("mlt_service");
-            QString currentid = clipProducer.parent().get("id");
+            QString serv = clipProducer->parent().get("mlt_service");
+            QString currentid = clipProducer->parent().get("id");
             if (serv == "framebuffer" || currentid.endsWith("_video")) {
-                clip = &clipProducer;
+                clip = clipProducer;
             } else {
                 if (prod == NULL) {
                     // Special case: prod is null when using placeholder clips.
                     // in that case, use the producer existing in playlist. Note that
                     // it will bypass the one producer per track logic and might cause
                     // Sound cracks if clip is moved so that it overlaps another copy of itself
-                    clip = clipProducer.cut(clipProducer.get_in(), clipProducer.get_out());
-                } else clip = prod->cut(clipProducer.get_in(), clipProducer.get_out());
+                    clip = clipProducer->cut(clipProducer->get_in(), clipProducer->get_out());
+                } else clip = prod->cut(clipProducer->get_in(), clipProducer->get_out());
             }
 
             // move all effects to the correct producer
-            mltPasteEffects(&clipProducer, clip);
+            mltPasteEffects(clipProducer, clip);
 
             int newIndex = destTrackPlaylist.insert_at(moveEnd, clip, 1);
+            delete clip;
+            clip = NULL;
+            if (clipProducer) delete clipProducer;
             destTrackPlaylist.consolidate_blanks(0);
             /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
                 kDebug() << "//////// moving clip transparency";
@@ -3010,6 +3055,8 @@ void Render::fillSlowMotionProducers()
                 if (id.startsWith("slowmotion:") && !nprod->is_blank()) {
                     // this is a slowmotion producer, add it to the list
                     QString url = QString::fromUtf8(nprod->get("resource"));
+                    int strobe = nprod->get_int("strobe");
+                    if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
                     if (!m_slowmotionProducers.contains(url)) {
                         m_slowmotionProducers.insert(url, nprod);
                     }
index b0990d8852b9137ebb2a7e566d05ed21d0caef8e..b36efdb4fa9eaadc8078ac204ca7cd8de028386c 100644 (file)
@@ -150,7 +150,6 @@ Q_OBJECT public:
     /** Gives the aspect ratio of the consumer */
     double consumerRatio() const;
 
-    void askForRefresh();
     void doRefresh();
 
     /** Save current producer frame as image */
@@ -201,7 +200,7 @@ Q_OBJECT public:
     to the clip and 0.6 is the speed in percents. The newly created producer will have it's
     "id" parameter set to: "slowmotion:parentid:speed", where parentid is the id of the original clip
     in the ClipManager list and speed is the current speed */
-    int mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt::Producer *prod);
+    int mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, int strobe, Mlt::Producer *prod);
 
     QList <Mlt::Producer *> producersList();
     void updatePreviewSettings();
@@ -228,7 +227,6 @@ private:   // Private attributes & methods
     Mlt::Producer *m_blackClip;
     QString m_activeProfile;
 
-    QTimer *m_refreshTimer;
     QTimer *m_osdTimer;
 
     /** A human-readable description of this renderer. */
index 3fcf28fc84d676a8b753cf0e3b4a49c0c5188860..b7a5581257378e34924c0f98eed275b2245b7cfd 100644 (file)
@@ -32,7 +32,7 @@
 #include <QKeyEvent>
 #include <QPushButton>
 #include <QPixmap>
-#include <QTimer>
+
 
 StatusBarMessageLabel::StatusBarMessageLabel(QWidget* parent) :
         QWidget(parent),
@@ -40,7 +40,6 @@ StatusBarMessageLabel::StatusBarMessageLabel(QWidget* parent) :
         m_state(Default),
         m_illumination(-64),
         m_minTextHeight(-1),
-        m_timer(0),
         m_closeButton(0)
 {
     setMinimumHeight(KIconLoader::SizeSmall);
@@ -49,8 +48,7 @@ StatusBarMessageLabel::StatusBarMessageLabel(QWidget* parent) :
     palette.setColor(QPalette::Background, Qt::transparent);
     setPalette(palette);
 
-    m_timer = new QTimer(this);
-    connect(m_timer, SIGNAL(timeout()), this, SLOT(timerDone()));
+    connect(&m_timer, SIGNAL(timeout()), this, SLOT(timerDone()));
 
     m_closeButton = new QPushButton(i18nc("@action:button", "Close"), this);
     m_closeButton->hide();
@@ -83,7 +81,7 @@ void StatusBarMessageLabel::setMessage(const QString& text,
 
     m_illumination = -64;
     m_state = Default;
-    m_timer->stop();
+    m_timer.stop();
 
     const char* iconName = 0;
     QPixmap pixmap;
@@ -101,14 +99,14 @@ void StatusBarMessageLabel::setMessage(const QString& text,
 
     case ErrorMessage:
         iconName = "dialog-warning";
-        m_timer->start(100);
+        m_timer.start(100);
         m_state = Illuminate;
         m_closeButton->hide();
         break;
 
     case MltError:
         iconName = "dialog-close";
-        m_timer->start(100);
+        m_timer.start(100);
         m_state = Illuminate;
         updateCloseButtonPosition();
         m_closeButton->show();
@@ -192,7 +190,7 @@ void StatusBarMessageLabel::timerDone()
             update();
         } else {
             m_state = Illuminated;
-            m_timer->start(1500);
+            m_timer.start(1500);
         }
         break;
     }
@@ -201,7 +199,7 @@ void StatusBarMessageLabel::timerDone()
         // start desaturation
         if (m_type != MltError) {
             m_state = Desaturate;
-            m_timer->start(80);
+            m_timer.start(80);
         }
         break;
     }
@@ -211,7 +209,7 @@ void StatusBarMessageLabel::timerDone()
         if (m_illumination < -128) {
             m_illumination = 0;
             m_state = Default;
-            m_timer->stop();
+            m_timer.stop();
             setMessage(QString(), DefaultMessage);
         } else {
             m_illumination -= 5;
index ce4b3fe1e7cb7260df0ad7e9e11a63ca2a393d3f..5f3cc8a43aa594734618e627348bac72e8809119 100644 (file)
 #define STATUSBARMESSAGELABEL_H
 
 
-#include <QtCore/QList>
-#include <QtGui/QPixmap>
+#include <QList>
+#include <QPixmap>
+#include <QWidget>
+#include <QTimer>
 
-#include <QtGui/QWidget>
 #include <definitions.h>
 
 class QPaintEvent;
 class QResizeEvent;
 class QPushButton;
-class QTimer;
 
 /**
  * @brief Represents a message text label as part of the status bar.
@@ -124,7 +124,7 @@ private:
     State m_state;
     int m_illumination;
     int m_minTextHeight;
-    QTimer* m_timer;
+    QTimer m_timer;
     QString m_text;
     QList<QString> m_pendingMessages;
     QPixmap m_pixmap;
index 959aac69ee887db2e63b29627f3e11d296c2337b..1f78d5d8e76e3fd8dc4c300a4a0bc83642d0630d 100644 (file)
@@ -165,12 +165,13 @@ QColor TitleDocument::getBackgroundColor()
 }
 
 
-bool TitleDocument::saveDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv)
+bool TitleDocument::saveDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double out)
 {
     if (!m_scene)
         return false;
 
     QDomDocument doc = xml(startv, endv);
+    doc.documentElement().setAttribute("out", out);
     KTemporaryFile tmpfile;
     if (!tmpfile.open()) {
         kWarning() << "/////  CANNOT CREATE TMP FILE in: " << tmpfile.fileName();
@@ -187,7 +188,7 @@ bool TitleDocument::saveDocument(const KUrl& url, QGraphicsPolygonItem* startv,
     return KIO::NetAccess::upload(tmpfile.fileName(), url, 0);
 }
 
-int TitleDocument::loadDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv)
+int TitleDocument::loadDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double *out)
 {
     QString tmpfile;
     QDomDocument doc;
@@ -202,14 +203,21 @@ int TitleDocument::loadDocument(const KUrl& url, QGraphicsPolygonItem* startv, Q
         } else
             return -1;
         KIO::NetAccess::removeTempFile(tmpfile);
-        return loadFromXml(doc, startv, endv);
+        return loadFromXml(doc, startv, endv, out);
     }
     return -1;
 }
 
-int TitleDocument::loadFromXml(QDomDocument doc, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv)
+int TitleDocument::loadFromXml(QDomDocument doc, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double *out)
 {
     QDomNodeList titles = doc.elementsByTagName("kdenlivetitle");
+
+    //TODO: get default title duration instead of hardcoded one
+    if (doc.documentElement().hasAttribute("out"))
+        *out = doc.documentElement().attribute("out").toDouble();
+    else
+        *out = 5000;
+
     int maxZValue = 0;
     if (titles.size()) {
 
index 263d79e67e1bb497fd25ea66f1023d04296e3356..637cdfa28ce5c7f4cc1219dadbc2d6806d666ddf 100644 (file)
@@ -30,10 +30,10 @@ class TitleDocument
 public:
     TitleDocument();
     void setScene(QGraphicsScene* scene);
-    bool saveDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv);
-    int loadDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv);
+    bool saveDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double out);
+    int loadDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double *out);
     QDomDocument xml(QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv);
-    int loadFromXml(QDomDocument doc, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv);
+    int loadFromXml(QDomDocument doc, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double *out);
     /** \brief Get the background color (incl. alpha) from the document, if possibly
      * \returns The background color of the document, inclusive alpha. If none found, returns (0,0,0,0) */
     QColor getBackgroundColor();
index 04209c090bfb323f678c293070a4a64dc5f4285a..1cf5cc1ce6ff3ea1b580d7827d3419a85bad6d59 100644 (file)
@@ -43,7 +43,7 @@ const int RECTITEM = 3;
 const int TEXTITEM = 8;
 static bool insertingValues = false;
 
-TitleWidget::TitleWidget(KUrl url, QString projectTitlePath, Render *render, QWidget *parent) :
+TitleWidget::TitleWidget(KUrl url, Timecode tc, QString projectTitlePath, Render *render, QWidget *parent) :
         QDialog(parent),
         Ui::TitleWidget_UI(),
         m_startViewport(NULL),
@@ -51,7 +51,8 @@ TitleWidget::TitleWidget(KUrl url, QString projectTitlePath, Render *render, QWi
         m_render(render),
         m_count(0),
         m_unicodeDialog(new UnicodeDialog(UnicodeDialog::InputHex)),
-        m_projectTitlePath(projectTitlePath)
+        m_projectTitlePath(projectTitlePath),
+        m_tc(tc)
 {
     setupUi(this);
     setFont(KGlobalSettings::toolBarFont());
@@ -66,6 +67,9 @@ TitleWidget::TitleWidget(KUrl url, QString projectTitlePath, Render *render, QWi
     m_frameHeight = render->renderHeight();
     showToolbars(TITLE_NONE);
 
+    //TODO: get default title duration instead of hardcoded one
+    title_duration->setText(m_tc.getTimecode(GenTime(5000 / 1000.0), m_render->fps()));
+
     connect(kcolorbutton, SIGNAL(clicked()), this, SLOT(slotChangeBackground())) ;
     connect(horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(slotChangeBackground())) ;
 
@@ -265,7 +269,9 @@ TitleWidget::TitleWidget(KUrl url, QString projectTitlePath, Render *render, QWi
     kDebug() << "// TITLE WIDGWT: " << graphicsView->viewport()->width() << "x" << graphicsView->viewport()->height();
     //toolBox->setItemEnabled(2, false);
     if (!url.isEmpty()) {
-        m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport) + 1;
+        double out;
+        m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport, &out) + 1;
+        title_duration->setText(m_tc.getTimecode(GenTime(out), m_render->fps()));
         slotSelectTool();
     } else {
         slotTextTool();
@@ -1306,7 +1312,9 @@ void TitleWidget::loadTitle()
             if (items.at(i)->zValue() > -1000) delete items.at(i);
         }
         m_scene->clearTextSelection();
-        m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport) + 1;
+        double out;
+        m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport, &out) + 1;
+        title_duration->setText(m_tc.getTimecode(GenTime(out / 1000.0), m_render->fps()));
         insertingValues = true;
         startViewportX->setValue(m_startViewport->data(0).toInt());
         startViewportY->setValue(m_startViewport->data(1).toInt());
@@ -1323,7 +1331,7 @@ void TitleWidget::saveTitle(KUrl url)
 {
     if (url.isEmpty()) url = KFileDialog::getSaveUrl(KUrl(m_projectTitlePath), "*.kdenlivetitle", this, i18n("Save Title"));
     if (!url.isEmpty()) {
-        if (m_titledocument.saveDocument(url, m_startViewport, m_endViewport) == false)
+        if (m_titledocument.saveDocument(url, m_startViewport, m_endViewport, GenTime(m_tc.getFrameCount(title_duration->text(), m_render->fps()), m_render->fps()).ms()) == false)
             KMessageBox::error(this, i18n("Cannot write to file %1", url.path()));
     }
 }
@@ -1331,15 +1339,30 @@ void TitleWidget::saveTitle(KUrl url)
 QDomDocument TitleWidget::xml()
 {
     QDomDocument doc = m_titledocument.xml(m_startViewport, m_endViewport);
+    doc.documentElement().setAttribute("out", GenTime(m_tc.getFrameCount(title_duration->text(), m_render->fps()), m_render->fps()).ms());
     if (cropImage->isChecked()) {
         doc.documentElement().setAttribute("crop", 1);
     }
     return doc;
 }
 
+int TitleWidget::duration() const
+{
+    return GenTime(m_tc.getFrameCount(title_duration->text(), m_render->fps()), m_render->fps()).frames(m_render->fps());
+}
+
 void TitleWidget::setXml(QDomDocument doc)
 {
-    m_count = m_titledocument.loadFromXml(doc, m_startViewport, m_endViewport);
+    double out;
+    m_count = m_titledocument.loadFromXml(doc, m_startViewport, m_endViewport, &out);
+    kDebug() << "\n\n// TITLE OUT: " << out;
+    title_duration->setText(m_tc.getTimecode(GenTime(out / 1000.0), m_render->fps()));
+    /*if (doc.documentElement().hasAttribute("out")) {
+    GenTime duration = GenTime(doc.documentElement().attribute("out").toDouble() / 1000.0);
+    title_duration->setText(m_tc.getTimecode(duration, m_render->fps()));
+    }
+    else title_duration->setText(m_tc.getTimecode(GenTime(5000), m_render->fps()));*/
+
     QDomElement e = doc.documentElement();
     cropImage->setChecked(e.hasAttribute("crop"));
     m_transformations.clear();
index d4a5fa826b7ba75c7f29a5cf3f1f60e162a3db2e..26e7e84af0c7a0a0bc1f2ad6af597b570bdb9caa 100644 (file)
@@ -24,6 +24,7 @@
 #include "renderer.h"
 #include "graphicsscenerectmove.h"
 #include "unicodedialog.h"
+#include "timecode.h"
 
 #include <QMap>
 #include <QSignalMapper>
@@ -48,7 +49,7 @@ class TitleWidget : public QDialog , public Ui::TitleWidget_UI
 public:
     /** \brief Constructor
      * \param projectPath Path to use when user requests loading or saving of titles as .kdenlivetitle documents */
-    TitleWidget(KUrl url, QString projectTitlePath, Render *render, QWidget *parent = 0);
+    TitleWidget(KUrl url, Timecode tc, QString projectTitlePath, Render *render, QWidget *parent = 0);
     virtual ~TitleWidget();
     QDomDocument xml();
     void setXml(QDomDocument doc);
@@ -75,6 +76,9 @@ public:
     */
     const QRect renderedRect();
 
+    /** \brief Get clip duration. */
+    int duration() const;
+
 protected:
     virtual void resizeEvent(QResizeEvent * event);
 
@@ -98,10 +102,12 @@ private:
     QAction *m_buttonLoad;
 
     QAction *m_unicodeAction;
+
     /** \brief Dialog for entering unicode in text fields */
     UnicodeDialog *m_unicodeDialog;
     /** project path for storing title clips */
     QString m_projectTitlePath;
+    Timecode m_tc;
 
     /** See http://doc.trolltech.com/4.5/signalsandslots.html#advanced-signals-and-slots-usage */
     QSignalMapper *m_signalMapper;
index 10ba42cb84036e6a94a66941b0a4d0b090aefbde..0ed52e0984eba2e69bdf3cd531399bef574d978f 100644 (file)
@@ -502,9 +502,12 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked)
             QString idString = elem.attribute("producer");
             QString id = idString;
             double speed = 1.0;
+            int strobe = 1;
             if (idString.startsWith("slowmotion")) {
                 id = idString.section(':', 1, 1);
                 speed = idString.section(':', 2, 2).toDouble();
+                strobe = idString.section(':', 3, 3).toInt();
+                if (strobe == 0) strobe = 1;
             } else id = id.section('_', 0, 0);
             DocClipBase *clip = m_doc->clipManager()->getClipById(id);
             if (clip == NULL) {
@@ -545,13 +548,21 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked)
                 clipinfo.cropStart = GenTime(in, m_doc->fps());
                 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);
+                ClipItem *item = new ClipItem(clip, clipinfo, m_doc->fps(), speed, strobe, 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();
                 position += (out - in + 1);
+                kDebug() << "/////////\n\n\n" << "CLIP SPEED: " << speed << ", " << strobe << "\n\n\n/////////////////////";
+                if (speed != 1.0 || strobe > 1) {
+                    QDomElement speedeffect = MainWindow::videoEffects.getEffectByTag(QString(), "speed").cloneNode().toElement();
+                    EffectsList::setParameter(speedeffect, "speed", QString::number((int)(100 * speed + 0.5)));
+                    EffectsList::setParameter(speedeffect, "strobe", QString::number(strobe));
+                    item->addEffect(speedeffect, false);
+                    item->effectsCounter();
+                }
 
                 // parse clip effects
                 QDomNodeList effects = elem.childNodes();