#include "trackdialog.h"
#include "tracksconfigdialog.h"
#include "configtrackscommand.h"
+#include "rebuildgroupcommand.h"
+#include "razorgroupcommand.h"
#include <KDebug>
#include <KLocale>
connect(&m_thumbsTimer, SIGNAL(timeout()), this, SLOT(slotFetchNextThumbs()));
m_thumbsTimer.setInterval(500);
m_thumbsTimer.setSingleShot(true);
+
+ connect(&m_audioMonitorTimer, SIGNAL(timeout()), this, SIGNAL(documentModified()));
+ m_audioMonitorTimer.setInterval(2000);
+ m_audioMonitorTimer.setSingleShot(true);
}
CustomTrackView::~CustomTrackView()
void CustomTrackView::setDocumentModified()
{
m_document->setModified(true);
+ m_audioMonitorTimer.start();
}
void CustomTrackView::setContextMenu(QMenu *timeline, QMenu *clip, QMenu *transition, QActionGroup *clipTypeGroup, QMenu *markermenu)
emit mousePosition(mappedXPos);
if (event->buttons() & Qt::MidButton) return;
- if (dragMode() == QGraphicsView::RubberBandDrag || (event->modifiers() == Qt::ControlModifier && m_tool != SPACERTOOL)) {
+ if (dragMode() == QGraphicsView::RubberBandDrag || (event->modifiers() == Qt::ControlModifier && m_tool != SPACERTOOL && m_operationMode != RESIZESTART && m_operationMode != RESIZEEND)) {
event->setAccepted(true);
m_moveOpMode = NONE;
QGraphicsView::mouseMoveEvent(event);
} else if (viewport()->width() - pos < 10) {
m_scrollOffset = 30;
m_scrollTimer.start();
- } else if (m_scrollTimer.isActive()) m_scrollTimer.stop();
-
+ } else if (m_scrollTimer.isActive()) {
+ m_scrollTimer.stop();
+ }
} else if (m_operationMode == RESIZESTART && move) {
m_document->renderer()->pause();
- m_dragItem->resizeStart((int)(snappedPos));
+ if (event->modifiers() != Qt::ControlModifier && m_dragItem->type() == AVWIDGET && m_dragItem->parentItem() && m_dragItem->parentItem() != m_selectionGroup) {
+ AbstractGroupItem *parent = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
+ if (parent)
+ parent->resizeStart((int)(snappedPos) - m_dragItemInfo.startPos.frames(m_document->fps()));
+ } else {
+ m_dragItem->resizeStart((int)(snappedPos));
+ }
} else if (m_operationMode == RESIZEEND && move) {
m_document->renderer()->pause();
- m_dragItem->resizeEnd((int)(snappedPos));
+ if (event->modifiers() != Qt::ControlModifier && m_dragItem->type() == AVWIDGET && m_dragItem->parentItem() && m_dragItem->parentItem() != m_selectionGroup) {
+ AbstractGroupItem *parent = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
+ if (parent)
+ parent->resizeEnd((int)(snappedPos) - m_dragItemInfo.endPos.frames(m_document->fps()));
+ } else {
+ m_dragItem->resizeEnd((int)(snappedPos));
+ }
} else if (m_operationMode == FADEIN && move) {
((ClipItem*) m_dragItem)->setFadeIn((int)(mappedXPos - m_dragItem->startPos().frames(m_document->fps())));
} else if (m_operationMode == FADEOUT && move) {
for (int i = 0; i < children.count(); i++) {
if (children.at(i)->type() == GROUPWIDGET) {
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
- for (int j = 0; j < subchildren.count(); j++) {
+ for (int j = 0; j < subchildren.count(); j++)
collidingItems.removeAll(subchildren.at(j));
- }
}
collidingItems.removeAll(children.at(i));
}
for (int i = 0; i < children.count(); i++) {
if (children.at(i)->type() == GROUPWIDGET) {
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
- for (int j = 0; j < subchildren.count(); j++) {
+ for (int j = 0; j < subchildren.count(); j++)
collidingItems.removeAll(subchildren.at(j));
- }
}
collidingItems.removeAll(children.at(i));
}
for (int i = 0; i < children.count(); i++) {
if (children.at(i)->type() == GROUPWIDGET) {
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
- for (int j = 0; j < subchildren.count(); j++) {
+ for (int j = 0; j < subchildren.count(); j++)
collidingItems.removeAll(subchildren.at(j));
- }
}
collidingItems.removeAll(children.at(i));
}
for (int i = 0; i < children.count(); i++) {
if (children.at(i)->type() == GROUPWIDGET) {
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
- for (int j = 0; j < subchildren.count(); j++) {
+ for (int j = 0; j < subchildren.count(); j++)
collidingItems.removeAll(subchildren.at(j));
- }
}
collidingItems.removeAll(children.at(i));
}
}
m_moveOpMode = opMode;
setTipAnimation(clip, opMode, size);
- if (opMode == MOVE)
+ if (opMode == MOVE) {
setCursor(Qt::OpenHandCursor);
- else if (opMode == RESIZESTART)
+ if (item->type() == AVWIDGET) {
+ ClipItem *ci = static_cast <ClipItem *>(item);
+ QString message = ci->clipName() + i18n(":");
+ message.append(i18n(" Position:") + m_document->timecode().getDisplayTimecode(ci->info().startPos, KdenliveSettings::frametimecode()));
+ message.append(i18n(" Duration:") + m_document->timecode().getDisplayTimecode(ci->cropDuration(), KdenliveSettings::frametimecode()));
+ if (clip->parentItem() && clip->parentItem()->type() == GROUPWIDGET) {
+ AbstractGroupItem *parent = static_cast <AbstractGroupItem *>(clip->parentItem());
+ if (clip->parentItem() == m_selectionGroup)
+ message.append(i18n(" Selection duration:"));
+ else
+ message.append(i18n(" Group duration:"));
+ message.append(m_document->timecode().getDisplayTimecode(parent->duration(), KdenliveSettings::frametimecode()));
+ if (parent->parentItem() && parent->parentItem()->type() == GROUPWIDGET) {
+ AbstractGroupItem *parent2 = static_cast <AbstractGroupItem *>(parent->parentItem());
+ message.append(i18n(" Selection duration:") + m_document->timecode().getDisplayTimecode(parent2->duration(), KdenliveSettings::frametimecode()));
+ }
+ }
+ emit displayMessage(message, InformationMessage);
+ }
+ } else if (opMode == RESIZESTART) {
setCursor(KCursor("left_side", Qt::SizeHorCursor));
- else if (opMode == RESIZEEND)
+ if (item->type() == AVWIDGET && item->parentItem() && item->parentItem() != m_selectionGroup)
+ emit displayMessage(i18n("Use Ctrl to resize only current item, otherwise all items in this group will be resized at once."), InformationMessage);
+ } else if (opMode == RESIZEEND) {
setCursor(KCursor("right_side", Qt::SizeHorCursor));
- else if (opMode == FADEIN || opMode == FADEOUT) {
+ if (item->type() == AVWIDGET && item->parentItem() && item->parentItem() != m_selectionGroup)
+ emit displayMessage(i18n("Use Ctrl to resize only current item, otherwise all items in this group will be resized at once."), InformationMessage);
+ } else if (opMode == FADEIN || opMode == FADEOUT) {
setCursor(Qt::PointingHandCursor);
emit displayMessage(i18n("Drag to add or resize a fade effect."), InformationMessage);
} else if (opMode == TRANSITIONSTART || opMode == TRANSITIONEND) {
}
#if QT_VERSION >= 0x040600
// Add shadow to dragged item, currently disabled because of painting artifacts
- //TODO: re-enable when fixed
+ //TODO: re-enable when fixed
/*QGraphicsDropShadowEffect *eff = new QGraphicsDropShadowEffect();
eff->setBlurRadius(5);
eff->setOffset(3, 3);
// Razor tool
if (m_tool == RAZORTOOL && m_dragItem) {
+ GenTime cutPos = GenTime((int)(mapToScene(event->pos()).x()), m_document->fps());
if (m_dragItem->type() == TRANSITIONWIDGET) {
emit displayMessage(i18n("Cannot cut a transition"), ErrorMessage);
- event->accept();
- m_dragItem = NULL;
- return;
- } else if (m_dragItem->parentItem() && m_dragItem->parentItem() != m_selectionGroup) {
- emit displayMessage(i18n("Cannot cut a clip in a group"), ErrorMessage);
- event->accept();
- m_dragItem = NULL;
- return;
+ } else {
+ m_document->renderer()->pause();
+ if (m_dragItem->parentItem() && m_dragItem->parentItem() != m_selectionGroup) {
+ razorGroup((AbstractGroupItem *)m_dragItem->parentItem(), cutPos);
+ } else {
+ AbstractClipItem *clip = static_cast <AbstractClipItem *>(m_dragItem);
+ RazorClipCommand* command = new RazorClipCommand(this, clip->info(), cutPos);
+ m_commandStack->push(command);
+ }
+ setDocumentModified();
}
- AbstractClipItem *clip = static_cast <AbstractClipItem *>(m_dragItem);
- RazorClipCommand* command = new RazorClipCommand(this, clip->info(), GenTime((int)(mapToScene(event->pos()).x()), m_document->fps()));
- m_document->renderer()->pause();
- m_commandStack->push(command);
- setDocumentModified();
m_dragItem = NULL;
event->accept();
return;
}
bool itemSelected = false;
- if (m_dragItem->isSelected()) itemSelected = true;
- else if (m_dragItem->parentItem() && m_dragItem->parentItem()->isSelected()) itemSelected = true;
- else if (dragGroup && dragGroup->isSelected()) itemSelected = true;
+ if (m_dragItem->isSelected())
+ itemSelected = true;
+ else if (m_dragItem->parentItem() && m_dragItem->parentItem()->isSelected())
+ itemSelected = true;
+ else if (dragGroup && dragGroup->isSelected())
+ itemSelected = true;
if (event->modifiers() == Qt::ControlModifier || itemSelected == false) {
if (event->modifiers() != Qt::ControlModifier) {
dragGroup = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
}
bool selected = !m_dragItem->isSelected();
- if (dragGroup) dragGroup->setSelected(selected);
- else m_dragItem->setSelected(selected);
+ if (dragGroup)
+ dragGroup->setSelected(selected);
+ else
+ m_dragItem->setSelected(selected);
groupSelectedItems();
ClipItem *clip = static_cast <ClipItem *>(m_dragItem);
if (m_dragItem && m_dragItem->type() == AVWIDGET && !m_dragItem->isItemLocked()) {
ClipItem *selected = static_cast <ClipItem*>(m_dragItem);
emit clipItemSelected(selected);
- } else emit clipItemSelected(NULL);
+ } else {
+ emit clipItemSelected(NULL);
+ }
}
// If clicked item is selected, allow move
// Update snap points
if (m_selectionGroup == NULL) {
- if (m_operationMode == RESIZEEND || m_operationMode == RESIZESTART) updateSnapPoints(NULL);
- else updateSnapPoints(m_dragItem);
+ if (m_operationMode == RESIZEEND || m_operationMode == RESIZESTART)
+ updateSnapPoints(NULL);
+ else
+ updateSnapPoints(m_dragItem);
} else {
QList <GenTime> offsetList;
QList<QGraphicsItem *> children = m_selectionGroup->childItems();
info.endPos = transitionClip->endPos();
} else {
GenTime transitionDuration(65, m_document->fps());
- if (m_dragItem->cropDuration() < transitionDuration) info.endPos = m_dragItem->endPos();
- else info.endPos = info.startPos + transitionDuration;
+ if (m_dragItem->cropDuration() < transitionDuration)
+ info.endPos = m_dragItem->endPos();
+ else
+ info.endPos = info.startPos + transitionDuration;
}
if (info.endPos == info.startPos) info.endPos = info.startPos + GenTime(65, m_document->fps());
// Check there is no other transition at that place
QGraphicsView::mousePressEvent(event);
}
-void CustomTrackView::rebuildGroup(AbstractGroupItem* group)
+void CustomTrackView::rebuildGroup(int childTrack, GenTime childPos)
+{
+ const QPointF p((int)childPos.frames(m_document->fps()), childTrack * m_tracksHeight + m_tracksHeight / 2);
+ QList<QGraphicsItem *> list = scene()->items(p);
+ AbstractGroupItem *group = NULL;
+ for (int i = 0; i < list.size(); i++) {
+ if (!list.at(i)->isEnabled()) continue;
+ if (list.at(i)->type() == GROUPWIDGET) {
+ group = static_cast <AbstractGroupItem *>(list.at(i));
+ break;
+ }
+ }
+ rebuildGroup(group);
+}
+
+void CustomTrackView::rebuildGroup(AbstractGroupItem *group)
{
if (group) {
QList <QGraphicsItem *> children = group->childItems();
if (m_dragItem && m_dragItem->hasKeyFrames()) {
/*if (m_moveOpMode == KEYFRAME) {
// user double clicked on a keyframe, open edit dialog
- //TODO: update for effects with several values per keyframe
+ //TODO: update for effects with several values per keyframe
QDialog d(parentWidget());
Ui::KeyFrameDialog_UI view;
view.setupUi(&d);
getTransitionAvailableSpace(item, minimum, maximum);
else
getClipAvailableSpace(item, minimum, maximum);
- //kDebug()<<"// GOT MOVE POS: "<<minimum.frames(25)<<" - "<<maximum.frames(25);
+
ClipDurationDialog d(item, m_document->timecode(), minimum, maximum, this);
if (d.exec() == QDialog::Accepted) {
ItemInfo clipInfo = item->info();
ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()), info.track);
if (!item || cutTime >= item->endPos() || cutTime <= item->startPos()) {
emit displayMessage(i18n("Cannot find clip to cut"), ErrorMessage);
- if (item) kDebug() << "///////// ERROR CUTTING CLIP : (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), INFO: (" << info.startPos.frames(25) << "-" << info.endPos.frames(25) << ")" << ", CUT: " << cutTime.frames(25);
- else kDebug() << "/// ERROR NO CLIP at: " << info.startPos.frames(m_document->fps()) << ", track: " << info.track;
+ if (item)
+ kDebug() << "///////// ERROR CUTTING CLIP : (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), INFO: (" << info.startPos.frames(25) << "-" << info.endPos.frames(25) << ")" << ", CUT: " << cutTime.frames(25);
+ else
+ kDebug() << "/// ERROR NO CLIP at: " << info.startPos.frames(m_document->fps()) << ", track: " << info.track;
m_blockRefresh = false;
return NULL;
}
}
item->resizeEnd(cutPos);
scene()->addItem(dup);
- if (item->checkKeyFrames()) slotRefreshEffects(item);
- if (dup->checkKeyFrames()) slotRefreshEffects(dup);
+ if (item->checkKeyFrames())
+ slotRefreshEffects(item);
+ if (dup->checkKeyFrames())
+ slotRefreshEffects(dup);
item->baseClip()->addReference();
m_document->updateClip(item->baseClip()->getId());
setDocumentModified();
if (success) {
item->resizeEnd((int) info.endPos.frames(m_document->fps()));
setDocumentModified();
- } else
+ } else {
emit displayMessage(i18n("Error when resizing clip"), ErrorMessage);
+ }
KdenliveSettings::setSnaptopoints(snap);
return item;
-
}
//QTimer::singleShot(3000, this, SLOT(slotEnableRefresh()));
}
if (isLocked) item->setItemLocked(true);
ItemInfo clipInfo = info;
clipInfo.track = m_document->tracksCount() - item->track();
- if (m_document->renderer()->mltInsertClip(clipInfo, item->xml(), item->baseClip()->producer(item->track()), m_scene->editMode() == OVERWRITEEDIT, m_scene->editMode() == INSERTEDIT) == -1) {
+
+ int worked = m_document->renderer()->mltInsertClip(clipInfo, item->xml(), item->baseClip()->producer(item->track()), m_scene->editMode() == OVERWRITEEDIT, m_scene->editMode() == INSERTEDIT);
+ if (worked == -1) {
emit displayMessage(i18n("Cannot insert clip in timeline"), ErrorMessage);
brokenClips.append(item);
continue;
setDocumentModified();
/*
- // debug info
+ // debug info
QRectF rect(0, 1 * m_tracksHeight + m_tracksHeight / 2, sceneRect().width(), 2);
QList<QGraphicsItem *> selection = m_scene->items(rect);
QStringList timelineList;
trackTransitionStartList[m_document->tracksCount() - info.track] = info.startPos.frames(m_document->fps());
}
}
-
- InsertSpaceCommand *command = new InsertSpaceCommand(this, clipsToMove, transitionsToMove, track, timeOffset, false);
- m_commandStack->push(command);
- if (track != -1) track = m_document->tracksCount() - track;
- kDebug() << "SPACER TRACK:" << track;
- m_document->renderer()->mltInsertSpace(trackClipStartList, trackTransitionStartList, track, timeOffset, GenTime());
+ if (!clipsToMove.isEmpty() || !transitionsToMove.isEmpty()) {
+ InsertSpaceCommand *command = new InsertSpaceCommand(this, clipsToMove, transitionsToMove, track, timeOffset, false);
+ m_commandStack->push(command);
+ if (track != -1) track = m_document->tracksCount() - track;
+ kDebug() << "SPACER TRACK:" << track;
+ m_document->renderer()->mltInsertSpace(trackClipStartList, trackTransitionStartList, track, timeOffset, GenTime());
+ setDocumentModified();
+ }
}
resetSelectionGroup(false);
m_operationMode = NONE;
adjustTimelineTransitions(m_scene->editMode(), transition, moveCommand);
new MoveTransitionCommand(this, m_dragItemInfo, info, false, moveCommand);
m_commandStack->push(moveCommand);
+ setDocumentModified();
}
}
} else {
info.track = m_document->tracksCount() - info.track;
Mlt::Producer *prod;
adjustTimelineClips(m_scene->editMode(), clip, ItemInfo(), moveGroup);
- if (clip->isAudioOnly()) prod = clip->baseClip()->audioProducer(info.track);
- else if (clip->isVideoOnly()) prod = clip->baseClip()->videoProducer();
- else prod = clip->baseClip()->producer(info.track);
+ if (clip->isAudioOnly())
+ prod = clip->baseClip()->audioProducer(info.track);
+ else if (clip->isVideoOnly())
+ prod = clip->baseClip()->videoProducer();
+ else
+ prod = clip->baseClip()->producer(info.track);
m_document->renderer()->mltInsertClip(info, clip->xml(), prod, m_scene->editMode() == OVERWRITEEDIT, m_scene->editMode() == INSERTEDIT);
for (int i = 0; i < clip->effectsCount(); i++) {
m_document->renderer()->mltAddEffect(info.track, info.startPos, clip->getEffectArgs(clip->effectAt(i)), false);
m_document->renderer()->mltAddTransition(tr->transitionTag(), newTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML());
}
}
-
new MoveGroupCommand(this, clipsToMove, transitionsToMove, timeOffset, trackOffset, false, moveGroup);
m_commandStack->push(moveGroup);
if (m_selectionGroup) {
m_selectionGroupInfo.startPos = GenTime(m_selectionGroup->scenePos().x(), m_document->fps());
m_selectionGroupInfo.track = m_selectionGroup->track();
+ } else {
+ rebuildGroup((AbstractGroupItem *)group);
}
setDocumentModified();
}
m_document->renderer()->doRefresh();
} else if (m_operationMode == RESIZESTART && m_dragItem->startPos() != m_dragItemInfo.startPos) {
// resize start
- prepareResizeClipStart(m_dragItem, m_dragItemInfo, m_dragItem->startPos().frames(m_document->fps()));
+ if (event->modifiers() != Qt::ControlModifier && m_dragItem->type() == AVWIDGET && m_dragItem->parentItem() && m_dragItem->parentItem() != m_selectionGroup) {
+ AbstractGroupItem *parent = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
+ if (parent) {
+ QUndoCommand *resizeCommand = new QUndoCommand();
+ resizeCommand->setText(i18n("Resize group"));
+ QList <QGraphicsItem *> items = parent->childItems();
+ QList <ItemInfo> infos = parent->resizeInfos();
+ parent->clearResizeInfos();
+ int itemcount = 0;
+ for (int i = 0; i < items.count(); ++i) {
+ AbstractClipItem *item = static_cast<AbstractClipItem *>(items.at(i));
+ if (item && item->type() == AVWIDGET) {
+ ItemInfo info = infos.at(itemcount);
+ prepareResizeClipStart(item, info, item->startPos().frames(m_document->fps()), false, resizeCommand);
+ ++itemcount;
+ }
+ }
+ m_commandStack->push(resizeCommand);
+ }
+ } else {
+ prepareResizeClipStart(m_dragItem, m_dragItemInfo, m_dragItem->startPos().frames(m_document->fps()));
+ }
} else if (m_operationMode == RESIZEEND && m_dragItem->endPos() != m_dragItemInfo.endPos) {
// resize end
- prepareResizeClipEnd(m_dragItem, m_dragItemInfo, m_dragItem->endPos().frames(m_document->fps()));
+ if (event->modifiers() != Qt::ControlModifier && m_dragItem->type() == AVWIDGET && m_dragItem->parentItem() && m_dragItem->parentItem() != m_selectionGroup) {
+ AbstractGroupItem *parent = static_cast <AbstractGroupItem *>(m_dragItem->parentItem());
+ if (parent) {
+ QUndoCommand *resizeCommand = new QUndoCommand();
+ resizeCommand->setText(i18n("Resize group"));
+ QList <QGraphicsItem *> items = parent->childItems();
+ QList <ItemInfo> infos = parent->resizeInfos();
+ parent->clearResizeInfos();
+ int itemcount = 0;
+ for (int i = 0; i < items.count(); ++i) {
+ AbstractClipItem *item = static_cast<AbstractClipItem *>(items.at(i));
+ if (item && item->type() == AVWIDGET) {
+ ItemInfo info = infos.at(itemcount);
+ prepareResizeClipEnd(item, info, item->endPos().frames(m_document->fps()), false, resizeCommand);
+ ++itemcount;
+ }
+ }
+ m_commandStack->push(resizeCommand);
+ }
+ } else {
+ prepareResizeClipEnd(m_dragItem, m_dragItemInfo, m_dragItem->endPos().frames(m_document->fps()));
+ }
} else if (m_operationMode == FADEIN) {
// resize fade in effect
ClipItem * item = static_cast <ClipItem *>(m_dragItem);
if ((val < -50 || val > 150) && item->editedKeyFramePos() != start && item->editedKeyFramePos() != end) {
//delete keyframe
item->movedKeyframe(item->getEffectAt(item->selectedEffectIndex()), item->selectedKeyFramePos(), -1, 0);
- } else item->movedKeyframe(item->getEffectAt(item->selectedEffectIndex()), item->selectedKeyFramePos(), item->editedKeyFramePos(), item->editedKeyFrameValue());
+ } else {
+ item->movedKeyframe(item->getEffectAt(item->selectedEffectIndex()), item->selectedKeyFramePos(), item->editedKeyFramePos(), item->editedKeyFrameValue());
+ }
QDomElement newEffect = item->selectedEffect().cloneNode().toElement();
//item->updateKeyframeEffect();
{
QList<QGraphicsItem *> itemList = scene()->selectedItems();
GenTime currentPos = GenTime(m_cursorPos, m_document->fps());
- for (int i = 0; i < itemList.count(); i++) {
+ QList <QGraphicsItem *> skipList;
+ for (int i = 0; i < itemList.count(); ++i) {
+ if (skipList.indexOf(itemList.at(i)) != -1)
+ continue;
if (itemList.at(i)->type() == AVWIDGET) {
ClipItem *item = static_cast <ClipItem *>(itemList.at(i));
if (item->parentItem() && item->parentItem() != m_selectionGroup) {
- emit displayMessage(i18n("Cannot cut a clip in a group"), ErrorMessage);
- } else if (currentPos > item->startPos() && currentPos < item->endPos()) {
+ skipList.append(item->parentItem()->childItems());
+ razorGroup((AbstractGroupItem *)item->parentItem(), currentPos);
+ } else if (currentPos > item->startPos() && currentPos < item->endPos()) {
RazorClipCommand *command = new RazorClipCommand(this, item->info(), currentPos);
m_commandStack->push(command);
}
+ } else if (itemList.at(i)->type() == GROUPWIDGET && itemList.at(i) != m_selectionGroup) {
+ skipList.append(itemList.at(i)->childItems());
+ razorGroup((AbstractGroupItem *)itemList.at(i), currentPos);
+ }
+ }
+}
+
+void CustomTrackView::razorGroup(AbstractGroupItem* group, GenTime cutPos)
+{
+ if (group) {
+ QList <QGraphicsItem *> children = group->childItems();
+ QList <ItemInfo> clips1, transitions1;
+ QList <ItemInfo> clipsCut, transitionsCut;
+ QList <ItemInfo> clips2, transitions2;
+ for (int i = 0; i < children.count(); ++i) {
+ children.at(i)->setSelected(false);
+ AbstractClipItem *child = static_cast <AbstractClipItem *>(children.at(i));
+ if (child->type() == AVWIDGET) {
+ if (cutPos > child->endPos())
+ clips1 << child->info();
+ else if (cutPos < child->startPos())
+ clips2 << child->info();
+ else
+ clipsCut << child->info();
+ } else {
+ if (cutPos > child->endPos())
+ transitions1 << child->info();
+ else if (cutPos < child->startPos())
+ transitions2 << child->info();
+ else
+ transitionsCut << child->info();
+ }
+ }
+ if (clipsCut.isEmpty() && transitionsCut.isEmpty() && ((clips1.isEmpty() && transitions1.isEmpty()) || (clips2.isEmpty() && transitions2.isEmpty())))
+ return;
+ RazorGroupCommand *command = new RazorGroupCommand(this, clips1, transitions1, clipsCut, transitionsCut, clips2, transitions2, cutPos);
+ m_commandStack->push(command);
+ }
+}
+
+void CustomTrackView::slotRazorGroup(QList <ItemInfo> clips1, QList <ItemInfo> transitions1, QList <ItemInfo> clipsCut, QList <ItemInfo> transitionsCut, QList <ItemInfo> clips2, QList <ItemInfo> transitions2, GenTime cutPos, bool cut)
+{
+ if (cut) {
+ for (int i = 0; i < clipsCut.count(); ++i) {
+ ClipItem *clip = getClipItemAt(clipsCut.at(i).startPos.frames(m_document->fps()), clipsCut.at(i).track);
+ if (clip) {
+ ClipItem *clipBehind = cutClip(clipsCut.at(i), cutPos, true);
+ clips1 << clip->info();
+ if (clipBehind != NULL)
+ clips2 << clipBehind->info();
+ }
}
+ /* TODO: cut transitionsCut
+ * For now just append them to group1 */
+ transitions1 << transitionsCut;
+ doGroupClips(clips1, transitions1, true);
+ doGroupClips(clips2, transitions2, true);
+ } else {
+ /* we might also just use clipsCut.at(0)->parentItem().
+ * Do this loop just in case something went wrong during cut */
+ for (int i = 0; i < clipsCut.count(); ++i) {
+ ClipItem *clip = getClipItemAt(cutPos.frames(m_document->fps()), clipsCut.at(i).track);
+ if (clip && clip->parentItem() && clip->parentItem()->type() == GROUPWIDGET) {
+ AbstractGroupItem *group = static_cast <AbstractGroupItem *>(clip->parentItem());
+ QList <QGraphicsItem *> children = group->childItems();
+ QList <ItemInfo> groupClips;
+ QList <ItemInfo> groupTrans;
+ for (int j = 0; j < children.count(); ++j) {
+ if (children.at(j)->type() == AVWIDGET)
+ groupClips << ((AbstractClipItem *)children.at(j))->info();
+ else if (children.at(j)->type() == TRANSITIONWIDGET)
+ groupTrans << ((AbstractClipItem *)children.at(j))->info();
+ }
+ doGroupClips(groupClips, groupTrans, false);
+ break;
+ }
+ }
+ for (int i = 0; i < clipsCut.count(); ++i)
+ cutClip(clipsCut.at(i), cutPos, false);
+ // TODO: uncut transitonsCut
+ doGroupClips(QList <ItemInfo>() << clips1 << clipsCut << clips2, QList <ItemInfo>() << transitions1 << transitionsCut << transitions2, true);
}
}
ItemInfo info = item->info();
int tracknumber = m_document->tracksCount() - info.track - 1;
bool isLocked = m_document->trackInfoAt(tracknumber).isLocked;
- if (isLocked) item->setItemLocked(true);
- else if (item->isItemLocked()) item->setItemLocked(false);
+ if (isLocked)
+ item->setItemLocked(true);
+ else if (item->isItemLocked())
+ item->setItemLocked(false);
if (item->type() == AVWIDGET) {
ClipItem *clip = static_cast <ClipItem*>(item);
info.track = m_document->tracksCount() - info.track;
Mlt::Producer *prod;
- if (clip->isAudioOnly()) prod = clip->baseClip()->audioProducer(info.track);
- else if (clip->isVideoOnly()) prod = clip->baseClip()->videoProducer();
- else prod = clip->baseClip()->producer(info.track);
+ if (clip->isAudioOnly())
+ prod = clip->baseClip()->audioProducer(info.track);
+ else if (clip->isVideoOnly())
+ prod = clip->baseClip()->videoProducer();
+ else
+ prod = clip->baseClip()->producer(info.track);
m_document->renderer()->mltInsertClip(info, clip->xml(), prod);
} else if (item->type() == TRANSITIONWIDGET) {
Transition *tr = static_cast <Transition*>(item);
int newTrack;
- if (!tr->forcedTrack()) newTrack = getPreviousVideoTrack(info.track);
- else {
+ if (!tr->forcedTrack()) {
+ newTrack = getPreviousVideoTrack(info.track);
+ } else {
newTrack = tr->transitionEndTrack() + trackOffset;
if (newTrack < 0 || newTrack > m_document->tracksCount()) newTrack = getPreviousVideoTrack(info.track);
}
m_document->renderer()->mltAddTransition(tr->transitionTag(), newTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML());
}
}
+ if (!reverseMove)
+ rebuildGroup(m_selectionGroup);
resetSelectionGroup(false);
KdenliveSettings::setSnaptopoints(snap);
m_document->renderer()->doRefresh();
setDocumentModified();
}
-void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo oldInfo, int pos, bool check)
+void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo oldInfo, int pos, bool check, QUndoCommand *command)
{
if (pos == oldInfo.startPos.frames(m_document->fps()))
return;
}
KdenliveSettings::setSnaptopoints(snap);
}
+
+ bool hasParentCommand = false;
+ if (command) {
+ hasParentCommand = true;
+ } else {
+ command = new QUndoCommand();
+ command->setText(i18n("Resize clip start"));
+ }
+
+ // do this here, too, because otherwise undo won't update the group
+ if (item->parentItem() && item->parentItem() != m_selectionGroup)
+ new RebuildGroupCommand(this, item->info().track, item->endPos() - GenTime(1, m_document->fps()), command);
+
ItemInfo info = item->info();
if (item->type() == AVWIDGET) {
ItemInfo resizeinfo = oldInfo;
resizeinfo.track = m_document->tracksCount() - resizeinfo.track;
bool success = m_document->renderer()->mltResizeClipStart(resizeinfo, item->startPos() - oldInfo.startPos);
if (success) {
- QUndoCommand *resizeCommand = new QUndoCommand();
- resizeCommand->setText(i18n("Resize clip"));
-
// Check if there is an automatic transition on that clip (lower track)
Transition *transition = getTransitionItemAtStart(oldInfo.startPos, oldInfo.track);
if (transition && transition->isAutomatic()) {
ItemInfo newTrInfo = trInfo;
newTrInfo.startPos = item->startPos();
if (newTrInfo.startPos < newTrInfo.endPos)
- new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+ new MoveTransitionCommand(this, trInfo, newTrInfo, true, command);
}
// Check if there is an automatic transition on that clip (upper track)
transition = getTransitionItemAtStart(oldInfo.startPos, oldInfo.track - 1);
newTrInfo.startPos = item->startPos();
ClipItem * upperClip = getClipItemAt(oldInfo.startPos, oldInfo.track - 1);
if ((!upperClip || !upperClip->baseClip()->isTransparent()) && newTrInfo.startPos < newTrInfo.endPos)
- new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+ new MoveTransitionCommand(this, trInfo, newTrInfo, true, command);
}
ClipItem *clip = static_cast < ClipItem * >(item);
// put a resize command before & after checking keyframes so that
// we are sure the resize is performed before whenever we do or undo the action
- new ResizeClipCommand(this, oldInfo, info, false, true, resizeCommand);
+ new ResizeClipCommand(this, oldInfo, info, false, true, command);
for (int i = 0; i < indexes.count(); i++) {
- new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effs.at(i).cloneNode().toElement(), clip->effectAt(indexes.at(i)), indexes.at(i), false, resizeCommand);
+ new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effs.at(i).cloneNode().toElement(), clip->effectAt(indexes.at(i)), indexes.at(i), false, command);
updateEffect(m_document->tracksCount() - clip->track(), clip->startPos(), clip->effectAt(indexes.at(i)), indexes.at(i));
}
- new ResizeClipCommand(this, oldInfo, info, false, true, resizeCommand);
+ new ResizeClipCommand(this, oldInfo, info, false, true, command);
emit clipItemSelected(clip);
} else {
- new ResizeClipCommand(this, oldInfo, info, false, false, resizeCommand);
+ new ResizeClipCommand(this, oldInfo, info, false, false, command);
}
-
- m_commandStack->push(resizeCommand);
} else {
KdenliveSettings::setSnaptopoints(false);
item->resizeStart((int) oldInfo.startPos.frames(m_document->fps()));
KdenliveSettings::setSnaptopoints(snap);
emit displayMessage(i18n("Cannot resize transition"), ErrorMessage);
} else {
- MoveTransitionCommand *command = new MoveTransitionCommand(this, oldInfo, info, false);
- m_commandStack->push(command);
+ MoveTransitionCommand *moveCommand = new MoveTransitionCommand(this, oldInfo, info, false, command);
+ if (command == NULL)
+ m_commandStack->push(moveCommand);
}
}
if (item->parentItem() && item->parentItem() != m_selectionGroup)
- rebuildGroup(static_cast <AbstractGroupItem *>(item->parentItem()));
+ new RebuildGroupCommand(this, item->info().track, item->endPos() - GenTime(1, m_document->fps()), command);
+
+ if (!hasParentCommand)
+ m_commandStack->push(command);
}
-void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldInfo, int pos, bool check)
+void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldInfo, int pos, bool check, QUndoCommand *command)
{
if (pos == oldInfo.endPos.frames(m_document->fps()))
return;
}
KdenliveSettings::setSnaptopoints(snap);
}
+
+ bool hasParentCommand = false;
+ if (command) {
+ hasParentCommand = true;
+ } else {
+ command = new QUndoCommand();
+ command->setText(i18n("Resize clip end"));
+ }
+
+ // do this here, too, because otherwise undo won't update the group
+ if (item->parentItem() && item->parentItem() != m_selectionGroup)
+ new RebuildGroupCommand(this, item->info().track, item->startPos(), command);
+
ItemInfo info = item->info();
if (item->type() == AVWIDGET) {
ItemInfo resizeinfo = info;
resizeinfo.track = m_document->tracksCount() - resizeinfo.track;
bool success = m_document->renderer()->mltResizeClipEnd(resizeinfo, resizeinfo.endPos - resizeinfo.startPos);
if (success) {
- QUndoCommand *resizeCommand = new QUndoCommand();
- resizeCommand->setText(i18n("Resize clip"));
-
// Check if there is an automatic transition on that clip (lower track)
Transition *tr = getTransitionItemAtEnd(oldInfo.endPos, oldInfo.track);
if (tr && tr->isAutomatic()) {
ItemInfo newTrInfo = trInfo;
newTrInfo.endPos = item->endPos();
if (newTrInfo.endPos > newTrInfo.startPos)
- new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+ new MoveTransitionCommand(this, trInfo, newTrInfo, true, command);
}
// Check if there is an automatic transition on that clip (upper track)
newTrInfo.endPos = item->endPos();
ClipItem * upperClip = getClipItemAtEnd(oldInfo.endPos, oldInfo.track - 1);
if ((!upperClip || !upperClip->baseClip()->isTransparent()) && newTrInfo.endPos > newTrInfo.startPos)
- new MoveTransitionCommand(this, trInfo, newTrInfo, true, resizeCommand);
+ new MoveTransitionCommand(this, trInfo, newTrInfo, true, command);
}
// put a resize command before & after checking keyframes so that
// we are sure the resize is performed before whenever we do or undo the action
- new ResizeClipCommand(this, oldInfo, info, false, true, resizeCommand);
+ new ResizeClipCommand(this, oldInfo, info, false, true, command);
for (int i = 0; i < indexes.count(); i++) {
- new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effs.at(i).cloneNode().toElement(), clip->effectAt(indexes.at(i)), indexes.at(i), false, resizeCommand);
+ new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effs.at(i).cloneNode().toElement(), clip->effectAt(indexes.at(i)), indexes.at(i), false, command);
updateEffect(m_document->tracksCount() - clip->track(), clip->startPos(), clip->effectAt(indexes.at(i)), indexes.at(i));
}
- new ResizeClipCommand(this, oldInfo, info, false, true, resizeCommand);
+ new ResizeClipCommand(this, oldInfo, info, false, true, command);
emit clipItemSelected(clip);
} else {
- new ResizeClipCommand(this, oldInfo, info, false, false, resizeCommand);
+ new ResizeClipCommand(this, oldInfo, info, false, false, command);
}
- m_commandStack->push(resizeCommand);
updatePositionEffects(clip, oldInfo);
} else {
KdenliveSettings::setSnaptopoints(false);
KdenliveSettings::setSnaptopoints(true);
emit displayMessage(i18n("Cannot resize transition"), ErrorMessage);
} else {
- MoveTransitionCommand *command = new MoveTransitionCommand(this, oldInfo, info, false);
- m_commandStack->push(command);
+ MoveTransitionCommand *moveCommand = new MoveTransitionCommand(this, oldInfo, info, false, command);
+ if (command == NULL)
+ m_commandStack->push(moveCommand);
}
}
if (item->parentItem() && item->parentItem() != m_selectionGroup)
- rebuildGroup(static_cast <AbstractGroupItem *>(item->parentItem()));
+ new RebuildGroupCommand(this, item->info().track, item->startPos(), command);
+
+ if (!hasParentCommand)
+ m_commandStack->push(command);
}
void CustomTrackView::updatePositionEffects(ClipItem * item, ItemInfo info)
int diff = sceneRect().width() - m_projectDuration;
if (diff * newmatrix.m11() < 50) {
- if (newmatrix.m11() < 0.4) setSceneRect(0, 0, (m_projectDuration + 100 / newmatrix.m11()), sceneRect().height());
- else setSceneRect(0, 0, (m_projectDuration + 300), sceneRect().height());
+ if (newmatrix.m11() < 0.4)
+ setSceneRect(0, 0, (m_projectDuration + 100 / newmatrix.m11()), sceneRect().height());
+ else
+ setSceneRect(0, 0, (m_projectDuration + 300), sceneRect().height());
}
centerOn(QPointF(cursorPos(), verticalPos));
}
void CustomTrackView::slotRefreshGuides()
{
if (KdenliveSettings::showmarkers()) {
- for (int i = 0; i < m_guides.count(); i++) {
+ for (int i = 0; i < m_guides.count(); i++)
m_guides.at(i)->update();
- }
}
}
}
// add guides
- for (int i = 0; i < m_guides.count(); i++) {
+ for (int i = 0; i < m_guides.count(); i++)
m_searchPoints.append(m_guides.at(i)->info());
- }
qSort(m_searchPoints);
}
for (int i = 0; i < itemList.count(); i++) {
if (itemList.at(i)->type() == AVWIDGET) {
ClipItem *item = (ClipItem *)itemList.at(i);
- if (item->clipProducer() == clipId) {
+ if (item->clipProducer() == clipId)
matchingInfo << item->info();
- }
}
}
return matchingInfo;
m_animationTimer->start();
}
}
+
+bool CustomTrackView::hasAudio(int track) const
+{
+ QRectF rect(0, (double)(track * m_tracksHeight + 1), (double) sceneRect().width(), (double)(m_tracksHeight - 1));
+ QList<QGraphicsItem *> collisions = scene()->items(rect, Qt::IntersectsItemBoundingRect);
+ QGraphicsItem *item;
+ for (int i = 0; i < collisions.count(); i++) {
+ item = collisions.at(i);
+ if (!item->isEnabled()) continue;
+ if (item->type() == AVWIDGET) {
+ ClipItem *clip = static_cast <ClipItem *>(item);
+ if (!clip->isVideoOnly() && (clip->clipType() == AUDIO || clip->clipType() == AV || clip->clipType() == PLAYLIST)) return true;
+ }
+ }
+ return false;
+}