double click a clip in timeline to edit position & duration, several clip move/resize fixes

svn path=/branches/KDE4/; revision=2289
parent d08f293f
......@@ -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 )
......
/***************************************************************************
* 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 <KDebug>
#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"
/***************************************************************************
* 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 <QDialog>
#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
......@@ -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 <GenTime> 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) {
......
......@@ -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
......@@ -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();
......
<ui version="4.0" >
<class>ClipDurationDialog_UI</class>
<widget class="QDialog" name="ClipDurationDialog_UI" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>226</width>
<height>149</height>
</rect>
</property>
<property name="windowTitle" >
<string>Duration</string>
</property>
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="position_label" >
<property name="text" >
<string>Position</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<layout class="QHBoxLayout" name="horizontalLayout" >
<item>
<widget class="KRestrictedLine" name="clip_position" >
<property name="inputMask" >
<string>99:99:99:99; </string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="KArrowButton" name="position_up" />
</item>
<item>
<widget class="KArrowButton" name="position_down" >
<property name="arrowType" stdset="0" >
<number>2</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="crop_label" >
<property name="text" >
<string>Crop start</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<layout class="QHBoxLayout" name="horizontalLayout_2" >
<item>
<widget class="KRestrictedLine" name="crop_position" >
<property name="inputMask" >
<string>99:99:99:99; </string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2" >
<item>
<widget class="KArrowButton" name="crop_up" />
</item>
<item>
<widget class="KArrowButton" name="crop_down" >
<property name="arrowType" stdset="0" >
<number>2</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="duration_label" >
<property name="text" >
<string>Duration</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<layout class="QHBoxLayout" name="horizontalLayout_3" >
<item>
<widget class="KRestrictedLine" name="clip_duration" >
<property name="inputMask" >
<string>99:99:99:99; </string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3" >
<item>
<widget class="KArrowButton" name="duration_up" />
</item>
<item>
<widget class="KArrowButton" name="duration_down" >
<property name="arrowType" stdset="0" >
<number>2</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2" >
<spacer name="verticalSpacer" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>218</width>
<height>2</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="2" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KArrowButton</class>
<extends>QPushButton</extends>
<header>karrowbutton.h</header>
</customwidget>
<customwidget>
<class>KRestrictedLine</class>
<extends>KLineEdit</extends>
<header>krestrictedline.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ClipDurationDialog_UI</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ClipDurationDialog_UI</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment