diff --git a/app/dialog/projectproperties/projectproperties.cpp b/app/dialog/projectproperties/projectproperties.cpp index c6d92d0fd..def4e269f 100644 --- a/app/dialog/projectproperties/projectproperties.cpp +++ b/app/dialog/projectproperties/projectproperties.cpp @@ -29,9 +29,6 @@ #include #include "common/filefunctions.h" -#include "common/ocioutils.h" -#include "config/config.h" -#include "core.h" #include "node/color/colormanager/colormanager.h" #include "render/diskmanager.h" @@ -100,24 +97,24 @@ ProjectPropertiesDialog::ProjectPropertiesDialog(Project* p, QWidget *parent) : QButtonGroup* disk_cache_btn_group = new QButtonGroup(); // Create radio buttons and add to widget and button group - disk_cache_radios_[ProjectSettingsNode::kCacheUseDefaultLocation] = new QRadioButton(tr("Use Default Location")); - disk_cache_radios_[ProjectSettingsNode::kCacheStoreAlongsideProject] = new QRadioButton(tr("Store Alongside Project")); - disk_cache_radios_[ProjectSettingsNode::kCacheCustomPath] = new QRadioButton(tr("Use Custom Location:")); + disk_cache_radios_[Project::kCacheUseDefaultLocation] = new QRadioButton(tr("Use Default Location")); + disk_cache_radios_[Project::kCacheStoreAlongsideProject] = new QRadioButton(tr("Store Alongside Project")); + disk_cache_radios_[Project::kCacheCustomPath] = new QRadioButton(tr("Use Custom Location:")); for (int i=0; iaddButton(disk_cache_radios_[i]); cache_layout->addWidget(disk_cache_radios_[i]); } // Create custom cache path widget - custom_cache_path_ = new PathWidget(working_project_->settings()->GetCustomCachePath(), this); + custom_cache_path_ = new PathWidget(working_project_->GetCustomCachePath(), this); custom_cache_path_->setEnabled(false); cache_layout->addWidget(custom_cache_path_); // Ensure custom cache path "enabled" is tied to the radio button being checked - connect(disk_cache_radios_[ProjectSettingsNode::kCacheCustomPath], &QRadioButton::toggled, custom_cache_path_, &PathWidget::setEnabled); + connect(disk_cache_radios_[Project::kCacheCustomPath], &QRadioButton::toggled, custom_cache_path_, &PathWidget::setEnabled); // Check the radio button that should currently be active - disk_cache_radios_[working_project_->settings()->GetCacheSetting()]->setChecked(true); + disk_cache_radios_[working_project_->GetCacheLocationSetting()]->setChecked(true); // Add disk cache settings button QPushButton* disk_cache_settings_btn = new QPushButton(tr("Disk Cache Settings")); @@ -147,9 +144,9 @@ void ProjectPropertiesDialog::accept() return; } - if (disk_cache_radios_[ProjectSettingsNode::kCacheUseDefaultLocation]->isChecked()) { + if (disk_cache_radios_[Project::kCacheUseDefaultLocation]->isChecked()) { // Keep new cache path empty, which means default - } else if (disk_cache_radios_[ProjectSettingsNode::kCacheStoreAlongsideProject]->isChecked()) { + } else if (disk_cache_radios_[Project::kCacheStoreAlongsideProject]->isChecked()) { // Ensure alongside project path is valid if (!VerifyPathAndWarnIfBad(working_project_->get_cache_alongside_project_path())) { return; @@ -161,13 +158,13 @@ void ProjectPropertiesDialog::accept() } } - if (custom_cache_path_->text() != working_project_->settings()->GetCustomCachePath()) { + if (custom_cache_path_->text() != working_project_->GetCustomCachePath()) { // Check if the user is okay with invalidating the current cache if (!DiskManager::ShowDiskCacheChangeConfirmationDialog(this)) { return; } - working_project_->settings()->SetCustomCachePath(custom_cache_path_->text()); + working_project_->SetCustomCachePath(custom_cache_path_->text()); emit DiskManager::instance()->InvalidateProject(working_project_); } @@ -243,9 +240,9 @@ void ProjectPropertiesDialog::OCIOFilenameUpdated() void ProjectPropertiesDialog::OpenDiskCacheSettings() { - if (disk_cache_radios_[ProjectSettingsNode::kCacheUseDefaultLocation]->isChecked()) { + if (disk_cache_radios_[Project::kCacheUseDefaultLocation]->isChecked()) { DiskManager::instance()->ShowDiskCacheSettingsDialog(DiskManager::instance()->GetDefaultCacheFolder(), this); - } else if (disk_cache_radios_[ProjectSettingsNode::kCacheStoreAlongsideProject]->isChecked()) { + } else if (disk_cache_radios_[Project::kCacheStoreAlongsideProject]->isChecked()) { DiskManager::instance()->ShowDiskCacheSettingsDialog(working_project_->get_cache_alongside_project_path(), this); } else { DiskManager::instance()->ShowDiskCacheSettingsDialog(custom_cache_path_->text(), this); diff --git a/app/node/project.cpp b/app/node/project.cpp index 5d5bf9db4..30ce0a246 100644 --- a/app/node/project.cpp +++ b/app/node/project.cpp @@ -56,11 +56,6 @@ Project::Project() : color_manager_->setParent(this); AddDefaultNode(color_manager_); - // Same with project settings - settings_ = new ProjectSettingsNode(); - settings_->setParent(this); - AddDefaultNode(settings_); - connect(color_manager(), &ColorManager::ValueChanged, this, &Project::ColorManagerValueChanged); } @@ -125,8 +120,6 @@ SerializedData Project::Load(QXmlStreamReader *reader) node = this->root(); } else if (is_cm) { node = this->color_manager(); - } else if (is_settings) { - node = this->settings(); } else { node = NodeFactory::CreateFromID(id); } @@ -174,8 +167,6 @@ void Project::Save(QXmlStreamWriter *writer) const writer->writeAttribute(QStringLiteral("root"), QStringLiteral("1")); } else if (node == this->color_manager()) { writer->writeAttribute(QStringLiteral("cm"), QStringLiteral("1")); - } else if (node == this->settings()) { - writer->writeAttribute(QStringLiteral("settings"), QStringLiteral("1")); } node->Save(writer); @@ -337,20 +328,20 @@ QString Project::get_cache_alongside_project_path() const QString Project::cache_path() const { - ProjectSettingsNode::CacheSetting setting = settings_->GetCacheSetting(); + CacheSetting setting = GetCacheLocationSetting(); switch (setting) { - case ProjectSettingsNode::kCacheUseDefaultLocation: + case kCacheUseDefaultLocation: break; - case ProjectSettingsNode::kCacheCustomPath: + case kCacheCustomPath: { - QString cache_path = settings_->GetCustomCachePath(); + QString cache_path = GetCustomCachePath(); if (cache_path.isEmpty()) { return cache_path; } break; } - case ProjectSettingsNode::kCacheStoreAlongsideProject: + case kCacheStoreAlongsideProject: { QString alongside = get_cache_alongside_project_path(); if (!alongside.isEmpty()) { @@ -373,6 +364,12 @@ Project *Project::GetProjectFromObject(const QObject *o) return QtUtils::GetParentOfType(o); } +void Project::SetSetting(const QString &key, const QString &value) +{ + settings_.insert(key, value); + emit SettingChanged(key, value); +} + void Project::ColorManagerValueChanged(const NodeInput &input, const TimeRange &range) { Q_UNUSED(input) diff --git a/app/node/project.h b/app/node/project.h index 57863fe50..a4d91c971 100644 --- a/app/node/project.h +++ b/app/node/project.h @@ -28,7 +28,6 @@ #include "node/color/colormanager/colormanager.h" #include "node/output/viewer/viewer.h" #include "node/project/footage/footage.h" -#include "node/project/projectsettings/projectsettings.h" #include "window/mainwindow/mainwindowlayoutinfo.h" namespace olive { @@ -48,6 +47,12 @@ class Project : public QObject { Q_OBJECT public: + enum CacheSetting { + kCacheUseDefaultLocation, + kCacheStoreAlongsideProject, + kCacheCustomPath + }; + Project(); virtual ~Project() override; @@ -83,7 +88,6 @@ public: Folder* root() const { return root_; } ColorManager* color_manager() const { return color_manager_; } - ProjectSettingsNode* settings() const { return settings_; } bool is_modified() const { return is_modified_; } void set_modified(bool e); @@ -131,8 +135,19 @@ public: */ static Project *GetProjectFromObject(const QObject *o); + static void CopySettings(Project *from, Project *to) { to->settings_ = from->settings_; } + static const QString kItemMimeType; + QString GetSetting(const QString &key) const { return settings_.value(key); } + void SetSetting(const QString &key, const QString &value); + + CacheSetting GetCacheLocationSetting() const { return static_cast(GetSetting(QStringLiteral("cachesetting")).toInt()); } + void SetCacheLocationSetting(CacheSetting s) { SetSetting(QStringLiteral("cachesetting"), QString::number(s)); } + + QString GetCustomCachePath() const { return GetSetting(QStringLiteral("customcachepath")); } + void SetCustomCachePath(const QString &path) { SetSetting(QStringLiteral("customcachepath"), path); } + signals: void NameChanged(); @@ -162,6 +177,8 @@ signals: void GroupChangedOutputPassthrough(NodeGroup *group, Node *output); + void SettingChanged(const QString &key, const QString &value); + protected: void AddDefaultNode(Node* n) { @@ -181,8 +198,6 @@ private: ColorManager* color_manager_; - ProjectSettingsNode* settings_; - bool is_modified_; bool autorecovery_saved_; @@ -191,6 +206,8 @@ private: QVector default_nodes_; + QMap settings_; + private slots: void ColorManagerValueChanged(const NodeInput& input, const TimeRange& range); diff --git a/app/node/project/CMakeLists.txt b/app/node/project/CMakeLists.txt index f66293413..81b41c183 100644 --- a/app/node/project/CMakeLists.txt +++ b/app/node/project/CMakeLists.txt @@ -16,7 +16,6 @@ add_subdirectory(folder) add_subdirectory(footage) -add_subdirectory(projectsettings) add_subdirectory(sequence) add_subdirectory(serializer) diff --git a/app/node/project/projectsettings/CMakeLists.txt b/app/node/project/projectsettings/CMakeLists.txt deleted file mode 100644 index fc7adab96..000000000 --- a/app/node/project/projectsettings/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# Olive - Non-Linear Video Editor -# Copyright (C) 2022 Olive Team -# -# 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 3 of the License, or -# (at your option) any later version. -# -# 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 . - -set(OLIVE_SOURCES - ${OLIVE_SOURCES} - node/project/projectsettings/projectsettings.cpp - node/project/projectsettings/projectsettings.h - PARENT_SCOPE -) diff --git a/app/node/project/projectsettings/projectsettings.cpp b/app/node/project/projectsettings/projectsettings.cpp deleted file mode 100644 index 93fb79127..000000000 --- a/app/node/project/projectsettings/projectsettings.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2022 Olive Team - - 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 3 of the License, or - (at your option) any later version. - - 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 . - -***/ - -#include "projectsettings.h" - -namespace olive { - -const QString ProjectSettingsNode::kCacheSetting = QStringLiteral("cache_setting"); -const QString ProjectSettingsNode::kCachePath = QStringLiteral("cache_path"); - -#define super Node - -ProjectSettingsNode::ProjectSettingsNode() -{ - AddInput(kCacheSetting, NodeValue::kCombo, 0, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable)); - - AddInput(kCachePath, NodeValue::kFile, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable)); - SetInputProperty(kCachePath, QStringLiteral("directory"), true); - UpdateCachePathEnabled(); -} - -void ProjectSettingsNode::Retranslate() -{ - super::Retranslate(); - - SetInputName(kCacheSetting, tr("Disk Cache Location")); - SetInputName(kCachePath, tr("Disk Cache Path")); - SetComboBoxStrings(kCacheSetting, {tr("Use Default Location"), tr("Store Alongside Project"), tr("Use Custom Location")}); - SetInputProperty(kCachePath, QStringLiteral("placeholder"), tr("(default)")); -} - -void ProjectSettingsNode::InputValueChangedEvent(const QString &input, int element) -{ - Q_UNUSED(element) - - if (input == kCacheSetting) { - UpdateCachePathEnabled(); - } -} - -void ProjectSettingsNode::UpdateCachePathEnabled() -{ - CacheSetting setting = GetCacheSetting(); - SetInputProperty(kCachePath, QStringLiteral("enabled"), (setting == kCacheCustomPath)); -} - -} diff --git a/app/node/project/projectsettings/projectsettings.h b/app/node/project/projectsettings/projectsettings.h deleted file mode 100644 index ec1a972cd..000000000 --- a/app/node/project/projectsettings/projectsettings.h +++ /dev/null @@ -1,92 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2022 Olive Team - - 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 3 of the License, or - (at your option) any later version. - - 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 . - -***/ - -#ifndef PROJECTSETTINGSNODE_H -#define PROJECTSETTINGSNODE_H - -#include "node/node.h" - -namespace olive { - -class ProjectSettingsNode : public Node -{ - Q_OBJECT -public: - ProjectSettingsNode(); - - NODE_DEFAULT_FUNCTIONS(ProjectSettingsNode) - - virtual QString Name() const override - { - return tr("Project Settings"); - } - - virtual QString id() const override - { - return QStringLiteral("org.olivevideoeditor.Olive.projectsettings"); - } - - virtual QVector Category() const override - { - return {kCategoryProject}; - } - - virtual QString Description() const override - { - return tr("Settings used throughout the project."); - } - - enum CacheSetting { - kCacheUseDefaultLocation, - kCacheStoreAlongsideProject, - kCacheCustomPath - }; - - static const QString kCacheSetting; - static const QString kCachePath; - - virtual void Retranslate() override; - - CacheSetting GetCacheSetting() const - { - return static_cast(GetStandardValue(kCacheSetting).toInt()); - } - - QString GetCustomCachePath() const - { - return GetStandardValue(kCachePath).toString(); - } - - void SetCustomCachePath(const QString& s) - { - SetStandardValue(kCachePath, s); - } - -protected: - virtual void InputValueChangedEvent(const QString &input, int element) override; - -private: - void UpdateCachePathEnabled(); - -}; - -} - -#endif // PROJECTSETTINGSNODE_H diff --git a/app/node/project/serializer/serializer210528.cpp b/app/node/project/serializer/serializer210528.cpp index baa5a0af7..4d1800be7 100644 --- a/app/node/project/serializer/serializer210528.cpp +++ b/app/node/project/serializer/serializer210528.cpp @@ -63,23 +63,27 @@ ProjectSerializer210528::LoadData ProjectSerializer210528::Load(Project *project reader->skipCurrentElement(); } else { Node* node; + bool handled_elsewhere = false; if (is_root) { node = project->root(); } else if (is_cm) { node = project->color_manager(); } else if (is_settings) { - node = project->settings(); + LoadProjectSettings(reader, project); + handled_elsewhere = true; } else { node = NodeFactory::CreateFromID(id); } - if (!node) { - qWarning() << "Failed to find node with ID" << id; - reader->skipCurrentElement(); - } else { - LoadNode(node, xml_node_data, reader); - node->setParent(project); + if (!handled_elsewhere) { + if (!node) { + qWarning() << "Failed to find node with ID" << id; + reader->skipCurrentElement(); + } else { + LoadNode(node, xml_node_data, reader); + node->setParent(project); + } } } } else { @@ -253,6 +257,54 @@ void ProjectSerializer210528::LoadNode(Node *node, XMLNodeData &xml_node_data, Q node->LoadFinishedEvent(); } +void ProjectSerializer210528::LoadProjectSettings(QXmlStreamReader *reader, Project *project) const +{ + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("input")) { + QString id; + XMLAttributeLoop(reader, attr) { + if (attr.name() == QStringLiteral("id")) { + id = attr.value().toString(); + } + } + + if (id == QStringLiteral("cache_setting") || id == QStringLiteral("cache_path")) { + QString value; + + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("primary")) { + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("standard")) { + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("track")) { + value = reader->readElementText(); + } else { + reader->skipCurrentElement(); + } + } + } else { + reader->skipCurrentElement(); + } + } + } else { + reader->skipCurrentElement(); + } + } + + if (id == QStringLiteral("cache_setting")) { + project->SetCacheLocationSetting(static_cast(value.toInt())); + } else { + project->SetCustomCachePath(value); + } + } else { + reader->skipCurrentElement(); + } + } else { + reader->skipCurrentElement(); + } + } +} + void ProjectSerializer210528::LoadInput(Node *node, QXmlStreamReader *reader, XMLNodeData &xml_node_data) const { QString param_id; diff --git a/app/node/project/serializer/serializer210528.h b/app/node/project/serializer/serializer210528.h index adcc83b2f..3ff084304 100644 --- a/app/node/project/serializer/serializer210528.h +++ b/app/node/project/serializer/serializer210528.h @@ -68,6 +68,8 @@ private: void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const; + void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const; + void LoadInput(Node *node, QXmlStreamReader* reader, XMLNodeData &xml_node_data) const; void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const; diff --git a/app/node/project/serializer/serializer210907.cpp b/app/node/project/serializer/serializer210907.cpp index f1ee256e0..1961cb3bf 100644 --- a/app/node/project/serializer/serializer210907.cpp +++ b/app/node/project/serializer/serializer210907.cpp @@ -63,23 +63,27 @@ ProjectSerializer210907::LoadData ProjectSerializer210907::Load(Project *project reader->skipCurrentElement(); } else { Node* node; + bool handled_elsewhere = false; if (is_root) { node = project->root(); } else if (is_cm) { node = project->color_manager(); } else if (is_settings) { - node = project->settings(); + LoadProjectSettings(reader, project); + handled_elsewhere = true; } else { node = NodeFactory::CreateFromID(id); } - if (!node) { - qWarning() << "Failed to find node with ID" << id; - reader->skipCurrentElement(); - } else { - LoadNode(node, xml_node_data, reader); - node->setParent(project); + if (!handled_elsewhere) { + if (!node) { + qWarning() << "Failed to find node with ID" << id; + reader->skipCurrentElement(); + } else { + LoadNode(node, xml_node_data, reader); + node->setParent(project); + } } } } else { @@ -250,6 +254,54 @@ void ProjectSerializer210907::LoadNode(Node *node, XMLNodeData &xml_node_data, Q node->LoadFinishedEvent(); } +void ProjectSerializer210907::LoadProjectSettings(QXmlStreamReader *reader, Project *project) const +{ + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("input")) { + QString id; + XMLAttributeLoop(reader, attr) { + if (attr.name() == QStringLiteral("id")) { + id = attr.value().toString(); + } + } + + if (id == QStringLiteral("cache_setting") || id == QStringLiteral("cache_path")) { + QString value; + + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("primary")) { + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("standard")) { + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("track")) { + value = reader->readElementText(); + } else { + reader->skipCurrentElement(); + } + } + } else { + reader->skipCurrentElement(); + } + } + } else { + reader->skipCurrentElement(); + } + } + + if (id == QStringLiteral("cache_setting")) { + project->SetCacheLocationSetting(static_cast(value.toInt())); + } else { + project->SetCustomCachePath(value); + } + } else { + reader->skipCurrentElement(); + } + } else { + reader->skipCurrentElement(); + } + } +} + void ProjectSerializer210907::LoadInput(Node *node, QXmlStreamReader *reader, XMLNodeData &xml_node_data) const { QString param_id; diff --git a/app/node/project/serializer/serializer210907.h b/app/node/project/serializer/serializer210907.h index ca9865980..d135aa2b5 100644 --- a/app/node/project/serializer/serializer210907.h +++ b/app/node/project/serializer/serializer210907.h @@ -67,6 +67,8 @@ private: void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const; + void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const; + void LoadInput(Node *node, QXmlStreamReader* reader, XMLNodeData &xml_node_data) const; void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const; diff --git a/app/node/project/serializer/serializer211228.cpp b/app/node/project/serializer/serializer211228.cpp index 4c6078cf1..8d0a81a55 100644 --- a/app/node/project/serializer/serializer211228.cpp +++ b/app/node/project/serializer/serializer211228.cpp @@ -65,23 +65,27 @@ ProjectSerializer211228::LoadData ProjectSerializer211228::Load(Project *project reader->skipCurrentElement(); } else { Node* node; + bool handled_elsewhere = false; if (is_root) { node = project->root(); } else if (is_cm) { node = project->color_manager(); } else if (is_settings) { - node = project->settings(); + LoadProjectSettings(reader, project); + handled_elsewhere = true; } else { node = NodeFactory::CreateFromID(id); } - if (!node) { - qWarning() << "Failed to find node with ID" << id; - reader->skipCurrentElement(); - } else { - LoadNode(node, xml_node_data, reader); - node->setParent(project); + if (!handled_elsewhere) { + if (!node) { + qWarning() << "Failed to find node with ID" << id; + reader->skipCurrentElement(); + } else { + LoadNode(node, xml_node_data, reader); + node->setParent(project); + } } } } else { @@ -300,6 +304,54 @@ void ProjectSerializer211228::LoadNode(Node *node, XMLNodeData &xml_node_data, Q node->LoadFinishedEvent(); } +void ProjectSerializer211228::LoadProjectSettings(QXmlStreamReader *reader, Project *project) const +{ + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("input")) { + QString id; + XMLAttributeLoop(reader, attr) { + if (attr.name() == QStringLiteral("id")) { + id = attr.value().toString(); + } + } + + if (id == QStringLiteral("cache_setting") || id == QStringLiteral("cache_path")) { + QString value; + + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("primary")) { + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("standard")) { + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("track")) { + value = reader->readElementText(); + } else { + reader->skipCurrentElement(); + } + } + } else { + reader->skipCurrentElement(); + } + } + } else { + reader->skipCurrentElement(); + } + } + + if (id == QStringLiteral("cache_setting")) { + project->SetCacheLocationSetting(static_cast(value.toInt())); + } else { + project->SetCustomCachePath(value); + } + } else { + reader->skipCurrentElement(); + } + } else { + reader->skipCurrentElement(); + } + } +} + void ProjectSerializer211228::LoadInput(Node *node, QXmlStreamReader *reader, XMLNodeData &xml_node_data) const { QString param_id; diff --git a/app/node/project/serializer/serializer211228.h b/app/node/project/serializer/serializer211228.h index ea028caed..2cf5d2537 100644 --- a/app/node/project/serializer/serializer211228.h +++ b/app/node/project/serializer/serializer211228.h @@ -68,6 +68,8 @@ private: void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const; + void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const; + void LoadInput(Node *node, QXmlStreamReader* reader, XMLNodeData &xml_node_data) const; void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const; diff --git a/app/node/project/serializer/serializer220403.cpp b/app/node/project/serializer/serializer220403.cpp index 1121623cb..7dbf2d459 100644 --- a/app/node/project/serializer/serializer220403.cpp +++ b/app/node/project/serializer/serializer220403.cpp @@ -84,30 +84,26 @@ ProjectSerializer220403::LoadData ProjectSerializer220403::Load(Project *project reader->skipCurrentElement(); } else { Node* node; + bool handled_elsewhere = false; if (is_root) { node = project->root(); } else if (is_cm) { node = project->color_manager(); } else if (is_settings) { - node = project->settings(); + LoadProjectSettings(reader, project); + handled_elsewhere = true; } else { node = NodeFactory::CreateFromID(id); } - if (!node) { - qWarning() << "Failed to find node with ID" << id; - reader->skipCurrentElement(); - } else { - // Disable cache while node is being loaded (we'll re-enable it later) - node->SetCachesEnabled(false); - - LoadNode(node, xml_node_data, reader); - - if (project) { - node->setParent(project); + if (!handled_elsewhere) { + if (!node) { + qWarning() << "Failed to find node with ID" << id; + reader->skipCurrentElement(); } else { - load_data.nodes.append(node); + LoadNode(node, xml_node_data, reader); + node->setParent(project); } } } @@ -456,6 +452,54 @@ void ProjectSerializer220403::LoadNode(Node *node, XMLNodeData &xml_node_data, Q node->LoadFinishedEvent(); } +void ProjectSerializer220403::LoadProjectSettings(QXmlStreamReader *reader, Project *project) const +{ + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("input")) { + QString id; + XMLAttributeLoop(reader, attr) { + if (attr.name() == QStringLiteral("id")) { + id = attr.value().toString(); + } + } + + if (id == QStringLiteral("cache_setting") || id == QStringLiteral("cache_path")) { + QString value; + + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("primary")) { + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("standard")) { + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("track")) { + value = reader->readElementText(); + } else { + reader->skipCurrentElement(); + } + } + } else { + reader->skipCurrentElement(); + } + } + } else { + reader->skipCurrentElement(); + } + } + + if (id == QStringLiteral("cache_setting")) { + project->SetCacheLocationSetting(static_cast(value.toInt())); + } else { + project->SetCustomCachePath(value); + } + } else { + reader->skipCurrentElement(); + } + } else { + reader->skipCurrentElement(); + } + } +} + void ProjectSerializer220403::LoadInput(Node *node, QXmlStreamReader *reader, XMLNodeData &xml_node_data) const { if (dynamic_cast(node)) { diff --git a/app/node/project/serializer/serializer220403.h b/app/node/project/serializer/serializer220403.h index e457e629d..5cc6e5d9e 100644 --- a/app/node/project/serializer/serializer220403.h +++ b/app/node/project/serializer/serializer220403.h @@ -74,6 +74,8 @@ private: void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const; + void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const; + void LoadInput(Node *node, QXmlStreamReader* reader, XMLNodeData &xml_node_data) const; void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const; diff --git a/app/render/projectcopier.cpp b/app/render/projectcopier.cpp index 91f574b63..19ab25c90 100644 --- a/app/render/projectcopier.cpp +++ b/app/render/projectcopier.cpp @@ -47,6 +47,7 @@ void ProjectCopier::SetProject(Project *project) disconnect(original_, &Project::InputDisconnected, this, &ProjectCopier::QueueEdgeRemove); disconnect(original_, &Project::ValueChanged, this, &ProjectCopier::QueueValueChange); disconnect(original_, &Project::InputValueHintChanged, this, &ProjectCopier::QueueValueHintChange); + disconnect(original_, &Project::SettingChanged, this, &ProjectCopier::QueueProjectSettingChange); } original_ = project; @@ -68,6 +69,9 @@ void ProjectCopier::SetProject(Project *project) } } + // Copy project settings + Project::CopySettings(original_, copy_); + // Ensure graph change value is just before the sync value UpdateGraphChangeValue(); UpdateLastSyncedValue(); @@ -79,6 +83,7 @@ void ProjectCopier::SetProject(Project *project) connect(original_, &Project::InputDisconnected, this, &ProjectCopier::QueueEdgeRemove, Qt::DirectConnection); connect(original_, &Project::ValueChanged, this, &ProjectCopier::QueueValueChange, Qt::DirectConnection); connect(original_, &Project::InputValueHintChanged, this, &ProjectCopier::QueueValueHintChange, Qt::DirectConnection); + connect(original_, &Project::SettingChanged, this, &ProjectCopier::QueueProjectSettingChange, Qt::DirectConnection); } } @@ -108,6 +113,9 @@ void ProjectCopier::ProcessUpdateQueue() case QueuedJob::kValueHintChanged: DoValueHintChange(job.input); break; + case QueuedJob::kProjectSettingChanged: + DoProjectSettingChange(job.key, job.value); + break; } } @@ -200,6 +208,11 @@ void ProjectCopier::DoValueHintChange(const NodeInput &input) our_input->SetValueHintForInput(input.input(), hint, input.element()); } +void ProjectCopier::DoProjectSettingChange(const QString &key, const QString &value) +{ + copy_->SetSetting(key, value); +} + void ProjectCopier::InsertIntoCopyMap(Node *node, Node *copy) { // Insert into map @@ -214,25 +227,25 @@ void ProjectCopier::InsertIntoCopyMap(Node *node, Node *copy) void ProjectCopier::QueueNodeAdd(Node *node) { - graph_update_queue_.push_back({QueuedJob::kNodeAdded, node, NodeInput(), nullptr}); + graph_update_queue_.push_back({QueuedJob::kNodeAdded, node, NodeInput(), nullptr, QString(), QString()}); UpdateGraphChangeValue(); } void ProjectCopier::QueueNodeRemove(Node *node) { - graph_update_queue_.push_back({QueuedJob::kNodeRemoved, node, NodeInput(), nullptr}); + graph_update_queue_.push_back({QueuedJob::kNodeRemoved, node, NodeInput(), nullptr, QString(), QString()}); UpdateGraphChangeValue(); } void ProjectCopier::QueueEdgeAdd(Node *output, const NodeInput &input) { - graph_update_queue_.push_back({QueuedJob::kEdgeAdded, nullptr, input, output}); + graph_update_queue_.push_back({QueuedJob::kEdgeAdded, nullptr, input, output, QString(), QString()}); UpdateGraphChangeValue(); } void ProjectCopier::QueueEdgeRemove(Node *output, const NodeInput &input) { - graph_update_queue_.push_back({QueuedJob::kEdgeRemoved, nullptr, input, output}); + graph_update_queue_.push_back({QueuedJob::kEdgeRemoved, nullptr, input, output, QString(), QString()}); UpdateGraphChangeValue(); } @@ -246,13 +259,19 @@ void ProjectCopier::QueueValueChange(const NodeInput &input) } } - graph_update_queue_.push_back({QueuedJob::kValueChanged, nullptr, input, nullptr}); + graph_update_queue_.push_back({QueuedJob::kValueChanged, nullptr, input, nullptr, QString(), QString()}); UpdateGraphChangeValue(); } void ProjectCopier::QueueValueHintChange(const NodeInput &input) { - graph_update_queue_.push_back({QueuedJob::kValueHintChanged, nullptr, input, nullptr}); + graph_update_queue_.push_back({QueuedJob::kValueHintChanged, nullptr, input, nullptr, QString(), QString()}); + UpdateGraphChangeValue(); +} + +void ProjectCopier::QueueProjectSettingChange(const QString &key, const QString &value) +{ + graph_update_queue_.push_back({QueuedJob::kProjectSettingChanged, nullptr, NodeInput(), nullptr, key, value}); UpdateGraphChangeValue(); } diff --git a/app/render/projectcopier.h b/app/render/projectcopier.h index 89d630872..f1065cd05 100644 --- a/app/render/projectcopier.h +++ b/app/render/projectcopier.h @@ -70,7 +70,8 @@ private: void DoEdgeAdd(Node *output, const NodeInput& input); void DoEdgeRemove(Node *output, const NodeInput& input); void DoValueChange(const NodeInput& input); - void DoValueHintChange(const NodeInput& input); + void DoValueHintChange(const NodeInput &input); + void DoProjectSettingChange(const QString &key, const QString &value); void InsertIntoCopyMap(Node* node, Node* copy); @@ -88,13 +89,17 @@ private: kEdgeAdded, kEdgeRemoved, kValueChanged, - kValueHintChanged + kValueHintChanged, + kProjectSettingChanged }; Type type; Node* node; NodeInput input; Node *output; + + QString key; + QString value; }; std::list graph_update_queue_; @@ -118,6 +123,8 @@ private slots: void QueueValueHintChange(const NodeInput &input); + void QueueProjectSettingChange(const QString &key, const QString &value); + }; } diff --git a/app/task/precache/precachetask.cpp b/app/task/precache/precachetask.cpp index e355251ca..39b63c450 100644 --- a/app/task/precache/precachetask.cpp +++ b/app/task/precache/precachetask.cpp @@ -41,7 +41,7 @@ PreCacheTask::PreCacheTask(Footage *footage, int index, Sequence* sequence) // Copy project config nodes Node::CopyInputs(footage->project()->color_manager(), project_->color_manager(), false); - Node::CopyInputs(footage->project()->settings(), project_->settings(), false); + Project::CopySettings(footage->project(), project_); // Copy footage node so it can precache without any modifications from the user screwing it up footage_ = static_cast(footage->copy());