- fix: convert to encoding setting in compiler set option not correctly handled

work save:
  git repository class
This commit is contained in:
Roy Qu 2022-02-15 00:01:50 +08:00
parent de230c63c7
commit 664922a301
23 changed files with 479 additions and 85 deletions

View File

@ -1,11 +1,15 @@
- change: rename "compile log" panel to "tools output"
- fix: debug panel can't be correctly show/hide
- enhancement: redesign tools output's context menu, add "clear" menu item
- enhancement: tools -> git in the options dialog
- enhancement: auto detect git in PATH
- enhancement: basic git commands
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
- enhancement: custome icons for project view
- fix: convert to encoding setting in compiler set option not correctly handled
Red Panda C++ Version 0.14.2
- enhancement: file system view mode for project

View File

@ -292,8 +292,7 @@ QString Compiler::getCharsetArgument(const QByteArray& encoding)
} else {
encodingName = encoding;
}
if (compilerSetExecCharset == ENCODING_SYSTEM_DEFAULT
|| compilerSetExecCharset.isEmpty()) {
if (compilerSetExecCharset == ENCODING_SYSTEM_DEFAULT || compilerSetExecCharset.isEmpty()) {
execEncodingName = systemEncodingName;
} else {
execEncodingName = compilerSetExecCharset;

View File

@ -1,15 +1,25 @@
#include "customfileiconprovider.h"
#include "iconsmanager.h"
#include "vcs/gitmanager.h"
#include "vcs/gitrepository.h"
CustomFileIconProvider::CustomFileIconProvider()
{
mVCSManager = new GitManager();
mVCSRepository = new GitRepository("");
}
CustomFileIconProvider::~CustomFileIconProvider()
{
delete mVCSManager;
delete mVCSRepository;
}
void CustomFileIconProvider::setRootFolder(const QString &folder)
{
mVCSRepository->setFolder(folder);
}
void CustomFileIconProvider::update()
{
mVCSRepository->update();
}
QIcon CustomFileIconProvider::icon(IconType type) const
@ -27,50 +37,50 @@ QIcon CustomFileIconProvider::icon(const QFileInfo &info) const
{
QIcon icon;
if (info.isDir()) {
if (mVCSManager && mVCSManager->isFileInRepository(info)) {
if (mVCSManager->isFileInStaged(info))
if (mVCSRepository->isFileInRepository(info)) {
if (mVCSRepository->isFileStaged(info))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_FOLDER_VCS_STAGED);
else if (mVCSManager->isFileChanged(info))
else if (mVCSRepository->isFileChanged(info))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_FOLDER_VCS_CHANGED);
else
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_FOLDER_VCS_NOCHANGE);
} else
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_FOLDER);
} if (isHFile(info.fileName())) {
if (mVCSManager && mVCSManager->isFileInRepository(info)) {
if (mVCSManager->isFileInStaged(info))
} else if (isHFile(info.fileName())) {
if (mVCSRepository->isFileInRepository(info)) {
if (mVCSRepository->isFileStaged(info))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_HFILE_VCS_STAGED);
else if (mVCSManager->isFileChanged(info))
else if (mVCSRepository->isFileChanged(info))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_HFILE_VCS_CHANGED);
else
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_HFILE_VCS_NOCHANGE);
} else
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_HFILE);
} else if (isCppFile(info.fileName())) {
if (mVCSManager && mVCSManager->isFileInRepository(info)) {
if (mVCSManager->isFileInStaged(info))
if (mVCSRepository->isFileInRepository(info)) {
if (mVCSRepository->isFileStaged(info))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_CPPFILE_VCS_STAGED);
else if (mVCSManager->isFileChanged(info))
else if (mVCSRepository->isFileChanged(info))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_CPPFILE_VCS_CHANGED);
else
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_CPPFILE_VCS_NOCHANGE);
} else
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_CPPFILE);
} else if (isCFile(info.fileName())) {
if (mVCSManager && mVCSManager->isFileInRepository(info)) {
if (mVCSManager->isFileInStaged(info))
if (mVCSRepository->isFileInRepository(info)) {
if (mVCSRepository->isFileStaged(info))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_CFILE_VCS_STAGED);
else if (mVCSManager->isFileChanged(info))
else if (mVCSRepository->isFileChanged(info))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_CFILE_VCS_CHANGED);
else
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_CFILE_VCS_NOCHANGE);
} else
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_CFILE);
} else if (info.suffix()=="dev") {
if (mVCSManager && mVCSManager->isFileInRepository(info)) {
if (mVCSManager->isFileInStaged(info))
if (mVCSRepository->isFileInRepository(info)) {
if (mVCSRepository->isFileStaged(info))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_PROJECTFILE_VCS_STAGED);
else if (mVCSManager->isFileChanged(info))
else if (mVCSRepository->isFileChanged(info))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_PROJECTFILE_VCS_CHANGED);
else
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_PROJECTFILE_VCS_NOCHANGE);

