- enhancement: git - pull / push / fetch

This commit is contained in:
royqh1979@gmail.com 2022-02-24 23:31:48 +08:00
parent 162121efa2
commit 8365db47a0
19 changed files with 461 additions and 4 deletions

View File

@ -9,6 +9,7 @@ Red Panda C++ Version 0.14.4
- enhancement: git - remotes - enhancement: git - remotes
- enhancement: rename "open folder" to "choose working folder" - enhancement: rename "open folder" to "choose working folder"
- enhancement: let user choose app theme when first run - enhancement: let user choose app theme when first run
- enhancement: git - pull / push / fetch
Red Panda C++ Version 0.14.3 Red Panda C++ Version 0.14.3
- fix: wrong code completion font size, when screen dpi changed - fix: wrong code completion font size, when screen dpi changed

View File

@ -111,8 +111,6 @@
</qresource> </qresource>
<qresource prefix="/demos"> <qresource prefix="/demos">
<file alias="dark.png">images/demos/dark.png</file> <file alias="dark.png">images/demos/dark.png</file>
<file alias="dark-zh_CN.png">images/demos/dark-zh_CN.png</file>
<file alias="light.png">images/demos/light.png</file> <file alias="light.png">images/demos/light.png</file>
<file alias="light-zh_CN.png">images/demos/light-zh_CN.png</file>
</qresource> </qresource>
</RCC> </RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -6943,3 +6943,92 @@ void MainWindow::on_actionGit_Remotes_triggered()
dialog.exec(); dialog.exec();
} }
void MainWindow::on_actionGit_Fetch_triggered()
{
QString folder;
if (ui->treeFiles->isVisible()) {
folder = pSettings->environment().currentFolder();
} else if (ui->projectView->isVisible() && mProject) {
folder = mProject->folder();
}
if (folder.isEmpty())
return;
GitManager manager;
QString output;
if (!manager.fetch(folder,output)) {
InfoMessageBox infoBox;
infoBox.showMessage(output);
}
}
void MainWindow::on_actionGit_Pull_triggered()
{
QString folder;
if (ui->treeFiles->isVisible()) {
folder = pSettings->environment().currentFolder();
} else if (ui->projectView->isVisible() && mProject) {
folder = mProject->folder();
}
if (folder.isEmpty())
return;
GitManager manager;
QString branch;
if (!manager.hasRepository(folder,branch))
return;
QString remote = manager.getBranchRemote(folder,branch);
QString output;
if (remote.isEmpty()) {
GitRemoteDialog dialog(folder);
QString remote = dialog.chooseRemote();
if (remote.trimmed().isEmpty())
return;
if (!manager.setBranchUpstream(folder,branch,remote,output)) {
InfoMessageBox infoBox;
infoBox.showMessage(output);
return;
}
}
manager.pull(folder,output);
if (!output.isEmpty()) {
InfoMessageBox infoBox;
infoBox.showMessage(output);
}
}
void MainWindow::on_actionGit_Push_triggered()
{
QString folder;
if (ui->treeFiles->isVisible()) {
folder = pSettings->environment().currentFolder();
} else if (ui->projectView->isVisible() && mProject) {
folder = mProject->folder();
}
if (folder.isEmpty())
return;
GitManager manager;
QString branch;
if (!manager.hasRepository(folder,branch))
return;
QString remote = manager.getBranchRemote(folder,branch);
QString output;
if (remote.isEmpty()) {
GitRemoteDialog dialog(folder);
QString remote = dialog.chooseRemote();
if (remote.trimmed().isEmpty())
return;
manager.push(folder,remote,branch,output);
if (!output.isEmpty()) {
InfoMessageBox infoBox;
infoBox.showMessage(output);
}
} else {
if (!output.isEmpty()) {
InfoMessageBox infoBox;
infoBox.showMessage(output);
}
}
}

View File

@ -598,6 +598,12 @@ private slots:
void on_actionGit_Remotes_triggered(); void on_actionGit_Remotes_triggered();
void on_actionGit_Fetch_triggered();
void on_actionGit_Pull_triggered();
void on_actionGit_Push_triggered();
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
EditorList *mEditorList; EditorList *mEditorList;

View File

