From 60cb9e1f3092575415ba61139071296c33b902ed Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Tue, 27 Sep 2011 12:20:52 +0000 Subject: [PATCH] * Fix aspect ratio of thumbnails to correctly use the project's arpect ratio * Fix transitions vertical offset in timeline causing possible corruption * Fix code for full zoom thumbnails generation svn path=/trunk/kdenlive/; revision=5930 --- src/clipitem.cpp | 289 ++++++++++++++++++++++------------------ src/clipitem.h | 3 +- src/clipmanager.cpp | 9 ++ src/clipmanager.h | 1 + src/customruler.cpp | 19 ++- src/customruler.h | 2 +- src/customtrackview.cpp | 37 ++++- src/customtrackview.h | 5 +- src/definitions.h | 1 - src/dvdwizardvob.cpp | 3 +- src/effectstackview.cpp | 1 + src/kthumb.cpp | 75 +++++++---- src/kthumb.h | 6 +- src/mainwindow.cpp | 4 +- src/markerdialog.cpp | 6 +- src/projectlist.cpp | 9 +- src/renderer.cpp | 35 ++--- src/trackview.cpp | 25 +++- src/trackview.h | 3 + src/transition.cpp | 24 ++-- 20 files changed, 335 insertions(+), 222 deletions(-) diff --git a/src/clipitem.cpp b/src/clipitem.cpp index e19af808..13274396 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -40,7 +40,9 @@ #include #include -ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, int strobe, bool generateThumbs) : +static int FRAME_SIZE; + +ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, int strobe, int frame_width, bool generateThumbs) : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_startFade(0), @@ -61,6 +63,7 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, i m_limitedKeyFrames(false) { setZValue(2); + FRAME_SIZE = frame_width; setRect(0, 0, (info.endPos - info.startPos).frames(fps) - 0.02, (double) itemHeight()); setPos(info.startPos.frames(fps), (double)(info.track * KdenliveSettings::trackheight()) + 1 + itemOffset()); @@ -135,7 +138,7 @@ ClipItem::~ClipItem() ClipItem *ClipItem::clone(ItemInfo info) const { - ClipItem *duplicate = new ClipItem(m_clip, info, m_fps, m_speed, m_strobe); + ClipItem *duplicate = new ClipItem(m_clip, info, m_fps, m_speed, m_strobe, FRAME_SIZE); if (m_clipType == IMAGE || m_clipType == TEXT) duplicate->slotSetStartThumb(m_startPix); else if (m_clipType != COLOR) { if (info.cropStart == m_info.cropStart) duplicate->slotSetStartThumb(m_startPix); @@ -731,16 +734,23 @@ void ClipItem::paint(QPainter *painter, QWidget *) { QColor paintColor; + QPen framePen; if (parentItem()) paintColor = QColor(255, 248, 149); else paintColor = m_baseColor; - if (isSelected() || (parentItem() && parentItem()->isSelected())) paintColor = paintColor.darker(); + if (isSelected() || (parentItem() && parentItem()->isSelected())) { + paintColor = paintColor.darker(); + framePen.setColor(Qt::red); + framePen.setWidth(2); + } + else { + framePen.setColor(paintColor.darker()); + } - painter->setMatrixEnabled(false); - const QRectF mapped = painter->matrix().mapRect(rect()).adjusted(0.5, 0, 0.5, 0); const QRectF exposed = option->exposedRect; - painter->setClipRect(mapped); - painter->fillRect(mapped, paintColor); - + painter->fillRect(exposed, paintColor); + painter->setClipRect(exposed); + painter->setMatrixEnabled(false); + const QRectF mapped = painter->matrix().mapRect(rect()).adjusted(0, 0, 1.0, 0.5); // draw thumbnails if (KdenliveSettings::videothumbnails() && !isAudioOnly()) { QPen pen = painter->pen(); @@ -762,26 +772,38 @@ void ClipItem::paint(QPainter *painter, QLineF l2(mapped.left() + m_startPix.width(), mapped.top(), mapped.left() + m_startPix.width(), mapped.bottom()); painter->drawLine(l2); } - if (painter->matrix().m11() == FRAME_SIZE && m_clip->thumbProducer() && clipType() != COLOR && clipType() != AUDIO && !m_audioOnly) { + + // if we are in full zoom, paint thumbnail for every frame + if (m_clip->thumbProducer() && clipType() != COLOR && clipType() != AUDIO && !m_audioOnly && painter->matrix().m11() == FRAME_SIZE) { int offset = (m_info.startPos - m_info.cropStart).frames(m_fps); - int left = qMax((int) m_info.startPos.frames(m_fps) + 1, (int) mapToScene(exposed.left(), 0).x()) - offset; - int right = qMin((int)(m_info.startPos + m_info.cropDuration).frames(m_fps) - 1, (int) mapToScene(exposed.right(), 0).x()) - offset; + int left = qMax((int) m_info.cropStart.frames(m_fps) + 1, (int) mapToScene(exposed.left(), 0).x() - offset); + int right = qMin((int)(m_info.cropStart + m_info.cropDuration).frames(m_fps) - 1, (int) mapToScene(exposed.right(), 0).x() - offset); QPointF startPos = mapped.topLeft(); - int twidth = FRAME_SIZE; int startOffset = m_info.cropStart.frames(m_fps); if (clipType() == IMAGE || clipType() == TEXT) { for (int i = left; i <= right; i++) { - painter->drawPixmap(startPos + QPointF(twidth *(i - startOffset), 0), m_startPix); + painter->drawPixmap(startPos + QPointF(FRAME_SIZE *(i - startOffset), 0), m_startPix); } } else { #if KDE_IS_VERSION(4,5,0) if (m_clip && m_clip->thumbProducer()) { - m_clip->thumbProducer()->queryIntraThumbs(left, right); - connect(m_clip->thumbProducer(), SIGNAL(thumbsCached()), this, SLOT(slotGotThumbsCache())); QString path = m_clip->fileURL().path() + "_"; + QImage img; + QPen pen(Qt::white); + pen.setStyle(Qt::DotLine); + painter->setPen(pen); + QList missing; for (int i = left; i <= right; i++) { - painter->drawImage(startPos + QPointF(twidth *(i - startOffset), 0), m_clip->thumbProducer()->findCachedThumb(path + QString::number(i))); + img = m_clip->thumbProducer()->findCachedThumb(path + QString::number(i)); + QPointF xpos = startPos + QPointF(FRAME_SIZE *(i - startOffset), 0); + if (img.isNull()) missing << i; + else painter->drawImage(xpos, img); + painter->drawLine(xpos, xpos + QPointF(0, mapped.height())); + } + if (!missing.isEmpty()) { + m_clip->thumbProducer()->queryIntraThumbs(missing); + connect(m_clip->thumbProducer(), SIGNAL(thumbsCached()), this, SLOT(slotGotThumbsCache())); } } #endif @@ -819,7 +841,6 @@ void ClipItem::paint(QPainter *painter, const int mappedEndPixel = painter->matrix().map(QPointF(endpixel + cropLeft, 0)).x() - clipStart; cropLeft = cropLeft * scale; - if (channels >= 1) { emit prepareAudioThumb(scale, mappedStartPixel, mappedEndPixel, channels); } @@ -830,133 +851,129 @@ void ClipItem::paint(QPainter *painter, } } - // Draw effects names - if (!m_effectNames.isEmpty() && mapped.width() > 40) { - QRectF txtBounding = painter->boundingRect(mapped, Qt::AlignLeft | Qt::AlignTop, m_effectNames); - QColor bgColor; - if (m_timeLine && m_timeLine->state() == QTimeLine::Running) { - qreal value = m_timeLine->currentValue(); - txtBounding.setWidth(txtBounding.width() * value); - bgColor.setRgb(50 + 200 *(1.0 - value), 50, 50, 100 + 50 * value); - } else bgColor.setRgb(50, 50, 90, 180); - - QPainterPath rounded; - rounded.moveTo(txtBounding.bottomRight()); - rounded.arcTo(txtBounding.right() - txtBounding.height() - 2, txtBounding.top() - txtBounding.height(), txtBounding.height() * 2, txtBounding.height() * 2, 270, 90); - rounded.lineTo(txtBounding.topLeft()); - rounded.lineTo(txtBounding.bottomLeft()); - painter->fillPath(rounded, bgColor); - painter->setPen(Qt::lightGray); - painter->drawText(txtBounding.adjusted(1, 0, 1, 0), Qt::AlignCenter, m_effectNames); - } - - // Draw clip name - QColor frameColor(paintColor.darker()); - if (isSelected() || (parentItem() && parentItem()->isSelected())) { - frameColor = QColor(Qt::red); - } - frameColor.setAlpha(160); - - const QRectF txtBounding2 = painter->boundingRect(mapped, Qt::AlignHCenter | Qt::AlignVCenter, ' ' + m_clipName + ' '); - //painter->fillRect(txtBounding2, frameColor); - painter->setBrush(frameColor); - painter->setPen(Qt::NoPen); - painter->drawRoundedRect(txtBounding2, 3, 3); - painter->setBrush(QBrush(Qt::NoBrush)); - - //painter->setPen(QColor(0, 0, 0, 180)); - //painter->drawText(txtBounding, Qt::AlignCenter, m_clipName); - if (m_videoOnly) { - painter->drawPixmap(txtBounding2.topLeft() - QPointF(17, -1), m_videoPix); - } else if (m_audioOnly) { - painter->drawPixmap(txtBounding2.topLeft() - QPointF(17, -1), m_audioPix); - } - painter->setPen(Qt::white); - painter->drawText(txtBounding2, Qt::AlignCenter, m_clipName); + // only paint details if clip is big enough + if (mapped.width() > 20) { + + // Draw effects names + if (!m_effectNames.isEmpty() && mapped.width() > 40) { + QRectF txtBounding = painter->boundingRect(mapped, Qt::AlignLeft | Qt::AlignTop, m_effectNames); + QColor bgColor; + if (m_timeLine && m_timeLine->state() == QTimeLine::Running) { + qreal value = m_timeLine->currentValue(); + txtBounding.setWidth(txtBounding.width() * value); + bgColor.setRgb(50 + 200 *(1.0 - value), 50, 50, 100 + 50 * value); + } else bgColor.setRgb(50, 50, 90, 180); + + QPainterPath rounded; + rounded.moveTo(txtBounding.bottomRight()); + rounded.arcTo(txtBounding.right() - txtBounding.height() - 2, txtBounding.top() - txtBounding.height(), txtBounding.height() * 2, txtBounding.height() * 2, 270, 90); + rounded.lineTo(txtBounding.topLeft()); + rounded.lineTo(txtBounding.bottomLeft()); + painter->fillPath(rounded, bgColor); + painter->setPen(Qt::lightGray); + painter->drawText(txtBounding.adjusted(1, 0, 1, 0), Qt::AlignCenter, m_effectNames); + } + const QRectF txtBounding2 = painter->boundingRect(mapped, Qt::AlignHCenter | Qt::AlignVCenter, ' ' + m_clipName + ' '); + painter->setBrush(framePen.color()); + painter->setPen(Qt::NoPen); + painter->drawRoundedRect(txtBounding2, 3, 3); + painter->setBrush(QBrush(Qt::NoBrush)); - // draw markers - if (isEnabled() && m_clip) { - QList < CommentedTime > markers = m_clip->commentedSnapMarkers(); - QList < CommentedTime >::Iterator it = markers.begin(); - GenTime pos; - double framepos; - QBrush markerBrush(QColor(120, 120, 0, 140)); - QPen pen = painter->pen(); - pen.setColor(QColor(255, 255, 255, 200)); - pen.setStyle(Qt::DotLine); - - for (; it != markers.end(); ++it) { - pos = GenTime((int)((*it).time().frames(m_fps) / qAbs(m_speed) + 0.5), m_fps) - cropStart(); - if (pos > GenTime()) { - if (pos > cropDuration()) break; - QLineF l(rect().x() + pos.frames(m_fps), rect().y(), rect().x() + pos.frames(m_fps), rect().bottom()); - QLineF l2 = painter->matrix().map(l); - painter->setPen(pen); - painter->drawLine(l2); - if (KdenliveSettings::showmarkers()) { - framepos = rect().x() + pos.frames(m_fps); - const QRectF r1(framepos + 0.04, 10, rect().width() - framepos - 2, rect().height() - 10); - const QRectF r2 = painter->matrix().mapRect(r1); - const QRectF txtBounding3 = painter->boundingRect(r2, Qt::AlignLeft | Qt::AlignTop, ' ' + (*it).comment() + ' '); - painter->setBrush(markerBrush); - painter->setPen(Qt::NoPen); - painter->drawRoundedRect(txtBounding3, 3, 3); - painter->setBrush(QBrush(Qt::NoBrush)); - painter->setPen(Qt::white); - painter->drawText(txtBounding3, Qt::AlignCenter, (*it).comment()); + if (m_videoOnly) { + painter->drawPixmap(txtBounding2.topLeft() - QPointF(17, -1), m_videoPix); + } else if (m_audioOnly) { + painter->drawPixmap(txtBounding2.topLeft() - QPointF(17, -1), m_audioPix); + } + painter->setPen(Qt::white); + painter->drawText(txtBounding2, Qt::AlignCenter, m_clipName); + + + // draw markers + if (isEnabled() && m_clip) { + QList < CommentedTime > markers = m_clip->commentedSnapMarkers(); + QList < CommentedTime >::Iterator it = markers.begin(); + GenTime pos; + double framepos; + QBrush markerBrush(QColor(120, 120, 0, 140)); + QPen pen = painter->pen(); + pen.setColor(QColor(255, 255, 255, 200)); + pen.setStyle(Qt::DotLine); + + for (; it != markers.end(); ++it) { + pos = GenTime((int)((*it).time().frames(m_fps) / qAbs(m_speed) + 0.5), m_fps) - cropStart(); + if (pos > GenTime()) { + if (pos > cropDuration()) break; + QLineF l(rect().x() + pos.frames(m_fps), rect().y(), rect().x() + pos.frames(m_fps), rect().bottom()); + QLineF l2 = painter->matrix().map(l); + painter->setPen(pen); + painter->drawLine(l2); + if (KdenliveSettings::showmarkers()) { + framepos = rect().x() + pos.frames(m_fps); + const QRectF r1(framepos + 0.04, 10, rect().width() - framepos - 2, rect().height() - 10); + const QRectF r2 = painter->matrix().mapRect(r1); + const QRectF txtBounding3 = painter->boundingRect(r2, Qt::AlignLeft | Qt::AlignTop, ' ' + (*it).comment() + ' '); + painter->setBrush(markerBrush); + painter->setPen(Qt::NoPen); + painter->drawRoundedRect(txtBounding3, 3, 3); + painter->setBrush(QBrush(Qt::NoBrush)); + painter->setPen(Qt::white); + painter->drawText(txtBounding3, Qt::AlignCenter, (*it).comment()); + } + //painter->fillRect(QRect(br.x() + framepos, br.y(), 10, br.height()), QBrush(QColor(0, 0, 0, 150))); } - //painter->fillRect(QRect(br.x() + framepos, br.y(), 10, br.height()), QBrush(QColor(0, 0, 0, 150))); } } - } - // draw start / end fades - QBrush fades; - if (isSelected()) { - fades = QBrush(QColor(200, 50, 50, 150)); - } else fades = QBrush(QColor(200, 200, 200, 200)); - - if (m_startFade != 0) { - QPainterPath fadeInPath; - fadeInPath.moveTo(0, 0); - fadeInPath.lineTo(0, rect().height()); - fadeInPath.lineTo(m_startFade, 0); - fadeInPath.closeSubpath(); - QPainterPath f1 = painter->matrix().map(fadeInPath); - painter->fillPath(f1/*.intersected(resultClipPath)*/, fades); - /*if (isSelected()) { - QLineF l(m_startFade * scale, 0, 0, itemHeight); - painter->drawLine(l); - }*/ - } - if (m_endFade != 0) { - QPainterPath fadeOutPath; - fadeOutPath.moveTo(rect().width(), 0); - fadeOutPath.lineTo(rect().width(), rect().height()); - fadeOutPath.lineTo(rect().width() - m_endFade, 0); - fadeOutPath.closeSubpath(); - QPainterPath f1 = painter->matrix().map(fadeOutPath); - painter->fillPath(f1/*.intersected(resultClipPath)*/, fades); - /*if (isSelected()) { - QLineF l(itemWidth - m_endFade * scale, 0, itemWidth, itemHeight); - painter->drawLine(l); - }*/ - } - - - painter->setPen(QPen(Qt::lightGray)); - // draw effect or transition keyframes - if (mapped.width() > 20) drawKeyFrames(painter, m_limitedKeyFrames); + // draw start / end fades + QBrush fades; + if (isSelected()) { + fades = QBrush(QColor(200, 50, 50, 150)); + } else fades = QBrush(QColor(200, 200, 200, 200)); + + if (m_startFade != 0) { + QPainterPath fadeInPath; + fadeInPath.moveTo(0, 0); + fadeInPath.lineTo(0, rect().height()); + fadeInPath.lineTo(m_startFade, 0); + fadeInPath.closeSubpath(); + QPainterPath f1 = painter->matrix().map(fadeInPath); + painter->fillPath(f1/*.intersected(resultClipPath)*/, fades); + /*if (isSelected()) { + QLineF l(m_startFade * scale, 0, 0, itemHeight); + painter->drawLine(l); + }*/ + } + if (m_endFade != 0) { + QPainterPath fadeOutPath; + fadeOutPath.moveTo(rect().width(), 0); + fadeOutPath.lineTo(rect().width(), rect().height()); + fadeOutPath.lineTo(rect().width() - m_endFade, 0); + fadeOutPath.closeSubpath(); + QPainterPath f1 = painter->matrix().map(fadeOutPath); + painter->fillPath(f1/*.intersected(resultClipPath)*/, fades); + /*if (isSelected()) { + QLineF l(itemWidth - m_endFade * scale, 0, itemWidth, itemHeight); + painter->drawLine(l); + }*/ + } - //painter->setMatrixEnabled(true); + painter->setPen(QPen(Qt::lightGray)); + // draw effect or transition keyframes + drawKeyFrames(painter, m_limitedKeyFrames); + } + // draw clip border // expand clip rect to allow correct painting of clip border - QPen pen1(frameColor); - painter->setPen(pen1); painter->setClipping(false); - painter->drawRect(painter->matrix().mapRect(rect())); + painter->setPen(framePen); + if (isSelected() || (parentItem() && parentItem()->isSelected())) { + painter->drawRect(mapped.adjusted(1.0, 0.5, -1.5, -0.5)); + } + else { + painter->drawRect(mapped.adjusted(0, 0.5, -0.5, -0.5)); + } } @@ -999,6 +1016,12 @@ int ClipItem::itemHeight() return KdenliveSettings::trackheight() - 2; } +void ClipItem::resetFrameWidth(int width) +{ + FRAME_SIZE = width; + update(); +} + QList ClipItem::snapMarkers() const { QList < GenTime > snaps; diff --git a/src/clipitem.h b/src/clipitem.h index 8a1137d6..c5323905 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -46,7 +46,7 @@ class ClipItem : public AbstractClipItem Q_OBJECT public: - ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, int strobe, bool generateThumbs = true); + ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, int strobe, int frame_width, bool generateThumbs = true); virtual ~ ClipItem(); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, @@ -172,6 +172,7 @@ public: * @return Fitting producer * Which producer is returned depends on the type of this clip (audioonly, videoonly, normal) */ Mlt::Producer *getProducer(int track, bool trackSpecific = true); + void resetFrameWidth(int width); protected: //virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event); diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp index d3669cad..bc07ebac 100644 --- a/src/clipmanager.cpp +++ b/src/clipmanager.cpp @@ -54,7 +54,9 @@ ClipManager::ClipManager(KdenliveDoc *doc) : connect(&m_modifiedTimer, SIGNAL(timeout()), this, SLOT(slotProcessModifiedClips())); #if KDE_IS_VERSION(4,5,0) + KImageCache::deleteCache("kdenlive-thumbs"); pixmapCache = new KImageCache("kdenlive-thumbs", 1000000); + pixmapCache->setEvictionPolicy(KSharedDataCache::EvictOldest); #endif } @@ -83,6 +85,13 @@ void ClipManager::clear() #endif } +void ClipManager::clearCache() +{ +#if KDE_IS_VERSION(4,5,0) + pixmapCache->clear(); +#endif +} + void ClipManager::checkAudioThumbs() { if (!KdenliveSettings::audiothumbnails()) { diff --git a/src/clipmanager.h b/src/clipmanager.h index 4bf78eb2..ad01a17c 100644 --- a/src/clipmanager.h +++ b/src/clipmanager.h @@ -105,6 +105,7 @@ Q_OBJECT public: void addFolder(const QString&, const QString&); void deleteFolder(const QString&); void clear(); + void clearCache(); AbstractGroupItem *createGroup(); void removeGroup(AbstractGroupItem *group); QDomElement groupsXml() const; diff --git a/src/customruler.cpp b/src/customruler.cpp index 98baa637..00b469d8 100644 --- a/src/customruler.cpp +++ b/src/customruler.cpp @@ -43,6 +43,7 @@ static const int LITTLE_MARK_LENGTH = (MIDDLE_MARK_LENGTH / 2); static const int LITTLE_MARK_X2 = LINE_END; static const int LITTLE_MARK_X1 = (LITTLE_MARK_X2 - LITTLE_MARK_LENGTH); +static int FRAME_SIZE; static int LABEL_SIZE; static const int END_LABEL_X = 4; static const int END_LABEL_Y = (END_LABEL_X + LABEL_SIZE - 2); @@ -62,16 +63,15 @@ CustomRuler::CustomRuler(Timecode tc, CustomTrackView *parent) : m_duration(0), m_offset(0), m_clickedGuide(-1), - m_mouseMove(NO_MOVE) + m_mouseMove(NO_MOVE), + m_rate(-1) { setFont(KGlobalSettings::toolBarFont()); QFontMetricsF fontMetrics(font()); LABEL_SIZE = fontMetrics.ascent() - 2; + updateFrameSize(); m_scale = 3; m_zoneColor = KStatefulBrush(KColorScheme::View, KColorScheme::PositiveBackground, KSharedConfig::openConfig(KdenliveSettings::colortheme())).brush(this).color(); - littleMarkDistance = FRAME_SIZE; - mediumMarkDistance = FRAME_SIZE * m_timecode.fps(); - bigMarkDistance = FRAME_SIZE * m_timecode.fps() * 60; m_zoneStart = 0; m_zoneEnd = 100; m_contextMenu = new QMenu(this); @@ -97,6 +97,17 @@ void CustomRuler::updateProjectFps(Timecode t) update(); } +void CustomRuler::updateFrameSize() +{ + FRAME_SIZE = m_view->getFrameWidth(); + kDebug()<<"// GOT FRM SZ: "< 0) setPixelPerMark(m_rate); +} + void CustomRuler::slotEditGuide() { m_view->slotEditGuide(m_clickedGuide); diff --git a/src/customruler.h b/src/customruler.h index 3ebcd107..c36cdd3f 100644 --- a/src/customruler.h +++ b/src/customruler.h @@ -48,7 +48,7 @@ public: void setZone(QPoint p); int offset() const; void updateProjectFps(Timecode t); - + void updateFrameSize(); protected: virtual void paintEvent(QPaintEvent * /*e*/); virtual void wheelEvent(QWheelEvent * e); diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 078eddda..ee7c5bd2 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -262,14 +262,35 @@ void CustomTrackView::checkAutoScroll() return m_scene->m_tracksList; }*/ -void CustomTrackView::checkTrackHeight() + +int CustomTrackView::getFrameWidth() +{ + return (int) (m_tracksHeight * m_document->mltProfile().display_aspect_num / m_document->mltProfile().display_aspect_den + 0.5); +} + +void CustomTrackView::updateSceneFrameWidth() +{ + int frameWidth = getFrameWidth(); + QList itemList = items(); + ClipItem *item; + for (int i = 0; i < itemList.count(); i++) { + if (itemList.at(i)->type() == AVWIDGET) { + item = (ClipItem*) itemList.at(i); + item->resetFrameWidth(frameWidth); + item->resetThumbs(true); + } + } +} + +bool CustomTrackView::checkTrackHeight() { - if (m_tracksHeight == KdenliveSettings::trackheight()) return; + if (m_tracksHeight == KdenliveSettings::trackheight()) return false; m_tracksHeight = KdenliveSettings::trackheight(); emit trackHeightChanged(); QList itemList = items(); ClipItem *item; Transition *transitionitem; + int frameWidth = getFrameWidth(); bool snap = KdenliveSettings::snaptopoints(); KdenliveSettings::setSnaptopoints(false); for (int i = 0; i < itemList.count(); i++) { @@ -277,6 +298,7 @@ void CustomTrackView::checkTrackHeight() item = (ClipItem*) itemList.at(i); item->setRect(0, 0, item->rect().width(), m_tracksHeight - 1); item->setPos((qreal) item->startPos().frames(m_document->fps()), (qreal) item->track() * m_tracksHeight + 1); + item->resetFrameWidth(frameWidth); item->resetThumbs(true); } else if (itemList.at(i)->type() == TRANSITIONWIDGET) { transitionitem = (Transition*) itemList.at(i); @@ -297,6 +319,7 @@ void CustomTrackView::checkTrackHeight() // verticalScrollBar()->setMaximum(m_tracksHeight * m_document->tracksCount()); KdenliveSettings::setSnaptopoints(snap); viewport()->update(); + return true; } /** Zoom or move viewport on mousewheel @@ -718,7 +741,6 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) // check item under mouse QList collisionList = items(m_clickEvent); - if (event->modifiers() == Qt::ControlModifier && m_tool != SPACERTOOL && collisionList.count() == 0) { // Pressing Ctrl + left mouse button in an empty area scrolls the timeline setDragMode(QGraphicsView::ScrollHandDrag); @@ -905,7 +927,8 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) } else { setCursorPos((int)(mapToScene(event->x(), 0).x())); } - QGraphicsView::mousePressEvent(event); + //QGraphicsView::mousePressEvent(event); + event->ignore(); return; } @@ -1491,7 +1514,7 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint &pos) return true; } m_selectionGroup = new AbstractGroupItem(m_document->fps()); - ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1); + ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1, getFrameWidth()); m_selectionGroup->addToGroup(item); item->setFlag(QGraphicsItem::ItemIsMovable, false); @@ -1549,7 +1572,7 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint &pos) info.track = 0; start += info.cropDuration; offsetList.append(start); - ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1, false); + ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1, getFrameWidth(), false); item->setFlag(QGraphicsItem::ItemIsMovable, false); m_selectionGroup->addToGroup(item); if (!clip->isPlaceHolder()) m_waitingThumbs.append(item); @@ -4115,7 +4138,7 @@ void CustomTrackView::addClip(QDomElement xml, const QString &clipId, ItemInfo i m_mutex.unlock(); } - ClipItem *item = new ClipItem(baseclip, info, m_document->fps(), xml.attribute("speed", "1").toDouble(), xml.attribute("strobe", "1").toInt()); + ClipItem *item = new ClipItem(baseclip, info, m_document->fps(), xml.attribute("speed", "1").toDouble(), xml.attribute("strobe", "1").toInt(), getFrameWidth()); item->setEffectList(effects); if (xml.hasAttribute("audio_only")) item->setAudioOnly(true); else if (xml.hasAttribute("video_only")) item->setVideoOnly(true); diff --git a/src/customtrackview.h b/src/customtrackview.h index dbde9f89..5e2def1a 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -88,7 +88,8 @@ public: /** @brief Cuts all clips that are selected at the timeline cursor position. */ void cutSelectedClips(); void setContextMenu(QMenu *timeline, QMenu *clip, QMenu *transition, QActionGroup *clipTypeGroup, QMenu *markermenu); - void checkTrackHeight(); + bool checkTrackHeight(); + void updateSceneFrameWidth(); //QList tracksList() const; void setTool(PROJECTTOOL tool); ClipItem *cutClip(ItemInfo info, GenTime cutTime, bool cut, bool execute = true); @@ -185,6 +186,8 @@ public: * Check whether given track has a clip with audio in it. */ bool hasAudio(int track) const; + int getFrameWidth(); + public slots: void setCursorPos(int pos, bool seek = true); void moveCursorPos(int delta); diff --git a/src/definitions.h b/src/definitions.h index 4384e8c6..7bedcd26 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -27,7 +27,6 @@ #include #include -const int FRAME_SIZE = 90; const int MAXCLIPDURATION = 15000; enum OPERATIONTYPE { NONE = 0, MOVE = 1, RESIZESTART = 2, RESIZEEND = 3, FADEIN = 4, FADEOUT = 5, TRANSITIONSTART = 6, TRANSITIONEND = 7, MOVEGUIDE = 8, KEYFRAME = 9, SEEK = 10, SPACER = 11, RUBBERSELECTION = 12}; diff --git a/src/dvdwizardvob.cpp b/src/dvdwizardvob.cpp index 8b9b0d6f..2e4a0be1 100644 --- a/src/dvdwizardvob.cpp +++ b/src/dvdwizardvob.cpp @@ -120,8 +120,9 @@ void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters) if (producer->is_blank() == false) { int width = 45.0 * profile.dar(); + int swidth = 45.0 * profile.width() / profile.height(); if (width % 2 == 1) width++; - item->setIcon(0, QPixmap::fromImage(KThumb::getFrame(producer, 0, width, 45))); + item->setIcon(0, QPixmap::fromImage(KThumb::getFrame(producer, 0, swidth, width, 45))); int playTime = producer->get_playtime(); item->setText(1, Timecode::getStringTimecode(playTime, profile.fps())); item->setData(1, Qt::UserRole, playTime); diff --git a/src/effectstackview.cpp b/src/effectstackview.cpp index c0866ae8..11f09cca 100644 --- a/src/effectstackview.cpp +++ b/src/effectstackview.cpp @@ -431,6 +431,7 @@ void EffectStackView::clear() ItemInfo info; m_effectedit->transferParamDesc(QDomElement(), info); //m_ui.region_url->clear(); + m_clipref = NULL; m_ui.buttonShowComments->setEnabled(false); m_ui.labelComment->setText(QString()); m_ui.effectlist->blockSignals(false); diff --git a/src/kthumb.cpp b/src/kthumb.cpp index 8fa3d6aa..b26b5f1a 100644 --- a/src/kthumb.cpp +++ b/src/kthumb.cpp @@ -46,6 +46,7 @@ KThumb::KThumb(ClipManager *clipManager, KUrl url, const QString &id, const QStr m_url(url), m_thumbFile(), m_dar(1), + m_ratio(1), m_producer(NULL), m_clipManager(clipManager), m_id(id), @@ -76,7 +77,11 @@ void KThumb::setProducer(Mlt::Producer *producer) m_producer = producer; // FIXME: the profile() call leaks an object, but trying to free // it leads to a double-free in Profile::~Profile() - if (producer) m_dar = producer->profile()->dar(); + if (producer) { + m_dar = producer->profile()->dar(); + m_ratio = (double) producer->profile()->width() / producer->profile()->height(); + } + } void KThumb::clearProducer() @@ -120,12 +125,13 @@ void KThumb::extractImage(int frame, int frame2) void KThumb::doGetThumbs() { const int theight = KdenliveSettings::trackheight(); - const int twidth = FRAME_SIZE;//(int)(theight * m_dar + 0.5); + const int swidth = (int)(theight * m_ratio + 0.5); + const int dwidth = (int)(theight * m_dar + 0.5); while (!m_requestedThumbs.isEmpty()) { int frame = m_requestedThumbs.takeFirst(); if (frame != -1) { - QImage img = getFrame(m_producer, frame, twidth, theight); + QImage img = getFrame(m_producer, frame, swidth, dwidth, theight); emit thumbReady(frame, img); } } @@ -133,7 +139,7 @@ void KThumb::doGetThumbs() QPixmap KThumb::extractImage(int frame, int width, int height) { - return QPixmap::fromImage(getFrame(m_producer, frame, width, height)); + return QPixmap::fromImage(getFrame(m_producer, frame, (int) (height * m_ratio + 0.5), width, height)); } //static @@ -146,16 +152,16 @@ QPixmap KThumb::getImage(KUrl url, int frame, int width, int height) //""); //Mlt::Producer producer(profile, "xml-string", tmp); Mlt::Producer *producer = new Mlt::Producer(profile, url.path().toUtf8().constData()); - - pix = QPixmap::fromImage(getFrame(producer, frame, width, height)); + double swidth = (double) profile.width() / profile.height(); + pix = QPixmap::fromImage(getFrame(producer, frame, (int) (height * swidth + 0.5), width, height)); delete producer; return pix; } //static -QImage KThumb::getFrame(Mlt::Producer *producer, int framepos, int width, int height) +QImage KThumb::getFrame(Mlt::Producer *producer, int framepos, int frameWidth, int displayWidth, int height) { - QImage p(width, height, QImage::Format_ARGB32_Premultiplied); + QImage p(displayWidth, height, QImage::Format_ARGB32_Premultiplied); if (producer == NULL || !producer->is_valid()) { p.fill(Qt::red); return p; @@ -168,33 +174,44 @@ QImage KThumb::getFrame(Mlt::Producer *producer, int framepos, int width, int he producer->seek(framepos); Mlt::Frame *frame = producer->get_frame(); - if (!frame) { - kDebug() << "///// BROKEN FRAME"; + p = getFrame(frame, frameWidth, displayWidth, height); + delete frame; + return p; +} + + +//static +QImage KThumb::getFrame(Mlt::Frame *frame, int frameWidth, int displayWidth, int height) +{ + QImage p(displayWidth, height, QImage::Format_ARGB32_Premultiplied); + if (frame == NULL || !frame->is_valid()) { p.fill(Qt::red); return p; } - int ow = width; + int ow = frameWidth; int oh = height; mlt_image_format format = mlt_image_rgb24a; uint8_t *data = frame->get_image(format, ow, oh, 0); QImage image((uchar *)data, ow, oh, QImage::Format_ARGB32_Premultiplied); - //mlt_service_unlock(service.get_service()); - if (!image.isNull()) { - if (ow > (2 * width)) { + if (ow > (2 * displayWidth)) { // there was a scaling problem, do it manually - QImage scaled = image.scaled(width, height); - p = scaled.rgbSwapped(); - } else p = image.rgbSwapped(); + QImage scaled = image.scaled(displayWidth, height); + image = scaled.rgbSwapped(); + } else { + image = image.scaled(displayWidth, height, Qt::IgnoreAspectRatio).rgbSwapped(); + } + QPainter painter(&p); + painter.fillRect(p.rect(), Qt::black); + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + painter.drawImage(p.rect(), image); + painter.end(); } else p.fill(Qt::red); - - delete frame; return p; } - //static uint KThumb::imageVariance(QImage image ) { @@ -446,9 +463,9 @@ void KThumb::askForAudioThumbs(const QString &id) } #if KDE_IS_VERSION(4,5,0) -void KThumb::queryIntraThumbs(int start, int end) +void KThumb::queryIntraThumbs(QList missingFrames) { - for (int i = start; i <= end; i++) { + foreach (int i, missingFrames) { if (!m_intraFramesQueue.contains(i)) m_intraFramesQueue.append(i); } qSort(m_intraFramesQueue); @@ -457,19 +474,23 @@ void KThumb::queryIntraThumbs(int start, int end) void KThumb::slotGetIntraThumbs() { - int theight = KdenliveSettings::trackheight(); - int twidth = FRAME_SIZE; + const int theight = KdenliveSettings::trackheight(); + const int frameWidth = (int)(theight * m_ratio + 0.5); + const int displayWidth = (int)(theight * m_dar + 0.5); QString path = m_url.path() + "_"; - QImage img; + bool addedThumbs = false; while (!m_intraFramesQueue.isEmpty()) { int pos = m_intraFramesQueue.takeFirst(); if (!m_clipManager->pixmapCache->contains(path + QString::number(pos))) { - m_clipManager->pixmapCache->insertImage(path + QString::number(pos), getFrame(m_producer, pos, twidth, theight)); + if (m_clipManager->pixmapCache->insertImage(path + QString::number(pos), getFrame(m_producer, pos, frameWidth, displayWidth, theight))) { + addedThumbs = true; + } + else kDebug()<<"// INSERT FAILD FOR: "< missingFrames); /** @brief Query cached thumbnail. */ QImage findCachedThumb(const QString path); #endif @@ -80,7 +80,8 @@ public slots: void removeAudioThumb(); void getAudioThumbs(int channel, double frame, double frameLength, int arrayWidth); static QPixmap getImage(KUrl url, int frame, int width, int height); - static QImage getFrame(Mlt::Producer *producer, int framepos, int width, int height); + static QImage getFrame(Mlt::Producer *producer, int framepos, int frameWidth, int displayWidth, int height); + static QImage getFrame(Mlt::Frame *frame, int frameWidth, int displayWidth, int height); /** @brief Calculates image variance, useful to know if a thumbnail is interesting. * @return an integer between 0 and 100. 0 means no variance, eg. black image while bigger values mean contrasted image * */ @@ -99,6 +100,7 @@ private: KUrl m_url; QString m_thumbFile; double m_dar; + double m_ratio; Mlt::Producer *m_producer; ClipManager *m_clipManager; QString m_id; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 81600b4f..42bf7ac7 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2296,6 +2296,8 @@ void MainWindow::slotUpdateProjectProfile(const QString &profile) if (m_renderWidget) m_renderWidget->setProfile(m_activeDocument->mltProfile()); m_timelineArea->setTabText(m_timelineArea->currentIndex(), m_activeDocument->description()); if (updateFps) m_activeTimeline->updateProjectFps(); + m_activeDocument->clipManager()->clearCache(); + m_activeTimeline->updateProfile(); m_activeDocument->setModified(true); m_commandStack->activeStack()->clear(); //Update the mouse position display so it will display in DF/NDF format by default based on the project setting. @@ -2639,7 +2641,7 @@ void MainWindow::updateConfiguration() if (m_activeTimeline) { m_activeTimeline->refresh(); m_activeTimeline->projectView()->checkAutoScroll(); - m_activeTimeline->projectView()->checkTrackHeight(); + m_activeTimeline->checkTrackHeight(); if (m_activeDocument) m_activeDocument->clipManager()->checkAudioThumbs(); } diff --git a/src/markerdialog.cpp b/src/markerdialog.cpp index 87e3f43a..a3935e5a 100644 --- a/src/markerdialog.cpp +++ b/src/markerdialog.cpp @@ -61,6 +61,7 @@ MarkerDialog::MarkerDialog(DocClipBase *clip, CommentedTime t, Timecode tc, cons if (width % 2 == 1) width++; QPixmap p(width, 100); QString colour = clip->getProperty("colour"); + int swidth = (int) (100.0 * m_profile->width() / m_profile->height() + 0.5); switch (m_clip->clipType()) { case VIDEO: @@ -70,7 +71,7 @@ MarkerDialog::MarkerDialog(DocClipBase *clip, CommentedTime t, Timecode tc, cons connect(this, SIGNAL(updateThumb()), m_previewTimer, SLOT(start())); case IMAGE: case TEXT: - p = QPixmap::fromImage(KThumb::getFrame(m_producer, m_in->getValue(), width, 100)); + p = QPixmap::fromImage(KThumb::getFrame(m_producer, m_in->getValue(), swidth, width, 100)); break; case COLOR: colour = colour.replace(0, 2, "#"); @@ -109,8 +110,9 @@ void MarkerDialog::slotUpdateThumb() m_previewTimer->stop(); int pos = m_in->getValue(); int width = 100.0 * m_dar; + int swidth = (int) (100.0 * m_profile->width() / m_profile->height() + 0.5); if (width % 2 == 1) width++; - QPixmap p = QPixmap::fromImage(KThumb::getFrame(m_producer, pos, width, 100)); + QPixmap p = QPixmap::fromImage(KThumb::getFrame(m_producer, pos, swidth, width, 100)); if (!p.isNull()) clip_thumb->setPixmap(p); else diff --git a/src/projectlist.cpp b/src/projectlist.cpp index e2115e45..6e5ddb6c 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -1645,13 +1645,14 @@ void ProjectList::slotRefreshClipThumbnail(QTreeWidgetItem *it, bool update) } QPixmap pix; int height = m_listView->iconSize().height(); - int width = (int)(height * m_render->dar()); + int swidth = (int)(height * m_render->frameRenderWidth() / m_render->renderHeight()+ 0.5); + int dwidth = (int)(height * m_render->dar() + 0.5); if (clip->clipType() == AUDIO) - pix = KIcon("audio-x-generic").pixmap(QSize(width, height)); + pix = KIcon("audio-x-generic").pixmap(QSize(dwidth, height)); else if (clip->clipType() == IMAGE) - pix = QPixmap::fromImage(KThumb::getFrame(item->referencedClip()->producer(), 0, width, height)); + pix = QPixmap::fromImage(KThumb::getFrame(item->referencedClip()->producer(), 0, swidth, dwidth, height)); else - pix = item->referencedClip()->extractImage(frame, width, height); + pix = item->referencedClip()->extractImage(frame, dwidth, height); if (!pix.isNull()) { monitorItemEditing(false); diff --git a/src/renderer.cpp b/src/renderer.cpp index 91251de4..e06b0f7a 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -190,6 +190,7 @@ void Render::buildConsumer(const QString &profileName) setenv("MLT_PROFILE", tmp, 1); m_mltProfile = new Mlt::Profile(tmp); m_mltProfile->set_explicit(true); + kDebug()<<"// ********* PROFILE AR: "<dar(); delete[] tmp; m_blackClip = new Mlt::Producer(*m_mltProfile, "colour", "black"); @@ -409,15 +410,15 @@ int Render::renderHeight() const QImage Render::extractFrame(int frame_position, QString path, int width, int height) { if (width == -1) { - width = renderWidth(); + width = frameRenderWidth(); height = renderHeight(); } else if (width % 2 == 1) width++; - + int dwidth = height * frameRenderWidth() / renderHeight(); if (!path.isEmpty()) { Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile, path.toUtf8().constData()); if (producer) { if (producer->is_valid()) { - QImage img = KThumb::getFrame(producer, frame_position, width, height); + QImage img = KThumb::getFrame(producer, frame_position, dwidth, width, height); delete producer; return img; } @@ -430,7 +431,7 @@ QImage Render::extractFrame(int frame_position, QString path, int width, int hei pix.fill(Qt::black); return pix; } - return KThumb::getFrame(m_mltProducer, frame_position, width, height); + return KThumb::getFrame(m_mltProducer, frame_position, dwidth, width, height); } QPixmap Render::getImageThumbnail(KUrl url, int /*width*/, int /*height*/) @@ -703,7 +704,8 @@ void Render::getFileProperties(const QDomElement &xml, const QString &clipId, in return; } - int width = (int)(imageHeight * m_mltProfile->dar() + 0.5); + int imageWidth = (int)((double) imageHeight * m_mltProfile->width() / m_mltProfile->height() + 0.5); + int fullWidth = (int)((double) imageHeight * m_mltProfile->dar() + 0.5); QMap < QString, QString > filePropertyMap; QMap < QString, QString > metadataPropertyMap; @@ -782,24 +784,13 @@ void Render::getFileProperties(const QDomElement &xml, const QString &clipId, in int variance; mlt_image_format format = mlt_image_rgb24a; - int frame_width = width; + int frame_width = imageWidth; int frame_height = imageHeight; - QPixmap pix; + QImage img; do { variance = 100; - uint8_t *data = frame->get_image(format, frame_width, frame_height, 0); - QImage image((uchar *)data, frame_width, frame_height, QImage::Format_ARGB32_Premultiplied); - - if (!image.isNull()) { - if (frame_width > (2 * width)) { - // there was a scaling problem, do it manually - QImage scaled = image.scaled(width, imageHeight); - pix = QPixmap::fromImage(scaled.rgbSwapped()); - } else pix = QPixmap::fromImage(image.rgbSwapped()); - variance = KThumb::imageVariance(image); - } else - pix.fill(Qt::black); - + img = KThumb::getFrame(frame, imageWidth, fullWidth, imageHeight); + variance = KThumb::imageVariance(img); if (frameNumber == 0 && variance< 6) { // Thumbnail is not interesting (for example all black, seek to fetch better thumb frameNumber = 100; @@ -809,10 +800,11 @@ void Render::getFileProperties(const QDomElement &xml, const QString &clipId, in variance = -1; } } while (variance == -1); + QPixmap pix = QPixmap::fromImage(img); emit replyGetImage(clipId, pix); } else if (frame->get_int("test_audio") == 0) { - QPixmap pixmap = KIcon("audio-x-generic").pixmap(QSize(width, imageHeight)); + QPixmap pixmap = KIcon("audio-x-generic").pixmap(QSize(fullWidth, imageHeight)); emit replyGetImage(clipId, pixmap); filePropertyMap["type"] = "audio"; } @@ -2993,6 +2985,7 @@ void Render::mltChangeTrackState(int track, bool mute, bool blind) if (mute && trackProducer.get_int("hide") < 2 ) { // We mute a track with sound if (track == getLowestNonMutedAudioTrack(tractor)) audioMixingBroken = true; + kDebug()<<"Muting track: "< 1 ) { // We un-mute a previously muted track diff --git a/src/trackview.cpp b/src/trackview.cpp index 7c27b463..be769d6a 100644 --- a/src/trackview.cpp +++ b/src/trackview.cpp @@ -472,7 +472,7 @@ void TrackView::moveCursorPos(int pos) void TrackView::slotChangeZoom(int horizontal, int vertical) { m_ruler->setPixelPerMark(horizontal); - m_scale = (double) FRAME_SIZE / m_ruler->comboScale[horizontal]; + m_scale = (double) m_trackview->getFrameWidth() / m_ruler->comboScale[horizontal]; if (vertical == -1) { // user called zoom @@ -490,7 +490,7 @@ void TrackView::slotChangeZoom(int horizontal, int vertical) int TrackView::fitZoom() const { - int zoom = (int)((duration() + 20 / m_scale) * FRAME_SIZE / m_trackview->width()); + int zoom = (int)((duration() + 20 / m_scale) * m_trackview->getFrameWidth() / m_trackview->width()); int i; for (i = 0; i < 13; i++) if (m_ruler->comboScale[i] > zoom) break; @@ -586,6 +586,7 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked, QDomNod // parse track int position = 0; QMap producerReplacementIds; + int frame_width = m_trackview->getFrameWidth(); QDomNodeList children = xml.childNodes(); for (int nodeindex = 0; nodeindex < children.count(); nodeindex++) { QDomNode n = children.item(nodeindex); @@ -727,7 +728,7 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked, QDomNod 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, strobe, false); + ClipItem *item = new ClipItem(clip, clipinfo, m_doc->fps(), speed, strobe, frame_width, false); if (idString.endsWith("_video")) item->setVideoOnly(true); else if (idString.endsWith("_audio")) item->setAudioOnly(true); m_scene->addItem(item); @@ -1110,6 +1111,24 @@ void TrackView::slotSaveTimelinePreview(const QString path) img.save(path); } +void TrackView::updateProfile() +{ + m_ruler->updateFrameSize(); + m_trackview->updateSceneFrameWidth(); + slotChangeZoom(m_doc->zoom().x(), m_doc->zoom().y()); + slotSetZone(m_doc->zone(), false); +} + +void TrackView::checkTrackHeight() +{ + if (m_trackview->checkTrackHeight()) { + m_doc->clipManager()->clearCache(); + m_ruler->updateFrameSize(); + m_trackview->updateSceneFrameWidth(); + slotChangeZoom(m_doc->zoom().x(), m_doc->zoom().y()); + slotSetZone(m_doc->zone(), false); + } +} #include "trackview.moc" diff --git a/src/trackview.h b/src/trackview.h index 5208fbce..409f3f8c 100644 --- a/src/trackview.h +++ b/src/trackview.h @@ -76,6 +76,9 @@ public: * Parses all tracks to check if there is audio data. */ bool checkProjectAudio() const; + void checkTrackHeight(); + void updateProfile(); + protected: virtual void keyPressEvent(QKeyEvent * event); diff --git a/src/transition.cpp b/src/transition.cpp index e4652d7b..71b66c32 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -40,7 +40,7 @@ Transition::Transition(const ItemInfo &info, int transitiontrack, double fps, QD { setZValue(3); m_info.cropDuration = info.endPos - info.startPos; - setPos(info.startPos.frames(fps), (qreal)(info.track * KdenliveSettings::trackheight() + itemOffset() + 1)); + setPos(info.startPos.frames(fps), (int)(info.track * KdenliveSettings::trackheight() + itemOffset() + 1)); #if QT_VERSION >= 0x040600 m_startAnimation = new QPropertyAnimation(this, "rect"); @@ -170,26 +170,26 @@ void Transition::paint(QPainter *painter, const QRectF exposed = option->exposedRect; painter->setClipRect(exposed); const QRectF br = rect(); + QPen framePen; const QRectF mapped = painter->matrix().mapRect(br); painter->fillRect(exposed, brush()); - //int top = (int)(br.y() + br.height() / 2 - 7); QPointF p1(br.x(), br.y() + br.height() / 2 - 7); painter->setMatrixEnabled(false); - //painter->drawPixmap(painter->matrix().map(p1) + QPointF(5, 0), transitionPixmap()); const QString text = m_name + (m_forceTransitionTrack ? "|>" : QString()); // Draw clip name - QColor frameColor(brush().color().darker()); if (isSelected() || (parentItem() && parentItem()->isSelected())) { - frameColor = QColor(Qt::red); + framePen.setColor(Qt::red); + framePen.setWidthF(2.0); + } + else { + framePen.setColor(brush().color().darker()); } - frameColor.setAlpha(160); const QRectF txtBounding = painter->boundingRect(mapped, Qt::AlignHCenter | Qt::AlignVCenter, ' ' + text + ' '); - //painter->fillRect(txtBounding2, frameColor); - painter->setBrush(frameColor); + painter->setBrush(framePen.color()); painter->setPen(Qt::NoPen); painter->drawRoundedRect(txtBounding, 3, 3); painter->setBrush(QBrush(Qt::NoBrush)); @@ -198,11 +198,9 @@ void Transition::paint(QPainter *painter, painter->drawText(txtBounding, Qt::AlignCenter, text); // Draw frame - QPen pen = painter->pen(); - pen.setColor(frameColor); - painter->setPen(pen); + painter->setPen(framePen); painter->setClipping(false); - painter->drawRect(painter->matrix().mapRect(rect())); + painter->drawRect(mapped.adjusted(1.0, 0, -1.0, 0)); } int Transition::type() const @@ -226,7 +224,7 @@ QVariant Transition::itemChange(GraphicsItemChange change, const QVariant &value int newTrack = newPos.y() / KdenliveSettings::trackheight(); newTrack = qMin(newTrack, projectScene()->tracksCount() - 1); newTrack = qMax(newTrack, 0); - newPos.setY((int)(newTrack * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2)); + newPos.setY((int)(newTrack * KdenliveSettings::trackheight() + itemOffset() + 1)); // Only one clip is moving QRectF sceneShape = rect(); sceneShape.translate(newPos); -- 2.39.2