Commit 7ad1d886 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Fix active effect mess, resulting in incorrect monitor connection and crash

Related to #973
CCBUG: 424809
parent e4caa646
Pipeline #53880 passed with stage
in 10 minutes and 31 seconds
......@@ -433,15 +433,12 @@ void KeyframeWidget::addParameter(const QPersistentModelIndex &index)
paramWidget = geomWidget;
} else if (type == ParamType::Roto_spline) {
m_monitorHelper = new RotoHelper(pCore->getMonitor(m_model->monitorId), m_model, index, this);
connect(m_monitorHelper, &KeyframeMonitorHelper::updateKeyframeData, this, &KeyframeWidget::slotUpdateKeyframesFromMonitor, Qt::UniqueConnection);
m_neededScene = MonitorSceneType::MonitorSceneRoto;
} else {
if (m_model->getAssetId() == QLatin1String("frei0r.c0rners")) {
if (m_neededScene == MonitorSceneDefault && !m_monitorHelper) {
m_neededScene = MonitorSceneType::MonitorSceneCorners;
m_monitorHelper = new CornersHelper(pCore->getMonitor(m_model->monitorId), m_model, index, this);
connect(m_monitorHelper, &KeyframeMonitorHelper::updateKeyframeData, this, &KeyframeWidget::slotUpdateKeyframesFromMonitor,
Qt::UniqueConnection);
connect(this, &KeyframeWidget::addIndex, m_monitorHelper, &CornersHelper::addIndex);
} else {
if (type == ParamType::KeyframeParam) {
......@@ -489,8 +486,14 @@ void KeyframeWidget::slotInitMonitor(bool active)
void KeyframeWidget::connectMonitor(bool active)
{
if (m_monitorHelper) {
if (m_monitorHelper->connectMonitor(active) && m_model->isActive()) {
slotRefreshParams();
if (m_model->isActive()) {
connect(m_monitorHelper, &KeyframeMonitorHelper::updateKeyframeData, this, &KeyframeWidget::slotUpdateKeyframesFromMonitor, Qt::UniqueConnection);
if (m_monitorHelper->connectMonitor(active)) {
slotRefreshParams();
}
} else {
m_monitorHelper->connectMonitor(false);
disconnect(m_monitorHelper, &KeyframeMonitorHelper::updateKeyframeData, this, &KeyframeWidget::slotUpdateKeyframesFromMonitor);
}
}
Monitor *monitor = pCore->getMonitor(m_model->monitorId);
......
......@@ -100,10 +100,7 @@ void EffectStackModel::removeService(const std::shared_ptr<Mlt::Service> &servic
void EffectStackModel::removeCurrentEffect()
{
int ix = 0;
if (auto ptr = m_masterService.lock()) {
ix = ptr->get_int("kdenlive:activeeffect");
}
int ix = getActiveEffect();
if (ix < 0) {
return;
}
......@@ -116,10 +113,7 @@ void EffectStackModel::removeCurrentEffect()
void EffectStackModel::removeAllEffects(Fun &undo, Fun & redo)
{
QWriteLocker locker(&m_lock);
int current = -1;
if (auto srv = m_masterService.lock()) {
current = srv->get_int("kdenlive:activeeffect");
}
int current = getActiveEffect();
while (rootItem->childCount() > 0) {
std::shared_ptr<EffectItemModel> effect = std::static_pointer_cast<EffectItemModel>(rootItem->child(0));
int parentId = -1;
......@@ -177,13 +171,11 @@ void EffectStackModel::removeEffect(const std::shared_ptr<EffectItemModel> &effe
Q_ASSERT(m_allItems.count(effect->getId()) > 0);
int parentId = -1;
if (auto ptr = effect->parentItem().lock()) parentId = ptr->getId();
int current = 0;
if (auto srv = m_masterService.lock()) {
current = srv->get_int("kdenlive:activeeffect");
if (current >= rootItem->childCount() - 1) {
srv->set("kdenlive:activeeffect", --current);
}
int current = getActiveEffect();
if (current >= rootItem->childCount() - 1) {
current--;
}
setActiveEffect(current);
int currentRow = effect->row();
Fun undo = addItem_lambda(effect, parentId);
if (currentRow != rowCount() - 1) {
......@@ -213,7 +205,6 @@ void EffectStackModel::removeEffect(const std::shared_ptr<EffectItemModel> &effe
if (outFades < 0) {
roles << TimelineModel::FadeOutRole;
}
qDebug() << "// EMITTING UNDO DATA CHANGE: " << roles;
emit dataChanged(QModelIndex(), QModelIndex(), roles);
}
// TODO: only update if effect is fade or keyframe
......@@ -234,7 +225,6 @@ void EffectStackModel::removeEffect(const std::shared_ptr<EffectItemModel> &effe
} else if (outFades < 0) {
roles << TimelineModel::FadeOutRole;
}
qDebug() << "// EMITTING REDO DATA CHANGE: " << roles;
emit dataChanged(QModelIndex(), QModelIndex(), roles);
pCore->updateItemKeyframes(m_ownerId);
return true;
......@@ -518,9 +508,7 @@ bool EffectStackModel::appendEffect(const QString &effectId, bool makeCurrent)
});
int currentActive = getActiveEffect();
if (makeCurrent) {
if (auto srvPtr = m_masterService.lock()) {
srvPtr->set("kdenlive:activeeffect", rowCount());
}
setActiveEffect(rowCount());
}
bool res = redo();
if (res) {
......@@ -572,9 +560,7 @@ bool EffectStackModel::appendEffect(const QString &effectId, bool makeCurrent)
PUSH_LAMBDA(update_undo, undo);
PUSH_UNDO(undo, redo, i18n("Add effect %1", EffectsRepository::get()->getName(effectId)));
} else if (makeCurrent) {
if (auto srvPtr = m_masterService.lock()) {
srvPtr->set("kdenlive:activeeffect", currentActive);
}
setActiveEffect(currentActive);
}
return res;
}
......@@ -1088,9 +1074,27 @@ void EffectStackModel::importEffects(const std::weak_ptr<Mlt::Service> &service,
void EffectStackModel::setActiveEffect(int ix)
{
QWriteLocker locker(&m_lock);
int current = -1;
if (auto ptr = m_masterService.lock()) {
current = ptr->get_int("kdenlive:activeeffect");
ptr->set("kdenlive:activeeffect", ix);
}
// Desactivate previous effect
if (current > -1 && current != ix) {
std::shared_ptr<EffectItemModel> effect = std::static_pointer_cast<EffectItemModel>(rootItem->child(current));
if (effect) {
effect->setActive(false);
emit currentChanged(getIndexFromItem(effect), false);
}
}
// Activate new effect
if (ix > -1 && ix < rootItem->childCount()) {
std::shared_ptr<EffectItemModel> effect = std::static_pointer_cast<EffectItemModel>(rootItem->child(ix));
if (effect) {
effect->setActive(true);
emit currentChanged(getIndexFromItem(effect), true);
}
}
pCore->updateItemKeyframes(m_ownerId);
}
......@@ -1245,10 +1249,7 @@ double EffectStackModel::getFilterParam(const QString &effectId, const QString &
KeyframeModel *EffectStackModel::getEffectKeyframeModel()
{
if (rootItem->childCount() == 0) return nullptr;
int ix = 0;
if (auto ptr = m_masterService.lock()) {
ix = ptr->get_int("kdenlive:activeeffect");
}
int ix = getActiveEffect();
if (ix < 0 || ix >= rootItem->childCount()) {
return nullptr;
}
......@@ -1334,10 +1335,7 @@ bool EffectStackModel::isStackEnabled() const
bool EffectStackModel::addEffectKeyFrame(int frame, double normalisedVal)
{
if (rootItem->childCount() == 0) return false;
int ix = 0;
if (auto ptr = m_masterService.lock()) {
ix = ptr->get_int("kdenlive:activeeffect");
}
int ix = getActiveEffect();
if (ix < 0) {
return false;
}
......@@ -1352,10 +1350,7 @@ bool EffectStackModel::addEffectKeyFrame(int frame, double normalisedVal)
bool EffectStackModel::removeKeyFrame(int frame)
{
if (rootItem->childCount() == 0) return false;
int ix = 0;
if (auto ptr = m_masterService.lock()) {
ix = ptr->get_int("kdenlive:activeeffect");
}
int ix = getActiveEffect();
if (ix < 0) {
return false;
}
......@@ -1367,10 +1362,7 @@ bool EffectStackModel::removeKeyFrame(int frame)
bool EffectStackModel::updateKeyFrame(int oldFrame, int newFrame, QVariant normalisedVal)
{
if (rootItem->childCount() == 0) return false;
int ix = 0;
if (auto ptr = m_masterService.lock()) {
ix = ptr->get_int("kdenlive:activeeffect");
}
int ix = getActiveEffect();
if (ix < 0) {
return false;
}
......@@ -1385,10 +1377,7 @@ bool EffectStackModel::updateKeyFrame(int oldFrame, int newFrame, QVariant norma
bool EffectStackModel::hasKeyFrame(int frame)
{
if (rootItem->childCount() == 0) return false;
int ix = 0;
if (auto ptr = m_masterService.lock()) {
ix = ptr->get_int("kdenlive:activeeffect");
}
int ix = getActiveEffect();
if (ix < 0) {
return false;
}
......
......@@ -190,6 +190,8 @@ signals:
void enabledStateChanged();
/** @brief: The master effect stack zones changed, update */
void updateMasterZones();
/** @brief: Currently active effect changed */
void currentChanged(QModelIndex ix, bool active);
};
#endif
......@@ -189,7 +189,7 @@ CollapsibleEffectView::CollapsibleEffectView(const std::shared_ptr<EffectItemMod
connect(m_view, &AssetParameterView::activateEffect, this, [this]() {
if (!decoframe->property("active").toBool()) {
// Activate effect if not already active
emit activateEffect(m_model);
emit activateEffect(m_model->row());
}
});
connect(m_view, &AssetParameterView::updateHeight, this, &CollapsibleEffectView::updateHeight);
......@@ -391,7 +391,6 @@ void CollapsibleEffectView::slotActivateEffect(bool active)
{
// m_colorIcon->setEnabled(active);
// bool active = ix.row() == m_model->row();
m_model->setActive(active);
decoframe->setProperty("active", active);
decoframe->setStyleSheet(decoframe->styleSheet());
if (active) {
......@@ -410,7 +409,7 @@ void CollapsibleEffectView::mousePressEvent(QMouseEvent *e)
m_dragStart = e->globalPos();
if (!decoframe->property("active").toBool()) {
// Activate effect if not already active
emit activateEffect(m_model);
emit activateEffect(m_model->row());
}
QWidget::mousePressEvent(e);
}
......@@ -450,7 +449,7 @@ void CollapsibleEffectView::slotDisable(bool disable)
std::static_pointer_cast<AbstractEffectItem>(m_model)->markEnabled(effectName, !disable);
pCore->getMonitor(m_model->monitorId)->slotShowEffectScene(needsMonitorEffectScene());
emit m_view->initKeyframeView(!disable);
emit activateEffect(m_model);
emit activateEffect(m_model->row());
}
void CollapsibleEffectView::updateScene()
......
......@@ -172,7 +172,7 @@ signals:
void importClipKeyframes(GraphicsRectItem, ItemInfo, QDomElement, const QMap<QString, QString> &keyframes = QMap<QString, QString>());
void switchHeight(std::shared_ptr<EffectItemModel> model, int height);
void startDrag(QPixmap, std::shared_ptr<EffectItemModel> effectModel);
void activateEffect(std::shared_ptr<EffectItemModel> effectModel);
void activateEffect(int row);
void showEffectZone(ObjectId id, QPair <int, int>inOut, bool checked);
void refresh();
/** @brief Requests saving the full effect stack. */
......
......@@ -170,10 +170,7 @@ void EffectStackView::dropEvent(QDropEvent *event)
} else {
if (m_model->appendEffect(effectId) && m_model->rowCount() > 0) {
added = true;
std::shared_ptr<AbstractEffectItem> item = m_model->getEffectStackRow(m_model->rowCount() - 1);
if (item) {
slotActivateEffect(std::static_pointer_cast<EffectItemModel>(item));
}
m_model->setActiveEffect(m_model->rowCount() - 1);
}
}
if (!added) {
......@@ -205,6 +202,13 @@ void EffectStackView::setModel(std::shared_ptr<EffectStackModel> model, const QS
m_scrollTimer.start();
connect(m_model.get(), &EffectStackModel::dataChanged, this, &EffectStackView::refresh);
connect(m_model.get(), &EffectStackModel::enabledStateChanged, this, &EffectStackView::changeEnabledState);
connect(m_model.get(), &EffectStackModel::currentChanged, this, [=](QModelIndex ix, bool active) {
m_effectsTree->setCurrentIndex(ix);
CollapsibleEffectView *w = static_cast<CollapsibleEffectView *>(m_effectsTree->indexWidget(ix));
if (w) {
w->slotActivateEffect(active);
}
});
connect(this, &EffectStackView::removeCurrentEffect, m_model.get(), &EffectStackModel::removeCurrentEffect);
// m_builtStack->setModel(model, stackOwner());
}
......@@ -259,13 +263,14 @@ void EffectStackView::loadEffects()
connect(view, &CollapsibleEffectView::switchHeight, this, &EffectStackView::slotAdjustDelegate, Qt::DirectConnection);
connect(view, &CollapsibleEffectView::startDrag, this, &EffectStackView::slotStartDrag);
connect(view, &CollapsibleEffectView::saveStack, this, &EffectStackView::slotSaveStack);
connect(view, &CollapsibleEffectView::activateEffect, this, [=](int row) {
m_model->setActiveEffect(row);
});
connect(view, &CollapsibleEffectView::createGroup, m_model.get(), &EffectStackModel::slotCreateGroup);
connect(view, &CollapsibleEffectView::activateEffect, this, &EffectStackView::slotActivateEffect);
connect(view, &CollapsibleEffectView::showEffectZone, pCore.get(), &Core::showEffectZone);
connect(this, &EffectStackView::blockWheenEvent, view, &CollapsibleEffectView::blockWheenEvent);
connect(view, &CollapsibleEffectView::seekToPos, this, [this](int pos) {
// at this point, the effects returns a pos relative to the clip. We need to convert it to a global time
qDebug()<<"==== CEFFECTSTACK SEEK TO POS: "<<pos;
int clipIn = pCore->getItemPosition(m_model->getOwnerId());
emit seekToPos(pos + clipIn);
});
......@@ -277,30 +282,32 @@ void EffectStackView::loadEffects()
}
});
QModelIndex ix = m_model->getIndexFromItem(effectModel);
if (active == i) {
effectModel->setActive(true);
activeIndex = ix;
}
m_effectsTree->setIndexWidget(ix, view);
auto *del = static_cast<WidgetDelegate *>(m_effectsTree->itemDelegate(ix));
del->setHeight(ix, view->height());
view->buttonUp->setEnabled(i > 0);
view->buttonDown->setEnabled(i < max - 1);
if (i == active) {
activeIndex = ix;
m_effectsTree->setCurrentIndex(activeIndex);
}
}
if (!hasLift) {
updateTreeHeight();
}
if (activeIndex.isValid()) {
doActivateEffect(active, activeIndex, true);
if (active > 0) {
if (hasLift) {
// Some effects have a complex timed layout, so we need to wait a bit before getting the correct position for the effect
QTimer::singleShot(100, this, &EffectStackView::slotFocusEffect);
} else {
slotFocusEffect();
}
m_effectsTree->setCurrentIndex(activeIndex);
CollapsibleEffectView *w = static_cast<CollapsibleEffectView *>(m_effectsTree->indexWidget(activeIndex));
if (w) {
w->slotActivateEffect(true);
}
}
if (hasLift) {
// Some effects have a complex timed layout, so we need to wait a bit before getting the correct position for the effect
QTimer::singleShot(100, this, &EffectStackView::slotFocusEffect);
} else {
slotFocusEffect();
}
qDebug() << "MUTEX UNLOCK!!!!!!!!!!!! loadEffects";
}
......@@ -327,15 +334,6 @@ void EffectStackView::updateTreeHeight()
}
}
void EffectStackView::slotActivateEffect(const std::shared_ptr<EffectItemModel> &effectModel)
{
qDebug() << "MUTEX LOCK!!!!!!!!!!!! slotactivateeffect: " << effectModel->row();
QMutexLocker lock(&m_mutex);
QModelIndex activeIx = m_model->getIndexFromItem(effectModel);
doActivateEffect(effectModel->row(), activeIx);
qDebug() << "MUTEX UNLOCK!!!!!!!!!!!! slotactivateeffect";
}
void EffectStackView::slotStartDrag(const QPixmap &pix, const std::shared_ptr<EffectItemModel> &effectModel)
{
auto *drag = new QDrag(this);
......@@ -466,31 +464,6 @@ void EffectStackView::switchCollapsed()
}
}
void EffectStackView::doActivateEffect(int row, QModelIndex activeIx, bool force)
{
int currentActive = m_model->getActiveEffect();
if (row == currentActive && !force) {
// Effect is already active
return;
}
if (row != currentActive && currentActive > -1 && currentActive < m_model->rowCount()) {
auto item = m_model->getEffectStackRow(currentActive);
if (item) {
QModelIndex ix = m_model->getIndexFromItem(item);
CollapsibleEffectView *w = static_cast<CollapsibleEffectView *>(m_effectsTree->indexWidget(ix));
if (w) {
w->slotActivateEffect(false);
}
}
}
m_effectsTree->setCurrentIndex(activeIx);
m_model->setActiveEffect(row);
CollapsibleEffectView *w = static_cast<CollapsibleEffectView *>(m_effectsTree->indexWidget(activeIx));
if (w) {
w->slotActivateEffect(true);
}
}
void EffectStackView::slotFocusEffect()
{
emit scrollView(m_effectsTree->visualRect(m_effectsTree->currentIndex()));
......
......@@ -102,10 +102,8 @@ private slots:
void refresh(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
void slotAdjustDelegate(const std::shared_ptr<EffectItemModel> &effectModel, int height);
void slotStartDrag(const QPixmap &pix, const std::shared_ptr<EffectItemModel> &effectModel);
void slotActivateEffect(const std::shared_ptr<EffectItemModel> &effectModel);
void loadEffects();
void updateTreeHeight();
void doActivateEffect(int row, QModelIndex ix, bool force = false);
void slotFocusEffect();
/** @brief Save current effect stack
*/
......
......@@ -141,8 +141,6 @@ Item {
function convertPoint(p)
{
console.log('FRAME: ', frame.x)
console.log('P: ', p.x)
var x = frame.x + p.x * root.scalex
var y = frame.y + p.y * root.scaley
return Qt.point(x,y);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment