/* * 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 "mainwindow/mainwindow.h" #include "webengine/webprofilemanager.h" #include "subwindow/subwindow.h" #include "webengine/webview.h" #include #include #include #include #include "configuration.h" 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 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) { auto *profileManager = dynamic_cast(qApp)->getProfileManager(); 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) { auto *profileManager = dynamic_cast(qApp)->getProfileManager(); 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) { auto *profileManager = dynamic_cast(qApp)->getProfileManager(); 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(qApp); Q_CHECK_PTR(browser); auto *profileManager = browser->getProfileManager(); 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()); } } } }