]> git.sesse.net Git - kdenlive/blobdiff - src/customtrackview.cpp
Add vertical timeline zoom:
[kdenlive] / src / customtrackview.cpp
index 97b14501b8b17d40c0160db5c67b15cea8e54911..e2c07e64712a13255dcd9d6868d2bf43b5cede55 100644 (file)
@@ -84,7 +84,7 @@
 
 CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscene, QWidget *parent) :
         QGraphicsView(projectscene, parent),
-        m_tracksHeight(KdenliveSettings::trackheight()),
+        m_tracksHeight(KdenliveSettings::defaulttrackheight()),
         m_projectDuration(0),
         m_cursorPos(0),
         m_document(doc),
@@ -114,6 +114,7 @@ CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscen
     else m_commandStack = NULL;
     setMouseTracking(true);
     setAcceptDrops(true);
+    KdenliveSettings::setTrackheight(m_tracksHeight);
     m_animationTimer = new QTimeLine(800);
     m_animationTimer->setFrameRange(0, 5);
     m_animationTimer->setUpdateInterval(100);
@@ -140,11 +141,16 @@ CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscen
     connect(&m_scrollTimer, SIGNAL(timeout()), this, SLOT(slotCheckMouseScrolling()));
     m_scrollTimer.setInterval(100);
     m_scrollTimer.setSingleShot(true);
+
+    connect(&m_thumbsTimer, SIGNAL(timeout()), this, SLOT(slotFetchNextThumbs()));
+    m_thumbsTimer.setInterval(500);
+    m_thumbsTimer.setSingleShot(true);
 }
 
 CustomTrackView::~CustomTrackView()
 {
     qDeleteAll(m_guides);
+    m_waitingThumbs.clear();
 }
 
 void CustomTrackView::setDocumentModified()
@@ -192,11 +198,14 @@ void CustomTrackView::checkAutoScroll()
     return m_scene->m_tracksList;
 }*/
 
-void CustomTrackView::checkTrackHeight()
+void CustomTrackView::checkTrackHeight(bool resetTrackHeight)
 {
+    if (resetTrackHeight) {
+        KdenliveSettings::setTrackheight(KdenliveSettings::defaulttrackheight());
+    }
     if (m_tracksHeight == KdenliveSettings::trackheight()) return;
     m_tracksHeight = KdenliveSettings::trackheight();
-    emit trackHeightChanged();
+    emit trackHeightChanged(resetTrackHeight);
     QList<QGraphicsItem *> itemList = items();
     ClipItem *item;
     Transition *transitionitem;
@@ -225,7 +234,7 @@ void CustomTrackView::checkTrackHeight()
     setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_document->tracksCount());
 //     verticalScrollBar()->setMaximum(m_tracksHeight * m_document->tracksCount());
     KdenliveSettings::setSnaptopoints(snap);
