From 42ab4294e4d3e57f025db54c1469106d76e2b72b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Wed, 17 Jun 2009 10:27:36 +0000 Subject: [PATCH] Fix possible crash on clip deletion, fetch thumbs sequentially when adding several clips to timeline so that we don't freeze svn path=/trunk/kdenlive/; revision=3553 --- src/clipitem.cpp | 15 +++++++++------ src/clipitem.h | 2 +- src/customtrackview.cpp | 26 +++++++++++++++++++++++++- src/customtrackview.h | 3 +++ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 1159d343..392feeb7 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -118,6 +118,11 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, b ClipItem::~ClipItem() { + blockSignals(true); + if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW || m_clipType == PLAYLIST) { + 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; @@ -491,18 +496,16 @@ void ClipItem::slotSetEndThumb(QImage img) void ClipItem::slotThumbReady(int frame, QPixmap pix) { if (scene() == NULL) return; - QRectF r = sceneBoundingRect(); - double width = m_startPix.width() / projectScene()->scale(); + QRectF r = boundingRect(); + double width = pix.width() / projectScene()->scale(); if (m_startThumbRequested && frame == cropStart().frames(m_fps)) { m_startPix = pix; m_startThumbRequested = false; - double height = r.height(); - update(r.x(), r.y(), width, height); + update(r.left(), r.top(), width, pix.height()); } else if (m_endThumbRequested && frame == (cropStart() + cropDuration()).frames(m_fps) - 1) { m_endPix = pix; m_endThumbRequested = false; - double height = r.height(); - update(r.right() - width, r.y(), width, height); + update(r.right() - width, r.y(), width, pix.height()); } } diff --git a/src/clipitem.h b/src/clipitem.h index 9436033d..ba485b55 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -157,7 +157,6 @@ private: QPixmap m_audioPix; private slots: - void slotFetchThumbs(); void slotGetStartThumb(); void slotGetEndThumb(); void slotGotAudioData(); @@ -168,6 +167,7 @@ private slots: void slotThumbReady(int frame, QPixmap pix); public slots: + void slotFetchThumbs(); void slotSetStartThumb(const QPixmap pix); void slotSetEndThumb(const QPixmap pix); diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 97b14501..c76b8a59 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -140,11 +140,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() @@ -258,6 +263,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) { @@ -1158,17 +1175,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; @@ -1697,6 +1717,8 @@ void CustomTrackView::dragMoveEvent(QDragMoveEvent * event) void CustomTrackView::dragLeaveEvent(QDragLeaveEvent * event) { if (m_selectionGroup && m_clipDrag) { + m_thumbsTimer.stop(); + m_waitingThumbs.clear(); QList items = m_selectionGroup->childItems(); qDeleteAll(items); scene()->destroyItemGroup(m_selectionGroup); @@ -2731,8 +2753,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(); } diff --git a/src/customtrackview.h b/src/customtrackview.h index 6ece8977..967ecbd5 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -216,6 +216,7 @@ private: QAction *m_deleteGuide; QActionGroup *m_clipTypeGroup; QTimer m_scrollTimer; + QTimer m_thumbsTimer; int m_scrollOffset; bool m_clipDrag; @@ -229,6 +230,7 @@ private: QPoint m_menuPosition; bool m_blockRefresh; AbstractGroupItem *m_selectionGroup; + QList m_waitingThumbs; /** Get the index of the video track that is just below current track */ int getPreviousVideoTrack(int track); @@ -253,6 +255,7 @@ private slots: void slotCheckMouseScrolling(); void slotEditTimeLineGuide(); void slotDeleteTimeLineGuide(); + void slotFetchNextThumbs(); signals: void cursorMoved(int, int); -- 2.39.2