Merge branch 'master' into cache-update
This commit is contained in:
@@ -73,6 +73,21 @@ bool Folder::ChildExistsWithName(const QString &s) const
|
||||
return ChildExistsWithNameInternal(this, s);
|
||||
}
|
||||
|
||||
bool Folder::HasChildRecursive(Node *child) const
|
||||
{
|
||||
for (Node *i : item_children_) {
|
||||
if (i == child) {
|
||||
return true;
|
||||
} else if (Folder *f = dynamic_cast<Folder*>(i)) {
|
||||
if (f->HasChildRecursive(child)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Folder::index_of_child_in_array(Node *item) const
|
||||
{
|
||||
int index_of_item = item_children_.indexOf(item);
|
||||
|
||||
@@ -65,6 +65,8 @@ public:
|
||||
|
||||
bool ChildExistsWithName(const QString& s) const;
|
||||
|
||||
bool HasChildRecursive(Node *child) const;
|
||||
|
||||
int item_child_count() const
|
||||
{
|
||||
return item_children_.size();
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
namespace olive {
|
||||
|
||||
const QString Footage::kFilenameInput = QStringLiteral("file_in");
|
||||
const QString Footage::kLoopModeInput = QStringLiteral("loop_in");
|
||||
|
||||
#define super ViewerOutput
|
||||
|
||||
@@ -45,10 +44,9 @@ Footage::Footage(const QString &filename) :
|
||||
ViewerOutput(false, false),
|
||||
timestamp_(0),
|
||||
valid_(false),
|
||||
cancelled_(nullptr)
|
||||
cancelled_(nullptr),
|
||||
total_stream_count_(0)
|
||||
{
|
||||
PrependInput(kLoopModeInput, NodeValue::kCombo, 0, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable));
|
||||
|
||||
PrependInput(kFilenameInput, NodeValue::kFile, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable));
|
||||
|
||||
Clear();
|
||||
@@ -70,8 +68,6 @@ void Footage::Retranslate()
|
||||
super::Retranslate();
|
||||
|
||||
SetInputName(kFilenameInput, tr("Filename"));
|
||||
SetInputName(kLoopModeInput, tr("Loop Mode"));
|
||||
SetComboBoxStrings(kLoopModeInput, {tr("None"), tr("Loop"), tr("Clamp")});
|
||||
}
|
||||
|
||||
void Footage::InputValueChangedEvent(const QString &input, int element)
|
||||
@@ -130,6 +126,9 @@ void Footage::Clear()
|
||||
// Clear decoder link
|
||||
decoder_.clear();
|
||||
|
||||
// Clear total stream count
|
||||
total_stream_count_ = 0;
|
||||
|
||||
// Reset ready state
|
||||
valid_ = false;
|
||||
}
|
||||
@@ -139,11 +138,6 @@ void Footage::SetValid()
|
||||
valid_ = true;
|
||||
}
|
||||
|
||||
Footage::LoopMode Footage::loop_mode() const
|
||||
{
|
||||
return static_cast<LoopMode>(GetStandardValue(kLoopModeInput).toInt());
|
||||
}
|
||||
|
||||
QString Footage::filename() const
|
||||
{
|
||||
return GetStandardValue(kFilenameInput).toString();
|
||||
@@ -263,17 +257,15 @@ void Footage::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeV
|
||||
// Pop filename from table
|
||||
QString file = value[kFilenameInput].toString();
|
||||
|
||||
LoopMode loop_mode = static_cast<LoopMode>(value[kLoopModeInput].toInt());
|
||||
|
||||
// If the file exists and the reference is valid, push a footage job to the renderer
|
||||
if (QFileInfo(file).exists()) {
|
||||
if (QFileInfo::exists(file)) {
|
||||
// Push length
|
||||
table->Push(NodeValue::kRational, QVariant::fromValue(GetLength()), this, false, QStringLiteral("length"));
|
||||
table->Push(NodeValue::kRational, QVariant::fromValue(GetLength()), this, QStringLiteral("length"));
|
||||
|
||||
// Push each stream as a footage job
|
||||
for (int i=0; i<GetTotalStreamCount(); i++) {
|
||||
Track::Reference ref = GetReferenceFromRealIndex(i);
|
||||
FootageJob job(decoder_, filename(), ref.type(), GetLength(), loop_mode);
|
||||
FootageJob job(decoder_, filename(), ref.type(), GetLength());
|
||||
|
||||
NodeValue::Type type;
|
||||
|
||||
@@ -294,7 +286,7 @@ void Footage::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeV
|
||||
type = NodeValue::kSamples;
|
||||
}
|
||||
|
||||
table->Push(type, QVariant::fromValue(job), this, false, ref.ToString());
|
||||
table->Push(type, QVariant::fromValue(job), this, ref.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,7 +331,7 @@ bool TimeIsOutOfBounds(const rational& time, const rational& length)
|
||||
return time < 0 || time >= length;
|
||||
}
|
||||
|
||||
rational Footage::AdjustTimeByLoopMode(rational time, Footage::LoopMode loop_mode, const rational &length, VideoParams::Type type, const rational& timebase)
|
||||
rational Footage::AdjustTimeByLoopMode(rational time, Decoder::LoopMode loop_mode, const rational &length, VideoParams::Type type, const rational& timebase)
|
||||
{
|
||||
if (type == VideoParams::kVideoTypeStill) {
|
||||
// No looping for still images
|
||||
@@ -348,15 +340,15 @@ rational Footage::AdjustTimeByLoopMode(rational time, Footage::LoopMode loop_mod
|
||||
|
||||
if (TimeIsOutOfBounds(time, length)) {
|
||||
switch (loop_mode) {
|
||||
case kLoopModeOff:
|
||||
case Decoder::kLoopModeOff:
|
||||
// Return no time to indicate no frame should be shown here
|
||||
time = rational::NaN;
|
||||
break;
|
||||
case kLoopModeClamp:
|
||||
case Decoder::kLoopModeClamp:
|
||||
// Clamp footage time to length
|
||||
time = clamp(time, rational(0), length - timebase);
|
||||
break;
|
||||
case kLoopModeLoop:
|
||||
case Decoder::kLoopModeLoop:
|
||||
// Loop footage time around job length
|
||||
do {
|
||||
if (time >= length) {
|
||||
@@ -509,6 +501,8 @@ void Footage::Reprobe()
|
||||
SetStream(Track::kSubtitle, QVariant::fromValue(footage_info.GetSubtitleStreams().at(i)), i);
|
||||
}
|
||||
|
||||
total_stream_count_ = footage_info.GetStreamCount();
|
||||
|
||||
SetValid();
|
||||
}
|
||||
|
||||
@@ -524,10 +518,13 @@ VideoParams Footage::MergeVideoStream(const VideoParams &base, const VideoParams
|
||||
merged.set_interlacing(over.interlacing());
|
||||
merged.set_colorspace(over.colorspace());
|
||||
merged.set_premultiplied_alpha(over.premultiplied_alpha());
|
||||
if (merged.video_type() == VideoParams::kVideoTypeImageSequence && over.video_type() == VideoParams::kVideoTypeImageSequence) {
|
||||
merged.set_video_type(over.video_type());
|
||||
merged.set_color_range(over.color_range());
|
||||
if (merged.video_type() == VideoParams::kVideoTypeImageSequence) {
|
||||
merged.set_start_time(over.start_time());
|
||||
merged.set_duration(over.duration());
|
||||
merged.set_frame_rate(over.frame_rate());
|
||||
merged.set_time_base(over.time_base());
|
||||
}
|
||||
|
||||
return merged;
|
||||
|
||||
@@ -24,10 +24,12 @@
|
||||
#include <QList>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "codec/decoder.h"
|
||||
#include "common/rational.h"
|
||||
#include "footagedescription.h"
|
||||
#include "node/output/viewer/viewer.h"
|
||||
#include "render/audioparams.h"
|
||||
#include "render/cancelatom.h"
|
||||
#include "render/videoparams.h"
|
||||
|
||||
namespace olive {
|
||||
@@ -43,12 +45,6 @@ class Footage : public ViewerOutput
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum LoopMode {
|
||||
kLoopModeOff,
|
||||
kLoopModeLoop,
|
||||
kLoopModeClamp
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Footage Constructor
|
||||
*/
|
||||
@@ -100,11 +96,6 @@ public:
|
||||
*/
|
||||
void SetValid();
|
||||
|
||||
/**
|
||||
* @brief Get currently set loop mode
|
||||
*/
|
||||
LoopMode loop_mode() const;
|
||||
|
||||
/**
|
||||
* @brief Return the current filename of this Footage object
|
||||
*/
|
||||
@@ -141,7 +132,7 @@ public:
|
||||
*/
|
||||
void set_timestamp(const qint64 &t);
|
||||
|
||||
void SetCancelPointer(const QAtomicInt* c)
|
||||
void SetCancelPointer(CancelAtom *c)
|
||||
{
|
||||
cancelled_ = c;
|
||||
}
|
||||
@@ -182,15 +173,16 @@ public:
|
||||
|
||||
virtual Node *GetConnectedSampleOutput() override;
|
||||
|
||||
static rational AdjustTimeByLoopMode(rational time, LoopMode loop_mode, const rational& length, VideoParams::Type type, const rational &timebase);
|
||||
static rational AdjustTimeByLoopMode(rational time, Decoder::LoopMode loop_mode, const rational& length, VideoParams::Type type, const rational &timebase);
|
||||
|
||||
virtual void LoadFinishedEvent() override;
|
||||
|
||||
virtual qint64 creation_time() const override;
|
||||
virtual qint64 mod_time() const override;
|
||||
|
||||
virtual int GetTotalStreamCount() const override { return total_stream_count_; }
|
||||
|
||||
static const QString kFilenameInput;
|
||||
static const QString kLoopModeInput;
|
||||
|
||||
protected:
|
||||
virtual void InputValueChangedEvent(const QString &input, int element) override;
|
||||
@@ -232,7 +224,9 @@ private:
|
||||
|
||||
bool valid_;
|
||||
|
||||
const QAtomicInt* cancelled_;
|
||||
CancelAtom *cancelled_;
|
||||
|
||||
int total_stream_count_;
|
||||
|
||||
private slots:
|
||||
void CheckFootage();
|
||||
|
||||
@@ -43,9 +43,11 @@ bool FootageDescription::Load(const QString &filename)
|
||||
// Default to first version of metadata (which wasn't versioned at all)
|
||||
unsigned version = 1;
|
||||
|
||||
XMLAttributeLoop((&reader), attr) {
|
||||
if (attr.name() == QStringLiteral("version")) {
|
||||
version = attr.value().toUInt();
|
||||
{
|
||||
XMLAttributeLoop((&reader), attr) {
|
||||
if (attr.name() == QStringLiteral("version")) {
|
||||
version = attr.value().toUInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +60,14 @@ bool FootageDescription::Load(const QString &filename)
|
||||
if (reader.name() == QStringLiteral("decoder")) {
|
||||
decoder_ = reader.readElementText();
|
||||
} else if (reader.name() == QStringLiteral("streams")) {
|
||||
{
|
||||
XMLAttributeLoop((&reader), attr) {
|
||||
if (attr.name() == QStringLiteral("count")) {
|
||||
total_stream_count_ = attr.value().toInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (XMLReadNextStartElement(&reader)) {
|
||||
if (reader.name() == QStringLiteral("video")) {
|
||||
VideoParams vp;
|
||||
@@ -116,6 +126,8 @@ bool FootageDescription::Save(const QString &filename) const
|
||||
|
||||
writer.writeStartElement(QStringLiteral("streams"));
|
||||
|
||||
writer.writeAttribute(QStringLiteral("count"), QString::number(total_stream_count_));
|
||||
|
||||
foreach (const VideoParams& vp, video_streams_) {
|
||||
writer.writeStartElement(QStringLiteral("video"));
|
||||
vp.Save(&writer);
|
||||
|
||||
@@ -32,7 +32,8 @@ class FootageDescription
|
||||
{
|
||||
public:
|
||||
FootageDescription(const QString& decoder = QString()) :
|
||||
decoder_(decoder)
|
||||
decoder_(decoder),
|
||||
total_stream_count_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -118,6 +119,9 @@ public:
|
||||
return StreamIsVideo(index) || StreamIsAudio(index) || StreamIsSubtitle(index);
|
||||
}
|
||||
|
||||
int GetStreamCount() const { return total_stream_count_; }
|
||||
void SetStreamCount(int s) { total_stream_count_ = s; }
|
||||
|
||||
bool Load(const QString& filename);
|
||||
|
||||
bool Save(const QString& filename) const;
|
||||
@@ -138,7 +142,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr unsigned kFootageMetaVersion = 2;
|
||||
static constexpr unsigned kFootageMetaVersion = 5;
|
||||
|
||||
QString decoder_;
|
||||
|
||||
@@ -148,6 +152,8 @@ private:
|
||||
|
||||
QVector<SubtitleParams> subtitle_streams_;
|
||||
|
||||
int total_stream_count_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "common/qtutils.h"
|
||||
#include "common/xmlutils.h"
|
||||
#include "core.h"
|
||||
#include "dialog/progress/progress.h"
|
||||
@@ -173,16 +174,7 @@ void Project::RegenerateUuid()
|
||||
|
||||
Project *Project::GetProjectFromObject(const QObject *o)
|
||||
{
|
||||
QObject *t = o->parent();
|
||||
|
||||
while (t) {
|
||||
if (Project *p = dynamic_cast<Project*>(t)) {
|
||||
return p;
|
||||
}
|
||||
t = t->parent();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return QtUtils::GetParentOfType<Project>(o);
|
||||
}
|
||||
|
||||
void Project::ColorManagerValueChanged(const NodeInput &input, const TimeRange &range)
|
||||
|
||||
@@ -170,6 +170,11 @@ QVariant ProjectViewModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Qt::EditRole:
|
||||
if (column_type == kName) {
|
||||
return internal_item->GetLabel();
|
||||
}
|
||||
break;
|
||||
case Qt::DecorationRole:
|
||||
// If this is the first column, return the Item's icon
|
||||
if (column_type == kName) {
|
||||
|
||||
@@ -159,6 +159,11 @@ ProjectSerializer::Result ProjectSerializer::Save(const SaveData &data, const QS
|
||||
|
||||
Result inner_result = Save(&writer, data, type);
|
||||
|
||||
if (writer.hasError()) {
|
||||
Result r(kXmlError);
|
||||
return r;
|
||||
}
|
||||
|
||||
project_file.close();
|
||||
|
||||
if (inner_result != kSuccess) {
|
||||
@@ -262,7 +267,7 @@ ProjectSerializer::Result ProjectSerializer::LoadWithSerializerVersion(uint vers
|
||||
Result r(kSuccess);
|
||||
if (reader->hasError()) {
|
||||
r = Result(kXmlError);
|
||||
r.SetDetails(reader->errorString());
|
||||
r.SetDetails(QCoreApplication::translate("Serializer", "%1 on line %2").arg(reader->errorString(), QString::number(reader->lineNumber())));
|
||||
}
|
||||
r.SetLoadData(ld);
|
||||
return r;
|
||||
|
||||
@@ -25,6 +25,20 @@
|
||||
|
||||
namespace olive {
|
||||
|
||||
// These wrappers may appear to do nothing, but they seem to address a bug where sometimes
|
||||
// QXmlStreamWriter would insert nonsense null characters into a project. This is probably some
|
||||
// real edge case like compiler optimization or some bullshit like that. I don't even know if it
|
||||
// affects all platforms, but it definitely affected me on Linux.
|
||||
void WriteStartElement(QXmlStreamWriter *writer, const QString &s)
|
||||
{
|
||||
writer->writeStartElement(s);
|
||||
}
|
||||
|
||||
void WriteEndElement(QXmlStreamWriter *writer)
|
||||
{
|
||||
writer->writeEndElement();
|
||||
}
|
||||
|
||||
ProjectSerializer220403::LoadData ProjectSerializer220403::Load(Project *project, QXmlStreamReader *reader, void *reserved) const
|
||||
{
|
||||
QMap<quintptr, QMap<QString, QString> > properties;
|
||||
@@ -328,23 +342,23 @@ void ProjectSerializer220403::Save(QXmlStreamWriter *writer, const SaveData &dat
|
||||
{
|
||||
if (!data.GetOnlySerializeMarkers().empty()) {
|
||||
|
||||
writer->writeStartElement(QStringLiteral("markers"));
|
||||
WriteStartElement(writer, QStringLiteral("markers"));
|
||||
|
||||
for (auto it=data.GetOnlySerializeMarkers().cbegin(); it!=data.GetOnlySerializeMarkers().cend(); it++) {
|
||||
TimelineMarker *marker = *it;
|
||||
|
||||
writer->writeStartElement(QStringLiteral("marker"));
|
||||
WriteStartElement(writer, QStringLiteral("marker"));
|
||||
|
||||
SaveMarker(writer, marker);
|
||||
|
||||
writer->writeEndElement(); // marker
|
||||
WriteEndElement(writer); // marker
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // markers
|
||||
WriteEndElement(writer); // markers
|
||||
|
||||
} else if (!data.GetOnlySerializeKeyframes().empty()) {
|
||||
|
||||
writer->writeStartElement(QStringLiteral("keyframes"));
|
||||
WriteStartElement(writer, QStringLiteral("keyframes"));
|
||||
|
||||
// Organize keyframes into node+input
|
||||
QHash<QString, QHash<QString, QMap<int, QMap<int, QVector<NodeKeyframe*> > > > > organized;
|
||||
@@ -355,57 +369,57 @@ void ProjectSerializer220403::Save(QXmlStreamWriter *writer, const SaveData &dat
|
||||
}
|
||||
|
||||
for (auto it=organized.cbegin(); it!=organized.cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
WriteStartElement(writer, QStringLiteral("node"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), it.key());
|
||||
|
||||
for (auto jt=it.value().cbegin(); jt!=it.value().cend(); jt++) {
|
||||
writer->writeStartElement(QStringLiteral("input"));
|
||||
WriteStartElement(writer, QStringLiteral("input"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), jt.key());
|
||||
|
||||
for (auto kt=jt.value().cbegin(); kt!=jt.value().cend(); kt++) {
|
||||
writer->writeStartElement(QStringLiteral("element"));
|
||||
WriteStartElement(writer, 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"));
|
||||
WriteStartElement(writer, QStringLiteral("track"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), QString::number(lt.key()));
|
||||
|
||||
for (NodeKeyframe *key : keys) {
|
||||
writer->writeStartElement(QStringLiteral("key"));
|
||||
WriteStartElement(writer, QStringLiteral("key"));
|
||||
SaveKeyframe(writer, key, key->parent()->GetInputDataType(key->input()));
|
||||
writer->writeEndElement(); // key
|
||||
WriteEndElement(writer); // key
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // track
|
||||
WriteEndElement(writer); // track
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // element
|
||||
WriteEndElement(writer); // element
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // input
|
||||
WriteEndElement(writer); // input
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // node;
|
||||
WriteEndElement(writer); // node;
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // keyframes
|
||||
WriteEndElement(writer); // keyframes
|
||||
|
||||
} else if (Project *project = data.GetProject()) {
|
||||
|
||||
writer->writeTextElement(QStringLiteral("uuid"), project->GetUuid().toString());
|
||||
|
||||
writer->writeStartElement(QStringLiteral("nodes"));
|
||||
WriteStartElement(writer, QStringLiteral("nodes"));
|
||||
|
||||
const QVector<Node*> &using_node_list = (data.GetOnlySerializeNodes().isEmpty()) ? project->nodes() : data.GetOnlySerializeNodes();
|
||||
|
||||
foreach (Node* node, using_node_list) {
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
WriteStartElement(writer, QStringLiteral("node"));
|
||||
|
||||
if (node == project->root()) {
|
||||
writer->writeAttribute(QStringLiteral("root"), QStringLiteral("1"));
|
||||
@@ -419,39 +433,39 @@ void ProjectSerializer220403::Save(QXmlStreamWriter *writer, const SaveData &dat
|
||||
|
||||
SaveNode(node, writer);
|
||||
|
||||
writer->writeEndElement(); // node
|
||||
WriteEndElement(writer); // node
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // nodes
|
||||
WriteEndElement(writer); // nodes
|
||||
|
||||
writer->writeStartElement(QStringLiteral("positions"));
|
||||
WriteStartElement(writer, QStringLiteral("positions"));
|
||||
|
||||
foreach (Node* context, using_node_list) {
|
||||
const Node::PositionMap &map = context->GetContextPositions();
|
||||
|
||||
if (!map.isEmpty()) {
|
||||
writer->writeStartElement(QStringLiteral("context"));
|
||||
WriteStartElement(writer, QStringLiteral("context"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(context)));
|
||||
|
||||
for (auto jt=map.cbegin(); jt!=map.cend(); jt++) {
|
||||
if (data.GetOnlySerializeNodes().isEmpty() || data.GetOnlySerializeNodes().contains(jt.key())) {
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
WriteStartElement(writer, QStringLiteral("node"));
|
||||
SavePosition(writer, jt.key(), jt.value());
|
||||
writer->writeEndElement(); // node
|
||||
WriteEndElement(writer); // node
|
||||
}
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // context
|
||||
WriteEndElement(writer); // context
|
||||
}
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // positions
|
||||
WriteEndElement(writer); // positions
|
||||
|
||||
writer->writeStartElement(QStringLiteral("properties"));
|
||||
WriteStartElement(writer, QStringLiteral("properties"));
|
||||
|
||||
for (auto it=data.GetProperties().cbegin(); it!=data.GetProperties().cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
WriteStartElement(writer, QStringLiteral("node"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(it.key())));
|
||||
|
||||
@@ -459,10 +473,10 @@ void ProjectSerializer220403::Save(QXmlStreamWriter *writer, const SaveData &dat
|
||||
writer->writeTextElement(jt.key(), jt.value());
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // node
|
||||
WriteEndElement(writer); // node
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // properties
|
||||
WriteEndElement(writer); // properties
|
||||
|
||||
// Save main window project layout
|
||||
project->GetLayoutInfo().toXml(writer);
|
||||
@@ -583,59 +597,59 @@ void ProjectSerializer220403::SaveNode(Node *node, QXmlStreamWriter *writer) con
|
||||
writer->writeTextElement(QStringLiteral("color"), QString::number(node->GetOverrideColor()));
|
||||
|
||||
foreach (const QString& input, node->inputs()) {
|
||||
writer->writeStartElement(QStringLiteral("input"));
|
||||
WriteStartElement(writer, QStringLiteral("input"));
|
||||
|
||||
SaveInput(node, writer, input);
|
||||
|
||||
writer->writeEndElement(); // input
|
||||
WriteEndElement(writer); // input
|
||||
}
|
||||
|
||||
writer->writeStartElement(QStringLiteral("links"));
|
||||
WriteStartElement(writer, QStringLiteral("links"));
|
||||
foreach (Node* link, node->links()) {
|
||||
writer->writeTextElement(QStringLiteral("link"), QString::number(reinterpret_cast<quintptr>(link)));
|
||||
}
|
||||
writer->writeEndElement(); // links
|
||||
WriteEndElement(writer); // links
|
||||
|
||||
writer->writeStartElement(QStringLiteral("connections"));
|
||||
WriteStartElement(writer, QStringLiteral("connections"));
|
||||
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("connection"));
|
||||
WriteStartElement(writer, QStringLiteral("connection"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("input"), it->first.input());
|
||||
writer->writeAttribute(QStringLiteral("element"), QString::number(it->first.element()));
|
||||
|
||||
writer->writeTextElement(QStringLiteral("output"), QString::number(reinterpret_cast<quintptr>(it->second)));
|
||||
|
||||
writer->writeEndElement(); // connection
|
||||
WriteEndElement(writer); // connection
|
||||
}
|
||||
writer->writeEndElement(); // connections
|
||||
WriteEndElement(writer); // connections
|
||||
|
||||
writer->writeStartElement(QStringLiteral("hints"));
|
||||
WriteStartElement(writer, QStringLiteral("hints"));
|
||||
for (auto it=node->GetValueHints().cbegin(); it!=node->GetValueHints().cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("hint"));
|
||||
WriteStartElement(writer, QStringLiteral("hint"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("input"), it.key().input);
|
||||
writer->writeAttribute(QStringLiteral("element"), QString::number(it.key().element));
|
||||
|
||||
SaveValueHint(&it.value(), writer);
|
||||
|
||||
writer->writeEndElement(); // hint
|
||||
WriteEndElement(writer); // hint
|
||||
}
|
||||
writer->writeEndElement();
|
||||
WriteEndElement(writer); // hints
|
||||
|
||||
writer->writeStartElement(QStringLiteral("caches"));
|
||||
WriteStartElement(writer, QStringLiteral("caches"));
|
||||
|
||||
writer->writeTextElement(QStringLiteral("audio"), node->audio_playback_cache()->GetUuid().toString());
|
||||
writer->writeTextElement(QStringLiteral("video"), node->video_frame_cache()->GetUuid().toString());
|
||||
writer->writeTextElement(QStringLiteral("thumb"), node->thumbnail_cache()->GetUuid().toString());
|
||||
writer->writeTextElement(QStringLiteral("waveform"), node->waveform_cache()->GetUuid().toString());
|
||||
|
||||
writer->writeEndElement(); // caches
|
||||
WriteEndElement(writer); // caches
|
||||
|
||||
writer->writeStartElement(QStringLiteral("custom"));
|
||||
WriteStartElement(writer, QStringLiteral("custom"));
|
||||
|
||||
SaveNodeCustom(writer, node);
|
||||
|
||||
writer->writeEndElement(); // custom
|
||||
WriteEndElement(writer); // custom
|
||||
}
|
||||
|
||||
void ProjectSerializer220403::LoadInput(Node *node, QXmlStreamReader *reader, XMLNodeData &xml_node_data) const
|
||||
@@ -705,27 +719,27 @@ void ProjectSerializer220403::SaveInput(Node *node, QXmlStreamWriter *writer, co
|
||||
{
|
||||
writer->writeAttribute(QStringLiteral("id"), id);
|
||||
|
||||
writer->writeStartElement(QStringLiteral("primary"));
|
||||
WriteStartElement(writer, QStringLiteral("primary"));
|
||||
|
||||
SaveImmediate(writer, node, id, -1);
|
||||
|
||||
writer->writeEndElement(); // primary
|
||||
WriteEndElement(writer); // primary
|
||||
|
||||
writer->writeStartElement(QStringLiteral("subelements"));
|
||||
WriteStartElement(writer, QStringLiteral("subelements"));
|
||||
|
||||
int arr_sz = node->InputArraySize(id);
|
||||
|
||||
writer->writeAttribute(QStringLiteral("count"), QString::number(arr_sz));
|
||||
|
||||
for (int i=0; i<arr_sz; i++) {
|
||||
writer->writeStartElement(QStringLiteral("element"));
|
||||
WriteStartElement(writer, QStringLiteral("element"));
|
||||
|
||||
SaveImmediate(writer, node, id, i);
|
||||
|
||||
writer->writeEndElement(); // element
|
||||
WriteEndElement(writer); // element
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // subelements
|
||||
WriteEndElement(writer); // subelements
|
||||
}
|
||||
|
||||
void ProjectSerializer220403::LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData &xml_node_data) const
|
||||
@@ -835,10 +849,10 @@ void ProjectSerializer220403::SaveImmediate(QXmlStreamWriter *writer, Node *node
|
||||
NodeValue::Type data_type = node->GetInputDataType(input);
|
||||
|
||||
// Write standard value
|
||||
writer->writeStartElement(QStringLiteral("standard"));
|
||||
WriteStartElement(writer, QStringLiteral("standard"));
|
||||
|
||||
foreach (const QVariant& v, node->GetSplitStandardValue(input, element)) {
|
||||
writer->writeStartElement(QStringLiteral("track"));
|
||||
WriteStartElement(writer, QStringLiteral("track"));
|
||||
|
||||
if (data_type == NodeValue::kVideoParams) {
|
||||
v.value<VideoParams>().Save(writer);
|
||||
@@ -848,29 +862,29 @@ void ProjectSerializer220403::SaveImmediate(QXmlStreamWriter *writer, Node *node
|
||||
writer->writeCharacters(NodeValue::ValueToString(data_type, v, true));
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // track
|
||||
WriteEndElement(writer); // track
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // standard
|
||||
WriteEndElement(writer); // standard
|
||||
|
||||
// Write keyframes
|
||||
writer->writeStartElement(QStringLiteral("keyframes"));
|
||||
WriteStartElement(writer, QStringLiteral("keyframes"));
|
||||
|
||||
for (const NodeKeyframeTrack& track : node->GetKeyframeTracks(input, element)) {
|
||||
writer->writeStartElement(QStringLiteral("track"));
|
||||
WriteStartElement(writer, QStringLiteral("track"));
|
||||
|
||||
for (NodeKeyframe* key : track) {
|
||||
writer->writeStartElement(QStringLiteral("key"));
|
||||
WriteStartElement(writer, QStringLiteral("key"));
|
||||
|
||||
SaveKeyframe(writer, key, data_type);
|
||||
|
||||
writer->writeEndElement(); // key
|
||||
WriteEndElement(writer); // key
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // track
|
||||
WriteEndElement(writer); // track
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // keyframes
|
||||
WriteEndElement(writer); // keyframes
|
||||
|
||||
if (data_type == NodeValue::kColor) {
|
||||
// Save color management information
|
||||
@@ -1115,9 +1129,9 @@ void ProjectSerializer220403::SaveNodeCustom(QXmlStreamWriter *writer, Node *nod
|
||||
{
|
||||
if (ViewerOutput *viewer = dynamic_cast<ViewerOutput*>(node)) {
|
||||
// Write TimelinePoints
|
||||
writer->writeStartElement(QStringLiteral("points"));
|
||||
WriteStartElement(writer, QStringLiteral("points"));
|
||||
SaveTimelinePoints(writer, viewer);
|
||||
writer->writeEndElement(); // points
|
||||
WriteEndElement(writer); // points
|
||||
|
||||
if (Footage *footage = dynamic_cast<Footage*>(node)) {
|
||||
writer->writeTextElement(QStringLiteral("timestamp"), QString::number(footage->timestamp()));
|
||||
@@ -1125,10 +1139,10 @@ void ProjectSerializer220403::SaveNodeCustom(QXmlStreamWriter *writer, Node *nod
|
||||
} else if (Track *track = dynamic_cast<Track*>(node)) {
|
||||
writer->writeTextElement(QStringLiteral("height"), QString::number(track->GetTrackHeight()));
|
||||
} else if (NodeGroup *group = dynamic_cast<NodeGroup*>(node)) {
|
||||
writer->writeStartElement(QStringLiteral("inputpassthroughs"));
|
||||
WriteStartElement(writer, QStringLiteral("inputpassthroughs"));
|
||||
|
||||
foreach (const NodeGroup::InputPassthrough &ip, group->GetInputPassthroughs()) {
|
||||
writer->writeStartElement(QStringLiteral("inputpassthrough"));
|
||||
WriteStartElement(writer, QStringLiteral("inputpassthrough"));
|
||||
|
||||
// Reference to inner input
|
||||
writer->writeTextElement(QStringLiteral("node"), QString::number(reinterpret_cast<quintptr>(ip.second.node())));
|
||||
@@ -1149,20 +1163,20 @@ void ProjectSerializer220403::SaveNodeCustom(QXmlStreamWriter *writer, Node *nod
|
||||
|
||||
writer->writeTextElement(QStringLiteral("default"), NodeValue::ValueToString(data_type, group_input.GetDefaultValue(), false));
|
||||
|
||||
writer->writeStartElement(QStringLiteral("properties"));
|
||||
WriteStartElement(writer, QStringLiteral("properties"));
|
||||
auto p = group_input.GetProperties();
|
||||
for (auto it=p.cbegin(); it!=p.cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("property"));
|
||||
WriteStartElement(writer, QStringLiteral("property"));
|
||||
writer->writeTextElement(QStringLiteral("key"), it.key());
|
||||
writer->writeTextElement(QStringLiteral("value"), it.value().toString());
|
||||
writer->writeEndElement(); // property
|
||||
WriteEndElement(writer); // property
|
||||
}
|
||||
writer->writeEndElement(); // properties
|
||||
WriteEndElement(writer); // properties
|
||||
|
||||
writer->writeEndElement(); // input
|
||||
WriteEndElement(writer); // input
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // inputpassthroughs
|
||||
WriteEndElement(writer); // inputpassthroughs
|
||||
|
||||
writer->writeTextElement(QStringLiteral("outputpassthrough"), QString::number(reinterpret_cast<quintptr>(group->GetOutputPassthrough())));
|
||||
}
|
||||
@@ -1183,13 +1197,13 @@ void ProjectSerializer220403::LoadTimelinePoints(QXmlStreamReader *reader, Viewe
|
||||
|
||||
void ProjectSerializer220403::SaveTimelinePoints(QXmlStreamWriter *writer, ViewerOutput *viewer) const
|
||||
{
|
||||
writer->writeStartElement(QStringLiteral("workarea"));
|
||||
WriteStartElement(writer, QStringLiteral("workarea"));
|
||||
SaveWorkArea(writer, viewer->GetWorkArea());
|
||||
writer->writeEndElement(); // workarea
|
||||
WriteEndElement(writer); // workarea
|
||||
|
||||
writer->writeStartElement(QStringLiteral("markers"));
|
||||
WriteStartElement(writer, QStringLiteral("markers"));
|
||||
SaveMarkerList(writer, viewer->GetMarkers());
|
||||
writer->writeEndElement(); // markers
|
||||
WriteEndElement(writer); // markers
|
||||
}
|
||||
|
||||
void ProjectSerializer220403::LoadMarker(QXmlStreamReader *reader, TimelineMarker *marker) const
|
||||
@@ -1270,11 +1284,11 @@ void ProjectSerializer220403::SaveMarkerList(QXmlStreamWriter *writer, TimelineM
|
||||
for (auto it=markers->cbegin(); it!=markers->cend(); it++) {
|
||||
TimelineMarker* marker = *it;
|
||||
|
||||
writer->writeStartElement(QStringLiteral("marker"));
|
||||
WriteStartElement(writer, QStringLiteral("marker"));
|
||||
|
||||
SaveMarker(writer, marker);
|
||||
|
||||
writer->writeEndElement(); // marker
|
||||
WriteEndElement(writer); // marker
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,13 +1319,13 @@ void ProjectSerializer220403::LoadValueHint(Node::ValueHint *hint, QXmlStreamRea
|
||||
|
||||
void ProjectSerializer220403::SaveValueHint(const Node::ValueHint *hint, QXmlStreamWriter *writer) const
|
||||
{
|
||||
writer->writeStartElement(QStringLiteral("types"));
|
||||
WriteStartElement(writer, QStringLiteral("types"));
|
||||
|
||||
for (auto it=hint->types().cbegin(); it!=hint->types().cend(); it++) {
|
||||
writer->writeTextElement(QStringLiteral("type"), QString::number(*it));
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // types
|
||||
WriteEndElement(writer); // types
|
||||
|
||||
writer->writeTextElement(QStringLiteral("index"), QString::number(hint->index()));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user