-    update();
+    viewport()->update();
 }
 
 /** Zoom or move viewport on mousewheel
@@ -258,6 +267,18 @@ int CustomTrackView::getPreviousVideoTrack(int track)
 }
 
 
+void CustomTrackView::slotFetchNextThumbs()
+{
+    if (!m_waitingThumbs.isEmpty()) {
+        ClipItem *item = m_waitingThumbs.takeFirst();
+        while ((item == NULL) && !m_waitingThumbs.isEmpty()) {
+            item = m_waitingThumbs.takeFirst();
+        }
+        if (item) item->slotFetchThumbs();
+        if (!m_waitingThumbs.isEmpty()) m_thumbsTimer.start();
+    }
+}
+
 void CustomTrackView::slotCheckMouseScrolling()
 {
     if (m_scrollOffset == 0) {
@@ -346,7 +367,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event)
             m_visualTip = NULL;
             QGraphicsView::mouseMoveEvent(event);
             return;
-        } else if (m_operationMode == SPACER && move) {
+        } else if (m_operationMode == SPACER && move && m_selectionGroup) {
             // spacer tool
             int mappedClick = (int)(mapToScene(m_clickEvent).x() + 0.5);
             m_selectionGroup->setPos(mappedXPos + (((int) m_selectionGroup->boundingRect().topLeft().x() + 0.5) - mappedClick) , m_selectionGroup->pos().y());
@@ -571,7 +592,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event)
 // virtual
 void CustomTrackView::mousePressEvent(QMouseEvent * event)
 {
-    kDebug() << "mousePressEvent STARTED";
+    //kDebug() << "mousePressEvent STARTED";
     setFocus(Qt::MouseFocusReason);
     m_menuPosition = QPoint();
 
@@ -696,7 +717,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event)
 
     // No item under click
     if (m_dragItem == NULL || m_tool == SPACERTOOL) {
-        resetSelectionGroup();
+        resetSelectionGroup(false);
         setCursor(Qt::ArrowCursor);
         m_scene->clearSelection();
         //event->accept();
@@ -716,9 +737,6 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event)
                 kDebug() << "SELELCTING ELEMENTS WITHIN =" << event->pos().x() << "/" <<  1 << ", " << mapFromScene(sceneRect().width(), 0).x() - event->pos().x() << "/" << sceneRect().height();
             }
 
-            resetSelectionGroup(false);
-            m_scene->clearSelection();
-
             for (int i = 0; i < selection.count(); i++) {
                 if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET) {
                     selection.at(i)->setSelected(true);
@@ -1158,17 +1176,20 @@ 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);
+            ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, false);
             start += clip->duration();
             offsetList.append(start);
             m_selectionGroup->addToGroup(item);
             item->setFlags(QGraphicsItem::ItemIsSelectable);
+            m_waitingThumbs.append(item);
         }
         //TODO: check if we do not overlap another clip when first dropping in timeline
         //if (insertPossible(m_selectionGroup, event->pos()))
         updateSnapPoints(NULL, offsetList);
         scene()->addItem(m_selectionGroup);
+        m_thumbsTimer.start();
         event->acceptProposedAction();
+
     } else {
         // the drag is not a clip (may be effect, ...)
         m_clipDrag = false;
@@ -1315,10 +1336,16 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track)
             ClipItem *item = (ClipItem *)itemList.at(i);
             if (effect.attribute("type") == "audio") {
                 // Don't add audio effects on video clips
-                if (item->isVideoOnly() || (item->clipType() != AUDIO && item->clipType() != AV && item->clipType() != PLAYLIST)) continue;
+                if (item->isVideoOnly() || (item->clipType() != AUDIO && item->clipType() != AV && item->clipType() != PLAYLIST)) {
+                    emit displayMessage(i18n("Cannot add an audio effect to this clip"), ErrorMessage);
+                    continue;
+                }
             } else if (effect.hasAttribute("type") == false) {
                 // Don't add video effect on audio clips
-                if (item->isAudioOnly() || item->clipType() == AUDIO) continue;
+                if (item->isAudioOnly() || item->clipType() == AUDIO) {
+                    emit displayMessage(i18n("Cannot add a video effect to this clip"), ErrorMessage);
+                    continue;
+                }
             }
             if (item->hasEffect(effect.attribute("tag"), effect.attribute("id")) != -1 && effect.attribute("unique", "0") != "0") {
                 emit displayMessage(i18n("Effect already present in clip"), ErrorMessage);
@@ -1697,6 +1724,8 @@ void CustomTrackView::dragMoveEvent(QDragMoveEvent * event)
 void CustomTrackView::dragLeaveEvent(QDragLeaveEvent * event)
 {
     if (m_selectionGroup && m_clipDrag) {
+        m_thumbsTimer.stop();
+        m_waitingThumbs.clear();
         QList<QGraphicsItem *> items = m_selectionGroup->childItems();
         qDeleteAll(items);
         scene()->destroyItemGroup(m_selectionGroup);
@@ -1842,7 +1871,7 @@ void CustomTrackView::addTrack(TrackInfo type, int ix)
     }
     m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), maxHeight);
     setSceneRect(0, 0, sceneRect().width(), maxHeight);
-    QTimer::singleShot(300, this, SIGNAL(trackHeightChanged()));
+    QTimer::singleShot(300, this, SIGNAL(trackHeightChanged(false)));
     viewport()->update();
     //setFixedHeight(50 * m_tracksCount);
 }
@@ -1907,7 +1936,7 @@ void CustomTrackView::removeTrack(int ix)
     }
     m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), maxHeight);
     setSceneRect(0, 0, sceneRect().width(), maxHeight);
-    QTimer::singleShot(300, this, SIGNAL(trackHeightChanged()));
+    QTimer::singleShot(300, this, SIGNAL(trackHeightChanged(false)));
     viewport()->update();
 }
 
@@ -1916,7 +1945,7 @@ void CustomTrackView::changeTrack(int ix, TrackInfo type)
     int tracknumber = m_document->tracksCount() - ix;
     m_document->setTrackType(tracknumber - 1, type);
     m_document->renderer()->mltChangeTrackState(tracknumber, m_document->trackInfoAt(tracknumber - 1).isMute, m_document->trackInfoAt(tracknumber - 1).isBlind);
-    QTimer::singleShot(300, this, SIGNAL(trackHeightChanged()));
+    QTimer::singleShot(300, this, SIGNAL(trackHeightChanged(false)));
     viewport()->update();
 }
 
@@ -2211,7 +2240,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
         m_dragGuide = NULL;
         m_dragItem = NULL;
         return;
-    } else if (m_operationMode == SPACER) {
+    } else if (m_operationMode == SPACER && m_selectionGroup) {
         int track;
         if (event->modifiers() != Qt::ControlModifier) {
             // We are moving all tracks
@@ -2266,7 +2295,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
         resetSelectionGroup(false);
         m_operationMode = NONE;
     } else if (m_operationMode == RUBBERSELECTION) {
-        kDebug() << "// END RUBBER SELECT";
+        //kDebug() << "// END RUBBER SELECT";
         resetSelectionGroup();
         groupSelectedItems();
         m_operationMode = NONE;
@@ -2480,7 +2509,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
                 m_document->setModified(true);
             }
         }
-
+        m_document->renderer()->doRefresh();
     } else if (m_operationMode == RESIZESTART && m_dragItem->startPos() != m_dragItemInfo.startPos) {
         // resize start
         if (m_dragItem->type() == AVWIDGET) {
@@ -2575,7 +2604,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
 
                 new ResizeClipCommand(this, m_dragItemInfo, info, false, resizeCommand);
                 m_commandStack->push(resizeCommand);
-                updateClipFade(static_cast <ClipItem *>(m_dragItem), true);
+                updateClipFade(static_cast <ClipItem *>(m_dragItem));
             } else {
                 m_dragItem->resizeEnd((int) m_dragItemInfo.endPos.frames(m_document->fps()));
                 emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
@@ -2731,8 +2760,10 @@ void CustomTrackView::deleteClip(ItemInfo info)
         }
     }*/
     scene()->removeItem(item);
