aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/coreplugin/iversioncontrol.cpp150
-rw-r--r--src/plugins/coreplugin/iversioncontrol.h38
-rw-r--r--src/plugins/fossil/fossilplugin.cpp25
-rw-r--r--src/plugins/git/gitplugin.cpp28
-rw-r--r--src/plugins/mercurial/mercurialplugin.cpp24
-rw-r--r--src/plugins/subversion/subversionplugin.cpp35
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