From: Jean-Baptiste M. <jb...@kd...> - 2012-03-29 03:37:50
|
Git commit 2e1eba4e997f5b4c2aa21345968ed0b192e788d1 by Jean-Baptiste Mardelle. Committed on 29/03/2012 at 02:44. Pushed by mardelle into branch 'effectstack'. Effect groups can now be dropped onto another clip M +25 -13 src/clipitem.cpp M +1 -1 src/clipitem.h M +61 -58 src/customtrackview.cpp M +3 -0 src/customtrackview.h M +12 -6 src/effectslist.cpp M +2 -2 src/effectslist.h M +2 -1 src/effectstack/collapsibleeffect.cpp M +1 -1 src/effectstack/collapsibleeffect.h M +27 -25 src/effectstack/collapsiblegroup.cpp M +7 -3 src/effectstack/collapsiblegroup.h M +39 -11 src/effectstack/effectstackview2.cpp M +4 -1 src/effectstack/effectstackview2.h http://commits.kde.org/kdenlive/2e1eba4e997f5b4c2aa21345968ed0b192e788d1 diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 1d0e4c7..f1de569 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -230,8 +230,6 @@ void ClipItem::initEffect(QDomElement effect, int diff) { // the kdenlive_ix int is used to identify an effect in mlt's playlist, should // not be changed - if (effect.attribute("kdenlive_ix").toInt() == 0) - effect.setAttribute("kdenlive_ix", QString::number(effectsCounter())); if (effect.attribute("id") == "freeze" && diff > 0) { EffectsList::setParameter(effect, "frame", QString::number(diff)); @@ -1410,31 +1408,36 @@ bool ClipItem::moveEffect(QDomElement effect, int ix) return true; } -EffectsParameterList ClipItem::addEffect(const QDomElement effect, bool /*animate*/) +EffectsParameterList ClipItem::addEffect(QDomElement effect, bool /*animate*/) { bool needRepaint = false; QLocale locale; int ix; + QDomElement insertedEffect; if (!effect.hasAttribute("kdenlive_ix")) { ix = effectsCounter(); } else ix = effect.attribute("kdenlive_ix").toInt(); if (!m_effectList.isEmpty() && ix <= m_effectList.count()) { needRepaint = true; - m_effectList.insert(effect); - } else m_effectList.append(effect); + insertedEffect = m_effectList.insert(effect); + } else insertedEffect = m_effectList.append(effect); + + // Update index to the real one + effect.setAttribute("kdenlive_ix", insertedEffect.attribute("kdenlive_ix")); + EffectsParameterList parameters; - parameters.addParam("tag", effect.attribute("tag")); - parameters.addParam("kdenlive_ix", effect.attribute("kdenlive_ix")); - if (effect.hasAttribute("src")) parameters.addParam("src", effect.attribute("src")); - if (effect.hasAttribute("disable")) parameters.addParam("disable", effect.attribute("disable")); + parameters.addParam("tag", insertedEffect.attribute("tag")); + parameters.addParam("kdenlive_ix", insertedEffect.attribute("kdenlive_ix")); + if (insertedEffect.hasAttribute("src")) parameters.addParam("src", insertedEffect.attribute("src")); + if (insertedEffect.hasAttribute("disable")) parameters.addParam("disable", insertedEffect.attribute("disable")); - QString effectId = effect.attribute("id"); - if (effectId.isEmpty()) effectId = effect.attribute("tag"); + QString effectId = insertedEffect.attribute("id"); + if (effectId.isEmpty()) effectId = insertedEffect.attribute("tag"); parameters.addParam("id", effectId); // special case: the affine effect needs in / out points - QDomNodeList params = effect.elementsByTagName("parameter"); + QDomNodeList params = insertedEffect.elementsByTagName("parameter"); int fade = 0; bool needInOutSync = false; for (int i = 0; i < params.count(); i++) { @@ -1635,7 +1638,16 @@ void ClipItem::dropEvent(QGraphicsSceneDragDropEvent * event) QDomDocument doc; doc.setContent(effects, true); QDomElement e = doc.documentElement(); - e.setAttribute("kdenlive_ix", 0); + if (e.tagName() == "list") { + // dropped an effect group + QDomNodeList effectlist = e.elementsByTagName("effect"); + for (int i = 0; i < effectlist.count(); i++) { + effectlist.at(i).toElement().removeAttribute("kdenlive_ix"); + } + } else { + // single effect dropped + e.removeAttribute("kdenlive_ix"); + } CustomTrackView *view = (CustomTrackView *) scene()->views()[0]; if (view) view->slotAddEffect(e, m_info.startPos, track()); } diff --git a/src/clipitem.h b/src/clipitem.h index 6457dbc..f5c8a5b 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -75,7 +75,7 @@ public: /** @brief Adds an effect to the clip. * @return The parameters that will be passed to Mlt */ - EffectsParameterList addEffect(const QDomElement effect, bool animate = true); + EffectsParameterList addEffect(QDomElement effect, bool animate = true); /** @brief Deletes the effect with id @param index. */ void deleteEffect(QString index); diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 61fb07b..66daef0 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -1727,32 +1727,21 @@ void CustomTrackView::slotAddGroupEffect(QDomElement effect, AbstractGroupItem * if (!namenode.isNull()) effectName = i18n(namenode.text().toUtf8().data()); else effectName = i18n("effect"); effectCommand->setText(i18n("Add %1", effectName)); - int count = 0; for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET) { ClipItem *item = static_cast <ClipItem *>(itemList.at(i)); - if (effect.attribute("type") == "audio") { - // Don't add audio effects on video clips - if (item->isVideoOnly() || (item->clipType() != AUDIO && item->clipType() != AV && item->clipType() != PLAYLIST)) continue; - } else if (effect.hasAttribute("type") == false) { - // Don't add video effect on audio clips - if (item->isAudioOnly() || item->clipType() == AUDIO) continue; - } - - if (effect.attribute("unique", "0") != "0" && item->hasEffect(effect.attribute("tag"), effect.attribute("id")) != -1) { - emit displayMessage(i18n("Effect already present in clip"), ErrorMessage); - continue; - } - if (item->isItemLocked()) { - continue; - } - item->initEffect(effect); - - new AddEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), effect, true, effectCommand); - count++; + if (effect.tagName() == "list") { + QDomNodeList effectlist = effect.elementsByTagName("effect"); + for (int j = 0; j < effectlist.count(); j++) { + processEffect(item, effectlist.at(j).toElement(), effectCommand); + } + } + else { + processEffect(item, effect, effectCommand); + } } } - if (count > 0) { + if (effectCommand->childCount() > 0) { m_commandStack->push(effectCommand); setDocumentModified(); } else delete effectCommand; @@ -1768,9 +1757,13 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track) QList<QGraphicsItem *> itemList; QUndoCommand *effectCommand = new QUndoCommand(); QString effectName; - QDomElement namenode = effect.firstChildElement("name"); - if (!namenode.isNull()) effectName = i18n(namenode.text().toUtf8().data()); - else effectName = i18n("effect"); + if (effect.tagName() == "list") { + effectName = effect.attribute("name"); + } else { + QDomElement namenode = effect.firstChildElement("name"); + if (!namenode.isNull()) effectName = i18n(namenode.text().toUtf8().data()); + else effectName = i18n("effect"); + } effectCommand->setText(i18n("Add %1", effectName)); if (track == -1) itemList = scene()->selectedItems(); @@ -1793,40 +1786,13 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track) for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET) { ClipItem *item = static_cast <ClipItem *>(itemList.at(i)); - if (effect.attribute("type") == "audio") { - // Don't add audio effects on video clips - if (item->isVideoOnly() || (item->clipType() != AUDIO && item->clipType() != AV && item->clipType() != PLAYLIST)) { - /* do not show error message when item is part of a group as the user probably knows what he does then - * and the message is annoying when working with the split audio feature */ - if (!item->parentItem() || item->parentItem() == m_selectionGroup) - emit displayMessage(i18n("Cannot add an audio effect to this clip"), ErrorMessage); - continue; - } - } else if (effect.attribute("type") == "video" || !effect.hasAttribute("type")) { - // Don't add video effect on audio clips - if (item->isAudioOnly() || item->clipType() == AUDIO) { - /* do not show error message when item is part of a group as the user probably knows what he does then - * and the message is annoying when working with the split audio feature */ - if (!item->parentItem() || item->parentItem() == m_selectionGroup) - emit displayMessage(i18n("Cannot add a video effect to this clip"), ErrorMessage); - continue; - } - } - if (item->hasEffect(effect.attribute("tag"), effect.attribute("id")) != -1 && effect.attribute("unique", "0") != "0") { - emit displayMessage(i18n("Effect already present in clip"), ErrorMessage); - continue; - } - if (item->isItemLocked()) { - continue; - } - - if (effect.attribute("id") == "freeze" && m_cursorPos > item->startPos().frames(m_document->fps()) && m_cursorPos < item->endPos().frames(m_document->fps())) { - item->initEffect(effect, m_cursorPos - item->startPos().frames(m_document->fps())); - } else { - kDebug()<<"PREIT 0: "<<effect.attribute("kdenlive_ix"); - item->initEffect(effect); - } - new AddEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), effect, true, effectCommand); + if (effect.tagName() == "list") { + QDomNodeList effectlist = effect.elementsByTagName("effect"); + for (int j = 0; j < effectlist.count(); j++) { + processEffect(item, effectlist.at(j).toElement(), effectCommand); + } + } + else processEffect(item, effect, effectCommand); } } if (effectCommand->childCount() > 0) { @@ -1850,6 +1816,43 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track) } else delete effectCommand; } +void CustomTrackView::processEffect(ClipItem *item, QDomElement effect, QUndoCommand *effectCommand) +{ + if (effect.attribute("type") == "audio") { + // Don't add audio effects on video clips + if (item->isVideoOnly() || (item->clipType() != AUDIO && item->clipType() != AV && item->clipType() != PLAYLIST)) { + /* do not show error message when item is part of a group as the user probably knows what he does then + * and the message is annoying when working with the split audio feature */ + if (!item->parentItem() || item->parentItem() == m_selectionGroup) + emit displayMessage(i18n("Cannot add an audio effect to this clip"), ErrorMessage); + return; + } + } else if (effect.attribute("type") == "video" || !effect.hasAttribute("type")) { + // Don't add video effect on audio clips + if (item->isAudioOnly() || item->clipType() == AUDIO) { + /* do not show error message when item is part of a group as the user probably knows what he does then + * and the message is annoying when working with the split audio feature */ + if (!item->parentItem() || item->parentItem() == m_selectionGroup) + emit displayMessage(i18n("Cannot add a video effect to this clip"), ErrorMessage); + return; + } + } + if (item->hasEffect(effect.attribute("tag"), effect.attribute("id")) != -1 && effect.attribute("unique", "0") != "0") { + emit displayMessage(i18n("Effect already present in clip"), ErrorMessage); + return; + } + if (item->isItemLocked()) { + return; + } + + if (effect.attribute("id") == "freeze" && m_cursorPos > item->startPos().frames(m_document->fps()) && m_cursorPos < item->endPos().frames(m_document->fps())) { + item->initEffect(effect, m_cursorPos - item->startPos().frames(m_document->fps())); + } else { + item->initEffect(effect); + } + new AddEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), effect, true, effectCommand); +} + void CustomTrackView::slotDeleteEffect(ClipItem *clip, int track, QDomElement effect, bool affectGroup) { if (clip == NULL) { diff --git a/src/customtrackview.h b/src/customtrackview.h index 015a2fe..6a66ae6 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -441,6 +441,9 @@ private: * @param fromStart false = resize from end * @param command Used as a parent for EditEffectCommand */ void adjustEffects(ClipItem *item, ItemInfo oldInfo, QUndoCommand *command); + + /** @brief Prepare an add clip command for an effect */ + void processEffect(ClipItem *item, QDomElement effect, QUndoCommand *effectCommand); private slots: void slotRefreshGuides(); diff --git a/src/effectslist.cpp b/src/effectslist.cpp index 77c1f41..276c748 100644 --- a/src/effectslist.cpp +++ b/src/effectslist.cpp @@ -297,12 +297,16 @@ void EffectsList::removeMetaProperties(QDomElement producer) } } -void EffectsList::append(QDomElement e) +QDomElement EffectsList::append(QDomElement e) { + QDomElement result; if (!e.isNull()) { - m_baseElement.appendChild(importNode(e, true)); - if (m_useIndex) updateIndexes(m_baseElement.childNodes()); + result = m_baseElement.appendChild(importNode(e, true)).toElement(); + if (m_useIndex) { + updateIndexes(m_baseElement.childNodes()); + } } + return result; } int EffectsList::count() const @@ -337,16 +341,18 @@ QDomElement EffectsList::itemFromIndex(int ix) const return effects.at(ix - 1).toElement(); } -void EffectsList::insert(QDomElement effect) +QDomElement EffectsList::insert(QDomElement effect) { QDomNodeList effects = m_baseElement.childNodes(); int ix = effect.attribute("kdenlive_ix").toInt(); - if (ix > effects.count()) m_baseElement.appendChild(importNode(effect, true)); + QDomElement result; + if (effect.hasAttribute("kdenlive_ix") && ix > effects.count()) result = m_baseElement.appendChild(importNode(effect, true)).toElement(); else { QDomElement listeffect = effects.at(ix - 1).toElement(); - m_baseElement.insertBefore(importNode(effect, true), listeffect); + result = m_baseElement.insertBefore(importNode(effect, true), listeffect).toElement(); } if (m_useIndex) updateIndexes(effects); + return result; } void EffectsList::updateIndexes(QDomNodeList effects) diff --git a/src/effectslist.h b/src/effectslist.h index 0e26b05..e338b2b 100644 --- a/src/effectslist.h +++ b/src/effectslist.h @@ -60,13 +60,13 @@ public: QString getInfoFromIndex(const int ix) const; QString getEffectInfo(const QDomElement effect) const; void clone(const EffectsList &original); - void append(QDomElement e); + QDomElement append(QDomElement e); bool isEmpty() const; int count() const; const QDomElement at(int ix) const; void removeAt(int ix); QDomElement itemFromIndex(int ix) const; - void insert(QDomElement effect); + QDomElement insert(QDomElement effect); void updateEffect(QDomElement effect); static bool hasKeyFrames(QDomElement effect); static bool hasSimpleKeyFrames(QDomElement effect); diff --git a/src/effectstack/collapsibleeffect.cpp b/src/effectstack/collapsibleeffect.cpp index 6ab1eb8..47f39de 100644 --- a/src/effectstack/collapsibleeffect.cpp +++ b/src/effectstack/collapsibleeffect.cpp @@ -428,6 +428,7 @@ void CollapsibleEffect::slotShow(bool show) void CollapsibleEffect::updateGroupIndex(int groupIndex) { m_info.groupIndex = groupIndex; + if (groupIndex == -1) m_info.groupName.clear(); m_effect.setAttribute("kdenlive_info", m_info.toString()); emit parameterChanged(m_original_effect, m_effect, effectIndex()); } @@ -592,7 +593,7 @@ void CollapsibleEffect::dropEvent(QDropEvent *event) emit addEffect(e); return; } - emit moveEffect(ix, effectIndex(), groupIndex()); + emit moveEffect(ix, effectIndex(), m_info.groupIndex, m_info.groupName); event->setDropAction(Qt::MoveAction); event->accept(); } diff --git a/src/effectstack/collapsibleeffect.h b/src/effectstack/collapsibleeffect.h index 29682d3..38d893e 100644 --- a/src/effectstack/collapsibleeffect.h +++ b/src/effectstack/collapsibleeffect.h @@ -199,7 +199,7 @@ signals: void resetEffect(int ix); /** @brief Ask for creation of a group. */ void createGroup(int ix); - void moveEffect(int current_pos, int new_pos, int groupIndex); + void moveEffect(int current_pos, int new_pos, int groupIndex, QString groupName); void unGroup(CollapsibleEffect *); void addEffect(QDomElement e); }; diff --git a/src/effectstack/collapsiblegroup.cpp b/src/effectstack/collapsiblegroup.cpp index 5b19a1f..de38ff5 100644 --- a/src/effectstack/collapsiblegroup.cpp +++ b/src/effectstack/collapsiblegroup.cpp @@ -42,6 +42,7 @@ MyEditableLabel::MyEditableLabel(QWidget * parent): { setFrame(false); setReadOnly(true); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); } void MyEditableLabel::mouseDoubleClickEvent ( QMouseEvent * e ) @@ -56,6 +57,7 @@ CollapsibleGroup::CollapsibleGroup(int ix, bool firstGroup, bool lastGroup, QStr m_index(ix) { setupUi(this); + m_subWidgets = QList <CollapsibleEffect *> (); setFont(KGlobalSettings::smallestReadableFont()); QHBoxLayout *l = static_cast <QHBoxLayout *>(framegroup->layout()); m_title = new MyEditableLabel(this); @@ -208,12 +210,9 @@ void CollapsibleGroup::slotShow(bool show) //emit parameterChanged(m_original_effect, m_effect, effectIndex()); } -void CollapsibleGroup::updateGroupIndex(int groupIndex) +QWidget *CollapsibleGroup::title() const { - /*TODO: - m_info.groupIndex = groupIndex; - m_effect.setAttribute("kdenlive_info", m_info.toString()); - emit parameterChanged(m_original_effect, m_effect, effectIndex());*/ + return m_title; } void CollapsibleGroup::addGroupEffect(CollapsibleEffect *effect) @@ -226,6 +225,8 @@ void CollapsibleGroup::addGroupEffect(CollapsibleEffect *effect) widgetFrame->setLayout(vbox); } effect->setGroupIndex(groupIndex()); + effect->setGroupName(m_title->text()); + m_subWidgets.append(effect); vbox->addWidget(effect); } @@ -238,14 +239,11 @@ void CollapsibleGroup::removeGroup(int ix, QVBoxLayout *layout) { QVBoxLayout *vbox = static_cast<QVBoxLayout *>(widgetFrame->layout()); if (vbox == NULL) return; - - for (int j = vbox->count() - 1; j >= 0; j--) { - QLayoutItem *child = vbox->takeAt(j); - CollapsibleGroup *e = static_cast<CollapsibleGroup *>(child->widget()); - layout->insertWidget(ix, e); - e->updateGroupIndex(-1); - delete child; + for (int i = m_subWidgets.count() - 1; i >= 0 ; i--) { + vbox->removeWidget(m_subWidgets.at(i)); + layout->insertWidget(ix, m_subWidgets.at(i)); } + m_subWidgets.clear(); } int CollapsibleGroup::groupIndex() const @@ -253,8 +251,6 @@ int CollapsibleGroup::groupIndex() const return m_index; } - - bool CollapsibleGroup::isGroup() const { return true; @@ -303,12 +299,9 @@ void CollapsibleGroup::dropEvent(QDropEvent *event) emit addEffect(e); return; } - int new_index = -1; - QVBoxLayout *vbox = static_cast<QVBoxLayout *>(widgetFrame->layout()); - if (vbox == NULL) return; - CollapsibleEffect *effect = static_cast<CollapsibleEffect *>(vbox->itemAt(vbox->count() -1)->widget()); - new_index = effect->effectIndex(); - emit moveEffect(ix, new_index, m_index); + if (m_subWidgets.isEmpty()) return; + int new_index = m_subWidgets.at(m_subWidgets.count() - 1)->effectIndex(); + emit moveEffect(ix, new_index, m_index, m_title->text()); event->setDropAction(Qt::MoveAction); event->accept(); } @@ -317,17 +310,26 @@ void CollapsibleGroup::slotRenameGroup() { m_title->setReadOnly(true); if (m_title->text().isEmpty()) m_title->setText(i18n("Effect Group")); - QList <CollapsibleEffect*> effects = findChildren<CollapsibleEffect*>(); - for (int j = 0; j < effects.count(); j++) { - effects.at(j)->setGroupName(m_title->text()); + for (int j = 0; j < m_subWidgets.count(); j++) { + m_subWidgets.at(j)->setGroupName(m_title->text()); } emit groupRenamed(this); } QList <CollapsibleEffect*> CollapsibleGroup::effects() { - QList <CollapsibleEffect*> result = findChildren<CollapsibleEffect*>(); - return result; + return m_subWidgets; } +QDomDocument CollapsibleGroup::effectsData() +{ + QDomDocument doc; + QDomElement list = doc.createElement("list"); + list.setAttribute("name", m_title->text()); + doc.appendChild(list); + for (int j = 0; j < m_subWidgets.count(); j++) { + list.appendChild(doc.importNode(m_subWidgets.at(j)->effect(), true)); + } + return doc; +} diff --git a/src/effectstack/collapsiblegroup.h b/src/effectstack/collapsiblegroup.h index ee3b8f3..79e7a5c 100644 --- a/src/effectstack/collapsiblegroup.h +++ b/src/effectstack/collapsiblegroup.h @@ -68,7 +68,12 @@ public: bool isActive() const; void addGroupEffect(CollapsibleEffect *effect); void removeGroup(int ix, QVBoxLayout *layout); + /** @brief Return all effects in group. */ QList <CollapsibleEffect*> effects(); + /** @brief Return the editable title widget. */ + QWidget *title() const; + /** @brief Return the XML data describing all effects in group. */ + QDomDocument effectsData(); public slots: void slotEnable(bool enable); @@ -85,11 +90,10 @@ private slots: void slotRenameGroup(); private: - //QList <CollapsibleEffect *> m_subParamWidgets; + QList <CollapsibleEffect *> m_subWidgets; QMenu *m_menu; EffectInfo m_info; int m_index; - void updateGroupIndex(int groupIndex); MyEditableLabel *m_title; protected: @@ -104,7 +108,7 @@ signals: void deleteGroup(int); void changeGroupPosition(int, bool); void activateEffect(int); - void moveEffect(int current_pos, int new_pos, int groupIndex); + void moveEffect(int current_pos, int new_pos, int groupIndex, QString groupName); void addEffect(QDomElement e); void unGroup(CollapsibleGroup *); void groupRenamed(CollapsibleGroup *); diff --git a/src/effectstack/effectstackview2.cpp b/src/effectstack/effectstackview2.cpp index eb9a3b8..55827de 100644 --- a/src/effectstack/effectstackview2.cpp +++ b/src/effectstack/effectstackview2.cpp @@ -48,6 +48,7 @@ EffectStackView2::EffectStackView2(Monitor *monitor, QWidget *parent) : m_clipref(NULL), m_trackindex(-1), m_draggedEffect(NULL), + m_draggedGroup(NULL), m_groupIndex(0) { m_effectMetaInfo.trackMode = false; @@ -141,6 +142,7 @@ void EffectStackView2::setupListView(int ix) { blockSignals(true); m_draggedEffect = NULL; + m_draggedGroup = NULL; disconnect(m_effectMetaInfo.monitor, SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int))); m_effects.clear(); m_groupIndex = 0; @@ -181,10 +183,11 @@ void EffectStackView2::setupListView(int ix) if (group == NULL) { group = new CollapsibleGroup(effectInfo.groupIndex, i == 0, i == m_currentEffectList.count() - 1, effectInfo.groupName, m_ui.container->widget()); - connect(group, SIGNAL(moveEffect(int,int,int)), this, SLOT(slotMoveEffect(int,int,int))); + connect(group, SIGNAL(moveEffect(int,int,int,QString)), this, SLOT(slotMoveEffect(int,int,int,QString))); connect(group, SIGNAL(unGroup(CollapsibleGroup*)), this , SLOT(slotUnGroup(CollapsibleGroup*))); connect(group, SIGNAL(groupRenamed(CollapsibleGroup *)), this, SLOT(slotRenameGroup(CollapsibleGroup*))); vbox1->addWidget(group); + group->installEventFilter( this ); } if (effectInfo.groupIndex >= m_groupIndex) m_groupIndex = effectInfo.groupIndex + 1; } @@ -226,7 +229,7 @@ void EffectStackView2::setupListView(int ix) connect(currentEffect, SIGNAL(checkMonitorPosition(int)), this, SLOT(slotCheckMonitorPosition(int))); connect(currentEffect, SIGNAL(seekTimeline(int)), this , SLOT(slotSeekTimeline(int))); connect(currentEffect, SIGNAL(createGroup(int)), this , SLOT(slotCreateGroup(int))); - connect(currentEffect, SIGNAL(moveEffect(int,int,int)), this , SLOT(slotMoveEffect(int,int,int))); + connect(currentEffect, SIGNAL(moveEffect(int,int,int,QString)), this , SLOT(slotMoveEffect(int,int,int,QString))); connect(currentEffect, SIGNAL(addEffect(QDomElement)), this , SLOT(slotAddEffect(QDomElement))); //ui.title->setPixmap(icon.pixmap(QSize(12, 12))); @@ -276,6 +279,18 @@ bool EffectStackView2::eventFilter( QObject * o, QEvent * e ) e->accept(); return false; } + m_draggedGroup = qobject_cast<CollapsibleGroup*>(o); + if (m_draggedGroup) { + QMouseEvent *me = static_cast<QMouseEvent *>(e); + if (me->button() == Qt::LeftButton && (m_draggedGroup->framegroup->underMouse() || m_draggedGroup->title()->underMouse())) + m_clickPoint = me->globalPos(); + else { + m_clickPoint = QPoint(); + m_draggedGroup = NULL; + } + e->accept(); + return false; + } } if (e->type() == QEvent::MouseMove) { if (qobject_cast<CollapsibleEffect*>(o)) { @@ -295,26 +310,37 @@ bool EffectStackView2::eventFilter( QObject * o, QEvent * e ) void EffectStackView2::mouseMoveEvent(QMouseEvent * event) { - if (m_draggedEffect && (event->buttons() & Qt::LeftButton) && (m_clickPoint != QPoint()) && ((event->globalPos() - m_clickPoint).manhattanLength() >= QApplication::startDragDistance())) { - startDrag(); + if (m_draggedEffect || m_draggedGroup) { + if ((event->buttons() & Qt::LeftButton) && (m_clickPoint != QPoint()) && ((event->globalPos() - m_clickPoint).manhattanLength() >= QApplication::startDragDistance())) { + startDrag(); + } } } void EffectStackView2::mouseReleaseEvent(QMouseEvent * event) { m_draggedEffect = NULL; + m_draggedGroup = NULL; QWidget::mouseReleaseEvent(event); } void EffectStackView2::startDrag() { - QDrag *drag = new QDrag(this); // The data to be transferred by the drag and drop operation is contained in a QMimeData object - QDomElement effect = m_draggedEffect->effect().cloneNode().toElement(); - QPixmap pixmap = QPixmap::grabWidget(m_draggedEffect->title); - drag->setPixmap(pixmap); QDomDocument doc; - doc.appendChild(doc.importNode(effect, true)); + QPixmap pixmap; + if (m_draggedEffect) { + QDomElement effect = m_draggedEffect->effect().cloneNode().toElement(); + doc.appendChild(doc.importNode(effect, true)); + pixmap = QPixmap::grabWidget(m_draggedEffect->title); + } + else if (m_draggedGroup) { + doc = m_draggedGroup->effectsData(); + pixmap = QPixmap::grabWidget(m_draggedGroup->title()); + } + else return; + QDrag *drag = new QDrag(this); + drag->setPixmap(pixmap); QMimeData *mime = new QMimeData; QByteArray data; data.append(doc.toString().toUtf8()); @@ -598,14 +624,15 @@ void EffectStackView2::slotCreateGroup(int ix) CollapsibleGroup *group = new CollapsibleGroup(m_groupIndex, ix == 1, ix == m_currentEffectList.count() - 2, QString(), m_ui.container->widget()); m_groupIndex++; - connect(group, SIGNAL(moveEffect(int,int,int)), this , SLOT(slotMoveEffect(int,int,int))); + connect(group, SIGNAL(moveEffect(int,int,int,QString)), this , SLOT(slotMoveEffect(int,int,int,QString))); connect(group, SIGNAL(unGroup(CollapsibleGroup*)), this , SLOT(slotUnGroup(CollapsibleGroup*))); connect(group, SIGNAL(groupRenamed(CollapsibleGroup *)), this , SLOT(slotRenameGroup(CollapsibleGroup*))); l->insertWidget(groupPos, group); + group->installEventFilter( this ); group->addGroupEffect(effectToMove); } -void EffectStackView2::slotMoveEffect(int currentIndex, int newIndex, int groupIndex) +void EffectStackView2::slotMoveEffect(int currentIndex, int newIndex, int groupIndex, QString groupName) { CollapsibleEffect *effectToMove = getEffectByIndex(currentIndex); if (effectToMove == NULL) return; @@ -616,6 +643,7 @@ void EffectStackView2::slotMoveEffect(int currentIndex, int newIndex, int groupI EffectInfo effectinfo; effectinfo.fromString(oldeffect.attribute("kdenlive_info")); effectinfo.groupIndex = groupIndex; + effectinfo.groupName = groupName; neweffect.setAttribute("kdenlive_info", effectinfo.toString()); ItemInfo info; diff --git a/src/effectstack/effectstackview2.h b/src/effectstack/effectstackview2.h index a23a400..ffcebec 100644 --- a/src/effectstack/effectstackview2.h +++ b/src/effectstack/effectstackview2.h @@ -93,6 +93,9 @@ private: /** @brief The effect currently being dragged, NULL if no drag happening. */ CollapsibleEffect *m_draggedEffect; + /** @brief The effect currently being dragged, NULL if no drag happening. */ + CollapsibleGroup *m_draggedGroup; + /** @brief The current number of groups. */ int m_groupIndex; @@ -158,7 +161,7 @@ private slots: ** @param group the effect on which the effect was dropped ** @param lastEffectIndex the last effect index in the group, effect will be inserted after that index */ - void slotMoveEffect(int currentIndex, int newIndex, int groupIndex); + void slotMoveEffect(int currentIndex, int newIndex, int groupIndex, QString groupName = QString()); /** @brief Remove effects from a group */ void slotUnGroup(CollapsibleGroup* group); |