All pastes #975728 Raw Edit

Anonymous

public diff v1 · immutable
·published 2008-04-07 19:29 UTC
rendered paste body
Index: src/konqcloseditem.cpp===================================================================--- src/konqcloseditem.cpp	(revisión: 794475)+++ src/konqcloseditem.cpp	(copia de trabajo)@@ -34,27 +34,21 @@ #include <kstandarddirs.h> #include <unistd.h> -class KConfigNew+KonqClosedItemsConfig::KonqClosedItemsConfig() {-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;-};+    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();+} +KonqClosedItemsConfig::~KonqClosedItemsConfig() {+    // config is "leaked"+}+ class KonqIcon { public:     KonqIcon()@@ -66,11 +60,13 @@     QImage image; }; -K_GLOBAL_STATIC(KConfigNew, s_config)++// deleted manually in KonqUndoManagerCommunicator::~KonqUndoManagerCommunicator()+K_GLOBAL_STATIC(KonqClosedItemsConfig, s_closedItemsConfig) 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(s_closedItemsConfig->config, group), m_serialNumber(serialNumber) { } @@ -92,7 +88,7 @@     kDebug(1202) << "deleted group" << m_configGroup.name(); } -QPixmap KonqClosedTabItem::icon() {+QPixmap KonqClosedTabItem::icon() const {     return KonqPixmapProvider::self()->pixmapFor(m_url); } @@ -104,11 +100,13 @@  KonqClosedWindowItem::~KonqClosedWindowItem() {-    m_configGroup.deleteGroup();-    kDebug(1202) << "deleted group" << m_configGroup.name();+// Do this manually when needed:+//     m_configGroup.deleteGroup();+//     kDebug(1202) << "deleted group" << m_configGroup.name(); } -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 +132,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();+    readConfig();+}++KonqClosedRemoteWindowItem::~KonqClosedRemoteWindowItem()+{+    if(m_remoteConfigGroup)+        delete m_remoteConfigGroup;+    +    if(m_remoteConfig)+        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);+}++const KConfigGroup& KonqClosedRemoteWindowItem::configGroup() const+{+    return *m_remoteConfigGroup;+}++KConfigGroup& KonqClosedRemoteWindowItem::configGroup()+{+    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,10 @@     }      mainWindow->viewManager()->loadRootItem( closedWindowItem.configGroup(), mainWindow->viewManager()->tabContainer(), KUrl(), true, KUrl() );+    // read window settings+    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 KonqUndoManagerCommunicator konqundomanageradaptor KonqUndoManagerCommunicatorAdaptor)+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,15 @@ #ifndef KONQUNDOMANAGER_H #define KONQUNDOMANAGER_H -#include "konqprivate_export.h"- #include <QObject>+#include <QString>+#include <QList> #include "konqcloseditem.h"+#include "konqundomanager_interface.h" class QAction; class KonqUndoManagerCommunicatorPrivate;+class QDBusMessage;+ /**  * Note that there is one KonqUndoManager per mainwindow.  * It integrates KonqFileUndoManager (undoing file operations)@@ -54,7 +57,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 +105,150 @@ /**  * 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 {     Q_OBJECT public:     friend class KonqUndoManagerCommunicatorPrivate;+         static KonqUndoManagerCommunicator *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);+ 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();+    +    /**+     * 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();+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,44 @@ 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;+};++class KonqClosedItemsConfig+{+public:+    KonqClosedItemsConfig();+    ~KonqClosedItemsConfig();+    KConfig *config;+    QString filename;+};+ #endif /* KONQCLOSEDITEM_H */ Index: src/konqundomanager.cpp===================================================================--- src/konqundomanager.cpp	(revisión: 794475)+++ src/konqundomanager.cpp	(copia de trabajo)@@ -19,22 +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 KonqUndoManagerCommunicatorPrivate+{ public:     KonqUndoManagerCommunicator instance;-    QList<KonqClosedWindowItem *> m_closedWindowItemList;     int m_maxNumClosedItems;+    bool m_amIalone; }; -K_GLOBAL_STATIC(KonqUndoManagerCommunicatorPrivate, myKonqUndoManagerCommunicatorPrivate)+K_GLOBAL_STATIC(KonqUndoManagerCommunicatorPrivate, myKonqUndoManagerCommunicatorPrivate);+static QList<KonqClosedWindowItem *> *s_closedWindowItemList = new QList<KonqClosedWindowItem *>();  KonqUndoManager::KonqUndoManager(QObject* parent)     : QObject(parent)@@ -51,8 +65,6 @@     connect(KonqUndoManagerCommunicator::self(),         SIGNAL(removeWindowInOtherInstances(KonqUndoManager *, const KonqClosedWindowItem *)), this,         SLOT( slotRemoveClosedWindowItem(KonqUndoManager *, const KonqClosedWindowItem *) ));--    populate(); }  KonqUndoManager::~KonqUndoManager()@@ -70,12 +82,14 @@         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(); @@ -115,27 +129,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();         }@@ -161,7 +159,6 @@             delete lastTab;     }     -    kDebug();     m_closedItemList.prepend(closedWindowItem);     emit undoTextChanged(i18n("Und&o: Closed Window"));     emit undoAvailable(true);@@ -201,15 +198,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);+        KonqUndoManagerCommunicator::self()->removeClosedWindowItem(this, closedRemoteWindowItem);+    } else if(closedWindowItem) {         emit openClosedWindow(*closedWindowItem);-        emit removeWindowInOtherInstances(this, closedWindowItem);+        KonqUndoManagerCommunicator::self()->removeClosedWindowItem(this, closedWindowItem);+        closedWindowItem->configGroup().deleteGroup();     }-    delete closedTabItem;+    delete closedItem;     emit undoAvailable(this->undoAvailable());     emit undoTextChanged(this->undoText());     emit closedItemsListChanged();@@ -258,7 +261,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 +271,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) {+            KonqUndoManagerCommunicator::self()->removeClosedWindowItem(this, closedWindowItem, false);+            delete closedWindowItem;+        }     }     emit closedItemsListChanged();     emit undoAvailable(this->undoAvailable());@@ -288,10 +294,25 @@ KonqUndoManagerCommunicator::KonqUndoManagerCommunicator() {     QTimer::singleShot(0, this, SLOT(readSettings()));+    +    qDBusRegisterMetaType<QList<QVariant> >();+    +    (void) new KonqUndoManagerCommunicatorAdaptor ( 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))); }  KonqUndoManagerCommunicator::~KonqUndoManagerCommunicator() {+    saveConfig();+    +    delete s_closedWindowItemList; }  KonqUndoManagerCommunicator *KonqUndoManagerCommunicator::self()@@ -300,42 +321,47 @@ }  void KonqUndoManagerCommunicator::addClosedWindowItem(KonqUndoManager-*real_sender, KonqClosedWindowItem *closedWindowItem)+*real_sender, KonqClosedWindowItem *closedWindowItem, bool propagate) {     // If we are off the limit, remove the last closed window item-    if(myKonqUndoManagerCommunicatorPrivate->m_closedWindowItemList.size() >= +    if(s_closedWindowItemList->size() >=          maxNumClosedItems())     {-        QList<KonqClosedWindowItem *> &closedWindowItemList =-        myKonqUndoManagerCommunicatorPrivate->m_closedWindowItemList;-        KonqClosedWindowItem* last = closedWindowItemList.last();+        KonqClosedWindowItem* last = s_closedWindowItemList->last();+                 emit removeWindowInOtherInstances(0L, last);-        closedWindowItemList.removeLast();+        emitNotifyClosedWindowItem(closedWindowItem);+        +        s_closedWindowItemList->removeLast();         delete last;     }     -    myKonqUndoManagerCommunicatorPrivate->m_closedWindowItemList.prepend(closedWindowItem);+    s_closedWindowItemList->prepend(closedWindowItem);     emit addWindowInOtherInstances(real_sender, closedWindowItem);+    +    if(propagate)+        emitNotifyClosedWindowItem(closedWindowItem); }  void KonqUndoManagerCommunicator::removeClosedWindowItem(KonqUndoManager-*real_sender, const KonqClosedWindowItem *closedWindowItem)+*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(s_closedWindowItemList->begin(),+    s_closedWindowItemList->end(), closedWindowItem);                  // If the item was found, remove it from the list-    if(it != closedWindowItemList.end()) {-        closedWindowItemList.erase(it);+    if(it != s_closedWindowItemList->end()) {+        s_closedWindowItemList->erase(it);     }     emit removeWindowInOtherInstances(real_sender, closedWindowItem);+    +    if(propagate)+        emitNotifyRemove(closedWindowItem); }  const QList<KonqClosedWindowItem *>& KonqUndoManagerCommunicator::closedWindowItemList() {-    return myKonqUndoManagerCommunicatorPrivate->m_closedWindowItemList;+    return *s_closedWindowItemList; }  int KonqUndoManagerCommunicator::maxNumClosedItems()@@ -355,11 +381,330 @@     KConfigGroup configGroup( config, "UndoManagerSettings");     myKonqUndoManagerCommunicatorPrivate->m_maxNumClosedItems = configGroup.readEntry("Maximum number of Closed Items", 20 );     myKonqUndoManagerCommunicatorPrivate->m_maxNumClosedItems = qMax(1, myKonqUndoManagerCommunicatorPrivate->m_maxNumClosedItems);+    +    myKonqUndoManagerCommunicatorPrivate->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() {     KConfigGroup configGroup(KSharedConfig::openConfig("konquerorrc"), "UndoManagerSettings");      configGroup.writeEntry("Value youngerThan", myKonqUndoManagerCommunicatorPrivate->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 KonqUndoManagerCommunicator::emitNotifyClosedWindowItem(+    const KonqClosedWindowItem *closedWindowItem)+{+    emit notifyClosedWindowItem( closedWindowItem->title(),+        closedWindowItem->numTabs(),+        closedWindowItem->configGroup().config()->name(),+        closedWindowItem->configGroup().name() );+}++void KonqUndoManagerCommunicator::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 KonqUndoManagerCommunicator::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 KonqUndoManagerCommunicator::slotNotifyClosedWindowItem(+    const QString& title, const int& numTabs, const QString& configFileName,+    const QString& configGroup, const QDBusMessage& msg )+{+     slotNotifyClosedWindowItem(title, numTabs, configFileName, configGroup, +        msg.service() );+}++void KonqUndoManagerCommunicator::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 KonqUndoManagerCommunicator::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())+    {+        QDBusInterface interface(msg.service(),+            "/KonqUndoManager", "org.kde.Konqueror.UndoManager");+        +        if(!interface.isValid())+            return;+        +        QList<QVariant> args;+        args.append(windowItems);+        args.append(dbusService());+        interface.callWithArgumentList(QDBus::NoBlock, "localClosedWindowItems", args );+    }+}++void KonqUndoManagerCommunicator::emitPong(const QString & service)+{+    QDBusInterface interface(service,+        "/KonqUndoManager", "org.kde.Konqueror.UndoManager");+    +    if(!interface.isValid())+        return;+    +    interface.call(QDBus::Block, "pong" );+}++void KonqUndoManagerCommunicator::localClosedWindowItems(+    const QList<QVariant>& windowItems, const QString& service)+{+    +    for (QList<QVariant>::const_iterator it = windowItems.begin();+        it != windowItems.end(); ++it)+    {+        QString title, configFileName, configGroup;+        int numTabs;+        QByteArray data = (*it).toByteArray();+        QDataStream stream( const_cast<QByteArray *>( &data ), QIODevice::ReadOnly );+        stream >> title >> numTabs >> configFileName >> configGroup;+        slotNotifyClosedWindowItem(title, numTabs, configFileName, configGroup,+            service);+    }+    +}++void KonqUndoManagerCommunicator::pong()+{+    myKonqUndoManagerCommunicatorPrivate->m_amIalone = false;+}++KonqClosedRemoteWindowItem* KonqUndoManagerCommunicator::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* KonqUndoManagerCommunicator::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 KonqUndoManagerCommunicator::populate()+{+    emit requestLocalClosedWindowItems();+}++void KonqUndoManagerCommunicator::removeClosedItemsConfigFiles()+{+    QString dir= KStandardDirs::locateLocal("appdata", "closeditems/");+    +    QDirIterator it(dir, QDir::Writable|QDir::Files);+    while (it.hasNext())+    {+        QFile::remove(it.next());+    }+}+++void KonqUndoManagerCommunicator::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 KonqUndoManagerCommunicator::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(!myKonqUndoManagerCommunicatorPrivate->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());+        // TODO: the config file isn't being written to disk. Why oh why??+        // I don't know. But this obviously leads to crashes if other konqueror+        // instance tries to read this closed window item from a non existant+        // config file.+        kDebug() << "WRITE TO DISK: " << closedWindowItem->configGroup().config()->name();+        closedWindowItem->configGroup().config()->sync(); // this doesn't work :-(+        +        // Add the item to all the windows and propagate over dbus+        addClosedWindowItem(0L, closedWindowItem, true);    +    }+}