aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2018-11-28 12:39:14 +0100
committerAqua-sama <aqua@iserlohn-fortress.net>2018-11-28 12:39:14 +0100
commit0b9cf8c968a89784b5c2b8afe1a819b33749165e (patch)
tree7153fc8fe5447ee710ce689352db6e0e3b8849cc
parentAdd Session::view and Session::restoreView (diff)
downloadsmolbote-0b9cf8c968a89784b5c2b8afe1a819b33749165e.tar.xz
Rewrite Session saving and loading
-rw-r--r--doc/Development/Configuring.asciidoc34
-rw-r--r--doc/Development/Session.asciidoc19
-rw-r--r--doc/Development/meson.asciidoc30
-rw-r--r--src/browser.cpp2
-rw-r--r--src/browser.h4
-rw-r--r--src/mainwindow/mainwindow.cpp32
-rw-r--r--src/mainwindow/mainwindow.h2
-rw-r--r--src/session/session.cpp95
-rw-r--r--src/session/session.h12
-rw-r--r--src/session/sessiondialog.cpp2
-rw-r--r--src/subwindow/subwindow.cpp2
-rw-r--r--src/subwindow/subwindow.h2
12 files changed, 163 insertions, 73 deletions
diff --git a/doc/Development/Configuring.asciidoc b/doc/Development/Configuring.asciidoc
deleted file mode 100644
index f436da5..0000000
--- a/doc/Development/Configuring.asciidoc
+++ /dev/null
@@ -1,34 +0,0 @@
-=== CMake
-
-==== Compiler flags
--pipe -fstack-protector-strong -fno-plt -fPIE
--march=native -mtune=native
-
-==== Install paths
-CMAKE_INSTALL_PREFIX is prepended onto all install paths. This variable defaults
-to /usr/local on *nix and c:/Program Files/${PROJECT_NAME} on Windows.
-
-On *nix you can use DESTDIR to relocate the entire installation. DESTDIR is
-prepended to CMAKE_INSTALL_PREFIX.
-
-This will install the project to /ports/pkg/install/usr:
-
-[source, sh]
-----
-cmake -DCMAKE_INSTALL_PREFIX=/usr ...
-...
-make DESTDIR=/ports/pkg/install install
-----
-
-==== clang-tidy
-CMAKE_CXX_CLANG_TIDY="clang-tidy;-checks=*"
-
-==== cppcheck
-CMAKE_CXX_CPPCHECK="cppcheck"
-
-==== ccache
--DCMAKE_CXX_COMPILER_LAUNCHER=ccache
-
-==== llvm libcpp
-CMAKE_CXX_FLAGS: -stdlib=libc++"
-CMAKE_EXE_LINKER_FLAGS -stdlib=libc++
diff --git a/doc/Development/Session.asciidoc b/doc/Development/Session.asciidoc
new file mode 100644
index 0000000..846d6a3
--- /dev/null
+++ b/doc/Development/Session.asciidoc
@@ -0,0 +1,19 @@
+== Session
+
+== Session JSON structure
+- windows: list of windows
+
+=== Window
+- subwindows: list of subwindows
+
+=== Subwindow
+- profile: profile ID
+- tabs: list of views
+- current: current tab index
+
+=== View
+- profile: profile ID
+- history: view history
+
+Storing history: compress, toBase64 (to make printable), toQString (to store in json)
+Restoring history: toLatin1 (turn into bytearray), fromBase64, uncompress
diff --git a/doc/Development/meson.asciidoc b/doc/Development/meson.asciidoc
new file mode 100644
index 0000000..1eb08c6
--- /dev/null
+++ b/doc/Development/meson.asciidoc
@@ -0,0 +1,30 @@
+==== Setting compiler
+Compiler can only be set when initially configuring the build, and cannot be
+changed with --reconfigure:
+
+[source, sh]
+----
+export CXX="ccache clang++"
+meson build-path
+----
+
+==== Setting linker
+[source, sh]
+----
+build% meson configure -Dcpp_link_args='-fuse_ld=gold'
+----
+
+==== Listing build options
+[source, sh]
+----
+build% meson configure
+----
+
+==== Changing build options
+[source, sh]
+----
+build% meson configure -D<option-name>=<enabled|disabled>
+# for example:
+build% meson configure -DPlasma=enabled
+----
+
diff --git a/src/browser.cpp b/src/browser.cpp
index 7130096..0a0bd91 100644
--- a/src/browser.cpp
+++ b/src/browser.cpp
@@ -221,7 +221,7 @@ void Browser::createSession(const QJsonObject &object)
}
}
if(window == nullptr)
- window = mainwindow->createSubWindow(m_config, profile);
+ window = mainwindow->createSubWindow(m_config.get(), profile);
const QJsonArray tabs = subwindow.value("tabs").toArray();
if(tabs.isEmpty())
diff --git a/src/browser.h b/src/browser.h
index 1989631..5a6404b 100644
--- a/src/browser.h
+++ b/src/browser.h
@@ -53,6 +53,10 @@ public:
void setup(QVector<QPluginLoader *> plugins);
+ const QVector<MainWindow *> windows() const
+ {
+ return qAsConst(m_windows);
+ }
QJsonObject session() const
{
return Session::session(m_windows);
diff --git a/src/mainwindow/mainwindow.cpp b/src/mainwindow/mainwindow.cpp
index a01cb94..9e6f187 100644
--- a/src/mainwindow/mainwindow.cpp
+++ b/src/mainwindow/mainwindow.cpp
@@ -95,7 +95,7 @@ MainWindow::MainWindow(const std::unique_ptr<Configuration> &config, QWidget *pa
{
connect(ui->actionNewSubwindow, &QAction::triggered, this, [this, &config]() {
auto *profile = WebProfile::defaultProfile();
- auto *window = createSubWindow(config, profile);
+ auto *window = createSubWindow(config.get(), profile);
window->addTab(profile->newtab(), profile);
});
config->setShortcut(ui->actionNewSubwindow, "mainwindow.shortcuts.newGroup");
@@ -118,34 +118,18 @@ MainWindow::MainWindow(const std::unique_ptr<Configuration> &config, QWidget *pa
// connect session menu
{
- connect(ui->actionSaveSession, &QAction::triggered, this, [this]() {
-#ifndef QT_DEBUG
- const QString filename = QFileDialog::getSaveFileName(this, tr("Save Session"), QDir::homePath(), tr("JSON (*.json)"));
+ const QString sessionPath = config->value<QString>("browser.session.path").value();
+ connect(ui->actionSaveSession, &QAction::triggered, this, [this, sessionPath]() {
+ const QString filename = QFileDialog::getSaveFileName(this, tr("Save Session"), sessionPath, tr("JSON (*.json)"));
QFile output(filename);
if(output.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
- output.write(QJsonDocument(Session::window(this)).toJson());
+ auto *browser = qobject_cast<Browser *>(qApp);
+ auto data = Session::_session(browser->windows());
+ output.write(QJsonDocument(data).toJson());
output.close();
}
-#else
- auto data = Session::view(currentView);
- QJsonDocument doc(data);
- qDebug(qUtf8Printable(doc.toJson()));
-#endif
});
-#ifdef QT_DEBUG
- auto *openViewAction = ui->menuSession->addAction("Open View");
- connect(openViewAction, &QAction::triggered, this, [this]() {
- const QString filename = QFileDialog::getOpenFileName(this, tr("Open View"), QDir::homePath(), tr("JSON (*json)"));
- QFile output(filename);
- if(output.open(QIODevice::ReadOnly | QIODevice::Text)) {
- QJsonDocument doc = QJsonDocument::fromJson(output.readAll());
- Session::restoreView(currentView, doc.object());
- output.close();
- }
- });
-#endif
-
connect(ui->actionLoadSession, &QAction::triggered, this, [this]() {
auto *sessionDialog = new SessionDialog(this);
sessionDialog->exec();
@@ -356,7 +340,7 @@ SubWindow *MainWindow::currentSubWindow() const
return qobject_cast<SubWindow *>(mdiArea->currentSubWindow());
}
-SubWindow *MainWindow::createSubWindow(const std::unique_ptr<Configuration> &config, WebProfile *profile)
+SubWindow *MainWindow::createSubWindow(const Configuration *config, WebProfile *profile)
{
bool shouldMaximize = true;
// if there is a current window, use its maximize state
diff --git a/src/mainwindow/mainwindow.h b/src/mainwindow/mainwindow.h
index 296a73e..de77540 100644
--- a/src/mainwindow/mainwindow.h
+++ b/src/mainwindow/mainwindow.h
@@ -54,7 +54,7 @@ signals:
public slots:
void createTab(const QUrl &url);
- SubWindow *createSubWindow(const std::unique_ptr<Configuration> &config, WebProfile *profile);
+ SubWindow *createSubWindow(const Configuration *config, WebProfile *profile);
private slots:
void setView(WebView *view);
diff --git a/src/session/session.cpp b/src/session/session.cpp
index d728d55..0853c70 100644
--- a/src/session/session.cpp
+++ b/src/session/session.cpp
@@ -7,15 +7,17 @@
*/
#include "session.h"
+#include "../webengine/webview.h"
+#include "browser.h"
#include "mainwindow/mainwindow.h"
+#include "profilemanager.h"
#include "subwindow/subwindow.h"
-#include <QJsonObject>
-#include <QJsonArray>
#include "webengine/webview.h"
-#include "profilemanager.h"
-#include "browser.h"
-#include "../webengine/webview.h"
+#include <QJsonArray>
+#include <QJsonObject>
#include <QWebEngineHistory>
+#include <memory>
+#include "configuration.h"
QJsonObject Session::session(QVector<MainWindow *> windows)
{
@@ -81,6 +83,58 @@ QJsonObject Session::window(const QString &profile, const QStringList &urls)
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)
+{
+ auto *profileManager = dynamic_cast<Browser *>(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<Browser *>(qApp)->getProfileManager();
@@ -91,10 +145,10 @@ QJsonObject Session::view(const WebView *view)
historyStream << *view->history();
QJsonObject viewData;
- viewData.insert("url", view->url().toString());
viewData.insert("profile", profileManager->id(view->profile()));
- //viewData.insert("history", QString(qCompress(historyData).toBase64()));
- viewData.insert("history", QString(historyData.toBase64()));
+
+ // store history: compress, toBase64 (to make printable), toQString (to store in json)
+ viewData.insert("history", QString(qCompress(historyData).toBase64()));
return viewData;
}
@@ -108,7 +162,30 @@ void Session::restoreView(WebView *view, const QJsonObject &data)
if(profile)
view->setProfile(profile);
- QByteArray historyData = QByteArray::fromBase64(data["history"].toString().toLatin1());
+ // 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);
+ auto *profileManager = browser->getProfileManager();
+ Q_CHECK_PTR(profileManager);
+
+ for(const auto windowData : sessionData["windows"].toArray()) {
+ auto *window = browser->createWindow();
+
+ for(const auto subwindowData : windowData.toObject()["subwindows"].toArray()) {
+ auto *subwindow = window->createSubWindow(browser->getConfiguration(), WebProfile::defaultProfile());
+ subwindow->setProfile(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
index 222c7ef..720b711 100644
--- a/src/session/session.h
+++ b/src/session/session.h
@@ -12,6 +12,7 @@
#include <QJsonDocument>
class MainWindow;
+class SubWindow;
class WebView;
namespace Session {
@@ -19,8 +20,17 @@ QJsonObject session(QVector<MainWindow *> windows);
QJsonObject window(const MainWindow *window);
QJsonObject window(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 e31a42f..5fd65c3 100644
--- a/src/session/sessiondialog.cpp
+++ b/src/session/sessiondialog.cpp
@@ -81,7 +81,7 @@ void SessionDialog::openSession(const QString &filename)
if(json.open(QIODevice::ReadOnly | QIODevice::Text)) {
auto *browser = qobject_cast<Browser *>(qApp);
auto doc = QJsonDocument::fromJson(json.readAll());
- browser->createSession(doc.object());
+ Session::restoreSession(doc.object());
json.close();
}
}
diff --git a/src/subwindow/subwindow.cpp b/src/subwindow/subwindow.cpp
index f718368..1006200 100644
--- a/src/subwindow/subwindow.cpp
+++ b/src/subwindow/subwindow.cpp
@@ -23,7 +23,7 @@
#include "profilemanager.h"
#include "webprofile.h"
-SubWindow::SubWindow(const std::unique_ptr<Configuration> &config, QWidget *parent, Qt::WindowFlags flags)
+SubWindow::SubWindow(const Configuration *config, QWidget *parent, Qt::WindowFlags flags)
: QMdiSubWindow(parent, flags)
, tabWidget(new TabWidget(this))
{
diff --git a/src/subwindow/subwindow.h b/src/subwindow/subwindow.h
index 5dd17f2..3d70c98 100644
--- a/src/subwindow/subwindow.h
+++ b/src/subwindow/subwindow.h
@@ -22,7 +22,7 @@ class SubWindow : public QMdiSubWindow
Q_OBJECT
public:
- explicit SubWindow(const std::unique_ptr<Configuration> &config, QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
+ explicit SubWindow(const Configuration *config, QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
~SubWindow() override;
WebView *currentView();