+    m_waitingThumbs.removeAll(item);
     if (m_dragItem == item) m_dragItem = NULL;
     delete item;
+    item = NULL;
     m_document->setModified(true);
     m_document->renderer()->doRefresh();
 }
@@ -3121,7 +3152,8 @@ void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end)
         // undo last move and emit error message
         emit displayMessage(i18n("Cannot move clip to position %1", m_document->timecode().getTimecodeFromFrames(end.startPos.frames(m_document->fps()))), ErrorMessage);
     }
-    kDebug() << " // MOVED CLIP TO: " << end.startPos.frames(25) << ", ITEM START: " << item->startPos().frames(25);
+    m_document->renderer()->doRefresh();
+    //kDebug() << " // MOVED CLIP TO: " << end.startPos.frames(25) << ", ITEM START: " << item->startPos().frames(25);
 }
 
 void CustomTrackView::moveGroup(QList <ItemInfo> startClip, QList <ItemInfo> startTransition, const GenTime offset, const int trackOffset, bool reverseMove)
@@ -3212,6 +3244,7 @@ void CustomTrackView::moveGroup(QList <ItemInfo> startClip, QList <ItemInfo> sta
             }
         }
         KdenliveSettings::setSnaptopoints(snap);
+        m_document->renderer()->doRefresh();
     } else kDebug() << "///////// WARNING; NO GROUP TO MOVE";
 }
 
@@ -3256,6 +3289,7 @@ void CustomTrackView::moveTransition(const ItemInfo start, const ItemInfo end)
         }
         emit transitionItemSelected(item, getPreviousVideoTrack(item->track()), p);
     }
+    m_document->renderer()->doRefresh();
 }
 
 void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end)
