]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/versioncontrol/versioncontrolobserver.cpp
SVN_SILENT made messages (.desktop file)
[dolphin.git] / src / versioncontrol / versioncontrolobserver.cpp
index aea60b28d86a3021233af190ff31160fc4652a98..f47f474845471a39ad34e4f1b0b2abc173ae610f 100644 (file)
@@ -20,6 +20,7 @@
 #include "versioncontrolobserver.h"
 
 #include <dolphinmodel.h>
+#include "dolphin_versioncontrolsettings.h"
 
 #include <kdirlister.h>
 #include <klocale.h>
 #include <QMutexLocker>
 #include <QTimer>
 
+/*
+ * Maintains a list of pending threads, that get regulary checked
+ * whether they are finished and hence can get deleted. QThread::wait()
+ * is never used to prevent any blocking of the user interface.
+ */
+struct PendingThreadsSingleton
+{
+    QList<UpdateItemStatesThread*> list;
+};
+K_GLOBAL_STATIC(PendingThreadsSingleton, s_pendingThreads)
+
+
 VersionControlObserver::VersionControlObserver(QAbstractItemView* view) :
     QObject(view),
     m_pendingItemStatesUpdate(false),
@@ -73,11 +86,26 @@ VersionControlObserver::VersionControlObserver(QAbstractItemView* view) :
 VersionControlObserver::~VersionControlObserver()
 {
     if (m_updateItemStatesThread != 0) {
-        disconnect(m_updateItemStatesThread, SIGNAL(finished()),
-                   this, SLOT(applyUpdatedItemStates()));
-        m_updateItemStatesThread->deleteWhenFinished();
-        m_updateItemStatesThread = 0;
+        if (m_updateItemStatesThread->isFinished()) {
+            delete m_updateItemStatesThread;
+            m_updateItemStatesThread = 0;
+        } else {
+            // The version controller gets deleted, while a thread still
+            // is working to get the version information. To avoid a blocking
+            // user interface, no waiting for the finished() signal of the thread is
+            // done. Instead the thread will be remembered inside the global
+            // list s_pendingThreads, which will checked regulary. The thread does
+            // not work on shared data that is part of the VersionController instance,
+            // so skipping the waiting is save.
+            disconnect(m_updateItemStatesThread, SIGNAL(finished()),
+                       this, SLOT(slotThreadFinished()));
+            s_pendingThreads->list.append(m_updateItemStatesThread);
+            m_updateItemStatesThread = 0;
+        }
     }
+
+    m_plugin->disconnect();
+    m_plugin = 0;
 }
 
 QList<QAction*> VersionControlObserver::contextMenuActions(const KFileItemList& items) const
@@ -115,6 +143,19 @@ void VersionControlObserver::silentDirectoryVerification()
 
 void VersionControlObserver::verifyDirectory()
 {
+    if (!s_pendingThreads->list.isEmpty()) {
+        // Try to cleanup pending threads (see explanation in destructor)
+        QList<UpdateItemStatesThread*>::iterator it = s_pendingThreads->list.begin();
+        while (it != s_pendingThreads->list.end()) {
+            if ((*it)->isFinished()) {
+                (*it)->deleteLater();
+                it = s_pendingThreads->list.erase(it);
+            } else {
+                ++it;
+            }
+        }
+    }
+
     KUrl versionControlUrl = m_dirLister->url();
     if (!versionControlUrl.isLocalFile()) {
         return;
@@ -169,8 +210,12 @@ void VersionControlObserver::verifyDirectory()
     }
 }
 
-void VersionControlObserver::applyUpdatedItemStates()
+void VersionControlObserver::slotThreadFinished()
 {
+    if (m_plugin == 0) {
+        return;
+    }
+
     if (!m_updateItemStatesThread->retrievedItems()) {
         // ignore m_silentUpdate for an error message
         emit errorMessage(i18nc("@info:status", "Update of version information failed."));
@@ -200,7 +245,7 @@ void VersionControlObserver::applyUpdatedItemStates()
         // operation has been completed because of the icon emblems.
         emit operationCompletedMessage(QString());
     }
-    
+
     if (m_pendingItemStatesUpdate) {
         m_pendingItemStatesUpdate = false;
         updateItemStates();
@@ -211,13 +256,13 @@ void VersionControlObserver::updateItemStates()
 {
     Q_ASSERT(m_plugin != 0);
     if (m_updateItemStatesThread == 0) {
-        m_updateItemStatesThread = new UpdateItemStatesThread(this);
+        m_updateItemStatesThread = new UpdateItemStatesThread();
         connect(m_updateItemStatesThread, SIGNAL(finished()),
-                this, SLOT(applyUpdatedItemStates()));
+                this, SLOT(slotThreadFinished()));
     }
     if (m_updateItemStatesThread->isRunning()) {
         // An update is currently ongoing. Wait until the thread has finished
-        // the update (see applyUpdatedItemStates()).
+        // the update (see slotThreadFinished()).
         m_pendingItemStatesUpdate = true;
         return;
     }
@@ -229,7 +274,7 @@ void VersionControlObserver::updateItemStates()
             emit infoMessage(i18nc("@info:status", "Updating version information..."));
         }
         m_updateItemStatesThread->setData(m_plugin, itemStates);
-        m_updateItemStatesThread->start(); // applyUpdatedItemStates() is called when finished
+        m_updateItemStatesThread->start(); // slotThreadFinished() is called when finished
     }
 }
 
@@ -263,11 +308,16 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& director
     if (plugins.isEmpty()) {
         // No searching for plugins has been done yet. Query the KServiceTypeTrader for
         // all fileview version control plugins and remember them in 'plugins'.
+        const QString disabledPlugins = VersionControlSettings::disabledPlugins();
+        const QStringList disabledPluginsList = disabledPlugins.split(',');
+
         const KService::List pluginServices = KServiceTypeTrader::self()->query("FileViewVersionControlPlugin");
         for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) {
-            KVersionControlPlugin* plugin = (*it)->createInstance<KVersionControlPlugin>();
-            Q_ASSERT(plugin != 0);
-            plugins.append(plugin);
+            if (!disabledPluginsList.contains((*it)->name())) {
+                KVersionControlPlugin* plugin = (*it)->createInstance<KVersionControlPlugin>();
+                Q_ASSERT(plugin != 0);
+                plugins.append(plugin);
+            }
         }
         if (plugins.isEmpty()) {
             pluginsAvailable = false;