View File

@ -3,14 +3,16 @@
#include <QFileIconProvider>
class GitManager;
class GitRepository;
class CustomFileIconProvider : public QFileIconProvider
{
public:
CustomFileIconProvider();
~CustomFileIconProvider();
void setRootFolder(const QString& folder);
void update();
private:
GitManager* mVCSManager;
GitRepository* mVCSRepository;
// QFileIconProvider interface
public:
QIcon icon(IconType type) const override;

View File

@ -68,7 +68,7 @@ const char* SaveException::what() const noexcept {
}
Editor::Editor(QWidget *parent):
Editor(parent,QObject::tr("untitled"),ENCODING_SYSTEM_DEFAULT,false,true,nullptr)
Editor(parent,QObject::tr("untitled"),ENCODING_AUTO_DETECT,false,true,nullptr)
{
}

View File

@ -162,6 +162,11 @@ int main(int argc, char *argv[])
//set default open folder
QDir::setCurrent(pSettings->environment().defaultOpenFolder());
//auto detect git in path
if (!pSettings->vcs().gitOk()) {
pSettings->vcs().detectGitInPath();
}
MainWindow mainWindow;
pMainWindow = &mainWindow;
if (app.arguments().count()>1) {

View File

@ -39,6 +39,7 @@
#include "iconsmanager.h"
#include "widgets/newclassdialog.h"
#include "widgets/newheaderdialog.h"
#include "vcs/gitmanager.h"
#include <QCloseEvent>
#include <QComboBox>
@ -287,7 +288,7 @@ MainWindow::MainWindow(QWidget *parent)
//files view
ui->treeFiles->setModel(&mFileSystemModel);
mFileSystemModel.setReadOnly(false);
mFileSystemModel.setIconProvider(&mFileIconProvider);
mFileSystemModel.setIconProvider(&mFileSystemModelIconProvider);
setFilesViewRoot(pSettings->environment().currentFolder());
for (int i=1;i<mFileSystemModel.columnCount();i++) {
ui->treeFiles->hideColumn(i);
@ -324,6 +325,9 @@ MainWindow::MainWindow(QWidget *parent)
ui->actionEGE_Manual->setVisible(pSettings->environment().language()=="zh_CN");
//git menu
connect(ui->menuGit, &QMenu::aboutToShow,
this, &MainWindow::updateVCSActions);
buildContextMenus();
updateAppTitle();
//applySettings();
@ -425,7 +429,8 @@ void MainWindow::updateEditorActions()
ui->actionAuto_Detect->setEnabled(true);
ui->actionEncode_in_ANSI->setEnabled(true);
ui->actionEncode_in_UTF_8->setEnabled(true);
ui->actionConvert_to_ANSI->setEnabled(e->encodingOption()!=ENCODING_SYSTEM_DEFAULT && e->fileEncoding()!=ENCODING_SYSTEM_DEFAULT);
ui->actionConvert_to_ANSI->setEnabled(e->encodingOption()!=ENCODING_SYSTEM_DEFAULT
&& e->fileEncoding()!=ENCODING_SYSTEM_DEFAULT);
ui->actionConvert_to_UTF_8->setEnabled(e->encodingOption()!=ENCODING_UTF8 && e->fileEncoding()!=ENCODING_UTF8);
ui->actionCopy->setEnabled(e->selAvail());
@ -663,6 +668,8 @@ void MainWindow::applySettings()
// ui->cbFilesPath->setItemIcon(i,pIconsManager->getIcon(IconsManager::FILESYSTEM_GIT));
// }
ui->menuGit->menuAction()->setVisible(pSettings->vcs().gitOk());
}
void MainWindow::applyUISettings()
@ -2968,7 +2975,12 @@ void MainWindow::onProjectViewContextMenu(const QPoint &pos)
onRoot = true;
}
}
GitManager vcsManager;
QString branch;
bool hasRepository = vcsManager.hasRepository(mProject->folder(),branch);
QMenu menu(this);
QMenu vcsMenu(this);
updateProjectActions();
menu.addAction(ui->actionProject_New_File);
menu.addAction(ui->actionNew_Class);
@ -2981,6 +2993,15 @@ void MainWindow::onProjectViewContextMenu(const QPoint &pos)
menu.addAction(mProject_Rename_Unit);
}
menu.addSeparator();
if (pSettings->vcs().gitOk()) {
if (hasRepository) {
menu.addMenu(&vcsMenu);
} else {
ui->actionGit_Create_Repository->setEnabled(true);
menu.addAction(ui->actionGit_Create_Repository);
}
menu.addSeparator();
}
if (onFolder && mProject->modelType()==ProjectModelType::Custom) {
menu.addAction(mProject_Add_Folder);
if (!onRoot) {
@ -3001,6 +3022,18 @@ void MainWindow::onProjectViewContextMenu(const QPoint &pos)
}
menu.addAction(ui->actionProject_options);
if (pSettings->vcs().gitOk() && hasRepository) {
vcsMenu.setTitle(tr("VCS"));
if (ui->projectView->selectionModel()->hasSelection())
vcsMenu.addAction(ui->actionGit_Add_Files);
vcsMenu.addAction(ui->actionGit_Commit);
vcsMenu.addAction(ui->actionGit_Reset);
vcsMenu.addAction(ui->actionGit_Revert);
ui->actionGit_Commit->setEnabled(true);
ui->actionGit_Reset->setEnabled(true);
ui->actionGit_Revert->setEnabled(true);
}
menu.exec(ui->projectView->mapToGlobal(pos));
}
@ -3054,12 +3087,24 @@ void MainWindow::onFileEncodingContextMenu(const QPoint &pos)
void MainWindow::onFilesViewContextMenu(const QPoint &pos)
{
GitManager vcsManager;
QString branch;
bool hasRepository = vcsManager.hasRepository(pSettings->environment().currentFolder(),branch);
QMenu menu(this);
QMenu vcsMenu(this);
menu.addAction(ui->actionOpen_Folder);
menu.addSeparator();
menu.addAction(mFilesView_CreateFolder);
menu.addSeparator();
if (pSettings->vcs().gitOk()) {
if (hasRepository) {
menu.addMenu(&vcsMenu);
} else {
ui->actionGit_Create_Repository->setEnabled(true);
menu.addAction(ui->actionGit_Create_Repository);
}
menu.addSeparator();
}
menu.addAction(mFilesView_Open);
menu.addAction(mFilesView_OpenWithExternal);
menu.addSeparator();
@ -3071,6 +3116,19 @@ void MainWindow::onFilesViewContextMenu(const QPoint &pos)
mFilesView_OpenWithExternal->setEnabled(info.isFile());
mFilesView_OpenInTerminal->setEnabled(!path.isEmpty());
mFilesView_OpenInExplorer->setEnabled(!path.isEmpty());
if (pSettings->vcs().gitOk() && hasRepository) {
vcsMenu.setTitle(tr("VCS"));
if (ui->treeFiles->selectionModel()->hasSelection())
vcsMenu.addAction(ui->actionGit_Add_Files);
vcsMenu.addAction(ui->actionGit_Commit);
vcsMenu.addAction(ui->actionGit_Reset);
vcsMenu.addAction(ui->actionGit_Revert);
ui->actionGit_Commit->setEnabled(true);
ui->actionGit_Reset->setEnabled(true);
ui->actionGit_Revert->setEnabled(true);
}
menu.exec(ui->treeFiles->mapToGlobal(pos));
}
@ -5501,6 +5559,7 @@ void MainWindow::newProjectUnitFile()
PProjectUnit newUnit = mProject->newUnit(
mProject->pointerToNode(node),newFileName);
idx = mProject->units().count()-1;
mProject->rebuildNodes();
mProject->saveUnits();
updateProjectView();
Editor * editor = mProject->openUnit(idx);
@ -5528,6 +5587,27 @@ void MainWindow::doFilesViewRemoveFile(const QModelIndex &index)
}
}
void MainWindow::updateVCSActions()
{
bool hasRepository = false;
bool shouldEnable = false;
if (ui->projectView->isVisible()) {
GitManager vcsManager;
QString branch;
hasRepository = vcsManager.hasRepository(mProject->folder(),branch);
shouldEnable = true;
} else if (ui->treeFiles->isVisible()) {
GitManager vcsManager;
QString branch;
hasRepository = vcsManager.hasRepository(pSettings->environment().currentFolder(),branch);
shouldEnable = true;
}
ui->actionGit_Create_Repository->setEnabled(!hasRepository && shouldEnable);
ui->actionGit_Commit->setEnabled(hasRepository && shouldEnable);
ui->actionGit_Reset->setEnabled(hasRepository && shouldEnable);
ui->actionGit_Revert->setEnabled(hasRepository && shouldEnable);
}
void MainWindow::invalidateProjectProxyModel()
{
mProjectProxyModel->invalidate();
@ -5663,6 +5743,7 @@ void MainWindow::showSearchReplacePanel(bool show)
void MainWindow::setFilesViewRoot(const QString &path)
{
mFileSystemModelIconProvider.setRootFolder(path);
mFileSystemModel.setRootPath(path);
ui->treeFiles->setRootIndex(mFileSystemModel.index(path));
pSettings->environment().setCurrentFolder(path);
@ -6450,3 +6531,58 @@ void MainWindow::on_actionNew_Class_triggered()
pSettings->ui().setNewHeaderDialogHeight(dialog.height());
}
void MainWindow::on_actionGit_Create_Repository_triggered()
{
if (ui->treeFiles->isVisible()) {
GitManager vcsManager;
vcsManager.createRepository(pSettings->environment().currentFolder());
int pos = ui->cbFilesPath->findText(pSettings->environment().currentFolder());
if (pos>=0) {
ui->cbFilesPath->setItemIcon(pos, pIconsManager->getIcon(IconsManager::FILESYSTEM_GIT));
}
} else if (ui->projectView->isVisible()) {
GitManager vcsManager;
vcsManager.createRepository(mProject->folder());
mProject->model()->beginUpdate();
mProject->model()->endUpdate();
}
}
void MainWindow::on_actionGit_Add_Files_triggered()
{
if (ui->treeFiles->isVisible()) {
GitManager vcsManager;
QModelIndexList indices = ui->treeFiles->selectionModel()->selectedRows();
foreach (const QModelIndex index,indices) {
QFileInfo info = mFileSystemModel.fileInfo(index);
vcsManager.add(info.absolutePath(),info.fileName());
}
//update icons in files view
mFileSystemModelIconProvider.update();
mFileSystemModel.setIconProvider(&mFileSystemModelIconProvider);
} else if (ui->projectView->isVisible()) {
GitManager vcsManager;
QModelIndexList indices = ui->projectView->selectionModel()->selectedRows();
foreach (const QModelIndex index,indices) {
QModelIndex realIndex = mProjectProxyModel->mapToSource(index);
ProjectModelNode * node = static_cast<ProjectModelNode*>(realIndex.internalPointer());
PProjectModelNode folderNode = mProject->pointerToNode(node);
if (!folderNode)
continue;
if (folderNode->unitIndex>=0) {
PProjectUnit unit = mProject->units()[folderNode->unitIndex];
QFileInfo info(unit->fileName());
vcsManager.add(info.absolutePath(),info.fileName());
}
}
//update icons in project view
mProject->model()->beginUpdate();
mProject->model()->endUpdate();
//update icons in files view too
mFileSystemModelIconProvider.update();
mFileSystemModel.setIconProvider(&mFileSystemModelIconProvider);
}
}

View File

@ -38,6 +38,7 @@
#include "widgets/labelwithmenu.h"
#include "widgets/bookmarkmodel.h"
#include "widgets/ojproblemsetmodel.h"
#include "widgets/customfilesystemmodel.h"
#include "customfileiconprovider.h"
@ -253,6 +254,7 @@ private:
void doFilesViewRemoveFile(const QModelIndex& index);
private slots:
void updateVCSActions();
void invalidateProjectProxyModel();
void onEditorRenamed(const QString& oldFilename, const QString& newFilename, bool firstSave);
void onAutoSaveTimeout();
@ -576,6 +578,10 @@ private slots:
void on_actionNew_Header_triggered();
void on_actionGit_Create_Repository_triggered();
void on_actionGit_Add_Files_triggered();
private:
Ui::MainWindow *ui;
EditorList *mEditorList;
@ -615,8 +621,8 @@ private:
PCodeSnippetManager mCodeSnippetManager;
PTodoParser mTodoParser;
PToolsManager mToolsManager;
QFileSystemModel mFileSystemModel;
CustomFileIconProvider mFileIconProvider;
CustomFileSystemModel mFileSystemModel;
CustomFileIconProvider mFileSystemModelIconProvider;
OJProblemSetModel mOJProblemSetModel;
OJProblemModel mOJProblemModel;
int mOJProblemSetNameCounter;

View File

@ -229,7 +229,7 @@
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>0</number>
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
@ -2774,6 +2774,11 @@
<string>Reset</string>
</property>
</action>
<action name="actionGit_Add_Files">
<property name="text">
<string>Add Files</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@ -1910,12 +1910,14 @@ ProjectModel::ProjectModel(Project *project, QObject *parent):
mProject(project)
{
mUpdateCount = 0;
mVCSManager = new GitManager();
mVCSRepository = new GitRepository("");
mIconProvider = new CustomFileIconProvider();
}
ProjectModel::~ProjectModel()
{
delete mVCSManager;
delete mVCSRepository;
delete mIconProvider;
}
void ProjectModel::beginUpdate()
@ -1930,6 +1932,8 @@ void ProjectModel::endUpdate()
{
mUpdateCount--;
if (mUpdateCount==0) {
mVCSRepository->setFolder(mProject->folder());
mIconProvider->setRootFolder(mProject->folder());
endResetModel();
}
}
@ -1990,21 +1994,20 @@ QVariant ProjectModel::data(const QModelIndex &index, int role) const
if (role == Qt::DisplayRole) {
if (p == mProject->rootNode().get()) {
QString branch;
if (mVCSManager->hasRepository(mProject->folder(),branch))
if (mVCSRepository->hasRepository(branch))
return QString("%1 [%2]").arg(p->text,branch);
}
return p->text;
} else if (role==Qt::EditRole) {
return p->text;
} else if (role == Qt::DecorationRole) {
CustomFileIconProvider provider;
QIcon icon;
if (p->unitIndex>=0) {
icon = provider.icon(mProject->units()[p->unitIndex]->fileName());
icon = mIconProvider->icon(mProject->units()[p->unitIndex]->fileName());
} else {
if (p == mProject->rootNode().get()) {
QString branch;
if (mVCSManager->hasRepository(mProject->folder(),branch))
if (mVCSRepository->hasRepository(branch))
icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_GIT);
} else {
switch(p->folderNodeType) {
@ -2019,7 +2022,7 @@ QVariant ProjectModel::data(const QModelIndex &index, int role) const
}
}
if (icon.isNull())
icon = provider.icon(QFileIconProvider::Folder);
icon = mIconProvider->icon(QFileIconProvider::Folder);
}
return icon;
}

