From: Till Theato Date: Fri, 16 Jul 2010 15:40:44 +0000 (+0000) Subject: Resize all items in a group at once (from end only for now; dragging from start will... X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=4cf9cdc9891b0ce00d5818320f942349946d695b;p=kdenlive Resize all items in a group at once (from end only for now; dragging from start will follow soon): http://kdenlive.org/mantis/view.php?id=1582 svn path=/trunk/kdenlive/; revision=4584 --- diff --git a/src/abstractgroupitem.cpp b/src/abstractgroupitem.cpp index 7d2cc39a..53f94057 100644 --- a/src/abstractgroupitem.cpp +++ b/src/abstractgroupitem.cpp @@ -42,6 +42,7 @@ AbstractGroupItem::AbstractGroupItem(double /* fps */) : setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); #endif setAcceptDrops(true); + m_resizeInfos = QList (); } int AbstractGroupItem::type() const @@ -381,3 +382,41 @@ void AbstractGroupItem::mousePressEvent(QGraphicsSceneMouseEvent * event) event->ignore(); } else QGraphicsItem::mousePressEvent(event); } + +void AbstractGroupItem::resizeEnd(int diff) +{ + bool info = false; + if (m_resizeInfos.isEmpty()) + info = true; + int maximum = diff; + QList children = childItems(); + QList items; + int itemcount = 0; + for (int i = 0; i < children.count(); ++i) { + AbstractClipItem *item = static_cast (children.at(i)); + if (item && item->type() == AVWIDGET) { + items << item; + if (info) + m_resizeInfos << item->info(); + item->resizeEnd((int)(m_resizeInfos.at(itemcount).endPos.frames(item->fps())) + diff); + int itemdiff = (int)(item->endPos() - m_resizeInfos.at(itemcount).endPos).frames(item->fps()); + if (qAbs(itemdiff) < qAbs(maximum)) + maximum = itemdiff; + ++itemcount; + } + } + + for (int i = 0; i < items.count(); ++i) + items.at(i)->resizeEnd((int)(m_resizeInfos.at(i).endPos.frames(items.at(i)->fps())) + maximum); +} + +QList< ItemInfo > AbstractGroupItem::resizeInfos() +{ + return m_resizeInfos; +} + +void AbstractGroupItem::clearResizeInfos() +{ + // m_resizeInfos.clear() will crash in some cases for unknown reasons - ttill + m_resizeInfos = QList (); +} diff --git a/src/abstractgroupitem.h b/src/abstractgroupitem.h index 45ed0656..bf080a26 100644 --- a/src/abstractgroupitem.h +++ b/src/abstractgroupitem.h @@ -44,6 +44,14 @@ public: void setItemLocked(bool locked); bool isItemLocked() const; // ItemInfo info() const; + /** @brief Resizes all clips in this group from the end. + * @param diff Difference to endPos stored in m_resizeInfos */ + void resizeEnd(int diff); + void resizeStart(int diff); + /** @brief Gets m_resizeInfos */ + QList resizeInfos(); + /** @brief Clears m_resizeInfos */ + void clearResizeInfos(); protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); @@ -56,6 +64,8 @@ protected: private: void fixItemRect(); QPainterPath groupShape(GRAPHICSRECTITEM type, QPointF offset) const; + /** Stores the original info of the items beeing resized. */ + QList m_resizeInfos; }; #endif diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 17c3f0f4..d58c1612 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -393,7 +393,13 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) m_dragItem->resizeStart((int)(snappedPos)); } else if (m_operationMode == RESIZEEND && move) { m_document->renderer()->pause(); - m_dragItem->resizeEnd((int)(snappedPos)); + if (m_dragItem->type() == AVWIDGET && m_dragItem->parentItem() && m_dragItem->parentItem() != m_selectionGroup) { + AbstractGroupItem *parent = static_cast (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) { @@ -1205,7 +1211,7 @@ void CustomTrackView::editItemDuration() getTransitionAvailableSpace(item, minimum, maximum); else getClipAvailableSpace(item, minimum, maximum); - //kDebug()<<"// GOT MOVE POS: "<timecode(), minimum, maximum, this); if (d.exec() == QDialog::Accepted) { ItemInfo clipInfo = item->info(); @@ -3174,7 +3180,28 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) 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 (m_dragItem->type() == AVWIDGET && m_dragItem->parentItem() && m_dragItem->parentItem() != m_selectionGroup) { + AbstractGroupItem *parent = static_cast (m_dragItem->parentItem()); + if (parent) { + QUndoCommand *resizeCommand = new QUndoCommand(); + resizeCommand->setText(i18n("Resize group")); + QList items = parent->childItems(); + QList infos = parent->resizeInfos(); + parent->clearResizeInfos(); + int itemcount = 0; + for (int i = 0; i < items.count(); ++i) { + AbstractClipItem *item = static_cast(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 (m_dragItem); @@ -3985,7 +4012,7 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end, bool 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; @@ -4007,8 +4034,13 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol 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")); + bool hasParentCommand = false; + if (command) { + hasParentCommand = true; + } else { + command = new QUndoCommand(); + command->setText(i18n("Resize clip start")); + } // Check if there is an automatic transition on that clip (lower track) Transition *transition = getTransitionItemAtStart(oldInfo.startPos, oldInfo.track); @@ -4017,7 +4049,7 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol 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); @@ -4027,7 +4059,7 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol 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); @@ -4054,18 +4086,19 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol // 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); + if (!hasParentCommand) + m_commandStack->push(command); } else { KdenliveSettings::setSnaptopoints(false); item->resizeStart((int) oldInfo.startPos.frames(m_document->fps())); @@ -4081,8 +4114,9 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol 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); } } @@ -4090,7 +4124,7 @@ void CustomTrackView::prepareResizeClipStart(AbstractClipItem* item, ItemInfo ol rebuildGroup(static_cast (item->parentItem())); } -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; @@ -4112,8 +4146,13 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI 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")); + bool hasParentCommand = false; + if (command) { + hasParentCommand = true; + } else { + command = new QUndoCommand(); + command->setText(i18n("Resize clip end")); + } // Check if there is an automatic transition on that clip (lower track) Transition *tr = getTransitionItemAtEnd(oldInfo.endPos, oldInfo.track); @@ -4122,7 +4161,7 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI 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) @@ -4133,7 +4172,7 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI 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); } @@ -4159,18 +4198,19 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI // 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); + if (!hasParentCommand) + m_commandStack->push(command); updatePositionEffects(clip, oldInfo); } else { KdenliveSettings::setSnaptopoints(false); @@ -4187,8 +4227,9 @@ void CustomTrackView::prepareResizeClipEnd(AbstractClipItem* item, ItemInfo oldI 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) diff --git a/src/customtrackview.h b/src/customtrackview.h index 7ee271d3..50ad4932 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -338,15 +338,17 @@ private: * @param item Item to resize * @param oldInfo The item's info before resizement (set to item->info() is @param check true) * @param pos New startPos - * @param check (optional, default = false) Whether to check for collisions */ - void prepareResizeClipStart(AbstractClipItem *item, ItemInfo oldInfo, int pos, bool check = false); + * @param check (optional, default = false) Whether to check for collisions + * @param command (optional) Will be used as parent command (for undo history) */ + void prepareResizeClipStart(AbstractClipItem *item, ItemInfo oldInfo, int pos, bool check = false, QUndoCommand *command = NULL); /** @brief Takes care of updating effects and attached transitions during a resize from end. * @param item Item to resize * @param oldInfo The item's info before resizement (set to item->info() is @param check true) * @param pos New endPos - * @param check (optional, default = false) Whether to check for collisions */ - void prepareResizeClipEnd(AbstractClipItem *item, ItemInfo oldInfo, int pos, bool check = false); + * @param check (optional, default = false) Whether to check for collisions + * @param command (optional) Will be used as parent command (for undo history) */ + void prepareResizeClipEnd(AbstractClipItem *item, ItemInfo oldInfo, int pos, bool check = false, QUndoCommand *command = NULL); private slots: void slotRefreshGuides();