Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 689bc84a authored by Nicolas Carion's avatar Nicolas Carion

Some fixes in effectstack to better support effectgroups

parent 8a54f504
......@@ -43,6 +43,8 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kdenlive\")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH})
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fsanitize=address -fno-omit-frame-pointer")
# To be switched on when releasing.
option(RELEASE_BUILD "Remove Git revision from program version (use for stable releases)" ON)
......@@ -78,7 +80,7 @@ include(CheckIncludeFiles)
check_include_files(malloc.h HAVE_MALLOC_H)
check_include_files(pthread.h HAVE_PTHREAD_H)
find_package(Qt5 REQUIRED COMPONENTS Core DBus Widgets Script Svg Quick )
find_package(Qt5 REQUIRED COMPONENTS Core DBus Widgets Svg Quick )
find_package(Qt5 OPTIONAL_COMPONENTS WebKitWidgets QUIET)
find_package(KF5 5.23.0 OPTIONAL_COMPONENTS XmlGui QUIET)
......
......@@ -142,6 +142,19 @@ QModelIndex AbstractTreeModel::getIndexFromItem(const std::shared_ptr<TreeItem>
return index(item->row(), 0, parentIndex);
}
QModelIndex AbstractTreeModel::getIndexFromId(int id) const
{
if (id == rootItem->getId()) {
return QModelIndex();
}
Q_ASSERT(m_allItems.count(id) > 0);
if (auto ptr = m_allItems.at(id).lock())
return getIndexFromItem(ptr);
Q_ASSERT(false);
return QModelIndex();
}
void AbstractTreeModel::notifyRowAboutToAppend(const std::shared_ptr<TreeItem> &item)
{
auto index = getIndexFromItem(item);
......
......@@ -51,6 +51,9 @@ public:
/* @brief Given an item from the hierarchy, construct the corresponding ModelIndex */
QModelIndex getIndexFromItem(const std::shared_ptr<TreeItem> &item) const;
/* @brief Given an item id, construct the corresponding ModelIndex */
QModelIndex getIndexFromId(int id) const;
/* @brief Return a ptr to an item given its id */
std::shared_ptr<TreeItem> getItemById(int id) const;
......
......@@ -43,7 +43,7 @@
*/
class AbstractTreeModel;
class TreeItem : public QObject, public enable_shared_from_this_virtual<TreeItem>
class TreeItem : public enable_shared_from_this_virtual<TreeItem>
{
public:
/* @brief Construct a TreeItem
......
......@@ -45,7 +45,7 @@ class ProjectItemModel;
* Project items are stored in a tree like structure ...
*/
class AbstractProjectItem : public TreeItem
class AbstractProjectItem : public QObject, public TreeItem
{
Q_OBJECT
......
......@@ -50,6 +50,19 @@ public:
friend class EffectGroupModel;
EffectItemType effectItemType() const;
/* @brief Return true if the effect or effect group applies only to audio */
virtual bool isAudio() const = 0;
/* @brief This function plants the effect into the given service in last position
*/
virtual void plant(const std::weak_ptr<Mlt::Service> &service) = 0;
/* @brief This function unplants (removes) the effect from the given service
*/
virtual void unplant(const std::weak_ptr<Mlt::Service> &service) = 0;
/* @brief This function connect the dataChanged signal of the effects to the dataChanged signal of the model. This workarounds limitation with signal when using multiple inheritance */
virtual void connectDataChanged() = 0;
protected:
/* @brief Toogles the mlt effect according to the current activation state*/
virtual void updateEnable() = 0;
......
......@@ -49,3 +49,34 @@ void EffectGroupModel::updateEnable()
std::static_pointer_cast<AbstractEffectItem>(child(i))->updateEnable();
}
}
bool EffectGroupModel::isAudio() const
{
bool result = false;
for (int i = 0; i < childCount() && !result; ++i) {
result = result || std::static_pointer_cast<AbstractEffectItem>(child(i))->isAudio();
}
return result;
}
void EffectGroupModel::plant(const std::weak_ptr<Mlt::Service> &service)
{
for (int i = 0; i < childCount(); ++i) {
std::static_pointer_cast<AbstractEffectItem>(child(i))->plant(service);
}
}
void EffectGroupModel::unplant(const std::weak_ptr<Mlt::Service> &service)
{
for (int i = 0; i < childCount(); ++i) {
std::static_pointer_cast<AbstractEffectItem>(child(i))->unplant(service);
}
}
void EffectGroupModel::connectDataChanged()
{
for (int i = 0; i < childCount(); ++i) {
std::static_pointer_cast<AbstractEffectItem>(child(i))->connectDataChanged();
}
}
......@@ -37,6 +37,19 @@ public:
*/
static std::shared_ptr<EffectGroupModel> construct(const QString &name, std::shared_ptr<AbstractTreeModel> stack);
/* @brief Return true if the effect applies only to audio */
bool isAudio() const override;
/* @brief This function plants the effect into the given service in last position
*/
void plant(const std::weak_ptr<Mlt::Service> &service) override;
/* @brief This function unplants (removes) the effect from the given service
*/
void unplant(const std::weak_ptr<Mlt::Service> &service) override;
/* @brief This function connect the dataChanged signal of the effects to the dataChanged signal of the model. This workarounds limitation with signal when using multiple inheritance */
void connectDataChanged();
protected:
EffectGroupModel(const QList<QVariant> &data, const QString &name, const std::shared_ptr<AbstractTreeModel> &stack);
......
......@@ -83,10 +83,24 @@ void EffectItemModel::updateEnable()
{
filter().set("disable", isEnabled() ? 0 : 1);
pCore->refreshProjectItem(m_ownerId);
emit dataChanged(index(row()), index(row()), QVector<int>());
if (auto ptr = m_model.lock()) {
QModelIndex index = ptr->getIndexFromId(m_id);
emit dataChanged(index, index, QVector<int>());
} else {
qDebug() << "Error, unable to send update to deleted model";
Q_ASSERT(false);
}
}
bool EffectItemModel::isAudio() const
{
return EffectsRepository::get()->getType(getAssetId()) == EffectType::Audio;
}
void EffectItemModel::connectDataChanged()
{
if (auto ptr = m_model.lock()) {
auto model = std::static_pointer_cast<EffectStackModel>(ptr);
connect(this, &EffectItemModel::dataChanged, model.get(), &EffectStackModel::dataChanged);
}
}
......@@ -41,15 +41,18 @@ public:
/* @brief This function plants the effect into the given service in last position
*/
void plant(const std::weak_ptr<Mlt::Service> &service);
void plant(const std::weak_ptr<Mlt::Service> &service) override;
/* @brief This function unplants (removes) the effect from the given service
*/
void unplant(const std::weak_ptr<Mlt::Service> &service);
void unplant(const std::weak_ptr<Mlt::Service> &service) override;
Mlt::Filter &filter() const;
/* @brief Return true if the effect applies only to audio */
bool isAudio() const;
bool isAudio() const override;
/* @brief This function connect the dataChanged signal of the effects to the dataChanged signal of the model. This workarounds limitation with signal when using multiple inheritance */
void connectDataChanged();
protected:
EffectItemModel(const QList<QVariant> &data, Mlt::Properties *effect, const QDomElement &xml, const QString &effectId,
......
......@@ -133,18 +133,12 @@ void EffectStackModel::registerItem(const std::shared_ptr<TreeItem> &item)
{
auto effectItem = std::static_pointer_cast<AbstractEffectItem>(item);
QModelIndex ix;
switch(effectItem->effectItemType()) {
case EffectItemType::Effect:{
auto effect = std::static_pointer_cast<EffectItemModel>(effectItem);
effect->plant(m_service);
effect->setEffectStackEnabled(m_effectStackEnabled);
ix = getIndexFromItem(effect);
connect(effect.get(), &EffectItemModel::dataChanged, this, &EffectStackModel::dataChanged);
if (!effect->isAudio()) {
pCore->refreshProjectItem(m_ownerId);
}
break;
}
effectItem->plant(m_service);
effectItem->setEffectStackEnabled(m_effectStackEnabled);
ix = getIndexFromItem(effectItem);
effectItem->connectDataChanged();
if (!effectItem->isAudio()) {
pCore->refreshProjectItem(m_ownerId);
}
AbstractTreeModel::registerItem(item);
if (ix.isValid()) {
......@@ -155,15 +149,9 @@ void EffectStackModel::registerItem(const std::shared_ptr<TreeItem> &item)
void EffectStackModel::deregisterItem(int id, TreeItem *item)
{
auto effectItem = static_cast<AbstractEffectItem*>(item);
switch(effectItem->effectItemType()) {
case EffectItemType::Effect:{
auto effect = static_cast<EffectItemModel*>(effectItem);
effect->unplant(this->m_service);
if (!effect->isAudio()) {
pCore->refreshProjectItem(m_ownerId);
}
break;
}
effectItem->unplant(this->m_service);
if (!effectItem->isAudio()) {
pCore->refreshProjectItem(m_ownerId);
}
AbstractTreeModel::deregisterItem(id, item);
}
......@@ -174,7 +162,7 @@ void EffectStackModel::setEffectStackEnabled(bool enabled)
// Recursively updates children states
for (int i = 0; i < rootItem->childCount(); ++i) {
std::static_pointer_cast<EffectItemModel>(rootItem->child(i))->setEffectStackEnabled(enabled);
std::static_pointer_cast<AbstractEffectItem>(rootItem->child(i))->setEffectStackEnabled(enabled);
}
}
......@@ -196,7 +184,6 @@ void EffectStackModel::importEffects(std::shared_ptr<EffectStackModel> sourceSta
auto clone = EffectItemModel::construct(effect->getAssetId(), shared_from_this());
rootItem->appendChild(clone);
clone->setParameters(effect->getAllParameters());
bool isAudioEffect = EffectsRepository::get()->getType(effect->getAssetId()) == EffectType::Audio;
// TODO parent should not always be root
Fun redo = addItem_lambda(clone, rootItem->getId());
redo();
......
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