change: change code style to Linux style except indent.
This commit is contained in:
@@ -34,274 +34,299 @@
|
||||
#include "serializer220403.h"
|
||||
#include "serializer230220.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
QVector<ProjectSerializer*> ProjectSerializer::instances_;
|
||||
QVector<ProjectSerializer *> ProjectSerializer::instances_;
|
||||
|
||||
void ProjectSerializer::Initialize()
|
||||
{
|
||||
// Make sure to order these from oldest to newest
|
||||
// Make sure to order these from oldest to newest
|
||||
|
||||
// FIXME: Implement this - yes it's a 0.1 project loader
|
||||
//instances_.append(new ProjectSerializer190219);
|
||||
// FIXME: Implement this - yes it's a 0.1 project loader
|
||||
//instances_.append(new ProjectSerializer190219);
|
||||
|
||||
instances_.append(new ProjectSerializer210528);
|
||||
instances_.append(new ProjectSerializer210907);
|
||||
instances_.append(new ProjectSerializer211228);
|
||||
instances_.append(new ProjectSerializer220403);
|
||||
instances_.append(new ProjectSerializer230220);
|
||||
instances_.append(new ProjectSerializer210528);
|
||||
instances_.append(new ProjectSerializer210907);
|
||||
instances_.append(new ProjectSerializer211228);
|
||||
instances_.append(new ProjectSerializer220403);
|
||||
instances_.append(new ProjectSerializer230220);
|
||||
}
|
||||
|
||||
void ProjectSerializer::Destroy()
|
||||
{
|
||||
qDeleteAll(instances_);
|
||||
instances_.clear();
|
||||
qDeleteAll(instances_);
|
||||
instances_.clear();
|
||||
}
|
||||
|
||||
ProjectSerializer::Result ProjectSerializer::Load(Project *project, const QString &filename, LoadType load_type)
|
||||
ProjectSerializer::Result ProjectSerializer::Load(Project *project,
|
||||
const QString &filename,
|
||||
LoadType load_type)
|
||||
{
|
||||
QFile project_file(filename);
|
||||
QFile project_file(filename);
|
||||
|
||||
if (project_file.open(QFile::ReadOnly)) {
|
||||
// Some project files are compressed, marked with "OVEC" at the beginning of the file. Check for
|
||||
// that signature now.
|
||||
std::unique_ptr<QXmlStreamReader> reader;
|
||||
if (CheckCompressedID(&project_file)) {
|
||||
// File is compressed, decompress into memory
|
||||
QByteArray b;
|
||||
b = qUncompress(project_file.readAll());
|
||||
reader.reset(new QXmlStreamReader(b));
|
||||
} else {
|
||||
project_file.seek(0);
|
||||
reader.reset(new QXmlStreamReader(&project_file));
|
||||
}
|
||||
if (project_file.open(QFile::ReadOnly)) {
|
||||
// Some project files are compressed, marked with "OVEC" at the beginning of the file. Check for
|
||||
// that signature now.
|
||||
std::unique_ptr<QXmlStreamReader> reader;
|
||||
if (CheckCompressedID(&project_file)) {
|
||||
// File is compressed, decompress into memory
|
||||
QByteArray b;
|
||||
b = qUncompress(project_file.readAll());
|
||||
reader.reset(new QXmlStreamReader(b));
|
||||
} else {
|
||||
project_file.seek(0);
|
||||
reader.reset(new QXmlStreamReader(&project_file));
|
||||
}
|
||||
|
||||
Result inner_result = Load(project, reader.get(), load_type);
|
||||
Result inner_result = Load(project, reader.get(), load_type);
|
||||
|
||||
project_file.close();
|
||||
project_file.close();
|
||||
|
||||
if (inner_result.code() != kSuccess) {
|
||||
return inner_result;
|
||||
}
|
||||
if (inner_result.code() != kSuccess) {
|
||||
return inner_result;
|
||||
}
|
||||
|
||||
if (reader->hasError()) {
|
||||
Result r(kXmlError);
|
||||
r.SetDetails(reader->errorString());
|
||||
return r;
|
||||
} else {
|
||||
return inner_result;
|
||||
}
|
||||
} else {
|
||||
return kFileError;
|
||||
}
|
||||
if (reader->hasError()) {
|
||||
Result r(kXmlError);
|
||||
r.SetDetails(reader->errorString());
|
||||
return r;
|
||||
} else {
|
||||
return inner_result;
|
||||
}
|
||||
} else {
|
||||
return kFileError;
|
||||
}
|
||||
}
|
||||
|
||||
ProjectSerializer::Result ProjectSerializer::Load(Project *project, QXmlStreamReader *reader, LoadType load_type)
|
||||
ProjectSerializer::Result ProjectSerializer::Load(Project *project,
|
||||
QXmlStreamReader *reader,
|
||||
LoadType load_type)
|
||||
{
|
||||
// Determine project version
|
||||
uint version = 0;
|
||||
Result res = kUnknownVersion;
|
||||
// Determine project version
|
||||
uint version = 0;
|
||||
Result res = kUnknownVersion;
|
||||
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("olive")
|
||||
|| reader->name() == QStringLiteral("project")) { // 0.1 projects only
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("olive") ||
|
||||
reader->name() == QStringLiteral("project")) { // 0.1 projects only
|
||||
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("version")) { // 230220+ projects
|
||||
version = attr.value().toUInt();
|
||||
} else if (reader->name() == QStringLiteral("url")) { // 230220+ projects
|
||||
project->SetSavedURL(attr.value().toString());
|
||||
}
|
||||
}
|
||||
XMLAttributeLoop(reader, attr)
|
||||
{
|
||||
if (attr.name() ==
|
||||
QStringLiteral("version")) { // 230220+ projects
|
||||
version = attr.value().toUInt();
|
||||
} else if (reader->name() ==
|
||||
QStringLiteral("url")) { // 230220+ projects
|
||||
project->SetSavedURL(attr.value().toString());
|
||||
}
|
||||
}
|
||||
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("version")) { // projects <= 220403
|
||||
version = reader->readElementText().toUInt();
|
||||
} else if (reader->name() == QStringLiteral("url")) { // projects <= 220403
|
||||
if (project) {
|
||||
project->SetSavedURL(reader->readElementText());
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
} else {
|
||||
// Handle any other value with the serializer
|
||||
res = LoadWithSerializerVersion(version, project, reader, load_type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() ==
|
||||
QStringLiteral("version")) { // projects <= 220403
|
||||
version = reader->readElementText().toUInt();
|
||||
} else if (reader->name() ==
|
||||
QStringLiteral("url")) { // projects <= 220403
|
||||
if (project) {
|
||||
project->SetSavedURL(reader->readElementText());
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
} else {
|
||||
// Handle any other value with the serializer
|
||||
res = LoadWithSerializerVersion(version, project, reader,
|
||||
load_type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
ProjectSerializer::Result ProjectSerializer::Paste(LoadType load_type, Project *project)
|
||||
ProjectSerializer::Result ProjectSerializer::Paste(LoadType load_type,
|
||||
Project *project)
|
||||
{
|
||||
QString clipboard = Core::PasteStringFromClipboard();
|
||||
if (clipboard.isEmpty()) {
|
||||
return kNoData;
|
||||
}
|
||||
QString clipboard = Core::PasteStringFromClipboard();
|
||||
if (clipboard.isEmpty()) {
|
||||
return kNoData;
|
||||
}
|
||||
|
||||
QXmlStreamReader reader(clipboard);
|
||||
QXmlStreamReader reader(clipboard);
|
||||
|
||||
return ProjectSerializer::Load(project, &reader, load_type);
|
||||
return ProjectSerializer::Load(project, &reader, load_type);
|
||||
}
|
||||
|
||||
ProjectSerializer::Result ProjectSerializer::Save(const SaveData &data, bool compress)
|
||||
ProjectSerializer::Result ProjectSerializer::Save(const SaveData &data,
|
||||
bool compress)
|
||||
{
|
||||
QString temp_save = FileFunctions::GetSafeTemporaryFilename(data.GetFilename());
|
||||
QString temp_save =
|
||||
FileFunctions::GetSafeTemporaryFilename(data.GetFilename());
|
||||
|
||||
QFile project_file(temp_save);
|
||||
QFile project_file(temp_save);
|
||||
|
||||
if (project_file.open(QFile::WriteOnly)) {
|
||||
QByteArray b;
|
||||
QXmlStreamWriter writer(&b);
|
||||
if (project_file.open(QFile::WriteOnly)) {
|
||||
QByteArray b;
|
||||
QXmlStreamWriter writer(&b);
|
||||
|
||||
Result inner_result = Save(&writer, data);
|
||||
Result inner_result = Save(&writer, data);
|
||||
|
||||
if (writer.hasError()) {
|
||||
Result r(kXmlError);
|
||||
return r;
|
||||
}
|
||||
if (writer.hasError()) {
|
||||
Result r(kXmlError);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (compress) {
|
||||
project_file.write("OVEC");
|
||||
project_file.write(qCompress(b));
|
||||
} else {
|
||||
project_file.write(b);
|
||||
}
|
||||
if (compress) {
|
||||
project_file.write("OVEC");
|
||||
project_file.write(qCompress(b));
|
||||
} else {
|
||||
project_file.write(b);
|
||||
}
|
||||
|
||||
project_file.close();
|
||||
project_file.close();
|
||||
|
||||
if (inner_result != kSuccess) {
|
||||
return inner_result;
|
||||
}
|
||||
if (inner_result != kSuccess) {
|
||||
return inner_result;
|
||||
}
|
||||
|
||||
// Save was successful, we can now rewrite the original file
|
||||
if (FileFunctions::RenameFileAllowOverwrite(temp_save, data.GetFilename())) {
|
||||
return kSuccess;
|
||||
} else {
|
||||
Result r(kOverwriteError);
|
||||
r.SetDetails(temp_save);
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
Result r(kFileError);
|
||||
r.SetDetails(temp_save);
|
||||
return r;
|
||||
}
|
||||
// Save was successful, we can now rewrite the original file
|
||||
if (FileFunctions::RenameFileAllowOverwrite(temp_save,
|
||||
data.GetFilename())) {
|
||||
return kSuccess;
|
||||
} else {
|
||||
Result r(kOverwriteError);
|
||||
r.SetDetails(temp_save);
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
Result r(kFileError);
|
||||
r.SetDetails(temp_save);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
ProjectSerializer::Result ProjectSerializer::Save(QXmlStreamWriter *writer, const SaveData &data)
|
||||
ProjectSerializer::Result ProjectSerializer::Save(QXmlStreamWriter *writer,
|
||||
const SaveData &data)
|
||||
{
|
||||
writer->setAutoFormatting(true);
|
||||
writer->setAutoFormatting(true);
|
||||
|
||||
writer->writeStartDocument();
|
||||
writer->writeStartDocument();
|
||||
|
||||
writer->writeStartElement("olive");
|
||||
writer->writeStartElement("olive");
|
||||
|
||||
// By default, save as last serializer which, assuming the instances are ordered correctly,
|
||||
// will be the newest file format. But we may allow saving as older versions later on.
|
||||
ProjectSerializer *serializer = instances_.last();
|
||||
// By default, save as last serializer which, assuming the instances are ordered correctly,
|
||||
// will be the newest file format. But we may allow saving as older versions later on.
|
||||
ProjectSerializer *serializer = instances_.last();
|
||||
|
||||
// Version is stored in YYMMDD from whenever the project format was last changed
|
||||
// Allows easy integer math for checking project versions.
|
||||
writer->writeAttribute(QStringLiteral("version"), QString::number(serializer->Version()));
|
||||
// Version is stored in YYMMDD from whenever the project format was last changed
|
||||
// Allows easy integer math for checking project versions.
|
||||
writer->writeAttribute(QStringLiteral("version"),
|
||||
QString::number(serializer->Version()));
|
||||
|
||||
if (!data.GetFilename().isEmpty()) {
|
||||
writer->writeAttribute("url", data.GetFilename());
|
||||
}
|
||||
if (!data.GetFilename().isEmpty()) {
|
||||
writer->writeAttribute("url", data.GetFilename());
|
||||
}
|
||||
|
||||
serializer->Save(writer, data, nullptr);
|
||||
serializer->Save(writer, data, nullptr);
|
||||
|
||||
writer->writeEndElement(); // olive
|
||||
writer->writeEndElement(); // olive
|
||||
|
||||
writer->writeEndDocument();
|
||||
writer->writeEndDocument();
|
||||
|
||||
if (writer->hasError()) {
|
||||
return kXmlError;
|
||||
}
|
||||
if (writer->hasError()) {
|
||||
return kXmlError;
|
||||
}
|
||||
|
||||
return kSuccess;
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
ProjectSerializer::Result ProjectSerializer::Copy(const SaveData &data)
|
||||
{
|
||||
QString copy_str;
|
||||
QXmlStreamWriter writer(©_str);
|
||||
QString copy_str;
|
||||
QXmlStreamWriter writer(©_str);
|
||||
|
||||
ProjectSerializer::Result res = ProjectSerializer::Save(&writer, data);
|
||||
ProjectSerializer::Result res = ProjectSerializer::Save(&writer, data);
|
||||
|
||||
if (res == kSuccess) {
|
||||
Core::CopyStringToClipboard(copy_str);
|
||||
}
|
||||
if (res == kSuccess) {
|
||||
Core::CopyStringToClipboard(copy_str);
|
||||
}
|
||||
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool ProjectSerializer::CheckCompressedID(QFile *file)
|
||||
{
|
||||
QByteArray b = file->read(4);
|
||||
return !memcmp(b.data(), "OVEC", 4);
|
||||
QByteArray b = file->read(4);
|
||||
return !memcmp(b.data(), "OVEC", 4);
|
||||
}
|
||||
|
||||
bool ProjectSerializer::IsCancelled() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectSerializer::Result ProjectSerializer::LoadWithSerializerVersion(uint version, Project *project, QXmlStreamReader *reader, LoadType load_type)
|
||||
ProjectSerializer::Result
|
||||
ProjectSerializer::LoadWithSerializerVersion(uint version, Project *project,
|
||||
QXmlStreamReader *reader,
|
||||
LoadType load_type)
|
||||
{
|
||||
// Failed to find version in file
|
||||
if (version == 0) {
|
||||
return kUnknownVersion;
|
||||
}
|
||||
// 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;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
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, load_type, nullptr);
|
||||
Result r(kSuccess);
|
||||
if (reader->hasError()) {
|
||||
r = Result(kXmlError);
|
||||
r.SetDetails(QCoreApplication::translate("Serializer", "%1 on line %2").arg(reader->errorString(), QString::number(reader->lineNumber())));
|
||||
}
|
||||
r.SetLoadData(ld);
|
||||
return r;
|
||||
} else {
|
||||
// Reached the end of the list with no serializer, assume too new
|
||||
return kProjectTooNew;
|
||||
}
|
||||
if (serializer) {
|
||||
LoadData ld = serializer->Load(project, reader, load_type, nullptr);
|
||||
Result r(kSuccess);
|
||||
if (reader->hasError()) {
|
||||
r = Result(kXmlError);
|
||||
r.SetDetails(
|
||||
QCoreApplication::translate("Serializer", "%1 on line %2")
|
||||
.arg(reader->errorString(),
|
||||
QString::number(reader->lineNumber())));
|
||||
}
|
||||
r.SetLoadData(ld);
|
||||
return r;
|
||||
} else {
|
||||
// Reached the end of the list with no serializer, assume too new
|
||||
return kProjectTooNew;
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSerializer::SaveData::SetOnlySerializeNodesAndResolveGroups(QVector<Node *> nodes)
|
||||
void ProjectSerializer::SaveData::SetOnlySerializeNodesAndResolveGroups(
|
||||
QVector<Node *> nodes)
|
||||
{
|
||||
// For any groups, add children
|
||||
for (int i=0; i<nodes.size(); i++) {
|
||||
// If this is a group, add the child nodes too
|
||||
if (NodeGroup *g = dynamic_cast<NodeGroup*>(nodes.at(i))) {
|
||||
for (auto it=g->GetContextPositions().cbegin(); it!=g->GetContextPositions().cend(); it++) {
|
||||
if (!nodes.contains(it.key())) {
|
||||
nodes.append(it.key());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// For any groups, add children
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
// If this is a group, add the child nodes too
|
||||
if (NodeGroup *g = dynamic_cast<NodeGroup *>(nodes.at(i))) {
|
||||
for (auto it = g->GetContextPositions().cbegin();
|
||||
it != g->GetContextPositions().cend(); it++) {
|
||||
if (!nodes.contains(it.key())) {
|
||||
nodes.append(it.key());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetOnlySerializeNodes(nodes);
|
||||
SetOnlySerializeNodes(nodes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
#include "node/project.h"
|
||||
#include "typeserializer.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief An abstract base class for serializing/deserializing project data
|
||||
@@ -35,167 +36,236 @@ namespace olive {
|
||||
* The goal of this is to further abstract serialized project data from their
|
||||
* in-memory representations.
|
||||
*/
|
||||
class ProjectSerializer
|
||||
{
|
||||
class ProjectSerializer {
|
||||
public:
|
||||
enum LoadType
|
||||
{
|
||||
kProject,
|
||||
kOnlyNodes,
|
||||
kOnlyClips,
|
||||
kOnlyMarkers,
|
||||
kOnlyKeyframes
|
||||
};
|
||||
enum LoadType {
|
||||
kProject,
|
||||
kOnlyNodes,
|
||||
kOnlyClips,
|
||||
kOnlyMarkers,
|
||||
kOnlyKeyframes
|
||||
};
|
||||
|
||||
ProjectSerializer() = default;
|
||||
ProjectSerializer() = default;
|
||||
|
||||
virtual ~ProjectSerializer(){}
|
||||
virtual ~ProjectSerializer()
|
||||
{
|
||||
}
|
||||
|
||||
DISABLE_COPY_MOVE(ProjectSerializer)
|
||||
DISABLE_COPY_MOVE(ProjectSerializer)
|
||||
|
||||
enum ResultCode {
|
||||
kSuccess,
|
||||
kProjectTooOld,
|
||||
kProjectTooNew,
|
||||
kUnknownVersion,
|
||||
kFileError,
|
||||
kXmlError,
|
||||
kOverwriteError,
|
||||
kNoData
|
||||
};
|
||||
enum ResultCode {
|
||||
kSuccess,
|
||||
kProjectTooOld,
|
||||
kProjectTooNew,
|
||||
kUnknownVersion,
|
||||
kFileError,
|
||||
kXmlError,
|
||||
kOverwriteError,
|
||||
kNoData
|
||||
};
|
||||
|
||||
using SerializedProperties = QHash<Node*, QMap<QString, QString> >;
|
||||
using SerializedKeyframes = QHash<QString, QVector<NodeKeyframe*> >;
|
||||
using SerializedProperties = QHash<Node *, QMap<QString, QString>>;
|
||||
using SerializedKeyframes = QHash<QString, QVector<NodeKeyframe *>>;
|
||||
|
||||
class LoadData
|
||||
{
|
||||
public:
|
||||
LoadData() = default;
|
||||
class LoadData {
|
||||
public:
|
||||
LoadData() = default;
|
||||
|
||||
SerializedProperties properties;
|
||||
SerializedProperties properties;
|
||||
|
||||
std::vector<TimelineMarker*> markers;
|
||||
std::vector<TimelineMarker *> markers;
|
||||
|
||||
SerializedKeyframes keyframes;
|
||||
SerializedKeyframes keyframes;
|
||||
|
||||
MainWindowLayoutInfo layout;
|
||||
MainWindowLayoutInfo layout;
|
||||
|
||||
QVector<Node*> nodes;
|
||||
QVector<Node *> nodes;
|
||||
|
||||
Node::OutputConnections promised_connections;
|
||||
Node::OutputConnections promised_connections;
|
||||
};
|
||||
|
||||
};
|
||||
class Result {
|
||||
public:
|
||||
Result(const ResultCode &code)
|
||||
: code_(code)
|
||||
{
|
||||
}
|
||||
|
||||
class Result
|
||||
{
|
||||
public:
|
||||
Result(const ResultCode &code) :
|
||||
code_(code)
|
||||
{}
|
||||
bool operator==(const ResultCode &code)
|
||||
{
|
||||
return code_ == code;
|
||||
}
|
||||
bool operator!=(const ResultCode &code)
|
||||
{
|
||||
return code_ != code;
|
||||
}
|
||||
|
||||
bool operator==(const ResultCode &code) { return code_ == code; }
|
||||
bool operator!=(const ResultCode &code) { return code_ != code; }
|
||||
const ResultCode &code() const
|
||||
{
|
||||
return code_;
|
||||
}
|
||||
|
||||
const ResultCode &code() const { return code_; }
|
||||
const QString &GetDetails() const
|
||||
{
|
||||
return details_;
|
||||
}
|
||||
|
||||
const QString &GetDetails() const { return details_; }
|
||||
void SetDetails(const QString &s)
|
||||
{
|
||||
details_ = s;
|
||||
}
|
||||
|
||||
void SetDetails(const QString &s) { details_ = s; }
|
||||
const LoadData &GetLoadData() const
|
||||
{
|
||||
return load_data_;
|
||||
}
|
||||
|
||||
const LoadData &GetLoadData() const { return load_data_; }
|
||||
void SetLoadData(const LoadData &p)
|
||||
{
|
||||
load_data_ = p;
|
||||
}
|
||||
|
||||
void SetLoadData(const LoadData &p) { load_data_ = p; }
|
||||
private:
|
||||
ResultCode code_;
|
||||
|
||||
private:
|
||||
ResultCode code_;
|
||||
QString details_;
|
||||
|
||||
QString details_;
|
||||
LoadData load_data_;
|
||||
};
|
||||
|
||||
LoadData load_data_;
|
||||
class SaveData {
|
||||
public:
|
||||
SaveData(LoadType type, Project *project = nullptr,
|
||||
const QString &filename = QString())
|
||||
{
|
||||
type_ = type;
|
||||
project_ = project;
|
||||
filename_ = filename;
|
||||
}
|
||||
|
||||
};
|
||||
Project *GetProject() const
|
||||
{
|
||||
return project_;
|
||||
}
|
||||
void SetProject(Project *p)
|
||||
{
|
||||
project_ = p;
|
||||
}
|
||||
|
||||
class SaveData
|
||||
{
|
||||
public:
|
||||
SaveData(LoadType type, Project *project = nullptr, const QString &filename = QString())
|
||||
{
|
||||
type_ = type;
|
||||
project_ = project;
|
||||
filename_ = filename;
|
||||
}
|
||||
const QString &GetFilename() const
|
||||
{
|
||||
return filename_;
|
||||
}
|
||||
void SetFilename(const QString &s)
|
||||
{
|
||||
filename_ = s;
|
||||
}
|
||||
|
||||
Project *GetProject() const { return project_; }
|
||||
void SetProject(Project *p) { project_ = p; }
|
||||
LoadType type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
const QString &GetFilename() const { return filename_; }
|
||||
void SetFilename(const QString &s) { filename_ = s; }
|
||||
const MainWindowLayoutInfo &GetLayout() const
|
||||
{
|
||||
return layout_;
|
||||
}
|
||||
void SetLayout(const MainWindowLayoutInfo &layout)
|
||||
{
|
||||
layout_ = layout;
|
||||
}
|
||||
|
||||
LoadType type() const { return type_; }
|
||||
const QVector<Node *> &GetOnlySerializeNodes() const
|
||||
{
|
||||
return only_serialize_nodes_;
|
||||
}
|
||||
void SetOnlySerializeNodes(const QVector<Node *> &only)
|
||||
{
|
||||
only_serialize_nodes_ = only;
|
||||
}
|
||||
void SetOnlySerializeNodesAndResolveGroups(QVector<Node *> only);
|
||||
|
||||
const MainWindowLayoutInfo &GetLayout() const { return layout_; }
|
||||
void SetLayout(const MainWindowLayoutInfo &layout) { layout_ = layout; }
|
||||
const std::vector<TimelineMarker *> &GetOnlySerializeMarkers() const
|
||||
{
|
||||
return only_serialize_markers_;
|
||||
}
|
||||
void SetOnlySerializeMarkers(const std::vector<TimelineMarker *> &only)
|
||||
{
|
||||
only_serialize_markers_ = only;
|
||||
}
|
||||
|
||||
const QVector<Node*> &GetOnlySerializeNodes() const { return only_serialize_nodes_; }
|
||||
void SetOnlySerializeNodes(const QVector<Node*> &only) { only_serialize_nodes_ = only; }
|
||||
void SetOnlySerializeNodesAndResolveGroups(QVector<Node*> only);
|
||||
const std::vector<NodeKeyframe *> &GetOnlySerializeKeyframes() const
|
||||
{
|
||||
return only_serialize_keyframes_;
|
||||
}
|
||||
void SetOnlySerializeKeyframes(const std::vector<NodeKeyframe *> &only)
|
||||
{
|
||||
only_serialize_keyframes_ = only;
|
||||
}
|
||||
|
||||
const std::vector<TimelineMarker*> &GetOnlySerializeMarkers() const { return only_serialize_markers_; }
|
||||
void SetOnlySerializeMarkers(const std::vector<TimelineMarker*> &only) { only_serialize_markers_ = only; }
|
||||
const SerializedProperties &GetProperties() const
|
||||
{
|
||||
return properties_;
|
||||
}
|
||||
void SetProperties(const SerializedProperties &p)
|
||||
{
|
||||
properties_ = p;
|
||||
}
|
||||
|
||||
const std::vector<NodeKeyframe*> &GetOnlySerializeKeyframes() const { return only_serialize_keyframes_; }
|
||||
void SetOnlySerializeKeyframes(const std::vector<NodeKeyframe*> &only) { only_serialize_keyframes_ = only; }
|
||||
private:
|
||||
LoadType type_;
|
||||
|
||||
const SerializedProperties &GetProperties() const { return properties_; }
|
||||
void SetProperties(const SerializedProperties &p) { properties_ = p; }
|
||||
Project *project_;
|
||||
|
||||
private:
|
||||
LoadType type_;
|
||||
QString filename_;
|
||||
|
||||
Project *project_;
|
||||
MainWindowLayoutInfo layout_;
|
||||
|
||||
QString filename_;
|
||||
QVector<Node *> only_serialize_nodes_;
|
||||
|
||||
MainWindowLayoutInfo layout_;
|
||||
SerializedProperties properties_;
|
||||
|
||||
QVector<Node*> only_serialize_nodes_;
|
||||
std::vector<TimelineMarker *> only_serialize_markers_;
|
||||
|
||||
SerializedProperties properties_;
|
||||
std::vector<NodeKeyframe *> only_serialize_keyframes_;
|
||||
};
|
||||
|
||||
std::vector<TimelineMarker*> only_serialize_markers_;
|
||||
static void Initialize();
|
||||
|
||||
std::vector<NodeKeyframe*> only_serialize_keyframes_;
|
||||
static void Destroy();
|
||||
|
||||
};
|
||||
static Result Load(Project *project, const QString &filename,
|
||||
LoadType load_type);
|
||||
static Result Load(Project *project, QXmlStreamReader *read_device,
|
||||
LoadType load_type);
|
||||
static Result Paste(LoadType load_type, Project *project = nullptr);
|
||||
|
||||
static void Initialize();
|
||||
static Result Save(const SaveData &data, bool compress);
|
||||
static Result Save(QXmlStreamWriter *write_device, const SaveData &data);
|
||||
static Result Copy(const SaveData &data);
|
||||
|
||||
static void Destroy();
|
||||
|
||||
static Result Load(Project *project, const QString &filename, LoadType load_type);
|
||||
static Result Load(Project *project, QXmlStreamReader *read_device, LoadType load_type);
|
||||
static Result Paste(LoadType load_type, Project *project = nullptr);
|
||||
|
||||
static Result Save(const SaveData &data, bool compress);
|
||||
static Result Save(QXmlStreamWriter *write_device, const SaveData &data);
|
||||
static Result Copy(const SaveData &data);
|
||||
|
||||
static bool CheckCompressedID(QFile *file);
|
||||
static bool CheckCompressedID(QFile *file);
|
||||
|
||||
protected:
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const = 0;
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
|
||||
LoadType load_type, void *reserved) const = 0;
|
||||
|
||||
virtual void Save(QXmlStreamWriter *writer, const SaveData &data, void *reserved) const {}
|
||||
virtual void Save(QXmlStreamWriter *writer, const SaveData &data,
|
||||
void *reserved) const
|
||||
{
|
||||
}
|
||||
|
||||
virtual uint Version() const = 0;
|
||||
virtual uint Version() const = 0;
|
||||
|
||||
bool IsCancelled() const;
|
||||
bool IsCancelled() const;
|
||||
|
||||
private:
|
||||
static Result LoadWithSerializerVersion(uint version, Project *project, QXmlStreamReader *reader, LoadType load_type);
|
||||
|
||||
static QVector<ProjectSerializer*> instances_;
|
||||
static Result LoadWithSerializerVersion(uint version, Project *project,
|
||||
QXmlStreamReader *reader,
|
||||
LoadType load_type);
|
||||
|
||||
static QVector<ProjectSerializer *> instances_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,11 +20,14 @@
|
||||
|
||||
#include "serializer190219.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
ProjectSerializer::LoadData ProjectSerializer190219::Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const
|
||||
namespace olive
|
||||
{
|
||||
return LoadData();
|
||||
|
||||
ProjectSerializer::LoadData
|
||||
ProjectSerializer190219::Load(Project *project, QXmlStreamReader *reader,
|
||||
LoadType load_type, void *reserved) const
|
||||
{
|
||||
return LoadData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,21 +23,21 @@
|
||||
|
||||
#include "serializer.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ProjectSerializer190219 : public ProjectSerializer
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class ProjectSerializer190219 : public ProjectSerializer {
|
||||
public:
|
||||
ProjectSerializer190219() = default;
|
||||
ProjectSerializer190219() = default;
|
||||
|
||||
protected:
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
|
||||
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 190219;
|
||||
}
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
|
||||
LoadType load_type, void *reserved) const override;
|
||||
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 190219;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,73 +23,81 @@
|
||||
|
||||
#include "serializer.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ProjectSerializer210528 : public ProjectSerializer
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class ProjectSerializer210528 : public ProjectSerializer {
|
||||
public:
|
||||
ProjectSerializer210528() = default;
|
||||
ProjectSerializer210528() = default;
|
||||
|
||||
protected:
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
|
||||
LoadType load_type, void *reserved) const override;
|
||||
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 210528;
|
||||
}
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 210528;
|
||||
}
|
||||
|
||||
private:
|
||||
struct XMLNodeData {
|
||||
struct SerializedConnection {
|
||||
NodeInput input;
|
||||
quintptr output_node;
|
||||
QString output_param;
|
||||
};
|
||||
struct XMLNodeData {
|
||||
struct SerializedConnection {
|
||||
NodeInput input;
|
||||
quintptr output_node;
|
||||
QString output_param;
|
||||
};
|
||||
|
||||
struct BlockLink {
|
||||
Node* block;
|
||||
quintptr link;
|
||||
};
|
||||
struct BlockLink {
|
||||
Node *block;
|
||||
quintptr link;
|
||||
};
|
||||
|
||||
struct GroupLink {
|
||||
NodeGroup *group;
|
||||
quintptr input_node;
|
||||
QString input_id;
|
||||
int input_element;
|
||||
};
|
||||
struct GroupLink {
|
||||
NodeGroup *group;
|
||||
quintptr input_node;
|
||||
QString input_id;
|
||||
int input_element;
|
||||
};
|
||||
|
||||
QHash<quintptr, Node*> node_ptrs;
|
||||
QList<SerializedConnection> desired_connections;
|
||||
QList<BlockLink> block_links;
|
||||
QVector<GroupLink> group_input_links;
|
||||
QHash<NodeGroup*, quintptr> group_output_links;
|
||||
QHash<quintptr, Node *> node_ptrs;
|
||||
QList<SerializedConnection> desired_connections;
|
||||
QList<BlockLink> block_links;
|
||||
QVector<GroupLink> group_input_links;
|
||||
QHash<NodeGroup *, quintptr> group_output_links;
|
||||
};
|
||||
|
||||
};
|
||||
void LoadNode(Node *node, XMLNodeData &xml_node_data,
|
||||
QXmlStreamReader *reader) const;
|
||||
|
||||
void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const;
|
||||
void LoadColorManager(QXmlStreamReader *reader, Project *project) const;
|
||||
|
||||
void LoadColorManager(QXmlStreamReader* reader, Project *project) const;
|
||||
void LoadProjectSettings(QXmlStreamReader *reader, Project *project) const;
|
||||
|
||||
void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const;
|
||||
void LoadInput(Node *node, QXmlStreamReader *reader,
|
||||
XMLNodeData &xml_node_data) 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;
|
||||
|
||||
void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const;
|
||||
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr,
|
||||
Node::Position *pos) const;
|
||||
|
||||
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const;
|
||||
void PostConnect(const XMLNodeData &xml_node_data) const;
|
||||
|
||||
void PostConnect(const XMLNodeData &xml_node_data) const;
|
||||
void LoadNodeCustom(QXmlStreamReader *reader, Node *node,
|
||||
XMLNodeData &xml_node_data) const;
|
||||
|
||||
void LoadNodeCustom(QXmlStreamReader *reader, Node *node, XMLNodeData &xml_node_data) const;
|
||||
void LoadTimelinePoints(QXmlStreamReader *reader,
|
||||
ViewerOutput *points) const;
|
||||
|
||||
void LoadTimelinePoints(QXmlStreamReader *reader, ViewerOutput *points) const;
|
||||
void LoadWorkArea(QXmlStreamReader *reader,
|
||||
TimelineWorkArea *workarea) const;
|
||||
|
||||
void LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const;
|
||||
|
||||
void LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const;
|
||||
|
||||
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
|
||||
void LoadMarkerList(QXmlStreamReader *reader,
|
||||
TimelineMarkerList *markers) const;
|
||||
|
||||
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,72 +23,80 @@
|
||||
|
||||
#include "serializer.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ProjectSerializer210907 : public ProjectSerializer
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class ProjectSerializer210907 : public ProjectSerializer {
|
||||
public:
|
||||
ProjectSerializer210907() = default;
|
||||
ProjectSerializer210907() = default;
|
||||
|
||||
protected:
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
|
||||
LoadType load_type, void *reserved) const override;
|
||||
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 210907;
|
||||
}
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 210907;
|
||||
}
|
||||
|
||||
private:
|
||||
struct XMLNodeData {
|
||||
struct SerializedConnection {
|
||||
NodeInput input;
|
||||
quintptr output_node;
|
||||
};
|
||||
struct XMLNodeData {
|
||||
struct SerializedConnection {
|
||||
NodeInput input;
|
||||
quintptr output_node;
|
||||
};
|
||||
|
||||
struct BlockLink {
|
||||
Node* block;
|
||||
quintptr link;
|
||||
};
|
||||
struct BlockLink {
|
||||
Node *block;
|
||||
quintptr link;
|
||||
};
|
||||
|
||||
struct GroupLink {
|
||||
NodeGroup *group;
|
||||
quintptr input_node;
|
||||
QString input_id;
|
||||
int input_element;
|
||||
};
|
||||
struct GroupLink {
|
||||
NodeGroup *group;
|
||||
quintptr input_node;
|
||||
QString input_id;
|
||||
int input_element;
|
||||
};
|
||||
|
||||
QHash<quintptr, Node*> node_ptrs;
|
||||
QList<SerializedConnection> desired_connections;
|
||||
QList<BlockLink> block_links;
|
||||
QVector<GroupLink> group_input_links;
|
||||
QHash<NodeGroup*, quintptr> group_output_links;
|
||||
QHash<quintptr, Node *> node_ptrs;
|
||||
QList<SerializedConnection> desired_connections;
|
||||
QList<BlockLink> block_links;
|
||||
QVector<GroupLink> group_input_links;
|
||||
QHash<NodeGroup *, quintptr> group_output_links;
|
||||
};
|
||||
|
||||
};
|
||||
void LoadNode(Node *node, XMLNodeData &xml_node_data,
|
||||
QXmlStreamReader *reader) const;
|
||||
|
||||
void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const;
|
||||
void LoadColorManager(QXmlStreamReader *reader, Project *project) const;
|
||||
|
||||
void LoadColorManager(QXmlStreamReader* reader, Project *project) const;
|
||||
void LoadProjectSettings(QXmlStreamReader *reader, Project *project) const;
|
||||
|
||||
void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const;
|
||||
void LoadInput(Node *node, QXmlStreamReader *reader,
|
||||
XMLNodeData &xml_node_data) 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;
|
||||
|
||||
void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const;
|
||||
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr,
|
||||
Node::Position *pos) const;
|
||||
|
||||
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const;
|
||||
void PostConnect(const XMLNodeData &xml_node_data) const;
|
||||
|
||||
void PostConnect(const XMLNodeData &xml_node_data) const;
|
||||
void LoadNodeCustom(QXmlStreamReader *reader, Node *node,
|
||||
XMLNodeData &xml_node_data) const;
|
||||
|
||||
void LoadNodeCustom(QXmlStreamReader *reader, Node *node, XMLNodeData &xml_node_data) const;
|
||||
void LoadTimelinePoints(QXmlStreamReader *reader,
|
||||
ViewerOutput *points) const;
|
||||
|
||||
void LoadTimelinePoints(QXmlStreamReader *reader, ViewerOutput *points) const;
|
||||
void LoadWorkArea(QXmlStreamReader *reader,
|
||||
TimelineWorkArea *workarea) const;
|
||||
|
||||
void LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const;
|
||||
|
||||
void LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const;
|
||||
|
||||
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
|
||||
void LoadMarkerList(QXmlStreamReader *reader,
|
||||
TimelineMarkerList *markers) const;
|
||||
|
||||
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,73 +23,81 @@
|
||||
|
||||
#include "serializer.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ProjectSerializer211228 : public ProjectSerializer
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class ProjectSerializer211228 : public ProjectSerializer {
|
||||
public:
|
||||
ProjectSerializer211228() = default;
|
||||
ProjectSerializer211228() = default;
|
||||
|
||||
protected:
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
|
||||
LoadType load_type, void *reserved) const override;
|
||||
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 211228;
|
||||
}
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 211228;
|
||||
}
|
||||
|
||||
private:
|
||||
struct XMLNodeData {
|
||||
struct SerializedConnection {
|
||||
NodeInput input;
|
||||
quintptr output_node;
|
||||
};
|
||||
struct XMLNodeData {
|
||||
struct SerializedConnection {
|
||||
NodeInput input;
|
||||
quintptr output_node;
|
||||
};
|
||||
|
||||
struct BlockLink {
|
||||
Node* block;
|
||||
quintptr link;
|
||||
};
|
||||
struct BlockLink {
|
||||
Node *block;
|
||||
quintptr link;
|
||||
};
|
||||
|
||||
struct GroupLink {
|
||||
NodeGroup *group;
|
||||
quintptr input_node;
|
||||
QString input_id;
|
||||
int input_element;
|
||||
};
|
||||
struct GroupLink {
|
||||
NodeGroup *group;
|
||||
quintptr input_node;
|
||||
QString input_id;
|
||||
int input_element;
|
||||
};
|
||||
|
||||
QHash<quintptr, Node*> node_ptrs;
|
||||
QList<SerializedConnection> desired_connections;
|
||||
QList<BlockLink> block_links;
|
||||
QVector<GroupLink> group_input_links;
|
||||
QHash<NodeGroup*, quintptr> group_output_links;
|
||||
QHash<Node*, QUuid> node_uuids;
|
||||
QHash<quintptr, Node *> node_ptrs;
|
||||
QList<SerializedConnection> desired_connections;
|
||||
QList<BlockLink> block_links;
|
||||
QVector<GroupLink> group_input_links;
|
||||
QHash<NodeGroup *, quintptr> group_output_links;
|
||||
QHash<Node *, QUuid> node_uuids;
|
||||
};
|
||||
|
||||
};
|
||||
void LoadNode(Node *node, XMLNodeData &xml_node_data,
|
||||
QXmlStreamReader *reader) const;
|
||||
|
||||
void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const;
|
||||
void LoadColorManager(QXmlStreamReader *reader, Project *project) const;
|
||||
|
||||
void LoadColorManager(QXmlStreamReader* reader, Project *project) const;
|
||||
void LoadProjectSettings(QXmlStreamReader *reader, Project *project) const;
|
||||
|
||||
void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const;
|
||||
void LoadInput(Node *node, QXmlStreamReader *reader,
|
||||
XMLNodeData &xml_node_data) 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;
|
||||
|
||||
void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const;
|
||||
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr,
|
||||
Node::Position *pos) const;
|
||||
|
||||
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const;
|
||||
void PostConnect(const XMLNodeData &xml_node_data) const;
|
||||
|
||||
void PostConnect(const XMLNodeData &xml_node_data) const;
|
||||
void LoadNodeCustom(QXmlStreamReader *reader, Node *node,
|
||||
XMLNodeData &xml_node_data) const;
|
||||
|
||||
void LoadNodeCustom(QXmlStreamReader *reader, Node *node, XMLNodeData &xml_node_data) const;
|
||||
void LoadTimelinePoints(QXmlStreamReader *reader,
|
||||
ViewerOutput *points) const;
|
||||
|
||||
void LoadTimelinePoints(QXmlStreamReader *reader, ViewerOutput *points) const;
|
||||
void LoadWorkArea(QXmlStreamReader *reader,
|
||||
TimelineWorkArea *workarea) const;
|
||||
|
||||
void LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const;
|
||||
|
||||
void LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const;
|
||||
|
||||
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
|
||||
void LoadMarkerList(QXmlStreamReader *reader,
|
||||
TimelineMarkerList *markers) const;
|
||||
|
||||
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,83 +23,92 @@
|
||||
|
||||
#include "serializer.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ProjectSerializer220403 : public ProjectSerializer
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class ProjectSerializer220403 : public ProjectSerializer {
|
||||
public:
|
||||
ProjectSerializer220403() = default;
|
||||
ProjectSerializer220403() = default;
|
||||
|
||||
protected:
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
|
||||
LoadType load_type, void *reserved) const override;
|
||||
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 220403;
|
||||
}
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 220403;
|
||||
}
|
||||
|
||||
private:
|
||||
struct XMLNodeData {
|
||||
struct SerializedConnection {
|
||||
NodeInput input;
|
||||
quintptr output_node;
|
||||
};
|
||||
struct XMLNodeData {
|
||||
struct SerializedConnection {
|
||||
NodeInput input;
|
||||
quintptr output_node;
|
||||
};
|
||||
|
||||
struct BlockLink {
|
||||
Node* block;
|
||||
quintptr link;
|
||||
};
|
||||
struct BlockLink {
|
||||
Node *block;
|
||||
quintptr link;
|
||||
};
|
||||
|
||||
struct GroupLink {
|
||||
NodeGroup *group;
|
||||
QString passthrough_id;
|
||||
quintptr input_node;
|
||||
QString input_id;
|
||||
int input_element;
|
||||
QString custom_name;
|
||||
InputFlags custom_flags;
|
||||
NodeValue::Type data_type;
|
||||
QVariant default_val;
|
||||
QHash<QString, QVariant> custom_properties;
|
||||
};
|
||||
struct GroupLink {
|
||||
NodeGroup *group;
|
||||
QString passthrough_id;
|
||||
quintptr input_node;
|
||||
QString input_id;
|
||||
int input_element;
|
||||
QString custom_name;
|
||||
InputFlags custom_flags;
|
||||
NodeValue::Type data_type;
|
||||
QVariant default_val;
|
||||
QHash<QString, QVariant> custom_properties;
|
||||
};
|
||||
|
||||
QHash<quintptr, Node*> node_ptrs;
|
||||
QList<SerializedConnection> desired_connections;
|
||||
QList<BlockLink> block_links;
|
||||
QVector<GroupLink> group_input_links;
|
||||
QHash<NodeGroup*, quintptr> group_output_links;
|
||||
QHash<Node*, QUuid> node_uuids;
|
||||
QHash<quintptr, Node *> node_ptrs;
|
||||
QList<SerializedConnection> desired_connections;
|
||||
QList<BlockLink> block_links;
|
||||
QVector<GroupLink> group_input_links;
|
||||
QHash<NodeGroup *, quintptr> group_output_links;
|
||||
QHash<Node *, QUuid> node_uuids;
|
||||
};
|
||||
|
||||
};
|
||||
void LoadNode(Node *node, XMLNodeData &xml_node_data,
|
||||
QXmlStreamReader *reader) const;
|
||||
|
||||
void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const;
|
||||
void LoadColorManager(QXmlStreamReader *reader, Project *project) const;
|
||||
|
||||
void LoadColorManager(QXmlStreamReader* reader, Project *project) const;
|
||||
void LoadProjectSettings(QXmlStreamReader *reader, Project *project) const;
|
||||
|
||||
void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const;
|
||||
void LoadInput(Node *node, QXmlStreamReader *reader,
|
||||
XMLNodeData &xml_node_data) 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;
|
||||
|
||||
void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const;
|
||||
void LoadKeyframe(QXmlStreamReader *reader, NodeKeyframe *key,
|
||||
NodeValue::Type data_type) const;
|
||||
|
||||
void LoadKeyframe(QXmlStreamReader *reader, NodeKeyframe *key, NodeValue::Type data_type) const;
|
||||
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr,
|
||||
Node::Position *pos) const;
|
||||
|
||||
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const;
|
||||
void PostConnect(const XMLNodeData &xml_node_data) const;
|
||||
|
||||
void PostConnect(const XMLNodeData &xml_node_data) const;
|
||||
void LoadNodeCustom(QXmlStreamReader *reader, Node *node,
|
||||
XMLNodeData &xml_node_data) const;
|
||||
|
||||
void LoadNodeCustom(QXmlStreamReader *reader, Node *node, XMLNodeData &xml_node_data) const;
|
||||
void LoadTimelinePoints(QXmlStreamReader *reader,
|
||||
ViewerOutput *viewer) const;
|
||||
|
||||
void LoadTimelinePoints(QXmlStreamReader *reader, ViewerOutput *viewer) const;
|
||||
void LoadMarker(QXmlStreamReader *reader, TimelineMarker *marker) const;
|
||||
|
||||
void LoadMarker(QXmlStreamReader *reader, TimelineMarker *marker) const;
|
||||
void LoadWorkArea(QXmlStreamReader *reader,
|
||||
TimelineWorkArea *workarea) const;
|
||||
|
||||
void LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const;
|
||||
|
||||
void LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const;
|
||||
|
||||
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
|
||||
void LoadMarkerList(QXmlStreamReader *reader,
|
||||
TimelineMarkerList *markers) const;
|
||||
|
||||
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,26 +23,28 @@
|
||||
|
||||
#include "serializer.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ProjectSerializer230220 : public ProjectSerializer
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class ProjectSerializer230220 : public ProjectSerializer {
|
||||
public:
|
||||
ProjectSerializer230220() = default;
|
||||
ProjectSerializer230220() = default;
|
||||
|
||||
protected:
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
|
||||
LoadType load_type, void *reserved) const override;
|
||||
|
||||
virtual void Save(QXmlStreamWriter *writer, const SaveData &data, void *reserved) const override;
|
||||
virtual void Save(QXmlStreamWriter *writer, const SaveData &data,
|
||||
void *reserved) const override;
|
||||
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 230220;
|
||||
}
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 230220;
|
||||
}
|
||||
|
||||
private:
|
||||
void PostConnect(const QVector<Node*> &nodes, SerializedData *project_data) const;
|
||||
|
||||
void PostConnect(const QVector<Node *> &nodes,
|
||||
SerializedData *project_data) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,44 +20,55 @@
|
||||
|
||||
#include "typeserializer.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
AudioParams TypeSerializer::LoadAudioParams(QXmlStreamReader *reader)
|
||||
{
|
||||
AudioParams a;
|
||||
AudioParams a;
|
||||
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("samplerate")) {
|
||||
a.set_sample_rate(reader->readElementText().toInt());
|
||||
} else if (reader->name() == QStringLiteral("channellayout")) {
|
||||
a.set_channel_layout(reader->readElementText().toULongLong());
|
||||
} else if (reader->name() == QStringLiteral("format")) {
|
||||
a.set_format(SampleFormat::from_string(reader->readElementText().toStdString()));
|
||||
} else if (reader->name() == QStringLiteral("enabled")) {
|
||||
a.set_enabled(reader->readElementText().toInt());
|
||||
} else if (reader->name() == QStringLiteral("streamindex")) {
|
||||
a.set_stream_index(reader->readElementText().toInt());
|
||||
} else if (reader->name() == QStringLiteral("duration")) {
|
||||
a.set_duration(reader->readElementText().toLongLong());
|
||||
} else if (reader->name() == QStringLiteral("timebase")) {
|
||||
a.set_time_base(rational::fromString(reader->readElementText().toStdString()));
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("samplerate")) {
|
||||
a.set_sample_rate(reader->readElementText().toInt());
|
||||
} else if (reader->name() == QStringLiteral("channellayout")) {
|
||||
a.set_channel_layout(reader->readElementText().toULongLong());
|
||||
} else if (reader->name() == QStringLiteral("format")) {
|
||||
a.set_format(SampleFormat::from_string(
|
||||
reader->readElementText().toStdString()));
|
||||
} else if (reader->name() == QStringLiteral("enabled")) {
|
||||
a.set_enabled(reader->readElementText().toInt());
|
||||
} else if (reader->name() == QStringLiteral("streamindex")) {
|
||||
a.set_stream_index(reader->readElementText().toInt());
|
||||
} else if (reader->name() == QStringLiteral("duration")) {
|
||||
a.set_duration(reader->readElementText().toLongLong());
|
||||
} else if (reader->name() == QStringLiteral("timebase")) {
|
||||
a.set_time_base(
|
||||
rational::fromString(reader->readElementText().toStdString()));
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
return a;
|
||||
}
|
||||
|
||||
void TypeSerializer::SaveAudioParams(QXmlStreamWriter *writer, const AudioParams &a)
|
||||
void TypeSerializer::SaveAudioParams(QXmlStreamWriter *writer,
|
||||
const AudioParams &a)
|
||||
{
|
||||
writer->writeTextElement(QStringLiteral("samplerate"), QString::number(a.sample_rate()));
|
||||
writer->writeTextElement(QStringLiteral("channellayout"), QString::number(a.channel_layout().u.mask));
|
||||
writer->writeTextElement(QStringLiteral("format"), QString::fromStdString(a.format().to_string()));
|
||||
writer->writeTextElement(QStringLiteral("enabled"), QString::number(a.enabled()));
|
||||
writer->writeTextElement(QStringLiteral("streamindex"), QString::number(a.stream_index()));
|
||||
writer->writeTextElement(QStringLiteral("duration"), QString::number(a.duration()));
|
||||
writer->writeTextElement(QStringLiteral("timebase"), QString::fromStdString(a.time_base().toString()));
|
||||
writer->writeTextElement(QStringLiteral("samplerate"),
|
||||
QString::number(a.sample_rate()));
|
||||
writer->writeTextElement(QStringLiteral("channellayout"),
|
||||
QString::number(a.channel_layout().u.mask));
|
||||
writer->writeTextElement(QStringLiteral("format"),
|
||||
QString::fromStdString(a.format().to_string()));
|
||||
writer->writeTextElement(QStringLiteral("enabled"),
|
||||
QString::number(a.enabled()));
|
||||
writer->writeTextElement(QStringLiteral("streamindex"),
|
||||
QString::number(a.stream_index()));
|
||||
writer->writeTextElement(QStringLiteral("duration"),
|
||||
QString::number(a.duration()));
|
||||
writer->writeTextElement(QStringLiteral("timebase"),
|
||||
QString::fromStdString(a.time_base().toString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,18 +27,17 @@
|
||||
|
||||
#include "common/xmlutils.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
using namespace core;
|
||||
|
||||
class TypeSerializer
|
||||
{
|
||||
class TypeSerializer {
|
||||
public:
|
||||
TypeSerializer() = default;
|
||||
|
||||
static AudioParams LoadAudioParams(QXmlStreamReader *reader);
|
||||
static void SaveAudioParams(QXmlStreamWriter *writer, const AudioParams &a);
|
||||
TypeSerializer() = default;
|
||||
|
||||
static AudioParams LoadAudioParams(QXmlStreamReader *reader);
|
||||
static void SaveAudioParams(QXmlStreamWriter *writer, const AudioParams &a);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user