View File

@ -101,7 +101,8 @@ private:
using PProjectUnit = std::shared_ptr<ProjectUnit>;
class GitManager;
class GitRepository;
class CustomFileIconProvider;
class ProjectModel : public QAbstractItemModel {
Q_OBJECT
public:
@ -111,8 +112,9 @@ public:
void endUpdate();
private:
Project* mProject;
GitManager *mVCSManager;
GitRepository *mVCSRepository;
int mUpdateCount;
CustomFileIconProvider* mIconProvider;
// QAbstractItemModel interface

View File

@ -5083,9 +5083,9 @@ void Settings::UI::doLoad()
mNewHeaderDialogHeight = intValue("new_header_dialog_height", 300*qApp->desktop()->height()/1080);
}
Settings::VCS::VCS(Settings *settings):_Base(settings,SETTING_VCS)
Settings::VCS::VCS(Settings *settings):_Base(settings,SETTING_VCS),
mGitOk(false)
{
}
void Settings::VCS::doSave()
@ -5095,7 +5095,7 @@ void Settings::VCS::doSave()
void Settings::VCS::doLoad()
{
mGitPath = stringValue("git_path", "");
setGitPath(stringValue("git_path", ""));
}
const QString &Settings::VCS::gitPath() const
@ -5105,5 +5105,54 @@ const QString &Settings::VCS::gitPath() const
void Settings::VCS::setGitPath(const QString &newGitPath)
{
if (mGitPath!=newGitPath) {
mGitPath = newGitPath;
validateGit();
}
}
void Settings::VCS::validateGit()
{
mGitOk = false;
QFileInfo fileInfo(mGitPath);
if (!fileInfo.exists()) {
return;
}
QStringList args;
args.append("--version");
QString output = runAndGetOutput(
fileInfo.fileName(),
fileInfo.absolutePath(),
args);
mGitOk = output.startsWith("git version");
}
bool Settings::VCS::gitOk() const
{
return mGitOk;
}
void Settings::VCS::detectGitInPath()
{
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
QString path = env.value("PATH");
QStringList pathList = path.split(PATH_SEPARATOR);
QSet<QString> searched;
foreach (const QString& s, pathList){
if (searched.contains(s))
continue;;
searched.insert(s);
QDir dir(s);
if (dir.exists(GIT_PROGRAM)) {
QString oldPath = mGitPath;
setGitPath(dir.filePath(GIT_PROGRAM));
if (mGitOk) {
doSave();
return;
} else {
mGitPath = oldPath;
}
}
}
}

