diff --git a/src/konqsessionmanager.cpp b/src/konqsessionmanager.cpp index cd93eed1f..730fcc89e 100644 --- a/src/konqsessionmanager.cpp +++ b/src/konqsessionmanager.cpp @@ -1,689 +1,694 @@ /* This file is part of the KDE project Copyright (C) 2008 Eduardo Robles Elvira 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "konqsessionmanager.h" #include "konqmisc.h" #include "konqmainwindow.h" #include "konqsessionmanager_interface.h" #include "konqsessionmanageradaptor.h" #include "konqviewmanager.h" #include "konqsettingsxt.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class KonqSessionManagerPrivate { public: KonqSessionManagerPrivate() : instance(0) { } ~KonqSessionManagerPrivate() { delete instance; } KonqSessionManager *instance; }; K_GLOBAL_STATIC(KonqSessionManagerPrivate, myKonqSessionManagerPrivate) static QString viewIdFor(const QString &sessionFile, const QString &viewId) { return (sessionFile + viewId); } static const QList windowConfigGroups(/*NOT const, we'll use writeEntry*/ KConfig &config) { QList groups; KConfigGroup generalGroup(&config, "General"); const int size = generalGroup.readEntry("Number of Windows", 0); for (int i = 0; i < size; i++) { groups << KConfigGroup(&config, "Window" + QString::number(i)); } return groups; } SessionRestoreDialog::SessionRestoreDialog(const QStringList &sessionFilePaths, QWidget *parent) : KDialog(parent, 0) , m_sessionItemsCount(0) , m_dontShowChecked(false) { setCaption(i18nc("@title:window", "Restore Session?")); setButtons(KDialog::Yes | KDialog::No | KDialog::Cancel); setObjectName(QStringLiteral("restoresession")); setButtonGuiItem(KDialog::Yes, KGuiItem(i18nc("@action:button yes", "Restore Session"), QStringLiteral("window-new"))); setButtonGuiItem(KDialog::No, KGuiItem(i18nc("@action:button no", "Do Not Restore"), QStringLiteral("dialog-close"))); setButtonGuiItem(KDialog::Cancel, KGuiItem(i18nc("@action:button ask later", "Ask Me Later"), QStringLiteral("chronometer"))); setDefaultButton(KDialog::Yes); setButtonFocus(KDialog::Yes); setModal(true); QWidget *mainWidget = new QWidget(this); QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget); mainLayout->setSpacing(KDialog::spacingHint() * 2); // provide extra spacing mainLayout->setMargin(0); QHBoxLayout *hLayout = new QHBoxLayout(); hLayout->setMargin(0); hLayout->setSpacing(-1); // use default spacing mainLayout->addLayout(hLayout, 5); QIcon icon(QLatin1String("dialog-warning")); if (!icon.isNull()) { QLabel *iconLabel = new QLabel(mainWidget); QStyleOption option; option.initFrom(mainWidget); iconLabel->setPixmap(icon.pixmap(mainWidget->style()->pixelMetric(QStyle::PM_MessageBoxIconSize, &option, mainWidget))); QVBoxLayout *iconLayout = new QVBoxLayout(); iconLayout->addStretch(1); iconLayout->addWidget(iconLabel); iconLayout->addStretch(5); hLayout->addLayout(iconLayout, 0); } const QString text(i18n("Konqueror did not close correctly. Would you like to restore these previous sessions?")); QLabel *messageLabel = new QLabel(text, mainWidget); Qt::TextInteractionFlags flags = (Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); messageLabel->setTextInteractionFlags(flags); messageLabel->setWordWrap(true); hLayout->addSpacing(KDialog::spacingHint()); hLayout->addWidget(messageLabel, 5); - QTreeWidget *treeWidget = 0; - if (!sessionFilePaths.isEmpty()) { - treeWidget = new QTreeWidget(mainWidget); - treeWidget->setHeader(0); - treeWidget->setHeaderHidden(true); - treeWidget->setToolTip(i18nc("@tooltip:session list", "Uncheck the sessions you do not want to be restored")); - - QStyleOptionViewItem styleOption; - styleOption.initFrom(treeWidget); - QFontMetrics fm(styleOption.font); - int w = treeWidget->width(); - const QRect desktop = QApplication::desktop()->screenGeometry(this); - - // Collect info from the sessions to restore - Q_FOREACH (const QString &sessionFile, sessionFilePaths) { - qDebug() << sessionFile; - QTreeWidgetItem *windowItem = 0; - KConfig config(sessionFile, KConfig::SimpleConfig); - const QList groups = windowConfigGroups(config); - Q_FOREACH (const KConfigGroup &group, groups) { - // To avoid a recursive search, let's do linear search on Foo_CurrentHistoryItem=1 - Q_FOREACH (const QString &key, group.keyList()) { - if (key.endsWith(QLatin1String("_CurrentHistoryItem"))) { - const QString viewId = key.left(key.length() - qstrlen("_CurrentHistoryItem")); - const QString historyIndex = group.readEntry(key, QString()); - const QString prefix = "HistoryItem" + viewId + '_' + historyIndex; - // Ignore the sidebar views - if (group.readEntry(prefix + "StrServiceName", QString()).startsWith(QLatin1String("konq_sidebar"))) { - continue; - } - const QString url = group.readEntry(prefix + "Url", QString()); - const QString title = group.readEntry(prefix + "Title", QString()); - qDebug() << viewId << url << title; - const QString displayText = (title.trimmed().isEmpty() ? url : title); - if (!displayText.isEmpty()) { - if (!windowItem) { - windowItem = new QTreeWidgetItem(treeWidget); - const int index = sessionFilePaths.indexOf(sessionFile) + 1; - windowItem->setText(0, i18nc("@item:treewidget", "Window %1", index)); - windowItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); - windowItem->setCheckState(0, Qt::Checked); - windowItem->setExpanded(true); - } - QTreeWidgetItem *item = new QTreeWidgetItem(windowItem); - item->setText(0, displayText); - item->setData(0, Qt::UserRole, viewIdFor(sessionFile, viewId)); - item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); - item->setCheckState(0, Qt::Checked); - w = qMax(w, fm.width(displayText)); - m_sessionItemsCount++; + Q_ASSERT(!sessionFilePaths.isEmpty()); + m_treeWidget = new QTreeWidget(mainWidget); + m_treeWidget->setHeader(0); + m_treeWidget->setHeaderHidden(true); + m_treeWidget->setToolTip(i18nc("@tooltip:session list", "Uncheck the sessions you do not want to be restored")); + + QStyleOptionViewItem styleOption; + styleOption.initFrom(m_treeWidget); + QFontMetrics fm(styleOption.font); + int w = m_treeWidget->width(); + const QRect desktop = QApplication::desktop()->screenGeometry(this); + + // Collect info from the sessions to restore + Q_FOREACH (const QString &sessionFile, sessionFilePaths) { + qDebug() << sessionFile; + QTreeWidgetItem *windowItem = 0; + KConfig config(sessionFile, KConfig::SimpleConfig); + const QList groups = windowConfigGroups(config); + Q_FOREACH (const KConfigGroup &group, groups) { + // To avoid a recursive search, let's do linear search on Foo_CurrentHistoryItem=1 + Q_FOREACH (const QString &key, group.keyList()) { + if (key.endsWith(QLatin1String("_CurrentHistoryItem"))) { + const QString viewId = key.left(key.length() - qstrlen("_CurrentHistoryItem")); + const QString historyIndex = group.readEntry(key, QString()); + const QString prefix = "HistoryItem" + viewId + '_' + historyIndex; + // Ignore the sidebar views + if (group.readEntry(prefix + "StrServiceName", QString()).startsWith(QLatin1String("konq_sidebar"))) { + continue; + } + const QString url = group.readEntry(prefix + "Url", QString()); + const QString title = group.readEntry(prefix + "Title", QString()); + qDebug() << viewId << url << title; + const QString displayText = (title.trimmed().isEmpty() ? url : title); + if (!displayText.isEmpty()) { + if (!windowItem) { + windowItem = new QTreeWidgetItem(m_treeWidget); + const int index = sessionFilePaths.indexOf(sessionFile) + 1; + windowItem->setText(0, i18nc("@item:treewidget", "Window %1", index)); + windowItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); + windowItem->setCheckState(0, Qt::Checked); + windowItem->setExpanded(true); } + QTreeWidgetItem *item = new QTreeWidgetItem(windowItem); + item->setText(0, displayText); + item->setData(0, Qt::UserRole, viewIdFor(sessionFile, viewId)); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); + item->setCheckState(0, Qt::Checked); + w = qMax(w, fm.width(displayText)); + m_sessionItemsCount++; } } } - - if (windowItem) { - m_checkedSessionItems.insert(windowItem, windowItem->childCount()); - } } - const int borderWidth = treeWidget->width() - treeWidget->viewport()->width() + treeWidget->verticalScrollBar()->height(); - w += borderWidth; - if (w > desktop.width() * 0.85) { // limit treeWidget size to 85% of screen width - w = qRound(desktop.width() * 0.85); + if (windowItem) { + m_checkedSessionItems.insert(windowItem, windowItem->childCount()); } - treeWidget->setMinimumWidth(w); - mainLayout->addWidget(treeWidget, 50); - treeWidget->setSelectionMode(QTreeWidget::NoSelection); - messageLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); } + const int borderWidth = m_treeWidget->width() - m_treeWidget->viewport()->width() + m_treeWidget->verticalScrollBar()->height(); + w += borderWidth; + if (w > desktop.width() * 0.85) { // limit treeWidget size to 85% of screen width + w = qRound(desktop.width() * 0.85); + } + m_treeWidget->setMinimumWidth(w); + mainLayout->addWidget(m_treeWidget, 50); + m_treeWidget->setSelectionMode(QTreeWidget::NoSelection); + messageLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + // Do not connect the itemChanged signal until after the treewidget // is completely populated to prevent the firing of the itemChanged // signal while in the process of adding the original session items. - if (treeWidget && treeWidget->topLevelItemCount() > 0) { - connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), - this, SLOT(slotItemChanged(QTreeWidgetItem*,int))); - } + connect(m_treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), + this, SLOT(slotItemChanged(QTreeWidgetItem*,int))); QCheckBox *checkbox = new QCheckBox(i18n("Do not ask again"), mainWidget); connect(checkbox, &QCheckBox::clicked, this, &SessionRestoreDialog::slotClicked); mainLayout->addWidget(checkbox); setMainWidget(mainWidget); } SessionRestoreDialog::~SessionRestoreDialog() { } +bool SessionRestoreDialog::isEmpty() const +{ + return m_treeWidget->topLevelItemCount() == 0; +} + QStringList SessionRestoreDialog::discardedSessionList() const { return m_discardedSessionList; } bool SessionRestoreDialog::isDontShowChecked() const { return m_dontShowChecked; } void SessionRestoreDialog::slotClicked(bool checked) { m_dontShowChecked = checked; } void SessionRestoreDialog::slotItemChanged(QTreeWidgetItem *item, int column) { Q_ASSERT(item); const int itemChildCount = item->childCount(); QTreeWidgetItem *parentItem = 0; const bool blocked = item->treeWidget()->blockSignals(true); if (itemChildCount > 0) { parentItem = item; for (int i = 0; i < itemChildCount; ++i) { QTreeWidgetItem *childItem = item->child(i); if (childItem) { childItem->setCheckState(column, item->checkState(column)); switch (childItem->checkState(column)) { case Qt::Checked: m_sessionItemsCount++; m_discardedSessionList.removeAll(childItem->data(column, Qt::UserRole).toString()); m_checkedSessionItems[item]++; break; case Qt::Unchecked: m_sessionItemsCount--; m_discardedSessionList.append(childItem->data(column, Qt::UserRole).toString()); m_checkedSessionItems[item]--; break; default: break; } } } } else { parentItem = item->parent(); switch (item->checkState(column)) { case Qt::Checked: m_sessionItemsCount++; m_discardedSessionList.removeAll(item->data(column, Qt::UserRole).toString()); m_checkedSessionItems[parentItem]++; break; case Qt::Unchecked: m_sessionItemsCount--; m_discardedSessionList.append(item->data(column, Qt::UserRole).toString()); m_checkedSessionItems[parentItem]--; break; default: break; } } const int numCheckSessions = m_checkedSessionItems.value(parentItem); switch (parentItem->checkState(column)) { case Qt::Checked: if (numCheckSessions == 0) { parentItem->setCheckState(column, Qt::Unchecked); } case Qt::Unchecked: if (numCheckSessions > 0) { parentItem->setCheckState(column, Qt::Checked); } default: break; } enableButton(KDialog::Yes, m_sessionItemsCount > 0); item->treeWidget()->blockSignals(blocked); } void SessionRestoreDialog::saveDontShow(const QString &dontShowAgainName, int result) { if (dontShowAgainName.isEmpty()) { return; } KConfigGroup::WriteConfigFlags flags = KConfig::Persistent; if (dontShowAgainName[0] == ':') { flags |= KConfigGroup::Global; } KConfigGroup cg(KSharedConfig::openConfig().data(), "Notification Messages"); cg.writeEntry(dontShowAgainName, result == Yes, flags); cg.sync(); } bool SessionRestoreDialog::shouldBeShown(const QString &dontShowAgainName, int *result) { if (dontShowAgainName.isEmpty()) { return true; } KConfigGroup cg(KSharedConfig::openConfig().data(), "Notification Messages"); const QString dontAsk = cg.readEntry(dontShowAgainName, QString()).toLower(); if (dontAsk == QLatin1String("yes") || dontAsk == QLatin1String("true")) { if (result) { *result = Yes; } return false; } if (dontAsk == QLatin1String("no") || dontAsk == QLatin1String("false")) { if (result) { *result = No; } return false; } return true; } KonqSessionManager::KonqSessionManager() : m_autosaveDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + "autosave") , m_autosaveEnabled(false) // so that enableAutosave works , m_createdOwnedByDir(false) , m_sessionConfig(0) { // Initialize dbus interfaces new KonqSessionManagerAdaptor(this); const QString dbusPath = QStringLiteral("/KonqSessionManager"); const QString dbusInterface = QStringLiteral("org.kde.Konqueror.SessionManager"); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.registerObject(dbusPath, this); m_baseService = KonqMisc::encodeFilename(dbus.baseService()); dbus.connect(QString(), dbusPath, dbusInterface, QStringLiteral("saveCurrentSession"), this, SLOT(slotSaveCurrentSession(QString))); // Initialize the timer const int interval = KonqSettings::autoSaveInterval(); if (interval > 0) { m_autoSaveTimer.setInterval(interval * 1000); connect(&m_autoSaveTimer, SIGNAL(timeout()), this, SLOT(autoSaveSession())); } enableAutosave(); connect(qApp, &QGuiApplication::commitDataRequest, this, &KonqSessionManager::slotCommitData); } KonqSessionManager::~KonqSessionManager() { if (m_sessionConfig) { QFile::remove(m_sessionConfig->name()); } delete m_sessionConfig; } // Don't restore preloaded konquerors void KonqSessionManager::slotCommitData(QSessionManager &sm) { if (!m_autosaveEnabled) { sm.setRestartHint(QSessionManager::RestartNever); } } void KonqSessionManager::disableAutosave() { if (!m_autosaveEnabled) { return; } m_autosaveEnabled = false; m_autoSaveTimer.stop(); if (m_sessionConfig) { QFile::remove(m_sessionConfig->name()); delete m_sessionConfig; m_sessionConfig = 0; } } void KonqSessionManager::enableAutosave() { if (m_autosaveEnabled) { return; } // Create the config file for autosaving current session QString filename = QLatin1String("autosave/") + m_baseService; const QString filePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + filename; delete m_sessionConfig; m_sessionConfig = new KConfig(filePath, KConfig::SimpleConfig); //qDebug() << "config filename:" << m_sessionConfig->name(); m_autosaveEnabled = true; m_autoSaveTimer.start(); } void KonqSessionManager::deleteOwnedSessions() { // Not dealing with the sessions about to remove anymore if (m_createdOwnedByDir && KTempDir::removeDir(dirForMyOwnedSessionFiles())) { m_createdOwnedByDir = false; } } KonqSessionManager *KonqSessionManager::self() { if (!myKonqSessionManagerPrivate->instance) { myKonqSessionManagerPrivate->instance = new KonqSessionManager(); } return myKonqSessionManagerPrivate->instance; } void KonqSessionManager::autoSaveSession() { if (!m_autosaveEnabled) { return; } const bool isActive = m_autoSaveTimer.isActive(); if (isActive) { m_autoSaveTimer.stop(); } saveCurrentSessionToFile(m_sessionConfig); m_sessionConfig->sync(); m_sessionConfig->markAsClean(); // Now that we have saved current session it's safe to remove our owned_by // directory deleteOwnedSessions(); if (isActive) { m_autoSaveTimer.start(); } } void KonqSessionManager::saveCurrentSessions(const QString &path) { emit saveCurrentSession(path); } void KonqSessionManager::slotSaveCurrentSession(const QString &path) { const QString filename = path + '/' + m_baseService; saveCurrentSessionToFile(filename); } void KonqSessionManager::saveCurrentSessionToFile(const QString &sessionConfigPath, KonqMainWindow *mainWindow) { QFile::remove(sessionConfigPath); KConfig config(sessionConfigPath, KConfig::SimpleConfig); QList mainWindows; if (mainWindow) { mainWindows << mainWindow; } saveCurrentSessionToFile(&config, mainWindows); } void KonqSessionManager::saveCurrentSessionToFile(KConfig *config, const QList &theMainWindows) { QList mainWindows = theMainWindows; if (mainWindows.isEmpty() && KonqMainWindow::mainWindowList()) { mainWindows = *KonqMainWindow::mainWindowList(); } unsigned int counter = 0; if (mainWindows.isEmpty()) { return; } foreach (KonqMainWindow *window, mainWindows) { if (!window->isPreloaded()) { KConfigGroup configGroup(config, "Window" + QString::number(counter)); window->saveProperties(configGroup); counter++; } } KConfigGroup configGroup(config, "General"); configGroup.writeEntry("Number of Windows", counter); } QString KonqSessionManager::autosaveDirectory() const { return m_autosaveDir; } QStringList KonqSessionManager::takeSessionsOwnership() { // Tell to other konqueror instances that we are the one dealing with // these sessions QDir dir(dirForMyOwnedSessionFiles()); QDir parentDir(m_autosaveDir); if (!dir.exists()) { m_createdOwnedByDir = parentDir.mkdir("owned_by" + m_baseService); } QDirIterator it(m_autosaveDir, QDir::Writable | QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); QStringList sessionFilePaths; QDBusConnectionInterface *idbus = QDBusConnection::sessionBus().interface(); while (it.hasNext()) { it.next(); // this is the case where another konq started to restore that session, // but crashed immediately. So we try to restore that session again if (it.fileInfo().isDir()) { // The remove() removes the "owned_by" part if (!idbus->isServiceRegistered( KonqMisc::decodeFilename(it.fileName().remove(0, 8)))) { QDirIterator it2(it.filePath(), QDir::Writable | QDir::Files); while (it2.hasNext()) { it2.next(); // take ownership of the abandoned file const QString newFileName = dirForMyOwnedSessionFiles() + '/' + it2.fileName(); QFile::rename(it2.filePath(), newFileName); sessionFilePaths.append(newFileName); } // Remove the old directory KTempDir::removeDir(it.filePath()); } } else { // it's a file if (!idbus->isServiceRegistered(KonqMisc::decodeFilename(it.fileName()))) { // and it's abandoned: take its ownership const QString newFileName = dirForMyOwnedSessionFiles() + '/' + it.fileName(); QFile::rename(it.filePath(), newFileName); sessionFilePaths.append(newFileName); } } } return sessionFilePaths; } void KonqSessionManager::restoreSessions(const QStringList &sessionFilePathsList, bool openTabsInsideCurrentWindow, KonqMainWindow *parent) { foreach (const QString &sessionFilePath, sessionFilePathsList) { restoreSession(sessionFilePath, openTabsInsideCurrentWindow, parent); } } void KonqSessionManager::restoreSessions(const QString &sessionsDir, bool openTabsInsideCurrentWindow, KonqMainWindow *parent) { QDirIterator it(sessionsDir, QDir::Readable | QDir::Files); while (it.hasNext()) { QFileInfo fi(it.next()); restoreSession(fi.filePath(), openTabsInsideCurrentWindow, parent); } } void KonqSessionManager::restoreSession(const QString &sessionFilePath, bool openTabsInsideCurrentWindow, KonqMainWindow *parent) { if (!QFile::exists(sessionFilePath)) { return; } KConfig config(sessionFilePath, KConfig::SimpleConfig); const QList groups = windowConfigGroups(config); Q_FOREACH (const KConfigGroup &configGroup, groups) { if (!openTabsInsideCurrentWindow) { KonqViewManager::openSavedWindow(configGroup)->show(); } else { parent->viewManager()->openSavedWindow(configGroup, true); } } } static void removeDiscardedSessions(const QStringList &sessionFiles, const QStringList &discardedSessions) { if (discardedSessions.isEmpty()) { return; } Q_FOREACH (const QString &sessionFile, sessionFiles) { KConfig config(sessionFile, KConfig::SimpleConfig); QList groups = windowConfigGroups(config); for (int i = 0, count = groups.count(); i < count; ++i) { KConfigGroup &group = groups[i]; const QString rootItem = group.readEntry("RootItem", "empty"); const QString viewsKey(rootItem + QLatin1String("_Children")); QStringList views = group.readEntry(viewsKey, QStringList()); QMutableStringListIterator it(views); while (it.hasNext()) { if (discardedSessions.contains(viewIdFor(sessionFile, it.next()))) { it.remove(); } } group.writeEntry(viewsKey, views); } } } bool KonqSessionManager::askUserToRestoreAutosavedAbandonedSessions() { const QStringList sessionFilePaths = takeSessionsOwnership(); if (sessionFilePaths.isEmpty()) { return false; } disableAutosave(); int result; QStringList discardedSessionList; const QLatin1String dontAskAgainName("Restore session when konqueror didn't close correctly"); if (SessionRestoreDialog::shouldBeShown(dontAskAgainName, &result)) { SessionRestoreDialog *restoreDlg = new SessionRestoreDialog(sessionFilePaths); - result = restoreDlg->exec(); - discardedSessionList = restoreDlg->discardedSessionList(); - if (restoreDlg->isDontShowChecked()) { - SessionRestoreDialog::saveDontShow(dontAskAgainName, result); + if (restoreDlg->isEmpty()) { + result = KDialog::No; + } else { + result = restoreDlg->exec(); + discardedSessionList = restoreDlg->discardedSessionList(); + if (restoreDlg->isDontShowChecked()) { + SessionRestoreDialog::saveDontShow(dontAskAgainName, result); + } } delete restoreDlg; } switch (result) { case KDialog::Yes: // Remove the discarded session list files. removeDiscardedSessions(sessionFilePaths, discardedSessionList); restoreSessions(sessionFilePaths); enableAutosave(); return true; case KDialog::No: deleteOwnedSessions(); enableAutosave(); return false; default: // Remove the ownership of the currently owned files QDirIterator it(dirForMyOwnedSessionFiles(), QDir::Writable | QDir::Files); while (it.hasNext()) { it.next(); // remove ownership of the abandoned file QFile::rename(it.filePath(), m_autosaveDir + '/' + it.fileName()); } // Remove the owned_by directory KTempDir::removeDir(dirForMyOwnedSessionFiles()); enableAutosave(); return false; } } diff --git a/src/konqsessionmanager.h b/src/konqsessionmanager.h index 75be9b52f..efb8c444c 100644 --- a/src/konqsessionmanager.h +++ b/src/konqsessionmanager.h @@ -1,227 +1,231 @@ /* This file is part of the KDE project Copyright (C) 2008 Eduardo Robles Elvira 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KONQSESSIONMANAGER_H #define KONQSESSIONMANAGER_H #include #include #include #include #include #include #include class KonqMainWindow; +class QTreeWidget; class QTreeWidgetItem; class QSessionManager; class SessionRestoreDialog : public KDialog { Q_OBJECT public: explicit SessionRestoreDialog(const QStringList &sessionFilePaths, QWidget *parent = Q_NULLPTR); virtual ~SessionRestoreDialog(); + bool isEmpty() const; + /** * Returns the list of session discarded/unselected by the user. */ QStringList discardedSessionList() const; /** * Returns true if the don't show checkbox is checked. */ bool isDontShowChecked() const; /** * Returns true if the corresponding session restore dialog should be shown. * * @param dontShowAgainName the name that identify the session restore dialog box. * @param result if not null, it will be set to the result that was chosen the last * time the dialog box was shown. This is only useful if the restore dialog box should * be shown. */ static bool shouldBeShown(const QString &dontShowAgainName, int *result); /** * Save the fact that the session restore dialog should not be shown again. * * @param dontShowAgainName the name that identify the session restore dialog. If * empty, this method does nothing. * @param result the value (Yes or No) that should be used as the result * for the message box. */ static void saveDontShow(const QString &dontShowAgainName, int result); private Q_SLOTS: void slotClicked(bool); void slotItemChanged(QTreeWidgetItem *, int); private: + QTreeWidget *m_treeWidget; QStringList m_discardedSessionList; QHash m_checkedSessionItems; int m_sessionItemsCount; bool m_dontShowChecked; }; /** * This class is a singleton. It does some session related tasks: * - Autosave current session every X seconds * - Restore a saved session if konqueror crashed * - Restore a given session manually */ class KONQ_TESTS_EXPORT KonqSessionManager : public QObject { Q_OBJECT public: friend class KonqSessionManagerPrivate; static KonqSessionManager *self(); /** * Restore saved session(s). * * @param sessionFilePathsList list of session files to restore. * @param openTabsInsideCurrentWindow indicates if you want to open the tabs * in current window or not. False by default. * @param parent indicates in which window the tabs will be opened if * openTabsInsideCurrentWindow is set to true. Otherwise it won't be used. */ void restoreSessions(const QStringList &sessionFilePathsList, bool openTabsInsideCurrentWindow = false, KonqMainWindow *parent = Q_NULLPTR); /** * Restore saved session(s). * * @param sessionsDir directory containing the session files to * restore. * @param openTabsInsideCurrentWindow indicates if you want to open the tabs * in current window or not. False by default. * @param parent indicates in which window the tabs will be opened if * openTabsInsideCurrentWindow is set to true. Otherwise it won't be used. */ void restoreSessions(const QString &sessionsDir, bool openTabsInsideCurrentWindow = false, KonqMainWindow *parent = Q_NULLPTR); /** * Restore saved session. * @param sessionFilePath session file to restore. * @param openTabsInsideCurrentWindow indicates if you want to open the tabs * in current window or not. False by default. * @param parent indicates in which window the tabs will be opened if * openTabsInsideCurrentWindow is set to true. Otherwise it won't be used. */ void restoreSession(const QString &sessionFilePath, bool openTabsInsideCurrentWindow = false, KonqMainWindow *parent = Q_NULLPTR); /** * Disable the autosave feature. It's called when a konqueror instance is * being preloaded */ void disableAutosave(); /** * Enable the autosave feature. It's called when a konqueror instance stops * being preloaded and starts having a window showed to the user. */ void enableAutosave(); /** * Removes the owned_by directory and all its files inside (which were * referencing the owned sessions). */ void deleteOwnedSessions(); /** * Save current session in a given path (absolute path to a file) * @param mainWindow if 0, all windows will be saved, else only the given one */ void saveCurrentSessionToFile(const QString &sessionConfigPath, KonqMainWindow *mainWindow = Q_NULLPTR); /** * Returns the autosave directory */ QString autosaveDirectory() const; public Q_SLOTS: /** * Ask the user with a KPassivePopup ballon if session should be restored */ bool askUserToRestoreAutosavedAbandonedSessions(); /** * Saves current session. * This is function is called by the autosave timer, but you can call it too * if you want. It won't do anything if m_autosaveEnabled is false. */ void autoSaveSession(); /** * Restore owned sessions */ //void restoreSessions(); /** * Save current sessions of all konqueror instances (propagated via a * dbus signal). */ void saveCurrentSessions(const QString &path); private Q_SLOTS: void slotCommitData(QSessionManager &sm); private: KonqSessionManager(); ~KonqSessionManager(); /** * Creates the owned_by directory with files inside referencing the owned * sessions and returns the list of filepaths with sessions to restore. * Returns an empty list if there is nothing to restore. */ QStringList takeSessionsOwnership(); QString dirForMyOwnedSessionFiles() const { return m_autosaveDir + "/owned_by" + m_baseService; } void saveCurrentSessionToFile(KConfig *config, const QList &mainWindows = QList()); private: QTimer m_autoSaveTimer; QString m_autosaveDir; QString m_baseService; bool m_autosaveEnabled; bool m_createdOwnedByDir; KConfig *m_sessionConfig; Q_SIGNALS: // DBUS signals /** * Save current session of all konqueror running instances in a given * directory */ void saveCurrentSession(const QString &path); private Q_SLOTS:// connected to DBUS signals void slotSaveCurrentSession(const QString &path); }; #endif /* KONQSESSIONMANAGER_H */