1 | #include "UnstagedMenu.h" |
2 | |
3 | #include <GitBase.h> |
4 | #include <GitLocal.h> |
5 | #include <GitSyncProcess.h> |
6 | #include <QLogger.h> |
7 | |
8 | #include <QDir> |
9 | #include <QFile> |
10 | #include <QMessageBox> |
11 | |
12 | using namespace QLogger; |
13 | |
14 | UnstagedMenu::(const QSharedPointer<GitBase> &git, const QString &fileName, QWidget *parent) |
15 | : QMenu(parent) |
16 | , mGit(git) |
17 | , mFileName(fileName) |
18 | { |
19 | setAttribute(Qt::WA_DeleteOnClose); |
20 | |
21 | connect(addAction(tr("See changes" )), &QAction::triggered, this, [this]() { emit signalShowDiff(mFileName); }); |
22 | connect(addAction(tr("Blame" )), &QAction::triggered, this, [this]() { emit signalShowFileHistory(mFileName); }); |
23 | connect(addAction(tr("Edit file" )), &QAction::triggered, this, |
24 | [this]() { emit signalEditFile(mGit->getWorkingDir() + "/" + mFileName); }); |
25 | |
26 | addSeparator(); |
27 | |
28 | connect(addAction(tr("Stage file" )), &QAction::triggered, this, &UnstagedMenu::signalStageFile); |
29 | |
30 | connect(addAction(tr("Revert file changes" )), &QAction::triggered, this, [this]() { |
31 | const auto msgBoxRet |
32 | = QMessageBox::question(this, tr("Ignoring file" ), tr("Are you sure you want to revert the changes?" )); |
33 | |
34 | if (msgBoxRet == QMessageBox::Yes) |
35 | { |
36 | QScopedPointer<GitLocal> git(new GitLocal(mGit)); |
37 | const auto ret = git->checkoutFile(mFileName); |
38 | |
39 | if (ret) |
40 | emit changeReverted(mFileName); |
41 | } |
42 | }); |
43 | |
44 | addSeparator(); |
45 | |
46 | const auto = addMenu(tr("Ignore" )); |
47 | |
48 | connect(ignoreMenu->addAction(tr("Ignore file" )), &QAction::triggered, this, [this]() { |
49 | const auto ret = QMessageBox::question(this, tr("Ignoring file" ), |
50 | tr("Are you sure you want to add the file to the black list?" )); |
51 | |
52 | if (ret == QMessageBox::Yes) |
53 | { |
54 | const auto gitRet = addEntryToGitIgnore(mFileName); |
55 | |
56 | if (gitRet) |
57 | emit signalCheckedOut(); |
58 | } |
59 | }); |
60 | |
61 | connect(addAction(tr("Delete file" )), &QAction::triggered, this, &UnstagedMenu::onDeleteFile); |
62 | |
63 | connect(addAction(tr("Delete ALL untracked files" )), &QAction::triggered, this, &UnstagedMenu::deleteUntracked); |
64 | |
65 | connect(ignoreMenu->addAction(tr("Ignore extension" )), &QAction::triggered, this, [this]() { |
66 | const auto msgBoxRet = QMessageBox::question( |
67 | this, tr("Ignoring extension" ), tr("Are you sure you want to add the file extension to the black list?" )); |
68 | |
69 | if (msgBoxRet == QMessageBox::Yes) |
70 | { |
71 | auto fileParts = mFileName.split("." ); |
72 | fileParts.takeFirst(); |
73 | const auto extension = QString("*.%1" ).arg(fileParts.join("." )); |
74 | const auto ret = addEntryToGitIgnore(extension); |
75 | |
76 | if (ret) |
77 | emit signalCheckedOut(); |
78 | } |
79 | }); |
80 | |
81 | connect(ignoreMenu->addAction(tr("Ignore containing folder" )), &QAction::triggered, this, [this]() { |
82 | const auto msgBoxRet = QMessageBox::question( |
83 | this, tr("Ignoring folder" ), tr("Are you sure you want to add the containing folder to the black list?" )); |
84 | |
85 | if (msgBoxRet == QMessageBox::Yes) |
86 | { |
87 | const auto path = mFileName.lastIndexOf("/" ); |
88 | const auto folder = mFileName.left(path); |
89 | const auto extension = QString("%1/*" ).arg(folder); |
90 | const auto ret = addEntryToGitIgnore(extension); |
91 | |
92 | if (ret) |
93 | emit signalCheckedOut(); |
94 | } |
95 | }); |
96 | |
97 | addSeparator(); |
98 | |
99 | connect(addAction(tr("Add all files to commit" )), &QAction::triggered, this, &UnstagedMenu::signalCommitAll); |
100 | connect(addAction(tr("Revert all changes" )), &QAction::triggered, this, [this]() { |
101 | const auto msgBoxRet |
102 | = QMessageBox::question(this, tr("Ignoring file" ), tr("Are you sure you want to undo all the changes?" )); |
103 | if (msgBoxRet == QMessageBox::Yes) |
104 | emit signalRevertAll(); |
105 | }); |
106 | } |
107 | |
108 | bool UnstagedMenu::(const QString &entry) |
109 | { |
110 | auto entryAdded = false; |
111 | QDir d(mGit->getWorkingDir()); |
112 | QFile f(d.absolutePath() + "/.gitignore" ); |
113 | |
114 | if (!f.exists()) |
115 | { |
116 | if (f.open(QIODevice::ReadWrite)) |
117 | f.close(); |
118 | } |
119 | |
120 | if (f.open(QIODevice::Append)) |
121 | { |
122 | const auto bytesWritten = f.write(entry.toUtf8() + "\n" ); |
123 | |
124 | if (bytesWritten != -1) |
125 | { |
126 | QMessageBox::information(this, tr("File added to .gitignore" ), |
127 | tr("The file has been added to the ignore list in the file .gitignore." )); |
128 | |
129 | entryAdded = true; |
130 | } |
131 | else |
132 | QMessageBox::critical(this, tr("Unable to add the entry" ), |
133 | tr("It was impossible to add the entry in the .gitignore file." )); |
134 | |
135 | f.close(); |
136 | } |
137 | |
138 | return entryAdded; |
139 | } |
140 | |
141 | void UnstagedMenu::() |
142 | { |
143 | const auto path = QString("%1" ).arg(mFileName); |
144 | |
145 | QLog_Info("UI" , "Removing path: " + path); |
146 | |
147 | QProcess p; |
148 | p.setWorkingDirectory(mGit->getWorkingDir()); |
149 | p.start("rm" , { "-rf" , path }); |
150 | |
151 | if (p.waitForFinished()) |
152 | emit signalCheckedOut(); |
153 | } |
154 | |