View File

@ -887,8 +887,13 @@ public:
explicit VCS(Settings *settings);
const QString &gitPath() const;
void setGitPath(const QString &newGitPath);
bool gitOk() const;
void detectGitInPath();
private:
void validateGit();
private:
QString mGitPath;
bool mGitOk;
protected:
void doSave() override;
void doLoad() override;

View File

@ -246,7 +246,7 @@ void CompilerSetOptionWidget::saveCurrentCompilerSet()
if (ui->cbEncodingDetails->isVisible()) {
pSet->setExecCharset(ui->cbEncodingDetails->currentText());
} else {
pSet->setExecCharset(ui->cbEncoding->currentText());
pSet->setExecCharset(ui->cbEncoding->currentData().toString());
}
//read values in the options widget

View File

@ -4,6 +4,7 @@
#include "../settings.h"
#include "../systemconsts.h"
#include "../utils.h"
#include "../mainwindow.h"
#include <QFileDialog>
@ -29,6 +30,7 @@ void ToolsGitWidget::doSave()
{
pSettings->vcs().setGitPath(ui->txtGitPath->text());
pSettings->vcs().save();
pMainWindow->applySettings();
}
void ToolsGitWidget::updateIcons(const QSize &size)

View File

@ -31,6 +31,7 @@
#define GPROF_PROGRAM "gprof.exe"
#define CLEAN_PROGRAM "del /q /f"
#define CPP_PROGRAM "cpp.exe"
#define GIT_PROGRAM "git.exe"
#elif defined(Q_OS_LINUX)
#define GCC_PROGRAM "gcc"
#define GPP_PROGRAM "g++"
@ -42,6 +43,7 @@
#define GPROF_PROGRAM "gprof"
#define CLEAN_PROGRAM "rm -rf"
#define CPP_PROGRAM "cpp"
#define GIT_PROGRAM "git"
#else
#error "Only support windows and linux now!"
#endif

