Commit 031231ab authored by Waqar Ahmed's avatar Waqar Ahmed
Browse files

Implement Stage All UI layer / backend

parent 162d8711
......@@ -78,6 +78,8 @@ QVariant GitStatusModel::data(const QModelIndex &index, int role) const
return QStringLiteral("Conflict (%1)").arg(m_nodes[Conflict].count());
} else if (row == Changed) {
return QStringLiteral("Modified (%1)").arg(m_nodes[Changed].count());
} else {
Q_UNREACHABLE();
}
} else if (role == Qt::FontRole) {
QFont bold;
......@@ -87,7 +89,7 @@ QVariant GitStatusModel::data(const QModelIndex &index, int role) const
static const auto branchIcon = QIcon(QStringLiteral(":/kxmlgui5/kateproject/sc-apps-git.svg"));
return branchIcon;
} else if (role == Role::TreeItemType) {
return ItemType::Node;
return NodeStage + row;
}
} else {
int rootIndex = index.internalId();
......@@ -100,7 +102,7 @@ QVariant GitStatusModel::data(const QModelIndex &index, int role) const
} else if (role == Qt::DecorationRole) {
return QIcon::fromTheme(QMimeDatabase().mimeTypeForFile(m_nodes[rootIndex].at(row).file, QMimeDatabase::MatchExtension).iconName());
} else if (role == Role::TreeItemType) {
return ItemType::File;
return ItemType::NodeFile;
}
}
......@@ -129,47 +131,3 @@ QVector<int> GitStatusModel::emptyRows()
}
return empty;
}
bool GitStatusModel::stageAll(const QModelIndex &idx)
{
if (!idx.isValid()) {
return false;
}
if (idx.internalId() != Root) {
return false;
}
// do actual staging, check for return code
// model update
const auto node = idx.row();
const auto srcSize = m_nodes[node].size();
const auto destSize = m_nodes[Staged].size();
beginMoveRows(createIndex(node, 0, Root), 0, srcSize, createIndex(Staged, 0, Root), destSize);
m_nodes[Staged].append(m_nodes[node]);
m_nodes[node].clear();
endMoveRows();
return true;
}
bool GitStatusModel::stageFile(const QModelIndex &idx)
{
if (!idx.isValid()) {
return false;
}
// do actual staging, check for return code
const auto parent = idx.internalId();
const auto destSize = m_nodes[Staged].size();
beginMoveRows(createIndex(parent, 0, Root), idx.row(), idx.row(), createIndex(Staged, 0, Root), destSize);
auto item = m_nodes[parent].at(idx.row());
m_nodes[Staged].append(item);
m_nodes[parent].remove(idx.row());
endMoveRows();
return true;
}
......@@ -10,7 +10,7 @@ class GitStatusModel : public QAbstractItemModel
public:
explicit GitStatusModel(QObject *parent);
enum ItemType { Node, File };
enum ItemType { NodeStage = 0, NodeChanges, NodeConflict, NodeUntrack, NodeFile };
enum Role { TreeItemType = Qt::UserRole };
public:
......@@ -26,8 +26,20 @@ public:
const QVector<GitUtils::StatusItem> &untracked);
QVector<int> emptyRows();
bool stageFile(const QModelIndex &idx);
bool stageAll(const QModelIndex &idx);
const QVector<GitUtils::StatusItem> &untrackedFiles() const
{
return m_nodes[3];
}
const QVector<GitUtils::StatusItem> &changedFiles() const
{
return m_nodes[1];
}
QModelIndex getModelIndex(ItemType type) const
{
return createIndex(type, 0, 0xFFFFFFFF);
}
private:
QVector<GitUtils::StatusItem> m_nodes[4];
......
......@@ -49,11 +49,17 @@ GitWidget::GitWidget(KateProject *project, QWidget *parent)
getStatus(m_project->baseDir());
}
void GitWidget::getStatus(const QString &repo, bool submodules)
void GitWidget::getStatus(const QString &repo, bool untracked, bool submodules)
{
disconnect(&git, SIGNAL(readyRead()), nullptr, nullptr);
connect(&git, &QProcess::readyRead, this, &GitWidget::gitStatusReady);
auto args = QStringList{QStringLiteral("status"), QStringLiteral("-z"), QStringLiteral("-u")};
auto args = QStringList{QStringLiteral("status"), QStringLiteral("-z")};
if (!untracked) {
args.append(QStringLiteral("-uno"));
} else {
args.append(QStringLiteral("-u"));
}
if (!submodules) {
args.append(QStringLiteral("--ignore-submodules"));
}
......@@ -63,6 +69,26 @@ void GitWidget::getStatus(const QString &repo, bool submodules)
git.start();
}
void GitWidget::stageAll(bool untracked)
{
auto args = QStringList{QStringLiteral("add"), QStringLiteral("-A"), QStringLiteral("--")};
const QVector<GitUtils::StatusItem> &files = untracked ? m_model->untrackedFiles() : m_model->changedFiles();
args.reserve(args.size() + files.size());
for (const auto &file : files) {
args.append(file.file);
}
git.setWorkingDirectory(m_project->baseDir());
git.setProgram(QStringLiteral("git"));
git.setArguments(args);
git.start();
if (git.waitForStarted() && git.waitForFinished(-1)) {
getStatus(m_project->baseDir());
}
}
void GitWidget::gitStatusReady()
{
disconnect(&git, &QProcess::readyRead, this, &GitWidget::gitStatusReady);
......@@ -167,6 +193,9 @@ void GitWidget::hideEmptyTreeNodes()
m_treeView->setRowHidden(i, QModelIndex(), true);
} else {
m_treeView->setRowHidden(i, QModelIndex(), false);
if (i != GitStatusModel::NodeUntrack) {
m_treeView->expand(m_model->getModelIndex((GitStatusModel::ItemType)i));
}
}
}
}
......@@ -195,22 +224,27 @@ void GitWidget::treeViewContextMenuEvent(QContextMenuEvent *e)
auto idx = m_model->index(m_treeView->currentIndex().row(), 0, m_treeView->currentIndex().parent());
auto type = idx.data(GitStatusModel::TreeItemType);
if (type == GitStatusModel::Node) {
if (type == GitStatusModel::NodeChanges || type == GitStatusModel::NodeUntrack) {
QMenu menu;
auto stage = menu.addAction(i18n("Stage All"));
auto act = menu.exec(m_treeView->viewport()->mapToGlobal(e->pos()));
if (act == stage) {
m_model->stageAll(m_treeView->currentIndex());
hideEmptyTreeNodes();
stageAll(type == GitStatusModel::NodeUntrack);
}
} else if (type == GitStatusModel::File) {
} else if (type == GitStatusModel::NodeFile) {
QMenu menu;
auto stage = menu.addAction(i18n("Stage file"));
auto act = menu.exec(m_treeView->viewport()->mapToGlobal(e->pos()));
if (act == stage) {
m_model->stageFile(m_treeView->currentIndex());
hideEmptyTreeNodes();
}
} else if (type == GitStatusModel::NodeStage) {
QMenu menu;
auto stage = menu.addAction(i18n("Unstage All"));
auto act = menu.exec(m_treeView->viewport()->mapToGlobal(e->pos()));
if (act == stage) {
hideEmptyTreeNodes();
}
}
......
......@@ -37,7 +37,9 @@ private:
QProcess git;
QFutureWatcher<GitParsedStatus> m_gitStatusWatcher;
void getStatus(const QString &repo, bool submodules = false);
void getStatus(const QString &repo, bool untracked = true, bool submodules = false);
void stageAll(bool untracked = false);
GitParsedStatus parseStatus(const QByteArray &raw);
void hideEmptyTreeNodes();
void treeViewContextMenuEvent(QContextMenuEvent *e);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment