diff --git a/mainwindow.cpp b/mainwindow.cpp index bd2b25bc2..5421f99a9 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -76,17 +76,71 @@ void MainWindow::setup_layout(bool reset) { QFile panel_config(get_config_dir().filePath("layout")); if (panel_config.exists() && panel_config.open(QFile::ReadOnly)) { - // default to resetting unless we find the tag in the XML file + // default to resetting unless we find layout data in the XML file reset = true; // read XML layout file QXmlStreamReader stream(&panel_config); + + // loop through XML for all data while (!stream.atEnd()) { - stream.readNextStartElement(); - if (stream.name() == "panels") { - restoreState(QByteArray::fromBase64(stream.readElementText().toUtf8()), 0); + stream.readNext(); + + if (stream.name() == "panels" && stream.isStartElement()) { + + // element contains MainWindow layout data to restore + stream.readNext(); + restoreState(QByteArray::fromBase64(stream.text().toUtf8()), 0); reset = false; + + } else if (stream.name() == "panel" && stream.isStartElement()) { + + // element contains layout data specific to a panel, we'll find the panel and load it + + // get panel name from XML attribute + QString panel_name; + const QXmlStreamAttributes& attributes = stream.attributes(); + for (int i=0;iobjectName() == panel_name) { + + // found the panel, so we can load its state + stream.readNext(); + panel->LoadLayoutState(QByteArray::fromBase64(stream.text().toUtf8())); + + // we found it, no more need to loop through panels + found_panel = true; + + break; + + } + + } + + if (!found_panel) { + qWarning() << "Panel specified in layout data doesn't exist. Layout wasn't loaded."; + } + + } + } + } panel_config.close(); @@ -904,10 +958,37 @@ void MainWindow::closeEvent(QCloseEvent *e) { QFile panel_config(get_config_dir().filePath("layout")); if (panel_config.open(QFile::WriteOnly)) { QXmlStreamWriter stream(&panel_config); + stream.setAutoFormatting(true); stream.writeStartDocument(); + stream.writeStartElement("layout"); + stream.writeTextElement("panels", saveState(0).toBase64()); + // if the panels have any specific layout data to save, save it now + for (int i=0;iSaveLayoutState(); + + if (!layout_data.isEmpty()) { + + // layout data is matched with the panel's objectName(), which we can't do if the panel has no name + const QString& panel_name = olive::panels.at(i)->objectName(); + if (panel_name.isEmpty()) { + qWarning() << "Panel" << i << "had layout state data but no objectName(). Layout was not saved."; + } else { + stream.writeStartElement("panel"); + + stream.writeAttribute("name", panel_name); + + stream.writeCharacters(layout_data.toBase64()); + + stream.writeEndElement(); + } + } + } + + stream.writeEndElement(); // layout + stream.writeEndDocument(); panel_config.close(); } else { diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index b6aa690e3..174baa795 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -321,7 +320,7 @@ void EffectControls::setup_ui() { hlayout->setSpacing(0); hlayout->setMargin(0); - QSplitter* splitter = new QSplitter(); + splitter = new QSplitter(); splitter->setOrientation(Qt::Horizontal); splitter->setChildrenCollapsible(false); @@ -507,6 +506,16 @@ void EffectControls::Retranslate() { UpdateTitle(); } +void EffectControls::LoadLayoutState(const QByteArray &data) +{ + splitter->restoreState(data); +} + +QByteArray EffectControls::SaveLayoutState() +{ + return splitter->saveState(); +} + void EffectControls::update_scrollbar() { verticalScrollBar->setMaximum(qMax(0, effects_area->height() - keyframeView->height() - headers->height())); verticalScrollBar->setPageStep(verticalScrollBar->height()); diff --git a/panels/effectcontrols.h b/panels/effectcontrols.h index fb5c16014..4cc3a9116 100644 --- a/panels/effectcontrols.h +++ b/panels/effectcontrols.h @@ -29,6 +29,7 @@ #include #include #include +#include #include "project/projectelements.h" #include "ui/timelineheader.h" @@ -78,6 +79,9 @@ public: void add_effect_paste_action(QMenu* menu); virtual void Retranslate() override; + + virtual void LoadLayoutState(const QByteArray& data) override; + virtual QByteArray SaveLayoutState() override; public slots: void cut(); void copy(bool del = false); @@ -112,6 +116,7 @@ private: QString panel_name; int mode; + QSplitter* splitter; QPushButton* btnAddVideoEffect; QLabel* lblVideoEffects; QPushButton* btnAddVideoTransition; diff --git a/panels/project.cpp b/panels/project.cpp index ebbe01e0a..1458ba4f0 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -1185,7 +1185,7 @@ void Project::save_project(bool autorecovery) { sequence_id = 1; QFile file(autorecovery ? autorecovery_filename : olive::ActiveProjectFilename); - if (!file.open(QIODevice::WriteOnly/* | QIODevice::Text*/)) { + if (!file.open(QIODevice::WriteOnly)) { qCritical() << "Could not open file"; return; } diff --git a/ui/panel.cpp b/ui/panel.cpp index 2892be2e8..ed54ea43d 100644 --- a/ui/panel.cpp +++ b/ui/panel.cpp @@ -37,6 +37,13 @@ Panel::~Panel() olive::panels.removeAll(this); } +void Panel::LoadLayoutState(const QByteArray &) {} + +QByteArray Panel::SaveLayoutState() +{ + return QByteArray(); +} + void Panel::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { diff --git a/ui/panel.h b/ui/panel.h index db7054b13..c4c9f2cbe 100644 --- a/ui/panel.h +++ b/ui/panel.h @@ -28,7 +28,11 @@ class Panel : public QDockWidget { public: Panel(QWidget* parent = nullptr); virtual ~Panel() override; + virtual void Retranslate() = 0; + + virtual void LoadLayoutState(const QByteArray& data); + virtual QByteArray SaveLayoutState(); protected: virtual void changeEvent(QEvent* e) override; };