groups: improved serialization
Introduced new project version with extra customization for groups
This commit is contained in:
@@ -58,7 +58,7 @@ void NodeGroup::Retranslate()
|
||||
}
|
||||
}
|
||||
|
||||
QString NodeGroup::AddInputPassthrough(const NodeInput &input, const InputFlags &flags)
|
||||
QString NodeGroup::AddInputPassthrough(const NodeInput &input, const InputFlags &flags, const QString &force_id)
|
||||
{
|
||||
Q_ASSERT(ContextContainsNode(input.node()));
|
||||
|
||||
@@ -70,11 +70,26 @@ QString NodeGroup::AddInputPassthrough(const NodeInput &input, const InputFlags
|
||||
}
|
||||
|
||||
// Add input
|
||||
QString id = input.input();
|
||||
int i = 2;
|
||||
while (HasInputWithID(id)) {
|
||||
id = QStringLiteral("%1_%2").arg(input.name(), QString::number(i));
|
||||
i++;
|
||||
QString id;
|
||||
if (force_id.isEmpty()) {
|
||||
id = input.input();
|
||||
int i = 2;
|
||||
while (HasInputWithID(id)) {
|
||||
id = QStringLiteral("%1_%2").arg(input.name(), QString::number(i));
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
id = force_id;
|
||||
|
||||
bool already_exists = false;
|
||||
for (auto it=input_passthroughs_.cbegin(); it!=input_passthroughs_.cend(); it++) {
|
||||
if (it->first == id) {
|
||||
already_exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(!already_exists);
|
||||
}
|
||||
|
||||
AddInput(id, input.GetDataType(), input.GetDefaultValue(), input.GetFlags() | flags);
|
||||
@@ -153,7 +168,7 @@ bool NodeGroup::GetInner(NodeInput *input)
|
||||
void NodeGroupAddInputPassthrough::redo()
|
||||
{
|
||||
if (!group_->ContainsInputPassthrough(input_)) {
|
||||
group_->AddInputPassthrough(input_);
|
||||
group_->AddInputPassthrough(input_, InputFlags(), force_id_);
|
||||
actually_added_ = true;
|
||||
} else {
|
||||
actually_added_ = false;
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
|
||||
virtual void Retranslate() override;
|
||||
|
||||
QString AddInputPassthrough(const NodeInput &input, const InputFlags &flags = InputFlags());
|
||||
QString AddInputPassthrough(const NodeInput &input, const InputFlags &flags = InputFlags(), const QString &force_id = QString());
|
||||
|
||||
void RemoveInputPassthrough(const NodeInput &input);
|
||||
|
||||
@@ -103,7 +103,7 @@ private:
|
||||
class NodeGroupAddInputPassthrough : public UndoCommand
|
||||
{
|
||||
public:
|
||||
NodeGroupAddInputPassthrough(NodeGroup *group, const NodeInput &input) :
|
||||
NodeGroupAddInputPassthrough(NodeGroup *group, const NodeInput &input, const QString &force_id = QString()) :
|
||||
group_(group),
|
||||
input_(input),
|
||||
actually_added_(false)
|
||||
@@ -124,6 +124,8 @@ private:
|
||||
|
||||
NodeInput input_;
|
||||
|
||||
QString force_id_;
|
||||
|
||||
bool actually_added_;
|
||||
|
||||
};
|
||||
|
||||
+32
-1
@@ -554,6 +554,37 @@ QVariant Node::GetSplitDefaultValueOnTrack(const QString &input, int track) cons
|
||||
}
|
||||
}
|
||||
|
||||
void Node::SetDefaultValue(const QString &input, const QVariant &val)
|
||||
{
|
||||
NodeValue::Type type = GetInputDataType(input);
|
||||
|
||||
SetSplitDefaultValue(input, NodeValue::split_normal_value_into_track_values(type, val));
|
||||
}
|
||||
|
||||
void Node::SetSplitDefaultValue(const QString &input, const SplitValue &val)
|
||||
{
|
||||
Input* i = GetInternalInputData(input);
|
||||
|
||||
if (i) {
|
||||
i->default_value = val;
|
||||
} else {
|
||||
ReportInvalidInput("set default value of", input);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::SetSplitDefaultValueOnTrack(const QString &input, const QVariant &val, int track)
|
||||
{
|
||||
Input* i = GetInternalInputData(input);
|
||||
|
||||
if (i) {
|
||||
if (track < i->default_value.size()) {
|
||||
i->default_value[track] = val;
|
||||
}
|
||||
} else {
|
||||
ReportInvalidInput("set default value on track of", input);
|
||||
}
|
||||
}
|
||||
|
||||
const QVector<NodeKeyframeTrack> &Node::GetKeyframeTracks(const QString &input, int element) const
|
||||
{
|
||||
return GetImmediate(input, element)->keyframe_tracks();
|
||||
@@ -1019,7 +1050,7 @@ Node *Node::CopyNodeAndDependencyGraphMinusItemsInternal(QMap<Node*, Node*>& cre
|
||||
// This node should have been created by the context loop above
|
||||
NodeInput input = it->second;
|
||||
input.set_node(created.value(input.node()));
|
||||
command->add_child(new NodeGroupAddInputPassthrough(dst_group, input));
|
||||
command->add_child(new NodeGroupAddInputPassthrough(dst_group, input, it->first));
|
||||
}
|
||||
|
||||
command->add_child(new NodeGroupSetOutputPassthrough(dst_group, created.value(src_group->GetOutputPassthrough())));
|
||||
|
||||
+6
-2
@@ -321,6 +321,8 @@ public:
|
||||
|
||||
virtual QString GetInputName(const QString& id) const;
|
||||
|
||||
void SetInputName(const QString& id, const QString& name);
|
||||
|
||||
bool IsInputHidden(const QString& input) const;
|
||||
bool IsInputConnectable(const QString& input) const;
|
||||
bool IsInputKeyframable(const QString& input) const;
|
||||
@@ -404,6 +406,10 @@ public:
|
||||
SplitValue GetSplitDefaultValue(const QString& input) const;
|
||||
QVariant GetSplitDefaultValueOnTrack(const QString& input, int track) const;
|
||||
|
||||
void SetDefaultValue(const QString& input, const QVariant &val);
|
||||
void SetSplitDefaultValue(const QString& input, const SplitValue &val);
|
||||
void SetSplitDefaultValueOnTrack(const QString& input, const QVariant &val, int track);
|
||||
|
||||
const QVector<NodeKeyframeTrack>& GetKeyframeTracks(const QString& input, int element) const;
|
||||
const QVector<NodeKeyframeTrack>& GetKeyframeTracks(const NodeInput& input) const
|
||||
{
|
||||
@@ -974,8 +980,6 @@ protected:
|
||||
|
||||
void RemoveInput(const QString& id);
|
||||
|
||||
void SetInputName(const QString& id, const QString& name);
|
||||
|
||||
void SetComboBoxStrings(const QString& id, const QStringList& strings)
|
||||
{
|
||||
SetInputProperty(id, QStringLiteral("combo_str"), strings);
|
||||
|
||||
@@ -123,6 +123,15 @@ QVariant NodeInput::GetProperty(const QString &key) const
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, QVariant> NodeInput::GetProperties() const
|
||||
{
|
||||
if (IsValid()) {
|
||||
return node_->GetInputProperties(input_);
|
||||
} else {
|
||||
return QHash<QString, QVariant>();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant NodeInput::GetValueAtTime(const rational &time) const
|
||||
{
|
||||
if (IsValid()) {
|
||||
|
||||
+44
-5
@@ -52,11 +52,6 @@ public:
|
||||
f_ = flags;
|
||||
}
|
||||
|
||||
bool operator&(const InputFlag& f) const
|
||||
{
|
||||
return f_ & f;
|
||||
}
|
||||
|
||||
InputFlags operator|(const InputFlags &f) const
|
||||
{
|
||||
InputFlags i = *this;
|
||||
@@ -70,6 +65,49 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputFlags operator&(const InputFlags &f) const
|
||||
{
|
||||
InputFlags i = *this;
|
||||
i &= f;
|
||||
return i;
|
||||
}
|
||||
|
||||
InputFlags &operator&=(const InputFlags &f)
|
||||
{
|
||||
f_ &= f.f_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputFlags operator&(const InputFlag &f) const
|
||||
{
|
||||
InputFlags i = *this;
|
||||
i &= f;
|
||||
return i;
|
||||
}
|
||||
|
||||
InputFlags &operator&=(const InputFlag &f)
|
||||
{
|
||||
f_ &= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputFlags operator~() const
|
||||
{
|
||||
InputFlags i = *this;
|
||||
i.f_ = ~i.f_;
|
||||
return i;
|
||||
}
|
||||
|
||||
inline operator bool() const
|
||||
{
|
||||
return f_;
|
||||
}
|
||||
|
||||
inline const uint64_t &value() const
|
||||
{
|
||||
return f_;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t f_;
|
||||
|
||||
@@ -188,6 +226,7 @@ public:
|
||||
QStringList GetComboBoxStrings() const;
|
||||
|
||||
QVariant GetProperty(const QString& key) const;
|
||||
QHash<QString, QVariant> GetProperties() const;
|
||||
|
||||
QVariant GetValueAtTime(const rational& time) const;
|
||||
|
||||
|
||||
@@ -27,5 +27,7 @@ set(OLIVE_SOURCES
|
||||
node/project/serializer/serializer210907.h
|
||||
node/project/serializer/serializer211228.cpp
|
||||
node/project/serializer/serializer211228.h
|
||||
node/project/serializer/serializer220403.cpp
|
||||
node/project/serializer/serializer220403.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "serializer210528.h"
|
||||
#include "serializer210907.h"
|
||||
#include "serializer211228.h"
|
||||
#include "serializer220403.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -45,6 +46,7 @@ void ProjectSerializer::Initialize()
|
||||
instances_.append(new ProjectSerializer210528);
|
||||
instances_.append(new ProjectSerializer210907);
|
||||
instances_.append(new ProjectSerializer211228);
|
||||
instances_.append(new ProjectSerializer220403);
|
||||
}
|
||||
|
||||
void ProjectSerializer::Destroy()
|
||||
|
||||
@@ -214,80 +214,6 @@ ProjectSerializer211228::LoadData ProjectSerializer211228::Load(Project *project
|
||||
return load_data;
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::Save(QXmlStreamWriter *writer, const SaveData &data, void *reserved) const
|
||||
{
|
||||
Project *project = data.GetProject();
|
||||
|
||||
writer->writeTextElement(QStringLiteral("uuid"), data.GetProject()->GetUuid().toString());
|
||||
|
||||
writer->writeStartElement(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"));
|
||||
|
||||
if (node == project->root()) {
|
||||
writer->writeAttribute(QStringLiteral("root"), QStringLiteral("1"));
|
||||
} else if (node == project->color_manager()) {
|
||||
writer->writeAttribute(QStringLiteral("cm"), QStringLiteral("1"));
|
||||
} else if (node == project->settings()) {
|
||||
writer->writeAttribute(QStringLiteral("settings"), QStringLiteral("1"));
|
||||
}
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), node->id());
|
||||
|
||||
SaveNode(node, writer);
|
||||
|
||||
writer->writeEndElement(); // node
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // nodes
|
||||
|
||||
writer->writeStartElement(QStringLiteral("positions"));
|
||||
|
||||
foreach (Node* context, using_node_list) {
|
||||
const Node::PositionMap &map = context->GetContextPositions();
|
||||
|
||||
if (!map.isEmpty()) {
|
||||
writer->writeStartElement(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"));
|
||||
SavePosition(writer, jt.key(), jt.value());
|
||||
writer->writeEndElement(); // node
|
||||
}
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // context
|
||||
}
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // positions
|
||||
|
||||
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
|
||||
|
||||
// Save main window project layout
|
||||
project->GetLayoutInfo().toXml(writer);
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const
|
||||
{
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
@@ -373,60 +299,6 @@ void ProjectSerializer211228::LoadNode(Node *node, XMLNodeData &xml_node_data, Q
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::SaveNode(Node *node, QXmlStreamWriter *writer) const
|
||||
{
|
||||
writer->writeTextElement(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(node)));
|
||||
|
||||
writer->writeTextElement(QStringLiteral("label"), node->GetLabel());
|
||||
writer->writeTextElement(QStringLiteral("color"), QString::number(node->GetOverrideColor()));
|
||||
|
||||
foreach (const QString& input, node->inputs()) {
|
||||
writer->writeStartElement(QStringLiteral("input"));
|
||||
|
||||
SaveInput(node, writer, input);
|
||||
|
||||
writer->writeEndElement(); // input
|
||||
}
|
||||
|
||||
writer->writeStartElement(QStringLiteral("links"));
|
||||
foreach (Node* link, node->links()) {
|
||||
writer->writeTextElement(QStringLiteral("link"), QString::number(reinterpret_cast<quintptr>(link)));
|
||||
}
|
||||
writer->writeEndElement(); // links
|
||||
|
||||
writer->writeStartElement(QStringLiteral("connections"));
|
||||
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
|
||||
writer->writeStartElement(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
|
||||
}
|
||||
writer->writeEndElement(); // connections
|
||||
|
||||
writer->writeStartElement(QStringLiteral("hints"));
|
||||
for (auto it=node->GetValueHints().cbegin(); it!=node->GetValueHints().cend(); it++) {
|
||||
writer->writeStartElement(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
|
||||
}
|
||||
writer->writeEndElement();
|
||||
|
||||
writer->writeStartElement(QStringLiteral("custom"));
|
||||
|
||||
SaveNodeCustom(writer, node);
|
||||
|
||||
writer->writeEndElement(); // custom
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::LoadInput(Node *node, QXmlStreamReader *reader, XMLNodeData &xml_node_data) const
|
||||
{
|
||||
QString param_id;
|
||||
@@ -484,33 +356,6 @@ void ProjectSerializer211228::LoadInput(Node *node, QXmlStreamReader *reader, XM
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::SaveInput(Node *node, QXmlStreamWriter *writer, const QString &id) const
|
||||
{
|
||||
writer->writeAttribute(QStringLiteral("id"), id);
|
||||
|
||||
writer->writeStartElement(QStringLiteral("primary"));
|
||||
|
||||
SaveImmediate(writer, node, id, -1);
|
||||
|
||||
writer->writeEndElement(); // primary
|
||||
|
||||
writer->writeStartElement(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"));
|
||||
|
||||
SaveImmediate(writer, node, id, i);
|
||||
|
||||
writer->writeEndElement(); // element
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // subelements
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData &xml_node_data) const
|
||||
{
|
||||
Q_UNUSED(xml_node_data)
|
||||
@@ -628,69 +473,6 @@ void ProjectSerializer211228::LoadImmediate(QXmlStreamReader *reader, Node *node
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::SaveImmediate(QXmlStreamWriter *writer, Node *node, const QString& input, int element) const
|
||||
{
|
||||
if (node->IsInputKeyframable(input)) {
|
||||
writer->writeTextElement(QStringLiteral("keyframing"), QString::number(node->IsInputKeyframing(input, element)));
|
||||
}
|
||||
|
||||
NodeValue::Type data_type = node->GetInputDataType(input);
|
||||
|
||||
// Write standard value
|
||||
writer->writeStartElement(QStringLiteral("standard"));
|
||||
|
||||
foreach (const QVariant& v, node->GetSplitStandardValue(input, element)) {
|
||||
writer->writeStartElement(QStringLiteral("track"));
|
||||
|
||||
if (data_type == NodeValue::kVideoParams) {
|
||||
v.value<VideoParams>().Save(writer);
|
||||
} else if (data_type == NodeValue::kAudioParams) {
|
||||
v.value<AudioParams>().Save(writer);
|
||||
} else {
|
||||
writer->writeCharacters(NodeValue::ValueToString(data_type, v, true));
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // track
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // standard
|
||||
|
||||
// Write keyframes
|
||||
writer->writeStartElement(QStringLiteral("keyframes"));
|
||||
|
||||
for (const NodeKeyframeTrack& track : node->GetKeyframeTracks(input, element)) {
|
||||
writer->writeStartElement(QStringLiteral("track"));
|
||||
|
||||
for (NodeKeyframe* key : track) {
|
||||
writer->writeStartElement(QStringLiteral("key"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("input"), key->input());
|
||||
writer->writeAttribute(QStringLiteral("time"), key->time().toString());
|
||||
writer->writeAttribute(QStringLiteral("type"), QString::number(key->type()));
|
||||
writer->writeAttribute(QStringLiteral("inhandlex"), QString::number(key->bezier_control_in().x()));
|
||||
writer->writeAttribute(QStringLiteral("inhandley"), QString::number(key->bezier_control_in().y()));
|
||||
writer->writeAttribute(QStringLiteral("outhandlex"), QString::number(key->bezier_control_out().x()));
|
||||
writer->writeAttribute(QStringLiteral("outhandley"), QString::number(key->bezier_control_out().y()));
|
||||
|
||||
writer->writeCharacters(NodeValue::ValueToString(data_type, key->value(), true));
|
||||
|
||||
writer->writeEndElement(); // key
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // track
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // keyframes
|
||||
|
||||
if (data_type == NodeValue::kColor) {
|
||||
// Save color management information
|
||||
writer->writeTextElement(QStringLiteral("csinput"), node->GetInputProperty(input, QStringLiteral("col_input")).toString());
|
||||
writer->writeTextElement(QStringLiteral("csdisplay"), node->GetInputProperty(input, QStringLiteral("col_display")).toString());
|
||||
writer->writeTextElement(QStringLiteral("csview"), node->GetInputProperty(input, QStringLiteral("col_view")).toString());
|
||||
writer->writeTextElement(QStringLiteral("cslook"), node->GetInputProperty(input, QStringLiteral("col_look")).toString());
|
||||
}
|
||||
}
|
||||
|
||||
bool ProjectSerializer211228::LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const
|
||||
{
|
||||
bool got_node_ptr = false;
|
||||
@@ -722,15 +504,6 @@ bool ProjectSerializer211228::LoadPosition(QXmlStreamReader *reader, quintptr *n
|
||||
return got_node_ptr && got_pos_x && got_pos_y;
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::SavePosition(QXmlStreamWriter *writer, Node *node, const Node::Position &pos) const
|
||||
{
|
||||
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(node)));
|
||||
|
||||
writer->writeTextElement(QStringLiteral("x"), QString::number(pos.position.x()));
|
||||
writer->writeTextElement(QStringLiteral("y"), QString::number(pos.position.y()));
|
||||
writer->writeTextElement(QStringLiteral("expanded"), QString::number(pos.expanded));
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::PostConnect(const XMLNodeData &xml_node_data) const
|
||||
{
|
||||
foreach (const XMLNodeData::SerializedConnection& con, xml_node_data.desired_connections) {
|
||||
@@ -827,36 +600,6 @@ void ProjectSerializer211228::LoadNodeCustom(QXmlStreamReader *reader, Node *nod
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::SaveNodeCustom(QXmlStreamWriter *writer, Node *node) const
|
||||
{
|
||||
if (ViewerOutput *viewer = dynamic_cast<ViewerOutput*>(node)) {
|
||||
// Write TimelinePoints
|
||||
writer->writeStartElement(QStringLiteral("points"));
|
||||
SaveTimelinePoints(writer, viewer->GetTimelinePoints());
|
||||
writer->writeEndElement(); // points
|
||||
|
||||
if (Footage *footage = dynamic_cast<Footage*>(node)) {
|
||||
writer->writeTextElement(QStringLiteral("timestamp"), QString::number(footage->timestamp()));
|
||||
}
|
||||
} 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"));
|
||||
|
||||
foreach (const NodeGroup::InputPassthrough &ip, group->GetInputPassthroughs()) {
|
||||
writer->writeStartElement(QStringLiteral("inputpassthrough"));
|
||||
writer->writeTextElement(QStringLiteral("node"), QString::number(reinterpret_cast<quintptr>(ip.second.node())));
|
||||
writer->writeTextElement(QStringLiteral("input"), ip.second.input());
|
||||
writer->writeTextElement(QStringLiteral("element"), QString::number(ip.second.element()));
|
||||
writer->writeEndElement(); // input
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // inputpassthroughs
|
||||
|
||||
writer->writeTextElement(QStringLiteral("outputpassthrough"), QString::number(reinterpret_cast<quintptr>(group->GetOutputPassthrough())));
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::LoadTimelinePoints(QXmlStreamReader *reader, TimelinePoints *points) const
|
||||
{
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
@@ -870,17 +613,6 @@ void ProjectSerializer211228::LoadTimelinePoints(QXmlStreamReader *reader, Timel
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::SaveTimelinePoints(QXmlStreamWriter *writer, TimelinePoints *points) const
|
||||
{
|
||||
writer->writeStartElement(QStringLiteral("workarea"));
|
||||
SaveWorkArea(writer, points->workarea());
|
||||
writer->writeEndElement(); // workarea
|
||||
|
||||
writer->writeStartElement(QStringLiteral("markers"));
|
||||
SaveMarkerList(writer, points->markers());
|
||||
writer->writeEndElement(); // markers
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const
|
||||
{
|
||||
rational range_in = workarea->in();
|
||||
@@ -905,13 +637,6 @@ void ProjectSerializer211228::LoadWorkArea(QXmlStreamReader *reader, TimelineWor
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::SaveWorkArea(QXmlStreamWriter *writer, TimelineWorkArea *workarea) const
|
||||
{
|
||||
writer->writeAttribute(QStringLiteral("enabled"), QString::number(workarea->enabled()));
|
||||
writer->writeAttribute(QStringLiteral("in"), workarea->in().toString());
|
||||
writer->writeAttribute(QStringLiteral("out"), workarea->out().toString());
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const
|
||||
{
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
@@ -936,20 +661,6 @@ void ProjectSerializer211228::LoadMarkerList(QXmlStreamReader *reader, TimelineM
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::SaveMarkerList(QXmlStreamWriter *writer, TimelineMarkerList *markers) const
|
||||
{
|
||||
foreach (TimelineMarker* marker, markers->list()) {
|
||||
writer->writeStartElement(QStringLiteral("marker"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("name"), marker->name());
|
||||
|
||||
writer->writeAttribute(QStringLiteral("in"), marker->time().in().toString());
|
||||
writer->writeAttribute(QStringLiteral("out"), marker->time().out().toString());
|
||||
|
||||
writer->writeEndElement(); // marker
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const
|
||||
{
|
||||
QVector<NodeValue::Type> types;
|
||||
@@ -975,19 +686,4 @@ void ProjectSerializer211228::LoadValueHint(Node::ValueHint *hint, QXmlStreamRea
|
||||
hint->set_type(types);
|
||||
}
|
||||
|
||||
void ProjectSerializer211228::SaveValueHint(const Node::ValueHint *hint, QXmlStreamWriter *writer) const
|
||||
{
|
||||
writer->writeStartElement(QStringLiteral("types"));
|
||||
|
||||
for (auto it=hint->types().cbegin(); it!=hint->types().cend(); it++) {
|
||||
writer->writeTextElement(QStringLiteral("type"), QString::number(*it));
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // types
|
||||
|
||||
writer->writeTextElement(QStringLiteral("index"), QString::number(hint->index()));
|
||||
|
||||
writer->writeTextElement(QStringLiteral("tag"), hint->tag());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@ public:
|
||||
protected:
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader, void *reserved) const override;
|
||||
|
||||
virtual void Save(QXmlStreamWriter *writer, const SaveData &data, void *reserved) const override;
|
||||
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 211228;
|
||||
@@ -70,42 +68,24 @@ private:
|
||||
|
||||
void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const;
|
||||
|
||||
void SaveNode(Node *node, QXmlStreamWriter *writer) const;
|
||||
|
||||
void LoadInput(Node *node, QXmlStreamReader* reader, XMLNodeData &xml_node_data) const;
|
||||
|
||||
void SaveInput(Node *node, QXmlStreamWriter* writer, const QString& id) const;
|
||||
|
||||
void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const;
|
||||
|
||||
void SaveImmediate(QXmlStreamWriter *writer, Node *node, const QString &input, int element) const;
|
||||
|
||||
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const;
|
||||
|
||||
void SavePosition(QXmlStreamWriter *writer, Node *node, const Node::Position &pos) const;
|
||||
|
||||
void PostConnect(const XMLNodeData &xml_node_data) const;
|
||||
|
||||
void LoadNodeCustom(QXmlStreamReader *reader, Node *node, XMLNodeData &xml_node_data) const;
|
||||
|
||||
void SaveNodeCustom(QXmlStreamWriter *writer, Node *node) const;
|
||||
|
||||
void LoadTimelinePoints(QXmlStreamReader *reader, TimelinePoints *points) const;
|
||||
|
||||
void SaveTimelinePoints(QXmlStreamWriter *writer, TimelinePoints *points) const;
|
||||
|
||||
void LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const;
|
||||
|
||||
void SaveWorkArea(QXmlStreamWriter *writer, TimelineWorkArea *workarea) const;
|
||||
|
||||
void LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const;
|
||||
|
||||
void SaveMarkerList(QXmlStreamWriter *writer, TimelineMarkerList *markers) const;
|
||||
|
||||
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
|
||||
|
||||
void SaveValueHint(const Node::ValueHint *hint, QXmlStreamWriter *writer) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,119 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2021 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef SERIALIZER220403_H
|
||||
#define SERIALIZER220403_H
|
||||
|
||||
#include "serializer.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ProjectSerializer220403 : public ProjectSerializer
|
||||
{
|
||||
public:
|
||||
ProjectSerializer220403() = default;
|
||||
|
||||
protected:
|
||||
virtual LoadData Load(Project *project, QXmlStreamReader *reader, void *reserved) const override;
|
||||
|
||||
virtual void Save(QXmlStreamWriter *writer, const SaveData &data, void *reserved) const override;
|
||||
|
||||
virtual uint Version() const override
|
||||
{
|
||||
return 220403;
|
||||
}
|
||||
|
||||
private:
|
||||
struct XMLNodeData {
|
||||
struct SerializedConnection {
|
||||
NodeInput input;
|
||||
quintptr output_node;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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 SaveNode(Node *node, QXmlStreamWriter *writer) const;
|
||||
|
||||
void LoadInput(Node *node, QXmlStreamReader* reader, XMLNodeData &xml_node_data) const;
|
||||
|
||||
void SaveInput(Node *node, QXmlStreamWriter* writer, const QString& id) const;
|
||||
|
||||
void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const;
|
||||
|
||||
void SaveImmediate(QXmlStreamWriter *writer, Node *node, const QString &input, int element) const;
|
||||
|
||||
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const;
|
||||
|
||||
void SavePosition(QXmlStreamWriter *writer, Node *node, const Node::Position &pos) const;
|
||||
|
||||
void PostConnect(const XMLNodeData &xml_node_data) const;
|
||||
|
||||
void LoadNodeCustom(QXmlStreamReader *reader, Node *node, XMLNodeData &xml_node_data) const;
|
||||
|
||||
void SaveNodeCustom(QXmlStreamWriter *writer, Node *node) const;
|
||||
|
||||
void LoadTimelinePoints(QXmlStreamReader *reader, TimelinePoints *points) const;
|
||||
|
||||
void SaveTimelinePoints(QXmlStreamWriter *writer, TimelinePoints *points) const;
|
||||
|
||||
void LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const;
|
||||
|
||||
void SaveWorkArea(QXmlStreamWriter *writer, TimelineWorkArea *workarea) const;
|
||||
|
||||
void LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const;
|
||||
|
||||
void SaveMarkerList(QXmlStreamWriter *writer, TimelineMarkerList *markers) const;
|
||||
|
||||
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
|
||||
|
||||
void SaveValueHint(const Node::ValueHint *hint, QXmlStreamWriter *writer) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SERIALIZER220403_H
|
||||
@@ -141,6 +141,7 @@ QByteArray NodeValue::ValueToBytes(NodeValue::Type type, const QVariant &value)
|
||||
case kShaderJob:
|
||||
case kSampleJob:
|
||||
case kGenerateJob:
|
||||
case kDataTypeCount:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -357,12 +358,78 @@ QString NodeValue::GetPrettyDataTypeName(Type type)
|
||||
case kShaderJob:
|
||||
case kSampleJob:
|
||||
case kGenerateJob:
|
||||
case kDataTypeCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return QCoreApplication::translate("NodeValue", "Unknown");
|
||||
}
|
||||
|
||||
QString NodeValue::GetDataTypeName(Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case kNone:
|
||||
return QStringLiteral("none");
|
||||
case kInt:
|
||||
return QStringLiteral("int");
|
||||
case kCombo:
|
||||
return QStringLiteral("combo");
|
||||
case kFloat:
|
||||
return QStringLiteral("float");
|
||||
case kRational:
|
||||
return QStringLiteral("rational");
|
||||
case kBoolean:
|
||||
return QStringLiteral("bool");
|
||||
case kColor:
|
||||
return QStringLiteral("color");
|
||||
case kMatrix:
|
||||
return QStringLiteral("matrix");
|
||||
case kText:
|
||||
return QStringLiteral("text");
|
||||
case kFont:
|
||||
return QStringLiteral("font");
|
||||
case kFile:
|
||||
return QStringLiteral("file");
|
||||
case kTexture:
|
||||
return QStringLiteral("texture");
|
||||
case kSamples:
|
||||
return QStringLiteral("samples");
|
||||
case kVec2:
|
||||
return QStringLiteral("vec2");
|
||||
case kVec3:
|
||||
return QStringLiteral("vec3");
|
||||
case kVec4:
|
||||
return QStringLiteral("vec4");
|
||||
case kBezier:
|
||||
return QStringLiteral("bezier");
|
||||
case kVideoParams:
|
||||
return QStringLiteral("vparam");
|
||||
case kAudioParams:
|
||||
return QStringLiteral("aparam");
|
||||
case kFootageJob:
|
||||
case kShaderJob:
|
||||
case kSampleJob:
|
||||
case kGenerateJob:
|
||||
case kDataTypeCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
NodeValue::Type NodeValue::GetDataTypeFromName(const QString &n)
|
||||
{
|
||||
// Slow but easy to maintain
|
||||
for (int i=0; i<kDataTypeCount; i++) {
|
||||
Type t = static_cast<Type>(i);
|
||||
if (GetDataTypeName(t) == n) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
return NodeValue::kNone;
|
||||
}
|
||||
|
||||
NodeValue NodeValueTable::GetWithMeta(const QVector<NodeValue::Type> &type, const QString &tag) const
|
||||
{
|
||||
int value_index = GetValueIndex(type, tag);
|
||||
|
||||
+9
-1
@@ -206,7 +206,12 @@ public:
|
||||
* take place. This value will usually be taken from a table and a kSamples value will be
|
||||
* pushed to take its place.
|
||||
*/
|
||||
kGenerateJob
|
||||
kGenerateJob,
|
||||
|
||||
/**
|
||||
* End of list
|
||||
*/
|
||||
kDataTypeCount
|
||||
};
|
||||
|
||||
static const QVector<Type> kNumber;
|
||||
@@ -261,6 +266,9 @@ public:
|
||||
|
||||
static QString GetPrettyDataTypeName(Type type);
|
||||
|
||||
static QString GetDataTypeName(Type type);
|
||||
static NodeValue::Type GetDataTypeFromName(const QString &n);
|
||||
|
||||
static QString ValueToString(Type data_type, const QVariant& value, bool value_is_a_key_track);
|
||||
|
||||
static QVariant StringToValue(Type data_type, const QString &string, bool value_is_a_key_track);
|
||||
|
||||
@@ -523,6 +523,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
case NodeValue::kFootageJob:
|
||||
case NodeValue::kBezier:
|
||||
case NodeValue::kNone:
|
||||
case NodeValue::kDataTypeCount:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
|
||||
case NodeValue::kGenerateJob:
|
||||
case NodeValue::kVideoParams:
|
||||
case NodeValue::kAudioParams:
|
||||
case NodeValue::kDataTypeCount:
|
||||
break;
|
||||
case NodeValue::kInt:
|
||||
{
|
||||
@@ -245,6 +246,7 @@ void NodeParamViewWidgetBridge::WidgetCallback()
|
||||
case NodeValue::kGenerateJob:
|
||||
case NodeValue::kVideoParams:
|
||||
case NodeValue::kAudioParams:
|
||||
case NodeValue::kDataTypeCount:
|
||||
break;
|
||||
case NodeValue::kInt:
|
||||
{
|
||||
@@ -421,6 +423,7 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
|
||||
case NodeValue::kGenerateJob:
|
||||
case NodeValue::kVideoParams:
|
||||
case NodeValue::kAudioParams:
|
||||
case NodeValue::kDataTypeCount:
|
||||
break;
|
||||
case NodeValue::kInt:
|
||||
{
|
||||
|
||||
@@ -261,7 +261,7 @@ void NodeView::Duplicate()
|
||||
for (auto it=src_group->GetInputPassthroughs().cbegin(); it!=src_group->GetInputPassthroughs().cend(); it++) {
|
||||
NodeInput input = it->second;
|
||||
input.set_node(new_nodes.at(selected.indexOf(input.node())));
|
||||
dst_group->AddInputPassthrough(input);
|
||||
dst_group->AddInputPassthrough(input, InputFlags(), it->first);
|
||||
}
|
||||
|
||||
dst_group->SetOutputPassthrough(new_nodes.at(selected.indexOf(src_group->GetOutputPassthrough())));
|
||||
|
||||
Reference in New Issue
Block a user