From: Jean-Baptiste M. <nu...@kd...> - 2017-06-02 15:56:57
|
Git commit df71c265e658d3fa6fced1f591babed661371095 by Jean-Baptiste Mardelle. Committed on 02/06/2017 at 15:56. Pushed by mardelle into branch 'refactoring_timeline'. Undo / redo system for asset parameters Using QUndoCommand so we can use the "merge" feature and have only one undo for multiple changes M +1 -0 src/assets/CMakeLists.txt A +71 -0 src/assets/model/assetcommand.cpp [License: GPL (v2/3)] A +48 -0 src/assets/model/assetcommand.hpp [License: GPL (v2/3)] M +6 -2 src/assets/model/assetparametermodel.cpp M +3 -1 src/assets/model/assetparametermodel.hpp M +5 -0 src/core.cpp M +1 -0 src/core.h M +25 -3 src/effectstack/widgets/animationwidget.cpp M +1 -0 src/effectstack/widgets/animationwidget.h https://commits.kde.org/kdenlive/df71c265e658d3fa6fced1f591babed661371095 diff --git a/src/assets/CMakeLists.txt b/src/assets/CMakeLists.txt index cc3791a5b..6b1773425 100644 --- a/src/assets/CMakeLists.txt +++ b/src/assets/CMakeLists.txt @@ -6,6 +6,7 @@ set(kdenlive_SRCS assets/assetlist/model/assettreemodel.cpp assets/assetpanel.cpp assets/model/assetparametermodel.cpp + assets/model/assetcommand.cpp assets/view/assetparameterview.cpp assets/view/widgets/abstractparamwidget.cpp assets/view/widgets/doubleparamwidget.cpp diff --git a/src/assets/model/assetcommand.cpp b/src/assets/model/assetcommand.cpp new file mode 100644 index 000000000..8dbc07ed8 --- /dev/null +++ b/src/assets/model/assetcommand.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2017 by by Jean-Baptiste Mardelle * + * This file is part of Kdenlive. See www.kdenlive.org. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3 or any later version accepted by the * + * membership of KDE e.V. (or its successor approved by the membership * + * of KDE e.V.), which shall act as a proxy defined in Section 14 of * + * version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + + +#include "assetcommand.hpp" +#include "transitions/transitionsrepository.hpp" +#include <memory> + + +AssetCommand::AssetCommand(std::shared_ptr<AssetParameterModel> &model, const QString &assetId, const QModelIndex &index, const QString &value, QUndoCommand *parent) + : QUndoCommand(parent) + , m_model(std::move(model)) + , m_index(index) + , m_value(value) + , m_updateView(false) + , m_stamp(QTime::currentTime()) +{ + m_name = m_model->data(index, AssetParameterModel::NameRole).toString(); + setText(i18n("Edit %1", TransitionsRepository::get()->getName(assetId))); + m_oldValue = m_model->data(index, AssetParameterModel::ValueRole).toString(); +} + +void AssetCommand::undo() +{ + m_model->setParameter(m_name, m_oldValue); + m_model->dataChanged(m_index, m_index, QVector<int>()); +} +// virtual +void AssetCommand::redo() +{ + m_model->setParameter(m_name, m_value); + if (m_updateView) { + m_model->dataChanged(m_index, m_index, QVector<int>()); + } + m_updateView = true; +} + +// virtual +int AssetCommand::id() const +{ + return 1; +} +// virtual +bool AssetCommand::mergeWith(const QUndoCommand *other) +{ + if (other->id() != id() || static_cast<const AssetCommand *>(other)->m_index != m_index || m_stamp.msecsTo(static_cast<const AssetCommand *>(other)->m_stamp) > 3000) { + return false; + } + m_value = static_cast<const AssetCommand *>(other)->m_value; + m_stamp = static_cast<const AssetCommand *>(other)->m_stamp; + return true; +} + diff --git a/src/assets/model/assetcommand.hpp b/src/assets/model/assetcommand.hpp new file mode 100644 index 000000000..5e8ccdc63 --- /dev/null +++ b/src/assets/model/assetcommand.hpp @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2017 by Jean-Baptiste Mardelle * + * This file is part of Kdenlive. See www.kdenlive.org. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3 or any later version accepted by the * + * membership of KDE e.V. (or its successor approved by the membership * + * of KDE e.V.), which shall act as a proxy defined in Section 14 of * + * version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef ASSETCOMMAND_H +#define ASSETCOMMAND_H + +#include "assetparametermodel.hpp" +#include <QUndoCommand> +#include <QTime> + +class AssetCommand : public QUndoCommand +{ +public: + AssetCommand(std::shared_ptr<AssetParameterModel> &model, const QString &assetId, const QModelIndex &index, const QString &value, 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; + QModelIndex m_index; + QString m_value; + QString m_name; + QString m_oldValue; + bool m_updateView; + QTime m_stamp; +}; + +#endif diff --git a/src/assets/model/assetparametermodel.cpp b/src/assets/model/assetparametermodel.cpp index aa812d918..f989e74bb 100644 --- a/src/assets/model/assetparametermodel.cpp +++ b/src/assets/model/assetparametermodel.cpp @@ -20,6 +20,7 @@ ***************************************************************************/ #include "assetparametermodel.hpp" +#include "assetcommand.hpp" #include "core.h" #include "klocalizedstring.h" #include "kdenlivesettings.h" @@ -332,6 +333,9 @@ void AssetParameterModel::setParameters(const QVector<QPair<QString, QVariant>> void AssetParameterModel::commitChanges(const QModelIndex &index, const QString &value) { - QString name = data(index, NameRole).toString(); - setParameter(name, value); + std::shared_ptr<AssetParameterModel> ptr = shared_from_this(); + AssetCommand *command = new AssetCommand(ptr, m_assetId, index, value); + pCore->pushUndo(command); } + + diff --git a/src/assets/model/assetparametermodel.hpp b/src/assets/model/assetparametermodel.hpp index 229c72567..af17b2756 100644 --- a/src/assets/model/assetparametermodel.hpp +++ b/src/assets/model/assetparametermodel.hpp @@ -26,6 +26,7 @@ #include "klocalizedstring.h" #include <QAbstractListModel> #include <QDomElement> +#include <QUndoCommand> #include <unordered_map> #include <memory> @@ -38,6 +39,7 @@ */ + enum class ParamType { Double, List, @@ -62,7 +64,7 @@ enum class ParamType { Readonly }; Q_DECLARE_METATYPE(ParamType) -class AssetParameterModel : public QAbstractListModel +class AssetParameterModel : public QAbstractListModel, public std::enable_shared_from_this<AssetParameterModel> { Q_OBJECT diff --git a/src/core.cpp b/src/core.cpp index 779120020..a203d0876 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -321,3 +321,8 @@ void Core::pushUndo(const Fun &undo, const Fun &redo, const QString &text) { currentDoc()->commandStack()->push(new FunctionalUndoCommand(undo, redo, text)); } + +void Core::pushUndo(QUndoCommand *command) +{ + currentDoc()->commandStack()->push(command); +} diff --git a/src/core.h b/src/core.h index 3c42afea0..5aaa861b1 100644 --- a/src/core.h +++ b/src/core.h @@ -124,6 +124,7 @@ public: /** @brief Create and push and undo object based on the corresponding functions Note that if you class permits and requires it, you should use the macro PUSH_UNDO instead*/ void pushUndo(const Fun &undo, const Fun &redo, const QString &text); + void pushUndo(QUndoCommand *command); private: explicit Core(); diff --git a/src/effectstack/widgets/animationwidget.cpp b/src/effectstack/widgets/animationwidget.cpp index 6e937f7b6..6eb66992d 100644 --- a/src/effectstack/widgets/animationwidget.cpp +++ b/src/effectstack/widgets/animationwidget.cpp @@ -233,9 +233,6 @@ void AnimationWidget::finishSetup() { // Load effect presets loadPresets(); - - // Load keyframes - rebuildKeyframes(); } // static @@ -747,6 +744,7 @@ void AnimationWidget::addParameter(QModelIndex ix) if (type == ParamType::Animated || type == ParamType::RestrictedAnim) { // one dimension parameter // Required to initialize anim property + m_inTimeline = paramTag; m_animProperties.anim_get_int(paramTag.toUtf8().constData(), 0, m_outPoint); buildSliderWidget(paramTag, ix); } else { @@ -763,6 +761,9 @@ void AnimationWidget::addParameter(QModelIndex ix) m_selectType->setVisible(false); m_selectType->setCurrentItem(0); } + m_parameters << ix; + // Load keyframes + rebuildKeyframes(); } void AnimationWidget::buildSliderWidget(const QString ¶mTag, QModelIndex ix) @@ -1639,5 +1640,26 @@ void AnimationWidget::slotShowComment(bool show) void AnimationWidget::slotRefresh() { + for (int i = 0; i < m_parameters.count(); i++) { + QModelIndex ix = m_parameters.at(i); + ParamType type = (ParamType)m_model->data(ix, AssetParameterModel::TypeRole).toInt(); + QString keyframes = m_model->data(ix, AssetParameterModel::ValueRole).toString(); + QString paramTag = m_model->data(ix, AssetParameterModel::NameRole).toString(); + m_animProperties.set(paramTag.toUtf8().constData(), keyframes.toUtf8().constData()); + m_attachedToEnd = KeyframeView::checkNegatives(keyframes, m_outPoint); + if (type == ParamType::Animated || type == ParamType::RestrictedAnim) { + // one dimension parameter + // Required to initialize anim property + m_animProperties.anim_get_int(paramTag.toUtf8().constData(), 0, m_outPoint); + } else { + // one dimension parameter + // TODO: multiple rect parameters in effect ? + m_rectParameter = paramTag; + m_inTimeline = paramTag; + // Required to initialize anim property + m_animProperties.anim_get_rect(paramTag.toUtf8().constData(), 0, m_outPoint); + } + } rebuildKeyframes(); + monitorSeek(m_monitor->position()); } diff --git a/src/effectstack/widgets/animationwidget.h b/src/effectstack/widgets/animationwidget.h index 0f9ed363e..ce5321e09 100644 --- a/src/effectstack/widgets/animationwidget.h +++ b/src/effectstack/widgets/animationwidget.h @@ -87,6 +87,7 @@ private: /** @brief the keyframe position which should be attached to end (negative frame) */ int m_attachedToEnd; QDomElement m_xml; + QList <QModelIndex> m_parameters; QString m_effectId; Mlt::Animation m_animController; Mlt::Properties m_animProperties; |