Commit d022a7fa authored by David Faure's avatar David Faure

Move KonqClosedWindowsManager to its own file

CCMAIL: edulix@gmail.com

svn path=/trunk/KDE/kdebase/apps/; revision=857579
parent 4a2b7da9
......@@ -64,6 +64,7 @@ set(konqueror_KDEINIT_SRCS
KonqViewAdaptor.cpp
konqproxystyle.cpp
konqundomanager.cpp
konqclosedwindowsmanager.cpp
konqsessionmanager.cpp
konqcloseditem.cpp
)
......@@ -75,8 +76,8 @@ kde4_add_ui_files(konqueror_KDEINIT_SRCS konqnewsessiondlg_base.ui)
qt4_add_dbus_interface(konqueror_KDEINIT_SRCS org.kde.Konqueror.Main.xml konqueror_interface)
qt4_add_dbus_interface(konqueror_KDEINIT_SRCS ${KDE4_DBUS_INTERFACES_DIR}/org.kde.kded.xml kded_interface)
qt4_add_dbus_adaptor(konqueror_KDEINIT_SRCS org.kde.Konqueror.UndoManager.xml konqundomanager.h KonqClosedWindowsManager konqundomanageradaptor KonqClosedWindowsManagerAdaptor)
qt4_add_dbus_interface(konqueror_KDEINIT_SRCS org.kde.Konqueror.UndoManager.xml konqundomanager_interface)
qt4_add_dbus_adaptor(konqueror_KDEINIT_SRCS org.kde.Konqueror.UndoManager.xml konqclosedwindowsmanager.h KonqClosedWindowsManager konqclosedwindowsmanageradaptor KonqClosedWindowsManagerAdaptor)
qt4_add_dbus_interface(konqueror_KDEINIT_SRCS org.kde.Konqueror.UndoManager.xml konqclosedwindowsmanager_interface)
qt4_add_dbus_adaptor(konqueror_KDEINIT_SRCS org.kde.Konqueror.SessionManager.xml konqsessionmanager.h KonqSessionManager konqsessionmanageradaptor KonqSessionManagerAdaptor)
qt4_add_dbus_interface(konqueror_KDEINIT_SRCS org.kde.Konqueror.SessionManager.xml konqsessionmanager_interface)
......
......@@ -19,7 +19,7 @@
*/
#include "konqcloseditem.h"
#include "konqundomanager.h"
#include "konqclosedwindowsmanager.h"
#include <QFile>
#include <QFont>
#include <QFontMetrics>
......@@ -42,7 +42,7 @@ public:
{
KIconEffect::deSaturate(image, 0.60f);
}
QImage image;
};
......@@ -92,7 +92,7 @@ QPixmap KonqClosedWindowItem::icon() const
QImage overlayImg = s_lightIconImage->image.copy();
int oldWidth = overlayImg.width();
QString countStr = QString::number( m_numTabs );
QFont f = KGlobalSettings::generalFont();
f.setBold(true);
......@@ -111,7 +111,7 @@ QPixmap KonqClosedWindowItem::icon() const
KColorScheme scheme(QPalette::Active, KColorScheme::Window);
p.setPen(scheme.foreground(KColorScheme::LinkText).color());
p.drawText(overlayImg.rect(), Qt::AlignCenter, countStr);
return QPixmap::fromImage(overlayImg);
}
......@@ -163,7 +163,7 @@ KConfigGroup& KonqClosedRemoteWindowItem::configGroup()
bool KonqClosedRemoteWindowItem::equalsTo(const QString& groupName,
const QString& configFileName) const
{
{
return (m_remoteGroupName == groupName &&
m_remoteConfigFileName == configFileName);
}
/* This file is part of the KDE project
Copyright 2007 David Faure <faure@kde.org>
Copyright 2007 Eduardo Robles Elvira <edulix@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 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 "konqclosedwindowsmanager.h"
#include "konqsettingsxt.h"
#include "konqmisc.h"
#include "konqcloseditem.h"
#include "konqclosedwindowsmanageradaptor.h"
#include "konqclosedwindowsmanager_interface.h"
#include <kio/fileundomanager.h>
#include <QDirIterator>
#include <QMetaType>
#include <QtDBus/QtDBus>
#include <kglobal.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kconfig.h>
#include <unistd.h> // getpid
Q_DECLARE_METATYPE(QList<QVariant>)
class KonqClosedWindowsManagerPrivate
{
public:
KonqClosedWindowsManager instance;
int m_maxNumClosedItems;
};
K_GLOBAL_STATIC(KonqClosedWindowsManagerPrivate, myKonqClosedWindowsManagerPrivate)
KonqClosedWindowsManager::KonqClosedWindowsManager()
{
//qDBusRegisterMetaType<QList<QVariant> >();
new KonqClosedWindowsManagerAdaptor ( this );
const QString dbusPath = "/KonqUndoManager";
const QString dbusInterface = "org.kde.Konqueror.UndoManager";
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerObject( dbusPath, this );
dbus.connect(QString(), dbusPath, dbusInterface, "notifyClosedWindowItem", this, SLOT(slotNotifyClosedWindowItem(QString,int,QString,QString,QDBusMessage)));
dbus.connect(QString(), dbusPath, dbusInterface, "notifyRemove", this, SLOT(slotNotifyRemove(QString,QString,QDBusMessage)));
QString filename = "closeditems/" + KonqMisc::encodeFilename(dbus.baseService());
QString file = KStandardDirs::locateLocal("tmp", filename);
QFile::remove(file);
KConfigGroup configGroup(KGlobal::config(), "Undo");
m_numUndoClosedItems = configGroup.readEntry("Number of Closed Windows", 0);
m_konqClosedItemsConfig = 0L;
m_blockClosedItems = false;
}
KonqClosedWindowsManager::~KonqClosedWindowsManager()
{
// Do some file cleaning
removeClosedItemsConfigFiles();
delete m_konqClosedItemsConfig;
}
KConfig* KonqClosedWindowsManager::config()
{
readConfig();
return m_konqClosedItemsConfig;
}
KonqClosedWindowsManager *KonqClosedWindowsManager::self()
{
return &myKonqClosedWindowsManagerPrivate->instance;
}
void KonqClosedWindowsManager::addClosedWindowItem(KonqUndoManager
*real_sender, KonqClosedWindowItem *closedWindowItem, bool propagate)
{
readConfig();
// If we are off the limit, remove the last closed window item
if(m_closedWindowItemList.size() >=
KonqSettings::maxNumClosedItems())
{
KonqClosedWindowItem* last = m_closedWindowItemList.last();
emit removeWindowInOtherInstances(0L, last);
emitNotifyRemove(last);
m_closedWindowItemList.removeLast();
delete last;
}
m_closedWindowItemList.prepend(closedWindowItem);
if(!m_blockClosedItems)
{
m_numUndoClosedItems++;
emit addWindowInOtherInstances(real_sender, closedWindowItem);
}
if(propagate)
{
emitNotifyClosedWindowItem(closedWindowItem);
// if it needs to be propagated means that it's a local window and thus
// we need to call to saveConfig() to keep updated the kconfig file, so
// that new konqueror instances can read it correctly updated.
saveConfig();
}
}
void KonqClosedWindowsManager::removeClosedWindowItem(KonqUndoManager
*real_sender, const KonqClosedWindowItem *closedWindowItem, bool propagate)
{
readConfig();
QList<KonqClosedWindowItem *>::iterator it = qFind(m_closedWindowItemList.begin(),
m_closedWindowItemList.end(), closedWindowItem);
// If the item was found, remove it from the list
if(it != m_closedWindowItemList.end()) {
m_closedWindowItemList.erase(it);
m_numUndoClosedItems--;
}
emit removeWindowInOtherInstances(real_sender, closedWindowItem);
if(propagate)
emitNotifyRemove(closedWindowItem);
}
const QList<KonqClosedWindowItem *>& KonqClosedWindowsManager::closedWindowItemList()
{
readConfig();
return m_closedWindowItemList;
}
void KonqClosedWindowsManager::readSettings()
{
readConfig();
}
static QString dbusService()
{
return QDBusConnection::sessionBus().baseService();
}
/**
* Returns whether the DBUS call we are handling was a call from us self
*/
bool isSenderOfSignal( const QDBusMessage& msg )
{
return dbusService() == msg.service();
}
bool isSenderOfSignal( const QString& service )
{
return dbusService() == service;
}
void KonqClosedWindowsManager::emitNotifyClosedWindowItem(
const KonqClosedWindowItem *closedWindowItem)
{
emit notifyClosedWindowItem( closedWindowItem->title(),
closedWindowItem->numTabs(),
closedWindowItem->configGroup().config()->name(),
closedWindowItem->configGroup().name() );
}
void KonqClosedWindowsManager::emitNotifyRemove(
const KonqClosedWindowItem *closedWindowItem)
{
const KonqClosedRemoteWindowItem* closedRemoteWindowItem =
dynamic_cast<const KonqClosedRemoteWindowItem *>(closedWindowItem);
// Here we do this because there's no need to call to configGroup() if it's
// a remote window item, and it would be error prone to be so, because
// it could give us a null pointer and konqueror would crash
if(closedRemoteWindowItem)
emit notifyRemove( closedRemoteWindowItem->remoteConfigFileName(),
closedRemoteWindowItem->remoteGroupName() );
else
emit notifyRemove( closedWindowItem->configGroup().config()->name(),
closedWindowItem->configGroup().name() );
}
void KonqClosedWindowsManager::slotNotifyClosedWindowItem(
const QString& title, const int& numTabs, const QString& configFileName,
const QString& configGroup, const QString& service )
{
if ( isSenderOfSignal( service ) )
return;
// Create a new ClosedWindowItem and add it to the list
KonqClosedWindowItem* closedWindowItem = new KonqClosedRemoteWindowItem(
title, configGroup, configFileName,
KIO::FileUndoManager::self()->newCommandSerialNumber(), numTabs,
service);
// Add it to all the windows but don't propogate over dbus,
// as it already comes from dbus)
addClosedWindowItem(0L, closedWindowItem, false);
}
void KonqClosedWindowsManager::slotNotifyClosedWindowItem(
const QString& title, const int& numTabs, const QString& configFileName,
const QString& configGroup, const QDBusMessage& msg )
{
slotNotifyClosedWindowItem(title, numTabs, configFileName, configGroup,
msg.service() );
}
void KonqClosedWindowsManager::slotNotifyRemove(
const QString& configFileName, const QString& configGroup,
const QDBusMessage& msg )
{
if ( isSenderOfSignal( msg ) )
return;
// Find the window item. It can be either remote or local
KonqClosedWindowItem* closedWindowItem =
findClosedRemoteWindowItem(configFileName, configGroup);
if(!closedWindowItem)
{
closedWindowItem = findClosedLocalWindowItem(configFileName, configGroup);
if(!closedWindowItem)
return;
}
// Remove it in all the windows but don't propogate over dbus,
// as it already comes from dbus)
removeClosedWindowItem(0L, closedWindowItem, false);
}
KonqClosedRemoteWindowItem* KonqClosedWindowsManager::findClosedRemoteWindowItem(
const QString& configFileName,
const QString& configGroup)
{
readConfig();
KonqClosedRemoteWindowItem* closedRemoteWindowItem = 0L;
for (QList<KonqClosedWindowItem *>::const_iterator it = m_closedWindowItemList.begin();
it != m_closedWindowItemList.end(); ++it)
{
closedRemoteWindowItem = dynamic_cast<KonqClosedRemoteWindowItem *>(*it);
if(closedRemoteWindowItem &&
closedRemoteWindowItem->equalsTo(configFileName, configGroup))
return closedRemoteWindowItem;
}
return closedRemoteWindowItem;
}
KonqClosedWindowItem* KonqClosedWindowsManager::findClosedLocalWindowItem(
const QString& configFileName,
const QString& configGroup)
{
readConfig();
KonqClosedWindowItem* closedWindowItem = 0L;
for (QList<KonqClosedWindowItem *>::const_iterator it = m_closedWindowItemList.begin();
it != m_closedWindowItemList.end(); ++it)
{
closedWindowItem = *it;
KonqClosedRemoteWindowItem* closedRemoteWindowItem =
dynamic_cast<KonqClosedRemoteWindowItem *>(closedWindowItem);
if(!closedRemoteWindowItem && closedWindowItem &&
closedWindowItem->configGroup().config()->name() == configFileName &&
closedWindowItem->configGroup().name() == configGroup)
return closedWindowItem;
}
return closedWindowItem;
}
void KonqClosedWindowsManager::removeClosedItemsConfigFiles()
{
QString dir = KStandardDirs::locateLocal("tmp", "closeditems/");
QDBusConnectionInterface *idbus = QDBusConnection::sessionBus().interface();
QDirIterator it(dir, QDir::Writable|QDir::Files);
while (it.hasNext())
{
// Only remove the files for those konqueror instances not running anymore
QString filename = it.next();
if(!idbus->isServiceRegistered(KonqMisc::decodeFilename(it.fileName())))
QFile::remove(filename);
}
}
void KonqClosedWindowsManager::saveConfig()
{
readConfig();
// Create / overwrite the saved closed windows list
QString filename = "closeditems_saved";
QString file = KStandardDirs::locateLocal("appdata", filename);
QFile::remove(file);
KConfig *config = new KConfig(filename, KConfig::SimpleConfig, "appdata");
// Populate the config file
KonqClosedWindowItem* closedWindowItem = 0L;
uint counter = m_closedWindowItemList.size()-1;
for (QList<KonqClosedWindowItem *>::const_iterator it = m_closedWindowItemList.begin();
it != m_closedWindowItemList.end(); ++it, --counter)
{
closedWindowItem = *it;
KConfigGroup configGroup(config, "Closed_Window" + QString::number(counter));
configGroup.writeEntry("title", closedWindowItem->title());
configGroup.writeEntry("numTabs", closedWindowItem->numTabs());
closedWindowItem->configGroup().copyTo(&configGroup);
}
KConfigGroup configGroup(KGlobal::config(), "Undo");
configGroup.writeEntry("Number of Closed Windows", m_closedWindowItemList.size());
configGroup.sync();
delete config;
}
void KonqClosedWindowsManager ::readConfig()
{
if(m_konqClosedItemsConfig)
return;
QString filename = "closeditems_saved";
QString file = KStandardDirs::locateLocal("appdata", filename);
m_konqClosedItemsConfig = new KConfig(file, KConfig::SimpleConfig);
// If the config file doesn't exists, there's nothing to read
if(!QFile::exists(file))
return;
m_blockClosedItems = true;
for(int i = 0; i < m_numUndoClosedItems; i++)
{
// For each item, create a new ClosedWindowItem
KConfigGroup configGroup(m_konqClosedItemsConfig, "Closed_Window" +
QString::number(i));
// The number of closed items was not correctly set, fix it and save the
// correct number.
if(!configGroup.exists())
{
m_numUndoClosedItems = i;
KConfigGroup configGroup(KGlobal::config(), "Undo");
configGroup.writeEntry("Number of Closed Windows",
m_closedWindowItemList.size());
configGroup.sync();
break;
}
QString title = configGroup.readEntry("title", i18n("no name"));
int numTabs = configGroup.readEntry("numTabs", 0);
KonqClosedWindowItem* closedWindowItem = new KonqClosedWindowItem(
title, KIO::FileUndoManager::self()->newCommandSerialNumber(),
numTabs);
configGroup.copyTo(&closedWindowItem->configGroup());
configGroup.writeEntry("foo", 0);
closedWindowItem->configGroup().config()->sync();
// Add the item only to this window
addClosedWindowItem(0L, closedWindowItem, false);
}
m_blockClosedItems = false;
}
bool KonqClosedWindowsManager::undoAvailable() const
{
return m_numUndoClosedItems > 0;
}
/* This file is part of the KDE project
Copyright 2007 David Faure <faure@kde.org>
Copyright 2007 Eduardo Robles Elvira <edulix@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 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 KONQCLOSEDWINDOWSMANAGER_H
#define KONQCLOSEDWINDOWSMANAGER_H
#include "konqprivate_export.h"
#include <QList>
#include <QObject>
class KonqClosedRemoteWindowItem;
class KonqUndoManager;
class KConfig;
class QDBusMessage;
class KonqClosedWindowItem;
class QString;
class KonqClosedWindowsManagerPrivate;
/**
* Provides a shared singleton for all Konq window instances.
* This class is a singleton, use self() to access its only instance.
*
* - it synchronizes the closed window list with other
* Konqueror instances via DBUS.
*
*/
class KONQ_TESTS_EXPORT KonqClosedWindowsManager : public QObject
{
Q_OBJECT
public:
friend class KonqClosedWindowsManagerPrivate;
static KonqClosedWindowsManager *self();
const QList<KonqClosedWindowItem *>& closedWindowItemList();
/**
* When a window is closed it's added with this function to
* m_closedWindowItemList.
*/
void addClosedWindowItem(KonqUndoManager *real_sender, KonqClosedWindowItem
*closedWindowItem, bool propagate = true);
void removeClosedWindowItem(KonqUndoManager *real_sender, const
KonqClosedWindowItem *closedWindowItem, bool propagate = true);
KConfig* config();
/**
* Called by the KonqUndoManager when a local window is being closed.
* Saves the closed windows list to disk inside a config file.
*/
void saveConfig();
bool undoAvailable() const;
public Q_SLOTS:
void readSettings();
/**
* Reads the list of closed window from the configuration file if it couldn't
* be retrieved from running konqueror windows and if it hasn't been read
* already. By default the closeditems_list file is not read, so each
* function which needs that file to be read first must call this function
* to ensure the closeditems list is filled.
*/
void readConfig();
Q_SIGNALS:
/**
* Notifies the addition the closed window list in all the konqueror windows of
* this konqueror instance.
*/
void addWindowInOtherInstances(KonqUndoManager *real_sender,
KonqClosedWindowItem *closedWindowItem);
/**
* Notifies the removal the closed window list in all the konqueror windows of
* this konqueror instance.
*/
void removeWindowInOtherInstances(KonqUndoManager *real_sender, const
KonqClosedWindowItem *closedWindowItem);
private:
KonqClosedWindowsManager();
virtual ~KonqClosedWindowsManager();
KonqClosedRemoteWindowItem* findClosedRemoteWindowItem(const QString& configFileName,
const QString& configGroup);
KonqClosedWindowItem* findClosedLocalWindowItem(const QString& configFileName,
const QString& configGroup);
/**
* This function removes all the closed items temporary files.
*/
void removeClosedItemsConfigFiles();
private:
QList<KonqClosedWindowItem *> m_closedWindowItemList;
int m_numUndoClosedItems;
KConfig *m_konqClosedItemsConfig;
int m_maxNumClosedItems;
/**
* This bool var is used internally to allow delayed initialization of the
* closed items list. When active, this flag prevents addClosedWindowItem()
* from emiting addWindowInOtherInstances() as the windows are already
* being dealt with inside KonqUndoManager::populate().
*/
bool m_blockClosedItems;
Q_SIGNALS: // DBUS signals
/**
* Every konqueror instance broadcasts new closed windows to other
* konqueror instances.
*/
void notifyClosedWindowItem( const QString& title, const int& numTabs,
const QString& configFileName, const QString& configGroup );
/**
* Every konqueror instance broadcasts removed closed windows to other
* konqueror instances.
*/
void notifyRemove( const QString& configFileName,
const QString& configGroup );
private Q_SLOTS:// connected to DBUS signals
void slotNotifyClosedWindowItem( const QString& title, const int& numTabs,
const QString& configFileName, const QString& configGroup,
const QString& service );
void slotNotifyClosedWindowItem( const QString& title, const int& numTabs,
const QString& configFileName, const QString& configGroup,
const QDBusMessage& msg );
void slotNotifyRemove( const QString& configFileName,
const QString& configGroup, const QDBusMessage& msg );
private:
void emitNotifyClosedWindowItem(const KonqClosedWindowItem *closedWindowItem);
void emitNotifyRemove(const KonqClosedWindowItem *closedWindowItem);
};