rendered paste bodyIndex: src/konqcloseditem.cpp
===================================================================
--- src/konqcloseditem.cpp (revisión: 794475)
+++ src/konqcloseditem.cpp (copia de trabajo)
@@ -19,6 +19,7 @@
*/
#include "konqcloseditem.h"
+#include "konqundomanager.h"
#include <QFile>
#include <QFont>
#include <QFontMetrics>
@@ -34,27 +35,6 @@
#include <kstandarddirs.h>
#include <unistd.h>
-class KConfigNew
-{
-public:
- KConfigNew()
- {
- filename = "closeditems/closeditems_" + QString::number(getpid());
- QString file = KStandardDirs::locateLocal("appdata", filename);
- if(QFile::exists(file))
- QFile::remove(file);
-
- config = new KConfig(filename, KConfig::SimpleConfig, "appdata");
- kDebug();
- }
- ~KConfigNew() {
- QFile::remove(KStandardDirs::locateLocal("appdata", filename));
- delete config;
- }
- KConfig *config;
- QString filename;
-};
-
class KonqIcon {
public:
KonqIcon()
@@ -66,11 +46,10 @@
QImage image;
};
-K_GLOBAL_STATIC(KConfigNew, s_config)
K_GLOBAL_STATIC(KonqIcon, s_lightIconImage)
KonqClosedItem::KonqClosedItem(const QString& title, const QString& group, quint64 serialNumber)
- : m_title(title), m_configGroup(s_config->config, group), m_serialNumber(serialNumber)
+ : m_title(title), m_configGroup(KonqClosedWindowsManager::self()->config(), group), m_serialNumber(serialNumber)
{
}
@@ -92,7 +71,7 @@
kDebug(1202) << "deleted group" << m_configGroup.name();
}
-QPixmap KonqClosedTabItem::icon() {
+QPixmap KonqClosedTabItem::icon() const {
return KonqPixmapProvider::self()->pixmapFor(m_url);
}
@@ -104,11 +83,12 @@
KonqClosedWindowItem::~KonqClosedWindowItem()
{
- m_configGroup.deleteGroup();
- kDebug(1202) << "deleted group" << m_configGroup.name();
+// Do this manually when needed:
+// m_configGroup.deleteGroup();
}
-QPixmap KonqClosedWindowItem::icon() {
+QPixmap KonqClosedWindowItem::icon() const
+{
QImage overlayImg = s_lightIconImage->image.copy();
int oldWidth = overlayImg.width();
QString countStr = QString::number( m_numTabs );
@@ -134,3 +114,57 @@
return QPixmap::fromImage(overlayImg);
}
+
+int KonqClosedWindowItem::numTabs() const
+{
+ return m_numTabs;
+}
+
+KonqClosedRemoteWindowItem::KonqClosedRemoteWindowItem(const QString& title,
+ const QString& groupName, const QString& configFileName, quint64 serialNumber,
+ int numTabs, const QString& dbusService)
+ : KonqClosedWindowItem(title, serialNumber, numTabs),
+ m_remoteGroupName(groupName), m_remoteConfigFileName(configFileName),
+ m_dbusService(dbusService), m_remoteConfigGroup(0L), m_remoteConfig(0L)
+{
+ kDebug();
+}
+
+KonqClosedRemoteWindowItem::~KonqClosedRemoteWindowItem()
+{
+ delete m_remoteConfigGroup;
+ delete m_remoteConfig;
+}
+
+void KonqClosedRemoteWindowItem::readConfig()
+{
+ // only do this once
+ if(m_remoteConfig || m_remoteConfigGroup)
+ return;
+
+ m_remoteConfig = new KConfig(
+ KStandardDirs::locateLocal("appdata", m_remoteConfigFileName),
+ KConfig::SimpleConfig, "appdata");
+ m_remoteConfigGroup = new KConfigGroup(m_remoteConfig, m_remoteGroupName);
+ kDebug();
+}
+
+const KConfigGroup& KonqClosedRemoteWindowItem::configGroup() const
+{
+ KonqClosedRemoteWindowItem *nonConstThis = const_cast<KonqClosedRemoteWindowItem *>(this);
+ nonConstThis->readConfig();
+ return *m_remoteConfigGroup;
+}
+
+KConfigGroup& KonqClosedRemoteWindowItem::configGroup()
+{
+ readConfig();
+ return *m_remoteConfigGroup;
+}
+
+bool KonqClosedRemoteWindowItem::equalsTo(const QString& groupName,
+ const QString& configFileName) const
+{
+ return (m_remoteGroupName == groupName &&
+ m_remoteConfigFileName == configFileName);
+}
Index: src/konqviewmanager.cpp
===================================================================
--- src/konqviewmanager.cpp (revisión: 794475)
+++ src/konqviewmanager.cpp (copia de trabajo)
@@ -358,9 +358,11 @@
}
mainWindow->viewManager()->loadRootItem( closedWindowItem.configGroup(), mainWindow->viewManager()->tabContainer(), KUrl(), true, KUrl() );
+ // read window settings
+ mainWindow->applyMainWindowSettings( KConfigGroup( KGlobal::config(), "KonqMainWindow" ), true );
+ mainWindow->applyMainWindowSettings( KConfigGroup( & closedWindowItem.configGroup(), "Main Window Settings" ), true );
mainWindow->activateChild();
mainWindow->show();
-
kDebug(1202) << "done";
}
Index: src/org.kde.Konqueror.UndoManager.xml
===================================================================
--- src/org.kde.Konqueror.UndoManager.xml (revisión: 0)
+++ src/org.kde.Konqueror.UndoManager.xml (revisión: 0)
@@ -0,0 +1,23 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.kde.Konqueror.UndoManager">
+ <signal name="notifyClosedWindowItem">
+ <arg name="title" type="s" direction="out"/>
+ <arg name="numTabs" type="i" direction="out"/>
+ <arg name="configFileName" type="s" direction="out"/>
+ <arg name="configGroup" type="s" direction="out"/>
+ </signal>
+ <signal name="notifyRemove">
+ <arg name="configFileName" type="s" direction="out"/>
+ <arg name="configGroup" type="s" direction="out"/>
+ </signal>
+ <signal name="requestLocalClosedWindowItems">
+ </signal>
+ <method name="localClosedWindowItems">
+ <arg name="windowItems" type="av" direction="in"/>
+ <arg name="service" type="s" direction="in"/>
+ </method>
+ <method name="pong">
+ </method>
+ </interface>
+</node>
Index: src/konqmainwindow.cpp
===================================================================
--- src/konqmainwindow.cpp (revisión: 794475)
+++ src/konqmainwindow.cpp (copia de trabajo)
@@ -2895,7 +2895,7 @@
QMenu* popup = m_paClosedItems->menu();
// Clear the menu and fill it with a maximum of s_closedTabsListLength number of urls
popup->clear();
- QAction* clearAction = popup->addAction( i18n("Empty Closed Tabs History") );
+ QAction* clearAction = popup->addAction( i18n("Empty Closed Items History") );
connect(clearAction, SIGNAL(triggered()), m_undoManager, SLOT(clearClosedItemsList()));
popup->insertSeparator((QAction*)0);
@@ -4994,10 +4994,7 @@
// save size to have something to restore if the profile does not contain size
saveWindowSize();
- // Save the window tabs so that we can restore it later, but only if there
- // are other windows opened
- if(s_konqMainWindowInstancesCount > 1)
- addClosedWindowToUndoList();
+ addClosedWindowToUndoList();
hide();
qApp->flush();
@@ -5040,7 +5037,11 @@
closedWindowItem->configGroup().writeEntry( "Height", height() );
closedWindowItem->configGroup().writeEntry( "FullScreen", fullScreenMode() );
tabContainer->saveConfig( closedWindowItem->configGroup(), prefix, flags, 0L, 0, 1);
-
+ // Save window settings
+ KConfigGroup cfg( &closedWindowItem->configGroup(), "Main Window Settings" );
+ saveMainWindowSettings( cfg );
+ closedWindowItem->configGroup().sync();
+
// 3. Finally add the KonqClosedWindowItem to the undo list
m_paClosedItems->setEnabled(true);
m_undoManager->addClosedWindowItem( closedWindowItem );
Index: src/CMakeLists.txt
===================================================================
--- src/CMakeLists.txt (revisión: 794475)
+++ src/CMakeLists.txt (copia de trabajo)
@@ -69,6 +69,9 @@
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)
+kde4_add_kdeinit_executable(konqueror ${konqueror_KDEINIT_SRCS} konqmain.cpp)
kde4_add_app_icon(konqueror_KDEINIT_SRCS "${KDE4_ICON_INSTALL_DIR}/oxygen/*/apps/konqueror.png")
Index: src/konqundomanager.h
===================================================================
--- src/konqundomanager.h (revisión: 794475)
+++ src/konqundomanager.h (copia de trabajo)
@@ -21,12 +21,16 @@
#ifndef KONQUNDOMANAGER_H
#define KONQUNDOMANAGER_H
-#include "konqprivate_export.h"
-
#include <QObject>
+#include <QString>
+#include <QList>
+#include <kconfig.h>
#include "konqcloseditem.h"
+#include "konqundomanager_interface.h"
class QAction;
-class KonqUndoManagerCommunicatorPrivate;
+class KonqClosedWindowsManagerPrivate;
+class QDBusMessage;
+
/**
* Note that there is one KonqUndoManager per mainwindow.
* It integrates KonqFileUndoManager (undoing file operations)
@@ -54,7 +58,7 @@
public Q_SLOTS:
void undo();
- void clearClosedItemsList();
+ void clearClosedItemsList(bool onlyInthisWindow = false);
void undoLastClosedItem();
/**
* Opens in a new tab/window the item the user selected from the closed tabs
@@ -102,31 +106,157 @@
/**
* 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.
+ *
+ * - When a konqueror instance is closed, the closed window list is written
+ * to disk so that the undo closed windows list can be retrieved even when
+ * no other konqueror instance is running.
*/
-class KONQ_TESTS_EXPORT KonqUndoManagerCommunicator : public QObject
+class KONQ_TESTS_EXPORT KonqClosedWindowsManager : public QObject
{
Q_OBJECT
public:
- friend class KonqUndoManagerCommunicatorPrivate;
- static KonqUndoManagerCommunicator *self();
+ friend class KonqClosedWindowsManagerPrivate;
+
+ static KonqClosedWindowsManager *self();
+
const QList<KonqClosedWindowItem *>& closedWindowItemList();
+
void addClosedWindowItem(KonqUndoManager *real_sender, KonqClosedWindowItem
- *closedWindowItem);
+ *closedWindowItem, bool propagate = true);
+
void removeClosedWindowItem(KonqUndoManager *real_sender, const
- KonqClosedWindowItem *closedWindowItem);
+
+ KonqClosedWindowItem *closedWindowItem, bool propagate = true);
+
void applySettings();
+
int maxNumClosedItems();
+
void setMaxNumClosedItems(int max);
+
+ KConfig* config();
+
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
+ */
+ 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);
+ KonqClosedWindowItem *closedWindowItem);
+
private:
- KonqUndoManagerCommunicator();
- virtual ~KonqUndoManagerCommunicator();
+ KonqClosedWindowsManager();
+
+ virtual ~KonqClosedWindowsManager();
+
+ /**
+ * Called by readSettings(), which is called by a singleShot timer inside
+ * the constructor. Fills the closed window list with items from other
+ * konqueror instances, being the list retrieved via DBUS using the method
+ * localClosedWindowItems();
+ *
+ * It also sets a timer so that if no other konqueror instance pings back in
+ * X miliseconds, then the closed window list is read from disk.
+ */
+ void populate();
+
+ /**
+ * Called by the destructor. Saves the closed windows list to disk inside a
+ * config file
+ */
+ void saveConfig();
+
+ KonqClosedRemoteWindowItem* findClosedRemoteWindowItem(const QString& configFileName,
+ const QString& configGroup);
+
+ KonqClosedWindowItem* findClosedLocalWindowItem(const QString& configFileName,
+ const QString& configGroup);
+
+ /**
+ * This function removes all the files in appdata/closeditem/. Thus, it's
+ * used to clean the config files inside that directory.
+ */
+ void removeClosedItemsConfigFiles();
+private:
+ QList<KonqClosedWindowItem *> m_closedWindowItemList;
+ KConfig *m_konqClosedItemsConfig;
+ int m_maxNumClosedItems;
+ bool m_amIalone;
+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 );
+
+ /**
+ * Ask over D-BUS to all running konqueror instances to return their list
+ * of local closed window items.
+ */
+ void requestLocalClosedWindowItems();
+public Q_SLOTS: // DBUS methods
+ /**
+ * This is the answer call when a konqueror instance receives a call from
+ * requestLocalClosedWindowItems().
+ */
+ void localClosedWindowItems(const QList<QVariant>& windowItems,
+ const QString& dbusService);
+
+ /**
+ * This signal is received from other konqueror instances in order to let
+ * us know that there are other konqueror instances from which we can
+ * retrieve the list of closed window items, so that we don't need to read
+ * them from disk.
+ */
+ void pong();
+
+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 );
+
+ void slotRequestLocalClosedWindowItems( const QDBusMessage& msg );
+
+private:
+ void emitNotifyClosedWindowItem(const KonqClosedWindowItem *closedWindowItem);
+
+ void emitNotifyRemove(const KonqClosedWindowItem *closedWindowItem);
+
+ void emitPong(const QString & service);
};
#endif /* KONQUNDOMANAGER_H */
Index: src/konqcloseditem.h
===================================================================
--- src/konqcloseditem.h (revisión: 794475)
+++ src/konqcloseditem.h (copia de trabajo)
@@ -23,17 +23,20 @@
#include "konqprivate_export.h"
#include <kconfiggroup.h>
+#include <QtDBus/QtDBus>
#include <QString>
#include <QImage>
+class KConfig;
+
class KONQ_TESTS_EXPORT KonqClosedItem : public QObject {
public:
virtual ~KonqClosedItem();
- const KConfigGroup& configGroup() const { return m_configGroup; }
- KConfigGroup& configGroup() { return m_configGroup; }
+ virtual KConfigGroup& configGroup() { return m_configGroup; }
+ virtual const KConfigGroup& configGroup() const { return m_configGroup; }
quint64 serialNumber() const { return m_serialNumber; }
QString title() const { return m_title; }
- virtual QPixmap icon() = 0;
+ virtual QPixmap icon() const = 0;
protected:
KonqClosedItem(const QString& title, const QString& group, quint64 serialNumber);
@@ -50,7 +53,7 @@
public:
KonqClosedTabItem(const QString& url, const QString& title, int index, quint64 serialNumber);
virtual ~KonqClosedTabItem();
- virtual QPixmap icon();
+ virtual QPixmap icon() const;
QString url() const { return m_url; }
/// The position inside the tabbar that the tab had when it was closed
int pos() const { return m_pos; }
@@ -68,11 +71,35 @@
public:
KonqClosedWindowItem(const QString& title, quint64 serialNumber, int numTabs);
virtual ~KonqClosedWindowItem();
- virtual QPixmap icon();
+ virtual QPixmap icon() const;
+ int numTabs() const;
protected:
int m_numTabs;
};
+class KONQ_TESTS_EXPORT KonqClosedRemoteWindowItem : public KonqClosedWindowItem {
+public:
+ KonqClosedRemoteWindowItem(const QString& title, const QString& groupName, const QString& configFileName, quint64 serialNumber, int numTabs, const QString& dbusService);
+ virtual ~KonqClosedRemoteWindowItem();
+ virtual KConfigGroup& configGroup();
+ virtual const KConfigGroup& configGroup() const;
+ bool equalsTo(const QString& groupName, const QString& configFileName) const;
+ QString dbusService() const { return m_dbusService; }
+ const QString& remoteGroupName() const { return m_remoteGroupName; }
+ const QString& remoteConfigFileName() const { return m_remoteConfigFileName; }
+protected:
+ /**
+ * Actually reads the config file. Call to this function before calling to
+ * configGroup().
+ */
+ void readConfig();
+ QString m_remoteGroupName;
+ QString m_remoteConfigFileName;
+ QString m_dbusService;
+ KConfigGroup* m_remoteConfigGroup;
+ KConfig* m_remoteConfig;
+};
+
#endif /* KONQCLOSEDITEM_H */
Index: src/konqundomanager.cpp
===================================================================
--- src/konqundomanager.cpp (revisión: 794475)
+++ src/konqundomanager.cpp (copia de trabajo)
@@ -19,23 +19,36 @@
*/
#include "konqundomanager.h"
+#include "konqundomanageradaptor.h"
+#include "konqundomanager_interface.h"
#include <QAction>
+#include <QByteArray>
+#include <QDBusArgument>
+#include <QDirIterator>
+#include <QFile>
+#include <QMetaType>
+#include <QtDBus/QtDBus>
#include <QTimer>
+#include <QVariant>
#include <konq_fileundomanager.h>
-#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kglobal.h>
+#include <kstandarddirs.h>
-class KonqUndoManagerCommunicatorPrivate {
+Q_DECLARE_METATYPE(QList<QVariant>);
+
+class KonqClosedWindowsManagerPrivate
+{
public:
- KonqUndoManagerCommunicator instance;
- QList<KonqClosedWindowItem *> m_closedWindowItemList;
+ KonqClosedWindowsManager instance;
int m_maxNumClosedItems;
+ bool m_amIalone;
};
-K_GLOBAL_STATIC(KonqUndoManagerCommunicatorPrivate, myKonqUndoManagerCommunicatorPrivate)
+K_GLOBAL_STATIC(KonqClosedWindowsManagerPrivate, myKonqClosedWindowsManagerPrivate);
+
KonqUndoManager::KonqUndoManager(QObject* parent)
: QObject(parent)
{
@@ -45,14 +58,12 @@
connect( KonqFileUndoManager::self(), SIGNAL(undoTextChanged(QString)),
this, SLOT(slotFileUndoTextChanged(QString)) );
- connect(KonqUndoManagerCommunicator::self(),
+ connect(KonqClosedWindowsManager::self(),
SIGNAL(addWindowInOtherInstances(KonqUndoManager *, KonqClosedWindowItem *)), this,
SLOT( slotAddClosedWindowItem(KonqUndoManager *, KonqClosedWindowItem *) ));
- connect(KonqUndoManagerCommunicator::self(),
+ connect(KonqClosedWindowsManager::self(),
SIGNAL(removeWindowInOtherInstances(KonqUndoManager *, const KonqClosedWindowItem *)), this,
SLOT( slotRemoveClosedWindowItem(KonqUndoManager *, const KonqClosedWindowItem *) ));
-
- populate();
}
KonqUndoManager::~KonqUndoManager()
@@ -62,22 +73,24 @@
disconnect( KonqFileUndoManager::self(), SIGNAL(undoTextChanged(QString)),
this, SLOT(slotFileUndoTextChanged(QString)) );
- disconnect(KonqUndoManagerCommunicator::self(),
+ disconnect(KonqClosedWindowsManager::self(),
SIGNAL(addWindowInOtherInstances(KonqUndoManager *, KonqClosedWindowItem *)), this,
SLOT( slotAddClosedWindowItem(KonqUndoManager *, KonqClosedWindowItem *) ));
- disconnect(KonqUndoManagerCommunicator::self(),
+ disconnect(KonqClosedWindowsManager::self(),
SIGNAL(removeWindowInOtherInstances(KonqUndoManager *, const KonqClosedWindowItem *)), this,
SLOT( slotRemoveClosedWindowItem(KonqUndoManager *, const KonqClosedWindowItem *) ));
KonqFileUndoManager::decRef();
- clearClosedItemsList();
+
+ // Clear the closed item lists but only removed closed windows items
+ // in this window
+ clearClosedItemsList(true);
}
void KonqUndoManager::populate()
{
- kDebug();
const QList<KonqClosedWindowItem *> closedWindowItemList =
- KonqUndoManagerCommunicator::self()->closedWindowItemList();
+ KonqClosedWindowsManager::self()->closedWindowItemList();
foreach(KonqClosedWindowItem *closedWindowItem, closedWindowItemList)
slotAddClosedWindowItem(0L, closedWindowItem);
@@ -115,27 +128,11 @@
void KonqUndoManager::undo()
{
if (!m_closedItemList.isEmpty()) {
- const KonqClosedItem* closedItem = m_closedItemList.first();
+ KonqClosedItem* closedItem = m_closedItemList.first();
// Check what to undo
- kDebug() << "closedTabItem->serialNumber:" << closedItem->serialNumber()
- << ", KonqFileUndoManager currentCommandSerialNumber(): " << KonqFileUndoManager::self()->currentCommandSerialNumber();
-
if (closedItem->serialNumber() > KonqFileUndoManager::self()->currentCommandSerialNumber()) {
- m_closedItemList.removeFirst();
- const KonqClosedTabItem* closedTabItem =
- dynamic_cast<const KonqClosedTabItem *>(closedItem);
- const KonqClosedWindowItem* closedWindowItem =
- dynamic_cast<const KonqClosedWindowItem *>(closedItem);
- if(closedTabItem)
- emit openClosedTab(*closedTabItem);
- else if(closedWindowItem) {
- emit openClosedWindow(*closedWindowItem);
- KonqUndoManagerCommunicator::self()->removeClosedWindowItem(this, closedWindowItem);
- }
- delete closedItem;
- emit undoAvailable(this->undoAvailable());
- emit closedItemsListChanged();
+ undoClosedItem(0);
} else {
KonqFileUndoManager::self()->undo();
}
@@ -149,7 +146,7 @@
if(real_sender == this)
return;
- if(m_closedItemList.size() >= KonqUndoManagerCommunicator::self()->maxNumClosedItems())
+ if(m_closedItemList.size() >= KonqClosedWindowsManager::self()->maxNumClosedItems())
{
const KonqClosedItem* last = m_closedItemList.last();
const KonqClosedTabItem* lastTab =
@@ -161,7 +158,6 @@
delete lastTab;
}
- kDebug();
m_closedItemList.prepend(closedWindowItem);
emit undoTextChanged(i18n("Und&o: Closed Window"));
emit undoAvailable(true);
@@ -170,7 +166,7 @@
void KonqUndoManager::addClosedWindowItem(KonqClosedWindowItem *closedWindowItem)
{
- KonqUndoManagerCommunicator::self()->addClosedWindowItem(this, closedWindowItem);
+ KonqClosedWindowsManager::self()->addClosedWindowItem(this, closedWindowItem);
}
void KonqUndoManager::slotRemoveClosedWindowItem(KonqUndoManager *real_sender, const KonqClosedWindowItem *closedWindowItem)
@@ -201,15 +197,21 @@
const KonqClosedTabItem* closedTabItem =
dynamic_cast<const KonqClosedTabItem *>(closedItem);
- const KonqClosedWindowItem* closedWindowItem =
- dynamic_cast<const KonqClosedWindowItem *>(closedItem);
+ KonqClosedRemoteWindowItem* closedRemoteWindowItem =
+ dynamic_cast<KonqClosedRemoteWindowItem *>(closedItem);
+ KonqClosedWindowItem* closedWindowItem =
+ dynamic_cast<KonqClosedWindowItem *>(closedItem);
if(closedTabItem)
emit openClosedTab(*closedTabItem);
- else if(closedWindowItem) {
+ else if(closedRemoteWindowItem) {
+ emit openClosedWindow(*closedRemoteWindowItem);
+ KonqClosedWindowsManager::self()->removeClosedWindowItem(this, closedRemoteWindowItem);
+ } else if(closedWindowItem) {
emit openClosedWindow(*closedWindowItem);
- emit removeWindowInOtherInstances(this, closedWindowItem);
+ KonqClosedWindowsManager::self()->removeClosedWindowItem(this, closedWindowItem);
+ closedWindowItem->configGroup().deleteGroup();
}
- delete closedTabItem;
+ delete closedItem;
emit undoAvailable(this->undoAvailable());
emit undoTextChanged(this->undoText());
emit closedItemsListChanged();
@@ -235,7 +237,7 @@
void KonqUndoManager::addClosedTabItem(KonqClosedTabItem* closedTabItem)
{
- if(m_closedItemList.size() >= KonqUndoManagerCommunicator::self()->maxNumClosedItems())
+ if(m_closedItemList.size() >= KonqClosedWindowsManager::self()->maxNumClosedItems())
{
const KonqClosedItem* last = m_closedItemList.last();
const KonqClosedTabItem* lastTab =
@@ -258,7 +260,7 @@
emit undoAvailable(this->undoAvailable());
}
-void KonqUndoManager::clearClosedItemsList()
+void KonqUndoManager::clearClosedItemsList(bool onlyInthisWindow)
{
// we only DELETE tab items! So we can't do this anymore:
// qDeleteAll(m_closedItemList);
@@ -268,13 +270,16 @@
KonqClosedItem *closedItem = *it;
const KonqClosedTabItem* closedTabItem =
dynamic_cast<const KonqClosedTabItem *>(closedItem);
-// const KonqClosedWindowItem* closedWindowItem =
-// dynamic_cast<const KonqClosedWindowItem *>(closedItem);
+ const KonqClosedWindowItem* closedWindowItem =
+ dynamic_cast<const KonqClosedWindowItem *>(closedItem);
m_closedItemList.erase(it);
if(closedTabItem)
delete closedTabItem;
- // we never delete closed window items here
+ else if (closedWindowItem && !onlyInthisWindow) {
+ KonqClosedWindowsManager::self()->removeClosedWindowItem(this, closedWindowItem, false);
+ delete closedWindowItem;
+ }
}
emit closedItemsListChanged();
emit undoAvailable(this->undoAvailable());
@@ -285,81 +290,426 @@
undoClosedItem(0);
}
-KonqUndoManagerCommunicator::KonqUndoManagerCommunicator()
+KonqClosedWindowsManager::KonqClosedWindowsManager()
{
QTimer::singleShot(0, this, SLOT(readSettings()));
+
+ 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)));
+ dbus.connect(QString(), dbusPath, dbusInterface, "requestLocalClosedWindowItems", this, SLOT(slotRequestLocalClosedWindowItems(QDBusMessage)));
+
+ QString filename = "closeditems/closeditems_" + QString::number(getpid());
+ QString file = KStandardDirs::locateLocal("appdata", filename);
+ QFile::remove(file);
+
+ m_konqClosedItemsConfig = new KConfig(filename, KConfig::SimpleConfig, "appdata");
+
}
-KonqUndoManagerCommunicator::~KonqUndoManagerCommunicator()
+KonqClosedWindowsManager::~KonqClosedWindowsManager()
{
+ saveConfig();
+
+ delete m_konqClosedItemsConfig;
}
-KonqUndoManagerCommunicator *KonqUndoManagerCommunicator::self()
+KConfig* KonqClosedWindowsManager::config()
{
- return &myKonqUndoManagerCommunicatorPrivate->instance;
+ return m_konqClosedItemsConfig;
}
-void KonqUndoManagerCommunicator::addClosedWindowItem(KonqUndoManager
-*real_sender, KonqClosedWindowItem *closedWindowItem)
+KonqClosedWindowsManager *KonqClosedWindowsManager::self()
{
+ return &myKonqClosedWindowsManagerPrivate->instance;
+}
+
+void KonqClosedWindowsManager::addClosedWindowItem(KonqUndoManager
+*real_sender, KonqClosedWindowItem *closedWindowItem, bool propagate)
+{
// If we are off the limit, remove the last closed window item
- if(myKonqUndoManagerCommunicatorPrivate->m_closedWindowItemList.size() >=
+ if(m_closedWindowItemList.size() >=
maxNumClosedItems())
{
- QList<KonqClosedWindowItem *> &closedWindowItemList =
- myKonqUndoManagerCommunicatorPrivate->m_closedWindowItemList;
- KonqClosedWindowItem* last = closedWindowItemList.last();
+ KonqClosedWindowItem* last = m_closedWindowItemList.last();
+
emit removeWindowInOtherInstances(0L, last);
- closedWindowItemList.removeLast();
+ emitNotifyClosedWindowItem(closedWindowItem);
+
+ m_closedWindowItemList.removeLast();
delete last;
}
- myKonqUndoManagerCommunicatorPrivate->m_closedWindowItemList.prepend(closedWindowItem);
+ m_closedWindowItemList.prepend(closedWindowItem);
emit addWindowInOtherInstances(real_sender, closedWindowItem);
+
+ if(propagate)
+ emitNotifyClosedWindowItem(closedWindowItem);
}
-void KonqUndoManagerCommunicator::removeClosedWindowItem(KonqUndoManager
-*real_sender, const KonqClosedWindowItem *closedWindowItem)
+void KonqClosedWindowsManager::removeClosedWindowItem(KonqUndoManager
+*real_sender, const KonqClosedWindowItem *closedWindowItem, bool propagate)
{
- QList<KonqClosedWindowItem *> &closedWindowItemList =
- myKonqUndoManagerCommunicatorPrivate->m_closedWindowItemList;
- QList<KonqClosedWindowItem *>::iterator it = qFind(closedWindowItemList.begin(),
- closedWindowItemList.end(), closedWindowItem);
+ QList<KonqClosedWindowItem *>::iterator it = qFind(m_closedWindowItemList.begin(),
+ m_closedWindowItemList.end(), closedWindowItem);
// If the item was found, remove it from the list
- if(it != closedWindowItemList.end()) {
- closedWindowItemList.erase(it);
+ if(it != m_closedWindowItemList.end()) {
+ m_closedWindowItemList.erase(it);
}
emit removeWindowInOtherInstances(real_sender, closedWindowItem);
+
+ if(propagate)
+ emitNotifyRemove(closedWindowItem);
}
-const QList<KonqClosedWindowItem *>& KonqUndoManagerCommunicator::closedWindowItemList()
+const QList<KonqClosedWindowItem *>& KonqClosedWindowsManager::closedWindowItemList()
{
- return myKonqUndoManagerCommunicatorPrivate->m_closedWindowItemList;
+ return m_closedWindowItemList;
}
-int KonqUndoManagerCommunicator::maxNumClosedItems()
+int KonqClosedWindowsManager::maxNumClosedItems()
{
- return myKonqUndoManagerCommunicatorPrivate->m_maxNumClosedItems;
+ return m_maxNumClosedItems;
}
-void KonqUndoManagerCommunicator::setMaxNumClosedItems(int max)
+void KonqClosedWindowsManager::setMaxNumClosedItems(int max)
{
- myKonqUndoManagerCommunicatorPrivate->m_maxNumClosedItems = qMax(1, max);
+ m_maxNumClosedItems = qMax(1, max);
}
-void KonqUndoManagerCommunicator::readSettings()
+void KonqClosedWindowsManager::readSettings()
{
KSharedConfigPtr config = KGlobal::config();
KConfigGroup configGroup( config, "UndoManagerSettings");
- myKonqUndoManagerCommunicatorPrivate->m_maxNumClosedItems = configGroup.readEntry("Maximum number of Closed Items", 20 );
- myKonqUndoManagerCommunicatorPrivate->m_maxNumClosedItems = qMax(1, myKonqUndoManagerCommunicatorPrivate->m_maxNumClosedItems);
+ m_maxNumClosedItems = configGroup.readEntry("Maximum number of Closed Items", 20 );
+ m_maxNumClosedItems = qMax(1, m_maxNumClosedItems);
+
+ m_amIalone = true;
+ populate();
+
+ // If in 0.5 seconds no other konqueror instance answer, we will assume that
+ // we're alone and therefore instead of getting the undo closed window list
+ // via dbus, we'll read it from disk
+ QTimer::singleShot(500, this, SLOT(readConfig()));
}
-void KonqUndoManagerCommunicator::applySettings()
+
+
+void KonqClosedWindowsManager::applySettings()
{
KConfigGroup configGroup(KSharedConfig::openConfig("konquerorrc"), "UndoManagerSettings");
- configGroup.writeEntry("Value youngerThan", myKonqUndoManagerCommunicatorPrivate->m_maxNumClosedItems );
+ configGroup.writeEntry("Value youngerThan", m_maxNumClosedItems );
}
+
+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,
+ KonqFileUndoManager::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);
+}
+
+void KonqClosedWindowsManager::slotRequestLocalClosedWindowItems(
+ const QDBusMessage& msg)
+{
+ if ( isSenderOfSignal( msg ) )
+ return;
+
+ emitPong(msg.service());
+
+
+ if ( closedWindowItemList().empty() )
+ return;
+
+ QList<QVariant> windowItems;
+ KonqClosedWindowItem *closedWindowItem;
+ for (QList<KonqClosedWindowItem *>::const_iterator it = closedWindowItemList().begin();
+ it != closedWindowItemList().end(); ++it)
+ {
+ closedWindowItem = *it;
+ KonqClosedRemoteWindowItem* closedRemoteWindowItem =
+ dynamic_cast<KonqClosedRemoteWindowItem *>(closedWindowItem);
+
+ if(!closedRemoteWindowItem && closedWindowItem)
+ {
+ // Add to the list
+ QByteArray data;
+ QDataStream stream( &data, QIODevice::WriteOnly );
+ stream << closedWindowItem->title();
+ stream << closedWindowItem->numTabs();
+ stream << closedWindowItem->configGroup().config()->name();
+ stream << closedWindowItem->configGroup().name();
+ QVariant variant(data);
+ windowItems.append(variant);
+ }
+ }
+
+ if(!windowItems.empty())
+ {
+ org::kde::Konqueror::UndoManager interface(msg.service(),
+ "/KonqUndoManager", QDBusConnection::sessionBus(), this);
+
+ if(!interface.isValid())
+ return;
+
+ interface.localClosedWindowItems(windowItems, dbusService());
+ }
+}
+
+void KonqClosedWindowsManager::emitPong(const QString & service)
+{
+ org::kde::Konqueror::UndoManager interface(service,
+ "/KonqUndoManager", QDBusConnection::sessionBus(), this);
+
+ if(!interface.isValid())
+ return;
+
+ interface.pong();
+}
+
+void KonqClosedWindowsManager::localClosedWindowItems(
+ const QList<QVariant>& windowItems, const QString& service)
+{
+
+ QListIterator<QVariant> it(windowItems);
+ for (it.toBack(); it.hasPrevious(); )
+ {
+ QString title, configFileName, configGroup;
+ int numTabs;
+ QByteArray data = (it.previous()).toByteArray();
+ QDataStream stream( const_cast<QByteArray *>( &data ), QIODevice::ReadOnly );
+ stream >> title >> numTabs >> configFileName >> configGroup;
+ slotNotifyClosedWindowItem(title, numTabs, configFileName, configGroup,
+ service);
+ }
+
+}
+
+void KonqClosedWindowsManager::pong()
+{
+ m_amIalone = false;
+}
+
+KonqClosedRemoteWindowItem* KonqClosedWindowsManager::findClosedRemoteWindowItem(
+ const QString& configFileName,
+ const QString& configGroup)
+{
+ KonqClosedRemoteWindowItem* closedRemoteWindowItem = 0L;
+ for (QList<KonqClosedWindowItem *>::const_iterator it = closedWindowItemList().begin();
+ it != 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)
+{
+ KonqClosedWindowItem* closedWindowItem = 0L;
+ for (QList<KonqClosedWindowItem *>::const_iterator it = closedWindowItemList().begin();
+ it != 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::populate()
+{
+ emit requestLocalClosedWindowItems();
+}
+
+void KonqClosedWindowsManager::removeClosedItemsConfigFiles()
+{
+ QString dir= KStandardDirs::locateLocal("appdata", "closeditems/");
+
+ QDirIterator it(dir, QDir::Writable|QDir::Files);
+ while (it.hasNext())
+ {
+ QFile::remove(it.next());
+ }
+}
+
+
+void KonqClosedWindowsManager::saveConfig()
+{
+ // Create / overwrite the saved closed windows list
+ QString filename = "closeditems_saved";
+ QString file = KStandardDirs::locateLocal("appdata", filename);
+ if(QFile::exists(file))
+ QFile::remove(file);
+
+ KConfig *config = new KConfig(filename, KConfig::SimpleConfig, "appdata");
+
+ // Populate the config file
+ KonqClosedWindowItem* closedWindowItem = 0L;
+ uint counter = closedWindowItemList().size()-1;
+ for (QList<KonqClosedWindowItem *>::const_iterator it = closedWindowItemList().begin();
+ it != 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(config, "General");
+ configGroup.writeEntry("Number of Closed Windows", closedWindowItemList().size());
+
+ delete config;
+}
+
+void KonqClosedWindowsManager::readConfig()
+{
+ // We will read the configuration file *only* if we are alone, which means
+ // only if we couldn't get the closed windows list via dbus because no
+ // dbus instance answered/exists
+ if(!m_amIalone)
+ return;
+
+ // Simplification: we assume there was no time to open and close
+ // a konqueror window in 500ms of konqueror life time and thus there
+ // shouldn't be any file in closeditem/* to do some houskeeping everytime
+ // konqueror starts
+ removeClosedItemsConfigFiles();
+
+ QString filename = "closeditems_saved";
+ QString file = KStandardDirs::locateLocal("appdata", filename);
+
+ // If the config file doesn't exists, there's nothing to read
+ if(!QFile::exists(file))
+ return;
+
+ KConfig config(filename, KConfig::SimpleConfig, "appdata");
+ KConfigGroup generalGroup(&config, "General");
+ int numClosedWindows = generalGroup.readEntry("Number of Closed Windows", 0);
+
+ for(int i = 0; i < numClosedWindows; i++)
+ {
+ // For each item, create a new ClosedWindowItem
+ KConfigGroup configGroup(&config, "Closed_Window" + QString::number(i));
+ QString title = configGroup.readEntry("title", i18n("no name"));
+ int numTabs = configGroup.readEntry("numTabs", 0);
+
+ KonqClosedWindowItem* closedWindowItem = new KonqClosedWindowItem(
+ title, KonqFileUndoManager::self()->newCommandSerialNumber(),
+ numTabs);
+ configGroup.copyTo(&closedWindowItem->configGroup());
+ configGroup.writeEntry("foo", 0);
+ closedWindowItem->configGroup().config()->sync();
+
+ // Add the item to all the windows and propagate over dbus
+ addClosedWindowItem(0L, closedWindowItem, true);
+ }
+}