nodes: fix serialized ID typos with backward compatibility

- ChromaKey tolerance inputs are now spelled "upper/lower_tolerance_in";
  old projects with the misspelled "tolerence" IDs keep loading (values
  and connections) via a new Node::GetInputIDForLegacyID() hook applied
  in LoadInput and connection deserialization
- flip/ripple/swirl/tile/wave node IDs moved to the consistent
  org.olivevideoeditor.Olive.* domain; NodeFactory::CreateFromID maps
  the old org.oliveeditor.* IDs so old projects still resolve
- Regression tests: legacy ChromaKey IDs (values + connections) and
  legacy factory IDs
This commit is contained in:
2026-07-17 08:38:25 +08:00
parent 2aa921b215
commit bec52b46b3
13 changed files with 139 additions and 18 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ QString FlipDistortNode::Name() const
QString FlipDistortNode::id() const
{
return QStringLiteral("org.oliveeditor.Olive.flip");
return QStringLiteral("org.olivevideoeditor.Olive.flip");
}
QVector<Node::CategoryID> FlipDistortNode::Category() const
@@ -67,7 +67,7 @@ QString RippleDistortNode::Name() const
QString RippleDistortNode::id() const
{
return QStringLiteral("org.oliveeditor.Olive.ripple");
return QStringLiteral("org.olivevideoeditor.Olive.ripple");
}
QVector<Node::CategoryID> RippleDistortNode::Category() const
+1 -1
View File
@@ -61,7 +61,7 @@ QString SwirlDistortNode::Name() const
QString SwirlDistortNode::id() const
{
return QStringLiteral("org.oliveeditor.Olive.swirl");
return QStringLiteral("org.olivevideoeditor.Olive.swirl");
}
QVector<Node::CategoryID> SwirlDistortNode::Category() const
+1 -1
View File
@@ -69,7 +69,7 @@ QString TileDistortNode::Name() const
QString TileDistortNode::id() const
{
return QStringLiteral("org.oliveeditor.Olive.tile");
return QStringLiteral("org.olivevideoeditor.Olive.tile");
}
QVector<Node::CategoryID> TileDistortNode::Category() const
+1 -1
View File
@@ -54,7 +54,7 @@ QString WaveDistortNode::Name() const
QString WaveDistortNode::id() const
{
return QStringLiteral("org.oliveeditor.Olive.wave");
return QStringLiteral("org.olivevideoeditor.Olive.wave");
}
QVector<Node::CategoryID> WaveDistortNode::Category() const
+19 -1
View File
@@ -22,6 +22,7 @@
#include "factory.h"
#include <QCoreApplication>
#include <QHash>
#include "audio/pan/pan.h"
#include "audio/volume/volume.h"
@@ -224,8 +225,25 @@ QString NodeFactory::GetNameFromID(const QString &id)
Node *NodeFactory::CreateFromID(const QString &id)
{
QString resolved_id = id;
// Node IDs renamed after older project files were written
static const QHash<QString, QString> kLegacyIDs = {
{ QStringLiteral("org.oliveeditor.Olive.flip"),
QStringLiteral("org.olivevideoeditor.Olive.flip") },
{ QStringLiteral("org.oliveeditor.Olive.ripple"),
QStringLiteral("org.olivevideoeditor.Olive.ripple") },
{ QStringLiteral("org.oliveeditor.Olive.swirl"),
QStringLiteral("org.olivevideoeditor.Olive.swirl") },
{ QStringLiteral("org.oliveeditor.Olive.tile"),
QStringLiteral("org.olivevideoeditor.Olive.tile") },
{ QStringLiteral("org.oliveeditor.Olive.wave"),
QStringLiteral("org.olivevideoeditor.Olive.wave") },
};
resolved_id = kLegacyIDs.value(id, id);
foreach (Node *n, library_) {
if (n->id() == id) {
if (n->id() == resolved_id) {
return n->copy();
}
}
+15 -2
View File
@@ -28,9 +28,9 @@ const QString ChromaKeyNode::kColorInput = QStringLiteral("color_key");
const QString ChromaKeyNode::kMaskOnlyInput = QStringLiteral("mask_only_in");
const QString ChromaKeyNode::kInvertInput = QStringLiteral("invert_in");
const QString ChromaKeyNode::kUpperToleranceInput =
QStringLiteral("upper_tolerence_in");
QStringLiteral("upper_tolerance_in");
const QString ChromaKeyNode::kLowerToleranceInput =
QStringLiteral("lower_tolerence_in");
QStringLiteral("lower_tolerance_in");
const QString ChromaKeyNode::kGarbageMatteInput = QStringLiteral("garbage_in");
const QString ChromaKeyNode::kCoreMatteInput = QStringLiteral("core_in");
const QString ChromaKeyNode::kShadowsInput = QStringLiteral("shadows_in");
@@ -163,4 +163,17 @@ void ChromaKeyNode::ConfigChanged()
GenerateProcessor();
}
QString ChromaKeyNode::GetInputIDForLegacyID(const QString &id) const
{
// Older project files used the misspelled "tolerence" input IDs
if (id == QStringLiteral("upper_tolerence_in")) {
return kUpperToleranceInput;
}
if (id == QStringLiteral("lower_tolerence_in")) {
return kLowerToleranceInput;
}
return super::GetInputIDForLegacyID(id);
}
} // namespace olive
+4
View File
@@ -46,6 +46,10 @@ public:
virtual void ConfigChanged() override;
// Maps the misspelled tolerance input IDs from old project files onto the
// corrected ones
virtual QString GetInputIDForLegacyID(const QString &id) const override;
static const QString kColorInput;
static const QString kInvertInput;
static const QString kMaskOnlyInput;
+12
View File
@@ -1351,6 +1351,10 @@ bool Node::Load(QXmlStreamReader *reader, SerializedData *data)
}
}
// Translate IDs renamed after older project files were
// written
param_id = GetInputIDForLegacyID(param_id);
QString output_node_id;
while (XMLReadNextStartElement(reader)) {
@@ -1573,6 +1577,11 @@ void Node::PostLoadEvent(SerializedData *data)
}
}
QString Node::GetInputIDForLegacyID(const QString &id) const
{
return id;
}
bool Node::LoadInput(QXmlStreamReader *reader, SerializedData *data)
{
if (dynamic_cast<NodeGroup *>(this)) {
@@ -1598,6 +1607,9 @@ bool Node::LoadInput(QXmlStreamReader *reader, SerializedData *data)
return false;
}
// Translate IDs renamed after older project files were written
param_id = GetInputIDForLegacyID(param_id);
if (!this->HasInputWithID(param_id)) {
qWarning() << "Failed to load parameter that didn't exist:" << param_id;
reader->skipCurrentElement();
+8
View File
@@ -1094,6 +1094,14 @@ public:
bool LoadInput(QXmlStreamReader *reader, SerializedData *data);
void SaveInput(QXmlStreamWriter *writer, const QString &id) const;
/**
* @brief Maps an input ID read from an old project file to its current ID
*
* Nodes whose input IDs have been renamed override this so old projects
* keep loading. The default implementation returns the ID unchanged.
*/
virtual QString GetInputIDForLegacyID(const QString &id) const;
bool LoadImmediate(QXmlStreamReader *reader, const QString &input,
int element, SerializedData *data);
void SaveImmediate(QXmlStreamWriter *writer, const QString &input,