diff --git a/app/common/xmlutils.h b/app/common/xmlutils.h index 67a881a0c..d8c012559 100644 --- a/app/common/xmlutils.h +++ b/app/common/xmlutils.h @@ -33,6 +33,7 @@ class Node; class NodeParam; class NodeInput; class NodeOutput; +class Item; #define XMLAttributeLoop(reader, item) \ QXmlStreamAttributes __attributes = reader->attributes(); \ @@ -61,6 +62,7 @@ struct XMLNodeData { QHash footage_ptrs; QList footage_connections; QList block_links; + QHash item_ptrs; }; diff --git a/app/panel/project/project.cpp b/app/panel/project/project.cpp index 5949ca1e3..079ba6d0c 100644 --- a/app/panel/project/project.cpp +++ b/app/panel/project/project.cpp @@ -99,6 +99,11 @@ void ProjectPanel::set_project(Project *p) } } +QModelIndex ProjectPanel::get_root_index() const +{ + return explorer_->get_root_index(); +} + void ProjectPanel::set_root(Item *item) { explorer_->set_root(item); @@ -161,7 +166,7 @@ void ProjectPanel::Edit(Item* item) void ProjectPanel::Retranslate() { - if (explorer_->root_index().isValid()) { + if (explorer_->get_root_index().isValid()) { SetTitle(tr("Folder")); } else { SetTitle(tr("Project")); @@ -198,10 +203,10 @@ void ProjectPanel::UpdateSubtitle() if (project()) { QString project_title = QStringLiteral("[*]%1").arg(project()->name()); - if (explorer_->root_index().isValid()) { + if (explorer_->get_root_index().isValid()) { QString folder_path; - Item* item = static_cast(explorer_->root_index().internalPointer()); + Item* item = static_cast(explorer_->get_root_index().internalPointer()); do { folder_path.prepend(QStringLiteral("/%1").arg(item->name())); diff --git a/app/panel/project/project.h b/app/panel/project/project.h index 49b740601..4e7ce3e7a 100644 --- a/app/panel/project/project.h +++ b/app/panel/project/project.h @@ -40,6 +40,8 @@ public: Project* project() const; void set_project(Project* p); + QModelIndex get_root_index() const; + void set_root(Item* item); QList SelectedItems() const; diff --git a/app/project/item/folder/folder.cpp b/app/project/item/folder/folder.cpp index 2bf9fac4e..d9c727a8b 100644 --- a/app/project/item/folder/folder.cpp +++ b/app/project/item/folder/folder.cpp @@ -51,6 +51,8 @@ void Folder::Load(QXmlStreamReader *reader, XMLNodeData& xml_node_data, const QA if (attr.name() == QStringLiteral("name")) { set_name(attr.value().toString()); + } else if (attr.name() == QStringLiteral("ptr")) { + xml_node_data.item_ptrs.insert(attr.value().toULongLong(), this); } } @@ -79,9 +81,11 @@ void Folder::Load(QXmlStreamReader *reader, XMLNodeData& xml_node_data, const QA void Folder::Save(QXmlStreamWriter *writer) const { - writer->writeStartElement("folder"); + writer->writeStartElement(QStringLiteral("folder")); - writer->writeAttribute("name", name()); + writer->writeAttribute(QStringLiteral("name"), name()); + + writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast(this))); foreach (ItemPtr child, children()) { child->Save(writer); diff --git a/app/project/item/sequence/sequence.cpp b/app/project/item/sequence/sequence.cpp index 71b51f8b9..b87a35925 100644 --- a/app/project/item/sequence/sequence.cpp +++ b/app/project/item/sequence/sequence.cpp @@ -51,10 +51,10 @@ void Sequence::Load(QXmlStreamReader *reader, XMLNodeData& xml_node_data, const return; } - if (attr.name() == "name") { + if (attr.name() == QStringLiteral("name")) { set_name(attr.value().toString()); - - // Currently the only thing we care about + } else if (attr.name() == QStringLiteral("ptr")) { + xml_node_data.item_ptrs.insert(attr.value().toULongLong(), this); } } @@ -137,22 +137,24 @@ void Sequence::Load(QXmlStreamReader *reader, XMLNodeData& xml_node_data, const void Sequence::Save(QXmlStreamWriter *writer) const { - writer->writeStartElement("sequence"); + writer->writeStartElement(QStringLiteral("sequence")); - writer->writeAttribute("name", name()); + writer->writeAttribute(QStringLiteral("name"), name()); - writer->writeStartElement("video"); + writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast(viewer_output_))); - writer->writeTextElement("width", QString::number(video_params().width())); - writer->writeTextElement("height", QString::number(video_params().height())); - writer->writeTextElement("timebase", video_params().time_base().toString()); + writer->writeStartElement(QStringLiteral("video")); + + writer->writeTextElement(QStringLiteral("width"), QString::number(video_params().width())); + writer->writeTextElement(QStringLiteral("height"), QString::number(video_params().height())); + writer->writeTextElement(QStringLiteral("timebase"), video_params().time_base().toString()); writer->writeEndElement(); // video - writer->writeStartElement("audio"); + writer->writeStartElement(QStringLiteral("audio")); - writer->writeTextElement("rate", QString::number(audio_params().sample_rate())); - writer->writeTextElement("layout", QString::number(audio_params().channel_layout())); + writer->writeTextElement(QStringLiteral("rate"), QString::number(audio_params().sample_rate())); + writer->writeTextElement(QStringLiteral("layout"), QString::number(audio_params().channel_layout())); writer->writeEndElement(); // audio @@ -165,7 +167,7 @@ void Sequence::Save(QXmlStreamWriter *writer) const } } - viewer_output_->Save(writer, "viewer"); + viewer_output_->Save(writer, QStringLiteral("viewer")); writer->writeEndElement(); // sequence } diff --git a/app/project/project.cpp b/app/project/project.cpp index 5ca5cd7d6..f84996ef7 100644 --- a/app/project/project.cpp +++ b/app/project/project.cpp @@ -60,6 +60,10 @@ void Project::Load(QXmlStreamReader *reader, const QAtomicInt* cancelled) } } + } else if (reader->name() == QStringLiteral("layout")) { + + Core::instance()->main_window()->LoadLayout(reader, xml_node_data); + } else { reader->skipCurrentElement(); } @@ -88,6 +92,9 @@ void Project::Save(QXmlStreamWriter *writer) const writer->writeEndElement(); // colormanagement + // Save main window project layout + Core::instance()->main_window()->SaveLayout(writer); + writer->writeEndElement(); // project } diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index 63e6ca6f8..29fb5fbbc 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -357,7 +357,7 @@ void ProjectExplorer::set_project(Project *p) model_.set_project(p); } -QModelIndex ProjectExplorer::root_index() const +QModelIndex ProjectExplorer::get_root_index() const { return tree_view_->rootIndex(); } diff --git a/app/widget/projectexplorer/projectexplorer.h b/app/widget/projectexplorer/projectexplorer.h index f0117741c..b5219b84d 100644 --- a/app/widget/projectexplorer/projectexplorer.h +++ b/app/widget/projectexplorer/projectexplorer.h @@ -54,7 +54,7 @@ public: Project* project() const; void set_project(Project* p); - QModelIndex root_index() const; + QModelIndex get_root_index() const; void set_root(Item* item); diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 2a3a5a34b..03f0a59d9 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -112,6 +112,42 @@ MainWindow::~MainWindow() #endif } +void MainWindow::LoadLayout(QXmlStreamReader *reader, XMLNodeData &xml_data) +{ + QMetaObject::invokeMethod(this, + "LoadLayoutInternal", + Qt::BlockingQueuedConnection, + Q_ARG(QXmlStreamReader*, reader), + Q_ARG(XMLNodeData*, &xml_data)); +} + +void MainWindow::SaveLayout(QXmlStreamWriter *writer) const +{ + writer->writeStartElement(QStringLiteral("layout")); + + writer->writeStartElement(QStringLiteral("folders")); + + foreach (ProjectPanel* panel, folder_panels_) { + writer->writeTextElement(QStringLiteral("folder"), + QString::number(reinterpret_cast(panel->get_root_index().internalPointer()))); + } + + writer->writeEndElement(); // folders + + writer->writeStartElement(QStringLiteral("timeline")); + + foreach (TimelinePanel* panel, timeline_panels_) { + writer->writeTextElement(QStringLiteral("sequence"), + QString::number(reinterpret_cast(panel->GetConnectedViewer()))); + } + + writer->writeEndElement(); // timeline + + writer->writeTextElement(QStringLiteral("state"), QString(saveState().toBase64())); + + writer->writeEndElement(); // layout +} + void MainWindow::OpenSequence(Sequence *sequence) { // See if this sequence is already open, and switch to it if so @@ -372,6 +408,53 @@ void MainWindow::FolderCloseRequested() panel->deleteLater(); } +void MainWindow::LoadLayoutInternal(QXmlStreamReader *reader, XMLNodeData *xml_data) +{ + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("folders")) { + + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("folder")) { + quintptr item_id = reader->readElementText().toULongLong(); + + Item* open_item = xml_data->item_ptrs.value(item_id); + + if (open_item) { + FolderOpen(open_item->project(), open_item, true); + } + } else { + reader->skipCurrentElement(); + } + } + + } else if (reader->name() == QStringLiteral("timeline")) { + + while (XMLReadNextStartElement(reader)) { + if (reader->name() == QStringLiteral("sequence")) { + quintptr item_id = reader->readElementText().toULongLong(); + + Sequence* open_seq = dynamic_cast(xml_data->item_ptrs.value(item_id)); + + if (open_seq) { + OpenSequence(open_seq); + } + } else { + reader->skipCurrentElement(); + } + } + + } else if (reader->name() == QStringLiteral("state")) { + + QByteArray state = QByteArray::fromBase64(reader->readElementText().toLatin1()); + + restoreState(state); + + } else { + reader->skipCurrentElement(); + } + } +} + TimelinePanel* MainWindow::AppendTimelinePanel() { TimelinePanel* panel = AppendPanelInternal(timeline_panels_); diff --git a/app/window/mainwindow/mainwindow.h b/app/window/mainwindow/mainwindow.h index a0a315751..61a3c1b69 100644 --- a/app/window/mainwindow/mainwindow.h +++ b/app/window/mainwindow/mainwindow.h @@ -53,6 +53,10 @@ public: virtual ~MainWindow() override; + void LoadLayout(QXmlStreamReader* reader, XMLNodeData& xml_data); + + void SaveLayout(QXmlStreamWriter* writer) const; + void OpenSequence(Sequence* sequence); void CloseSequence(Sequence* sequence); @@ -135,6 +139,8 @@ private slots: void FolderCloseRequested(); + void LoadLayoutInternal(QXmlStreamReader* reader, XMLNodeData *xml_data); + }; OLIVE_NAMESPACE_EXIT