diff --git a/src/views/versioncontrol/kversioncontrolplugin.cpp b/src/views/versioncontrol/kversioncontrolplugin.cpp index 2e1a4468b8..9cbf0eb5b6 100644 --- a/src/views/versioncontrol/kversioncontrolplugin.cpp +++ b/src/views/versioncontrol/kversioncontrolplugin.cpp @@ -15,3 +15,8 @@ KVersionControlPlugin::KVersionControlPlugin(QObject* parent) : KVersionControlPlugin::~KVersionControlPlugin() { } + +QString KVersionControlPlugin::localRepositoryRoot(const QString &/*directory*/) const +{ + return QString(); +} diff --git a/src/views/versioncontrol/kversioncontrolplugin.h b/src/views/versioncontrol/kversioncontrolplugin.h index 0de305d14f..a8894ac17d 100644 --- a/src/views/versioncontrol/kversioncontrolplugin.h +++ b/src/views/versioncontrol/kversioncontrolplugin.h @@ -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 diff --git a/src/views/versioncontrol/versioncontrolobserver.cpp b/src/views/versioncontrol/versioncontrolobserver.cpp index c66c639c87..5f7c34194c 100644 --- a/src/views/versioncontrol/versioncontrolobserver.cpp +++ b/src/views/versioncontrol/versioncontrolobserver.cpp @@ -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 VersionControlObserver::actions(const KFileItemList& items) cons } else { QList 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(QMapfileName()) ); + 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; - } +KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& directory) +{ + initPlugins(); - // 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; - - // 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; } diff --git a/src/views/versioncontrol/versioncontrolobserver.h b/src/views/versioncontrol/versioncontrolobserver.h index 89c0471486..f6b4d9b5fd 100644 --- a/src/views/versioncontrol/versioncontrolobserver.h +++ b/src/views/versioncontrol/versioncontrolobserver.h @@ -101,7 +101,6 @@ private slots: private: typedef QPair ItemState; - typedef QPair 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 m_plugins; + QList m_plugins; UpdateItemStatesThread* m_updateItemStatesThread; friend class UpdateItemStatesThread;