@@ -3291,7 +3325,7 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end)
         bool success = m_document->renderer()->mltResizeClipEnd(clipinfo, end.endPos - clipinfo.startPos);
         if (success) {
             item->resizeEnd((int) end.endPos.frames(m_document->fps()));
-            updateClipFade(item, true);
+            updateClipFade(item);
         } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
     }
     if (end.cropStart != start.cropStart) {
@@ -3308,85 +3342,86 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end)
     KdenliveSettings::setSnaptopoints(snap);
 }
 
-void CustomTrackView::updateClipFade(ClipItem * item, bool updateFadeOut)
-{
-    if (!updateFadeOut) {
-        int end = item->fadeIn();
-        if (end != 0) {
-            // there is a fade in effect
-            int effectPos = item->hasEffect("volume", "fadein");
-            if (effectPos != -1) {
-                QDomElement oldeffect = item->effectAt(effectPos);
-                int start = item->cropStart().frames(m_document->fps());
-                int max = item->cropDuration().frames(m_document->fps());
-                if (end > max) {
-                    item->setFadeIn(max);
-                    end = item->fadeIn();
-                }
-                end += start;
-                EffectsList::setParameter(oldeffect, "in", QString::number(start));
-                EffectsList::setParameter(oldeffect, "out", QString::number(end));
-                if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - item->track(), item->startPos(), item->getEffectArgs(oldeffect)))
-                    emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
-                // if fade effect is displayed, update the effect edit widget with new clip duration
-                if (item->isSelected() && effectPos == item->selectedEffectIndex()) emit clipItemSelected(item, effectPos);
+void CustomTrackView::updateClipFade(ClipItem * item)
+{
+    int end = item->fadeIn();
+    if (end != 0) {
+        // there is a fade in effect
+        int effectPos = item->hasEffect("volume", "fadein");
+        if (effectPos != -1) {
+            QDomElement oldeffect = item->effectAt(effectPos);
+            int start = item->cropStart().frames(m_document->fps());
+            int max = item->cropDuration().frames(m_document->fps());
+            if (end > max) {
+                // Make sure the fade effect is not longer than the clip
+                item->setFadeIn(max);
+                end = item->fadeIn();
             }
-            effectPos = item->hasEffect("brightness", "fade_from_black");
-            if (effectPos != -1) {
-                QDomElement oldeffect = item->effectAt(effectPos);
-                int start = item->cropStart().frames(m_document->fps());
-                int max = item->cropDuration().frames(m_document->fps());
-                if (end > max) {
-                    item->setFadeIn(max);
-                    end = item->fadeIn();
-                }
-                end += start;
-                EffectsList::setParameter(oldeffect, "in", QString::number(start));
-                EffectsList::setParameter(oldeffect, "out", QString::number(end));
-                if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - item->track(), item->startPos(), item->getEffectArgs(oldeffect)))
-                    emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
-                // if fade effect is displayed, update the effect edit widget with new clip duration
-                if (item->isSelected() && effectPos == item->selectedEffectIndex()) emit clipItemSelected(item, effectPos);
+            end += start;
+            EffectsList::setParameter(oldeffect, "in", QString::number(start));
+            EffectsList::setParameter(oldeffect, "out", QString::number(end));
+            if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - item->track(), item->startPos(), item->getEffectArgs(oldeffect)))
+                emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
+            // if fade effect is displayed, update the effect edit widget with new clip duration
+            if (item->isSelected() && effectPos == item->selectedEffectIndex()) emit clipItemSelected(item, effectPos);
+        }
+        effectPos = item->hasEffect("brightness", "fade_from_black");
+        if (effectPos != -1) {
+            QDomElement oldeffect = item->effectAt(effectPos);
+            int start = item->cropStart().frames(m_document->fps());
+            int max = item->cropDuration().frames(m_document->fps());
+            if (end > max) {
+                // Make sure the fade effect is not longer than the clip
+                item->setFadeIn(max);
+                end = item->fadeIn();
             }
-        }
-    } else {
-        int start = item->fadeOut();
-        if (start != 0) {
-            // there is a fade in effect
-            int effectPos = item->hasEffect("volume", "fadeout");
-            if (effectPos != -1) {
-                QDomElement oldeffect = item->effectAt(effectPos);
-                int end = (item->duration() - item->cropStart()).frames(m_document->fps());
-                int max = item->cropDuration().frames(m_document->fps());
-                if (end > max) {
-                    item->setFadeOut(max);
-                    start = item->fadeOut();
-                }
-                start = end - start;
-                EffectsList::setParameter(oldeffect, "in", QString::number(start));
-                EffectsList::setParameter(oldeffect, "out", QString::number(end));
-                if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - item->track(), item->startPos(), item->getEffectArgs(oldeffect)))
-                    emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
-                // if fade effect is displayed, update the effect edit widget with new clip duration
-                if (item->isSelected() && effectPos == item->selectedEffectIndex()) emit clipItemSelected(item, effectPos);
+            end += start;
+            EffectsList::setParameter(oldeffect, "in", QString::number(start));
+            EffectsList::setParameter(oldeffect, "out", QString::number(end));
+            if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - item->track(), item->startPos(), item->getEffectArgs(oldeffect)))
+                emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
+            // if fade effect is displayed, update the effect edit widget with new clip duration
+            if (item->isSelected() && effectPos == item->selectedEffectIndex()) emit clipItemSelected(item, effectPos);
+        }
+    }
+    int start = item->fadeOut();
+    if (start != 0) {
+        // there is a fade out effect
+        int effectPos = item->hasEffect("volume", "fadeout");
+        if (effectPos != -1) {
+            QDomElement oldeffect = item->effectAt(effectPos);
+            int max = item->cropDuration().frames(m_document->fps());
+            int end = max + item->cropStart().frames(m_document->fps());
+            if (start > max) {
+                // Make sure the fade effect is not longer than the clip
+                item->setFadeOut(max);
+                start = item->fadeOut();
             }
-            effectPos = item->hasEffect("brightness", "fade_to_black");
-            if (effectPos != -1) {
-                QDomElement oldeffect = item->effectAt(effectPos);
-                int end = (item->duration() - item->cropStart()).frames(m_document->fps());
-                int max = item->cropDuration().frames(m_document->fps());
-                if (end > max) {
-                    item->setFadeOut(max);
-                    start = item->fadeOut();
-                }
-                start = end - start;
-                EffectsList::setParameter(oldeffect, "in", QString::number(start));
-                EffectsList::setParameter(oldeffect, "out", QString::number(end));
-                if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - item->track(), item->startPos(), item->getEffectArgs(oldeffect)))
-                    emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
-                // if fade effect is displayed, update the effect edit widget with new clip duration
-                if (item->isSelected() && effectPos == item->selectedEffectIndex()) emit clipItemSelected(item, effectPos);
+            start = end - start;
+            EffectsList::setParameter(oldeffect, "in", QString::number(start));
+            EffectsList::setParameter(oldeffect, "out", QString::number(end));
+            if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - item->track(), item->startPos(), item->getEffectArgs(oldeffect)))
+                emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
+            // if fade effect is displayed, update the effect edit widget with new clip duration
+            if (item->isSelected() && effectPos == item->selectedEffectIndex()) emit clipItemSelected(item, effectPos);
+        }
+        effectPos = item->hasEffect("brightness", "fade_to_black");
+        if (effectPos != -1) {
+            QDomElement oldeffect = item->effectAt(effectPos);
+            int max = item->cropDuration().frames(m_document->fps());
+            int end = max + item->cropStart().frames(m_document->fps());
+            if (start > max) {
+                // Make sure the fade effect is not longer than the clip
+                item->setFadeOut(max);
+                start = item->fadeOut();
             }
+            start = end - start;
+            EffectsList::setParameter(oldeffect, "in", QString::number(start));
+            EffectsList::setParameter(oldeffect, "out", QString::number(end));
+            if (!m_document->renderer()->mltEditEffect(m_document->tracksCount() - item->track(), item->startPos(), item->getEffectArgs(oldeffect)))
+                emit displayMessage(i18n("Problem editing effect"), ErrorMessage);
+            // if fade effect is displayed, update the effect edit widget with new clip duration
+            if (item->isSelected() && effectPos == item->selectedEffectIndex()) emit clipItemSelected(item, effectPos);
         }
     }
 }
@@ -3723,7 +3758,7 @@ void CustomTrackView::slotRefreshGuides()
     }
 }
 
-void CustomTrackView::drawBackground(QPainter * painter, const QRectF & rect)
+void CustomTrackView::drawBackground(QPainter * painter, const QRectF &rect)
 {
     QRectF r = rect;
     r.setWidth(r.width() + 1);