diff options
author | hjk <[email protected]> | 2024-02-07 16:13:22 +0100 |
---|---|---|
committer | hjk <[email protected]> | 2024-02-09 16:00:56 +0000 |
commit | 0b44cc5589a0fb94271131bfa2cddfc61b58bced (patch) | |
tree | fa0df0613a69af8e6ac4c40053efb1d2e215c0a9 /src | |
parent | 5a643b1c0a33daf8bac64e3c7688af8b80956dd4 (diff) |
Vcs: Hide topic cache in new IVersionControl pimpl
Potentially more stable api long-term. Also simplifies the
user side code a bit.
Change-Id: I6913e27e2a5dc14907e72f252081cdbed34842a3
Reviewed-by: Orgad Shaneh <[email protected]>
Reviewed-by: <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/coreplugin/iversioncontrol.cpp | 150 | ||||
-rw-r--r-- | src/plugins/coreplugin/iversioncontrol.h | 38 | ||||
-rw-r--r-- | src/plugins/fossil/fossilplugin.cpp | 25 | ||||
-rw-r--r-- | src/plugins/git/gitplugin.cpp | 28 | ||||
-rw-r--r-- | src/plugins/mercurial/mercurialplugin.cpp | 24 | ||||
-rw-r--r-- | src/plugins/subversion/subversionplugin.cpp | 35 |
6 files changed, 129 insertions, 171 deletions
diff --git a/src/plugins/coreplugin/iversioncontrol.cpp b/src/plugins/coreplugin/iversioncontrol.cpp index 4cbc8050a26..f70e4be492e 100644 --- a/src/plugins/coreplugin/iversioncontrol.cpp +++ b/src/plugins/coreplugin/iversioncontrol.cpp @@ -14,43 +14,39 @@ #include <QRegularExpression> #include <QStringList> -/*! - \class Core::IVersionControl::TopicCache - \inheaderfile coreplugin/iversioncontrol.h - \inmodule QtCreator - - \brief The TopicCache class stores a cache which maps a directory to a topic. - - A VCS topic is typically the current active branch name, but it can also have other - values (for example the latest tag) when there is no active branch. +using namespace Utils; - It is displayed: - \list - \li In the project tree, next to each root project - corresponding to the project. - \li In the main window title - corresponding to the current active editor. - \endlist +namespace Core { - In order to enable topic display, an IVersionControl subclass needs to create - an instance of the TopicCache subclass with appropriate overrides for its - pure virtual functions, and pass this instance to IVersionControl's constructor. +namespace Internal { - The cache tracks a file in the repository, which is expected to change when the - topic changes. When the file is modified, the cache is refreshed. - For example: for Git this file is typically <repository>/.git/HEAD - */ +class TopicData +{ +public: + QDateTime timeStamp; + QString topic; +}; -/*! - \fn Utils::FilePath Core::IVersionControl::TopicCache::trackFile(const Utils::FilePath &repository) - Returns the path to the file that invalidates the cache for \a repository when - the file is modified. +class IVersionControlPrivate +{ +public: + IVersionControl::FileTracker m_fileTracker; + IVersionControl::TopicRefresher m_topicRefresher; + QHash<FilePath, TopicData> m_topicCache; +}; - \fn QString Core::IVersionControl::TopicCache::refreshTopic(const Utils::FilePath &repository) - Returns the current topic for \a repository. - */ +} // Internal -using namespace Utils; +IVersionControl::IVersionControl() + : d(new Internal::IVersionControlPrivate) +{ + Core::VcsManager::addVersionControl(this); +} -namespace Core { +IVersionControl::~IVersionControl() +{ + delete d; +} QString IVersionControl::vcsOpenText() const { @@ -111,50 +107,49 @@ IVersionControl::RepoUrl IVersionControl::getRepoUrl(const QString &location) co return RepoUrl(location); } -void IVersionControl::setTopicCache(TopicCache *topicCache) +FilePath IVersionControl::trackFile(const FilePath &repository) { - m_topicCache = topicCache; + QTC_ASSERT(d->m_fileTracker, return {}); + return d->m_fileTracker(repository); } -QString IVersionControl::vcsTopic(const FilePath &topLevel) +QString IVersionControl::refreshTopic(const FilePath &repository) { - return m_topicCache ? m_topicCache->topic(topLevel) : QString(); + QTC_ASSERT(d->m_topicRefresher, return {}); + return d->m_topicRefresher(repository); } -IVersionControl::IVersionControl() -{ - Core::VcsManager::addVersionControl(this); -} +/*! + Returns the topic for repository under \a topLevel. -IVersionControl::~IVersionControl() -{ - delete m_topicCache; -} + A VCS topic is typically the current active branch name, but it can also have other + values (for example the latest tag) when there is no active branch. -FilePaths IVersionControl::unmanagedFiles(const FilePaths &filePaths) const -{ - return Utils::filtered(filePaths, [this](const FilePath &fp) { - return !managesFile(fp.parentDir(), fp.fileName()); - }); -} + It is displayed: + \list + \li In the project tree, next to each root project - corresponding to the project. + \li In the main window title - corresponding to the current active editor. + \endlist -IVersionControl::OpenSupportMode IVersionControl::openSupportMode(const FilePath &filePath) const -{ - Q_UNUSED(filePath) - return NoOpen; -} + In order to enable topic display, an IVersionControl subclass needs to create + an instance of the TopicCache subclass with appropriate overrides for its + pure virtual functions, and pass this instance to IVersionControl's constructor. -IVersionControl::TopicCache::~TopicCache() = default; + The cache tracks a file in the repository, which is expected to change when the + topic changes. When the file is modified, the cache is refreshed. + For example: for Git this file is typically <repository>/.git/HEAD -/*! - Returns the topic for repository under \a topLevel. + The base implementation features a cache. If the cache for \a topLevel is valid, + it will be used. Otherwise it will be refreshed using the items provided by + \c setTopicFileTracker() and \c setTopicRefresher(). - If the cache for \a topLevel is valid, it will be used. Otherwise it will be refreshed. + \sa setTopicFileTracker(), setTopicRefresher(). */ -QString IVersionControl::TopicCache::topic(const FilePath &topLevel) + +QString IVersionControl::vcsTopic(const FilePath &topLevel) { QTC_ASSERT(!topLevel.isEmpty(), return QString()); - TopicData &data = m_cache[topLevel]; + Internal::TopicData &data = d->m_topicCache[topLevel]; const FilePath file = trackFile(topLevel); if (file.isEmpty()) @@ -166,6 +161,43 @@ QString IVersionControl::TopicCache::topic(const FilePath &topLevel) return data.topic = refreshTopic(topLevel); } +/*! + Provides the \a fileTracker function object for use in \c vscTopic() cache handling. + + The parameter object takes a repository as input and returns the file + that should trigger topic refresh (e.g. .git/HEAD for Git). + + Modification of this file will invalidate the internal topic cache for the repository. +*/ + +void IVersionControl::setTopicFileTracker(const FileTracker &fileTracker) +{ + d->m_fileTracker = fileTracker; +} + +/*! + Provides the \a topicRefresher function object for use in \c vscTopic() cache handling. + + The parameter object takes a repository as input and returns its current topic. + */ + +void IVersionControl::setTopicRefresher(const TopicRefresher &topicRefresher) +{ + d->m_topicRefresher = topicRefresher; +} + +FilePaths IVersionControl::unmanagedFiles(const FilePaths &filePaths) const +{ + return Utils::filtered(filePaths, [this](const FilePath &fp) { + return !managesFile(fp.parentDir(), fp.fileName()); + }); +} + +IVersionControl::OpenSupportMode IVersionControl::openSupportMode(const FilePath &filePath) const +{ + Q_UNUSED(filePath) + return NoOpen; +} void IVersionControl::fillLinkContextMenu(QMenu *, const FilePath &, const QString &) { } diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h index e97749ca1b2..31e35437770 100644 --- a/src/plugins/coreplugin/iversioncontrol.h +++ b/src/plugins/coreplugin/iversioncontrol.h @@ -8,16 +8,15 @@ #include <utils/id.h> #include <utils/filepath.h> -#include <QDateTime> #include <QFlags> -#include <QHash> #include <QObject> -#include <QString> QT_FORWARD_DECLARE_CLASS(QMenu); namespace Core { +namespace Internal { class IVersionControlPrivate; } + class CORE_EXPORT IVersionControl : public QObject { Q_OBJECT @@ -43,28 +42,6 @@ public: OpenMandatory /*!< Files must always be opened by the VCS */ }; - class CORE_EXPORT TopicCache - { - public: - virtual ~TopicCache(); - QString topic(const Utils::FilePath &topLevel); - - protected: - virtual Utils::FilePath trackFile(const Utils::FilePath &repository) = 0; - virtual QString refreshTopic(const Utils::FilePath &repository) = 0; - - private: - class TopicData - { - public: - QDateTime timeStamp; - QString topic; - }; - - QHash<Utils::FilePath, TopicData> m_cache; - - }; - IVersionControl(); ~IVersionControl() override; @@ -218,7 +195,14 @@ public: }; virtual RepoUrl getRepoUrl(const QString &location) const; - void setTopicCache(TopicCache *topicCache); + // Topic cache + using FileTracker = std::function<Utils::FilePath(const Utils::FilePath &)>; + Utils::FilePath trackFile(const Utils::FilePath &repository); + void setTopicFileTracker(const FileTracker &fileTracker); + + using TopicRefresher = std::function<QString(const Utils::FilePath &)>; + QString refreshTopic(const Utils::FilePath &repository); + void setTopicRefresher(const TopicRefresher &topicRefresher); signals: void repositoryChanged(const Utils::FilePath &repository); @@ -226,7 +210,7 @@ signals: void configurationChanged(); private: - TopicCache *m_topicCache = nullptr; + Internal::IVersionControlPrivate *d; }; } // namespace Core diff --git a/src/plugins/fossil/fossilplugin.cpp b/src/plugins/fossil/fossilplugin.cpp index b09ffda013b..25fcdfa923a 100644 --- a/src/plugins/fossil/fossilplugin.cpp +++ b/src/plugins/fossil/fossilplugin.cpp @@ -61,23 +61,6 @@ using namespace std::placeholders; namespace Fossil::Internal { -class FossilTopicCache final : public IVersionControl::TopicCache -{ -public: - FossilTopicCache() = default; - -protected: - FilePath trackFile(const FilePath &repository) final - { - return repository.pathAppended(Constants::FOSSILREPO); - } - - QString refreshTopic(const FilePath &repository) final - { - return fossilClient().synchronousTopic(repository); - } -}; - class FossilPluginPrivate final : public VersionControlBase { public: @@ -222,7 +205,13 @@ FossilPluginPrivate::FossilPluginPrivate() { Context context(Constants::FOSSIL_CONTEXT); - setTopicCache(new FossilTopicCache); + setTopicFileTracker([](const FilePath &repository) { + return repository.pathAppended(Constants::FOSSILREPO); + }); + setTopicRefresher([](const FilePath &repository) { + return fossilClient().synchronousTopic(repository); + }); + connect(&fossilClient(), &VcsBaseClient::changed, this, &FossilPluginPrivate::changed); m_commandLocator = new CommandLocator("Fossil", "fossil", "fossil", this); diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 9535f14128d..915796bdbf0 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -382,25 +382,6 @@ public: static GitPluginPrivate *dd = nullptr; -class GitTopicCache : public IVersionControl::TopicCache -{ -public: - GitTopicCache() {} - -protected: - FilePath trackFile(const FilePath &repository) override - { - const FilePath gitDir = gitClient().findGitDirForRepository(repository); - return gitDir.isEmpty() ? FilePath() : gitDir / "HEAD"; - } - - QString refreshTopic(const FilePath &repository) override - { - emit dd->repositoryChanged(repository); - return gitClient().synchronousTopic(repository); - } -}; - GitPluginPrivate::~GitPluginPrivate() { cleanCommitMessageFile(); @@ -560,7 +541,14 @@ GitPluginPrivate::GitPluginPrivate() { dd = this; - setTopicCache(new GitTopicCache); + setTopicFileTracker([](const FilePath &repository) { + const FilePath gitDir = gitClient().findGitDirForRepository(repository); + return gitDir.isEmpty() ? FilePath() : gitDir / "HEAD"; + }); + setTopicRefresher([this](const FilePath &repository) { + emit repositoryChanged(repository); + return gitClient().synchronousTopic(repository); + }); m_fileActions.reserve(10); m_projectActions.reserve(10); diff --git a/src/plugins/mercurial/mercurialplugin.cpp b/src/plugins/mercurial/mercurialplugin.cpp index 1fa1fc8155e..91c25139d9f 100644 --- a/src/plugins/mercurial/mercurialplugin.cpp +++ b/src/plugins/mercurial/mercurialplugin.cpp @@ -51,23 +51,6 @@ using namespace std::placeholders; namespace Mercurial::Internal { -class MercurialTopicCache : public Core::IVersionControl::TopicCache -{ -public: - MercurialTopicCache() = default; - -protected: - FilePath trackFile(const FilePath &repository) override - { - return repository.pathAppended(".hg/branch"); - } - - QString refreshTopic(const FilePath &repository) override - { - return mercurialClient().branchQuerySync(repository.toString()); - } -}; - class MercurialPluginPrivate final : public VcsBase::VersionControlBase { public: @@ -203,7 +186,12 @@ MercurialPluginPrivate::MercurialPluginPrivate() [] { return new CommitEditor; } }); - setTopicCache(new MercurialTopicCache); + setTopicFileTracker([](const FilePath &repository) { + return repository.pathAppended(".hg/branch"); + }); + setTopicRefresher([](const FilePath &repository) { + return mercurialClient().branchQuerySync(repository.toString()); + }); Core::Context context(Constants::MERCURIAL_CONTEXT); diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 95a774e1f83..cab80c64d0d 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -126,24 +126,6 @@ static inline QStringList svnDirectories() return rc; } -class SubversionPluginPrivate; - -class SubversionTopicCache : public Core::IVersionControl::TopicCache -{ -public: - SubversionTopicCache(SubversionPluginPrivate *plugin) : - m_plugin(plugin) - { } - -protected: - FilePath trackFile(const FilePath &repository) override; - - QString refreshTopic(const FilePath &repository) override; - -private: - SubversionPluginPrivate *m_plugin; -}; - class SubversionPluginPrivate final : public VcsBase::VersionControlBase { public: @@ -312,7 +294,12 @@ SubversionPluginPrivate::SubversionPluginPrivate() { dd = this; - setTopicCache(new SubversionTopicCache(this)); + setTopicFileTracker([this](const FilePath &repository) { + return FilePath::fromString(monitorFile(repository)); + }); + setTopicRefresher([this](const FilePath &repository) { + return synchronousTopic(repository); + }); using namespace Constants; using namespace Core::Constants; @@ -1153,16 +1140,6 @@ VcsCommand *SubversionPluginPrivate::createInitialCheckoutCommand(const QString return command; } -FilePath SubversionTopicCache::trackFile(const FilePath &repository) -{ - return FilePath::fromString(m_plugin->monitorFile(repository)); -} - -QString SubversionTopicCache::refreshTopic(const FilePath &repository) -{ - return m_plugin->synchronousTopic(repository); -} - #ifdef WITH_TESTS |