diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2020-04-13 15:44:09 +0300 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2020-04-13 15:44:09 +0300 |
commit | 396bc0c1721af8d3ee970228e7df457f6b2c73d5 (patch) | |
tree | 5aee4f0faec3fdfe616e1684dcb1736be9126bc1 /src/session | |
parent | Add singleapplication.wrap (diff) | |
download | smolbote-396bc0c1721af8d3ee970228e7df457f6b2c73d5.tar.xz |
Rewrite Session backend
Add session.hpp, containing structs that describe session data
MainWindow, SubWindow and WebView can be created from
Session::structs
Opening new window will automatically open a default subwindow and tab
if none were specified
Add lib/session_formats
Add JsonSession, to serialize/deserialize Session structs into JSON
- add some tests
clang-tidy:
- fix various warnings
- disable modernize-use-trailing-return-type check
Diffstat (limited to 'src/session')
-rw-r--r-- | src/session/savesessiondialog.cpp | 12 | ||||
-rw-r--r-- | src/session/savesessiondialog.h | 8 | ||||
-rw-r--r-- | src/session/session.cpp | 177 | ||||
-rw-r--r-- | src/session/session.h | 34 | ||||
-rw-r--r-- | src/session/sessiondialog.cpp | 89 | ||||
-rw-r--r-- | src/session/sessiondialog.h | 13 | ||||
-rw-r--r-- | src/session/sessiondialog.ui | 12 | ||||
-rw-r--r-- | src/session/sessionform.cpp | 36 | ||||
-rw-r--r-- | src/session/sessionform.h | 37 | ||||
-rw-r--r-- | src/session/sessionform.ui | 41 |
10 files changed, 68 insertions, 391 deletions
diff --git a/src/session/savesessiondialog.cpp b/src/session/savesessiondialog.cpp index 507cddb..ff5e696 100644 --- a/src/session/savesessiondialog.cpp +++ b/src/session/savesessiondialog.cpp @@ -1,7 +1,7 @@ /* * This file is part of smolbote. It's copyrighted by the contributors recorded * in the version control history of the file, available from its original - * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * location: https://library.iserlohn-fortress.net/aqua/smolbote.git * * SPDX-License-Identifier: GPL-3.0 */ @@ -9,6 +9,7 @@ #include "savesessiondialog.h" #include "browser.h" #include "mainwindow/mainwindow.h" +#include "session_json.hpp" #include "subwindow/subwindow.h" #include "ui_savesessiondialog.h" #include "webengine/webprofilemanager.h" @@ -61,18 +62,17 @@ void SaveSessionDialog::save(const QString &sessionPath) QFile output(filename); if(output.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { - QVector<MainWindow *> windows; + QVector<Session::MainWindow> windows; for(int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem *item = ui->treeWidget->topLevelItem(i); if(item->checkState(0) == Qt::Checked) { auto *window = static_cast<MainWindow *>(item->data(0, Qt::UserRole).value<void *>()); - Q_CHECK_PTR(window); - windows.append(window); + windows.append(window->serialize()); } } - auto data = Session::_session(windows); - output.write(QJsonDocument(data).toJson()); + JsonSession session(windows); + output.write(session.serialize()); output.close(); } } diff --git a/src/session/savesessiondialog.h b/src/session/savesessiondialog.h index ade1d23..8a162d1 100644 --- a/src/session/savesessiondialog.h +++ b/src/session/savesessiondialog.h @@ -1,7 +1,7 @@ /* * This file is part of smolbote. It's copyrighted by the contributors recorded * in the version control history of the file, available from its original - * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * location: https://library.iserlohn-fortress.net/aqua/smolbote.git * * SPDX-License-Identifier: GPL-3.0 */ @@ -22,7 +22,11 @@ class SaveSessionDialog : public QDialog public: explicit SaveSessionDialog(QWidget *parent = nullptr); - ~SaveSessionDialog(); + explicit SaveSessionDialog(const SaveSessionDialog &) = delete; + explicit SaveSessionDialog(SaveSessionDialog &&) = delete; + SaveSessionDialog &operator=(const SaveSessionDialog &) = delete; + SaveSessionDialog &operator=(SaveSessionDialog &&) = delete; + ~SaveSessionDialog() override; public slots: void save(const QString &sessionPath); diff --git a/src/session/session.cpp b/src/session/session.cpp deleted file mode 100644 index c97c22b..0000000 --- a/src/session/session.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * This file is part of smolbote. It's copyrighted by the contributors recorded - * in the version control history of the file, available from its original - * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#include "session.h" -#include "../webengine/webview.h" -#include "browser.h" -#include "configuration.h" -#include "mainwindow/mainwindow.h" -#include "subwindow/subwindow.h" -#include "webengine/webprofilemanager.h" -#include "webengine/webview.h" -#include <QJsonArray> -#include <QJsonObject> -#include <QWebEngineHistory> -#include <memory> - -QJsonObject Session::fromCommandLine(const QString &profile, const QStringList &urls) -{ - QJsonObject session; - - QJsonArray subwindows; - { - QJsonObject window; - window.insert("profile", profile); - - QJsonArray tabs; - for(const auto &url : urls) { - QJsonObject tab; - tab.insert("url", url); - tab.insert("profile", profile); - tabs.append(tab); - } - window.insert("tabs", tabs); - - subwindows.append(window); - } - session.insert("subwindows", subwindows); - - return session; -} - -////// - -QJsonObject Session::_session(const QVector<MainWindow *> windows) -{ - QJsonObject sessionData; - - { - QJsonArray windowList; - for(const auto *window : windows) { - windowList.append(Session::_window(window)); - } - sessionData.insert("windows", windowList); - } - - return sessionData; -} - -QJsonObject Session::_window(const MainWindow *window) -{ - QJsonObject windowData; - - { - QJsonArray subwindows; - for(const auto *subwindow : window->subWindows()) { - subwindows.append(Session::_subwindow(subwindow)); - } - windowData.insert("subwindows", subwindows); - } - - return windowData; -} - -QJsonObject Session::_subwindow(const SubWindow *subwindow) -{ - const auto *profileManager = WebProfileManager::instance(); - Q_CHECK_PTR(profileManager); - - QJsonObject subwindowData; - - subwindowData.insert("profile", profileManager->id(subwindow->profile())); - - { - QJsonArray tabs; - for(int i = 0; i < subwindow->tabCount(); ++i) { - tabs.append(Session::view(subwindow->view(i))); - } - subwindowData.insert("tabs", tabs); - } - - return subwindowData; -} - -QJsonObject Session::view(const WebView *view) -{ - const auto *profileManager = WebProfileManager::instance(); - Q_CHECK_PTR(profileManager); - - QByteArray historyData; - QDataStream historyStream(&historyData, QIODevice::WriteOnly); - historyStream << *view->history(); - - QJsonObject viewData; - viewData.insert("profile", profileManager->id(view->profile())); - - // store history: compress, toBase64 (to make printable), toQString (to store in json) - viewData.insert("history", QString(qCompress(historyData).toBase64())); - - return viewData; -} - -void Session::restoreView(WebView *view, const QJsonObject &data) -{ - const auto *profileManager = WebProfileManager::instance(); - Q_CHECK_PTR(profileManager); - - auto *profile = profileManager->profile(data["profile"].toString()); - if(profile != nullptr) - view->setProfile(profile); - - auto url = data.value("url"); - if(url.isString()) - view->load(QUrl::fromUserInput(url.toString())); - else { - // restore history: toLatin1 (turn into bytearray), fromBase64, uncompress - QByteArray historyData = qUncompress(QByteArray::fromBase64(data["history"].toString().toLatin1())); - QDataStream historyStream(&historyData, QIODevice::ReadOnly); - historyStream >> *view->history(); - } -} - -void Session::restoreSession(const QJsonObject &sessionData) -{ - auto *browser = dynamic_cast<Browser *>(qApp); - Q_CHECK_PTR(browser); - const auto *profileManager = WebProfileManager::instance(); - Q_CHECK_PTR(profileManager); - - for(const auto subwindowData : sessionData["subwindows"].toArray()) { - MainWindow *window = nullptr; - SubWindow *subwindow = nullptr; - - if(!browser->windows().isEmpty()) { - window = browser->windows().last(); - subwindow = window->currentSubWindow(); - } else { - window = browser->createWindow(); - subwindow = window->createSubWindow(profileManager->profile(subwindowData.toObject()["profile"].toString())); - } - - Q_CHECK_PTR(window); - Q_CHECK_PTR(subwindow); - - for(const auto tabData : subwindowData.toObject()["tabs"].toArray()) { - auto *view = subwindow->view(subwindow->addTab()); - Session::restoreView(view, tabData.toObject()); - } - } - - for(const auto windowData : sessionData["windows"].toArray()) { - auto *window = browser->createWindow(); - - for(const auto subwindowData : windowData.toObject()["subwindows"].toArray()) { - auto *subwindow = window->createSubWindow(profileManager->profile(subwindowData.toObject()["profile"].toString())); - - for(const auto tabData : subwindowData.toObject()["tabs"].toArray()) { - auto *view = subwindow->view(subwindow->addTab()); - Session::restoreView(view, tabData.toObject()); - } - } - } -} diff --git a/src/session/session.h b/src/session/session.h deleted file mode 100644 index 8a96bb2..0000000 --- a/src/session/session.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of smolbote. It's copyrighted by the contributors recorded - * in the version control history of the file, available from its original - * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#ifndef SMOLBOTE_SESSION_H -#define SMOLBOTE_SESSION_H - -#include <QJsonDocument> - -class MainWindow; -class SubWindow; -class WebView; - -namespace Session { -QJsonObject fromCommandLine(const QString &profile, const QStringList &urls); - -// TODO: -QJsonObject _session(const QVector<MainWindow *> windows); -QJsonObject _window(const MainWindow *window); -QJsonObject _subwindow(const SubWindow *subwindow); - - -QJsonObject view(const WebView *view); -void restoreView(WebView *view, const QJsonObject &data); - -void restoreSession(const QJsonObject &sessionData); - -} // namespace Session - -#endif // SMOLBOTE_SESSION_H diff --git a/src/session/sessiondialog.cpp b/src/session/sessiondialog.cpp index 301b4b6..36cf9cb 100644 --- a/src/session/sessiondialog.cpp +++ b/src/session/sessiondialog.cpp @@ -1,7 +1,7 @@ /* * This file is part of smolbote. It's copyrighted by the contributors recorded * in the version control history of the file, available from its original - * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * location: https://library.iserlohn-fortress.net/aqua/smolbote.git * * SPDX-License-Identifier: GPL-3.0 */ @@ -9,56 +9,59 @@ #include "sessiondialog.h" #include "../browser.h" #include "../util.h" -#include "sessionform.h" +#include "configuration.h" +#include "session_json.hpp" #include "ui_sessiondialog.h" -#include "ui_sessionform.h" #include <QFile> #include <QFileDialog> -#include <QToolButton> #include <QStyle> -#include "configuration.h" +#include <QToolButton> SessionDialog::SessionDialog(QWidget *parent) : QDialog(parent) + , create_window_str(QObject::tr("Create a new window")) , ui(new Ui::SessionDialog) { ui->setupUi(this); - ui->open->setIcon(style()->standardIcon(QStyle::SP_DirOpenIcon)); auto *browser = qobject_cast<Browser *>(qApp); Q_CHECK_PTR(browser); Configuration conf; for(const QString &path : Util::files(conf.value<QString>("session.path").value(), { "*.json" })) { - addItem(path); + ui->listWidget->addItem(path); } - ui->listWidget->addItem(tr("Create a new window")); + ui->listWidget->addItem(create_window_str); - connect(ui->listWidget, &QListWidget::currentItemChanged, this, [this](QListWidgetItem *currentItem, QListWidgetItem *previousItem) { - auto *currentWidget = qobject_cast<SessionForm *>(ui->listWidget->itemWidget(currentItem)); - if(currentWidget != nullptr) - currentWidget->ui->delete_toolButton->show(); - - auto *previousWidget = qobject_cast<SessionForm *>(ui->listWidget->itemWidget(previousItem)); - if(previousWidget != nullptr) - previousWidget->ui->delete_toolButton->hide(); + connect(ui->listWidget, &QListWidget::currentItemChanged, this, [this](QListWidgetItem *currentItem, QListWidgetItem * /*previousItem*/) { + ui->delete_toolButton->setEnabled(currentItem->text() != create_window_str); }); - connect(ui->open, &QPushButton::clicked, this, [this]() { + connect(ui->open_toolButton, &QToolButton::clicked, this, [this]() { const QString filename = QFileDialog::getOpenFileName(this, tr("Select Session file"), QDir::homePath(), tr("JSON (*.json)")); if(!filename.isEmpty()) { - ui->listWidget->setCurrentItem(addItem(filename)); + ui->listWidget->addItem(filename); + ui->listWidget->setCurrentRow(ui->listWidget->count() - 1); accept(); } }); + connect(ui->delete_toolButton, &QToolButton::clicked, this, [this]() { + const auto path = ui->listWidget->currentItem()->text(); + if(path != create_window_str) { + QFile(path).remove(); + delete ui->listWidget->currentItem(); + } + }); + accepted_connection = connect(this, &SessionDialog::accepted, this, [this, browser]() { - auto *currentWidget = qobject_cast<SessionForm *>(ui->listWidget->itemWidget(ui->listWidget->currentItem())); - if(currentWidget != nullptr) - this->openSession(currentWidget->ui->label->text()); - else - browser->createWindow(); + const auto path = ui->listWidget->currentItem()->text(); + if(path != create_window_str) { + openSession(path); + } else { + browser->open({}); + } }); connect(ui->search, &QLineEdit::textEdited, this, &SessionDialog::search); @@ -69,7 +72,7 @@ SessionDialog::~SessionDialog() delete ui; } -std::optional<QJsonObject> SessionDialog::pickSession() +std::optional<QVector<Session::MainWindow>> SessionDialog::pickSession() { disconnect(accepted_connection); @@ -77,52 +80,32 @@ std::optional<QJsonObject> SessionDialog::pickSession() return std::nullopt; } - auto *currentWidget = qobject_cast<SessionForm *>(ui->listWidget->itemWidget(ui->listWidget->currentItem())); - if(currentWidget != nullptr) { - QFile json(currentWidget->ui->label->text()); + const auto path = ui->listWidget->currentItem()->text(); + if(path != create_window_str) { + QFile json(path); if(json.open(QIODevice::ReadOnly | QIODevice::Text)) { - auto doc = QJsonDocument::fromJson(json.readAll()); - return doc.object(); + JsonSession session(json.readAll()); + return session.get(); } } return std::nullopt; } -QListWidgetItem *SessionDialog::addItem(const QString &path) -{ - auto *item = new QListWidgetItem(ui->listWidget); - auto *widget = new SessionForm(path, this); - connect(widget->ui->delete_toolButton, &QToolButton::clicked, this, [item, widget]() { - delete item; - delete widget; - }); - ui->listWidget->setItemWidget(item, widget); - return item; -} - void SessionDialog::search(const QString &text) { for(int i = 0; i < ui->listWidget->count(); ++i) { auto *item = ui->listWidget->item(i); - auto *widget = qobject_cast<SessionForm *>(ui->listWidget->itemWidget(item)); - - if(widget == nullptr) - item->setHidden(!text.isEmpty()); - else - item->setHidden(!widget->ui->label->text().contains(text)); + item->setHidden(!item->text().contains(text)); } } void SessionDialog::openSession(const QString &filename) { auto *browser = qobject_cast<Browser *>(qApp); - Q_CHECK_PTR(browser); - QFile json(filename); - if(json.open(QIODevice::ReadOnly | QIODevice::Text)) { - auto doc = QJsonDocument::fromJson(json.readAll()); - Session::restoreSession(doc.object()); - json.close(); + if(json.open(QIODevice::ReadOnly | QIODevice::Text) && browser != nullptr) { + JsonSession session(json.readAll()); + browser->open(session.get()); } } diff --git a/src/session/sessiondialog.h b/src/session/sessiondialog.h index 9bf8a68..0a04940 100644 --- a/src/session/sessiondialog.h +++ b/src/session/sessiondialog.h @@ -1,7 +1,7 @@ /* * This file is part of smolbote. It's copyrighted by the contributors recorded * in the version control history of the file, available from its original - * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * location: https://library.iserlohn-fortress.net/aqua/smolbote.git * * SPDX-License-Identifier: GPL-3.0 */ @@ -9,6 +9,7 @@ #ifndef SMOLBOTE_SESSIONDIALOG_H #define SMOLBOTE_SESSIONDIALOG_H +#include "session.hpp" #include <QDialog> namespace Ui @@ -22,16 +23,20 @@ class SessionDialog : public QDialog public: explicit SessionDialog(QWidget *parent = nullptr); + explicit SessionDialog(const SessionDialog &) = delete; + explicit SessionDialog(SessionDialog &&) = delete; + SessionDialog &operator=(const SessionDialog &) = delete; + SessionDialog &operator=(SessionDialog &&) = delete; ~SessionDialog() override; - std::optional<QJsonObject> pickSession(); + std::optional<QVector<Session::MainWindow>> pickSession(); private slots: - QListWidgetItem *addItem(const QString &path); void search(const QString &text); - void openSession(const QString &filename); + static void openSession(const QString &filename); private: + const QString create_window_str; Ui::SessionDialog *ui; QMetaObject::Connection accepted_connection; }; diff --git a/src/session/sessiondialog.ui b/src/session/sessiondialog.ui index dab49d9..4049b75 100644 --- a/src/session/sessiondialog.ui +++ b/src/session/sessiondialog.ui @@ -41,13 +41,23 @@ <item> <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> - <widget class="QPushButton" name="open"> + <widget class="QToolButton" name="open_toolButton"> <property name="text"> <string>Open from File</string> </property> </widget> </item> <item> + <widget class="QToolButton" name="delete_toolButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Delete</string> + </property> + </widget> + </item> + <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="orientation"> <enum>Qt::Horizontal</enum> diff --git a/src/session/sessionform.cpp b/src/session/sessionform.cpp deleted file mode 100644 index 761cb42..0000000 --- a/src/session/sessionform.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of smolbote. It's copyrighted by the contributors recorded - * in the version control history of the file, available from its original - * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#include "sessionform.h" -#include "ui_sessionform.h" -#include <QStyle> - -SessionForm::SessionForm(const QString &path, QWidget *parent) - : QWidget(parent) - , ui(new Ui::SessionForm) -{ - ui->setupUi(this); - ui->label->setText(path); - ui->delete_toolButton->setIcon(style()->standardIcon(QStyle::SP_TrashIcon)); - ui->delete_toolButton->hide(); -} - -SessionForm::~SessionForm() -{ - delete ui; -} - -void SessionForm::showDetails() -{ - ui->delete_toolButton->show(); -} - -void SessionForm::hideDetails() -{ - ui->delete_toolButton->hide(); -} diff --git a/src/session/sessionform.h b/src/session/sessionform.h deleted file mode 100644 index 5e5f52e..0000000 --- a/src/session/sessionform.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of smolbote. It's copyrighted by the contributors recorded - * in the version control history of the file, available from its original - * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#ifndef SMOLBOTE_SESSIONFORM_H -#define SMOLBOTE_SESSIONFORM_H - -#include <QWidget> - -namespace Ui -{ -class SessionForm; -} - -class SessionForm : public QWidget -{ - Q_OBJECT - - friend class SessionDialog; - -public: - explicit SessionForm(const QString &path, QWidget *parent = nullptr); - ~SessionForm() override; - -public slots: - void showDetails(); - void hideDetails(); - -private: - Ui::SessionForm *ui; -}; - -#endif // SMOLBOTE_SESSIONFORM_H diff --git a/src/session/sessionform.ui b/src/session/sessionform.ui deleted file mode 100644 index dbf0237..0000000 --- a/src/session/sessionform.ui +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>SessionForm</class> - <widget class="QWidget" name="SessionForm"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>711</width> - <height>34</height> - </rect> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <layout class="QHBoxLayout" name="horizontalLayout"> - <property name="topMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>TextLabel</string> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="delete_toolButton"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> |