View File

@ -1140,3 +1140,5 @@ void copyFolder(const QString &fromDir, const QString &toDir)
}
}
}

View File

@ -2,6 +2,7 @@
#include "../utils.h"
#include "../settings.h"
#include <QDir>
#include <QFileInfo>
GitManager::GitManager(QObject *parent) : QObject(parent)
@ -16,6 +17,16 @@ void GitManager::createRepository(const QString &folder)
QStringList args;
args.append("init");
runGit(folder,args);
QStringList contents;
contents.append(".git");
contents.append("*.o");
contents.append("*.exe");
contents.append("*.");
QDir dir(folder);
stringsToFile(contents,dir.filePath(".gitignore"));
add(folder,".gitignore");
}
bool GitManager::hasRepository(const QString &folder, QString& currentBranch)
@ -50,7 +61,7 @@ bool GitManager::isFileInRepository(const QFileInfo& fileInfo)
return output.trimmed() == fileInfo.fileName();
}
bool GitManager::isFileInStaged(const QFileInfo &fileInfo)
bool GitManager::isFileStaged(const QFileInfo &fileInfo)
{
QStringList args;
args.append("diff");
@ -111,6 +122,23 @@ QStringList GitManager::listFiles(const QString &folder)
return textToLines(runGit(folder,args));
}
QStringList GitManager::listStagedFiles(const QString &folder)
{
QStringList args;
args.append("diff");
args.append("--staged");
args.append("--name-only");
return textToLines(runGit(folder,args));
}
QStringList GitManager::listChangedFiles(const QString &folder)
{
QStringList args;
args.append("diff");
args.append("--name-only");
return textToLines(runGit(folder,args));
}
void GitManager::clone(const QString &folder, const QString &url)
{
QStringList args;
@ -161,8 +189,15 @@ void GitManager::reset(const QString &folder, const QString &commit, GitResetStr
runGit(folder,args);
}
bool GitManager::isValid()
{
return pSettings->vcs().gitOk();
}
QString GitManager::runGit(const QString& workingFolder, const QStringList &args)
{
if (!isValid())
return "";
QFileInfo fileInfo(pSettings->vcs().gitPath());
if (!fileInfo.exists())
return "fatal: git doesn't exist";
@ -174,12 +209,98 @@ QString GitManager::runGit(const QString& workingFolder, const QStringList &args
fileInfo.absoluteFilePath(),
workingFolder,
args);
output = escapeUTF8String(output.toUtf8());
emit gitCmdFinished(output);
// if (output.startsWith("fatal:"))
// throw GitError(output);
return output;
}
QString GitManager::escapeUTF8String(const QByteArray &rawString)
{
QByteArray stringValue;
int p = 0;
while (p<rawString.length()) {
char ch = rawString[p];
if (ch =='\\' && p+1 < rawString.length()) {
p++;
ch = rawString[p];
switch (ch) {
case '\'':
stringValue+=0x27;
p++;
break;
case '"':
stringValue+=0x22;
p++;
break;
case '?':
stringValue+=0x3f;
p++;
break;
case '\\':
stringValue+=0x5c;
p++;
break;
case 'a':
stringValue+=0x07;
p++;
break;
case 'b':
stringValue+=0x08;
p++;
break;
case 'f':
stringValue+=0x0c;
p++;
break;
case 'n':
stringValue+=0x0a;
p++;
break;
case 'r':
stringValue+=0x0d;
p++;
break;
case 't':
stringValue+=0x09;
p++;
break;
case 'v':
stringValue+=0x0b;
p++;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
{
int i=0;
for (i=0;i<3;i++) {
if (p+i>=rawString.length() ||
rawString[p+i]<'0' || rawString[p+i]>'7')
break;
}
bool ok;
unsigned char ch = rawString.mid(p,i).toInt(&ok,8);
stringValue+=ch;
p+=i;
break;
}
}
} else {
if (ch!='\"')
stringValue+=ch;
p++;
}
}
return QString::fromUtf8(stringValue);
}
GitError::GitError(const QString &reason):BaseError(reason)
{

View File

@ -3,6 +3,7 @@
#include <QObject>
#include <QFileInfo>
#include <QSet>
#include "utils.h"
#include "gitrepository.h"
@ -22,7 +23,7 @@ public:
bool hasRepository(const QString& folder, QString& currentBranch);
bool isFileInRepository(const QFileInfo& fileInfo);
bool isFileInStaged(const QFileInfo& fileInfo);
bool isFileStaged(const QFileInfo& fileInfo);
bool isFileChanged(const QFileInfo& fileInfo);
void add(const QString& folder, const QString& path);
@ -30,17 +31,23 @@ public:
void rename(const QString& folder, const QString& oldName, const QString& newName);
void restore(const QString& folder, const QString& path);
QStringList listFiles(const QString& folder);
QStringList listStagedFiles(const QString& folder);
QStringList listChangedFiles(const QString& folder);
void clone(const QString& folder, const QString& url);
void commit(const QString& folder, const QString& message);
void revert(const QString& folder);
void reset(const QString& folder, const QString& commit, GitResetStrategy strategy);
bool isValid();
signals:
void gitCmdRunning(const QString& gitCmd);
void gitCmdFinished(const QString& message);
private:
QString runGit(const QString& workingFolder, const QStringList& args);
QString escapeUTF8String(const QByteArray& rawString);
private:
};

View File

@ -1,12 +1,17 @@
#include "gitrepository.h"
#include "gitmanager.h"
GitRepository::GitRepository(const QString& folder, GitManager *manager, QObject *parent)
GitRepository::GitRepository(const QString& folder, QObject *parent)
: QObject{parent},
mFolder(folder),
mManager(manager)
mInRepository(false)
{
Q_ASSERT(manager!=nullptr);
mManager = new GitManager();
setFolder(folder);
}
GitRepository::~GitRepository()
{
delete mManager;
}
const QString &GitRepository::folder() const
@ -21,7 +26,8 @@ void GitRepository::createRepository()
bool GitRepository::hasRepository(QString& currentBranch)
{
return mManager->hasRepository(mFolder, currentBranch);
currentBranch = mBranch;
return mInRepository;
}
void GitRepository::add(const QString &path)
@ -44,12 +50,11 @@ void GitRepository::restore(const QString &path)
mManager->restore(mFolder, path);
}
QStringList GitRepository::listFiles(bool refresh)
QSet<QString> GitRepository::listFiles(bool refresh)
{
if (refresh || mFiles.isEmpty()) {
mFiles = mManager->listFiles(mFolder);
}
return mFiles;
if (refresh)
update();
return mFilesInRepositories;
}
void GitRepository::clone(const QString &url)
@ -72,18 +77,33 @@ void GitRepository::reset(const QString &commit, GitResetStrategy strategy)
mManager->reset(mFolder,commit,strategy);
}
GitManager *GitRepository::manager() const
{
return mManager;
}
void GitRepository::setManager(GitManager *newManager)
{
Q_ASSERT(newManager!=nullptr);
mManager = newManager;
}
void GitRepository::setFolder(const QString &newFolder)
{
mFolder = newFolder;
update();
}
void GitRepository::update()
{
if (!mManager->isValid()) {
mInRepository = false;
mBranch = "";
mFilesInRepositories.clear();
mChangedFiles.clear();
mStagedFiles.clear();
} else {
mInRepository = mManager->hasRepository(mFolder,mBranch);
convertFilesListToSet(mManager->listFiles(mFolder),mFilesInRepositories);
convertFilesListToSet(mManager->listChangedFiles(mFolder),mChangedFiles);
convertFilesListToSet(mManager->listStagedFiles(mFolder),mStagedFiles);
}
}
void GitRepository::convertFilesListToSet(const QStringList &filesList, QSet<QString> &set)
{
set.clear();
foreach (const QString& s, filesList) {
set.insert(includeTrailingPathDelimiter(mFolder)+s);
}
}

