add more spacing
[personal-kdebase.git] / apps / konqueror / src / konqsessionmanager.cpp
bloba9ff7e0d5189cb01fda7a00b04b871a47c25aca0
1 /*
2 This file is part of the KDE project
3 Copyright (C) 2008 Eduardo Robles Elvira <edulix@gmail.com>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 #include "konqsessionmanager.h"
22 #include "konqmisc.h"
23 #include "konqmainwindow.h"
24 #include "konqsessionmanager_interface.h"
25 #include "konqsessionmanageradaptor.h"
26 #include "konqviewmanager.h"
27 #include "konqsettingsxt.h"
29 #include <kglobal.h>
30 #include <kdebug.h>
31 #include <kio/deletejob.h>
32 #include <kstandarddirs.h>
33 #include <kvbox.h>
34 #include <khbox.h>
35 #include <klocale.h>
36 #include <kmessagebox.h>
37 #include <kurl.h>
38 #include <kio/netaccess.h>
40 #include <QPushButton>
41 #include <QtCore/QFileInfo>
42 #include <QPoint>
43 #include <QtDBus/QtDBus>
44 #include <QtAlgorithms>
45 #include <QDirIterator>
46 #include <QtCore/QDir>
47 #include <QDBusArgument>
48 #include <QFile>
49 #include <QSize>
51 class KonqSessionManagerPrivate
53 public:
54 KonqSessionManagerPrivate()
55 : instance(0)
59 ~KonqSessionManagerPrivate()
61 delete instance;
64 KonqSessionManager *instance;
67 K_GLOBAL_STATIC(KonqSessionManagerPrivate, myKonqSessionManagerPrivate)
69 KonqSessionManager::KonqSessionManager()
70 : m_autosaveDir(KStandardDirs::locateLocal("appdata", "autosave"))
72 // Initialize dbus interfaces
73 new KonqSessionManagerAdaptor ( this );
75 const QString dbusPath = "/KonqSessionManager";
76 const QString dbusInterface = "org.kde.Konqueror.SessionManager";
78 QDBusConnection dbus = QDBusConnection::sessionBus();
79 dbus.registerObject( dbusPath, this );
80 m_baseService = KonqMisc::encodeFilename(dbus.baseService());
81 dbus.connect(QString(), dbusPath, dbusInterface, "saveCurrentSession", this, SLOT(slotSaveCurrentSession(QString)));
83 // Initialize the timer
84 int interval = KonqSettings::autoSaveInterval();
85 if(interval > 0)
87 m_autoSaveTimer.setInterval(interval*1000);
88 connect( &m_autoSaveTimer, SIGNAL( timeout() ), this,
89 SLOT( autoSaveSession() ) );
91 m_autosaveEnabled = false; // so that enableAutosave works
92 enableAutosave();
95 KonqSessionManager::~KonqSessionManager()
99 void KonqSessionManager::disableAutosave()
101 if(!m_autosaveEnabled)
102 return;
104 m_autosaveEnabled = false;
105 m_autoSaveTimer.stop();
106 QString file = KStandardDirs::locateLocal("appdata",
107 m_autoSavedSessionConfig->name());
108 QFile::remove(file);
109 delete m_autoSavedSessionConfig;
112 void KonqSessionManager::enableAutosave()
114 if(m_autosaveEnabled)
115 return;
117 // Create the config file for autosaving current session
118 QString filename = "autosave/" + m_baseService;
119 QString file = KStandardDirs::locateLocal("appdata", filename);
120 QFile::remove(file);
122 m_autoSavedSessionConfig = new KConfig(filename, KConfig::SimpleConfig,
123 "appdata");
124 m_autosaveEnabled = true;
125 m_autoSaveTimer.start();
128 void KonqSessionManager::deleteOwnedSessions()
130 // Not dealing with the sessions about to remove anymore
131 QDir dir(dirForMyOwnedSessionFiles());
133 if(dir.exists())
135 KIO::Job *delJob = KIO::del(KUrl(dir.path()), KIO::HideProgressInfo);
136 KIO::NetAccess::synchronousRun(delJob, NULL);
140 KonqSessionManager* KonqSessionManager::self()
142 if(!myKonqSessionManagerPrivate->instance)
143 myKonqSessionManagerPrivate->instance = new KonqSessionManager();
145 return myKonqSessionManagerPrivate->instance;
148 void KonqSessionManager::autoSaveSession()
150 if(!m_autosaveEnabled)
151 return;
153 bool isActive = m_autoSaveTimer.isActive();
154 if(isActive)
155 m_autoSaveTimer.stop();
157 saveCurrentSession(m_autoSavedSessionConfig);
159 // Now that we have saved current session it's safe to remove our owned_by
160 // directory
161 deleteOwnedSessions();
163 if(isActive)
164 m_autoSaveTimer.start();
167 void KonqSessionManager::saveCurrentSessions(const QString & path)
169 emit saveCurrentSession(path);
172 void KonqSessionManager::slotSaveCurrentSession(const QString & path)
174 QString filename = path + '/' + m_baseService;
176 KConfig sessionConfig(filename, KConfig::SimpleConfig, "appdata");
177 saveCurrentSession(&sessionConfig);
180 void KonqSessionManager::saveCurrentSession(KConfig* sessionConfig)
182 QList<KonqMainWindow*> *mainWindows = KonqMainWindow::mainWindowList();
183 unsigned int counter = 0;
185 if(!mainWindows || mainWindows->isEmpty())
186 return;
188 foreach ( KonqMainWindow* window, *mainWindows )
190 KConfigGroup configGroup(sessionConfig, "Window" +
191 QString::number(counter));
192 window->saveProperties(configGroup);
193 counter++;
195 KConfigGroup configGroup(sessionConfig, "General");
196 configGroup.writeEntry("Number of Windows", counter);
197 sessionConfig->sync();
200 bool KonqSessionManager::takeSessionsOwnership()
202 bool found = false;
203 // Tell to other konqueror instances that we are the one dealing with
204 // these sessions
205 QDir dir(dirForMyOwnedSessionFiles());
206 QDir parentDir(m_autosaveDir);
208 if(!dir.exists())
209 parentDir.mkdir("owned_by" + m_baseService);
211 QDirIterator it(m_autosaveDir, QDir::Writable|QDir::Files|QDir::Dirs|
212 QDir::NoDotAndDotDot);
214 QDBusConnectionInterface *idbus = QDBusConnection::sessionBus().interface();
216 while (it.hasNext())
218 it.next();
219 // this is the case where another konq started to restore that session,
220 // but crashed immediately. So we try to restore that session again
221 if(it.fileInfo().isDir())
223 // The remove() removes the "owned_by" part
224 if(!idbus->isServiceRegistered(
225 KonqMisc::decodeFilename(it.fileName().remove(0, 8))))
227 QDirIterator it2(it.filePath(), QDir::Writable|QDir::Files);
228 while (it2.hasNext())
230 found = true;
231 it2.next();
232 // take ownership of the abandoned file
233 QFile::rename(it2.filePath(), dirForMyOwnedSessionFiles() +
234 '/' + it2.fileName());
236 // Remove the old directory
237 KIO::Job *delJob = KIO::del(KUrl(it.filePath()), KIO::HideProgressInfo);
238 KIO::NetAccess::synchronousRun(delJob, NULL);
240 } else { // it's a file
241 if(!idbus->isServiceRegistered(KonqMisc::decodeFilename(it.fileName())))
243 // and it's abandoned: take its ownership
244 QFile::rename(it.filePath(), dirForMyOwnedSessionFiles() + '/' +
245 it.fileName());
246 found = true;
251 return found;
255 void KonqSessionManager::restoreSessions()
257 QStringList ownedSessions;
258 QDirIterator it(dirForMyOwnedSessionFiles(), QDir::Writable|QDir::Files);
260 while (it.hasNext())
262 it.next();
263 ownedSessions.append(it.filePath());
265 restoreSessions(ownedSessions);
268 void KonqSessionManager::restoreSessions(const QStringList &sessionFilePathsList,
269 bool openTabsInsideCurrentWindow, KonqMainWindow *parent)
271 foreach ( const QString& sessionFilePath, sessionFilePathsList )
273 restoreSession(sessionFilePath, openTabsInsideCurrentWindow, parent);
277 void KonqSessionManager::restoreSessions(const QString &sessionsDir, bool
278 openTabsInsideCurrentWindow, KonqMainWindow *parent)
280 QDirIterator it(sessionsDir, QDir::Readable|QDir::Files);
282 while (it.hasNext())
284 QFileInfo fi(it.next());
285 restoreSession(fi.filePath(), openTabsInsideCurrentWindow, parent);
289 void KonqSessionManager::restoreSession(const QString &sessionFilePath, bool
290 openTabsInsideCurrentWindow, KonqMainWindow *parent)
292 QString file(sessionFilePath);
293 if(!QFile::exists(file))
294 return;
296 KConfig config(sessionFilePath, KConfig::SimpleConfig);
298 KConfigGroup generalGroup(&config, "General");
299 int size = generalGroup.readEntry("Number of Windows", 0);
301 for(int i = 0; i < size; i++)
303 KConfigGroup configGroup(&config, "Window" + QString::number(i));
305 if(!openTabsInsideCurrentWindow)
306 KonqViewManager::openSavedWindow(configGroup)->show();
307 else
308 parent->viewManager()->openSavedWindow(configGroup, true);
313 bool KonqSessionManager::askUserToRestoreAutosavedAbandonedSessions()
315 if(!takeSessionsOwnership())
316 return false;
318 disableAutosave();
320 switch(KMessageBox::questionYesNoCancel(0,
321 i18n("Konqueror didn't close correctly. Would you like to restore session?"),
322 i18n("Restore Session?"),
323 KGuiItem(i18n("Restore Session"), "window-new"),
324 KGuiItem(i18n("Do Not Restore"), "dialog-close"),
325 KGuiItem(i18n("Ask Me Later"), "chronometer"),
326 "Restore session when konqueror didn't close correctly"
329 case KMessageBox::Yes:
330 restoreSessions();
331 enableAutosave();
332 return true;
333 case KMessageBox::No:
334 deleteOwnedSessions();
335 enableAutosave();
336 return false;
337 default:
338 // Remove the ownership of the currently owned files
339 QDirIterator it(dirForMyOwnedSessionFiles(),
340 QDir::Writable|QDir::Files);
342 while (it.hasNext())
344 it.next();
345 // remove ownership of the abandoned file
346 QFile::rename(it.filePath(), m_autosaveDir + '/' + it.fileName());
348 // Remove the owned_by directory
349 KIO::Job *delJob = KIO::del(KUrl(dirForMyOwnedSessionFiles()), KIO::HideProgressInfo);
350 KIO::NetAccess::synchronousRun(delJob, NULL);
351 enableAutosave();
352 return false;
356 #include "konqsessionmanager.moc"