]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Version Control plugin: allow plugins to return repository root
authorMéven Car <meven29@gmail.com>
Sat, 5 Dec 2020 09:19:53 +0000 (10:19 +0100)
committerElvis Angelaccio <elvis.angelaccio@kde.org>
Sun, 27 Dec 2020 17:18:40 +0000 (17:18 +0000)
Currently plugins `fileName()` only return path file extension.

This changes allows plugins to return the absolute file path to their repository root.

CCBUG: 430024

src/views/versioncontrol/kversioncontrolplugin.cpp
src/views/versioncontrol/kversioncontrolplugin.h
src/views/versioncontrol/versioncontrolobserver.cpp
src/views/versioncontrol/versioncontrolobserver.h

index 2e1a4468b839b516b1fa2058fcdc295818601e3d..9cbf0eb5b63774c208a234e5e1cf897a938c9952 100644 (file)
@@ -15,3 +15,8 @@ KVersionControlPlugin::KVersionControlPlugin(QObject* parent) :
 KVersionControlPlugin::~KVersionControlPlugin()
 {
 }
+
+QString KVersionControlPlugin::localRepositoryRoot(const QString &/*directory*/) const
+{
+    return QString();
+}
index 0de305d14fc162033e4cfc29c8c44c4f830adb63..a8894ac17d4c9c09014170ba3374d883de15fe03 100644 (file)
@@ -143,6 +143,12 @@ public:
      */
     virtual QString fileName() const = 0;
 
