change: change code style to Linux style except indent.
This commit is contained in:
@@ -26,459 +26,527 @@
|
||||
#include "node/group/group.h"
|
||||
#include "node/serializeddata.h"
|
||||
#include <QtCore>
|
||||
namespace olive {
|
||||
|
||||
ProjectSerializer230220::LoadData ProjectSerializer230220::Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const
|
||||
namespace olive
|
||||
{
|
||||
QMap<quintptr, QMap<QString, QString> > properties;
|
||||
QMap<quintptr, QMap<quintptr, Node::Position> > positions;
|
||||
LoadData load_data;
|
||||
SerializedData project_data;
|
||||
|
||||
switch (load_type) {
|
||||
case kProject:
|
||||
{
|
||||
if (reader->name() == QStringLiteral("project")) {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("project")) {
|
||||
project_data = project->Load(reader);
|
||||
} else if (reader->name() == QStringLiteral("layout")) {
|
||||
load_data.layout = MainWindowLayoutInfo::fromXml(reader, project_data.node_ptrs);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
PostConnect(project->nodes(), &project_data);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kOnlyMarkers:
|
||||
{
|
||||
if (reader->name() == QStringLiteral("markers")) {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("marker")) {
|
||||
TimelineMarker *marker = new TimelineMarker();
|
||||
marker->load(reader);
|
||||
load_data.markers.push_back(marker);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kOnlyKeyframes:
|
||||
{
|
||||
if (reader->name() == QStringLiteral("keyframes")) {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("node")) {
|
||||
QString node_id;
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
node_id = attr.value().toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Node *n = nullptr;
|
||||
if (!node_id.isEmpty()) {
|
||||
n = NodeFactory::CreateFromID(node_id);
|
||||
}
|
||||
|
||||
if (!n) {
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("input")) {
|
||||
QString input_id;
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
input_id = attr.value().toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (input_id.isEmpty()) {
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("element")) {
|
||||
QString element_id;
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
element_id = attr.value().toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (element_id.isEmpty()) {
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("track")) {
|
||||
QString track_id;
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
track_id = attr.value().toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (track_id.isEmpty()) {
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("key")) {
|
||||
NodeKeyframe *key = new NodeKeyframe();
|
||||
key->set_input(input_id);
|
||||
key->set_element(element_id.toInt());
|
||||
key->set_track(track_id.toInt());
|
||||
|
||||
key->load(reader, n->GetInputDataType(input_id));
|
||||
|
||||
load_data.keyframes[node_id].append(key);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete n;
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kOnlyClips:
|
||||
case kOnlyNodes:
|
||||
{
|
||||
if ((load_type == kOnlyNodes && reader->name() == QStringLiteral("nodes")) || (load_type == kOnlyClips && reader->name() == QStringLiteral("timeline"))) {
|
||||
QMap<quintptr, Node*> skipped_items;
|
||||
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("node")) {
|
||||
QString id;
|
||||
quintptr ptr = 0;
|
||||
QVector<quintptr> items;
|
||||
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
id = attr.value().toString();
|
||||
} else if (attr.name() == QStringLiteral("ptr")) {
|
||||
ptr = attr.value().toULongLong();
|
||||
} else if (attr.name() == QStringLiteral("items")) {
|
||||
QVector<QStringView> l = attr.value().split(',');
|
||||
items.reserve(l.size());
|
||||
for (const QStringView &s : l) {
|
||||
items.append(s.toULongLong());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (id.isEmpty()) {
|
||||
qWarning() << "Failed to load node with empty ID";
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
bool dependency_of_item = false;
|
||||
|
||||
if (project && !items.empty()) {
|
||||
for (quintptr p : items) {
|
||||
if (project->nodes().contains(reinterpret_cast<Node*>(p))) {
|
||||
dependency_of_item = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dependency_of_item) {
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
Node* node = NodeFactory::CreateFromID(id);
|
||||
if (!node) {
|
||||
qWarning() << "Failed to find node with ID" << id;
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
if (project && node->IsItem() && ptr) {
|
||||
// If we're pasting an object into the same project, we should re-use the item
|
||||
// rather than duplicate.
|
||||
Node *existing = reinterpret_cast<Node *>(ptr);
|
||||
if (project->nodes().contains(existing)) {
|
||||
// Connect this
|
||||
skipped_items.insert(ptr, existing);
|
||||
|
||||
// Don't continue loading this
|
||||
delete node;
|
||||
node = nullptr;
|
||||
|
||||
// Skip element
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (node) {
|
||||
// Disable cache while node is being loaded (we'll re-enable it later)
|
||||
node->SetCachesEnabled(false);
|
||||
node->Load(reader, &project_data);
|
||||
load_data.nodes.append(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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 {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipped_items.empty()) {
|
||||
for (auto it = project_data.desired_connections.begin(); it != project_data.desired_connections.end(); ) {
|
||||
const SerializedData::SerializedConnection &sc = *it;
|
||||
|
||||
if (Node *si = skipped_items.value(sc.output_node)) {
|
||||
// Convert this to a promised connection
|
||||
Node::OutputConnection oc = {si, sc.input};
|
||||
load_data.promised_connections.push_back(oc);
|
||||
it = project_data.desired_connections.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve serialized properties (if any)
|
||||
for (auto it=properties.cbegin(); it!=properties.cend(); it++) {
|
||||
Node *node = project_data.node_ptrs.value(it.key());
|
||||
if (node) {
|
||||
load_data.properties.insert(node, it.value());
|
||||
}
|
||||
}
|
||||
|
||||
PostConnect(load_data.nodes, &project_data);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return load_data;
|
||||
}
|
||||
|
||||
void WriteNodeMap(QXmlStreamWriter *writer, Node *node, const QVector<Node*> &nodes)
|
||||
ProjectSerializer230220::LoadData
|
||||
ProjectSerializer230220::Load(Project *project, QXmlStreamReader *reader,
|
||||
LoadType load_type, void *reserved) const
|
||||
{
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
QMap<quintptr, QMap<QString, QString>> properties;
|
||||
QMap<quintptr, QMap<quintptr, Node::Position>> positions;
|
||||
LoadData load_data;
|
||||
SerializedData project_data;
|
||||
|
||||
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(node)));
|
||||
switch (load_type) {
|
||||
case kProject: {
|
||||
if (reader->name() == QStringLiteral("project")) {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("project")) {
|
||||
project_data = project->Load(reader);
|
||||
} else if (reader->name() == QStringLiteral("layout")) {
|
||||
load_data.layout = MainWindowLayoutInfo::fromXml(
|
||||
reader, project_data.node_ptrs);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto oc : node->output_connections()) {
|
||||
if (nodes.contains(oc.second.node())) {
|
||||
WriteNodeMap(writer, oc.second.node(), nodes);
|
||||
}
|
||||
}
|
||||
PostConnect(project->nodes(), &project_data);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kOnlyMarkers: {
|
||||
if (reader->name() == QStringLiteral("markers")) {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("marker")) {
|
||||
TimelineMarker *marker = new TimelineMarker();
|
||||
marker->load(reader);
|
||||
load_data.markers.push_back(marker);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kOnlyKeyframes: {
|
||||
if (reader->name() == QStringLiteral("keyframes")) {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("node")) {
|
||||
QString node_id;
|
||||
XMLAttributeLoop(reader, attr)
|
||||
{
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
node_id = attr.value().toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
writer->writeEndElement();
|
||||
Node *n = nullptr;
|
||||
if (!node_id.isEmpty()) {
|
||||
n = NodeFactory::CreateFromID(node_id);
|
||||
}
|
||||
|
||||
if (!n) {
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("input")) {
|
||||
QString input_id;
|
||||
XMLAttributeLoop(reader, attr)
|
||||
{
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
input_id = attr.value().toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (input_id.isEmpty()) {
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() ==
|
||||
QStringLiteral("element")) {
|
||||
QString element_id;
|
||||
XMLAttributeLoop(reader, attr)
|
||||
{
|
||||
if (attr.name() ==
|
||||
QStringLiteral("id")) {
|
||||
element_id =
|
||||
attr.value().toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (element_id.isEmpty()) {
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
while (XMLReadNextStartElement(
|
||||
reader)) {
|
||||
if (reader->name() ==
|
||||
QStringLiteral(
|
||||
"track")) {
|
||||
QString track_id;
|
||||
XMLAttributeLoop(reader,
|
||||
attr)
|
||||
{
|
||||
if (attr.name() ==
|
||||
QStringLiteral(
|
||||
"id")) {
|
||||
track_id =
|
||||
attr.value()
|
||||
.toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (track_id.isEmpty()) {
|
||||
reader
|
||||
->skipCurrentElement();
|
||||
} else {
|
||||
while (
|
||||
XMLReadNextStartElement(
|
||||
reader)) {
|
||||
if (reader
|
||||
->name() ==
|
||||
QStringLiteral(
|
||||
"key")) {
|
||||
NodeKeyframe *key =
|
||||
new NodeKeyframe();
|
||||
key->set_input(
|
||||
input_id);
|
||||
key->set_element(
|
||||
element_id
|
||||
.toInt());
|
||||
key->set_track(
|
||||
track_id
|
||||
.toInt());
|
||||
|
||||
key->load(
|
||||
reader,
|
||||
n->GetInputDataType(
|
||||
input_id));
|
||||
|
||||
load_data
|
||||
.keyframes
|
||||
[node_id]
|
||||
.append(
|
||||
key);
|
||||
} else {
|
||||
reader
|
||||
->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader
|
||||
->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete n;
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kOnlyClips:
|
||||
case kOnlyNodes: {
|
||||
if ((load_type == kOnlyNodes &&
|
||||
reader->name() == QStringLiteral("nodes")) ||
|
||||
(load_type == kOnlyClips &&
|
||||
reader->name() == QStringLiteral("timeline"))) {
|
||||
QMap<quintptr, Node *> skipped_items;
|
||||
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("node")) {
|
||||
QString id;
|
||||
quintptr ptr = 0;
|
||||
QVector<quintptr> items;
|
||||
|
||||
XMLAttributeLoop(reader, attr)
|
||||
{
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
id = attr.value().toString();
|
||||
} else if (attr.name() == QStringLiteral("ptr")) {
|
||||
ptr = attr.value().toULongLong();
|
||||
} else if (attr.name() == QStringLiteral("items")) {
|
||||
QVector<QStringView> l = attr.value().split(',');
|
||||
items.reserve(l.size());
|
||||
for (const QStringView &s : l) {
|
||||
items.append(s.toULongLong());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (id.isEmpty()) {
|
||||
qWarning() << "Failed to load node with empty ID";
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
bool dependency_of_item = false;
|
||||
|
||||
if (project && !items.empty()) {
|
||||
for (quintptr p : items) {
|
||||
if (project->nodes().contains(
|
||||
reinterpret_cast<Node *>(p))) {
|
||||
dependency_of_item = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dependency_of_item) {
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
Node *node = NodeFactory::CreateFromID(id);
|
||||
if (!node) {
|
||||
qWarning()
|
||||
<< "Failed to find node with ID" << id;
|
||||
reader->skipCurrentElement();
|
||||
} else {
|
||||
if (project && node->IsItem() && ptr) {
|
||||
// If we're pasting an object into the same project, we should re-use the item
|
||||
// rather than duplicate.
|
||||
Node *existing =
|
||||
reinterpret_cast<Node *>(ptr);
|
||||
if (project->nodes().contains(existing)) {
|
||||
// Connect this
|
||||
skipped_items.insert(ptr, existing);
|
||||
|
||||
// Don't continue loading this
|
||||
delete node;
|
||||
node = nullptr;
|
||||
|
||||
// Skip element
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (node) {
|
||||
// Disable cache while node is being loaded (we'll re-enable it later)
|
||||
node->SetCachesEnabled(false);
|
||||
node->Load(reader, &project_data);
|
||||
load_data.nodes.append(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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 {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipped_items.empty()) {
|
||||
for (auto it = project_data.desired_connections.begin();
|
||||
it != project_data.desired_connections.end();) {
|
||||
const SerializedData::SerializedConnection &sc = *it;
|
||||
|
||||
if (Node *si = skipped_items.value(sc.output_node)) {
|
||||
// Convert this to a promised connection
|
||||
Node::OutputConnection oc = { si, sc.input };
|
||||
load_data.promised_connections.push_back(oc);
|
||||
it = project_data.desired_connections.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve serialized properties (if any)
|
||||
for (auto it = properties.cbegin(); it != properties.cend(); it++) {
|
||||
Node *node = project_data.node_ptrs.value(it.key());
|
||||
if (node) {
|
||||
load_data.properties.insert(node, it.value());
|
||||
}
|
||||
}
|
||||
|
||||
PostConnect(load_data.nodes, &project_data);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return load_data;
|
||||
}
|
||||
|
||||
void ProjectSerializer230220::Save(QXmlStreamWriter *writer, const SaveData &data, void *reserved) const
|
||||
void WriteNodeMap(QXmlStreamWriter *writer, Node *node,
|
||||
const QVector<Node *> &nodes)
|
||||
{
|
||||
if (!data.GetOnlySerializeMarkers().empty()) {
|
||||
writer->writeStartElement(QStringLiteral("markers"));
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
|
||||
writer->writeAttribute(QStringLiteral("ptr"),
|
||||
QString::number(reinterpret_cast<quintptr>(node)));
|
||||
|
||||
for (auto it=data.GetOnlySerializeMarkers().cbegin(); it!=data.GetOnlySerializeMarkers().cend(); it++) {
|
||||
TimelineMarker *marker = *it;
|
||||
writer->writeStartElement(QStringLiteral("marker"));
|
||||
marker->save(writer);
|
||||
writer->writeEndElement(); // marker
|
||||
}
|
||||
for (auto oc : node->output_connections()) {
|
||||
if (nodes.contains(oc.second.node())) {
|
||||
WriteNodeMap(writer, oc.second.node(), nodes);
|
||||
}
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // markers
|
||||
} else if (!data.GetOnlySerializeKeyframes().empty()) {
|
||||
writer->writeStartElement(QStringLiteral("keyframes"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
|
||||
|
||||
// Organize keyframes into node+input
|
||||
QHash<QString, QHash<QString, QMap<int, QMap<int, QVector<NodeKeyframe*> > > > > organized;
|
||||
|
||||
for (auto it=data.GetOnlySerializeKeyframes().cbegin(); it!=data.GetOnlySerializeKeyframes().cend(); it++) {
|
||||
NodeKeyframe *key = *it;
|
||||
organized[key->parent()->id()][key->input()][key->element()][key->track()].append(key);
|
||||
}
|
||||
|
||||
for (auto it=organized.cbegin(); it!=organized.cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), it.key());
|
||||
|
||||
for (auto jt=it.value().cbegin(); jt!=it.value().cend(); jt++) {
|
||||
writer->writeStartElement(QStringLiteral("input"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), jt.key());
|
||||
|
||||
for (auto kt=jt.value().cbegin(); kt!=jt.value().cend(); kt++) {
|
||||
writer->writeStartElement(QStringLiteral("element"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), QString::number(kt.key()));
|
||||
|
||||
for (auto lt=kt.value().cbegin(); lt!=kt.value().cend(); lt++) {
|
||||
const QVector<NodeKeyframe *> &keys = lt.value();
|
||||
|
||||
writer->writeStartElement(QStringLiteral("track"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), QString::number(lt.key()));
|
||||
|
||||
for (NodeKeyframe *key : keys) {
|
||||
writer->writeStartElement(QStringLiteral("key"));
|
||||
key->save(writer, key->parent()->GetInputDataType(key->input()));
|
||||
writer->writeEndElement(); // key
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // track
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // element
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // input
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // node;
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // keyframes
|
||||
} else if (!data.GetOnlySerializeNodes().empty()) {
|
||||
if (data.type() == kOnlyClips) {
|
||||
writer->writeStartElement(QStringLiteral("timeline"));
|
||||
} else {
|
||||
writer->writeStartElement(QStringLiteral("nodes"));
|
||||
}
|
||||
|
||||
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
|
||||
|
||||
for (Node *n : data.GetOnlySerializeNodes()) {
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
|
||||
QStringList item_list;
|
||||
for (Node *i : data.GetOnlySerializeNodes()) {
|
||||
if (i->IsItem() && i->InputsFrom(n, true)) {
|
||||
item_list.append(QString::number(reinterpret_cast<quintptr>(i)));
|
||||
}
|
||||
}
|
||||
if (!item_list.empty()) {
|
||||
writer->writeAttribute(QStringLiteral("items"), item_list.join(','));
|
||||
}
|
||||
|
||||
n->Save(writer);
|
||||
writer->writeEndElement(); // node
|
||||
}
|
||||
|
||||
if (!data.GetProperties().empty()) {
|
||||
writer->writeStartElement(QStringLiteral("properties"));
|
||||
for (auto it=data.GetProperties().cbegin(); it!=data.GetProperties().cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(it.key())));
|
||||
|
||||
for (auto jt=it.value().cbegin(); jt!=it.value().cend(); jt++) {
|
||||
writer->writeTextElement(jt.key(), jt.value());
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // node
|
||||
}
|
||||
writer->writeEndElement(); // properties
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // nodes
|
||||
} else if (Project *project = data.GetProject()) {
|
||||
writer->writeStartElement(QStringLiteral("project"));
|
||||
|
||||
writer->writeStartElement(QStringLiteral("project"));
|
||||
project->Save(writer);
|
||||
writer->writeEndElement(); // project
|
||||
|
||||
writer->writeStartElement(QStringLiteral("layout"));
|
||||
data.GetLayout().toXml(writer);
|
||||
writer->writeEndElement(); // layout
|
||||
|
||||
writer->writeEndElement(); // project
|
||||
} else {
|
||||
qCritical() << "ProjectSerializer provided nothing to save";
|
||||
}
|
||||
writer->writeEndElement();
|
||||
}
|
||||
|
||||
void ProjectSerializer230220::PostConnect(const QVector<Node *> &nodes, SerializedData *project_data) const
|
||||
void ProjectSerializer230220::Save(QXmlStreamWriter *writer,
|
||||
const SaveData &data, void *reserved) const
|
||||
{
|
||||
foreach (const SerializedData::SerializedConnection& con, project_data->desired_connections) {
|
||||
if (Node *out = project_data->node_ptrs.value(con.output_node)) {
|
||||
Node::ConnectEdge(out, con.input);
|
||||
}
|
||||
}
|
||||
if (!data.GetOnlySerializeMarkers().empty()) {
|
||||
writer->writeStartElement(QStringLiteral("markers"));
|
||||
|
||||
foreach (const SerializedData::BlockLink& l, project_data->block_links) {
|
||||
Node *a = l.block;
|
||||
Node *b = project_data->node_ptrs.value(l.link);
|
||||
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
|
||||
|
||||
Node::Link(a, b);
|
||||
}
|
||||
for (auto it = data.GetOnlySerializeMarkers().cbegin();
|
||||
it != data.GetOnlySerializeMarkers().cend(); it++) {
|
||||
TimelineMarker *marker = *it;
|
||||
writer->writeStartElement(QStringLiteral("marker"));
|
||||
marker->save(writer);
|
||||
writer->writeEndElement(); // marker
|
||||
}
|
||||
|
||||
for (auto it = nodes.cbegin(); it != nodes.cend(); it++){
|
||||
Node *n = *it;
|
||||
writer->writeEndElement(); // markers
|
||||
} else if (!data.GetOnlySerializeKeyframes().empty()) {
|
||||
writer->writeStartElement(QStringLiteral("keyframes"));
|
||||
|
||||
n->PostLoadEvent(project_data);
|
||||
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
|
||||
|
||||
n->SetCachesEnabled(true);
|
||||
}
|
||||
// Organize keyframes into node+input
|
||||
QHash<QString,
|
||||
QHash<QString, QMap<int, QMap<int, QVector<NodeKeyframe *>>>>>
|
||||
organized;
|
||||
|
||||
for (auto it = data.GetOnlySerializeKeyframes().cbegin();
|
||||
it != data.GetOnlySerializeKeyframes().cend(); it++) {
|
||||
NodeKeyframe *key = *it;
|
||||
organized[key->parent()->id()][key->input()][key->element()]
|
||||
[key->track()]
|
||||
.append(key);
|
||||
}
|
||||
|
||||
for (auto it = organized.cbegin(); it != organized.cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), it.key());
|
||||
|
||||
for (auto jt = it.value().cbegin(); jt != it.value().cend(); jt++) {
|
||||
writer->writeStartElement(QStringLiteral("input"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), jt.key());
|
||||
|
||||
for (auto kt = jt.value().cbegin(); kt != jt.value().cend();
|
||||
kt++) {
|
||||
writer->writeStartElement(QStringLiteral("element"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"),
|
||||
QString::number(kt.key()));
|
||||
|
||||
for (auto lt = kt.value().cbegin(); lt != kt.value().cend();
|
||||
lt++) {
|
||||
const QVector<NodeKeyframe *> &keys = lt.value();
|
||||
|
||||
writer->writeStartElement(QStringLiteral("track"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"),
|
||||
QString::number(lt.key()));
|
||||
|
||||
for (NodeKeyframe *key : keys) {
|
||||
writer->writeStartElement(QStringLiteral("key"));
|
||||
key->save(writer, key->parent()->GetInputDataType(
|
||||
key->input()));
|
||||
writer->writeEndElement(); // key
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // track
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // element
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // input
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // node;
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // keyframes
|
||||
} else if (!data.GetOnlySerializeNodes().empty()) {
|
||||
if (data.type() == kOnlyClips) {
|
||||
writer->writeStartElement(QStringLiteral("timeline"));
|
||||
} else {
|
||||
writer->writeStartElement(QStringLiteral("nodes"));
|
||||
}
|
||||
|
||||
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
|
||||
|
||||
for (Node *n : data.GetOnlySerializeNodes()) {
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
|
||||
QStringList item_list;
|
||||
for (Node *i : data.GetOnlySerializeNodes()) {
|
||||
if (i->IsItem() && i->InputsFrom(n, true)) {
|
||||
item_list.append(
|
||||
QString::number(reinterpret_cast<quintptr>(i)));
|
||||
}
|
||||
}
|
||||
if (!item_list.empty()) {
|
||||
writer->writeAttribute(QStringLiteral("items"),
|
||||
item_list.join(','));
|
||||
}
|
||||
|
||||
n->Save(writer);
|
||||
writer->writeEndElement(); // node
|
||||
}
|
||||
|
||||
if (!data.GetProperties().empty()) {
|
||||
writer->writeStartElement(QStringLiteral("properties"));
|
||||
for (auto it = data.GetProperties().cbegin();
|
||||
it != data.GetProperties().cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
|
||||
writer->writeAttribute(
|
||||
QStringLiteral("ptr"),
|
||||
QString::number(reinterpret_cast<quintptr>(it.key())));
|
||||
|
||||
for (auto jt = it.value().cbegin(); jt != it.value().cend();
|
||||
jt++) {
|
||||
writer->writeTextElement(jt.key(), jt.value());
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // node
|
||||
}
|
||||
writer->writeEndElement(); // properties
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // nodes
|
||||
} else if (Project *project = data.GetProject()) {
|
||||
writer->writeStartElement(QStringLiteral("project"));
|
||||
|
||||
writer->writeStartElement(QStringLiteral("project"));
|
||||
project->Save(writer);
|
||||
writer->writeEndElement(); // project
|
||||
|
||||
writer->writeStartElement(QStringLiteral("layout"));
|
||||
data.GetLayout().toXml(writer);
|
||||
writer->writeEndElement(); // layout
|
||||
|
||||
writer->writeEndElement(); // project
|
||||
} else {
|
||||
qCritical() << "ProjectSerializer provided nothing to save";
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSerializer230220::PostConnect(const QVector<Node *> &nodes,
|
||||
SerializedData *project_data) const
|
||||
{
|
||||
foreach (const SerializedData::SerializedConnection &con,
|
||||
project_data->desired_connections) {
|
||||
if (Node *out = project_data->node_ptrs.value(con.output_node)) {
|
||||
Node::ConnectEdge(out, con.input);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const SerializedData::BlockLink &l, project_data->block_links) {
|
||||
Node *a = l.block;
|
||||
Node *b = project_data->node_ptrs.value(l.link);
|
||||
|
||||
Node::Link(a, b);
|
||||
}
|
||||
|
||||
for (auto it = nodes.cbegin(); it != nodes.cend(); it++) {
|
||||
Node *n = *it;
|
||||
|
||||
n->PostLoadEvent(project_data);
|
||||
|
||||
n->SetCachesEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user