View File

@ -1,7 +1,9 @@
#ifndef GITREPOSITORY_H
#define GITREPOSITORY_H
#include <QFileInfo>
#include <QObject>
#include <QSet>
#include <memory>
enum class GitResetStrategy {
@ -17,34 +19,59 @@ class GitRepository : public QObject
{
Q_OBJECT
public:
explicit GitRepository(const QString& folder, GitManager* manager, QObject *parent = nullptr);
explicit GitRepository(const QString& folder, QObject *parent = nullptr);
~GitRepository();
const QString &folder() const;
void createRepository();
bool hasRepository(QString& currentBranch);
bool isFileInRepository(const QFileInfo& fileInfo) {
return isFileInRepository(fileInfo.absoluteFilePath());
}
bool isFileInRepository(const QString& filePath) {
return mFilesInRepositories.contains(filePath);
}
bool isFileStaged(const QFileInfo& fileInfo) {
return isFileStaged(fileInfo.absoluteFilePath());
}
bool isFileStaged(const QString& filePath) {
return mStagedFiles.contains(filePath);
}
bool isFileChanged(const QFileInfo& fileInfo) {
return isFileChanged(fileInfo.absoluteFilePath());
}
bool isFileChanged(const QString& filePath) {
return mChangedFiles.contains(filePath);
}
void add(const QString& path);
void remove(const QString& path);
void rename(const QString& oldName, const QString& newName);
void restore(const QString& path);
QStringList listFiles(bool refresh);
QSet<QString> listFiles(bool refresh);
void clone(const QString& url);
void commit(const QString& message);
void revert();
void reset(const QString& commit, GitResetStrategy strategy);
GitManager *manager() const;
void setManager(GitManager *newManager);
void setFolder(const QString &newFolder);
void update();
signals:
private:
QString mFolder;
bool mInRepository;
QString mBranch;
GitManager* mManager;
QStringList mFiles;
QSet<QString> mFilesInRepositories;
QSet<QString> mChangedFiles;
QSet<QString> mStagedFiles;
private:
void convertFilesListToSet(const QStringList& filesList,QSet<QString>& set);
};
#endif // GITREPOSITORY_H

View File

@ -4,10 +4,6 @@
CustomFileSystemModel::CustomFileSystemModel(QObject *parent) : QFileSystemModel(parent)
{
mGitManager = new GitManager(this);
mGitRepository = new GitRepository("",mGitManager,mGitManager);
connect(this,&QFileSystemModel::rootPathChanged,
this, &CustomFileSystemModel::onRootPathChanged);
}
QVariant CustomFileSystemModel::data(const QModelIndex &index, int role) const
@ -15,7 +11,3 @@ QVariant CustomFileSystemModel::data(const QModelIndex &index, int role) const
return QFileSystemModel::data(index,role);
}
void CustomFileSystemModel::onRootPathChanged(const QString &folder)
{
mGitRepository->setFolder(folder);
}

View File

@ -15,11 +15,6 @@ public:
// QAbstractItemModel interface
public:
QVariant data(const QModelIndex &index, int role) const override;
private slots:
void onRootPathChanged(const QString& folder);
private:
GitRepository *mGitRepository;
GitManager *mGitManager;
};
#endif // CUSTOMFILESYSTEMMODEL_H