From 95265b50de041c51b5111bc397709fe3ce83b1fc Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Mon, 7 Jul 2008 20:48:50 +0000 Subject: [PATCH] * Guides improvements and fixes * Timeline ruler cursor fixes svn path=/branches/KDE4/; revision=2294 --- src/customruler.cpp | 7 +++- src/customtrackview.cpp | 66 ++++++++++++++++++++++++++----- src/customtrackview.h | 5 +++ src/definitions.h | 28 ++++++++++++++ src/editguidecommand.cpp | 1 - src/guide.cpp | 40 ++++++++++++++++++- src/guide.h | 7 +++- src/markerdialog.cpp | 84 +++++++++++++++++++++------------------- 8 files changed, 183 insertions(+), 55 deletions(-) diff --git a/src/customruler.cpp b/src/customruler.cpp index 60e05fa1..461a5803 100644 --- a/src/customruler.cpp +++ b/src/customruler.cpp @@ -91,6 +91,8 @@ CustomRuler::CustomRuler(Timecode tc, CustomTrackView *parent) connect(addGuide, SIGNAL(triggered()), m_view, SLOT(slotAddGuide())); QAction *delGuide = m_contextMenu->addAction(KIcon("document-new"), i18n("Delete Guide")); connect(delGuide, SIGNAL(triggered()), m_view, SLOT(slotDeleteGuide())); + QAction *editGuide = m_contextMenu->addAction(KIcon("document-new"), i18n("Edit Guide")); + connect(editGuide, SIGNAL(triggered()), m_view, SLOT(slotEditGuide())); } // virtual @@ -114,6 +116,7 @@ void CustomRuler::mousePressEvent(QMouseEvent * event) { // virtual void CustomRuler::mouseMoveEvent(QMouseEvent * event) { int pos = (int)((event->x() + offset()) / pixelPerMark() / FRAME_SIZE); + if (pos < 0) pos = 0; if (m_moveCursor == RULER_CURSOR) { m_view->setCursorPos(pos); return; @@ -216,7 +219,7 @@ void CustomRuler::paintEvent(QPaintEvent *e) { p.fillRect(QRect(zoneStart - offset(), e->rect().y() + e->rect().height() / 2, zoneEnd - zoneStart, e->rect().height() / 2), QBrush(QColor(133, 255, 143))); - int value = m_view->cursorPos() - offset() + 4; + int value = m_view->cursorPos() - offset(); int minval = minimum(); int maxval = maximum() + offset() - endOffset(); @@ -311,7 +314,7 @@ void CustomRuler::paintEvent(QPaintEvent *e) { } // draw pointer - if (showPointer() && value > 0) { + if (showPointer() && value >= 0) { QPolygon pa(3); pa.setPoints(3, value - 6, 7, value + 6, 7, value, 16); p.setBrush(QBrush(Qt::yellow)); diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 04eaba36..e343dfc9 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -91,6 +91,8 @@ CustomTrackView::CustomTrackView(KdenliveDoc *doc, QGraphicsScene * projectscene KIcon razorIcon("edit-cut"); m_razorCursor = QCursor(razorIcon.pixmap(22, 22)); + verticalScrollBar()->setTracking(true); + connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(slotRefreshGuides())); } CustomTrackView::~CustomTrackView() { @@ -590,7 +592,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) { m_commandStack->push(command); updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); } - } else { + } else if (m_dragItem) { ClipDurationDialog d(m_dragItem, m_document->timecode(), this); if (d.exec() == QDialog::Accepted) { if (d.startPos() != m_dragItem->startPos()) { @@ -626,6 +628,12 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) { } } } + } else { + QList collisionList = items(event->pos()); + if (collisionList.count() == 1 && collisionList.at(0)->type() == GUIDEITEM) { + Guide *editGuide = (Guide *) collisionList.at(0); + if (editGuide) slotEditGuide(editGuide->info()); + } } } @@ -999,6 +1007,7 @@ int CustomTrackView::cursorPos() { } void CustomTrackView::moveCursorPos(int delta) { + if (m_cursorPos + delta < 0) delta = 0 - m_cursorPos; emit cursorMoved((int)(m_cursorPos * m_scale), (int)((m_cursorPos + delta) * m_scale)); m_cursorPos += delta; m_cursorLine->setPos(m_cursorPos * m_scale, 0); @@ -1030,7 +1039,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { m_dragGuide->setFlag(QGraphicsItem::ItemIsMovable, false); EditGuideCommand *command = new EditGuideCommand(this, m_dragGuide->position(), m_dragGuide->label(), GenTime(m_dragGuide->pos().x() / m_scale, m_document->fps()), m_dragGuide->label(), false); m_commandStack->push(command); - m_dragGuide->update(GenTime(m_dragGuide->pos().x() / m_scale, m_document->fps())); + m_dragGuide->updateGuide(GenTime(m_dragGuide->pos().x() / m_scale, m_document->fps())); m_dragGuide = NULL; m_dragItem = NULL; return; @@ -1579,11 +1588,9 @@ void CustomTrackView::editGuide(const GenTime oldPos, const GenTime pos, const Q if (oldPos > GenTime() && pos > GenTime()) { // move guide for (int i = 0; i < m_guides.count(); i++) { - kDebug() << "// LOOKING FOR GUIDE (" << i << "): " << m_guides.at(i)->position().frames(25) << ", LOOK: " << oldPos.frames(25) << "x" << pos.frames(25); if (m_guides.at(i)->position() == oldPos) { Guide *item = m_guides.at(i); - item->update(pos, comment); - item->updatePosition(m_scale); + item->updateGuide(pos, comment); break; } } @@ -1617,12 +1624,37 @@ bool CustomTrackView::addGuide(const GenTime pos, const QString &comment) { } void CustomTrackView::slotAddGuide() { - if (addGuide(GenTime(m_cursorPos, m_document->fps()), i18n("guide"))) { - EditGuideCommand *command = new EditGuideCommand(this, GenTime(), QString(), GenTime(m_cursorPos, m_document->fps()), i18n("guide"), false); + CommentedTime marker(GenTime(m_cursorPos, m_document->fps()), i18n("Guide")); + MarkerDialog d(NULL, marker, m_document->timecode(), this); + if (d.exec() != QDialog::Accepted) return; + if (addGuide(d.newMarker().time(), d.newMarker().comment())) { + EditGuideCommand *command = new EditGuideCommand(this, GenTime(), QString(), d.newMarker().time(), d.newMarker().comment(), false); + m_commandStack->push(command); + } +} + +void CustomTrackView::slotEditGuide() { + GenTime pos = GenTime(m_cursorPos, m_document->fps()); + bool found = false; + for (int i = 0; i < m_guides.count(); i++) { + if (m_guides.at(i)->position() == pos) { + slotEditGuide(m_guides.at(i)->info()); + found = true; + break; + } + } + if (!found) emit displayMessage(i18n("No guide at cursor time"), ErrorMessage); +} + +void CustomTrackView::slotEditGuide(CommentedTime guide) { + MarkerDialog d(NULL, guide, m_document->timecode(), this); + if (d.exec() == QDialog::Accepted) { + EditGuideCommand *command = new EditGuideCommand(this, guide.time(), guide.comment(), d.newMarker().time(), d.newMarker().comment(), true); m_commandStack->push(command); } } + void CustomTrackView::slotDeleteGuide() { GenTime pos = GenTime(m_cursorPos, m_document->fps()); bool found = false; @@ -1674,6 +1706,15 @@ void CustomTrackView::setScale(double scaleFactor) { verticalScrollBar()->setValue(vert); } +void CustomTrackView::slotRefreshGuides() { + if (KdenliveSettings::showmarkers()) { + kDebug() << "// refresh GUIDES"; + for (int i = 0; i < m_guides.count(); i++) { + m_guides.at(i)->update(); + } + } +} + void CustomTrackView::drawBackground(QPainter * painter, const QRectF & rect) { QRect rectInView = viewport()->rect(); rectInView.moveTo(horizontalScrollBar()->value(), verticalScrollBar()->value()); @@ -1740,19 +1781,26 @@ bool CustomTrackView::findNextString(const QString &text) { void CustomTrackView::initSearchStrings() { m_searchPoints.clear(); - QList itemList = items(); for (int i = 0; i < itemList.count(); i++) { + // parse all clip names if (itemList.at(i)->type() == AVWIDGET) { ClipItem *item = static_cast (itemList.at(i)); GenTime start = item->startPos(); CommentedTime t(start, item->clipName()); m_searchPoints.append(t); - + // add all clip markers QList < CommentedTime > markers = item->commentedSnapMarkers(); m_searchPoints += markers; } } + + // add guides + for (int i = 0; i < m_guides.count(); i++) { + m_searchPoints.append(m_guides.at(i)->info()); + } + + qSort(m_searchPoints); } void CustomTrackView::clearSearchStrings() { diff --git a/src/customtrackview.h b/src/customtrackview.h index 2b85e14c..50da76f6 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -109,6 +109,8 @@ public slots: void slotAddClipMarker(int id, GenTime t, QString c); bool addGuide(const GenTime pos, const QString &comment); void slotAddGuide(); + void slotEditGuide(CommentedTime guide); + void slotEditGuide(); void slotDeleteGuide(); void editGuide(const GenTime oldPos, const GenTime pos, const QString &comment); @@ -170,6 +172,9 @@ private: int getPreviousVideoTrack(int track); void updateClipFade(ClipItem * item, bool updateFadeOut = false); +private slots: + void slotRefreshGuides(); + signals: void cursorMoved(int, int); void zoomIn(); diff --git a/src/definitions.h b/src/definitions.h index 1279a542..d0aa354c 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -93,8 +93,36 @@ public: void setComment(QString comm) { c = comm; } + + /* Implementation of > operator; Works identically as with basic types. */ + bool operator>(CommentedTime op) const { + return t > op.time(); + } + /* Implementation of < operator; Works identically as with basic types. */ + bool operator<(CommentedTime op) const { + return t < op.time(); + } + /* Implementation of >= operator; Works identically as with basic types. */ + bool operator>=(CommentedTime op) const { + return t >= op.time(); + } + /* Implementation of <= operator; Works identically as with basic types. */ + bool operator<=(CommentedTime op) const { + return t <= op.time(); + } + /* Implementation of == operator; Works identically as with basic types. */ + bool operator==(CommentedTime op) const { + return t == op.time(); + } + /* Implementation of != operator; Works identically as with basic types. */ + bool operator!=(CommentedTime op) const { + return t != op.time(); + } + private: GenTime t; QString c; + + }; #endif diff --git a/src/editguidecommand.cpp b/src/editguidecommand.cpp index e1687d38..844b860c 100644 --- a/src/editguidecommand.cpp +++ b/src/editguidecommand.cpp @@ -24,7 +24,6 @@ EditGuideCommand::EditGuideCommand(CustomTrackView *view, const GenTime oldPos, else if (m_oldPos == m_pos) setText(i18n("Edit guide")); else if (m_pos <= GenTime()) setText(i18n("Delete guide")); else setText(i18n("Move guide")); - kDebug() << "/// CREATE GUIDE COMMAND, TIMES: " << m_oldPos.frames(25) << "x" << m_pos.frames(25); } diff --git a/src/guide.cpp b/src/guide.cpp index 8bd55a89..55cf462c 100644 --- a/src/guide.cpp +++ b/src/guide.cpp @@ -20,11 +20,13 @@ #include #include +#include #include #include "guide.h" #include "customtrackview.h" +#include "kdenlivesettings.h" Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double scale, double fps, double height) : QGraphicsLineItem(), m_view(view), m_position(pos), m_label(label), m_scale(scale), m_fps(fps) { @@ -35,12 +37,15 @@ Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double scale, do setPen(QPen(QBrush(QColor(0, 0, 200, 180)), 2)); setZValue(999); setAcceptsHoverEvents(true); + const QFontMetrics metric = m_view->fontMetrics(); + m_width = metric.width(" " + m_label + " ") + 2; + prepareGeometryChange(); } void Guide::updatePosition(double scale) { - setPos(m_position.frames(m_fps) * scale, 0); m_scale = scale; + setPos(m_position.frames(m_fps) * m_scale, 0); } QString Guide::label() const { @@ -51,11 +56,19 @@ GenTime Guide::position() const { return m_position; } -void Guide::update(const GenTime newPos, const QString &comment) { +CommentedTime Guide::info() const { + return CommentedTime(m_position, m_label); +} + +void Guide::updateGuide(const GenTime newPos, const QString &comment) { m_position = newPos; + setPos(m_position.frames(m_fps) * m_scale, 0); if (comment != QString()) { m_label = comment; setToolTip(m_label); + const QFontMetrics metric = m_view->fontMetrics(); + m_width = metric.width(" " + m_label + " ") + 2; + prepareGeometryChange(); } } @@ -86,3 +99,26 @@ QVariant Guide::itemChange(GraphicsItemChange change, const QVariant &value) { return QGraphicsItem::itemChange(change, value); } +// virtual +QRectF Guide::boundingRect() const { + if (KdenliveSettings::showmarkers()) { + QRectF rect = QGraphicsLineItem::boundingRect(); + rect.setWidth(m_width); + return rect; + } else return QGraphicsLineItem::boundingRect(); +} + +// virtual +void Guide::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) { + QGraphicsLineItem::paint(painter, option, w); + if (KdenliveSettings::showmarkers()) { + QRectF br = boundingRect(); + QRectF txtBounding = painter->boundingRect(br.x(), br.y() + 10 + m_view->verticalScrollBar()->value(), m_width, 50, Qt::AlignLeft | Qt::AlignTop, " " + m_label + " "); + QPainterPath path; + path.addRoundedRect(txtBounding, 3, 3); + painter->fillPath(path, QBrush(pen().color())); + painter->setPen(Qt::white); + painter->drawText(txtBounding, Qt::AlignCenter, m_label); + } +} + diff --git a/src/guide.h b/src/guide.h index 4d57d77a..e76b6c67 100644 --- a/src/guide.h +++ b/src/guide.h @@ -23,6 +23,7 @@ #include #include "gentime.h" +#include "definitions.h" #define GUIDEITEM 8000 @@ -34,9 +35,12 @@ public: Guide(CustomTrackView *view, GenTime pos, QString label, double scale, double fps, double height); void updatePosition(double scale); GenTime position() const; - void update(const GenTime newPos, const QString &comment = QString()); + void updateGuide(const GenTime newPos, const QString &comment = QString()); QString label() const; + CommentedTime info() const; virtual int type() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w); + virtual QRectF boundingRect() const; protected: virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *); @@ -49,6 +53,7 @@ private: double m_scale; double m_fps; CustomTrackView *m_view; + int m_width; }; #endif diff --git a/src/markerdialog.cpp b/src/markerdialog.cpp index e036720b..143fa737 100644 --- a/src/markerdialog.cpp +++ b/src/markerdialog.cpp @@ -24,26 +24,54 @@ #include "kthumb.h" #include "kdenlivesettings.h" -MarkerDialog::MarkerDialog(DocClipBase *clip, CommentedTime t, Timecode tc, QWidget * parent): QDialog(parent), m_tc(tc), m_clip(clip), m_marker(t) { +MarkerDialog::MarkerDialog(DocClipBase *clip, CommentedTime t, Timecode tc, QWidget * parent): QDialog(parent), m_tc(tc), m_clip(clip), m_marker(t), m_producer(NULL), m_profile(NULL) { setFont(KGlobalSettings::toolBarFont()); m_fps = m_tc.fps(); m_view.setupUi(this); m_previewTimer = new QTimer(this); - m_previewTimer->setInterval(500); - connect(m_previewTimer, SIGNAL(timeout()), this, SLOT(slotUpdateThumb())); - - m_profile = new Mlt::Profile((char*) KdenliveSettings::current_profile().data()); - m_dar = m_profile->dar(); - QDomDocument doc; - QDomElement westley = doc.createElement("westley"); - QDomElement play = doc.createElement("playlist"); - doc.appendChild(westley); - westley.appendChild(play); - play.appendChild(doc.importNode(clip->toXML(), true)); - //char *tmp = doc.toString().toUtf8().data(); - m_producer = new Mlt::Producer(*m_profile, "westley-xml", doc.toString().toUtf8().data()); - //delete[] tmp; + + if (m_clip != NULL) { + m_previewTimer->setInterval(500); + connect(m_previewTimer, SIGNAL(timeout()), this, SLOT(slotUpdateThumb())); + m_profile = new Mlt::Profile((char*) KdenliveSettings::current_profile().data()); + m_dar = m_profile->dar(); + QDomDocument doc; + QDomElement westley = doc.createElement("westley"); + QDomElement play = doc.createElement("playlist"); + doc.appendChild(westley); + westley.appendChild(play); + play.appendChild(doc.importNode(clip->toXML(), true)); + //char *tmp = doc.toString().toUtf8().data(); + m_producer = new Mlt::Producer(*m_profile, "westley-xml", doc.toString().toUtf8().data()); + //delete[] tmp; + + QPixmap p((int)(100 * m_dar), 100); + QString colour = clip->getProperty("colour"); + switch (m_clip->clipType()) { + case VIDEO: + case AV: + case SLIDESHOW: + case PLAYLIST: + 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); + break; + case COLOR: + colour = colour.replace(0, 2, "#"); + p.fill(QColor(colour.left(7))); + break; + default: + p.fill(Qt::black); + } + if (!p.isNull()) { + m_view.clip_thumb->setFixedWidth(p.width()); + m_view.clip_thumb->setFixedHeight(p.height()); + m_view.clip_thumb->setPixmap(p); + } + connect(m_view.marker_position, SIGNAL(textChanged(const QString &)), this, SIGNAL(updateThumb())); + } else m_view.clip_thumb->setHidden(true); m_view.marker_position->setText(tc.getTimecode(t.time(), m_fps)); m_view.marker_comment->setText(t.comment()); @@ -52,31 +80,7 @@ MarkerDialog::MarkerDialog(DocClipBase *clip, CommentedTime t, Timecode tc, QWid m_view.marker_comment->selectAll(); m_view.marker_comment->setFocus(); - QPixmap p((int)(100 * m_dar), 100); - QString colour = clip->getProperty("colour"); - switch (m_clip->clipType()) { - case VIDEO: - case AV: - case SLIDESHOW: - case PLAYLIST: - 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); - break; - case COLOR: - colour = colour.replace(0, 2, "#"); - p.fill(QColor(colour.left(7))); - break; - default: - p.fill(Qt::black); - } - if (!p.isNull()) { - m_view.clip_thumb->setFixedWidth(p.width()); - m_view.clip_thumb->setFixedHeight(p.height()); - m_view.clip_thumb->setPixmap(p); - } - connect(m_view.marker_position, SIGNAL(textChanged(const QString &)), this, SIGNAL(updateThumb())); + adjustSize(); } -- 2.39.2