@ -1603,6 +1603,9 @@
</property> </property>
<addaction name="actionGit_Create_Repository"/> <addaction name="actionGit_Create_Repository"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionGit_Pull"/>
<addaction name="actionGit_Push"/>
<addaction name="actionGit_Fetch"/>
<addaction name="actionGit_Remotes"/> <addaction name="actionGit_Remotes"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionGit_Log"/> <addaction name="actionGit_Log"/>
@ -2821,6 +2824,21 @@
<string>Remotes...</string> <string>Remotes...</string>
</property> </property>
</action> </action>
<action name="actionGit_Fetch">
<property name="text">
<string>Fetch</string>
</property>
</action>
<action name="actionGit_Pull">
<property name="text">
<string>Pull</string>
</property>
</action>
<action name="actionGit_Push">
<property name="text">
<string>Push</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -284,6 +284,73 @@ QString GitManager::getRemoteURL(const QString &folder, const QString &name)
return runGit(folder,args).trimmed(); return runGit(folder,args).trimmed();
} }
QString GitManager::getBranchRemote(const QString &folder, const QString &branch)
{
QStringList args;
args.append("config");
args.append("--get");
args.append(QString("branch.%1.remote").arg(branch));
return runGit(folder,args).trimmed();
}
QString GitManager::getBranchMerge(const QString &folder, const QString &branch)
{
QStringList args;
args.append("config");
args.append("--get");
args.append(QString("branch.%1.merge").arg(branch));
return runGit(folder,args).trimmed();
}
bool GitManager::setBranchUpstream(
const QString &folder,
const QString &branch,
const QString &remoteName,
QString& output)
{
QStringList args;
args.append("branch");
args.append(QString("--set-upstream-to=%1/%2").arg(remoteName,branch));
args.append(branch);
output = runGit(folder,args).trimmed();
return !output.startsWith("error") && !output.startsWith("fatal");
}
bool GitManager::fetch(const QString &folder, QString &output)
{
QStringList args;
args.append("fetch");
output = runGit(folder,args).trimmed();
return !output.startsWith("error") && !output.startsWith("fatal");
}
bool GitManager::pull(const QString &folder, QString &output)
{
QStringList args;
args.append("pull");
output = runGit(folder,args).trimmed();
return !output.startsWith("error") && !output.startsWith("fatal");
}
bool GitManager::push(const QString &folder, QString &output)
{
QStringList args;
args.append("push");
output = runGit(folder,args).trimmed();
return !output.startsWith("error") && !output.startsWith("fatal");
}
bool GitManager::push(const QString &folder, const QString &remoteName, const QString &branch, QString &output)
{
QStringList args;
args.append("push");
args.append("--set-upstream");
args.append(remoteName);
args.append(branch);
output = runGit(folder,args).trimmed();
return !output.startsWith("error") && !output.startsWith("fatal");
}
QStringList GitManager::listBranches(const QString &folder, int &current) QStringList GitManager::listBranches(const QString &folder, int &current)
{ {
QStringList args; QStringList args;

View File

@ -50,6 +50,21 @@ public:
bool setRemoteURL(const QString& folder, const QString& name, bool setRemoteURL(const QString& folder, const QString& name,
const QString& newURL, QString& output); const QString& newURL, QString& output);
QString getRemoteURL(const QString& folder, const QString& name); QString getRemoteURL(const QString& folder, const QString& name);
QString getBranchRemote(const QString& folder, const QString& branch);
QString getBranchMerge(const QString& folder, const QString& branch);
bool setBranchUpstream(const QString& folder,
const QString& branch,
const QString& remoteName,
QString &output);
bool fetch(const QString& folder, QString& output);
bool pull(const QString& folder, QString& output);
bool push(const QString& folder, QString& output);
bool push(const QString& folder,
const QString& remoteName,
const QString& branch,
QString& output);
QStringList listBranches(const QString& folder, int& current); QStringList listBranches(const QString& folder, int& current);
bool switchToBranch(const QString& folder, const QString& branch, bool create, bool switchToBranch(const QString& folder, const QString& branch, bool create,

View File

@ -7,7 +7,8 @@
GitRemoteDialog::GitRemoteDialog(const QString& folder, QWidget *parent) : GitRemoteDialog::GitRemoteDialog(const QString& folder, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::GitRemoteDialog), ui(new Ui::GitRemoteDialog),
mFolder(folder) mFolder(folder),
mChooseMode(false)
{ {
ui->setupUi(this); ui->setupUi(this);
GitManager manager; GitManager manager;
@ -29,6 +30,18 @@ GitRemoteDialog::~GitRemoteDialog()
delete ui; delete ui;
} }
QString GitRemoteDialog::chooseRemote()
{
mChooseMode = true;
ui->btnClose->setText(tr("Ok"));
if (exec()==QDialog::Accepted) {
if (ui->lstRemotes->selectedItems().count()>0)
return ui->lstRemotes->selectedItems()[0]->text();
}
return "";
}
void GitRemoteDialog::updateIcons() void GitRemoteDialog::updateIcons()
{ {
ui->btnAdd->setIcon(pIconsManager->getIcon(IconsManager::ACTION_MISC_ADD)); ui->btnAdd->setIcon(pIconsManager->getIcon(IconsManager::ACTION_MISC_ADD));
@ -81,9 +94,13 @@ void GitRemoteDialog::on_btnAdd_clicked()
ui->pnlProcess->setVisible(true); ui->pnlProcess->setVisible(true);
ui->btnProcess->setText(tr("Add")); ui->btnProcess->setText(tr("Add"));
ui->btnRemove->setEnabled(false); ui->btnRemove->setEnabled(false);
if (ui->lstRemotes->count()==0) {
ui->txtName->setText("origin");
ui->txtURL->setFocus();
} else
ui->txtName->setFocus();
} }
void GitRemoteDialog::on_btnRemove_clicked() void GitRemoteDialog::on_btnRemove_clicked()
{ {
if (ui->lstRemotes->selectedItems().count()>0) { if (ui->lstRemotes->selectedItems().count()>0) {
@ -164,3 +181,9 @@ void GitRemoteDialog::on_txtURL_textChanged(const QString & /*arg1*/)
checkDetails(); checkDetails();
} }
void GitRemoteDialog::on_btnClose_clicked()
{
accept();
}

View File

@ -14,6 +14,7 @@ class GitRemoteDialog : public QDialog
public: public:
explicit GitRemoteDialog(const QString& folder, QWidget *parent = nullptr); explicit GitRemoteDialog(const QString& folder, QWidget *parent = nullptr);
~GitRemoteDialog(); ~GitRemoteDialog();
QString chooseRemote();
private slots: private slots:
void updateIcons(); void updateIcons();
@ -30,10 +31,13 @@ private slots:
void on_txtURL_textChanged(const QString &arg1); void on_txtURL_textChanged(const QString &arg1);
void on_btnClose_clicked();
private: private:
Ui::GitRemoteDialog *ui; Ui::GitRemoteDialog *ui;
QString mFolder; QString mFolder;
QStringList mRemotes; QStringList mRemotes;
bool mChooseMode;
}; };
#endif // GITREMOTEDIALOG_H #endif // GITREMOTEDIALOG_H

View File

@ -0,0 +1,78 @@
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#include <stdio.h>
HINSTANCE hInst;
LRESULT MainDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);
LRESULT TxtPasswordWndProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);
WNDPROC lpfnTxtPasswordWndProc=NULL;
HWND hMainDlg = NULL;
HWND hwndTxtPassword = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
MSG msg;
hMainDlg = CreateDialog(hInstance, (LPCTSTR)IDD_MAIN_DIALOG, 0,(DLGPROC)MainDlgProc);
ShowWindow(hMainDlg, nCmdShow);
hwndTxtPassword = GetDlgItem(hMainDlg,ID_TXT_PASSWORD);
lpfnTxtPasswordWndProc = (WNDPROC) SetWindowLongPtr(hwndTxtPassword, GWLP_WNDPROC, (LONG_PTR)TxtPasswordWndProc);
HWND hwndTxtPrompt = GetDlgItem(hMainDlg,ID_TXT_PROMPT);
Static_SetText(hwndTxtPrompt, lpCmdLine);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
//In Subclass Proc
LRESULT CALLBACK TxtPasswordWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg) {
case WM_KEYDOWN:
if (wParam==VK_RETURN) {
char s[500+1];
Edit_GetText(hwndTxtPassword,s,500);
printf(s);
DestroyWindow(hMainDlg);
return TRUE;
}
break;
}
return CallWindowProc(lpfnTxtPasswordWndProc, hwnd, msg, wParam, lParam);
}
LRESULT MainDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_INITDIALOG :
return TRUE ;
case WM_COMMAND :
switch (LOWORD (wParam)) {
case IDOK :
case IDCANCEL :
DestroyWindow(hDlg);
return TRUE ;
}
break ;
case WM_KEYUP:
printf("%d\n",wParam);
if (wParam == VK_RETURN) {
DestroyWindow(hDlg);
}
break;
case WM_CLOSE:
DestroyWindow(hDlg);
return TRUE;
case WM_DESTROY:
PostQuitMessage(0);
return TRUE;
};
return FALSE;//返回FALSE给缺省对话框函数DefDlgProc(),表示没有处理本消息
}

