Skip to content

Commit

Permalink
Color nodes of project tree based on the type of VCS change.
Browse files Browse the repository at this point in the history
+ Put tracked and untracked changes into one map
  • Loading branch information
harryherold authored and arBmind committed Apr 2, 2022
1 parent 4c6d594 commit 64094ec
Show file tree
Hide file tree
Showing 14 changed files with 64 additions and 60 deletions.
1 change: 1 addition & 0 deletions share/qtcreator/themes/dark.creatortheme
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ VcsBase_FileModified_TextColor=ff8ee0ff
VcsBase_FileDeleted_TextColor=ffff6c6c
VcsBase_FileRenamed_TextColor=ffffa500
VcsBase_FileUnmerged_TextColor=ffff4040
VcsBase_FolderModified_TextColor=ffbd9c

Bookmarks_TextMarkColor=ff8080ff

Expand Down
1 change: 1 addition & 0 deletions share/qtcreator/themes/default.creatortheme
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ VcsBase_FileModified_TextColor=ff0000ee
VcsBase_FileDeleted_TextColor=ff800000
VcsBase_FileRenamed_TextColor=ffd77d00
VcsBase_FileUnmerged_TextColor=ffee0000
VcsBase_FolderModified_TextColor=cc6600

Bookmarks_TextMarkColor=ffa0a0ff

Expand Down
1 change: 1 addition & 0 deletions share/qtcreator/themes/design-light.creatortheme
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ VcsBase_FileModified_TextColor=ff0000ee
VcsBase_FileDeleted_TextColor=ff800000
VcsBase_FileRenamed_TextColor=ffd77d00
VcsBase_FileUnmerged_TextColor=ffee0000
VcsBase_FolderModified_TextColor=cc6600

Bookmarks_TextMarkColor=ffa0a0ff

Expand Down
1 change: 1 addition & 0 deletions share/qtcreator/themes/design.creatortheme
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ VcsBase_FileModified_TextColor=ff8ee0ff
VcsBase_FileDeleted_TextColor=fffff6c6c
VcsBase_FileRenamed_TextColor=ffffa500
VcsBase_FileUnmerged_TextColor=ffff4040
VcsBase_FolderModified_TextColor=ffbd9c

Bookmarks_TextMarkColor=ff8080ff

Expand Down
1 change: 1 addition & 0 deletions share/qtcreator/themes/flat-dark.creatortheme
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ VcsBase_FileModified_TextColor=ff8ee0ff
VcsBase_FileDeleted_TextColor=fffff6c6c
VcsBase_FileRenamed_TextColor=ffffa500
VcsBase_FileUnmerged_TextColor=ffff4040
VcsBase_FolderModified_TextColor=ffbd9c

Bookmarks_TextMarkColor=ff8080ff

Expand Down
1 change: 1 addition & 0 deletions share/qtcreator/themes/flat-light.creatortheme
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ VcsBase_FileModified_TextColor=ff0000ee
VcsBase_FileDeleted_TextColor=ff800000
VcsBase_FileRenamed_TextColor=ffd77d00
VcsBase_FileUnmerged_TextColor=ffee0000
VcsBase_FolderModified_TextColor=cc6600

Bookmarks_TextMarkColor=ffa0a0ff

Expand Down
1 change: 1 addition & 0 deletions share/qtcreator/themes/flat.creatortheme
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ VcsBase_FileModified_TextColor=ff0000ee
VcsBase_FileDeleted_TextColor=ff800000
VcsBase_FileRenamed_TextColor=ffd77d00
VcsBase_FileUnmerged_TextColor=ffee0000
VcsBase_FolderModified_TextColor=cc6600

Bookmarks_TextMarkColor=ffa0a0ff

Expand Down
1 change: 1 addition & 0 deletions src/libs/utils/theme/theme.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ class QTCREATOR_UTILS_EXPORT Theme : public QObject
VcsBase_FileDeleted_TextColor,
VcsBase_FileRenamed_TextColor,
VcsBase_FileUnmerged_TextColor,
VcsBase_FolderModified_TextColor,

