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"
23 #include "konqmainwindow.h"
24 #include "konqsessionmanager_interface.h"
25 #include "konqsessionmanageradaptor.h"
26 #include "konqviewmanager.h"
27 #include "konqsettingsxt.h"
31 #include <kio/deletejob.h>
32 #include <kstandarddirs.h>
36 #include <kmessagebox.h>
38 #include <kio/netaccess.h>
40 #include <QPushButton>
41 #include <QtCore/QFileInfo>
43 #include <QtDBus/QtDBus>
44 #include <QtAlgorithms>
45 #include <QDirIterator>
46 #include <QtCore/QDir>
47 #include <QDBusArgument>
51 class KonqSessionManagerPrivate
54 KonqSessionManagerPrivate()
59 ~KonqSessionManagerPrivate()
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();
87 m_autoSaveTimer
.setInterval(interval
*1000);
88 connect( &m_autoSaveTimer
, SIGNAL( timeout() ), this,
89 SLOT( autoSaveSession() ) );
91 m_autosaveEnabled
= false; // so that enableAutosave works
95 KonqSessionManager::~KonqSessionManager()
99 void KonqSessionManager::disableAutosave()
101 if(!m_autosaveEnabled
)
104 m_autosaveEnabled
= false;
105 m_autoSaveTimer
.stop();
106 QString file
= KStandardDirs::locateLocal("appdata",
107 m_autoSavedSessionConfig
->name());
109 delete m_autoSavedSessionConfig
;
112 void KonqSessionManager::enableAutosave()
114 if(m_autosaveEnabled
)
117 // Create the config file for autosaving current session
118 QString filename
= "autosave/" + m_baseService
;
119 QString file
= KStandardDirs::locateLocal("appdata", filename
);
122 m_autoSavedSessionConfig
= new KConfig(filename
, KConfig::SimpleConfig
,
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());
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
)
153 bool isActive
= m_autoSaveTimer
.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
161 deleteOwnedSessions();
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())
188 foreach ( KonqMainWindow
* window
, *mainWindows
)
190 KConfigGroup
configGroup(sessionConfig
, "Window" +
191 QString::number(counter
));
192 window
->saveProperties(configGroup
);
195 KConfigGroup
configGroup(sessionConfig
, "General");
196 configGroup
.writeEntry("Number of Windows", counter
);
197 sessionConfig
->sync();
200 bool KonqSessionManager::takeSessionsOwnership()
203 // Tell to other konqueror instances that we are the one dealing with
205 QDir
dir(dirForMyOwnedSessionFiles());
206 QDir
parentDir(m_autosaveDir
);
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();
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())
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() + '/' +
255 void KonqSessionManager::restoreSessions()
257 QStringList ownedSessions
;
258 QDirIterator
it(dirForMyOwnedSessionFiles(), QDir::Writable
|QDir::Files
);
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
);
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
))
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();
308 parent
->viewManager()->openSavedWindow(configGroup
, true);
313 bool KonqSessionManager::askUserToRestoreAutosavedAbandonedSessions()
315 if(!takeSessionsOwnership())
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
:
333 case KMessageBox::No
:
334 deleteOwnedSessions();
338 // Remove the ownership of the currently owned files
339 QDirIterator
it(dirForMyOwnedSessionFiles(),
340 QDir::Writable
|QDir::Files
);
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
);
356 #include "konqsessionmanager.moc"