//virtual
void ClipItem::dropEvent(QGraphicsSceneDragDropEvent * event)
{
- const QString effects = QString::fromUtf8(event->mimeData()->data("kdenlive/effectslist"));
- QDomDocument doc;
- doc.setContent(effects, true);
- const QDomElement e = doc.documentElement();
- if (scene() && !scene()->views().isEmpty()) {
- event->accept();
+ if (event->proposedAction() == Qt::CopyAction && scene() && !scene()->views().isEmpty()) {
+ const QString effects = QString::fromUtf8(event->mimeData()->data("kdenlive/effectslist"));
+ event->acceptProposedAction();
+ QDomDocument doc;
+ doc.setContent(effects, true);
+ const QDomElement e = doc.documentElement();
CustomTrackView *view = (CustomTrackView *) scene()->views()[0];
if (view) view->slotAddEffect(e, m_info.startPos, track());
}
+ else return;
}
//virtual
void ClipItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
if (isItemLocked()) event->setAccepted(false);
- else event->setAccepted(event->mimeData()->hasFormat("kdenlive/effectslist"));
+ else if (event->mimeData()->hasFormat("kdenlive/effectslist")) {
+ event->acceptProposedAction();
+ } else event->setAccepted(false);
}
void ClipItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
void CustomTrackView::dragEnterEvent(QDragEnterEvent * event)
{
if (insertDropClips(event->mimeData(), event->pos())) {
- event->acceptProposedAction();
+ if (event->source() == this) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ } else {
+ event->setDropAction(Qt::MoveAction);
+ event->acceptProposedAction();
+ }
} else QGraphicsView::dragEnterEvent(event);
}
if (itemList.at(i)->type() == AVWIDGET) {
ClipItem *clip = static_cast<ClipItem *>(itemList.at(i));
if (!clip->isSelected()) {
- clearSelection();
+ clearSelection(false);
clip->setSelected(true);
}
clip->setSelectedEffect(clip->effectsCount() - 1);
- emit clipItemSelected(clip, clip->effectsCount() - 1);
+ emit clipItemSelected(clip, clip->selectedEffectIndex());
break;
}
}
splitAudio();
}
-void CustomTrackView::clearSelection()
+void CustomTrackView::clearSelection(bool emitInfo)
{
resetSelectionGroup();
scene()->clearSelection();
m_dragItem = NULL;
- emit clipItemSelected(NULL);
+ if (emitInfo) emit clipItemSelected(NULL);
}
void CustomTrackView::updatePalette()
*
* Inserts at the position of timeline cursor and selected track. */
void insertClipCut(DocClipBase *clip, int in, int out);
- void clearSelection();
+ void clearSelection(bool emitInfo = true);
void editItemDuration();
void buildGuidesMenu(QMenu *goMenu) const;
/** update the timeline objects when palette changes */
connect(m_dragVal, SIGNAL(inTimeline(int)), this, SIGNAL(setInTimeline(int)));
}
+DoubleParameterWidget::~DoubleParameterWidget()
+{
+ delete m_dragVal;
+ if (m_commentLabel) delete m_commentLabel;
+}
+
int DoubleParameterWidget::spinSize()
{
return m_dragVal->spinSize();
class QLabel;
-class QSlider;
-class QSpinBox;
class DragValue;
/**
* @param suffix (optional) Suffix to display in spinbox
* @param parent (optional) Parent Widget */
DoubleParameterWidget(const QString &name, double value, double min, double max, double defaultValue, const QString &comment, int id, const QString suffix = QString(), int decimals = 0, QWidget* parent = 0);
+ ~DoubleParameterWidget();
/** @brief Gets the parameter's value. */
double getValue();
void slotSetValue(double value, bool final);
private:
- QLabel *m_name;
- QSlider *m_slider;
- QSpinBox *m_spinBox;
DragValue *m_dragVal;
QLabel *m_commentLabel;
if (m_intEdit) delete m_intEdit;
if (m_doubleEdit) delete m_doubleEdit;
delete m_menu;
- delete m_scale;
- delete m_directUpdate;
+ //delete m_scale;
+ //delete m_directUpdate;
}
int DragValue::spinSize()
setFocusPolicy(Qt::StrongFocus);
}
+
CollapsibleEffect::CollapsibleEffect(QDomElement effect, QDomElement original_effect, ItemInfo info, int ix, EffectMetaInfo *metaInfo, bool lastEffect, QWidget * parent) :
QWidget(parent),
m_paramWidget(NULL),
frame->setBackgroundRole(QPalette::Midlight);
frame->setAutoFillBackground(true);
setFont(KGlobalSettings::smallestReadableFont());
- QDomElement namenode = m_effect.firstChildElement("name");
- if (namenode.isNull()) return;
- QString type = m_effect.attribute("type", QString());
- KIcon icon;
- if (type == "audio") icon = KIcon("kdenlive-show-audio");
- else if (m_effect.attribute("tag") == "region") icon = KIcon("kdenlive-mask-effect");
- else if (type == "custom") icon = KIcon("kdenlive-custom-effect");
- else icon = KIcon("kdenlive-show-video");
buttonUp->setIcon(KIcon("go-up"));
buttonUp->setToolTip(i18n("Move effect up"));
//checkAll->setToolTip(i18n("Enable/Disable all effects"));
//buttonShowComments->setIcon(KIcon("help-about"));
//buttonShowComments->setToolTip(i18n("Show additional information for the parameters"));
-
+ QDomElement namenode = m_effect.firstChildElement("name");
+ if (namenode.isNull()) return;
title->setText(i18n(namenode.text().toUtf8().data()));
+ QString type = m_effect.attribute("type", QString());
+ KIcon icon;
+ if (type == "audio") icon = KIcon("kdenlive-show-audio");
+ else if (m_effect.attribute("tag") == "region") icon = KIcon("kdenlive-mask-effect");
+ else if (type == "custom") icon = KIcon("kdenlive-custom-effect");
+ else icon = KIcon("kdenlive-show-video");
title->setIcon(icon);
- QMenu *menu = new QMenu;
- menu->addAction(KIcon("view-refresh"), i18n("Reset effect"), this, SLOT(slotResetEffect()));
- menu->addAction(KIcon("document-save"), i18n("Save effect"), this, SLOT(slotSaveEffect()));
- title->setMenu(menu);
+
+ m_menu = new QMenu;
+ m_menu->addAction(KIcon("view-refresh"), i18n("Reset effect"), this, SLOT(slotResetEffect()));
+ m_menu->addAction(KIcon("document-save"), i18n("Save effect"), this, SLOT(slotSaveEffect()));
+ title->setMenu(m_menu);
if (m_effect.attribute("disable") == "1") {
enabledBox->setCheckState(Qt::Unchecked);
cb->installEventFilter( this );
cb->setFocusPolicy( Qt::StrongFocus );
}
-
}
CollapsibleEffect::~CollapsibleEffect()
{
if (m_paramWidget) delete m_paramWidget;
+ delete m_menu;
}
bool CollapsibleEffect::eventFilter( QObject * o, QEvent * e )
{
- if(e->type() == QEvent::Wheel) {
+ if (e->type() == QEvent::Wheel) {
+ QWheelEvent *we = static_cast<QWheelEvent *>(e);
+ if (we->modifiers() != Qt::NoModifier) {
+ e->accept();
+ return false;
+ }
if (qobject_cast<QAbstractSpinBox*>(o)) {
if(qobject_cast<QAbstractSpinBox*>(o)->focusPolicy() == Qt::WheelFocus)
{
return QWidget::eventFilter(o, e);
}
+QDomElement CollapsibleEffect::effect() const
+{
+ return m_effect;
+}
void CollapsibleEffect::setActive(bool activate)
{
ParameterContainer::~ParameterContainer()
{
- clearLayout(m_vbox);
+ //clearLayout(m_vbox);
delete m_vbox;
}
#include "effectstackedit.h"
#include <QDomElement>
+#include <QToolButton>
class QFrame;
class Monitor;
virtual bool eventFilter( QObject * o, QEvent * e );
/** @brief Update effect GUI to reflect parameted changes. */
void updateWidget(ItemInfo info, int index, QDomElement effect, EffectMetaInfo *metaInfo);
+ QDomElement effect() const;
public slots:
void slotSyncEffectsPos(int pos);
QDomElement m_effect;
QDomElement m_original_effect;
QList <QDomElement> m_subEffects;
- bool m_lastEffect; int m_in;
+ bool m_lastEffect;
+ int m_in;
int m_out;
bool m_active;
+ QMenu *m_menu;
+ QPoint m_clickPoint;
protected:
virtual void mouseDoubleClickEvent ( QMouseEvent * event );
EffectStackView2::EffectStackView2(Monitor *monitor, QWidget *parent) :
QWidget(parent),
m_clipref(NULL),
- m_trackindex(-1)
+ m_trackindex(-1),
+ m_draggedEffect(NULL)
{
m_effectMetaInfo.trackMode = false;
m_effectMetaInfo.monitor = monitor;
m_effects.clear();
QWidget *view = m_ui.container->takeWidget();
if (view) {
- if (view->layout()) clearLayout(view->layout());
delete view;
}
m_ui.checkAll->setToolTip(QString());
setupListView(0);
}
-void EffectStackView2::clearLayout(QLayout *layout)
-{
- QLayoutItem *item;
- while((item = layout->takeAt(0))) {
- if (item->layout()) {
- clearLayout(item->layout());
- delete item->layout();
- }
- if (item->widget()) {
- delete item->widget();
- }
- delete item;
- }
-}
void EffectStackView2::setupListView(int ix)
{
//TODO: clear list
- kDebug()<<"++++++++++++++++++++++++++++++++ setup: "<<children().count();
-
blockSignals(true);
+ m_draggedEffect = NULL;
disconnect(m_effectMetaInfo.monitor, SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
m_effects.clear();
QWidget *view = m_ui.container->takeWidget();
if (view) {
- if (view->layout()) clearLayout(view->layout());
delete view;
+ //view->deleteLater();
}
blockSignals(false);
view = new QWidget(m_ui.container);
CollapsibleEffect *currentEffect = new CollapsibleEffect(d, m_currentEffectList.at(i), info, i, &m_effectMetaInfo, i == m_currentEffectList.count() - 1, view);
m_effects.append(currentEffect);
vbox1->addWidget(currentEffect);
+
+ // Check drag & drop
+ currentEffect->installEventFilter( this );
+
connect(currentEffect, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int)), this , SLOT(slotUpdateEffectParams(const QDomElement, const QDomElement, int)));
connect(currentEffect, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QString)), this , SLOT(slotStartFilterJob(QString,QString,QString,QString,QString,QString)));
connect(currentEffect, SIGNAL(deleteEffect(const QDomElement, int)), this , SLOT(slotDeleteEffect(const QDomElement, int)));
connect(m_effectMetaInfo.monitor, SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
}
+bool EffectStackView2::eventFilter( QObject * o, QEvent * e )
+{
+ // Check if user clicked in an effect's top bar to start dragging it
+ if (e->type() == QEvent::MouseButtonPress) {
+ m_draggedEffect = qobject_cast<CollapsibleEffect*>(o);
+ if (m_draggedEffect) {
+ QMouseEvent *me = static_cast<QMouseEvent *>(e);
+ if (me->button() == Qt::LeftButton && (m_draggedEffect->frame->underMouse() || m_draggedEffect->title->underMouse()))
+ m_clickPoint = me->pos();
+ else {
+ m_clickPoint = QPoint();
+ m_draggedEffect = NULL;
+ }
+ e->accept();
+ return false;
+ }
+ }
+ if (e->type() == QEvent::MouseMove) {
+ if (qobject_cast<CollapsibleEffect*>(o)) {
+ CollapsibleEffect *effect = qobject_cast<CollapsibleEffect*>(o);
+ QMouseEvent *me = static_cast<QMouseEvent *>(e);
+ if (me->buttons() != Qt::LeftButton) {
+ e->accept();
+ return false;
+ }
+ else {
+ e->ignore();
+ return true;
+ }
+ }
+ }
+ return QWidget::eventFilter(o, e);
+}
+
+void EffectStackView2::mouseMoveEvent(QMouseEvent * event)
+{
+ if (m_draggedEffect && (event->buttons() & Qt::LeftButton) && (m_clickPoint != QPoint()) && ((event->pos() - m_clickPoint).manhattanLength() >= QApplication::startDragDistance()))
+ startDrag();
+}
+
+void EffectStackView2::mouseReleaseEvent(QMouseEvent * event)
+{
+ m_draggedEffect = 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);
+ effect.setAttribute("kdenlive_ix", 0);
+ QDomDocument doc;
+ doc.appendChild(doc.importNode(effect, true));
+ QMimeData *mime = new QMimeData;
+ QByteArray data;
+ data.append(doc.toString().toUtf8());
+ mime->setData("kdenlive/effectslist", data);
+
+ // Assign ownership of the QMimeData object to the QDrag object.
+ drag->setMimeData(mime);
+ // Start the drag and drop operation
+ drag->exec(Qt::CopyAction);// | Qt::MoveAction);
+}
+
void EffectStackView2::slotUpdateEffectState(bool disable, int index)
{
void EffectStackView2::slotSetCurrentEffect(int ix)
{
- if (ix != m_clipref->selectedEffectIndex())
+ if (m_clipref && ix != m_clipref->selectedEffectIndex())
m_clipref->setSelectedEffect(ix);
for (int i = 0; i < m_effects.count(); i++) {
m_effects.at(i)->setActive(i == ix);
if (!dom.isNull()) {
dom.setAttribute("kdenlive_ix", old.attribute("kdenlive_ix"));
//TODO: Track mode
- /*if (m_trackMode) {
+ if (m_effectMetaInfo.trackMode) {
EffectsList::setParameter(dom, "in", QString::number(0));
EffectsList::setParameter(dom, "out", QString::number(m_trackInfo.duration));
ItemInfo info;
info.cropStart = GenTime(0);
info.startPos = GenTime(-1);
info.track = 0;
- m_effectedit->transferParamDesc(dom, info);
- emit updateEffect(NULL, m_trackindex, old, dom, activeRow);
- } else*/ {
+ m_effects.at(ix)->updateWidget(info, ix, dom, &m_effectMetaInfo);
+ emit updateEffect(NULL, m_trackindex, old, dom, ix);
+ } else {
m_clipref->initEffect(dom);
m_effects.at(ix)->updateWidget(m_clipref->info(), ix, dom, &m_effectMetaInfo);
//m_effectedit->transferParamDesc(dom, m_clipref->info());
/** @brief Tells the effect editor to update its timecode format. */
void updateTimecodeFormat();
+
+ /** @brief Used to trigger drag effects. */
+ virtual bool eventFilter( QObject * o, QEvent * e );
+protected:
+ virtual void mouseMoveEvent(QMouseEvent * event);
+ virtual void mouseReleaseEvent(QMouseEvent * event);
+
private:
Ui::EffectStack2_UI m_ui;
ClipItem* m_clipref;
QList <CollapsibleEffect*> m_effects;
EffectsList m_currentEffectList;
+
+ /** @brief Contains infos about effect like is it a track effect, which monitor displays it,... */
EffectMetaInfo m_effectMetaInfo;
+
+ /** @brief The last mouse click position, used to detect drag events. */
+ QPoint m_clickPoint;
/** @brief The track index of currently edited track. */
int m_trackindex;
/** If in track mode: Info of the edited track to be able to access its duration. */
TrackInfo m_trackInfo;
+
+ /** @brief The effect currently being dragged, NULL if no drag happening. */
+ CollapsibleEffect *m_draggedEffect;
/** @brief Sets the list of effects according to the clip's effect list.
* @param ix Number of the effect to preselect */
void setupListView(int ix);
- void clearLayout(QLayout *layout);
+ /** @brief Build the drag info and start it. */
+ void startDrag();
public slots:
/** @brief Sets the clip whose effect list should be managed.
QStringList list = QString(event->mimeData()->data("kdenlive/clip")).split(';');
emit addClipCut(list.at(0), list.at(1).toInt(), list.at(2).toInt());
}
- event->acceptProposedAction();
+ if (event->source() == this) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ } else {
+ event->acceptProposedAction();
+ }
QTreeWidget::dropEvent(event);
}
drag->setMimeData(mimeData);
drag->setPixmap(clickItem->data(0, Qt::DecorationRole).value<QPixmap>());
drag->setHotSpot(QPoint(0, 50));
- drag->exec();
+ drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
}
} else {
if (it && (it->flags() & Qt::ItemIsDragEnabled)) {
drag->setMimeData(mimeData);
drag->setPixmap(it->data(0, Qt::DecorationRole).value<QPixmap>());
drag->setHotSpot(QPoint(0, 50));
- drag->exec();
+ drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
}
//event->accept();
}
<rect>
<x>0</x>
<y>0</y>
- <width>176</width>
- <height>38</height>
+ <width>185</width>
+ <height>42</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
+ <property name="verticalSpacing">
+ <number>0</number>
+ </property>
<property name="margin">
<number>0</number>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <property name="horizontalSpacing">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
<number>0</number>
</property>
- <property name="margin">
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
- <item row="0" column="2">
- <widget class="QToolButton" name="title">
+ <item>
+ <widget class="QToolButton" name="collapseButton">
<property name="text">
- <string/>
- </property>
- <property name="popupMode">
- <enum>QToolButton::MenuButtonPopup</enum>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextBesideIcon</enum>
+ <string>...</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
<property name="arrowType">
- <enum>Qt::NoArrow</enum>
+ <enum>Qt::DownArrow</enum>
</property>
</widget>
</item>
- <item row="0" column="1">
+ <item>
<widget class="QCheckBox" name="enabledBox">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="0" column="4">
- <widget class="QToolButton" name="buttonUp">
+ <item>
+ <widget class="QToolButton" name="title">
<property name="text">
<string>...</string>
</property>
+ <property name="popupMode">
+ <enum>QToolButton::MenuButtonPopup</enum>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
- <item row="0" column="3">
+ <item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</spacer>
</item>
- <item row="0" column="5">
- <widget class="QToolButton" name="buttonDown">
+ <item>
+ <widget class="QToolButton" name="buttonUp">
<property name="text">
<string>...</string>
</property>
</property>
</widget>
</item>
- <item row="0" column="0">
- <widget class="QToolButton" name="collapseButton">
+ <item>
+ <widget class="QToolButton" name="buttonDown">
<property name="text">
<string>...</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
- <property name="arrowType">
- <enum>Qt::DownArrow</enum>
- </property>
</widget>
</item>
- <item row="0" column="6">
+ <item>
<widget class="QToolButton" name="buttonDel">
<property name="text">
<string>...</string>