aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/Session.md30
-rw-r--r--lib/configuration/configuration.cpp1
-rw-r--r--src/browser.cpp5
-rw-r--r--src/main.cpp10
-rw-r--r--src/mainwindow/mainwindow.cpp25
-rw-r--r--src/mainwindow/subwindow.cpp28
-rw-r--r--src/mainwindow/subwindow.h5
-rw-r--r--src/session.cpp16
-rw-r--r--src/singleapplication.cpp12
-rw-r--r--src/singleapplication.h1
10 files changed, 102 insertions, 31 deletions
diff --git a/doc/Session.md b/doc/Session.md
new file mode 100644
index 0000000..3018253
--- /dev/null
+++ b/doc/Session.md
@@ -0,0 +1,30 @@
+## Session format
+A session is a single window, which contains a list of subwindows.
+
+Each subwindow has a profile (profile id), and a list of tabs.
+
+Each tab has a profile (profile id) and url.
+
+~~~json
+{
+ "subwindows": [
+ {
+ "profile": "<profile id>",
+ "tabs": [
+ {
+ "profile": "<profile id>",
+ "url": "<url>"
+ },
+ {
+ ...
+ }
+ ]
+ }
+ ]
+}
+
+~~~
+
+## --session
+This command-line option causes the browser to load the specified json file.
+
diff --git a/lib/configuration/configuration.cpp b/lib/configuration/configuration.cpp
index 0c49a83..769c003 100644
--- a/lib/configuration/configuration.cpp
+++ b/lib/configuration/configuration.cpp
@@ -50,6 +50,7 @@ Configuration::Configuration(QObject *parent)
("config,c", po::value<std::string>()->default_value(defaultUserConfigLocation()), "Set the configuration file.")
("socket,s", po::value<std::string>()->default_value(defaultSocketPath()), "Local server socket")
+ ("session", po::value<std::string>(), "Load session data from the specified path.")
("args", po::value<std::vector<std::string>>(), "arguments")
;
diff --git a/src/browser.cpp b/src/browser.cpp
index fe103a8..b793bb1 100644
--- a/src/browser.cpp
+++ b/src/browser.cpp
@@ -97,7 +97,6 @@ void Browser::setup(const QString &defaultProfile)
const auto entries = profilesDir.entryInfoList({ "*.profile" }, QDir::Files | QDir::Readable, QDir::Time);
for(const QFileInfo &f : entries) {
- auto name = f.baseName();
auto *profile = ProfileManager::loadProfile(f.absoluteFilePath(), defaults);
emit registerProfile(profile);
}
@@ -161,7 +160,9 @@ void Browser::createSession(const QJsonObject &object)
else {
for(const QJsonValue &t : subwindow.value("tabs").toArray()) {
const QJsonObject tab = t.toObject();
- window->addTab(QUrl::fromUserInput(tab.value("url").toString()));
+ const QUrl url = QUrl::fromUserInput(tab.value("url").toString());
+ WebProfile *p = ProfileManager::profile(tab.value("profile").toString());
+ window->addTab(url, p);
}
}
}
diff --git a/src/main.cpp b/src/main.cpp
index 93f033b..c2cc0a1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -121,7 +121,15 @@ int main(int argc, char **argv)
QObject::connect(&app, &Browser::messageAvailable, &app, &Browser::createSession);
}
- app.sendMessage(Session::toJsonObject(config->value<QString>("profile.default").value(), urls));
+ if(config->exists("session")) {
+ QFile sessionJson(config->value<QString>("session").value());
+ if(sessionJson.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ app.sendMessage(sessionJson.readAll());
+ sessionJson.close();
+ }
+ } else
+ app.sendMessage(Session::toJsonObject(config->value<QString>("profile.default").value(), urls));
+
if(isSingleInstance)
return app.exec();
else
diff --git a/src/mainwindow/mainwindow.cpp b/src/mainwindow/mainwindow.cpp
index 9a9b8e8..7adc9db 100644
--- a/src/mainwindow/mainwindow.cpp
+++ b/src/mainwindow/mainwindow.cpp
@@ -29,10 +29,8 @@
#include <QUrl>
#include <configuration/configuration.h>
#include <webprofile.h>
-
-#ifdef QT_DEBUG
#include "session.h"
-#endif
+#include <QFileDialog>
#ifdef PLASMA_BLUR
#include <KWindowEffects>
@@ -175,6 +173,27 @@ void MainWindow::createMenuBar()
auto *quitAction = smolboteMenu->addAction(tr("Quit"), qApp, &QApplication::quit);
m_config->setShortcut(quitAction, "mainwindow.shortcuts.quit");
+ // session menu
+ auto *sessionMenu = menuBar()->addMenu(tr("Session"));
+
+ sessionMenu->addAction(tr("Save Session"), this, [this]() {
+ const QString filename = QFileDialog::getSaveFileName(this, tr("Save Session"), QDir::homePath(), tr("JSON (*.json)"));
+ QFile output(filename);
+ if(output.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
+ output.write(QJsonDocument(Session::toJsonObject(this)).toJson());
+ output.close();
+ }
+ });
+ sessionMenu->addAction(tr("Load Session"), this, [this]() {
+ const QString filename = QFileDialog::getOpenFileName(this, tr("Load Session"), QDir::homePath(), tr("JSON (*.json)"));
+ QFile json(filename);
+ if(json.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ auto *browser = qobject_cast<Browser *>(qApp);
+ browser->sendMessage(json.readAll());
+ json.close();
+ }
+ });
+
// window menu
auto *windowMenu = menuBar()->addMenu(tr("Window"));
diff --git a/src/mainwindow/subwindow.cpp b/src/mainwindow/subwindow.cpp
index bcddabf..5a1eeda 100644
--- a/src/mainwindow/subwindow.cpp
+++ b/src/mainwindow/subwindow.cpp
@@ -127,6 +127,11 @@ WebView *SubWindow::view(int index) const
return qobject_cast<WebView *>(tabWidget->widget(index));
}
+int SubWindow::tabCount() const
+{
+ return tabWidget->count();
+}
+
void SubWindow::setProfile(WebProfile *profile)
{
Q_CHECK_PTR(profile);
@@ -142,9 +147,9 @@ WebProfile *SubWindow::profile() const
return m_profile;
}
-int SubWindow::addTab(const QUrl &url)
+int SubWindow::addTab(const QUrl &url, WebProfile *profile)
{
- auto *view = new WebView(m_profile, this);
+ auto *view = new WebView((profile == nullptr) ? m_profile : profile, this);
if(!url.isEmpty())
view->load(url);
return tabWidget->addTab(view);
@@ -154,22 +159,3 @@ void SubWindow::setCurrentTab(int index)
{
tabWidget->setCurrentIndex(index);
}
-
-QJsonObject SubWindow::session() const
-{
- QJsonObject obj;
- obj.insert("profile", ProfileManager::id(m_profile));
-
- QJsonArray tabs;
- for(int i = 0; i < tabWidget->count(); ++i) {
- auto *view = qobject_cast<WebView *>(tabWidget->widget(i));
- if(view) {
- QJsonObject tab;
- tab.insert(view->url().toString(), ProfileManager::id(view->profile()));
- tabs.append(tab);
- }
- }
- obj.insert("tabs", tabs);
-
- return obj;
-}
diff --git a/src/mainwindow/subwindow.h b/src/mainwindow/subwindow.h
index e6d7177..1283481 100644
--- a/src/mainwindow/subwindow.h
+++ b/src/mainwindow/subwindow.h
@@ -26,18 +26,17 @@ public:
WebView *currentView();
WebView *view(int index) const;
+ int tabCount() const;
void setProfile(WebProfile *profile);
WebProfile *profile() const;
- QJsonObject session() const;
-
signals:
void currentViewChanged(WebView *view);
void showStatusMessage(const QString &message, int timeout = 0);
public slots:
- int addTab(const QUrl &url = QUrl());
+ int addTab(const QUrl &url = QUrl(), WebProfile *profile = nullptr);
void setCurrentTab(int index);
private:
diff --git a/src/session.cpp b/src/session.cpp
index 6d025dc..0cbb0e8 100644
--- a/src/session.cpp
+++ b/src/session.cpp
@@ -11,6 +11,8 @@
#include "mainwindow/subwindow.h"
#include <QJsonObject>
#include <QJsonArray>
+#include "webengine/webview.h"
+#include "profilemanager.h"
Session::Session(QObject *parent) : QObject(parent)
{
@@ -22,7 +24,19 @@ QJsonObject Session::toJsonObject(MainWindow *window)
QJsonArray subwindows;
for(const SubWindow *subwindow : window->subWindows()) {
- subwindows.append(subwindow->session());
+ QJsonObject window;
+ window.insert("profile", ProfileManager::id(subwindow->profile()));
+
+ QJsonArray tabs;
+ for(int i = 0; i < subwindow->tabCount(); ++i) {
+ QJsonObject tab;
+ tab.insert("url", subwindow->view(i)->url().toString());
+ tab.insert("profile", ProfileManager::id(subwindow->view(i)->profile()));
+ tabs.append(tab);
+ }
+ window.insert("tabs", tabs);
+
+ subwindows.append(window);
}
session.insert("subwindows", subwindows);
diff --git a/src/singleapplication.cpp b/src/singleapplication.cpp
index 60eaa6d..3c442b4 100644
--- a/src/singleapplication.cpp
+++ b/src/singleapplication.cpp
@@ -62,6 +62,18 @@ QString SingleApplication::serverName() const
return m_localServer->fullServerName();
}
+int SingleApplication::sendMessage(const QByteArray &data)
+{
+ QLocalSocket socket;
+ socket.connectToServer(LOCALSERVER_KEY);
+ if(socket.waitForConnected(LOCALSERVER_TIMEOUT)) {
+ socket.write(data);
+ socket.waitForBytesWritten(LOCALSERVER_TIMEOUT);
+ return EXIT_SUCCESS;
+ }
+ return EXIT_FAILURE;
+}
+
int SingleApplication::sendMessage(const QJsonObject &message)
{
QLocalSocket socket;
diff --git a/src/singleapplication.h b/src/singleapplication.h
index 68af953..84c0fda 100644
--- a/src/singleapplication.h
+++ b/src/singleapplication.h
@@ -23,6 +23,7 @@ public:
bool bindLocalSocket(const QString &name);
QString serverName() const;
+ int sendMessage(const QByteArray &data);
int sendMessage(const QJsonObject &message);
signals: