Commit 41c50ec0 authored by Waqar Ahmed's avatar Waqar Ahmed
Browse files

git: show file history initial commit


Signed-off-by: Waqar Ahmed's avatarWaqar Ahmed <waqar.17a@gmail.com>
parent f608f65b
......@@ -64,6 +64,7 @@ target_sources(
gitstatusmodel.cpp
gitcommitdialog.cpp
stashdialog.cpp
filehistorywidget.cpp
tools/kateprojectcodeanalysistoolcppcheck.cpp
tools/kateprojectcodeanalysistoolflake8.cpp
......
#include "filehistorywidget.h"
#include <QDate>
#include <QDebug>
#include <QFileInfo>
#include <QProcess>
#include <QVBoxLayout>
#include <KLocalizedString>
// git log --format=%H%n%aN%n%aE%n%at%n%ct%n%P%n%B --author-date-order
static QList<QByteArray> getFileHistory(const QString &file)
{
QProcess git;
git.setWorkingDirectory(QFileInfo(file).absolutePath());
QStringList args{QStringLiteral("log"),
QStringLiteral("--format=%H%n%aN%n%aE%n%at%n%ct%n%P%n%B"),
QStringLiteral("-z"),
QStringLiteral("--author-date-order"),
file};
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
return git.readAll().split(0x00);
}
return {};
}
struct Commit {
QByteArray hash;
QString authorName;
QString email;
qint64 authorDate;
qint64 commitDate;
QByteArray parentHash;
QString msg;
};
static QVector<Commit> parseCommits(const QList<QByteArray> &raw)
{
QVector<Commit> commits;
commits.reserve(raw.size());
std::transform(raw.cbegin(), raw.cend(), std::back_inserter(commits), [](const QByteArray &r) {
const auto lines = r.split('\n');
if (lines.length() < 7) {
return Commit{};
}
auto hash = lines.at(0);
// qWarning() << hash;
auto author = QString::fromUtf8(lines.at(1));
// qWarning() << author;
auto email = QString::fromUtf8(lines.at(2));
// qWarning() << email;
qint64 authorDate = lines.at(3).toLong();
// qWarning() << authorDate;
qint64 commitDate = lines.at(4).toLong();
// qWarning() << commitDate;
auto parent = lines.at(5);
// qWarning() << parent;
auto msg = QString::fromUtf8(lines.at(6));
// qWarning() << msg;
return Commit{hash, author, email, authorDate, commitDate, parent, msg};
});
return commits;
}
class CommitListModel : public QAbstractListModel
{
public:
CommitListModel(QObject *parent = nullptr)
: QAbstractListModel(parent)
{
}
enum Role { Author = Qt::UserRole + 1, Email, Date, Hash };
int rowCount(const QModelIndex &) const override
{
return m_rows.count();
}
QVariant data(const QModelIndex &index, int role) const override
{
if (!index.isValid()) {
return {};
}
auto row = index.row();
switch (role) {
case Qt::DisplayRole:
return m_rows[row].msg;
case Role::Author:
return m_rows[row].authorName;
case Role::Email:
return m_rows[row].email;
case Role::Date:
return m_rows[row].commitDate;
case Role::Hash:
return m_rows[row].hash;
}
return {};
}
void refresh(const QVector<Commit> &cmts)
{
beginResetModel();
m_rows = cmts;
endResetModel();
}
private:
QVector<Commit> m_rows;
};
FileHistoryWidget::FileHistoryWidget(const QString &file, QWidget *parent)
: QWidget(parent)
, m_file(file)
{
setLayout(new QVBoxLayout);
m_backBtn.setText(i18n("Back"));
connect(&m_backBtn, &QPushButton::clicked, this, &FileHistoryWidget::backClicked);
layout()->addWidget(&m_backBtn);
m_listView = new QListView;
layout()->addWidget(m_listView);
auto model = new CommitListModel(this);
model->refresh(parseCommits(getFileHistory(file)));
m_listView->setModel(model);
}
#ifndef FILEHISTORYWIDGET_H
#define FILEHISTORYWIDGET_H
#include <QListView>
#include <QPushButton>
#include <QWidget>
class FileHistoryWidget : public QWidget
{
Q_OBJECT
public:
explicit FileHistoryWidget(const QString &file, QWidget *parent = nullptr);
private:
QPushButton m_backBtn;
QListView *m_listView;
QString m_file;
Q_SIGNALS:
void backClicked();
};
#endif // FILEHISTORYWIDGET_H
......@@ -128,6 +128,8 @@ void KateProjectTreeViewContextMenu::exec(const QString &filename, const QModelI
auto rename = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18n("&Rename"));
auto history = menu.addAction(i18n("Show File History"));
/**
* run menu and handle the triggered action
*/
......@@ -147,6 +149,8 @@ void KateProjectTreeViewContextMenu::exec(const QString &filename, const QModelI
dlg->show();
} else if (action == rename) {
static_cast<KateProjectViewTree *>(parent)->edit(index);
} else if (action == history) {
showFileHistory(index.data(Qt::UserRole).toString());
} else {
// One of the git actions was triggered
}
......
......@@ -8,14 +8,16 @@
#ifndef KATE_PROJECT_TREE_VIEW_CONTEXT_MENU_H
#define KATE_PROJECT_TREE_VIEW_CONTEXT_MENU_H
#include <QObject>
#include <QPoint>
#include <QString>
class QWidget;
class QModelIndex;
class KateProjectTreeViewContextMenu
class KateProjectTreeViewContextMenu : public QObject
{
Q_OBJECT
public:
/**
* construct project view for given project
......@@ -35,6 +37,11 @@ public:
*/
void exec(const QString &filename, const QModelIndex &index, const QPoint &pos, QWidget *parent);
/**
* emits on clicking Menu->Show File History
*/
Q_SIGNAL void showFileHistory(const QString &file);
protected:
};
......
/* This file is part of the Kate project.
/* This file is part of the Kate project.
*
* SPDX-FileCopyrightText: 2012 Christoph Cullmann <cullmann@kde.org>
*
......@@ -7,6 +7,7 @@
#include "kateprojectview.h"
#include "branchesdialog.h"
#include "filehistorywidget.h"
#include "git/gitutils.h"
#include "gitwidget.h"
#include "kateprojectfiltermodel.h"
......@@ -28,6 +29,7 @@ KateProjectView::KateProjectView(KateProjectPluginView *pluginView, KateProject
: m_pluginView(pluginView)
, m_project(project)
, m_treeView(new KateProjectViewTree(pluginView, project))
, m_stackWidget(new QStackedWidget(this))
, m_filter(new KLineEdit())
, m_branchBtn(new QToolButton)
{
......@@ -38,10 +40,13 @@ KateProjectView::KateProjectView(KateProjectPluginView *pluginView, KateProject
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_branchBtn);
layout->addWidget(m_treeView);
// layout->addWidget(m_treeView);
layout->addWidget(m_stackWidget);
layout->addWidget(m_filter);
setLayout(layout);
m_stackWidget->addWidget(m_treeView);
m_branchBtn->setAutoRaise(true);
m_branchBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
m_branchBtn->setSizePolicy(QSizePolicy::Minimum, m_branchBtn->sizePolicy().verticalPolicy());
......@@ -93,6 +98,9 @@ KateProjectView::KateProjectView(KateProjectPluginView *pluginView, KateProject
connect(&m_branchChangedWatcher, &QFileSystemWatcher::fileChanged, this, [this] {
m_project->reload(true);
});
// file history
connect(m_treeView, &KateProjectViewTree::showFileHistory, this, &KateProjectView::showFileGitHistory);
}
KateProjectView::~KateProjectView()
......@@ -123,3 +131,23 @@ void KateProjectView::filterTextChanged(const QString &filterText)
QTimer::singleShot(100, m_treeView, &QTreeView::expandAll);
}
}
void KateProjectView::setTreeViewAsCurrent()
{
Q_ASSERT(m_treeView != m_stackWidget->currentWidget());
auto currentFileHistory = m_stackWidget->currentWidget();
m_stackWidget->removeWidget(currentFileHistory);
delete currentFileHistory;
m_stackWidget->setCurrentWidget(m_treeView);
}
void KateProjectView::showFileGitHistory(const QString &file)
{
// create on demand and on switch back delete
auto fhs = new FileHistoryWidget(file);
connect(fhs, &FileHistoryWidget::backClicked, this, &KateProjectView::setTreeViewAsCurrent);
m_stackWidget->addWidget(fhs);
m_stackWidget->setCurrentWidget(fhs);
}
......@@ -17,6 +17,8 @@ class KLineEdit;
class KateProjectPluginView;
class BranchesDialog;
class QToolButton;
class QStackedWidget;
class FileHistoryWidget;
/**
* Class representing a view of a project.
......@@ -66,6 +68,10 @@ private Q_SLOTS:
*/
void filterTextChanged(const QString &filterText);
void setTreeViewAsCurrent();
void showFileGitHistory(const QString &file);
private:
/**
* our plugin view
......@@ -82,6 +88,11 @@ private:
*/
KateProjectViewTree *m_treeView;
/**
* Contains treeview + file history commit list
*/
QStackedWidget *m_stackWidget;
/**
* filter
*/
......
......@@ -159,6 +159,7 @@ void KateProjectViewTree::contextMenuEvent(QContextMenuEvent *event)
}
KateProjectTreeViewContextMenu menu;
connect(&menu, &KateProjectTreeViewContextMenu::showFileHistory, this, &KateProjectViewTree::showFileHistory);
menu.exec(filePath, index, viewport()->mapToGlobal(event->pos()), this);
event->accept();
......
......@@ -84,6 +84,9 @@ private:
* our project
*/
KateProject *m_project;
Q_SIGNALS:
void showFileHistory(const QString &file);
};
#endif
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