+    /**
+     * Returns the path of the local repository root for the versionned directory
+     * Returns an emtpy QString when directory is not part of a working copy
+     */
+    virtual QString localRepositoryRoot(const QString& directory) const;
+
     /**
      * Is invoked whenever the version control
      * information will get retrieved for the directory
index c66c639c87fbdd86b92aec1edf01966d546c6fbb..5f7c34194cd43022f2e667dd66124ac69173db21 100644 (file)
@@ -21,7 +21,6 @@
 VersionControlObserver::VersionControlObserver(QObject* parent) :
     QObject(parent),
     m_pendingItemStatesUpdate(false),
-    m_versionedDirectory(false),
     m_silentUpdate(false),
     m_view(nullptr),
     m_model(nullptr),
@@ -114,7 +113,7 @@ QList<QAction*> VersionControlObserver::actions(const KFileItemList& items) cons
     } else {
         QList<QAction*> actions;
         for (const auto &plugin : qAsConst(m_plugins)) {
-            actions << plugin.first->outOfVersionControlActions(items);
+            actions << plugin->outOfVersionControlActions(items);
         }
         return actions;
     }
@@ -155,23 +154,23 @@ void VersionControlObserver::verifyDirectory()
         return;
     }
 
-    m_plugin = searchPlugin(rootItem.url());
-    if (m_plugin) {
-        if (!m_versionedDirectory) {
-            m_versionedDirectory = true;
+    if (m_plugin != nullptr) {
+        if (!rootItem.url().path().startsWith(m_wcRoot) || !QFile::exists(m_wcRoot + '/' + m_plugin->fileName())) {
+            m_plugin = nullptr;
 
-            // The directory is versioned. Assume that the user will further browse through
-            // versioned directories and decrease the verification timer.
-            m_dirVerificationTimer->setInterval(100);
+            // The directory is not versioned. Reset the verification timer to a higher
+            // value, so that browsing through non-versioned directories is not slown down
+            // by an immediate verification.
+            m_dirVerificationTimer->setInterval(500);
+        } else {
+            // View was versionned but should not be anymore
+            updateItemStates();
         }
+    } else if ((m_plugin = searchPlugin(rootItem.url()))) {
+        // The directory is versioned. Assume that the user will further browse through
+        // versioned directories and decrease the verification timer.
+        m_dirVerificationTimer->setInterval(100);
         updateItemStates();
-    } else if (m_versionedDirectory) {
-        m_versionedDirectory = false;
-
-        // The directory is not versioned. Reset the verification timer to a higher
-        // value, so that browsing through non-versioned directories is not slown down
-        // by an immediate verification.
-        m_dirVerificationTimer->setInterval(500);
     }
 }
 
@@ -273,7 +272,7 @@ int VersionControlObserver::createItemStatesList(QMap<QString, QVector<ItemState
     return index - firstIndex; // number of processed items
 }
 
-KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& directory)
+void VersionControlObserver::initPlugins()
 {
     if (!m_pluginsInitialized) {
         // No searching for plugins has been done yet. Query the KServiceTypeTrader for
@@ -294,65 +293,37 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& director
                     connect(plugin, &KVersionControlPlugin::operationCompletedMessage,
                             this, &VersionControlObserver::operationCompletedMessage);
 
-                    m_plugins.append( qMakePair(plugin, plugin->fileName()) );
+                    m_plugins.append(plugin);
                 }
             }
         }
         m_pluginsInitialized = true;
     }
+}
 
-    if (m_plugins.empty()) {
-        // A searching for plugins has already been done, but no
-        // plugins are installed
-        return nullptr;
-    }
-
-    // We use the number of upUrl() calls to find the best matching plugin
-    // for the given directory. The smaller value, the better it is (0 is best).
-    KVersionControlPlugin* bestPlugin = nullptr;
-    int bestScore = INT_MAX;
+KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& directory)
+{
+    initPlugins();
 
-    // Verify whether the current directory contains revision information
-    // like .svn, .git, ...
-    for (const auto &it : qAsConst(m_plugins)) {
-        const QString fileName = directory.path() + '/' + it.second;
+    // Verify whether the current directory is under a version system
+    for (const auto &plugin : qAsConst(m_plugins)) {
+        // first naively check if we are at working copy root
+        const QString fileName = directory.path() + '/' + plugin->fileName();
         if (QFile::exists(fileName)) {
-            // The score of this plugin is 0 (best), so we can just return this plugin,
-            // instead of going through the plugin scoring procedure, we can't find a better one ;)
-            return it.first;
+            m_wcRoot = directory.path();
+            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) {
-            QUrl dirUrl(directory);
-            QUrl upUrl = KIO::upUrl(dirUrl);
-            int upUrlCounter = 1;
-            while ((upUrlCounter < bestScore) && (upUrl != dirUrl)) {
-                const QString fileName = dirUrl.path() + '/' + it.second;
-                if (QFile::exists(fileName)) {
-                    if (upUrlCounter < bestScore) {
-                        bestPlugin = it.first;
-                        bestScore = upUrlCounter;
-                    }
-                    break;
-                }
-                dirUrl = upUrl;
-                upUrl = KIO::upUrl(dirUrl);
-                ++upUrlCounter;
-            }
+        auto wcRoot = plugin->localRepositoryRoot(directory.path());
+        if (!wcRoot.isEmpty()) {
+            m_wcRoot = wcRoot;
+            return plugin;
         }
     }
-
-    return bestPlugin;
+    return nullptr;
 }
 
 bool VersionControlObserver::isVersionControlled() const
 {
-    return m_versionedDirectory && m_plugin;
+    return m_plugin != nullptr;
 }
 
index 89c04714866a3a743c98f724717f921193e1dea9..f6b4d9b5fd4233efc01e30c1e835ffee3db05fcb 100644 (file)
@@ -101,7 +101,6 @@ private slots:
 
 private:
     typedef QPair<KFileItem, KVersionControlPlugin::ItemVersion> ItemState;
-    typedef QPair<KVersionControlPlugin*, QString> VCSPlugin;
 
     void updateItemStates();
 
@@ -133,10 +132,12 @@ private:
     bool isVersionControlled() const;
 
 private:
+    void initPlugins();
+
     bool m_pendingItemStatesUpdate;
-    bool m_versionedDirectory;
     bool m_silentUpdate; // if true, no messages will be send during the update
                          // of version states
+    QString m_wcRoot;
 
     DolphinView* m_view;
     KFileItemModel* m_model;
@@ -145,7 +146,7 @@ private:
 
     bool m_pluginsInitialized;
     KVersionControlPlugin* m_plugin;
-    QList<VCSPlugin> m_plugins;
+    QList<KVersionControlPlugin*> m_plugins;
     UpdateItemStatesThread* m_updateItemStatesThread;
 
     friend class UpdateItemStatesThread;