- enhancement: git - log
This commit is contained in:
parent
adb201b4c1
commit
13993bbc3c
3
NEWS.md
3
NEWS.md
|
@ -1,3 +1,6 @@
|
|||
Red Panda C++ Version 0.14.4
|
||||
- enhancement: git - log
|
||||
|
||||
Red Panda C++ Version 0.14.3
|
||||
- fix: wrong code completion font size, when screen dpi changed
|
||||
- enhancement: replace Files View Panel's path lineedit control with combo box
|
||||
|
|
|
@ -10,7 +10,7 @@ isEmpty(APP_NAME) {
|
|||
}
|
||||
|
||||
isEmpty(APP_VERSION) {
|
||||
APP_VERSION=0.14.3
|
||||
APP_VERSION=0.14.4
|
||||
}
|
||||
|
||||
isEmpty(PREFIX) {
|
||||
|
@ -92,6 +92,7 @@ SOURCES += \
|
|||
todoparser.cpp \
|
||||
toolsmanager.cpp \
|
||||
vcs/gitbranchdialog.cpp \
|
||||
vcs/gitlogdialog.cpp \
|
||||
vcs/gitmanager.cpp \
|
||||
vcs/gitmergedialog.cpp \
|
||||
vcs/gitrepository.cpp \
|
||||
|
@ -227,6 +228,7 @@ HEADERS += \
|
|||
todoparser.h \
|
||||
toolsmanager.h \
|
||||
vcs/gitbranchdialog.h \
|
||||
vcs/gitlogdialog.h \
|
||||
vcs/gitmanager.h \
|
||||
vcs/gitmergedialog.h \
|
||||
vcs/gitrepository.h \
|
||||
|
@ -326,6 +328,7 @@ FORMS += \
|
|||
settingsdialog/toolsgeneralwidget.ui \
|
||||
settingsdialog/toolsgitwidget.ui \
|
||||
vcs/gitbranchdialog.ui \
|
||||
vcs/gitlogdialog.ui \
|
||||
vcs/gitmergedialog.ui \
|
||||
widgets/aboutdialog.ui \
|
||||
widgets/cpudialog.ui \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -43,6 +43,7 @@
|
|||
#include "vcs/gitrepository.h"
|
||||
#include "vcs/gitbranchdialog.h"
|
||||
#include "vcs/gitmergedialog.h"
|
||||
#include "vcs/gitlogdialog.h"
|
||||
#include "widgets/infomessagebox.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
|
@ -3092,6 +3093,7 @@ void MainWindow::onProjectViewContextMenu(const QPoint &pos)
|
|||
if (shouldAdd)
|
||||
vcsMenu.addAction(ui->actionGit_Add_Files);
|
||||
}
|
||||
vcsMenu.addAction(ui->actionGit_Log);
|
||||
vcsMenu.addAction(ui->actionGit_Branch);
|
||||
vcsMenu.addAction(ui->actionGit_Merge);
|
||||
vcsMenu.addAction(ui->actionGit_Commit);
|
||||
|
@ -3099,9 +3101,10 @@ void MainWindow::onProjectViewContextMenu(const QPoint &pos)
|
|||
|
||||
bool canBranch = !mProject->model()->iconProvider()->VCSRepository()->hasChangedFiles()
|
||||
&& !mProject->model()->iconProvider()->VCSRepository()->hasStagedFiles();
|
||||
ui->actionGit_Branch->setEnabled(canBranch);
|
||||
ui->actionGit_Merge->setEnabled(canBranch);
|
||||
ui->actionGit_Commit->setEnabled(canBranch);
|
||||
ui->actionGit_Branch->setEnabled(true);
|
||||
ui->actionGit_Commit->setEnabled(true);
|
||||
ui->actionGit_Log->setEnabled(true);
|
||||
ui->actionGit_Restore->setEnabled(true);
|
||||
|
||||
// vcsMenu.addAction(ui->actionGit_Reset);
|
||||
|
@ -3212,6 +3215,7 @@ void MainWindow::onFilesViewContextMenu(const QPoint &pos)
|
|||
if (shouldAdd)
|
||||
vcsMenu.addAction(ui->actionGit_Add_Files);
|
||||
}
|
||||
vcsMenu.addAction(ui->actionGit_Log);
|
||||
vcsMenu.addAction(ui->actionGit_Branch);
|
||||
vcsMenu.addAction(ui->actionGit_Merge);
|
||||
vcsMenu.addAction(ui->actionGit_Commit);
|
||||
|
@ -3221,6 +3225,7 @@ void MainWindow::onFilesViewContextMenu(const QPoint &pos)
|
|||
&& !mFileSystemModelIconProvider.VCSRepository()->hasStagedFiles();
|
||||
ui->actionGit_Branch->setEnabled(canBranch);
|
||||
ui->actionGit_Merge->setEnabled(canBranch);
|
||||
ui->actionGit_Log->setEnabled(true);
|
||||
ui->actionGit_Commit->setEnabled(true);
|
||||
ui->actionGit_Restore->setEnabled(true);
|
||||
|
||||
|
@ -5736,6 +5741,7 @@ void MainWindow::updateVCSActions()
|
|||
&& !mFileSystemModelIconProvider.VCSRepository()->hasStagedFiles();
|
||||
}
|
||||
ui->actionGit_Create_Repository->setEnabled(!hasRepository && shouldEnable);
|
||||
ui->actionGit_Log->setEnabled(hasRepository && shouldEnable);
|
||||
ui->actionGit_Commit->setEnabled(hasRepository && shouldEnable);
|
||||
ui->actionGit_Branch->setEnabled(hasRepository && shouldEnable && canBranch);
|
||||
ui->actionGit_Merge->setEnabled(hasRepository && shouldEnable && canBranch);
|
||||
|
@ -6877,3 +6883,27 @@ void MainWindow::on_actionGit_Merge_triggered()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionGit_Log_triggered()
|
||||
{
|
||||
QString folder;
|
||||
if (ui->treeFiles->isVisible()) {
|
||||
folder = pSettings->environment().currentFolder();
|
||||
} else if (ui->projectView->isVisible() && mProject) {
|
||||
folder = mProject->folder();
|
||||
}
|
||||
if (folder.isEmpty())
|
||||
return;
|
||||
GitLogDialog dialog(folder);
|
||||
if (dialog.exec()==QDialog::Accepted) {
|
||||
//update project view
|
||||
if (mProject) {
|
||||
mProject->model()->beginUpdate();
|
||||
mProject->model()->endUpdate();
|
||||
}
|
||||
//update files view
|
||||
setFilesViewRoot(pSettings->environment().currentFolder());
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
|
|
|
@ -594,6 +594,8 @@ private slots:
|
|||
|
||||
void on_actionGit_Merge_triggered();
|
||||
|
||||
void on_actionGit_Log_triggered();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
EditorList *mEditorList;
|
||||
|
|
|
@ -542,7 +542,7 @@
|
|||
<enum>QTabWidget::South</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
|
@ -1603,6 +1603,7 @@
|
|||
</property>
|
||||
<addaction name="actionGit_Create_Repository"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionGit_Log"/>
|
||||
<addaction name="actionGit_Branch"/>
|
||||
<addaction name="actionGit_Merge"/>
|
||||
<addaction name="separator"/>
|
||||
|
@ -2802,6 +2803,14 @@
|
|||
<string>Merge</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGit_Log">
|
||||
<property name="text">
|
||||
<string>Show Log</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Show Log</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
#include "gitlogdialog.h"
|
||||
#include "ui_gitlogdialog.h"
|
||||
#include "gitmanager.h"
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
GitLogDialog::GitLogDialog(const QString& folder, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::GitLogDialog),
|
||||
mModel(folder)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tblLogs->setModel(&mModel);
|
||||
ui->tblLogs->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
|
||||
connect(ui->tblLogs,&QTableView::customContextMenuRequested,
|
||||
this, &GitLogDialog::onLogsContextMenu);
|
||||
}
|
||||
|
||||
GitLogDialog::~GitLogDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
GitLogModel::GitLogModel(const QString &folder, QObject *parent):
|
||||
QAbstractTableModel(parent),mFolder(folder)
|
||||
{
|
||||
GitManager manager;
|
||||
mCount = manager.logCounts(folder);
|
||||
}
|
||||
|
||||
int GitLogModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return mCount;
|
||||
}
|
||||
|
||||
int GitLogModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
QVariant GitLogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
if (role == Qt::DisplayRole) {
|
||||
int row = index.row();
|
||||
GitManager manager;
|
||||
QList<PGitCommitInfo> listCommitInfos =
|
||||
manager.log(mFolder,row,1);
|
||||
if (listCommitInfos.isEmpty()) {
|
||||
return QVariant();
|
||||
}
|
||||
switch(index.column()) {
|
||||
case 0:
|
||||
return listCommitInfos[0]->authorDate;
|
||||
case 1:
|
||||
return listCommitInfos[0]->author;
|
||||
case 2:
|
||||
return listCommitInfos[0]->title;
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant GitLogModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation==Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
switch(section) {
|
||||
case 0:
|
||||
return tr("Date");
|
||||
case 1:
|
||||
return tr("Author");
|
||||
case 2:
|
||||
return tr("Title");
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
const QString &GitLogModel::folder() const
|
||||
{
|
||||
return mFolder;
|
||||
}
|
||||
|
||||
void GitLogDialog::on_btnClose_clicked()
|
||||
{
|
||||
reject();
|
||||
}
|
||||
|
||||
void GitLogDialog::onLogsContextMenu(const QPoint &pos)
|
||||
{
|
||||
QMenu menu(this);
|
||||
QString branch;
|
||||
GitManager manager;
|
||||
if (!manager.hasRepository(mModel.folder(), branch))
|
||||
return;
|
||||
menu.addAction(ui->actionRevert);
|
||||
menu.addAction(ui->actionReset);
|
||||
menu.addAction(ui->actionBranch);
|
||||
menu.addAction(ui->actionTag);
|
||||
ui->actionReset->setText(tr("Reset \"%1\" to this...").arg(branch));
|
||||
ui->actionRevert->setText(tr("Revert \"%1\" to this...").arg(branch));
|
||||
ui->actionBranch->setText(tr("Create Branch at this version..."));
|
||||
ui->actionTag->setText(tr("Create Tag at this version..."));
|
||||
menu.exec(ui->tblLogs->mapToGlobal(pos));
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef GITLOGDIALOG_H
|
||||
#define GITLOGDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QAbstractTableModel>
|
||||
#include <QMap>
|
||||
#include "gitutils.h"
|
||||
|
||||
namespace Ui {
|
||||
class GitLogDialog;
|
||||
}
|
||||
|
||||
class GitLogModel: public QAbstractTableModel {
|
||||
public:
|
||||
explicit GitLogModel(const QString& folder,QObject *parent = nullptr);
|
||||
|
||||
// QAbstractItemModel interface
|
||||
public:
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
const QString &folder() const;
|
||||
|
||||
private:
|
||||
QString mFolder;
|
||||
int mCount;
|
||||
QMap<int,PGitCommitInfo> mGitCommitInfos;
|
||||
};
|
||||
|
||||
class GitLogDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GitLogDialog(const QString& folder, QWidget *parent = nullptr);
|
||||
~GitLogDialog();
|
||||
|
||||
private slots:
|
||||
void on_btnClose_clicked();
|
||||
void onLogsContextMenu(const QPoint &pos);
|
||||
|
||||
private:
|
||||
Ui::GitLogDialog *ui;
|
||||
GitLogModel mModel;
|
||||
};
|
||||
|
||||
#endif // GITLOGDIALOG_H
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GitLogDialog</class>
|
||||
<widget class="QDialog" name="GitLogDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>922</width>
|
||||
<height>613</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Git Log</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableView" name="tblLogs">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>250</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>795</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnClose">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionReset">
|
||||
<property name="text">
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRevert">
|
||||
<property name="text">
|
||||
<string>Revert</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionBranch">
|
||||
<property name="text">
|
||||
<string>branch</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionTag">
|
||||
<property name="text">
|
||||
<string>Tag</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -126,6 +126,65 @@ void GitManager::restore(const QString &folder, const QString &path)
|
|||
runGit(folder,args);
|
||||
}
|
||||
|
||||
int GitManager::logCounts(const QString &folder, const QString &branch)
|
||||
{
|
||||
QStringList args;
|
||||
args.append("rev-list");
|
||||
args.append("--count");
|
||||
if (branch.isEmpty())
|
||||
args.append("HEAD");
|
||||
else
|
||||
args.append(branch);
|
||||
QString s = runGit(folder,args).trimmed();
|
||||
bool ok;
|
||||
int result = s.toInt(&ok);
|
||||
if (!ok)
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<PGitCommitInfo> GitManager::log(const QString &folder, int start, int count, const QString &branch)
|
||||
{
|
||||
QStringList args;
|
||||
args.append("log");
|
||||
args.append("--skip");
|
||||
args.append(QString("%1").arg(start-1));
|
||||
args.append("-n");
|
||||
args.append(QString("%1").arg(count));
|
||||
args.append("--format=medium");
|
||||
args.append("--date=iso-strict");
|
||||
if (branch.isEmpty())
|
||||
args.append("HEAD");
|
||||
else
|
||||
args.append(branch);
|
||||
QString output = runGit(folder,args);
|
||||
QStringList lines = textToLines(output);
|
||||
QList<PGitCommitInfo> result;
|
||||
int pos = 0;
|
||||
PGitCommitInfo commitInfo;
|
||||
while (pos<lines.length()) {
|
||||
if (lines[pos].startsWith("commit ")) {
|
||||
commitInfo = std::make_shared<GitCommitInfo>();
|
||||
commitInfo->commitHash=lines[pos].mid(QString("commit ").length()).trimmed();
|
||||
result.append(commitInfo);
|
||||
} else if(!commitInfo) {
|
||||
break;
|
||||
} else if (lines[pos].startsWith("Author:")) {
|
||||
commitInfo->author=lines[pos].mid(QString("Author:").length()).trimmed();
|
||||
} else if (lines[pos].startsWith("Date:")) {
|
||||
commitInfo->authorDate=QDateTime::fromString(lines[pos].mid(QString("Date:").length()).trimmed(),Qt::ISODate);
|
||||
} else if (!lines[pos].trimmed().isEmpty()) {
|
||||
if (commitInfo->title.isEmpty()) {
|
||||
commitInfo->title = lines[pos].trimmed();
|
||||
} else {
|
||||
commitInfo->fullCommitMessage.append(lines[pos].trimmed()+"\n");
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList GitManager::listFiles(const QString &folder)
|
||||
{
|
||||
QStringList args;
|
||||
|
|
|
@ -33,6 +33,9 @@ public:
|
|||
void rename(const QString& folder, const QString& oldName, const QString& newName);
|
||||
void restore(const QString& folder, const QString& path);
|
||||
|
||||
int logCounts(const QString& folder, const QString& branch=QString());
|
||||
QList<PGitCommitInfo> log(const QString& folder, int start, int count, const QString& branch=QString());
|
||||
|
||||
QStringList listFiles(const QString& folder);
|
||||
QStringList listStagedFiles(const QString& folder);
|
||||
QStringList listChangedFiles(const QString& folder);
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#ifndef GITUTILS_H
|
||||
#define GITUTILS_H
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QString>
|
||||
#include <memory>
|
||||
|
||||
|
||||
enum class GitResetStrategy {
|
||||
Soft,
|
||||
Hard,
|
||||
|
@ -30,4 +35,14 @@ enum class GitMergeStrategyOption {
|
|||
Subtree
|
||||
};
|
||||
|
||||
struct GitCommitInfo {
|
||||
QString commitHash;
|
||||
QString author;
|
||||
QDateTime authorDate;
|
||||
QString title;
|
||||
QString fullCommitMessage;
|
||||
};
|
||||
|
||||
using PGitCommitInfo = std::shared_ptr<GitCommitInfo>;
|
||||
|
||||
#endif // GITUTILS_H
|
||||
|
|
|
@ -7,7 +7,7 @@ SUBDIRS += \
|
|||
|
||||
APP_NAME = RedPandaCPP
|
||||
|
||||
APP_VERSION = 0.14.3
|
||||
APP_VERSION = 0.14.4
|
||||
|
||||
linux: {
|
||||
|
||||
|
|
Loading…
Reference in New Issue