]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/versioncontrol/versioncontrolobserver.cpp
Invert default behavior regarding loading of version control plugins: Only load plugi...
[dolphin.git] / src / versioncontrol / versioncontrolobserver.cpp
index ebe59e049af49847e4f3c1351e2445046df9cf8e..c5a0b982fc9df67a3f7ec81bf07d0b331df9f9e0 100644 (file)
@@ -28,6 +28,7 @@
 #include <kservicetypetrader.h>
 #include <kversioncontrolplugin.h>
 
+#include "pendingthreadsmaintainer.h"
 #include "updateitemstatesthread.h"
 
 #include <QAbstractProxyModel>
@@ -74,26 +75,33 @@ VersionControlObserver::VersionControlObserver(QAbstractItemView* view) :
 VersionControlObserver::~VersionControlObserver()
 {
     if (m_updateItemStatesThread != 0) {
-        disconnect(m_updateItemStatesThread, SIGNAL(finished()),
-                   this, SLOT(applyUpdatedItemStates()));
         if (m_updateItemStatesThread->isFinished()) {
             delete m_updateItemStatesThread;
+            m_updateItemStatesThread = 0;
         } else {
-            m_updateItemStatesThread->deleteWhenFinished();
+            // The version controller gets deleted, while a thread still
+            // is working to get the version information. To avoid a blocking
+            // user interface, the thread will be forwarded to the
+            // PendingThreadsMaintainer, which will delete the thread later.
+            disconnect(m_updateItemStatesThread, SIGNAL(finished()),
+                       this, SLOT(slotThreadFinished()));
+            PendingThreadsMaintainer::instance().append(m_updateItemStatesThread);
+            m_updateItemStatesThread = 0;
         }
-        m_updateItemStatesThread = 0;
     }
 
-    m_plugin->disconnect();
-    m_plugin = 0;
+    if (m_plugin != 0) {
+        m_plugin->disconnect();
+        m_plugin = 0;
+    }
 }
 
 QList<QAction*> VersionControlObserver::contextMenuActions(const KFileItemList& items) const
 {
     QList<QAction*> actions;
-    if (isVersioned() && m_updateItemStatesThread->beginReadItemStates()) {
+    if (isVersioned() && m_updateItemStatesThread->lockPlugin()) {
         actions = m_plugin->contextMenuActions(items);
-        m_updateItemStatesThread->endReadItemStates();
+        m_updateItemStatesThread->unlockPlugin();
     }
     return actions;
 }
@@ -101,9 +109,9 @@ QList<QAction*> VersionControlObserver::contextMenuActions(const KFileItemList&
 QList<QAction*> VersionControlObserver::contextMenuActions(const QString& directory) const
 {
     QList<QAction*> actions;
-    if (isVersioned() && m_updateItemStatesThread->beginReadItemStates()) {
+    if (isVersioned() && m_updateItemStatesThread->lockPlugin()) {
         actions = m_plugin->contextMenuActions(directory);
-        m_updateItemStatesThread->endReadItemStates();
+        m_updateItemStatesThread->unlockPlugin();
     }
 
     return actions;
@@ -133,16 +141,7 @@ void VersionControlObserver::verifyDirectory()
     }
 
     m_plugin = searchPlugin(versionControlUrl);
-    const bool foundVersionInfo = (m_plugin != 0);
-    if (!foundVersionInfo && m_versionedDirectory) {
-        // Version control systems like Git provide the version information
-        // file only in the root directory. Check whether the version information file can
-        // be found in one of the parent directories.
-
-        // TODO...
-    }
-
-    if (foundVersionInfo) {
+    if (m_plugin != 0) {
         if (!m_versionedDirectory) {
             m_versionedDirectory = true;
 
@@ -177,11 +176,9 @@ void VersionControlObserver::verifyDirectory()
     }
 }
 
-void VersionControlObserver::applyUpdatedItemStates()
+void VersionControlObserver::slotThreadFinished()
 {
     if (m_plugin == 0) {
-        // The signal finished() has been emitted, but the thread has been marked
-        // as invalid in the meantime. Just ignore the signal in this case.
         return;
     }
 
@@ -214,7 +211,7 @@ void VersionControlObserver::applyUpdatedItemStates()
         // operation has been completed because of the icon emblems.
         emit operationCompletedMessage(QString());
     }
-    
+
     if (m_pendingItemStatesUpdate) {
         m_pendingItemStatesUpdate = false;
         updateItemStates();
@@ -227,11 +224,11 @@ void VersionControlObserver::updateItemStates()
     if (m_updateItemStatesThread == 0) {
         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;
     }
@@ -243,7 +240,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
     }
 }
 
@@ -269,7 +266,7 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& director
     static QList<KVersionControlPlugin*> plugins;
 
     if (!pluginsAvailable) {
-        // a searching for plugins has already been done, but no
+        // A searching for plugins has already been done, but no
         // plugins are installed
         return 0;
     }
@@ -277,12 +274,11 @@ 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 QStringList enabledPlugins = VersionControlSettings::enabledPlugins();
 
         const KService::List pluginServices = KServiceTypeTrader::self()->query("FileViewVersionControlPlugin");
         for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) {
-            if (!disabledPluginsList.contains((*it)->name())) {
+            if (enabledPlugins.contains((*it)->name())) {
                 KVersionControlPlugin* plugin = (*it)->createInstance<KVersionControlPlugin>();
                 Q_ASSERT(plugin != 0);
                 plugins.append(plugin);
@@ -294,15 +290,36 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& director
         }
     }
 
-    // verify whether the current directory contains revision information
+    // Verify whether the current directory contains revision information
     // like .svn, .git, ...
     foreach (KVersionControlPlugin* plugin, plugins) {
-        KUrl fileUrl = directory;
+        // Use the KDirLister cache to check for .svn, .git, ... files
+        KUrl dirUrl(directory);
+        KUrl fileUrl = dirUrl;
         fileUrl.addPath(plugin->fileName());
         const KFileItem item = m_dirLister->findByUrl(fileUrl);
         if (!item.isNull()) {
             return plugin;
         }
+
+        // Version control systems like Git provide the version information
+        // file only in the root directory. Check whether the version information file can
+        // be found in one of the parent directories. For performance reasons this
+        // step is only done, if the previous directory was marked as versioned by
+        // m_versionedDirectory. Drawback: Until e. g. Git is recognized, the root directory
+        // must be shown at least once.
+        if (m_versionedDirectory) {
+            KUrl upUrl = dirUrl.upUrl();
+            while (upUrl != dirUrl) {
+                const QString filePath = dirUrl.pathOrUrl(KUrl::AddTrailingSlash) + plugin->fileName();
+                QFileInfo file(filePath);
+                if (file.exists()) {
+                    return plugin;
+                }
+                dirUrl = upUrl;
+                upUrl = dirUrl.upUrl();
+            }
+        }
     }
 
     return 0;