Fix crash and broken undo/redo with lift/gamma/gain effect. Fixes #172

parent be8345a2
Pipeline #2973 passed with stage
in 20 minutes and 24 seconds
......@@ -11,22 +11,22 @@
<parameter type="colorwheel" name="lift_b" default="0" min="0" max="500" factor="100">
<name>Lift: Blue</name>
</parameter>
<parameter type="double" name="gamma_r" default="1" min="0" max="500" factor="100">
<parameter type="colorwheel" name="gamma_r" default="1" min="0" max="500" factor="100">
<name>Gamma: Red</name>
</parameter>
<parameter type="double" name="gamma_g" default="1" min="0" max="500" factor="100">
<parameter type="colorwheel" name="gamma_g" default="1" min="0" max="500" factor="100">
<name>Gamma: Green</name>
</parameter>
<parameter type="double" name="gamma_b" default="1" min="0" max="500" factor="100">
<parameter type="colorwheel" name="gamma_b" default="1" min="0" max="500" factor="100">
<name>Gamma: Blue</name>
</parameter>
<parameter type="double" name="gain_r" default="1" min="0" max="500" factor="100">
<parameter type="colorwheel" name="gain_r" default="1" min="0" max="500" factor="100">
<name>Gain: Red</name>
</parameter>
<parameter type="double" name="gain_g" default="1" min="0" max="500" factor="100">
<parameter type="colorwheel" name="gain_g" default="1" min="0" max="500" factor="100">
<name>Gain: Green</name>
</parameter>
<parameter type="double" name="gain_b" default="1" min="0" max="500" factor="100">
<parameter type="colorwheel" name="gain_b" default="1" min="0" max="500" factor="100">
<name>Gain: Blue</name>
</parameter>
</effect>
......@@ -73,6 +73,67 @@ bool AssetCommand::mergeWith(const QUndoCommand *other)
return true;
}
AssetMultiCommand::AssetMultiCommand(const std::shared_ptr<AssetParameterModel> &model, const QList <QModelIndex> indexes, const QStringList values, QUndoCommand *parent)
: QUndoCommand(parent)
, m_model(model)
, m_indexes(indexes)
, m_values(values)
, m_updateView(false)
, m_stamp(QTime::currentTime())
{
QLocale locale;
qDebug()<<"CREATING MULTIPLE COMMAND!!!\nVALUES: "<<m_values;
m_name = m_model->data(indexes.first(), AssetParameterModel::NameRole).toString();
const QString id = model->getAssetId();
if (EffectsRepository::get()->exists(id)) {
setText(i18n("Edit %1", EffectsRepository::get()->getName(id)));
} else if (TransitionsRepository::get()->exists(id)) {
setText(i18n("Edit %1", TransitionsRepository::get()->getName(id)));
}
for (QModelIndex ix : m_indexes) {
QVariant previousVal = m_model->data(ix, AssetParameterModel::ValueRole);
m_oldValues << (previousVal.type() == QVariant::Double ? locale.toString(previousVal.toDouble()) : previousVal.toString());
}
}
void AssetMultiCommand::undo()
{
int indx = 0;
int max = m_indexes.size() - 1;
for (const QModelIndex &ix : m_indexes) {
m_model->setParameter(m_model->data(ix, AssetParameterModel::NameRole).toString(), m_oldValues.at(indx), indx == max, ix);
indx++;
}
}
// virtual
void AssetMultiCommand::redo()
{
int indx = 0;
int max = m_indexes.size() - 1;
for (const QModelIndex &ix : m_indexes) {
m_model->setParameter(m_model->data(ix, AssetParameterModel::NameRole).toString(), m_values.at(indx), m_updateView && indx == max, ix);
indx++;
}
m_updateView = true;
}
// virtual
int AssetMultiCommand::id() const
{
return 1;
}
// virtual
bool AssetMultiCommand::mergeWith(const QUndoCommand *other)
{
if (other->id() != id() || static_cast<const AssetMultiCommand *>(other)->m_indexes != m_indexes ||
m_stamp.msecsTo(static_cast<const AssetMultiCommand *>(other)->m_stamp) > 3000) {
return false;
}
m_values = static_cast<const AssetMultiCommand *>(other)->m_values;
m_stamp = static_cast<const AssetMultiCommand *>(other)->m_stamp;
return true;
}
AssetKeyframeCommand::AssetKeyframeCommand(const std::shared_ptr<AssetParameterModel> &model, const QModelIndex &index, QVariant value, GenTime pos,
QUndoCommand *parent)
: QUndoCommand(parent)
......
......@@ -46,6 +46,25 @@ private:
QTime m_stamp;
};
class AssetMultiCommand : public QUndoCommand
{
public:
AssetMultiCommand(const std::shared_ptr<AssetParameterModel> &model, const QList<QModelIndex> indexes, const QStringList values, QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
int id() const override;
bool mergeWith(const QUndoCommand *other) override;
private:
std::shared_ptr<AssetParameterModel> m_model;
QList<QModelIndex> m_indexes;
QStringList m_values;
QString m_name;
QStringList m_oldValues;
bool m_updateView;
QTime m_stamp;
};
class AssetKeyframeCommand : public QUndoCommand
{
public:
......
......@@ -85,6 +85,7 @@ void AssetParameterView::setModel(const std::shared_ptr<AssetParameterModel> &mo
// Special case, the colorwheel widget manages several parameters
QModelIndex index = model->index(0, 0);
auto w = AbstractParamWidget::construct(model, index, frameSize, this);
connect(w, &AbstractParamWidget::valuesChanged, this, &AssetParameterView::commitMultipleChanges);
connect(w, &AbstractParamWidget::valueChanged, this, &AssetParameterView::commitChanges);
m_lay->addWidget(w);
m_widgets.push_back(w);
......@@ -158,6 +159,18 @@ void AssetParameterView::commitChanges(const QModelIndex &index, const QString &
}
}
void AssetParameterView::commitMultipleChanges(const QList <QModelIndex> indexes, const QStringList &values, bool storeUndo)
{
// Warning: please note that some widgets (for example keyframes) do NOT send the valueChanged signal and do modifications on their own
auto *command = new AssetMultiCommand(m_model, indexes, values);
if (storeUndo) {
pCore->pushUndo(command);
} else {
command->redo();
delete command;
}
}
void AssetParameterView::unsetModel()
{
QMutexLocker lock(&m_lock);
......
......@@ -100,6 +100,7 @@ private slots:
@param storeUndo: if true, an undo object is created
*/
void commitChanges(const QModelIndex &index, const QString &value, bool storeUndo);
void commitMultipleChanges(const QList <QModelIndex> indexes, const QStringList &values, bool storeUndo);
QVector<QPair<QString, QVariant>> getDefaultValues() const;
signals:
......
......@@ -54,6 +54,7 @@ signals:
The bool allows to decide whether an undo object should be created
*/
void valueChanged(QModelIndex, QString, bool);
void valuesChanged(const QList <QModelIndex>, const QStringList&, bool);
/* @brief Signal sent when the filter needs to be deactivated or reactivated.
This happens for example when the user has to pick a color.
......
......@@ -111,6 +111,7 @@ NegQColor ColorWheel::color() const
void ColorWheel::setColor(const NegQColor &color)
{
m_color = color;
update();
}
int ColorWheel::wheelSize() const
......
......@@ -62,21 +62,21 @@ LumaLiftGainParam::LumaLiftGainParam(std::shared_ptr<AssetParameterModel> model,
connect(this, &LumaLiftGainParam::liftChanged, [this, indexes]() {
NegQColor liftColor = m_lift->color();
emit valueChanged(indexes.value(QStringLiteral("lift_r")), m_locale.toString(liftColor.redF()), true);
emit valueChanged(indexes.value(QStringLiteral("lift_g")), m_locale.toString(liftColor.greenF()), true);
emit valueChanged(indexes.value(QStringLiteral("lift_b")), m_locale.toString(liftColor.blueF()), true);
QList <QModelIndex> ixes{indexes.value(QStringLiteral("lift_r")),indexes.value(QStringLiteral("lift_g")), indexes.value(QStringLiteral("lift_b"))};
QStringList values {m_locale.toString(liftColor.redF()), m_locale.toString(liftColor.greenF()), m_locale.toString(liftColor.blueF())};
emit valuesChanged(ixes, values, true);
});
connect(this, &LumaLiftGainParam::gammaChanged, [this, indexes]() {
NegQColor gammaColor = m_gamma->color();
emit valueChanged(indexes.value(QStringLiteral("gamma_r")), m_locale.toString(gammaColor.redF() * GAMMA_FACTOR), true);
emit valueChanged(indexes.value(QStringLiteral("gamma_g")), m_locale.toString(gammaColor.greenF() * GAMMA_FACTOR), true);
emit valueChanged(indexes.value(QStringLiteral("gamma_b")), m_locale.toString(gammaColor.blueF() * GAMMA_FACTOR), true);
QList <QModelIndex> ixes{indexes.value(QStringLiteral("gamma_r")),indexes.value(QStringLiteral("gamma_g")), indexes.value(QStringLiteral("gamma_b"))};
QStringList values {m_locale.toString(gammaColor.redF() * GAMMA_FACTOR), m_locale.toString(gammaColor.greenF() * GAMMA_FACTOR), m_locale.toString(gammaColor.blueF() * GAMMA_FACTOR)};
emit valuesChanged(ixes, values, true);
});
connect(this, &LumaLiftGainParam::gainChanged, [this, indexes]() {
NegQColor gainColor = m_gain->color();
emit valueChanged(indexes.value(QStringLiteral("gain_r")), m_locale.toString(gainColor.redF() * GAIN_FACTOR), true);
emit valueChanged(indexes.value(QStringLiteral("gain_g")), m_locale.toString(gainColor.greenF() * GAIN_FACTOR), true);
emit valueChanged(indexes.value(QStringLiteral("gain_b")), m_locale.toString(gainColor.blueF() * GAIN_FACTOR), true);
QList <QModelIndex> ixes{indexes.value(QStringLiteral("gain_r")),indexes.value(QStringLiteral("gain_g")), indexes.value(QStringLiteral("gain_b"))};
QStringList values {m_locale.toString(gainColor.redF() * GAIN_FACTOR), m_locale.toString(gainColor.greenF() * GAIN_FACTOR), m_locale.toString(gainColor.blueF() * GAIN_FACTOR)};
emit valuesChanged(ixes, values, true);
});
}
......@@ -131,11 +131,6 @@ void LumaLiftGainParam::slotRefresh()
NegQColor gain = NegQColor::fromRgbF(values.value(QStringLiteral("gain_r")) / GAIN_FACTOR, values.value(QStringLiteral("gain_g")) / GAIN_FACTOR,
values.value(QStringLiteral("gain_b")) / GAIN_FACTOR);
/*QColor lift = QColor::fromRgbF(values.value(QStringLiteral("lift_r")), values.value(QStringLiteral("lift_g")), values.value(QStringLiteral("lift_b")));
QColor gamma = QColor::fromRgbF(values.value(QStringLiteral("gamma_r")) / GAMMA_FACTOR, values.value(QStringLiteral("gamma_g")) / GAMMA_FACTOR,
values.value(QStringLiteral("gamma_b")) / GAMMA_FACTOR);
QColor gain = QColor::fromRgbF(values.value(QStringLiteral("gain_r")) / GAIN_FACTOR, values.value(QStringLiteral("gain_g")) / GAIN_FACTOR,
values.value(QStringLiteral("gain_b")) / GAIN_FACTOR);*/
qDebug() << "//REFRESHING WIDGET START 2--------------__";
m_lift->setColor(lift);
m_gamma->setColor(gamma);
......
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