mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-24 12:46:35 +01:00
Session manager (#2293)
This commit is contained in:
parent
2654081912
commit
755ec16598
@ -164,6 +164,7 @@ void BrowserWindow::postLaunch()
|
||||
|
||||
case MainApplication::OpenHomePage:
|
||||
case MainApplication::RestoreSession:
|
||||
case MainApplication::SelectSession:
|
||||
startUrl = m_homepage;
|
||||
break;
|
||||
|
||||
@ -178,7 +179,7 @@ void BrowserWindow::postLaunch()
|
||||
startUrl.clear();
|
||||
m_tabWidget->addView(QUrl("qupzilla:restore"), Qz::NT_CleanSelectedTabAtTheEnd);
|
||||
}
|
||||
else if (mApp->afterLaunch() == MainApplication::RestoreSession && mApp->restoreManager()) {
|
||||
else if ((mApp->afterLaunch() == MainApplication::SelectSession || mApp->afterLaunch() == MainApplication::RestoreSession) && mApp->restoreManager()) {
|
||||
addTab = !mApp->restoreSession(this, mApp->restoreManager()->restoreData());
|
||||
}
|
||||
break;
|
||||
@ -1316,7 +1317,7 @@ void BrowserWindow::closeEvent(QCloseEvent* event)
|
||||
Settings settings;
|
||||
bool askOnClose = settings.value("Browser-Tabs-Settings/AskOnClosing", true).toBool();
|
||||
|
||||
if (mApp->afterLaunch() == MainApplication::RestoreSession && mApp->windowCount() == 1) {
|
||||
if ((mApp->afterLaunch() == MainApplication::SelectSession || mApp->afterLaunch() == MainApplication::RestoreSession) && mApp->windowCount() == 1) {
|
||||
askOnClose = false;
|
||||
}
|
||||
|
||||
|
@ -148,5 +148,10 @@ void DataPaths::initCurrentProfile(const QString &profilePath)
|
||||
if (m_paths[Cache].isEmpty())
|
||||
m_paths[Cache].append(m_paths[CurrentProfile].at(0) + QLatin1String("/cache"));
|
||||
|
||||
QDir().mkpath(m_paths[Cache].at(0));
|
||||
if (m_paths[Sessions].isEmpty())
|
||||
m_paths[Sessions].append(m_paths[CurrentProfile].at(0) + QLatin1String("/sessions"));
|
||||
|
||||
QDir dir;
|
||||
dir.mkpath(m_paths[Cache].at(0));
|
||||
dir.mkpath(m_paths[Sessions].at(0));
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ public:
|
||||
CurrentProfile = 6, // $Profiles/current_profile
|
||||
Temp = 7, // $Config/tmp
|
||||
Cache = 8, // $XDG_CACHE_HOME/qupzilla or $CurrentProfile/cache
|
||||
LastPath = 9
|
||||
Sessions = 9, // $CurrentProfile/sessions
|
||||
LastPath = 10
|
||||
};
|
||||
|
||||
explicit DataPaths();
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "desktopnotificationsfactory.h"
|
||||
#include "html5permissions/html5permissionsmanager.h"
|
||||
#include "scripts.h"
|
||||
#include "sessionmanager.h"
|
||||
|
||||
#include <QWebEngineSettings>
|
||||
#include <QDesktopServices>
|
||||
@ -91,6 +92,7 @@ MainApplication::MainApplication(int &argc, char** argv)
|
||||
, m_browsingLibrary(0)
|
||||
, m_networkManager(0)
|
||||
, m_restoreManager(0)
|
||||
, m_sessionManager(0)
|
||||
, m_downloadManager(0)
|
||||
, m_userAgentManager(0)
|
||||
, m_searchEnginesManager(0)
|
||||
@ -275,8 +277,19 @@ MainApplication::MainApplication(int &argc, char** argv)
|
||||
script.setSourceCode(Scripts::setupWebChannel());
|
||||
m_webProfile->scripts()->insert(script);
|
||||
|
||||
m_autoSaver = new AutoSaver(this);
|
||||
connect(m_autoSaver, SIGNAL(save()), this, SLOT(saveSession()));
|
||||
if (!isPrivate()) {
|
||||
m_sessionManager = new SessionManager(this);
|
||||
m_autoSaver = new AutoSaver(this);
|
||||
connect(m_autoSaver, SIGNAL(save()), m_sessionManager, SLOT(autoSaveLastSession()));
|
||||
|
||||
Settings settings;
|
||||
m_isStartingAfterCrash = settings.value("SessionRestore/isRunning", false).toBool();
|
||||
settings.setValue("SessionRestore/isRunning", true);
|
||||
|
||||
// we have to ask about startup session before creating main window
|
||||
if (!m_isStartingAfterCrash && afterLaunch() == SelectSession)
|
||||
m_restoreManager = new RestoreManager(sessionManager()->askSessionFromUser());
|
||||
}
|
||||
|
||||
translateApp();
|
||||
loadSettings();
|
||||
@ -294,11 +307,8 @@ MainApplication::MainApplication(int &argc, char** argv)
|
||||
|
||||
|
||||
if (!isPrivate()) {
|
||||
Settings settings;
|
||||
m_isStartingAfterCrash = settings.value("SessionRestore/isRunning", false).toBool();
|
||||
settings.setValue("SessionRestore/isRunning", true);
|
||||
|
||||
#ifndef DISABLE_CHECK_UPDATES
|
||||
Settings settings;
|
||||
bool checkUpdates = settings.value("Web-Browser-Settings/CheckUpdates", true).toBool();
|
||||
|
||||
if (checkUpdates) {
|
||||
@ -306,10 +316,10 @@ MainApplication::MainApplication(int &argc, char** argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
backupSavedSessions();
|
||||
sessionManager()->backupSavedSessions();
|
||||
|
||||
if (m_isStartingAfterCrash || afterLaunch() == RestoreSession) {
|
||||
m_restoreManager = new RestoreManager();
|
||||
m_restoreManager = new RestoreManager(sessionManager()->lastActiveSessionPath());
|
||||
if (!m_restoreManager->isValid()) {
|
||||
destroyRestoreManager();
|
||||
} else {
|
||||
@ -562,6 +572,11 @@ RestoreManager* MainApplication::restoreManager()
|
||||
return m_restoreManager;
|
||||
}
|
||||
|
||||
SessionManager* MainApplication::sessionManager()
|
||||
{
|
||||
return m_sessionManager;
|
||||
}
|
||||
|
||||
DownloadManager* MainApplication::downloadManager()
|
||||
{
|
||||
if (!m_downloadManager) {
|
||||
@ -655,7 +670,8 @@ void MainApplication::restoreOverrideCursor()
|
||||
|
||||
void MainApplication::changeOccurred()
|
||||
{
|
||||
m_autoSaver->changeOccurred();
|
||||
if (m_autoSaver)
|
||||
m_autoSaver->changeOccurred();
|
||||
}
|
||||
|
||||
void MainApplication::quitApplication()
|
||||
@ -665,8 +681,8 @@ void MainApplication::quitApplication()
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_windows.count() > 0) {
|
||||
saveSession();
|
||||
if (m_sessionManager && m_windows.count() > 0) {
|
||||
m_sessionManager->autoSaveLastSession();
|
||||
}
|
||||
|
||||
m_isClosing = true;
|
||||
@ -708,7 +724,7 @@ void MainApplication::postLaunch()
|
||||
QTimer::singleShot(5000, this, &MainApplication::runDeferredPostLaunchActions);
|
||||
}
|
||||
|
||||
void MainApplication::writeCurrentSession(const QString &filePath)
|
||||
QByteArray MainApplication::saveState() const
|
||||
{
|
||||
QByteArray data;
|
||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||
@ -726,19 +742,7 @@ void MainApplication::writeCurrentSession(const QString &filePath)
|
||||
}
|
||||
}
|
||||
|
||||
QFile file(filePath);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
file.write(data);
|
||||
file.close();
|
||||
}
|
||||
|
||||
void MainApplication::saveSession()
|
||||
{
|
||||
if (m_isPrivate || m_isRestoring || m_windows.count() == 0 || m_restoreManager) {
|
||||
return;
|
||||
}
|
||||
|
||||
writeCurrentSession(DataPaths::currentProfilePath() + QLatin1String("/session.dat"));
|
||||
return data;
|
||||
}
|
||||
|
||||
void MainApplication::saveSettings()
|
||||
@ -786,6 +790,8 @@ void MainApplication::saveSettings()
|
||||
qzSettings->saveSettings();
|
||||
AdBlockManager::instance()->save();
|
||||
QFile::remove(DataPaths::currentProfilePath() + QLatin1String("/WebpageIcons.db"));
|
||||
|
||||
sessionManager()->saveSettings();
|
||||
}
|
||||
|
||||
void MainApplication::messageReceived(const QString &message)
|
||||
@ -1059,27 +1065,6 @@ void MainApplication::translateApp()
|
||||
installTranslator(sys);
|
||||
}
|
||||
|
||||
void MainApplication::backupSavedSessions()
|
||||
{
|
||||
// session.dat - current
|
||||
// session.dat.old - first backup
|
||||
// session.dat.old1 - second backup
|
||||
|
||||
const QString sessionFile = DataPaths::currentProfilePath() + QLatin1String("/session.dat");
|
||||
|
||||
if (!QFile::exists(sessionFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (QFile::exists(sessionFile + QLatin1String(".old"))) {
|
||||
QFile::remove(sessionFile + QLatin1String(".old1"));
|
||||
QFile::copy(sessionFile + QLatin1String(".old"), sessionFile + QLatin1String(".old1"));
|
||||
}
|
||||
|
||||
QFile::remove(sessionFile + QLatin1String(".old"));
|
||||
QFile::copy(sessionFile, sessionFile + QLatin1String(".old"));
|
||||
}
|
||||
|
||||
void MainApplication::checkDefaultWebBrowser()
|
||||
{
|
||||
if (isPortable()) {
|
||||
|
@ -49,6 +49,7 @@ class HTML5PermissionsManager;
|
||||
class RegisterQAppAssociation;
|
||||
class DesktopNotificationsFactory;
|
||||
class ProxyStyle;
|
||||
class SessionManager;
|
||||
|
||||
class QUPZILLA_EXPORT MainApplication : public QtSingleApplication
|
||||
{
|
||||
@ -59,7 +60,8 @@ public:
|
||||
OpenBlankPage = 0,
|
||||
OpenHomePage = 1,
|
||||
OpenSpeedDial = 2,
|
||||
RestoreSession = 3
|
||||
RestoreSession = 3,
|
||||
SelectSession = 4
|
||||
};
|
||||
|
||||
explicit MainApplication(int &argc, char** argv);
|
||||
@ -101,6 +103,7 @@ public:
|
||||
|
||||
NetworkManager* networkManager();
|
||||
RestoreManager* restoreManager();
|
||||
SessionManager* sessionManager();
|
||||
DownloadManager* downloadManager();
|
||||
UserAgentManager* userAgentManager();
|
||||
SearchEnginesManager* searchEnginesManager();
|
||||
@ -108,6 +111,8 @@ public:
|
||||
DesktopNotificationsFactory* desktopNotifications();
|
||||
QWebEngineProfile* webProfile() const;
|
||||
|
||||
QByteArray saveState() const;
|
||||
|
||||
static MainApplication* instance();
|
||||
|
||||
public slots:
|
||||
@ -120,8 +125,6 @@ public slots:
|
||||
void changeOccurred();
|
||||
void quitApplication();
|
||||
|
||||
void writeCurrentSession(const QString &filePath);
|
||||
|
||||
signals:
|
||||
void settingsReloaded();
|
||||
void activeWindowChanged(BrowserWindow* window);
|
||||
@ -129,7 +132,6 @@ signals:
|
||||
private slots:
|
||||
void postLaunch();
|
||||
|
||||
void saveSession();
|
||||
void saveSettings();
|
||||
|
||||
void messageReceived(const QString &message);
|
||||
@ -150,7 +152,6 @@ private:
|
||||
void loadTheme(const QString &name);
|
||||
|
||||
void translateApp();
|
||||
void backupSavedSessions();
|
||||
|
||||
void setUserStyleSheet(const QString &filePath);
|
||||
|
||||
@ -173,6 +174,7 @@ private:
|
||||
|
||||
NetworkManager* m_networkManager;
|
||||
RestoreManager* m_restoreManager;
|
||||
SessionManager* m_sessionManager;
|
||||
DownloadManager* m_downloadManager;
|
||||
UserAgentManager* m_userAgentManager;
|
||||
SearchEnginesManager* m_searchEnginesManager;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "qzsettings.h"
|
||||
#include "pluginproxy.h"
|
||||
#include "webinspector.h"
|
||||
#include "sessionmanager.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMetaObject>
|
||||
@ -529,6 +530,22 @@ void MainMenu::init()
|
||||
ADD_ACTION("File/OpenFile", m_menuFile, QIcon::fromTheme(QSL("document-open")), tr("Open &File..."), SLOT(openFile()), "Ctrl+O");
|
||||
ADD_ACTION("File/CloseWindow", m_menuFile, QIcon::fromTheme(QSL("window-close")), tr("Close Window"), SLOT(closeWindow()), "Ctrl+Shift+W");
|
||||
m_menuFile->addSeparator();
|
||||
|
||||
if (!mApp->isPrivate()) {
|
||||
action = new QAction(tr("New Session..."), this);
|
||||
connect(action, SIGNAL(triggered()), mApp->sessionManager(), SLOT(newSession()));
|
||||
m_actions[QSL("File/NewSession")] = action;
|
||||
m_menuFile->addAction(action);
|
||||
action = new QAction(tr("Save Session..."), this);
|
||||
connect(action, SIGNAL(triggered()), mApp->sessionManager(), SLOT(saveSession()));
|
||||
m_actions[QSL("File/SaveSession")] = action;
|
||||
m_menuFile->addAction(action);
|
||||
QMenu* sessionsSubmenu = new QMenu(tr("Sessions"));
|
||||
connect(sessionsSubmenu, SIGNAL(aboutToShow()), mApp->sessionManager(), SLOT(aboutToShowSessionsMenu()));
|
||||
m_menuFile->addMenu(sessionsSubmenu);
|
||||
m_menuFile->addSeparator();
|
||||
}
|
||||
|
||||
ADD_ACTION("File/SavePageAs", m_menuFile, QIcon::fromTheme(QSL("document-save")), tr("&Save Page As..."), SLOT(savePageAs()), "Ctrl+S");
|
||||
ADD_ACTION("File/SendLink", m_menuFile, QIcon::fromTheme(QSL("mail-message-new")), tr("Send Link..."), SLOT(sendLink()), "");
|
||||
ADD_ACTION("File/Print", m_menuFile, QIcon::fromTheme(QSL("document-print")), tr("&Print..."), SLOT(printPage()), "Ctrl+P");
|
||||
|
@ -166,6 +166,7 @@ SOURCES += \
|
||||
preferences/useragentdialog.cpp \
|
||||
session/recoveryjsobject.cpp \
|
||||
session/restoremanager.cpp \
|
||||
session/sessionmanager.cpp \
|
||||
sidebar/bookmarkssidebar.cpp \
|
||||
sidebar/historysidebar.cpp \
|
||||
sidebar/sidebar.cpp \
|
||||
@ -347,6 +348,7 @@ HEADERS += \
|
||||
preferences/useragentdialog.h \
|
||||
session/recoveryjsobject.h \
|
||||
session/restoremanager.h \
|
||||
session/sessionmanager.h \
|
||||
sidebar/bookmarkssidebar.h \
|
||||
sidebar/historysidebar.h \
|
||||
sidebar/sidebar.h \
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "datapaths.h"
|
||||
#include "iconprovider.h"
|
||||
#include "useragentmanager.h"
|
||||
#include "sessionmanager.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QSettings>
|
||||
@ -375,7 +376,7 @@ QString QupZillaSchemeReply::configPage()
|
||||
cPage.replace(QLatin1String("%PATHS-TEXT%"),
|
||||
QString("<dt>%1</dt><dd>%2<dd>").arg(tr("Profile"), DataPaths::currentProfilePath()) +
|
||||
QString("<dt>%1</dt><dd>%2<dd>").arg(tr("Settings"), DataPaths::currentProfilePath() + "/settings.ini") +
|
||||
QString("<dt>%1</dt><dd>%2<dd>").arg(tr("Saved session"), DataPaths::currentProfilePath() + "/session.dat") +
|
||||
QString("<dt>%1</dt><dd>%2<dd>").arg(tr("Saved session"), SessionManager::defaultSessionPath()) +
|
||||
QString("<dt>%1</dt><dd>%2<dd>").arg(tr("Pinned tabs"), DataPaths::currentProfilePath() + "/pinnedtabs.dat") +
|
||||
QString("<dt>%1</dt><dd>%2<dd>").arg(tr("Data"), DataPaths::path(DataPaths::AppData)) +
|
||||
QString("<dt>%1</dt><dd>%2<dd>").arg(tr("Themes"), DataPaths::path(DataPaths::Themes)) +
|
||||
|
@ -318,6 +318,11 @@
|
||||
<string>Restore session</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Select session</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
|
@ -22,10 +22,10 @@
|
||||
|
||||
#include <QFile>
|
||||
|
||||
RestoreManager::RestoreManager()
|
||||
RestoreManager::RestoreManager(const QString &file)
|
||||
: m_recoveryObject(new RecoveryJsObject(this))
|
||||
{
|
||||
createFromFile(DataPaths::currentProfilePath() + QLatin1String("/session.dat"));
|
||||
createFromFile(file);
|
||||
}
|
||||
|
||||
RestoreManager::~RestoreManager()
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
QVector<WebTab::SavedTab> tabsState;
|
||||
};
|
||||
|
||||
explicit RestoreManager();
|
||||
explicit RestoreManager(const QString &file);
|
||||
virtual ~RestoreManager();
|
||||
|
||||
bool isValid() const;
|
||||
|
433
src/lib/session/sessionmanager.cpp
Normal file
433
src/lib/session/sessionmanager.cpp
Normal file
@ -0,0 +1,433 @@
|
||||
/* ============================================================
|
||||
* QupZilla - Qt web browser
|
||||
* Copyright (C) 2017 Razi Alavizadeh <s.r.alavizadeh@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "browserwindow.h"
|
||||
#include "datapaths.h"
|
||||
#include "mainapplication.h"
|
||||
#include "restoremanager.h"
|
||||
#include "sessionmanager.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QComboBox>
|
||||
#include <QDateTime>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
||||
SessionManager::SessionManager(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_firstBackupSession(DataPaths::currentProfilePath() + QL1S("/session.dat.old"))
|
||||
, m_secondBackupSession(DataPaths::currentProfilePath() + QL1S("/session.dat.old1"))
|
||||
{
|
||||
QFileSystemWatcher* sessionFilesWatcher = new QFileSystemWatcher({DataPaths::path(DataPaths::Sessions)}, this);
|
||||
connect(sessionFilesWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(sessionsDirectoryChanged()));
|
||||
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
static void addSessionSubmenu(QObject* receiver, QMenu* menu, const QString &title, const QString &filePath, const QFileInfo &lastActiveSessionFileInfo)
|
||||
{
|
||||
QMenu* sessionSubmenu = new QMenu(title, menu);
|
||||
QObject::connect(sessionSubmenu, SIGNAL(aboutToShow()), receiver, SLOT(aboutToShowSessionSubmenu()));
|
||||
|
||||
QAction* action = menu->addMenu(sessionSubmenu);
|
||||
action->setData(filePath);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(QFileInfo(filePath) == lastActiveSessionFileInfo);
|
||||
}
|
||||
|
||||
static void addSessionsMetaDataToMenu(QObject* receiver, QMenu* menu, const QFileInfo &lastActiveSessionFileInfo, const QList<SessionManager::SessionMetaData> &sessionsMetaDataList)
|
||||
{
|
||||
for (const SessionManager::SessionMetaData &metaData : sessionsMetaDataList) {
|
||||
addSessionSubmenu(receiver, menu, metaData.name, metaData.filePath, lastActiveSessionFileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionManager::aboutToShowSessionsMenu()
|
||||
{
|
||||
QMenu* menu = qobject_cast<QMenu*>(sender());
|
||||
menu->clear();
|
||||
|
||||
const QFileInfo lastActiveSessionInfo(m_lastActiveSessionPath);
|
||||
|
||||
fillSessionsMetaDataListIfNeeded();
|
||||
|
||||
addSessionsMetaDataToMenu(this, menu, lastActiveSessionInfo, m_sessionsMetaDataList);
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
if (QFile::exists(m_firstBackupSession))
|
||||
addSessionSubmenu(this, menu, tr("First Backup"), m_firstBackupSession, lastActiveSessionInfo);
|
||||
if (QFile::exists(m_secondBackupSession))
|
||||
addSessionSubmenu(this, menu, tr("Second Backup"), m_secondBackupSession, lastActiveSessionInfo);
|
||||
}
|
||||
|
||||
void SessionManager::aboutToShowSessionSubmenu()
|
||||
{
|
||||
QMenu* menu = qobject_cast<QMenu*>(sender());
|
||||
menu->clear();
|
||||
|
||||
const QString sessionFilePath = menu->menuAction()->data().toString();
|
||||
|
||||
const QFileInfo currentSessionFileInfo(m_lastActiveSessionPath);
|
||||
const QFileInfo sessionFileInfo(sessionFilePath);
|
||||
|
||||
QList<QAction*> actions;
|
||||
QAction* action;
|
||||
|
||||
if (sessionFileInfo != currentSessionFileInfo || mApp->restoreManager()) {
|
||||
if (sessionFileInfo != QFileInfo(m_firstBackupSession) && sessionFileInfo != QFileInfo(m_secondBackupSession)) {
|
||||
action = new QAction(SessionManager::tr("Switch To"), menu);
|
||||
action->setData(sessionFilePath);
|
||||
QObject::connect(action, SIGNAL(triggered(bool)), this, SLOT(switchToSession()));
|
||||
actions << action;
|
||||
}
|
||||
|
||||
action = new QAction(SessionManager::tr("Open"), menu);
|
||||
action->setData(sessionFilePath);
|
||||
QObject::connect(action, SIGNAL(triggered(bool)), this, SLOT(openSession()));
|
||||
actions << action;
|
||||
|
||||
action = new QAction(menu);
|
||||
action->setSeparator(true);
|
||||
actions << action;
|
||||
}
|
||||
|
||||
action = new QAction(SessionManager::tr("Clone"), menu);
|
||||
action->setData(sessionFilePath);
|
||||
QObject::connect(action, SIGNAL(triggered(bool)), this, SLOT(cloneSession()));
|
||||
actions << action;
|
||||
|
||||
if (sessionFileInfo != currentSessionFileInfo) {
|
||||
action = new QAction(SessionManager::tr("Rename"), menu);
|
||||
action->setData(sessionFilePath);
|
||||
QObject::connect(action, SIGNAL(triggered(bool)), this, SLOT(renameSession()));
|
||||
actions << action;
|
||||
}
|
||||
|
||||
if (sessionFileInfo != currentSessionFileInfo && sessionFileInfo != QFileInfo(defaultSessionPath()) &&
|
||||
sessionFileInfo != QFileInfo(m_firstBackupSession) && sessionFileInfo != QFileInfo(m_secondBackupSession)) {
|
||||
action = new QAction(SessionManager::tr("Remove"), menu);
|
||||
action->setData(sessionFilePath);
|
||||
QObject::connect(action, SIGNAL(triggered(bool)), this, SLOT(deleteSession()));
|
||||
actions << action;
|
||||
}
|
||||
|
||||
menu->addActions(actions);
|
||||
}
|
||||
|
||||
void SessionManager::sessionsDirectoryChanged()
|
||||
{
|
||||
m_sessionsMetaDataList.clear();
|
||||
}
|
||||
|
||||
void SessionManager::switchToSession()
|
||||
{
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
if (!action)
|
||||
return;
|
||||
|
||||
openSession(action->data().toString(), true);
|
||||
}
|
||||
|
||||
void SessionManager::openSession(QString sessionFilePath, bool switchSession)
|
||||
{
|
||||
if (sessionFilePath.isEmpty()) {
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
if (!action)
|
||||
return;
|
||||
|
||||
sessionFilePath = action->data().toString();
|
||||
}
|
||||
|
||||
QVector<RestoreManager::WindowData> sessionData;
|
||||
RestoreManager::createFromFile(sessionFilePath, sessionData);
|
||||
|
||||
if (sessionData.isEmpty())
|
||||
return;
|
||||
|
||||
BrowserWindow* window = mApp->getWindow();
|
||||
if (switchSession) {
|
||||
writeCurrentSession(m_lastActiveSessionPath);
|
||||
|
||||
window = mApp->createWindow(Qz::BW_OtherRestoredWindow);
|
||||
for (BrowserWindow* win : mApp->windows()) {
|
||||
if (win != window)
|
||||
win->close();
|
||||
}
|
||||
|
||||
m_lastActiveSessionPath = QFileInfo(sessionFilePath).canonicalFilePath();
|
||||
}
|
||||
|
||||
mApp->openSession(window, sessionData);
|
||||
}
|
||||
|
||||
void SessionManager::renameSession(QString sessionFilePath, bool clone)
|
||||
{
|
||||
if (sessionFilePath.isEmpty()) {
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
if (!action)
|
||||
return;
|
||||
|
||||
sessionFilePath = action->data().toString();
|
||||
}
|
||||
|
||||
bool ok;
|
||||
const QString suggestedName = QFileInfo(sessionFilePath).baseName() + (clone ? tr("_cloned") : tr("_renamed"));
|
||||
QString newName = QInputDialog::getText(mApp->activeWindow(), (clone ? tr("Clone Session") : tr("Rename Session")),
|
||||
tr("Please enter a new name:"), QLineEdit::Normal,
|
||||
suggestedName, &ok);
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
const QString newSessionPath = QString("%1/%2.dat").arg(DataPaths::path(DataPaths::Sessions)).arg(newName);
|
||||
if (QFile::exists(newSessionPath)) {
|
||||
QMessageBox::information(mApp->activeWindow(), tr("Error!"), tr("The session file \"%1\" exists. Please enter another name.").arg(newName));
|
||||
renameSession(sessionFilePath, clone);
|
||||
return;
|
||||
}
|
||||
|
||||
if (clone) {
|
||||
if (!QFile::copy(sessionFilePath, newSessionPath)) {
|
||||
QMessageBox::information(mApp->activeWindow(), tr("Error!"), tr("An error occurred when cloning session file."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!QFile::rename(sessionFilePath, newSessionPath)) {
|
||||
QMessageBox::information(mApp->activeWindow(), tr("Error!"), tr("An error occurred when renaming session file."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SessionManager::cloneSession()
|
||||
{
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
if (!action)
|
||||
return;
|
||||
|
||||
renameSession(action->data().toString(), true);
|
||||
}
|
||||
|
||||
void SessionManager::deleteSession()
|
||||
{
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
if (!action)
|
||||
return;
|
||||
|
||||
const QString filePath = action->data().toString();
|
||||
|
||||
QMessageBox::StandardButton result = QMessageBox::information(mApp->activeWindow(), tr("Warning!"), tr("Are you sure to delete following session?\n%1")
|
||||
.arg(QDir::toNativeSeparators(filePath)), QMessageBox::Yes | QMessageBox::No);
|
||||
if (result == QMessageBox::Yes) {
|
||||
QFile::remove(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionManager::saveSession()
|
||||
{
|
||||
bool ok;
|
||||
QString sessionName = QInputDialog::getText(mApp->activeWindow(), tr("Save Session"),
|
||||
tr("Please enter a name to save session:"), QLineEdit::Normal,
|
||||
tr("Saved Session (%1)").arg(QDateTime::currentDateTime().toString("dd MMM yyyy HH-mm-ss")), &ok);
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
const QString filePath = QString("%1/%2.dat").arg(DataPaths::path(DataPaths::Sessions)).arg(sessionName);
|
||||
if (QFile::exists(filePath)) {
|
||||
QMessageBox::information(mApp->activeWindow(), tr("Error!"), tr("The session file \"%1\" exists. Please enter another name.").arg(sessionName));
|
||||
saveSession();
|
||||
return;
|
||||
}
|
||||
|
||||
writeCurrentSession(filePath);
|
||||
}
|
||||
|
||||
void SessionManager::newSession()
|
||||
{
|
||||
bool ok;
|
||||
QString sessionName = QInputDialog::getText(mApp->activeWindow(), tr("New Session"),
|
||||
tr("Please enter a name to create new session:"), QLineEdit::Normal,
|
||||
tr("New Session (%1)").arg(QDateTime::currentDateTime().toString("dd MMM yyyy HH-mm-ss")), &ok);
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
const QString filePath = QString("%1/%2.dat").arg(DataPaths::path(DataPaths::Sessions)).arg(sessionName);
|
||||
if (QFile::exists(filePath)) {
|
||||
QMessageBox::information(mApp->activeWindow(), tr("Error!"), tr("The session file \"%1\" exists. Please enter another name.").arg(sessionName));
|
||||
newSession();
|
||||
return;
|
||||
}
|
||||
|
||||
writeCurrentSession(m_lastActiveSessionPath);
|
||||
|
||||
BrowserWindow* window = mApp->createWindow(Qz::BW_NewWindow);
|
||||
for (BrowserWindow* win : mApp->windows()) {
|
||||
if (win != window)
|
||||
win->close();
|
||||
}
|
||||
|
||||
m_lastActiveSessionPath = filePath;
|
||||
autoSaveLastSession();
|
||||
}
|
||||
|
||||
void SessionManager::fillSessionsMetaDataListIfNeeded()
|
||||
{
|
||||
if (!m_sessionsMetaDataList.isEmpty())
|
||||
return;
|
||||
|
||||
QDir dir(DataPaths::path(DataPaths::Sessions));
|
||||
|
||||
const QFileInfoList sessionFiles = QFileInfoList() << QFileInfo(defaultSessionPath()) << dir.entryInfoList({QSL("*.*")}, QDir::Files, QDir::Time);
|
||||
|
||||
QStringList fileNames;
|
||||
|
||||
for (int i = 0; i < sessionFiles.size(); ++i) {
|
||||
const QFileInfo &fileInfo = sessionFiles.at(i);
|
||||
QVector<RestoreManager::WindowData> data;
|
||||
RestoreManager::createFromFile(fileInfo.absoluteFilePath(), data);
|
||||
|
||||
if (data.isEmpty())
|
||||
continue;
|
||||
|
||||
SessionMetaData metaData;
|
||||
metaData.name = fileInfo.baseName();
|
||||
|
||||
if (fileInfo == QFileInfo(defaultSessionPath()))
|
||||
metaData.name = tr("Default Session");
|
||||
else if (fileNames.contains(fileInfo.baseName()))
|
||||
metaData.name = fileInfo.fileName();
|
||||
else
|
||||
metaData.name = fileInfo.baseName();
|
||||
|
||||
fileNames << metaData.name;
|
||||
metaData.filePath = fileInfo.canonicalFilePath();
|
||||
|
||||
m_sessionsMetaDataList << metaData;
|
||||
}
|
||||
}
|
||||
|
||||
void SessionManager::loadSettings()
|
||||
{
|
||||
Settings settings;
|
||||
settings.beginGroup("Web-Browser-Settings");
|
||||
m_lastActiveSessionPath = settings.value("lastActiveSessionPath", defaultSessionPath()).toString();
|
||||
settings.endGroup();
|
||||
|
||||
// fallback to default session
|
||||
if (!QFile::exists(m_lastActiveSessionPath))
|
||||
m_lastActiveSessionPath = defaultSessionPath();
|
||||
}
|
||||
|
||||
void SessionManager::saveSettings()
|
||||
{
|
||||
Settings settings;
|
||||
settings.beginGroup("Web-Browser-Settings");
|
||||
settings.setValue("lastActiveSessionPath", m_lastActiveSessionPath);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
QString SessionManager::defaultSessionPath()
|
||||
{
|
||||
return DataPaths::currentProfilePath() + QL1S("/session.dat");
|
||||
}
|
||||
|
||||
QString SessionManager::lastActiveSessionPath() const
|
||||
{
|
||||
return m_lastActiveSessionPath;
|
||||
}
|
||||
|
||||
void SessionManager::backupSavedSessions()
|
||||
{
|
||||
if (!QFile::exists(m_lastActiveSessionPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (QFile::exists(m_firstBackupSession)) {
|
||||
QFile::remove(m_secondBackupSession);
|
||||
QFile::copy(m_firstBackupSession, m_secondBackupSession);
|
||||
}
|
||||
|
||||
QFile::remove(m_firstBackupSession);
|
||||
QFile::copy(m_lastActiveSessionPath, m_firstBackupSession);
|
||||
}
|
||||
|
||||
void SessionManager::writeCurrentSession(const QString &filePath)
|
||||
{
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::WriteOnly) || file.write(mApp->saveState()) == -1) {
|
||||
qWarning() << "Error! can not write the current session file: " << filePath << file.errorString();
|
||||
return;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
void SessionManager::autoSaveLastSession()
|
||||
{
|
||||
if (mApp->isPrivate() || mApp->isRestoring() || mApp->windowCount() == 0 || mApp->restoreManager()) {
|
||||
return;
|
||||
}
|
||||
|
||||
saveSettings();
|
||||
writeCurrentSession(m_lastActiveSessionPath);
|
||||
}
|
||||
|
||||
QString SessionManager::askSessionFromUser()
|
||||
{
|
||||
fillSessionsMetaDataListIfNeeded();
|
||||
|
||||
QDialog dialog(mApp->getWindow(), Qt::WindowStaysOnTopHint);
|
||||
QLabel label(tr("Please select the startup session:"), &dialog);
|
||||
QComboBox comboBox(&dialog);
|
||||
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog);
|
||||
connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
|
||||
connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
|
||||
|
||||
QVBoxLayout layout;
|
||||
layout.addWidget(&label);
|
||||
layout.addWidget(&comboBox);
|
||||
layout.addWidget(&buttonBox);
|
||||
dialog.setLayout(&layout);
|
||||
|
||||
const QFileInfo lastActiveSessionFileInfo(m_lastActiveSessionPath);
|
||||
|
||||
for (const SessionMetaData &metaData : m_sessionsMetaDataList) {
|
||||
if (QFileInfo(metaData.filePath) != lastActiveSessionFileInfo) {
|
||||
comboBox.addItem(metaData.name, metaData.filePath);
|
||||
}
|
||||
else {
|
||||
comboBox.insertItem(0, tr("%1 (last session)").arg(metaData.name), metaData.filePath);
|
||||
}
|
||||
}
|
||||
|
||||
comboBox.setCurrentIndex(0);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
m_lastActiveSessionPath = comboBox.currentData().toString();
|
||||
}
|
||||
|
||||
return m_lastActiveSessionPath;
|
||||
}
|
74
src/lib/session/sessionmanager.h
Normal file
74
src/lib/session/sessionmanager.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* ============================================================
|
||||
* QupZilla - Qt web browser
|
||||
* Copyright (C) 2017 Razi Alavizadeh <s.r.alavizadeh@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#ifndef SESSIONMANAGER_H
|
||||
#define SESSIONMANAGER_H
|
||||
|
||||
#include "qzcommon.h"
|
||||
|
||||
class QAction;
|
||||
class QMenu;
|
||||
|
||||
|
||||
class QUPZILLA_EXPORT SessionManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SessionManager(QObject* parent = 0);
|
||||
|
||||
struct SessionMetaData {
|
||||
QString name;
|
||||
QString filePath;
|
||||
};
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
static QString defaultSessionPath();
|
||||
QString lastActiveSessionPath() const;
|
||||
QString askSessionFromUser();
|
||||
|
||||
void backupSavedSessions();
|
||||
void writeCurrentSession(const QString &filePath);
|
||||
|
||||
public slots:
|
||||
void autoSaveLastSession();
|
||||
|
||||
private slots:
|
||||
void aboutToShowSessionsMenu();
|
||||
void aboutToShowSessionSubmenu();
|
||||
void sessionsDirectoryChanged();
|
||||
void switchToSession();
|
||||
void openSession(QString sessionFilePath = QString(), bool switchSession = false);
|
||||
void renameSession(QString sessionFilePath = QString(), bool clone = false);
|
||||
void cloneSession();
|
||||
void deleteSession();
|
||||
void saveSession();
|
||||
void newSession();
|
||||
|
||||
private:
|
||||
void fillSessionsMetaDataListIfNeeded();
|
||||
|
||||
QList<SessionMetaData> m_sessionsMetaDataList;
|
||||
|
||||
QString m_firstBackupSession;
|
||||
QString m_secondBackupSession;
|
||||
QString m_lastActiveSessionPath;
|
||||
};
|
||||
|
||||
#endif // SESSIONMANAGER_H
|
Loading…
Reference in New Issue
Block a user