/* Bookmarks Plugin */
Bookmarks_TextMarkColor,
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/coreplugin/iversioncontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ QString IVersionControl::vcsTopic(const FilePath &topLevel)
return m_topicCache ? m_topicCache->topic(topLevel) : QString();
}

ChangeSets IVersionControl::localChanges(const Utils::FilePath &)
VcsChangeSet IVersionControl::localChanges(const Utils::FilePath &)
{
return {};
}
Expand Down
10 changes: 7 additions & 3 deletions src/plugins/coreplugin/iversioncontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ QT_FORWARD_DECLARE_CLASS(QMenu);

namespace Core {

using ChangeSet = QSet<QString>;
using ChangeSets = std::tuple<ChangeSet, ChangeSet>;
enum class VcsChangeType {
FileChanged,
FileUntracked,
FolderContainsChanges,
};
using VcsChangeSet = QHash<QString, VcsChangeType>;

class ShellCommand;

Expand Down Expand Up @@ -202,7 +206,7 @@ class CORE_EXPORT IVersionControl : public QObject
*/
virtual QString vcsTopic(const Utils::FilePath &topLevel);

virtual ChangeSets localChanges(const Utils::FilePath &directory);
virtual VcsChangeSet localChanges(const Utils::FilePath &directory);

/*!
* Display annotation for a file and scroll to line
Expand Down
29 changes: 12 additions & 17 deletions src/plugins/git/gitplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class GitPluginPrivate final : public VcsBase::VcsBasePluginPrivate
void vcsAnnotate(const FilePath &filePath, int line) final;
void vcsDescribe(const FilePath &source, const QString &id) final { m_gitClient.show(source.toString(), id); };
QString vcsTopic(const FilePath &directory) final;
Core::ChangeSets localChanges(const Utils::FilePath &directory) final;
Core::VcsChangeSet localChanges(const Utils::FilePath &directory) final;

Core::ShellCommand *createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory,
Expand Down Expand Up @@ -1918,18 +1918,18 @@ QString GitPluginPrivate::vcsTopic(const FilePath &directory)
return topic;
}

Core::ChangeSets GitPluginPrivate::localChanges(const Utils::FilePath &directory)
Core::VcsChangeSet GitPluginPrivate::localChanges(const Utils::FilePath &directory)
{
QSet<QString> trackedChanges, untrackedChanges;
auto splitPathIntoSet = [&] (const QString& path, QSet<QString> & paths) {
paths.insert(directory.pathAppended(path).toString());
const auto sectionCount = path.count("/");
auto changeSet = Core::VcsChangeSet{};
auto splitFilePath = [&] (const QString& filePath, bool isUntracked) {
auto fileChangeType = isUntracked ? Core::VcsChangeType::FileUntracked : Core::VcsChangeType::FileChanged;
changeSet.insert(directory.pathAppended(filePath).toString(), fileChangeType);
const auto sectionCount = filePath.count("/");
for (auto i = 0; i < sectionCount; ++i)
{
paths.insert(directory.pathAppended(path.section('/', 0, i)).toString());
changeSet.insert(directory.pathAppended(filePath.section('/', 0, i)).toString(), Core::VcsChangeType::FolderContainsChanges);
}
};

QString output = "";
const auto status = m_gitClient.gitStatus(directory,
StatusMode::NoSubmodules,
Expand All @@ -1938,20 +1938,15 @@ Core::ChangeSets GitPluginPrivate::localChanges(const Utils::FilePath &directory
if (status == GitClient::StatusResult::StatusChanged) {
QTextStream stream(&output);
QString line;
untrackedChanges.insert(directory.toString());
trackedChanges.insert(directory.toString());
changeSet.insert(directory.toString(), Core::VcsChangeType::FolderContainsChanges);
while(stream.readLineInto(&line)) {
const auto & classFilePair = line.trimmed().split(QRegularExpression("\\s+"));
Q_ASSERT(classFilePair.count() == 2);
if (classFilePair[0].contains('D') || classFilePair[0].contains('?')) {
splitPathIntoSet(classFilePair[1].trimmed(), untrackedChanges);
}
else {
splitPathIntoSet(classFilePair[1].trimmed(), trackedChanges);
}
bool isUntracked = classFilePair[0].contains('D') || classFilePair[0].contains('?');
splitFilePath(classFilePair[1].trimmed(), isUntracked);
}
}
return {trackedChanges, untrackedChanges};
return changeSet;
}

Core::ShellCommand *GitPluginPrivate::createInitialCheckoutCommand(const QString &url,
Expand Down
27 changes: 16 additions & 11 deletions src/plugins/projectexplorer/projectmodels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,8 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
ProjectVcsStatus * projectVcsStatus = ProjectVcsStatus::instance();

switch (role) {
case Qt::DisplayRole: {
QString displayName = node->displayName();
auto result = projectVcsStatus->hasVcsStatusChanges(nodeForIndex(index));
if (result) {
displayName += "*";
}
return displayName;
}
case Qt::DisplayRole:
return node->displayName();
case Qt::EditRole:
return node->filePath().fileName();
case Qt::ToolTipRole: {
Expand Down Expand Up @@ -263,9 +257,20 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
font.setBold(true);
return font;
}
case Qt::ForegroundRole:
return node->isEnabled() ? QVariant()
: Utils::creatorTheme()->color(Utils::Theme::TextColorDisabled);
case Qt::ForegroundRole: {
if (node->isEnabled() == false) {
return Utils::creatorTheme()->color(Utils::Theme::TextColorDisabled);
}
auto result = projectVcsStatus->vcsStatusChanges(nodeForIndex(index));
if (result.has_value()) {
switch (*result) {
case Core::VcsChangeType::FileChanged : return Utils::creatorTheme()->color(Utils::Theme::VcsBase_FileModified_TextColor);
case Core::VcsChangeType::FileUntracked : return Utils::creatorTheme()->color(Utils::Theme::VcsBase_FileUnmerged_TextColor);
case Core::VcsChangeType::FolderContainsChanges : return Utils::creatorTheme()->color(Utils::Theme::VcsBase_FolderModified_TextColor);
}
}
return QVariant();
}
case Project::FilePathRole:
return node->filePath().toString();
case Project::isParsingRole:
Expand Down
36 changes: 15 additions & 21 deletions src/plugins/projectexplorer/projectvcsstatus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
#include <QJsonArray>
#include <QTimer>

#include <algorithm>

using namespace Core;

namespace ProjectExplorer {
Expand Down Expand Up @@ -52,7 +50,7 @@ ProjectVcsStatus::ProjectVcsStatus(QObject *parent) : QObject(parent)
auto * vcs = Core::VcsManager::findVersionControlForDirectory(Utils::FilePath::fromString(projectPath));
if (!m_projectStatusCache.contains(projectPath) && vcs != nullptr) {
qDebug() << "Register project" << projectPath;
m_projectStatusCache.insert(projectPath, ChangeSets{});
m_projectStatusCache.insert(projectPath, Core::VcsChangeSet{});
}
});
connect(SessionManager::instance(), &SessionManager::projectRemoved,
Expand Down Expand Up @@ -89,44 +87,40 @@ void ProjectVcsStatus::checkStatus()
emit vcsStatusChanged();
}

bool ProjectVcsStatus::hasVcsStatusChanges(ProjectExplorer::Node * node) const
std::optional<Core::VcsChangeType> ProjectVcsStatus::vcsStatusChanges(ProjectExplorer::Node * node) const
{
if (node == nullptr) {
return false;
return std::nullopt;
}
if (auto * fileNode = node->asFileNode()) {
return m_fileNodeFolderMap.contains(fileNode);
auto * fileNode = node->asFileNode();
if (fileNode != nullptr && m_fileNodeFolderMap.contains(fileNode)) {
Q_ASSERT(m_projectStatusCache[m_currentProject].contains(fileNode->filePath().toString()));
return m_projectStatusCache[m_currentProject][fileNode->filePath().toString()];
}
else if (auto * folderNode = node->asFolderNode()) {
for (auto iter = m_filePathNodeMap.constBegin(); iter != m_filePathNodeMap.constEnd(); ++iter) {
if (hasSameStartPath(folderPathOf(folderNode), iter.key()) && m_fileNodeFolderMap.value(iter.value()).contains(folderNode)) {
return true;
return Core::VcsChangeType::FolderContainsChanges;
}
}
}
return false;
return std::nullopt;
}

bool ProjectVcsStatus::updateProjectStatusCache()
{
bool hasTrackedChanges = false;
bool hasUnTrackedChanges = false;
if (m_currentProject.count() != 0) {
auto & changeSet = m_projectStatusCache[m_currentProject];
auto * vcs = Core::VcsManager::findVersionControlForDirectory(Utils::FilePath::fromString(m_currentProject));
if (vcs != nullptr) {
auto [newTrackedChanges, newUntrackedChanges] = vcs->localChanges(Utils::FilePath::fromString(m_currentProject));
hasTrackedChanges |= newTrackedChanges != changeSet.trackedChanges;
if (hasTrackedChanges) {
changeSet.trackedChanges = newTrackedChanges;
}
hasUnTrackedChanges |= newUntrackedChanges != changeSet.untrackedChanges;
if (hasUnTrackedChanges) {
changeSet.untrackedChanges = newUntrackedChanges;
auto newChangeSet = vcs->localChanges(Utils::FilePath::fromString(m_currentProject));
if (newChangeSet != changeSet) {
changeSet = newChangeSet;
return true;
}
}
}
return hasTrackedChanges || hasUnTrackedChanges;
return false;
}

NodeFileList ProjectVcsStatus::changedFileNodesForCurrentProject() const
Expand All @@ -140,7 +134,7 @@ NodeFileList ProjectVcsStatus::changedFileNodesForCurrentProject() const
return {};
}
QHash<QString, ProjectExplorer::FileNode *> fileMap;
const auto & projectStatusCache = m_projectStatusCache.value(project->projectDirectory().toString()).trackedChanges;
const auto & projectStatusCache = m_projectStatusCache.value(project->projectDirectory().toString());
if (projectNode != nullptr) {
projectNode->forEachNode(
[&](FileNode * fileNode) {
Expand Down
12 changes: 5 additions & 7 deletions src/plugins/projectexplorer/projectvcsstatus.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
#include <QObject>

#include <tuple>
#include <optional>

namespace Core {
class IVersionControl;
enum class VcsChangeType;
}

namespace ProjectExplorer {
Expand All @@ -17,13 +19,9 @@ class ProjectVcsStatus : public QObject
Q_OBJECT

public:
using ChangeSet = QSet<QString>;
struct ChangeSets {
ChangeSet untrackedChanges;
ChangeSet trackedChanges;
};
using VcsChangeSet = QHash<QString, Core::VcsChangeType>;

using ProjectStatusMap = QHash<QString, ChangeSets>;
using ProjectStatusMap = QHash<QString, VcsChangeSet>;
using NodeFileList = QList<ProjectExplorer::FileNode *>;

using UnSafeFolderNodePtr = const ProjectExplorer::FolderNode *;
Expand All @@ -36,7 +34,7 @@ class ProjectVcsStatus : public QObject

static ProjectVcsStatus* instance();

bool hasVcsStatusChanges(ProjectExplorer::Node *) const;
std::optional<Core::VcsChangeType> vcsStatusChanges(ProjectExplorer::Node *) const;

ProjectVcsStatus(const ProjectVcsStatus&) = delete;
ProjectVcsStatus &operator=(const ProjectVcsStatus &) = delete;
Expand Down

0 comments on commit 64094ec

Please sign in to comment.