fixed deserializer issue introduced by copy/paste fix

This commit is contained in:
itsmattkc
2022-04-26 09:04:34 -07:00
parent abb84aa2ca
commit 45b18f6df2
6 changed files with 464 additions and 475 deletions
+54 -35
View File
@@ -86,53 +86,36 @@ ProjectSerializer::Result ProjectSerializer::Load(Project *project, QXmlStreamRe
{
// Determine project version
uint version = 0;
Result res = kUnknownVersion;
while (!version && XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("olive") || reader->name() == type) {
while(!version && XMLReadNextStartElement(reader)) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("olive")
|| reader->name() == QStringLiteral("project")) { // 0.1 projects only
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("version")) {
version = reader->readElementText().toUInt();
} else if (reader->name() == QStringLiteral("url")) {
project->SetSavedURL(reader->readElementText());
// HACK for 0.1 projects
if (version == 190219) {
res = LoadWithSerializerVersion(version, project, reader);
}
} else if (reader->name() == type) {
// Found our data
res = LoadWithSerializerVersion(version, project, reader);
} else {
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
}
// Failed to find version in file
if (version == 0) {
return kUnknownVersion;
}
// We should now have the version, if we have a serializer for it, use it to load the project
ProjectSerializer *serializer = nullptr;
foreach (ProjectSerializer *s, instances_) {
if (version == s->Version()) {
serializer = s;
break;
} else if (version < s->Version()) {
// Assuming the instance list is in order, if the project version is less than any version
// we find, we must not support it anymore
return kProjectTooOld;
}
}
if (serializer) {
LoadData ld = serializer->Load(project, reader, nullptr);
Result r(kSuccess);
if (reader->hasError()) {
r = Result(kXmlError);
r.SetDetails(reader->errorString());
}
r.SetLoadData(ld);
return r;
} else {
// Reached the end of the list with no serializer, assume too new
return kProjectTooNew;
}
return res;
}
ProjectSerializer::Result ProjectSerializer::Save(const SaveData &data, const QString &type)
@@ -209,4 +192,40 @@ bool ProjectSerializer::IsCancelled() const
return false;
}
ProjectSerializer::Result ProjectSerializer::LoadWithSerializerVersion(uint version, Project *project, QXmlStreamReader *reader)
{
// Failed to find version in file
if (version == 0) {
return kUnknownVersion;
}
// We should now have the version, if we have a serializer for it, use it to load the project
ProjectSerializer *serializer = nullptr;
foreach (ProjectSerializer *s, instances_) {
if (version == s->Version()) {
serializer = s;
break;
} else if (version < s->Version()) {
// Assuming the instance list is in order, if the project version is less than any version
// we find, we must not support it anymore
return kProjectTooOld;
}
}
if (serializer) {
LoadData ld = serializer->Load(project, reader, nullptr);
Result r(kSuccess);
if (reader->hasError()) {
r = Result(kXmlError);
r.SetDetails(reader->errorString());
}
r.SetLoadData(ld);
return r;
} else {
// Reached the end of the list with no serializer, assume too new
return kProjectTooNew;
}
}
}
+2
View File
@@ -153,6 +153,8 @@ protected:
bool IsCancelled() const;
private:
static Result LoadWithSerializerVersion(uint version, Project *project, QXmlStreamReader *reader);
static QVector<ProjectSerializer*> instances_;
};
@@ -29,133 +29,125 @@ ProjectSerializer210528::LoadData ProjectSerializer210528::Load(Project *project
XMLNodeData xml_node_data;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("url")) {
project->SetSavedURL(reader->readElementText());
} else if (reader->name() == QStringLiteral("project")) {
if (reader->name() == QStringLiteral("layout")) {
// Since the main window's functions have to occur in the GUI thread (and we're likely
// loading in a secondary thread), we load all necessary data into a separate struct so we
// can continue loading and queue it with the main window so it can handle the data
// appropriately in its own thread.
project->SetLayoutInfo(MainWindowLayoutInfo::fromXml(reader, xml_node_data.node_ptrs));
} else if (reader->name() == QStringLiteral("uuid")) {
project->SetUuid(QUuid::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("nodes")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("layout")) {
if (reader->name() == QStringLiteral("node")) {
bool is_root = false;
bool is_cm = false;
bool is_settings = false;
QString id;
// Since the main window's functions have to occur in the GUI thread (and we're likely
// loading in a secondary thread), we load all necessary data into a separate struct so we
// can continue loading and queue it with the main window so it can handle the data
// appropriately in its own thread.
project->SetLayoutInfo(MainWindowLayoutInfo::fromXml(reader, xml_node_data.node_ptrs));
} else if (reader->name() == QStringLiteral("uuid")) {
project->SetUuid(QUuid::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("nodes")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
bool is_root = false;
bool is_cm = false;
bool is_settings = false;
QString id;
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
id = attr.value().toString();
} else if (attr.name() == QStringLiteral("root") && attr.value() == QStringLiteral("1")) {
is_root = true;
} else if (attr.name() == QStringLiteral("cm") && attr.value() == QStringLiteral("1")) {
is_cm = true;
} else if (attr.name() == QStringLiteral("settings") && attr.value() == QStringLiteral("1")) {
is_settings = true;
}
}
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
id = attr.value().toString();
} else if (attr.name() == QStringLiteral("root") && attr.value() == QStringLiteral("1")) {
is_root = true;
} else if (attr.name() == QStringLiteral("cm") && attr.value() == QStringLiteral("1")) {
is_cm = true;
} else if (attr.name() == QStringLiteral("settings") && attr.value() == QStringLiteral("1")) {
is_settings = true;
}
if (id.isEmpty()) {
qWarning() << "Failed to load node with empty ID";
reader->skipCurrentElement();
} else {
Node* node;
if (is_root) {
node = project->root();
} else if (is_cm) {
node = project->color_manager();
} else if (is_settings) {
node = project->settings();
} 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);
}
}
} else {
reader->skipCurrentElement();
}
}
} else if (reader->name() == QStringLiteral("positions")) {
if (id.isEmpty()) {
qWarning() << "Failed to load node with empty ID";
reader->skipCurrentElement();
} else {
Node* node;
while (XMLReadNextStartElement(reader)) {
if (is_root) {
node = project->root();
} else if (is_cm) {
node = project->color_manager();
} else if (is_settings) {
node = project->settings();
} else {
node = NodeFactory::CreateFromID(id);
}
if (reader->name() == QStringLiteral("context")) {
if (!node) {
qWarning() << "Failed to find node with ID" << id;
reader->skipCurrentElement();
} else {
LoadNode(node, xml_node_data, reader);
node->setParent(project);
}
}
} else {
reader->skipCurrentElement();
}
}
quintptr context_ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
context_ptr = attr.value().toULongLong();
break;
}
}
} else if (reader->name() == QStringLiteral("positions")) {
Node *context = xml_node_data.node_ptrs.value(context_ptr);
while (XMLReadNextStartElement(reader)) {
if (!context) {
qWarning() << "Failed to find pointer for context";
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr node_ptr;
Node::Position node_pos;
if (reader->name() == QStringLiteral("context")) {
if (LoadPosition(reader, &node_ptr, &node_pos)) {
Node *node = xml_node_data.node_ptrs.value(node_ptr);
quintptr context_ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
context_ptr = attr.value().toULongLong();
break;
}
}
if (node) {
context->SetNodePositionInContext(node, node_pos);
} else {
qWarning() << "Failed to find pointer for node position";
reader->skipCurrentElement();
}
}
Node *context = xml_node_data.node_ptrs.value(context_ptr);
if (!context) {
qWarning() << "Failed to find pointer for context";
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr node_ptr;
Node::Position node_pos;
if (LoadPosition(reader, &node_ptr, &node_pos)) {
Node *node = xml_node_data.node_ptrs.value(node_ptr);
if (node) {
context->SetNodePositionInContext(node, node_pos);
} else {
qWarning() << "Failed to find pointer for node position";
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
} else {
reader->skipCurrentElement();
}
}
} else {
// Skip this
reader->skipCurrentElement();
}
}
} else {
// Skip this
reader->skipCurrentElement();
}
}
@@ -29,133 +29,125 @@ ProjectSerializer210907::LoadData ProjectSerializer210907::Load(Project *project
XMLNodeData xml_node_data;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("url")) {
project->SetSavedURL(reader->readElementText());
} else if (reader->name() == QStringLiteral("project")) {
if (reader->name() == QStringLiteral("layout")) {
// Since the main window's functions have to occur in the GUI thread (and we're likely
// loading in a secondary thread), we load all necessary data into a separate struct so we
// can continue loading and queue it with the main window so it can handle the data
// appropriately in its own thread.
project->SetLayoutInfo(MainWindowLayoutInfo::fromXml(reader, xml_node_data.node_ptrs));
} else if (reader->name() == QStringLiteral("uuid")) {
project->SetUuid(QUuid::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("nodes")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("layout")) {
if (reader->name() == QStringLiteral("node")) {
bool is_root = false;
bool is_cm = false;
bool is_settings = false;
QString id;
// Since the main window's functions have to occur in the GUI thread (and we're likely
// loading in a secondary thread), we load all necessary data into a separate struct so we
// can continue loading and queue it with the main window so it can handle the data
// appropriately in its own thread.
project->SetLayoutInfo(MainWindowLayoutInfo::fromXml(reader, xml_node_data.node_ptrs));
} else if (reader->name() == QStringLiteral("uuid")) {
project->SetUuid(QUuid::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("nodes")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
bool is_root = false;
bool is_cm = false;
bool is_settings = false;
QString id;
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
id = attr.value().toString();
} else if (attr.name() == QStringLiteral("root") && attr.value() == QStringLiteral("1")) {
is_root = true;
} else if (attr.name() == QStringLiteral("cm") && attr.value() == QStringLiteral("1")) {
is_cm = true;
} else if (attr.name() == QStringLiteral("settings") && attr.value() == QStringLiteral("1")) {
is_settings = true;
}
}
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
id = attr.value().toString();
} else if (attr.name() == QStringLiteral("root") && attr.value() == QStringLiteral("1")) {
is_root = true;
} else if (attr.name() == QStringLiteral("cm") && attr.value() == QStringLiteral("1")) {
is_cm = true;
} else if (attr.name() == QStringLiteral("settings") && attr.value() == QStringLiteral("1")) {
is_settings = true;
}
if (id.isEmpty()) {
qWarning() << "Failed to load node with empty ID";
reader->skipCurrentElement();
} else {
Node* node;
if (is_root) {
node = project->root();
} else if (is_cm) {
node = project->color_manager();
} else if (is_settings) {
node = project->settings();
} 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);
}
}
} else {
reader->skipCurrentElement();
}
}
} else if (reader->name() == QStringLiteral("positions")) {
if (id.isEmpty()) {
qWarning() << "Failed to load node with empty ID";
reader->skipCurrentElement();
} else {
Node* node;
while (XMLReadNextStartElement(reader)) {
if (is_root) {
node = project->root();
} else if (is_cm) {
node = project->color_manager();
} else if (is_settings) {
node = project->settings();
} else {
node = NodeFactory::CreateFromID(id);
}
if (reader->name() == QStringLiteral("context")) {
if (!node) {
qWarning() << "Failed to find node with ID" << id;
reader->skipCurrentElement();
} else {
LoadNode(node, xml_node_data, reader);
node->setParent(project);
}
}
} else {
reader->skipCurrentElement();
}
}
quintptr context_ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
context_ptr = attr.value().toULongLong();
break;
}
}
} else if (reader->name() == QStringLiteral("positions")) {
Node *context = xml_node_data.node_ptrs.value(context_ptr);
while (XMLReadNextStartElement(reader)) {
if (!context) {
qWarning() << "Failed to find pointer for context";
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr node_ptr;
Node::Position node_pos;
if (reader->name() == QStringLiteral("context")) {
if (LoadPosition(reader, &node_ptr, &node_pos)) {
Node *node = xml_node_data.node_ptrs.value(node_ptr);
quintptr context_ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
context_ptr = attr.value().toULongLong();
break;
}
}
if (node) {
context->SetNodePositionInContext(node, node_pos);
} else {
qWarning() << "Failed to find pointer for node position";
reader->skipCurrentElement();
}
}
Node *context = xml_node_data.node_ptrs.value(context_ptr);
if (!context) {
qWarning() << "Failed to find pointer for context";
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr node_ptr;
Node::Position node_pos;
if (LoadPosition(reader, &node_ptr, &node_pos)) {
Node *node = xml_node_data.node_ptrs.value(node_ptr);
if (node) {
context->SetNodePositionInContext(node, node_pos);
} else {
qWarning() << "Failed to find pointer for node position";
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
} else {
reader->skipCurrentElement();
}
}
} else {
// Skip this
reader->skipCurrentElement();
}
}
} else {
// Skip this
reader->skipCurrentElement();
}
}
+114 -122
View File
@@ -31,157 +31,149 @@ ProjectSerializer211228::LoadData ProjectSerializer211228::Load(Project *project
XMLNodeData xml_node_data;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("url")) {
project->SetSavedURL(reader->readElementText());
} else if (reader->name() == QStringLiteral("project")) {
if (reader->name() == QStringLiteral("layout")) {
// Since the main window's functions have to occur in the GUI thread (and we're likely
// loading in a secondary thread), we load all necessary data into a separate struct so we
// can continue loading and queue it with the main window so it can handle the data
// appropriately in its own thread.
project->SetLayoutInfo(MainWindowLayoutInfo::fromXml(reader, xml_node_data.node_ptrs));
} else if (reader->name() == QStringLiteral("uuid")) {
project->SetUuid(QUuid::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("nodes")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("layout")) {
if (reader->name() == QStringLiteral("node")) {
bool is_root = false;
bool is_cm = false;
bool is_settings = false;
QString id;
// Since the main window's functions have to occur in the GUI thread (and we're likely
// loading in a secondary thread), we load all necessary data into a separate struct so we
// can continue loading and queue it with the main window so it can handle the data
// appropriately in its own thread.
project->SetLayoutInfo(MainWindowLayoutInfo::fromXml(reader, xml_node_data.node_ptrs));
} else if (reader->name() == QStringLiteral("uuid")) {
project->SetUuid(QUuid::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("nodes")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
bool is_root = false;
bool is_cm = false;
bool is_settings = false;
QString id;
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
id = attr.value().toString();
} else if (attr.name() == QStringLiteral("root") && attr.value() == QStringLiteral("1")) {
is_root = true;
} else if (attr.name() == QStringLiteral("cm") && attr.value() == QStringLiteral("1")) {
is_cm = true;
} else if (attr.name() == QStringLiteral("settings") && attr.value() == QStringLiteral("1")) {
is_settings = true;
}
}
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
id = attr.value().toString();
} else if (attr.name() == QStringLiteral("root") && attr.value() == QStringLiteral("1")) {
is_root = true;
} else if (attr.name() == QStringLiteral("cm") && attr.value() == QStringLiteral("1")) {
is_cm = true;
} else if (attr.name() == QStringLiteral("settings") && attr.value() == QStringLiteral("1")) {
is_settings = true;
}
if (id.isEmpty()) {
qWarning() << "Failed to load node with empty ID";
reader->skipCurrentElement();
} else {
Node* node;
if (is_root) {
node = project->root();
} else if (is_cm) {
node = project->color_manager();
} else if (is_settings) {
node = project->settings();
} 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);
}
}
} else {
reader->skipCurrentElement();
}
}
} else if (reader->name() == QStringLiteral("positions")) {
if (id.isEmpty()) {
qWarning() << "Failed to load node with empty ID";
reader->skipCurrentElement();
} else {
Node* node;
while (XMLReadNextStartElement(reader)) {
if (is_root) {
node = project->root();
} else if (is_cm) {
node = project->color_manager();
} else if (is_settings) {
node = project->settings();
} else {
node = NodeFactory::CreateFromID(id);
}
if (reader->name() == QStringLiteral("context")) {
if (!node) {
qWarning() << "Failed to find node with ID" << id;
reader->skipCurrentElement();
} else {
LoadNode(node, xml_node_data, reader);
node->setParent(project);
}
}
} else {
reader->skipCurrentElement();
}
}
quintptr context_ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
context_ptr = attr.value().toULongLong();
break;
}
}
} else if (reader->name() == QStringLiteral("positions")) {
if (context_ptr) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr node_ptr;
Node::Position node_pos;
while (XMLReadNextStartElement(reader)) {
if (LoadPosition(reader, &node_ptr, &node_pos)) {
if (node_ptr) {
positions[context_ptr].insert(node_ptr, node_pos);
} else {
qWarning() << "Failed to find pointer for node position";
reader->skipCurrentElement();
}
}
if (reader->name() == QStringLiteral("context")) {
quintptr context_ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
context_ptr = attr.value().toULongLong();
break;
}
}
if (context_ptr) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr node_ptr;
Node::Position node_pos;
if (LoadPosition(reader, &node_ptr, &node_pos)) {
if (node_ptr) {
positions[context_ptr].insert(node_ptr, node_pos);
} else {
qWarning() << "Failed to find pointer for node position";
reader->skipCurrentElement();
}
}
} else {
qWarning() << "Attempted to load context with no pointer";
reader->skipCurrentElement();
}
} else {
reader->skipCurrentElement();
}
}
} else if (reader->name() == QStringLiteral("properties")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
ptr = attr.value().toULongLong();
// Only attribute we're looking for right now
break;
}
}
if (ptr) {
QMap<QString, QString> properties_for_node;
while (XMLReadNextStartElement(reader)) {
properties_for_node.insert(reader->name().toString(), reader->readElementText());
}
properties.insert(ptr, properties_for_node);
}
} else {
reader->skipCurrentElement();
}
} else {
qWarning() << "Attempted to load context with no pointer";
reader->skipCurrentElement();
}
} else {
// Skip this
reader->skipCurrentElement();
}
}
} else if (reader->name() == QStringLiteral("properties")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
ptr = attr.value().toULongLong();
// Only attribute we're looking for right now
break;
}
}
if (ptr) {
QMap<QString, QString> properties_for_node;
while (XMLReadNextStartElement(reader)) {
properties_for_node.insert(reader->name().toString(), reader->readElementText());
}
properties.insert(ptr, properties_for_node);
}
} else {
reader->skipCurrentElement();
}
}
} else {
// Skip this
reader->skipCurrentElement();
}
}
+114 -122
View File
@@ -31,157 +31,149 @@ ProjectSerializer220403::LoadData ProjectSerializer220403::Load(Project *project
XMLNodeData xml_node_data;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("url")) {
project->SetSavedURL(reader->readElementText());
} else if (reader->name() == QStringLiteral("project")) {
if (reader->name() == QStringLiteral("layout")) {
// Since the main window's functions have to occur in the GUI thread (and we're likely
// loading in a secondary thread), we load all necessary data into a separate struct so we
// can continue loading and queue it with the main window so it can handle the data
// appropriately in its own thread.
project->SetLayoutInfo(MainWindowLayoutInfo::fromXml(reader, xml_node_data.node_ptrs));
} else if (reader->name() == QStringLiteral("uuid")) {
project->SetUuid(QUuid::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("nodes")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("layout")) {
if (reader->name() == QStringLiteral("node")) {
bool is_root = false;
bool is_cm = false;
bool is_settings = false;
QString id;
// Since the main window's functions have to occur in the GUI thread (and we're likely
// loading in a secondary thread), we load all necessary data into a separate struct so we
// can continue loading and queue it with the main window so it can handle the data
// appropriately in its own thread.
project->SetLayoutInfo(MainWindowLayoutInfo::fromXml(reader, xml_node_data.node_ptrs));
} else if (reader->name() == QStringLiteral("uuid")) {
project->SetUuid(QUuid::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("nodes")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
bool is_root = false;
bool is_cm = false;
bool is_settings = false;
QString id;
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
id = attr.value().toString();
} else if (attr.name() == QStringLiteral("root") && attr.value() == QStringLiteral("1")) {
is_root = true;
} else if (attr.name() == QStringLiteral("cm") && attr.value() == QStringLiteral("1")) {
is_cm = true;
} else if (attr.name() == QStringLiteral("settings") && attr.value() == QStringLiteral("1")) {
is_settings = true;
}
}
{
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
id = attr.value().toString();
} else if (attr.name() == QStringLiteral("root") && attr.value() == QStringLiteral("1")) {
is_root = true;
} else if (attr.name() == QStringLiteral("cm") && attr.value() == QStringLiteral("1")) {
is_cm = true;
} else if (attr.name() == QStringLiteral("settings") && attr.value() == QStringLiteral("1")) {
is_settings = true;
}
if (id.isEmpty()) {
qWarning() << "Failed to load node with empty ID";
reader->skipCurrentElement();
} else {
Node* node;
if (is_root) {
node = project->root();
} else if (is_cm) {
node = project->color_manager();
} else if (is_settings) {
node = project->settings();
} 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);
}
}
} else {
reader->skipCurrentElement();
}
}
} else if (reader->name() == QStringLiteral("positions")) {
if (id.isEmpty()) {
qWarning() << "Failed to load node with empty ID";
reader->skipCurrentElement();
} else {
Node* node;
while (XMLReadNextStartElement(reader)) {
if (is_root) {
node = project->root();
} else if (is_cm) {
node = project->color_manager();
} else if (is_settings) {
node = project->settings();
} else {
node = NodeFactory::CreateFromID(id);
}
if (reader->name() == QStringLiteral("context")) {
if (!node) {
qWarning() << "Failed to find node with ID" << id;
reader->skipCurrentElement();
} else {
LoadNode(node, xml_node_data, reader);
node->setParent(project);
}
}
} else {
reader->skipCurrentElement();
}
}
quintptr context_ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
context_ptr = attr.value().toULongLong();
break;
}
}
} else if (reader->name() == QStringLiteral("positions")) {
if (context_ptr) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr node_ptr;
Node::Position node_pos;
while (XMLReadNextStartElement(reader)) {
if (LoadPosition(reader, &node_ptr, &node_pos)) {
if (node_ptr) {
positions[context_ptr].insert(node_ptr, node_pos);
} else {
qWarning() << "Failed to find pointer for node position";
reader->skipCurrentElement();
}
}
if (reader->name() == QStringLiteral("context")) {
quintptr context_ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
context_ptr = attr.value().toULongLong();
break;
}
}
if (context_ptr) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr node_ptr;
Node::Position node_pos;
if (LoadPosition(reader, &node_ptr, &node_pos)) {
if (node_ptr) {
positions[context_ptr].insert(node_ptr, node_pos);
} else {
qWarning() << "Failed to find pointer for node position";
reader->skipCurrentElement();
}
}
} else {
qWarning() << "Attempted to load context with no pointer";
reader->skipCurrentElement();
}
} else {
reader->skipCurrentElement();
}
}
} else if (reader->name() == QStringLiteral("properties")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
ptr = attr.value().toULongLong();
// Only attribute we're looking for right now
break;
}
}
if (ptr) {
QMap<QString, QString> properties_for_node;
while (XMLReadNextStartElement(reader)) {
properties_for_node.insert(reader->name().toString(), reader->readElementText());
}
properties.insert(ptr, properties_for_node);
}
} else {
reader->skipCurrentElement();
}
} else {
qWarning() << "Attempted to load context with no pointer";
reader->skipCurrentElement();
}
} else {
// Skip this
reader->skipCurrentElement();
}
}
} else if (reader->name() == QStringLiteral("properties")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
ptr = attr.value().toULongLong();
// Only attribute we're looking for right now
break;
}
}
if (ptr) {
QMap<QString, QString> properties_for_node;
while (XMLReadNextStartElement(reader)) {
properties_for_node.insert(reader->name().toString(), reader->readElementText());
}
properties.insert(ptr, properties_for_node);
}
} else {
reader->skipCurrentElement();
}
}
} else {
// Skip this
reader->skipCurrentElement();
}
}