From: Jean-Baptiste Mardelle Date: Tue, 5 Aug 2008 11:22:31 +0000 (+0000) Subject: Fix timeline handling of objects (move them instead of changing their bounding rect X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=12ec352602795fa2970c71fccab4bad309d817ea;p=kdenlive Fix timeline handling of objects (move them instead of changing their bounding rect svn path=/branches/KDE4/; revision=2363 --- diff --git a/src/abstractclipitem.cpp b/src/abstractclipitem.cpp index 77a26f5b..29912987 100644 --- a/src/abstractclipitem.cpp +++ b/src/abstractclipitem.cpp @@ -45,11 +45,14 @@ ItemInfo AbstractClipItem::info() const { } void AbstractClipItem::moveTo(int x, double scale, int offset, int newTrack, bool checkCollision) { - double origX = rect().x(); - double origY = rect().y(); + qreal origX = pos().x(); + qreal origY = pos().y(); bool success = true; if (x < 0) return; - setRect(x * scale, origY + offset, rect().width(), rect().height()); + //setRect(x * scale, origY + offset, rect().width(), rect().height()); + //double xoffset = (x - m_startPos.frames(m_fps)) * scale;// - origX; + setPos((qreal) x * scale, (qreal) pos().y() + offset); + QList collisionList = collidingItems(Qt::IntersectsItemBoundingRect); if (collisionList.size() == 0) m_track = newTrack; if (checkCollision) @@ -61,16 +64,15 @@ void AbstractClipItem::moveTo(int x, double scale, int offset, int newTrack, boo if (x < m_startPos.frames(m_fps)) { kDebug() << "COLLISION, MOVING TO------"; m_startPos = ((AbstractClipItem *)item)->endPos(); - origX = m_startPos.frames(m_fps) * scale; + origX = (qreal) m_startPos.frames(m_fps) * scale; } else if (x > m_startPos.frames(m_fps)) { //kDebug() << "COLLISION, MOVING TO+++: "<startPos().frames(m_fps); m_startPos = ((AbstractClipItem *)item)->startPos() - m_cropDuration; - origX = m_startPos.frames(m_fps) * scale; + origX = (qreal) m_startPos.frames(m_fps) * scale; } } - setRect(origX, origY, rect().width(), rect().height()); + setPos(origX, origY); offset = 0; - origX = rect().x(); success = false; break; } @@ -79,10 +81,6 @@ void AbstractClipItem::moveTo(int x, double scale, int offset, int newTrack, boo m_track = newTrack; m_startPos = GenTime(x, m_fps); } - /* QList childrenList = QGraphicsItem::children(); - for (int i = 0; i < childrenList.size(); ++i) { - childrenList.at(i)->moveBy(rect().x() - origX , offset); - }*/ } GenTime AbstractClipItem::endPos() const { @@ -115,17 +113,24 @@ void AbstractClipItem::resizeStart(int posx, double scale) { m_startPos += durationDiff; if (type() == AVWIDGET) m_cropStart += durationDiff; m_cropDuration = m_cropDuration - durationDiff; - setRect(m_startPos.frames(m_fps) * scale, rect().y(), m_cropDuration.frames(m_fps) * scale, rect().height()); - QList collisionList = collidingItems(Qt::IntersectsItemBoundingRect); - for (int i = 0; i < collisionList.size(); ++i) { - QGraphicsItem *item = collisionList.at(i); - if (item->type() == type()) { - GenTime diff = ((AbstractClipItem *)item)->endPos() + GenTime(1, m_fps) - m_startPos; - setRect((m_startPos + diff).frames(m_fps) * scale, rect().y(), (m_cropDuration - diff).frames(m_fps) * scale, rect().height()); - m_startPos += diff; - if (type() == AVWIDGET) m_cropStart += diff; - m_cropDuration = m_cropDuration - diff; - break; + + setRect(0, 0, (qreal) m_cropDuration.frames(m_fps) * scale - .5, rect().height()); + setPos((qreal) m_startPos.frames(m_fps) * scale, pos().y()); + //setRect((double) m_startPos.frames(m_fps) * scale, rect().y(), (double) m_cropDuration.frames(m_fps) * scale, rect().height()); + if (durationDiff < GenTime()) { + QList collisionList = collidingItems(Qt::IntersectsItemBoundingRect); + for (int i = 0; i < collisionList.size(); ++i) { + QGraphicsItem *item = collisionList.at(i); + if (item->type() == type() && item->pos().x() < pos().x()) { + kDebug() << "///////// COLLISION DETECTED!!!!!!!!!"; + GenTime diff = ((AbstractClipItem *)item)->endPos() + GenTime(1, m_fps) - m_startPos; + setRect(0, 0, (qreal)(m_cropDuration - diff).frames(m_fps) * scale - .5, rect().height()); + setPos((qreal)(m_startPos + diff).frames(m_fps) * scale, pos().y()); + m_startPos += diff; + if (type() == AVWIDGET) m_cropStart += diff; + m_cropDuration = m_cropDuration - diff; + break; + } } } } @@ -140,15 +145,20 @@ void AbstractClipItem::resizeEnd(int posx, double scale) { durationDiff = maxDuration() - m_cropDuration - m_cropStart; } m_cropDuration += durationDiff; - setRect(m_startPos.frames(m_fps) * scale, rect().y(), m_cropDuration.frames(m_fps) * scale, rect().height()); - QList collisionList = collidingItems(Qt::IntersectsItemBoundingRect); - for (int i = 0; i < collisionList.size(); ++i) { - QGraphicsItem *item = collisionList.at(i); - if (item->type() == type()) { - GenTime diff = ((AbstractClipItem *)item)->startPos() - GenTime(1, m_fps) - startPos(); - m_cropDuration = diff; - setRect(m_startPos.frames(m_fps) * scale, rect().y(), (m_cropDuration.frames(m_fps)) * scale, rect().height()); - break; + setRect(0, 0, (qreal) m_cropDuration.frames(m_fps) * scale - .5, rect().height()); + if (durationDiff > GenTime()) { + QList collisionList = collidingItems(Qt::IntersectsItemBoundingRect); + for (int i = 0; i < collisionList.size(); ++i) { + QGraphicsItem *item = collisionList.at(i); + if (item->type() == type() && item->pos().x() > pos().x()) { + kDebug() << "///////// COLLISION DETECTED!!!!!!!!!"; + kDebug() << "///////// CURRENT: " << startPos().frames(25) << "x" << endPos().frames(25) << ", RECT: " << rect() << "-" << pos(); + kDebug() << "///////// COLLISION: " << ((AbstractClipItem *)item)->startPos().frames(25) << "x" << ((AbstractClipItem *)item)->endPos().frames(25) << ", RECT: " << ((AbstractClipItem *)item)->rect() << "-" << item->pos(); + GenTime diff = ((AbstractClipItem *)item)->startPos() - GenTime(1, m_fps) - startPos(); + m_cropDuration = diff; + setRect(0, 0, (qreal)(m_cropDuration.frames(m_fps)) * scale - .5, rect().height()); + break; + } } } } @@ -274,7 +284,7 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) { } int AbstractClipItem::mouseOverKeyFrames(QPointF pos) { - QRectF br = rect(); + QRectF br = sceneBoundingRect(); double maxw = br.width() / m_cropDuration.frames(m_fps); double maxh = br.height() / 100.0 * m_keyframeFactor; if (m_keyframes.count() > 1) { @@ -297,7 +307,7 @@ int AbstractClipItem::mouseOverKeyFrames(QPointF pos) { void AbstractClipItem::updateSelectedKeyFrame() { if (m_editedKeyframe == -1) return; - QRectF br = rect(); + QRectF br = sceneBoundingRect(); double maxw = br.width() / m_cropDuration.frames(m_fps); double maxh = br.height() / 100.0 * m_keyframeFactor; update(br.x() + maxw * (m_selectedKeyframe - m_cropStart.frames(m_fps)) - 3, br.bottom() - m_keyframes[m_selectedKeyframe] * maxh - 3, 12, 12); @@ -348,9 +358,10 @@ double AbstractClipItem::keyFrameFactor() const { } void AbstractClipItem::addKeyFrame(const GenTime pos, const double value) { - QRectF br = rect(); + QRectF br = sceneBoundingRect(); double maxh = 100.0 / br.height() / m_keyframeFactor; double newval = (br.bottom() - value) * maxh; + kDebug() << "Rect: " << br << "/ SCENE: " << sceneBoundingRect() << ", VALUE: " << value << ", MAX: " << maxh << ", NEWVAL: " << newval; int newpos = (int) pos.frames(m_fps) ; m_keyframes[newpos] = newval; m_selectedKeyframe = newpos; diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 01ddd6e0..624ea480 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -40,9 +40,10 @@ #include "kthumb.h" ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps) - : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), m_effectsCounter(1), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_thumbsRequested(0), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(1.0) { - QRectF rect((double) info.startPos.frames(fps) * scale, (double)(info.track * KdenliveSettings::trackheight() + 1), (double)(info.endPos - info.startPos).frames(fps) * scale, (double)(KdenliveSettings::trackheight() - 1)); - setRect(rect); + : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), m_effectsCounter(1), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_thumbsRequested(2), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(1.0), framePixelWidth(0) { + setRect(0, 0, (qreal)(info.endPos - info.startPos).frames(fps) * scale - .5, (qreal)(KdenliveSettings::trackheight() - 1)); + setPos((qreal) info.startPos.frames(fps) * scale, (qreal)(info.track * KdenliveSettings::trackheight()) + 1); + kDebug() << "// ADDing CLIP TRK HGTH: " << KdenliveSettings::trackheight(); m_clipName = clip->name(); m_producer = clip->getId(); @@ -71,7 +72,7 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps) connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(extractImage(int, int))); connect(clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap))); connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData())); - QTimer::singleShot(300, this, SLOT(slotFetchThumbs())); + QTimer::singleShot(200, this, SLOT(slotFetchThumbs())); startThumbTimer = new QTimer(this); startThumbTimer->setSingleShot(true); @@ -100,6 +101,9 @@ ClipItem::~ClipItem() { ClipItem *ClipItem::clone(double scale, ItemInfo info) const { ClipItem *duplicate = new ClipItem(m_clip, info, scale, m_fps); + if (info.cropStart == cropStart()) duplicate->slotThumbReady(info.cropStart.frames(m_fps), m_startPix); + if (info.cropStart + (info.endPos - info.startPos) == m_cropStart + m_cropDuration) duplicate->slotThumbReady((m_cropStart + m_cropDuration).frames(m_fps) - 1, m_endPix); + kDebug() << "// CLoning clip: " << (info.cropStart + (info.endPos - info.startPos)).frames(m_fps) << ", CURRENT end: " << (cropStart() + duration()).frames(m_fps); duplicate->setEffectList(m_effectList); duplicate->setSpeed(m_speed); return duplicate; @@ -247,6 +251,9 @@ QDomElement ClipItem::selectedEffect() { } void ClipItem::resetThumbs() { + m_startPix = QPixmap(); + m_endPix = QPixmap(); + m_thumbsRequested = 2; slotFetchThumbs(); audioThumbCachePic.clear(); } @@ -266,35 +273,40 @@ void ClipItem::refreshClip() { } void ClipItem::slotFetchThumbs() { - m_thumbsRequested = 2; - emit getThumb((int)m_cropStart.frames(m_fps), (int)(m_cropStart + m_cropDuration).frames(m_fps)); + if (m_endPix.isNull() && m_startPix.isNull()) { + emit getThumb((int)m_cropStart.frames(m_fps), (int)(m_cropStart + m_cropDuration).frames(m_fps) - 1); + } else { + if (m_endPix.isNull()) slotGetEndThumb(); + if (m_startPix.isNull()) slotGetStartThumb(); + } } void ClipItem::slotGetStartThumb() { - m_thumbsRequested++; emit getThumb((int)m_cropStart.frames(m_fps), -1); } void ClipItem::slotGetEndThumb() { - m_thumbsRequested++; - emit getThumb(-1, (int)(m_cropStart + m_cropDuration).frames(m_fps)); + emit getThumb(-1, (int)(m_cropStart + m_cropDuration).frames(m_fps) - 1); } void ClipItem::slotThumbReady(int frame, QPixmap pix) { - //if (m_thumbsRequested == 0) return; if (frame == m_cropStart.frames(m_fps)) { m_startPix = pix; - QRectF r = boundingRect(); + QRectF r = sceneBoundingRect(); r.setRight(pix.width() + 2); update(r); m_thumbsRequested--; - } else if (frame == (m_cropStart + m_cropDuration).frames(m_fps)) { + } else if (frame == (m_cropStart + m_cropDuration).frames(m_fps) - 1) { m_endPix = pix; - QRectF r = boundingRect(); + QRectF r = sceneBoundingRect(); r.setLeft(r.right() - pix.width() - 2); update(r); m_thumbsRequested--; } + if (m_thumbsRequested == 0) { + // Ok, we have out start and end thumbnails... + disconnect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap))); + } } void ClipItem::slotGotAudioData() { @@ -353,15 +365,18 @@ void ClipItem::paint(QPainter *painter, QBrush paintColor = brush(); if (isSelected()) paintColor = QBrush(QColor(79, 93, 121)); QRectF br = rect(); - double scale = br.width() / m_cropDuration.frames(m_fps); + const double itemWidth = br.width(); + const double itemHeight = br.height(); + kDebug() << "/// ITEM RECT: " << br << ", EPXOSED: " << option->exposedRect; + double scale = itemWidth / (double) m_cropDuration.frames(m_fps); // kDebug()<<"/// EXPOSED RECT: "<exposedRect.x()<<" X "<exposedRect.right(); - int startpixel = (int)option->exposedRect.x() - rect().x(); + double startpixel = option->exposedRect.x(); // - pos().x(); if (startpixel < 0) startpixel = 0; - int endpixel = (int)option->exposedRect.right(); + double endpixel = option->exposedRect.right(); if (endpixel < 0) endpixel = 0; @@ -378,22 +393,22 @@ void ClipItem::paint(QPainter *painter, // draw thumbnails if (!m_startPix.isNull() && KdenliveSettings::videothumbnails()) { if (m_clipType == IMAGE) { - painter->drawPixmap(QPointF(br.right() - m_startPix.width(), br.y()), m_startPix); - QLine l(br.right() - m_startPix.width(), br.y(), br.right() - m_startPix.width(), br.y() + br.height()); + painter->drawPixmap(QPointF(itemWidth - m_startPix.width(), 0), m_startPix); + QLine l(itemWidth - m_startPix.width(), 0, itemWidth - m_startPix.width(), itemHeight); painter->drawLine(l); } else { - painter->drawPixmap(QPointF(br.right() - m_endPix.width(), br.y()), m_endPix); - QLine l(br.right() - m_endPix.width(), br.y(), br.right() - m_endPix.width(), br.y() + br.height()); + painter->drawPixmap(QPointF(itemWidth - m_endPix.width(), 0), m_endPix); + QLine l(itemWidth - m_endPix.width(), 0, itemWidth - m_endPix.width(), itemHeight); painter->drawLine(l); } - painter->drawPixmap(QPointF(br.x(), br.y()), m_startPix); - QLine l2(br.x() + m_startPix.width(), br.y(), br.x() + m_startPix.width(), br.y() + br.height()); + painter->drawPixmap(QPointF(0, 0), m_startPix); + QLine l2(m_startPix.width(), 0, 0 + m_startPix.width(), itemHeight); painter->drawLine(l2); } // draw audio thumbnails - if (KdenliveSettings::audiothumbnails() && ((m_clipType == AV && option->exposedRect.bottom() > (br.y() + br.height() / 2)) || m_clipType == AUDIO) && audioThumbReady) { + if (KdenliveSettings::audiothumbnails() && ((m_clipType == AV && option->exposedRect.bottom() > (itemHeight / 2)) || m_clipType == AUDIO) && audioThumbReady) { QPainterPath path = m_clipType == AV ? roundRectPathLower : resultClipPath; if (m_clipType == AV) painter->fillPath(path, QBrush(QColor(200, 200, 200, 140))); @@ -401,11 +416,12 @@ void ClipItem::paint(QPainter *painter, int channels = baseClip()->getProperty("channels").toInt(); if (scale != framePixelWidth) audioThumbCachePic.clear(); - emit prepareAudioThumb(scale, path, startpixel, endpixel + 200, channels);//200 more for less missing parts before repaint after scrolling - int cropLeft = (int)((m_cropStart).frames(m_fps) * scale); - for (int startCache = startpixel - startpixel % 100; startCache < endpixel + 300;startCache += 100) { + double cropLeft = m_cropStart.frames(m_fps) * scale; + emit prepareAudioThumb(scale, path, startpixel + cropLeft, endpixel + cropLeft, channels);//200 more for less missing parts before repaint after scrolling + int newstart = startpixel + cropLeft; + for (int startCache = newstart - (newstart) % 100; startCache < endpixel + cropLeft; startCache += 100) { if (audioThumbCachePic.contains(startCache) && !audioThumbCachePic[startCache].isNull()) - painter->drawPixmap((int)(roundRectPathUpper.united(roundRectPathLower).boundingRect().x() + startCache - cropLeft), (int)(path.boundingRect().y()), audioThumbCachePic[startCache]); + painter->drawPixmap((int)(startCache - cropLeft), (int)(path.boundingRect().y()), audioThumbCachePic[startCache]); } } @@ -426,10 +442,10 @@ void ClipItem::paint(QPainter *painter, if (pos > GenTime()) { if (pos > duration()) break; framepos = scale * pos.frames(m_fps); - QLineF l(br.x() + framepos, br.y() + 5, br.x() + framepos, br.y() + br.height() - 5); + QLineF l(framepos, 5, framepos, itemHeight - 5); painter->drawLine(l); if (KdenliveSettings::showmarkers()) { - const QRectF txtBounding = painter->boundingRect(br.x() + framepos + 1, br.y() + 10, br.width() - framepos - 2, br.height() - 10, Qt::AlignLeft | Qt::AlignTop, " " + (*it).comment() + " "); + const QRectF txtBounding = painter->boundingRect(framepos + 1, 10, itemWidth - framepos - 2, itemHeight - 10, Qt::AlignLeft | Qt::AlignTop, " " + (*it).comment() + " "); QPainterPath path; path.addRoundedRect(txtBounding, 3, 3); painter->fillPath(path, markerBrush); @@ -450,31 +466,31 @@ void ClipItem::paint(QPainter *painter, if (m_startFade != 0) { QPainterPath fadeInPath; - fadeInPath.moveTo(br.x() , br.y()); - fadeInPath.lineTo(br.x() , br.bottom()); - fadeInPath.lineTo(br.x() + m_startFade * scale, br.y()); + fadeInPath.moveTo(0, 0); + fadeInPath.lineTo(0, itemHeight); + fadeInPath.lineTo(m_startFade * scale, itemHeight); fadeInPath.closeSubpath(); painter->fillPath(fadeInPath/*.intersected(resultClipPath)*/, fades); if (isSelected()) { - QLineF l(br.x() + m_startFade * scale, br.y(), br.x(), br.bottom()); + QLineF l(m_startFade * scale, 0, 0, itemHeight); painter->drawLine(l); } } if (m_endFade != 0) { QPainterPath fadeOutPath; - fadeOutPath.moveTo(br.right(), br.y()); - fadeOutPath.lineTo(br.right(), br.bottom()); - fadeOutPath.lineTo(br.right() - m_endFade * scale, br.y()); + fadeOutPath.moveTo(itemWidth, 0); + fadeOutPath.lineTo(itemWidth, itemHeight); + fadeOutPath.lineTo(itemWidth - m_endFade * scale, 0); fadeOutPath.closeSubpath(); painter->fillPath(fadeOutPath/*.intersected(resultClipPath)*/, fades); if (isSelected()) { - QLineF l(br.right() - m_endFade * scale, br.y(), br.x() + br.width(), br.bottom()); + QLineF l(itemWidth - m_endFade * scale, 0, itemWidth, itemHeight); painter->drawLine(l); } } // Draw effects names - if (!m_effectNames.isEmpty() && br.width() > 30) { + if (!m_effectNames.isEmpty() && itemWidth > 30) { QRectF txtBounding = painter->boundingRect(br, Qt::AlignLeft | Qt::AlignTop, m_effectNames); txtBounding.setRight(txtBounding.right() + 15); painter->setPen(Qt::white); @@ -510,7 +526,7 @@ void ClipItem::paint(QPainter *painter, // draw effect or transition keyframes - if (br.width() > 20) drawKeyFrames(painter, option->exposedRect); + if (itemWidth > 20) drawKeyFrames(painter, option->exposedRect); // draw clip border painter->setClipRect(option->exposedRect); @@ -518,7 +534,7 @@ void ClipItem::paint(QPainter *painter, //painter->setClipRect(option->exposedRect); painter->drawPath(resultClipPath); - if (m_hover && br.width() > 30) { + if (m_hover && itemWidth > 30) { painter->setBrush(QColor(180, 180, 50, 180)); //gradient); // draw transitions handles @@ -532,9 +548,9 @@ void ClipItem::paint(QPainter *painter, transitionHandle.lineTo(handle_size * 3, handle_size * 3); transitionHandle.lineTo(0, handle_size * 3); transitionHandle.closeSubpath(); - int pointy = (int)(br.y() + br.height() / 2); - int pointx1 = (int)(br.x() + 10); - int pointx2 = (int)(br.x() + br.width() - (10 + handle_size * 3)); + int pointy = (int)(itemHeight / 2); + int pointx1 = 10; + int pointx2 = (int)(itemWidth - (10 + handle_size * 3)); #if 0 painter->setPen(QPen(Qt::black)); painter->setBrush(QBrush(QColor(50, 50, 0))); @@ -570,24 +586,25 @@ OPERATIONTYPE ClipItem::operationMode(QPointF pos, double scale) { m_editedKeyframe = mouseOverKeyFrames(pos); if (m_editedKeyframe != -1) return KEYFRAME; } - if (qAbs((int)(pos.x() - (rect().x() + scale * m_startFade))) < 6 && qAbs((int)(pos.y() - rect().y())) < 6) { + QRectF rect = sceneBoundingRect(); + if (qAbs((int)(pos.x() - (rect.x() + scale * m_startFade))) < 6 && qAbs((int)(pos.y() - rect.y())) < 6) { if (m_startFade == 0) setToolTip(i18n("Add audio fade")); else setToolTip(i18n("Audio fade duration: %1s", GenTime(m_startFade, m_fps).seconds())); return FADEIN; - } else if (qAbs((int)(pos.x() - rect().x())) < 6) { + } else if (qAbs((int)(pos.x() - rect.x())) < 6) { setToolTip(i18n("Crop from start: %1s", cropStart().seconds())); return RESIZESTART; - } else if (qAbs((int)(pos.x() - (rect().x() + rect().width() - scale * m_endFade))) < 6 && qAbs((int)(pos.y() - rect().y())) < 6) { + } else if (qAbs((int)(pos.x() - (rect.x() + rect.width() - scale * m_endFade))) < 6 && qAbs((int)(pos.y() - rect.y())) < 6) { if (m_endFade == 0) setToolTip(i18n("Add audio fade")); else setToolTip(i18n("Audio fade duration: %1s", GenTime(m_endFade, m_fps).seconds())); return FADEOUT; - } else if (qAbs((int)(pos.x() - (rect().x() + rect().width()))) < 6) { + } else if (qAbs((int)(pos.x() - (rect.x() + rect.width()))) < 6) { setToolTip(i18n("Clip duration: %1s", duration().seconds())); return RESIZEEND; - } else if (qAbs((int)(pos.x() - (rect().x() + 16))) < 10 && qAbs((int)(pos.y() - (rect().y() + rect().height() / 2 + 5))) < 8) { + } else if (qAbs((int)(pos.x() - (rect.x() + 16))) < 10 && qAbs((int)(pos.y() - (rect.y() + rect.height() / 2 + 5))) < 8) { setToolTip(i18n("Add transition")); return TRANSITIONSTART; - } else if (qAbs((int)(pos.x() - (rect().x() + rect().width() - 21))) < 10 && qAbs((int)(pos.y() - (rect().y() + rect().height() / 2 + 5))) < 8) { + } else if (qAbs((int)(pos.x() - (rect.x() + rect.width() - 21))) < 10 && qAbs((int)(pos.y() - (rect.y() + rect.height() / 2 + 5))) < 8) { setToolTip(i18n("Add transition")); return TRANSITIONEND; } @@ -630,10 +647,10 @@ QList ClipItem::commentedSnapMarkers() const { void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, QPainterPath path, int startpixel, int endpixel, int channels) { QRectF re = path.boundingRect(); - //kDebug() << "// PREP AUDIO THMB FRMO : " << startpixel << ", to: " << endpixel; + kDebug() << "// PREP AUDIO THMB FRMO : " << startpixel << ", to: " << endpixel; //if ( (!audioThumbWasDrawn || framePixelWidth!=pixelForOneFrame ) && !baseClip()->audioFrameChache.isEmpty()){ - for (int startCache = startpixel - startpixel % 100;startCache + 100 < endpixel ;startCache += 100) { + for (int startCache = startpixel - startpixel % 100;startCache + 100 < endpixel + 100;startCache += 100) { //kDebug() << "creating " << startCache; //if (framePixelWidth!=pixelForOneFrame || if (framePixelWidth == pixelForOneFrame && audioThumbCachePic.contains(startCache)) @@ -720,7 +737,8 @@ void ClipItem::setFadeIn(int pos, double scale) { if (pos < 0) pos = 0; if (pos > m_cropDuration.frames(m_fps)) pos = (int)(m_cropDuration.frames(m_fps) / 2); m_startFade = pos; - update(rect().x(), rect().y(), qMax(oldIn, pos) * scale, rect().height()); + QRectF rect = boundingRect(); + update(rect.x(), rect.y(), qMax(oldIn, pos) * scale, rect.height()); } void ClipItem::setFadeOut(int pos, double scale) { @@ -728,7 +746,8 @@ void ClipItem::setFadeOut(int pos, double scale) { if (pos < 0) pos = 0; if (pos > m_cropDuration.frames(m_fps)) pos = (int)(m_cropDuration.frames(m_fps) / 2); m_endFade = pos; - update(rect().x() + rect().width() - qMax(oldOut, pos) * scale, rect().y(), pos * scale, rect().height()); + QRectF rect = boundingRect(); + update(rect.x() + rect.width() - qMax(oldOut, pos) * scale, rect.y(), pos * scale, rect.height()); } @@ -767,17 +786,31 @@ void ClipItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { } void ClipItem::resizeStart(int posx, double scale) { + const int min = (startPos() - cropStart()).frames(m_fps); + if (posx < min) posx = min; + if (posx == startPos().frames(m_fps)) return; const int previous = cropStart().frames(m_fps); AbstractClipItem::resizeStart(posx, scale); checkEffectsKeyframesPos(previous, cropStart().frames(m_fps), true); - if (m_hasThumbs && KdenliveSettings::videothumbnails()) startThumbTimer->start(100); + if (m_hasThumbs && KdenliveSettings::videothumbnails()) { + m_thumbsRequested++; + connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap))); + startThumbTimer->start(100); + } } void ClipItem::resizeEnd(int posx, double scale) { + const int max = (startPos() - cropStart() + maxDuration()).frames(m_fps) + 1; + if (posx > max) posx = max; + if (posx == endPos().frames(m_fps)) return; const int previous = (cropStart() + duration()).frames(m_fps); AbstractClipItem::resizeEnd(posx, scale); checkEffectsKeyframesPos(previous, (cropStart() + duration()).frames(m_fps), false); - if (m_hasThumbs && KdenliveSettings::videothumbnails()) endThumbTimer->start(100); + if (m_hasThumbs && KdenliveSettings::videothumbnails()) { + m_thumbsRequested++; + connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap))); + endThumbTimer->start(100); + } } diff --git a/src/clipitem.h b/src/clipitem.h index f21d049e..b62543c4 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -143,7 +143,6 @@ private: void checkEffectsKeyframesPos(const int previous, const int current, bool fromStart); private slots: - void slotThumbReady(int frame, QPixmap pix); void slotFetchThumbs(); void slotGetStartThumb(); void slotGetEndThumb(); @@ -151,6 +150,9 @@ private slots: void slotPrepareAudioThumb(double pixelForOneFrame, QPainterPath path, int startpixel, int endpixel, int channels); void animate(qreal value); +public slots: + void slotThumbReady(int frame, QPixmap pix); + signals: void getThumb(int, int); void prepareAudioThumb(double, QPainterPath, int, int, int); diff --git a/src/clipproperties.cpp b/src/clipproperties.cpp index 1111277e..4bb88aba 100644 --- a/src/clipproperties.cpp +++ b/src/clipproperties.cpp @@ -326,7 +326,7 @@ void ClipProperties::parseFolder() { m_view.slide_info->setText(i18n("%1 images found", m_count)); QDomElement xml = m_clip->toXML(); xml.setAttribute("resource", m_view.clip_path->text() + extension); - QPixmap pix = m_clip->thumbProducer()->getImage(xml, 1, 240, 180); + QPixmap pix = m_clip->thumbProducer()->getImage(KUrl(m_view.clip_path->text() + extension), 1, 240, 180); QMap props = m_clip->properties(); m_view.clip_duration->setText(m_tc.getTimecodeFromFrames(props.value("ttl").toInt() * m_count)); m_view.clip_thumb->setPixmap(pix); diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 9d9922cd..f9d12fbf 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -125,11 +125,13 @@ void CustomTrackView::checkTrackHeight() { for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET) { item = (ClipItem*) itemList.at(i); - item->setRect(item->rect().x(), item->track() * m_tracksHeight, item->rect().width(), m_tracksHeight - 1); + item->setRect(0, 0, item->rect().width(), m_tracksHeight - 1); + item->setPos((qreal) item->startPos().frames(m_document->fps()) * m_scale, (qreal) item->track() * m_tracksHeight); item->resetThumbs(); } else if (itemList.at(i)->type() == TRANSITIONWIDGET) { transitionitem = (Transition*) itemList.at(i); - transitionitem->setRect(transitionitem->rect().x(), transitionitem->track() * m_tracksHeight + m_tracksHeight / 2, transitionitem->rect().width(), m_tracksHeight - 1); + transitionitem->setRect(0, 0, transitionitem->rect().width(), m_tracksHeight / 3 * 2 - 1); + transitionitem->setPos((qreal) transitionitem->startPos().frames(m_document->fps()) * m_scale, (qreal) transitionitem->track() * m_tracksHeight + m_tracksHeight / 3 * 2); } } m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count()); @@ -216,7 +218,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { } else if (m_operationMode == KEYFRAME) { GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart(); double pos = mapToScene(event->pos()).toPoint().y(); - QRectF br = m_dragItem->rect(); + QRectF br = m_dragItem->sceneBoundingRect(); double maxh = 100.0 / br.height(); pos = (br.bottom() - pos) * maxh; m_dragItem->updateKeyFramePos(keyFramePos, pos); @@ -287,11 +289,12 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { } else if (opMode == RESIZESTART) { setCursor(KCursor("left_side", Qt::SizeHorCursor)); if (m_visualTip == NULL) { + QRectF rect = clip->sceneBoundingRect(); QPolygon polygon; - polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); - polygon << QPoint((int)(clip->rect().x() + size * 2), (int)(clip->rect().y() + clip->rect().height() / 2)); - polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 + size * 2)); - polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); + polygon << QPoint((int)rect.x(), (int)(rect.y() + rect.height() / 2 - size * 2)); + polygon << QPoint((int)(rect.x() + size * 2), (int)(rect.y() + rect.height() / 2)); + polygon << QPoint((int)rect.x(), (int)(rect.y() + rect.height() / 2 + size * 2)); + polygon << QPoint((int)rect.x(), (int)(rect.y() + rect.height() / 2 - size * 2)); m_visualTip = new QGraphicsPolygonItem(polygon); ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor); @@ -303,21 +306,22 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { m_visualTip->setPos(0, 0); double scale = 2.0; m_animation->setScaleAt(.5, scale, 1); - m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale, 0)); + m_animation->setPosAt(.5, QPointF(rect.x() - rect.x() * scale, 0)); scale = 1.0; m_animation->setScaleAt(1, scale, 1); - m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, 0)); + m_animation->setPosAt(1, QPointF(rect.x() - rect.x() * scale, 0)); scene()->addItem(m_visualTip); m_animationTimer->start(); } } else if (opMode == RESIZEEND) { setCursor(KCursor("right_side", Qt::SizeHorCursor)); if (m_visualTip == NULL) { + QRectF rect = clip->sceneBoundingRect(); QPolygon polygon; - polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); - polygon << QPoint((int)(clip->rect().x() + clip->rect().width() - size * 2), (int)(clip->rect().y() + clip->rect().height() / 2)); - polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 + size * 2)); - polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); + polygon << QPoint((int)(rect.x() + rect.width()), (int)(rect.y() + rect.height() / 2 - size * 2)); + polygon << QPoint((int)(rect.x() + rect.width() - size * 2), (int)(rect.y() + rect.height() / 2)); + polygon << QPoint((int)(rect.x() + rect.width()), (int)(rect.y() + rect.height() / 2 + size * 2)); + polygon << QPoint((int)(rect.x() + rect.width()), (int)(rect.y() + rect.height() / 2 - size * 2)); m_visualTip = new QGraphicsPolygonItem(polygon); ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor); @@ -330,17 +334,17 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { m_visualTip->setPos(0, 0); double scale = 2.0; m_animation->setScaleAt(.5, scale, 1); - m_animation->setPosAt(.5, QPointF(clip->rect().x() - clip->rect().x() * scale - clip->rect().width(), 0)); + m_animation->setPosAt(.5, QPointF(rect.x() - rect.x() * scale - rect.width(), 0)); scale = 1.0; m_animation->setScaleAt(1, scale, 1); - m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, 0)); + m_animation->setPosAt(1, QPointF(rect.x() - rect.x() * scale, 0)); scene()->addItem(m_visualTip); m_animationTimer->start(); } } else if (opMode == FADEIN) { if (m_visualTip == NULL) { ClipItem *item = (ClipItem *) clip; - m_visualTip = new QGraphicsEllipseItem(item->rect().x() + item->fadeIn() * m_scale - size, item->rect().y() - 8, size * 2, 16); + m_visualTip = new QGraphicsEllipseItem(item->pos().x() + item->fadeIn() * m_scale - size, item->pos().y() - 8, size * 2, 16); ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); m_visualTip->setZValue(100); @@ -350,10 +354,10 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { m_visualTip->setPos(0, 0); double scale = 2.0; m_animation->setScaleAt(.5, scale, scale); - m_animation->setPosAt(.5, QPointF(item->rect().x() - item->rect().x() * scale - item->fadeIn() * m_scale, item->rect().y() - item->rect().y() * scale)); + m_animation->setPosAt(.5, QPointF(item->pos().x() - item->pos().x() * scale - item->fadeIn() * m_scale, item->pos().y() - item->pos().y() * scale)); scale = 1.0; m_animation->setScaleAt(1, scale, scale); - m_animation->setPosAt(1, QPointF(item->rect().x() - item->rect().x() * scale, item->rect().y() - item->rect().y() * scale)); + m_animation->setPosAt(1, QPointF(item->pos().x() - item->pos().x() * scale, item->pos().y() - item->pos().y() * scale)); scene()->addItem(m_visualTip); m_animationTimer->start(); } @@ -361,7 +365,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { } else if (opMode == FADEOUT) { if (m_visualTip == NULL) { ClipItem *item = (ClipItem *) clip; - m_visualTip = new QGraphicsEllipseItem(item->rect().x() + item->rect().width() - item->fadeOut() * m_scale - size, item->rect().y() - 8, size*2, 16); + m_visualTip = new QGraphicsEllipseItem(item->pos().x() + item->rect().width() - item->fadeOut() * m_scale - size, item->pos().y() - 8, size*2, 16); ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); m_visualTip->setZValue(100); @@ -371,16 +375,17 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { m_visualTip->setPos(0, 0); double scale = 2.0; m_animation->setScaleAt(.5, scale, scale); - m_animation->setPosAt(.5, QPointF(item->rect().x() - item->rect().x() * scale - item->rect().width() + item->fadeOut() * m_scale, item->rect().y() - item->rect().y() * scale)); + m_animation->setPosAt(.5, QPointF(item->pos().x() - item->pos().x() * scale - item->rect().width() + item->fadeOut() * m_scale, item->pos().y() - item->pos().y() * scale)); scale = 1.0; m_animation->setScaleAt(1, scale, scale); - m_animation->setPosAt(1, QPointF(item->rect().x() - item->rect().x() * scale, item->rect().y() - item->rect().y() * scale)); + m_animation->setPosAt(1, QPointF(item->pos().x() - item->pos().x() * scale, item->pos().y() - item->pos().y() * scale)); scene()->addItem(m_visualTip); m_animationTimer->start(); } setCursor(Qt::PointingHandCursor); } else if (opMode == TRANSITIONSTART) { if (m_visualTip == NULL) { + QRectF rect = clip->sceneBoundingRect(); m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10); ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); @@ -388,7 +393,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { m_animation = new QGraphicsItemAnimation; m_animation->setItem(m_visualTip); m_animation->setTimeLine(m_animationTimer); - m_visualTip->setPos(clip->rect().x() + 10, clip->rect().y() + clip->rect().height() / 2 + 12); + m_visualTip->setPos(rect.x() + 10, rect.y() + rect.height() / 2 + 12); double scale = 2.0; m_animation->setScaleAt(.5, scale, scale); scale = 1.0; @@ -399,6 +404,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { setCursor(Qt::PointingHandCursor); } else if (opMode == TRANSITIONEND) { if (m_visualTip == NULL) { + QRectF rect = clip->sceneBoundingRect(); m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10); ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); @@ -406,7 +412,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { m_animation = new QGraphicsItemAnimation; m_animation->setItem(m_visualTip); m_animation->setTimeLine(m_animationTimer); - m_visualTip->setPos(clip->rect().x() + clip->rect().width() - 10 , clip->rect().y() + clip->rect().height() / 2 + 12); + m_visualTip->setPos(rect.x() + rect.width() - 10 , rect.y() + rect.height() / 2 + 12); double scale = 2.0; m_animation->setScaleAt(.5, scale, scale); scale = 1.0; @@ -513,7 +519,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { m_dragItem = (AbstractClipItem *) item; - m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps()) * m_scale), (int)(event->pos().y() - m_dragItem->rect().top())); + m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps()) * m_scale), (int)(event->pos().y() - m_dragItem->pos().y())); m_dragItemInfo.startPos = m_dragItem->startPos(); m_dragItemInfo.endPos = m_dragItem->endPos(); m_dragItemInfo.track = m_dragItem->track(); @@ -525,7 +531,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { m_selectedClipList.append(static_cast (selected.at(i))); } - m_operationMode = m_dragItem->operationMode(item->mapFromScene(mapToScene(event->pos())), m_scale); + m_operationMode = m_dragItem->operationMode(mapToScene(event->pos()), m_scale); if (m_operationMode == KEYFRAME) { m_dragItem->updateSelectedKeyFrame(); m_blockRefresh = false; @@ -810,13 +816,15 @@ void CustomTrackView::slotUpdateClipEffect(ClipItem *clip, QDomElement oldeffect void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) { if (cut) { // cut clip - ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()), info.track); + ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()) + 1, info.track); if (!item || cutTime >= item->endPos() || cutTime <= item->startPos()) { emit displayMessage(i18n("Cannot find clip to cut"), ErrorMessage); kDebug() << "///////// ERROR CUTTING CLIP : (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), INFO: (" << info.startPos.frames(25) << "-" << info.endPos.frames(25) << ")" << ", CUT: " << cutTime.frames(25); m_blockRefresh = false; return; } + kDebug() << "///////// CUTTING CLIP : (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), INFO: (" << info.startPos.frames(25) << "-" << info.endPos.frames(25) << ")" << ", CUT: " << cutTime.frames(25); + m_document->renderer()->mltCutClip(m_tracksList.count() - info.track, cutTime); int cutPos = (int) cutTime.frames(m_document->fps()); ItemInfo newPos; @@ -824,25 +832,38 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) { newPos.endPos = info.endPos; newPos.cropStart = item->cropStart() + (cutTime - info.startPos); newPos.track = info.track; - item->resizeEnd(cutPos, m_scale); ClipItem *dup = item->clone(m_scale, newPos); + kDebug() << "// REsizing item to: " << cutPos; + item->resizeEnd(cutPos, m_scale); scene()->addItem(dup); item->baseClip()->addReference(); m_document->updateClip(item->baseClip()->getId()); + kDebug() << "///////// CUTTING CLIP RESULT: (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), DUP: (" << dup->startPos().frames(25) << "-" << dup->endPos().frames(25) << ")" << ", CUT: " << cutTime.frames(25); kDebug() << "// CUTTING CLIP dONE"; } else { // uncut clip + ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()), info.track); - ClipItem *dup = getClipItemAt((int) cutTime.frames(m_document->fps()), info.track); - if (!item || !dup) { + ClipItem *dup = getClipItemAt((int) cutTime.frames(m_document->fps()) + 1, info.track); + if (!item || !dup || item == dup) { emit displayMessage(i18n("Cannot find clip to uncut"), ErrorMessage); m_blockRefresh = false; return; } - /*kDebug() << "// UNCUTTING CLIPS: " << item->startPos().frames(25) << ", SECOND: " << dup->startPos().frames(25); - kDebug() << "// UNCUTTING CLIPS, SEC END " << dup->endPos().frames(25) << ", CUT: " << cutTime.frames(25); - kDebug() << "// UNCUTTING CLIPS, INFO " << info.endPos.frames(25) << ", start: " << info.startPos.frames(25);*/ - deleteClip(dup->info()); + + kDebug() << "// UNCUTTING CLIPS: ITEM 1 (" << item->startPos().frames(25) << "x" << item->endPos().frames(25) << ")"; + kDebug() << "// UNCUTTING CLIPS: ITEM 2 (" << dup->startPos().frames(25) << "x" << dup->endPos().frames(25) << ")"; + kDebug() << "// UNCUTTING CLIPS, INFO (" << info.startPos.frames(25) << "x" << info.endPos.frames(25) << ") , CUT: " << cutTime.frames(25);; + //deleteClip(dup->info()); + + + if (dup->isSelected()) emit clipItemSelected(NULL); + dup->baseClip()->removeReference(); + m_document->updateClip(dup->baseClip()->getId()); + scene()->removeItem(dup); + delete dup; + m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, cutTime); + ItemInfo clipinfo = item->info(); clipinfo.track = m_tracksList.count() - clipinfo.track; bool success = m_document->renderer()->mltResizeClipEnd(clipinfo, info.endPos - info.startPos); @@ -850,6 +871,7 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) { item->resizeEnd((int) info.endPos.frames(m_document->fps()), m_scale); } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); + } QTimer::singleShot(3000, this, SLOT(slotEnableRefresh())); } @@ -1279,6 +1301,7 @@ void CustomTrackView::deleteClip(ItemInfo info) { if (item->isSelected()) emit clipItemSelected(NULL); item->baseClip()->removeReference(); m_document->updateClip(item->baseClip()->getId()); + scene()->removeItem(item); delete item; m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, info.startPos); m_document->renderer()->doRefresh(); @@ -1350,7 +1373,7 @@ void CustomTrackView::cutSelectedClips() { GenTime currentPos = GenTime(m_cursorPos, m_document->fps()); for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET) { - ClipItem *item = (ClipItem *) itemList.at(i); + ClipItem *item = static_cast (itemList.at(i)); if (currentPos > item->startPos() && currentPos < item->endPos()) { RazorClipCommand *command = new RazorClipCommand(this, item->info(), currentPos, true); m_commandStack->push(command); @@ -1905,7 +1928,8 @@ void CustomTrackView::setScale(double scaleFactor) { for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET) { AbstractClipItem *clip = (AbstractClipItem *)itemList.at(i); - clip->setRect(clip->startPos().frames(m_document->fps()) * m_scale, clip->rect().y(), clip->duration().frames(m_document->fps()) * m_scale, clip->rect().height()); + clip->setRect(0, 0, (qreal) clip->duration().frames(m_document->fps()) * m_scale - .5, clip->rect().height()); + clip->setPos((qreal) clip->startPos().frames(m_document->fps()) * m_scale, clip->pos().y()); } } diff --git a/src/customtrackview.h b/src/customtrackview.h index 79ce4e5e..2a4e5d24 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -25,8 +25,7 @@ #include #include #include - -#include +#include #include "kdenlivedoc.h" #include "docclipbase.h" @@ -148,7 +147,7 @@ private: OPERATIONTYPE m_moveOpMode; AbstractClipItem *m_dragItem; Guide *m_dragGuide; - KUndoStack *m_commandStack; + QUndoStack *m_commandStack; QGraphicsItem *m_visualTip; QGraphicsItemAnimation *m_animation; QTimeLine *m_animationTimer; diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index c18d8807..9e1769f1 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -37,7 +37,7 @@ #include "mainwindow.h" -KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, MltVideoProfile profile, QUndoGroup *undoGroup, MainWindow *parent): QObject(parent), m_render(NULL), m_url(url), m_projectFolder(projectFolder), m_profile(profile), m_fps((double)profile.frame_rate_num / profile.frame_rate_den), m_width(profile.width), m_height(profile.height), m_commandStack(new KUndoStack(undoGroup)), m_modified(false), m_documentLoadingProgress(0), m_documentLoadingStep(0.0), m_startPos(0), m_zoom(7) { +KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, MltVideoProfile profile, QUndoGroup *undoGroup, MainWindow *parent): QObject(parent), m_render(NULL), m_url(url), m_projectFolder(projectFolder), m_profile(profile), m_fps((double)profile.frame_rate_num / profile.frame_rate_den), m_width(profile.width), m_height(profile.height), m_commandStack(new QUndoStack(undoGroup)), m_modified(false), m_documentLoadingProgress(0), m_documentLoadingStep(0.0), m_startPos(0), m_zoom(7) { kDebug() << "// init profile, ratnum: " << profile.frame_rate_num << ", " << profile.frame_rate_num << ", width: " << profile.width; m_clipManager = new ClipManager(this); KdenliveSettings::setProject_fps(m_fps); @@ -429,7 +429,7 @@ void KdenliveDoc::loadingProgressed() { emit progressInfo(QString(), (int) m_documentLoadingProgress); } -KUndoStack *KdenliveDoc::commandStack() { +QUndoStack *KdenliveDoc::commandStack() { return m_commandStack; } diff --git a/src/kdenlivedoc.h b/src/kdenlivedoc.h index e3a325a0..391fe90b 100644 --- a/src/kdenlivedoc.h +++ b/src/kdenlivedoc.h @@ -22,15 +22,15 @@ #define KDENLIVEDOC_H #include -#include -#include +#include +#include #include #include #include +#include #include -#include -#include +#include #include "gentime.h" #include "timecode.h" @@ -56,7 +56,7 @@ Q_OBJECT public: Timecode timecode() const; QDomDocument toXml() const; void setRenderer(Render *render); - KUndoStack *commandStack(); + QUndoStack *commandStack(); QString producerName(int id); void setProducerDuration(int id, int duration); int getProducerDuration(int id); @@ -116,7 +116,7 @@ private: int m_height; Timecode m_timecode; Render *m_render; - KUndoStack *m_commandStack; + QUndoStack *m_commandStack; QDomDocument generateSceneList(); ClipManager *m_clipManager; MltVideoProfile m_profile; diff --git a/src/kthumb.cpp b/src/kthumb.cpp index f6cfc7c4..b380ee25 100644 --- a/src/kthumb.cpp +++ b/src/kthumb.cpp @@ -168,34 +168,43 @@ void KThumb::extractImage(int frame, int frame2) { return; } if (frame != -1) { - QPixmap pix = getFrame(*m_producer, frame, twidth, KdenliveSettings::trackheight()); + QPixmap pix = getFrame(m_producer, frame, twidth, KdenliveSettings::trackheight()); emit thumbReady(frame, pix); } if (frame2 != -1) { - QPixmap pix = getFrame(*m_producer, frame2, twidth , KdenliveSettings::trackheight()); + QPixmap pix = getFrame(m_producer, frame2, twidth , KdenliveSettings::trackheight()); emit thumbReady(frame2, pix); } } +QPixmap KThumb::extractImage(int frame, int width, int height) { + return getFrame(m_producer, frame, width, height); +} + //static QPixmap KThumb::getImage(KUrl url, int frame, int width, int height) { Mlt::Profile profile((char*) KdenliveSettings::current_profile().data()); QPixmap pix(width, height); if (url.isEmpty()) return pix; - char *tmp = Render::decodedString(""); - Mlt::Producer producer(profile, "westley-xml", tmp); + char *tmp = Render::decodedString(url.path()); + //""); + //Mlt::Producer producer(profile, "westley-xml", tmp); + Mlt::Producer *producer = new Mlt::Producer(profile, tmp); delete[] tmp; - if (producer.is_blank()) { - + if (producer->is_blank()) { pix.fill(Qt::black); + delete producer; return pix; } - return getFrame(producer, frame, width, height); + pix = getFrame(producer, frame, width, height); + delete producer; + return pix; } //static +/* QPixmap KThumb::getImage(QDomElement xml, int frame, int width, int height) { Mlt::Profile profile((char*) KdenliveSettings::current_profile().data()); QPixmap pix(width, height); @@ -214,24 +223,34 @@ QPixmap KThumb::getImage(QDomElement xml, int frame, int width, int height) { return pix; } return getFrame(producer, frame, width, height); -} +}*/ //static -QPixmap KThumb::getFrame(Mlt::Producer producer, int framepos, int width, int height) { - producer.seek(framepos); - Mlt::Frame *frame = producer.get_frame(); +QPixmap KThumb::getFrame(Mlt::Producer *producer, int framepos, int width, int height) { + kDebug() << "//REQUESTING FRAME: " << framepos; + if (producer == NULL) return QPixmap(); + producer->seek(framepos); + Mlt::Frame *frame = producer->get_frame(); + if (!frame) { + kDebug() << "///// BROKEN FRAME"; + return QPixmap(); + } + kDebug() << "///// FRAME exists"; mlt_image_format format = mlt_image_yuv422; int frame_width = 0; int frame_height = 0; frame->set("normalised_height", height); frame->set("normalised_width", width); QPixmap pix(width, height); - + kDebug() << "///// FRAME exists 2"; uint8_t *data = frame->get_image(format, frame_width, frame_height, 0); + kDebug() << "///// FRAME exists 2a"; uint8_t *new_image = (uint8_t *)mlt_pool_alloc(frame_width * (frame_height + 1) * 4); + kDebug() << "///// FRAME exists 2b"; mlt_convert_yuv422_to_rgb24a((uint8_t *)data, new_image, frame_width * frame_height); + kDebug() << "///// FRAME exists 2c"; QImage image((uchar *)new_image, frame_width, frame_height, QImage::Format_ARGB32); - + kDebug() << "///// FRAME exists 3"; if (!image.isNull()) { pix = pix.fromImage(image.rgbSwapped()); } else @@ -239,6 +258,7 @@ QPixmap KThumb::getFrame(Mlt::Producer producer, int framepos, int width, int he mlt_pool_release(new_image); delete frame; + kDebug() << "//REQUESTING FRAME " << framepos << " OVER"; return pix; } /* diff --git a/src/kthumb.h b/src/kthumb.h index e6bed31e..e6227fd3 100644 --- a/src/kthumb.h +++ b/src/kthumb.h @@ -78,16 +78,17 @@ Q_OBJECT public: public slots: void extractImage(int frame, int frame2); + QPixmap extractImage(int frame, int width, int height); void updateClipUrl(KUrl url); static QPixmap getImage(KUrl url, int width, int height); - static QPixmap getImage(QDomElement xml, int frame, int width, int height); +// static QPixmap getImage(QDomElement xml, int frame, int width, int height); /* void getImage(KUrl url, int frame, int width, int height); void getThumbs(KUrl url, int startframe, int endframe, int width, int height);*/ void stopAudioThumbs(); void removeAudioThumb(); void getAudioThumbs(int channel, double frame, double frameLength, int arrayWidth); static QPixmap getImage(KUrl url, int frame, int width, int height); - static QPixmap getFrame(Mlt::Producer producer, int framepos, int width, int height); + static QPixmap getFrame(Mlt::Producer *producer, int framepos, int width, int height); protected: virtual void customEvent(QEvent * event); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index caa72737..106fb0e0 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -700,11 +700,15 @@ void MainWindow::setupActions() { KStandardAction::paste(this, SLOT(slotPaste()), actionCollection()); - KStandardAction::undo(this, SLOT(undo()), - actionCollection()); + KAction *undo = KStandardAction::undo(m_commandStack, SLOT(undo()), + actionCollection()); + undo->setEnabled(false); + connect(m_commandStack, SIGNAL(canUndoChanged(bool)), undo, SLOT(setEnabled(bool))); - KStandardAction::redo(this, SLOT(redo()), - actionCollection()); + KAction *redo = KStandardAction::redo(m_commandStack, SLOT(redo()), + actionCollection()); + redo->setEnabled(false); + connect(m_commandStack, SIGNAL(canRedoChanged(bool)), redo, SLOT(setEnabled(bool))); KStandardAction::fullScreen(this, SLOT(slotFullScreen()), this, actionCollection()); @@ -716,14 +720,6 @@ void MainWindow::setupActions() { readOptions(); } -void MainWindow::undo() { - m_commandStack->undo(); -} - -void MainWindow::redo() { - m_commandStack->redo(); -} - void MainWindow::slotDisplayActionMessage(QAction *a) { statusBar()->showMessage(a->data().toString(), 3000); } diff --git a/src/mainwindow.h b/src/mainwindow.h index cd7df070..a0bd27e3 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -165,8 +165,6 @@ public slots: private slots: void newFile(); - void undo(); - void redo(); void queryQuit(); void activateDocument(); void connectDocument(TrackView*, KdenliveDoc*); diff --git a/src/markerdialog.cpp b/src/markerdialog.cpp index 8de2b07f..de34f80c 100644 --- a/src/markerdialog.cpp +++ b/src/markerdialog.cpp @@ -56,7 +56,7 @@ MarkerDialog::MarkerDialog(DocClipBase *clip, CommentedTime t, Timecode tc, QWid connect(this, SIGNAL(updateThumb()), m_previewTimer, SLOT(start())); case IMAGE: case TEXT: - p = KThumb::getFrame(*m_producer, t.time().frames(m_fps), (int)(100 * m_dar), 100); + p = KThumb::getFrame(m_producer, t.time().frames(m_fps), (int)(100 * m_dar), 100); break; case COLOR: colour = colour.replace(0, 2, "#"); @@ -93,7 +93,7 @@ MarkerDialog::~MarkerDialog() { void MarkerDialog::slotUpdateThumb() { m_previewTimer->stop(); int pos = m_tc.getFrameCount(m_view.marker_position->text(), m_fps); - QPixmap p = KThumb::getFrame(*m_producer, pos, (int)(100 * m_dar), 100); + QPixmap p = KThumb::getFrame(m_producer, pos, (int)(100 * m_dar), 100); if (!p.isNull()) m_view.clip_thumb->setPixmap(p); else kDebug() << "!!!!!!!!!!! ERROR CREATING THUMB"; } diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 7ccd5da7..2b9744db 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -456,7 +456,7 @@ void ProjectList::slotRefreshClipThumbnail(ProjectItem *item) { if (item) { int height = 50; int width = (int)(height * m_render->dar()); - QPixmap pix = KThumb::getImage(item->toXml(), item->referencedClip()->getClipThumbFrame(), width, height); + QPixmap pix = item->referencedClip()->thumbProducer()->extractImage(item->referencedClip()->getClipThumbFrame(), width, height); item->setIcon(0, pix); } } diff --git a/src/projectlist.h b/src/projectlist.h index d06befa4..cfa7d80d 100644 --- a/src/projectlist.h +++ b/src/projectlist.h @@ -26,8 +26,8 @@ #include #include #include +#include -#include #include #include @@ -128,7 +128,7 @@ private: double m_fps; QToolBar *m_toolbar; QMenu *m_menu; - KUndoStack *m_commandStack; + QUndoStack *m_commandStack; int m_clipIdCounter; void selectItemById(const int clipId); ProjectItem *getItemById(int id); diff --git a/src/razorclipcommand.cpp b/src/razorclipcommand.cpp index 75fb9d8b..7485910a 100644 --- a/src/razorclipcommand.cpp +++ b/src/razorclipcommand.cpp @@ -28,13 +28,13 @@ RazorClipCommand::RazorClipCommand(CustomTrackView *view, const ItemInfo info, c // virtual void RazorClipCommand::undo() { -// kDebug()<<"---- undoing action"; + // kDebug()<<"---- undoing action"; m_doIt = true; m_view->cutClip(m_info, m_cutTime, false); } // virtual void RazorClipCommand::redo() { - kDebug() << "---- redoing action cut: " << m_cutTime.frames(25); + // kDebug() << "---- redoing action cut: " << m_cutTime.frames(25); if (m_doIt) m_view->cutClip(m_info, m_cutTime, true); m_doIt = true; diff --git a/src/razorclipcommand.h b/src/razorclipcommand.h index c9ca1a31..200fc5df 100644 --- a/src/razorclipcommand.h +++ b/src/razorclipcommand.h @@ -23,7 +23,6 @@ #include #include -#include #include #include "definitions.h" diff --git a/src/renderer.cpp b/src/renderer.cpp index 9d6e20d5..12312dde 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -284,7 +284,7 @@ QPixmap Render::extractFrame(int frame_position, int width, int height) { pix.fill(Qt::black); return pix; } - return KThumb::getFrame(*m_mltProducer, frame_position, width, height); + return KThumb::getFrame(m_mltProducer, frame_position, width, height); } QPixmap Render::getImageThumbnail(KUrl url, int width, int height) { diff --git a/src/transition.cpp b/src/transition.cpp index be01c204..2e163439 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -32,7 +32,10 @@ #include "kdenlivesettings.h" #include "mainwindow.h" -Transition::Transition(const ItemInfo info, int transitiontrack, double scale, double fps, QDomElement params) : AbstractClipItem(info, QRectF(info.startPos.frames(fps) *scale , info.track * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2, (info.endPos - info.startPos).frames(fps) * scale , KdenliveSettings::trackheight() / 3 * 2 - 1), fps), m_gradient(QLinearGradient(0, 0, 0, 0)) { +Transition::Transition(const ItemInfo info, int transitiontrack, double scale, double fps, QDomElement params) : AbstractClipItem(info, QRectF(), fps), m_gradient(QLinearGradient(0, 0, 0, 0)) { + setRect(0, 0, (qreal)(info.endPos - info.startPos).frames(fps) * scale - .5, (qreal)(KdenliveSettings::trackheight() / 3 * 2 - 1)); + setPos((qreal) info.startPos.frames(fps) * scale, (qreal)(info.track * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2)); + m_singleClip = true; m_transitionTrack = transitiontrack; m_secondClip = NULL; @@ -158,8 +161,9 @@ int Transition::type() const { } OPERATIONTYPE Transition::operationMode(QPointF pos, double scale) { - if (qAbs((int)(pos.x() - rect().x())) < 6) return RESIZESTART; - else if (qAbs((int)(pos.x() - (rect().x() + rect().width()))) < 6) return RESIZEEND; + QRectF rect = sceneBoundingRect(); + if (qAbs((int)(pos.x() - rect.x())) < 6) return RESIZESTART; + else if (qAbs((int)(pos.x() - (rect.right()))) < 6) return RESIZEEND; return MOVE; }