View File

@ -0,0 +1,98 @@
[Project]
filename = redpanda-git-askpass.dev
name = redpanda-git-askpass
UnitCount = 3
Type = 0
Ver = 3
ObjFiles =
Includes =
Libs =
PrivateResource = redpanda-git-askpass_private.rc
ResourceIncludes =
MakeIncludes =
Compiler =
CppCompiler =
Linker =
IsCpp = 1
Icon = redpanda-git-askpass.ico
ExeOutput =
ObjectOutput =
LogOutput =
LogOutputEnabled = 0
OverrideOutput = 0
OverrideOutputName =
HostApplication =
UseCustomMakefile = 0
CustomMakefile =
UsePrecompiledHeader = 0
PrecompiledHeader =
CommandLine =
Folders =
IncludeVersionInfo = 0
SupportXPThemes = 0
CompilerSet = 0
CompilerSetType = 0
CompilerSettings = 000000a000000000000010001
StaticLink = 1
AddCharset = 1
Encoding = AUTO
ModelType = 0
UseUTF8 = 0
[Unit1]
FileName = main.c
CompileCpp = 1
Folder =
Compile = 1
Link = 1
Priority = 1000
OverrideBuildCmd = 0
BuildCmd =
DetectEncoding = 1
FileEncoding = AUTO
[Unit2]
FileName = resource.rc
Folder = Resources
Compile = 1
Link = 1
Priority = 1000
OverrideBuildCmd = 0
BuildCmd =
DetectEncoding = 1
FileEncoding = AUTO
[Unit3]
FileName = resource.h
CompileCpp = 1
Folder =
Compile = 1
Link = 1
Priority = 1000
OverrideBuildCmd = 0
BuildCmd =
DetectEncoding = 1
FileEncoding = AUTO
[VersionInfo]
Major = 1
Minor = 0
Release = 0
Build = 0
LanguageID = 1033
CharsetID = 1252
CompanyName =
FileVersion =
FileDescription = Developed using the Red Panda C++ IDE
InternalName =
LegalCopyright =
LegalTrademarks =
OriginalFilename =
ProductName =
ProductVersion =
AutoIncBuildNr = 0
SyncProduct = 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@ -0,0 +1,23 @@
/* THIS FILE WILL BE OVERWRITTEN BY Red Panda C++ */
/* DO NOT EDIT ! */
#ifndef redpanda-git-askpass_private_rc
#define redpanda-git-askpass_private_rc
/* VERSION DEFINITIONS */
#define VER_STRING "1.0.0.0"
#define VER_MAJOR 1
#define VER_MINOR 0
#define VER_RELEASE 0
#define VER_BUILD 0
#define COMPANY_NAME ""
#define FILE_VERSION ""
#define FILE_DESCRIPTION "Developed using the Red Panda C++ IDE"
#define INTERNAL_NAME ""
#define LEGAL_COPYRIGHT ""
#define LEGAL_TRADEMARKS ""
#define ORIGINAL_FILENAME ""
#define PRODUCT_NAME ""
#define PRODUCT_VERSION ""
#endif /*redpanda-git-askpass_private_rc*/

View File

@ -0,0 +1,6 @@
/* THIS FILE WILL BE OVERWRITTEN BY Red Panda C++ */
/* DO NOT EDIT! */
#include "resource.rc"
A ICON "redpanda-git-askpass.ico"

View File

@ -0,0 +1,7 @@
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif
#define IDD_MAIN_DIALOG 101
#define ID_TXT_PASSWORD 40000
#define ID_TXT_PROMPT 40001

View File

@ -0,0 +1,24 @@
// Generated by ResEdit 1.6.5
// Copyright (C) 2006-2015
// http://www.resedit.net
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"
//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_MAIN_DIALOG DIALOG 0, 0, 180, 56
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Dialog"
FONT 12, "Microsoft Sans Serif"
{
LTEXT "Static", ID_TXT_PROMPT, 7, 7, 169, 13, SS_LEFT, WS_EX_LEFT
EDITTEXT ID_TXT_PASSWORD, 7, 26, 168, 19, ES_AUTOHSCROLL, WS_EX_LEFT
}