From 55355a920ac3e7d86fa9f102301d5766dc43421f Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Sat, 28 Jun 2008 20:35:16 +0000 Subject: [PATCH] double click a clip in timeline to edit position & duration, several clip move/resize fixes svn path=/branches/KDE4/; revision=2289 --- src/CMakeLists.txt | 2 + src/clipdurationdialog.cpp | 115 +++++++++++++++++ src/clipdurationdialog.h | 59 +++++++++ src/clipitem.cpp | 13 +- src/clipitem.h | 5 +- src/customtrackview.cpp | 53 ++++++-- src/widgets/clipdurationdialog_ui.ui | 184 +++++++++++++++++++++++++++ 7 files changed, 413 insertions(+), 18 deletions(-) create mode 100644 src/clipdurationdialog.cpp create mode 100644 src/clipdurationdialog.h create mode 100644 src/widgets/clipdurationdialog_ui.ui diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 70a13dcd..adf9d138 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,6 +50,7 @@ kde4_add_ui_files(kdenlive_UI widgets/clipproperties_ui.ui widgets/markerdialog_ui.ui widgets/keyframedialog_ui.ui + widgets/clipdurationdialog_ui.ui ) set(kdenlive_SRCS @@ -117,6 +118,7 @@ set(kdenlive_SRCS statusbarmessagelabel.cpp regiongrabber.cpp editkeyframecommand.cpp + clipdurationdialog.cpp ) kde4_add_kcfg_files(kdenlive_SRCS GENERATE_MOC kdenlivesettings.kcfgc ) diff --git a/src/clipdurationdialog.cpp b/src/clipdurationdialog.cpp new file mode 100644 index 00000000..5e05647b --- /dev/null +++ b/src/clipdurationdialog.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#include + +#include "clipdurationdialog.h" +#include "kdenlivesettings.h" + +ClipDurationDialog::ClipDurationDialog(AbstractClipItem *clip, Timecode tc, QWidget * parent): QDialog(parent), m_tc(tc), m_clip(clip) { + setFont(KGlobalSettings::toolBarFont()); + m_fps = m_tc.fps(); + m_view.setupUi(this); + + if (clip->type() == TRANSITIONWIDGET) { + m_view.crop_up->hide(); + m_view.crop_down->hide(); + m_view.crop_position->hide(); + m_view.crop_label->hide(); + } + + m_view.clip_position->setText(tc.getTimecode(m_clip->startPos(), m_fps)); + m_view.crop_position->setText(tc.getTimecode(m_clip->cropStart(), m_fps)); + m_view.clip_duration->setText(tc.getTimecode(m_clip->duration(), m_fps)); + connect(m_view.position_up, SIGNAL(clicked()), this, SLOT(slotPosUp())); + connect(m_view.position_down, SIGNAL(clicked()), this, SLOT(slotPosDown())); + connect(m_view.crop_up, SIGNAL(clicked()), this, SLOT(slotCropUp())); + connect(m_view.crop_down, SIGNAL(clicked()), this, SLOT(slotCropDown())); + connect(m_view.duration_up, SIGNAL(clicked()), this, SLOT(slotDurUp())); + connect(m_view.duration_down, SIGNAL(clicked()), this, SLOT(slotDurDown())); + + adjustSize(); +} + +ClipDurationDialog::~ClipDurationDialog() { +} + +void ClipDurationDialog::slotPosUp() { + int position = m_tc.getFrameCount(m_view.clip_position->text(), m_fps); + //if (duration >= m_clip->duration().frames(m_fps)) return; + position ++; + m_view.clip_position->setText(m_tc.getTimecode(GenTime(position, m_fps), m_fps)); +} + +void ClipDurationDialog::slotPosDown() { + int position = m_tc.getFrameCount(m_view.clip_position->text(), m_fps); + //if (duration >= m_clip->duration().frames(m_fps)) return; + position --; + m_view.clip_position->setText(m_tc.getTimecode(GenTime(position, m_fps), m_fps)); +} + +void ClipDurationDialog::slotDurUp() { + int duration = m_tc.getFrameCount(m_view.clip_duration->text(), m_fps); + int crop = m_tc.getFrameCount(m_view.crop_position->text(), m_fps); + if (duration + crop > m_clip->maxDuration().frames(m_fps)) return; + duration ++; + m_view.clip_duration->setText(m_tc.getTimecode(GenTime(duration, m_fps), m_fps)); +} + +void ClipDurationDialog::slotDurDown() { + int duration = m_tc.getFrameCount(m_view.clip_duration->text(), m_fps); + if (duration <= 0) return; + duration --; + m_view.clip_duration->setText(m_tc.getTimecode(GenTime(duration, m_fps), m_fps)); +} + +void ClipDurationDialog::slotCropUp() { + int crop = m_tc.getFrameCount(m_view.crop_position->text(), m_fps); + int duration = m_tc.getFrameCount(m_view.clip_duration->text(), m_fps); + if (duration + crop > m_clip->maxDuration().frames(m_fps)) return; + crop ++; + m_view.crop_position->setText(m_tc.getTimecode(GenTime(crop, m_fps), m_fps)); +} + +void ClipDurationDialog::slotCropDown() { + int crop = m_tc.getFrameCount(m_view.crop_position->text(), m_fps); + if (crop <= 0) return; + crop --; + m_view.crop_position->setText(m_tc.getTimecode(GenTime(crop, m_fps), m_fps)); +} + +GenTime ClipDurationDialog::startPos() const { + int pos = m_tc.getFrameCount(m_view.clip_position->text(), m_fps); + return GenTime(pos, m_fps); +} + +GenTime ClipDurationDialog::cropStart() const { + int pos = m_tc.getFrameCount(m_view.crop_position->text(), m_fps); + return GenTime(pos, m_fps); +} + +GenTime ClipDurationDialog::duration() const { + int pos = m_tc.getFrameCount(m_view.clip_duration->text(), m_fps); + return GenTime(pos, m_fps); +} + +#include "clipdurationdialog.moc" + + diff --git a/src/clipdurationdialog.h b/src/clipdurationdialog.h new file mode 100644 index 00000000..368e1f77 --- /dev/null +++ b/src/clipdurationdialog.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#ifndef CLIPDURATIONDIALOG_H +#define CLIPDURATIONDIALOG_H + +#include + +#include "abstractclipitem.h" +#include "timecode.h" +#include "ui_clipdurationdialog_ui.h" + + +class ClipDurationDialog : public QDialog { + Q_OBJECT + +public: + ClipDurationDialog(AbstractClipItem *clip, Timecode tc, QWidget * parent = 0); + ~ClipDurationDialog(); + GenTime startPos() const; + GenTime cropStart() const; + GenTime duration() const; + +private slots: + void slotPosUp(); + void slotPosDown(); + void slotDurUp(); + void slotDurDown(); + void slotCropUp(); + void slotCropDown(); + +private: + Ui::ClipDurationDialog_UI m_view; + AbstractClipItem *m_clip; + Timecode m_tc; + double m_fps; + +}; + + +#endif + diff --git a/src/clipitem.cpp b/src/clipitem.cpp index c502264b..2cadbe95 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -63,7 +63,7 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, GenTime cropStart, double s setFlags(QGraphicsItem::ItemClipsToShape | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); setAcceptsHoverEvents(true); - connect(this , SIGNAL(prepareAudioThumb(double, QPainterPath, int, int)) , this, SLOT(slotPrepareAudioThumb(double, QPainterPath, int, int))); + connect(this , SIGNAL(prepareAudioThumb(double, QPainterPath, int, int, int)) , this, SLOT(slotPrepareAudioThumb(double, QPainterPath, int, int, int))); setBrush(QColor(141, 166, 215)); if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW) { @@ -373,15 +373,15 @@ void ClipItem::paint(QPainter *painter, } // draw audio thumbnails - if (KdenliveSettings::audiothumbnails() && ((m_clipType == AV && option->exposedRect.bottom() > br.height() / 2) || m_clipType == AUDIO) && audioThumbReady) { + if (KdenliveSettings::audiothumbnails() && ((m_clipType == AV && option->exposedRect.bottom() > (br.y() + br.height() / 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))); - int channels = 2; + int channels = baseClip()->getProperty("channels").toInt(); if (scale != framePixelWidth) audioThumbCachePic.clear(); - emit prepareAudioThumb(scale, path, startpixel, endpixel + 200);//200 more for less missing parts before repaint after scrolling + 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) { if (audioThumbCachePic.contains(startCache) && !audioThumbCachePic[startCache].isNull()) @@ -591,11 +591,10 @@ QList ClipItem::snapMarkers() const { return snaps; } -void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, QPainterPath path, int startpixel, int endpixel) { - int channels = 2; +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; //if ( (!audioThumbWasDrawn || framePixelWidth!=pixelForOneFrame ) && !baseClip()->audioFrameChache.isEmpty()){ for (int startCache = startpixel - startpixel % 100;startCache + 100 < endpixel ;startCache += 100) { diff --git a/src/clipitem.h b/src/clipitem.h index 190c669b..892ab8de 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -140,13 +140,12 @@ private slots: void slotGetStartThumb(); void slotGetEndThumb(); void slotGotAudioData(); - void slotPrepareAudioThumb(double, QPainterPath, int, int); + void slotPrepareAudioThumb(double pixelForOneFrame, QPainterPath path, int startpixel, int endpixel, int channels); void animate(qreal value); signals: void getThumb(int, int); - void prepareAudioThumb(double, QPainterPath, int, int); - + void prepareAudioThumb(double, QPainterPath, int, int, int); }; #endif diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 574c1cda..da04d2fe 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -57,6 +57,7 @@ #include "markerdialog.h" #include "mainwindow.h" #include "ui_keyframedialog_ui.h" +#include "clipdurationdialog.h" //TODO: @@ -589,6 +590,42 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) { m_commandStack->push(command); updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect()); } + } else { + ClipDurationDialog d(m_dragItem, m_document->timecode(), this); + if (d.exec() == QDialog::Accepted) { + if (d.startPos() != m_dragItem->startPos()) { + if (m_dragItem->type() == AVWIDGET) { + ItemInfo startInfo; + startInfo.startPos = m_dragItem->startPos(); + startInfo.endPos = m_dragItem->endPos(); + startInfo.track = m_dragItem->track(); + ItemInfo endInfo; + endInfo.startPos = d.startPos(); + endInfo.endPos = m_dragItem->endPos() + (endInfo.startPos - startInfo.startPos); + endInfo.track = m_dragItem->track(); + MoveClipCommand *command = new MoveClipCommand(this, startInfo, endInfo, true); + m_commandStack->push(command); + } else { + //TODO: move transition + } + } + if (d.duration() != m_dragItem->duration()) { + if (m_dragItem->type() == AVWIDGET) { + ItemInfo startInfo; + startInfo.startPos = m_dragItem->startPos(); + startInfo.endPos = m_dragItem->endPos(); + startInfo.track = m_dragItem->track(); + ItemInfo endInfo; + endInfo.startPos = startInfo.startPos; + endInfo.endPos = endInfo.startPos + d.duration(); + endInfo.track = m_dragItem->track(); + ResizeClipCommand *command = new ResizeClipCommand(this, startInfo, endInfo, true); + m_commandStack->push(command); + } else { + //TODO: resize transition + } + } + } } } @@ -1011,7 +1048,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { // undo last move and emit error message MoveClipCommand *command = new MoveClipCommand(this, info, m_dragItemInfo, true); m_commandStack->push(command); - emit displayMessage(i18n("Cannot move clip to requested position"), ErrorMessage); + emit displayMessage(i18n("Cannot move clip to position %1seconds", QString::number(m_dragItemInfo.startPos.seconds(), 'g', 2)), ErrorMessage); } } if (m_dragItem->type() == TRANSITIONWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) { @@ -1233,7 +1270,7 @@ Transition *CustomTrackView::getTransitionItemAt(GenTime pos, int track) { void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end) { ClipItem *item = getClipItemAt((int) start.startPos.frames(m_document->fps()) + 1, start.track); if (!item) { - emit displayMessage(i18n("Cannot move clip at time: %1s on track %2", start.startPos.seconds(), start.track), ErrorMessage); + emit displayMessage(i18n("Cannot move clip at time: %1s on track %2", QString::number(start.startPos.seconds(), 'g', 2), start.track), ErrorMessage); kDebug() << "----------------  ERROR, CANNOT find clip to move at.. ";// << startPos.x() * m_scale * FRAME_SIZE + 1 << ", " << startPos.y() * m_tracksHeight + m_tracksHeight / 2; return; } @@ -1244,7 +1281,7 @@ void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end) { item->moveTo((int) end.startPos.frames(m_document->fps()), m_scale, (int)((end.track - start.track) * m_tracksHeight), end.track); } else { // undo last move and emit error message - emit displayMessage(i18n("Cannot move clip to requested position"), ErrorMessage); + emit displayMessage(i18n("Cannot move clip to position %1seconds", QString::number(end.startPos.seconds(), 'g', 2)), ErrorMessage); } } @@ -1274,11 +1311,11 @@ void CustomTrackView::moveTransition(const ItemInfo start, const ItemInfo end) { } void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end) { - int offset; + int offset = 0; bool resizeClipStart = true; if (start.startPos == end.startPos) resizeClipStart = false; - if (resizeClipStart) offset = 1; - else offset = -1; + /*if (resizeClipStart) offset = 1; + else offset = -1;*/ ClipItem *item = getClipItemAt((int)(start.startPos.frames(m_document->fps()) + offset), start.track); if (!item) { emit displayMessage(i18n("Cannot move clip at time: %1s on track %2", start.startPos.seconds(), start.track), ErrorMessage); @@ -1290,8 +1327,8 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end) { item->resizeStart((int) end.startPos.frames(m_document->fps()), m_scale); updateClipFade(item); } else { - m_document->renderer()->mltResizeClipEnd(m_tracksList.count() - item->track(), item->startPos(), item->cropStart(), item->cropStart() + end.startPos - item->startPos()); - item->resizeEnd((int) end.startPos.frames(m_document->fps()), m_scale); + m_document->renderer()->mltResizeClipEnd(m_tracksList.count() - item->track(), item->startPos(), item->cropStart(), item->cropStart() + end.endPos - item->startPos()); + item->resizeEnd((int) end.endPos.frames(m_document->fps()), m_scale); updateClipFade(item, true); } m_document->renderer()->doRefresh(); diff --git a/src/widgets/clipdurationdialog_ui.ui b/src/widgets/clipdurationdialog_ui.ui new file mode 100644 index 00000000..577e832f --- /dev/null +++ b/src/widgets/clipdurationdialog_ui.ui @@ -0,0 +1,184 @@ + + ClipDurationDialog_UI + + + + 0 + 0 + 226 + 149 + + + + Duration + + + + + + Position + + + + + + + + + 99:99:99:99; + + + + + + + + + + + + 2 + + + + + + + + + + + Crop start + + + + + + + + + 99:99:99:99; + + + + + + + + + + + + 2 + + + + + + + + + + + Duration + + + + + + + + + 99:99:99:99; + + + + + + + + + + + + 2 + + + + + + + + + + + Qt::Vertical + + + + 218 + 2 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + KArrowButton + QPushButton +
karrowbutton.h
+
+ + KRestrictedLine + KLineEdit +
krestrictedline.h
+
+
+ + + + buttonBox + accepted() + ClipDurationDialog_UI + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ClipDurationDialog_UI + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
-- 2.39.2