diff options
Diffstat (limited to 'src/views/versioncontrol')
4 files changed, 53 insertions, 65 deletions
diff --git a/src/views/versioncontrol/kversioncontrolplugin.cpp b/src/views/versioncontrol/kversioncontrolplugin.cpp index 2e1a4468b..9cbf0eb5b 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 0de305d14..aeac5ad29 100644 --- a/src/views/versioncontrol/kversioncontrolplugin.h +++ b/src/views/versioncontrol/kversioncontrolplugin.h @@ -144,6 +144,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 * \p directory. It is assured that the directory @@ -177,6 +183,7 @@ public: * @return List of actions that are available for the out of version control * items \p items. It's opposed to the \p versionedActions. Common usage * is for clone/checkout actions. + * @since 21.04 */ virtual QList<QAction*> outOfVersionControlActions(const KFileItemList& items) const = 0; diff --git a/src/views/versioncontrol/versioncontrolobserver.cpp b/src/views/versioncontrol/versioncontrolobserver.cpp index c66c639c8..cf5be3c91 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), @@ -113,8 +112,8 @@ QList<QAction*> VersionControlObserver::actions(const KFileItemList& items) cons return m_plugin->versionControlActions(items); } else { QList<QAction*> actions; - for (const auto &plugin : qAsConst(m_plugins)) { - actions << plugin.first->outOfVersionControlActions(items); + for (const QPointer<KVersionControlPlugin> &plugin : qAsConst(m_plugins)) { + 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_localRepoRoot) || !QFile::exists(m_localRepoRoot + '/' + 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,41 @@ 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; - } +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 is under a version system + for (const QPointer<KVersionControlPlugin> &plugin : qAsConst(m_plugins)) { + if (!plugin) { + continue; + } - // 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; + // 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_localRepoRoot = 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; - } + const QString root = plugin->localRepositoryRoot(directory.path()); + if (!root.isEmpty()) { + m_localRepoRoot = root; + 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 89c047148..5f425fe85 100644 --- a/src/views/versioncontrol/versioncontrolobserver.h +++ b/src/views/versioncontrol/versioncontrolobserver.h @@ -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_localRepoRoot; DolphinView* m_view; KFileItemModel* m_model; @@ -145,7 +146,7 @@ private: bool m_pluginsInitialized; KVersionControlPlugin* m_plugin; - QList<VCSPlugin> m_plugins; + QList<QPointer<KVersionControlPlugin>> m_plugins; UpdateItemStatesThread* m_updateItemStatesThread; friend class UpdateItemStatesThread; |
