diff options
-rw-r--r-- | doc/Session.md | 30 | ||||
-rw-r--r-- | lib/configuration/configuration.cpp | 1 | ||||
-rw-r--r-- | src/browser.cpp | 5 | ||||
-rw-r--r-- | src/main.cpp | 10 | ||||
-rw-r--r-- | src/mainwindow/mainwindow.cpp | 25 | ||||
-rw-r--r-- | src/mainwindow/subwindow.cpp | 28 | ||||
-rw-r--r-- | src/mainwindow/subwindow.h | 5 | ||||
-rw-r--r-- | src/session.cpp | 16 | ||||
-rw-r--r-- | src/singleapplication.cpp | 12 | ||||
-rw-r--r-- | src/singleapplication.h | 1 |
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: |