1 | #include "ConfigWidget.h" |
2 | #include "ui_ConfigWidget.h" |
3 | |
4 | #include <FileEditor.h> |
5 | #include <GitBase.h> |
6 | #include <GitQlientSettings.h> |
7 | #include <QLogger.h> |
8 | |
9 | #include <CredentialsDlg.h> |
10 | #include <GitConfig.h> |
11 | #include <GitCredentials.h> |
12 | #include <QDir> |
13 | #include <QFileInfo> |
14 | #include <QMessageBox> |
15 | #include <QProcess> |
16 | #include <QPushButton> |
17 | #include <QStandardPaths> |
18 | #include <QTimer> |
19 | |
20 | using namespace QLogger; |
21 | |
22 | namespace |
23 | { |
24 | qint64 dirSize(QString dirPath) |
25 | { |
26 | qint64 size = 0; |
27 | QDir dir(dirPath); |
28 | |
29 | auto entryList = dir.entryList(QDir::Files | QDir::System | QDir::Hidden); |
30 | |
31 | for (const auto &filePath : qAsConst(entryList)) |
32 | { |
33 | QFileInfo fi(dir, filePath); |
34 | size += fi.size(); |
35 | } |
36 | |
37 | entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden); |
38 | |
39 | for (const auto &childDirPath : qAsConst(entryList)) |
40 | size += dirSize(dirPath + QDir::separator() + childDirPath); |
41 | |
42 | return size; |
43 | } |
44 | } |
45 | |
46 | ConfigWidget::ConfigWidget(const QSharedPointer<GitBase> &git, QWidget *parent) |
47 | : QWidget(parent) |
48 | , ui(new Ui::ConfigWidget) |
49 | , mGit(git) |
50 | , mFeedbackTimer(new QTimer()) |
51 | , mSave(new QPushButton()) |
52 | { |
53 | ui->setupUi(this); |
54 | |
55 | mFeedbackTimer->setInterval(3000); |
56 | |
57 | mSave->setIcon(QIcon(":/icons/save" )); |
58 | mSave->setToolTip(tr("Save" )); |
59 | connect(mSave, &QPushButton::clicked, this, &ConfigWidget::saveFile); |
60 | ui->tabWidget->setCornerWidget(mSave); |
61 | |
62 | ui->mainLayout->setColumnStretch(0, 1); |
63 | ui->mainLayout->setColumnStretch(1, 3); |
64 | |
65 | const auto localGitLayout = new QVBoxLayout(ui->localGit); |
66 | localGitLayout->setContentsMargins(QMargins()); |
67 | |
68 | mLocalGit = new FileEditor(false, this); |
69 | mLocalGit->editFile(mGit->getGitDir().append("/config" )); |
70 | localGitLayout->addWidget(mLocalGit); |
71 | |
72 | const auto globalGitLayout = new QVBoxLayout(ui->globalGit); |
73 | globalGitLayout->setContentsMargins(QMargins()); |
74 | |
75 | mGlobalGit = new FileEditor(false, this); |
76 | mGlobalGit->editFile( |
77 | QString("%1/%2" ).arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation), ".gitconfig" )); |
78 | globalGitLayout->addWidget(mGlobalGit); |
79 | |
80 | GitQlientSettings settings(mGit->getGitDir()); |
81 | |
82 | ui->chDevMode->setChecked(settings.localValue("DevMode" , false).toBool()); |
83 | enableWidgets(); |
84 | |
85 | // GitQlient configuration |
86 | ui->chDisableLogs->setChecked(settings.globalValue("logsDisabled" , true).toBool()); |
87 | ui->cbLogLevel->setCurrentIndex(settings.globalValue("logsLevel" , static_cast<int>(LogLevel::Warning)).toInt()); |
88 | ui->spCommitTitleLength->setValue(settings.globalValue("commitTitleMaxLength" , 50).toInt()); |
89 | |
90 | const auto originalStyles = settings.globalValue("colorSchema" , "dark" ).toString(); |
91 | ui->cbStyle->setCurrentText(originalStyles); |
92 | connect(ui->cbStyle, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentIndexChanged), this, |
93 | [this, originalStyles]() { |
94 | mShowResetMsg = ui->cbStyle->currentText() != originalStyles; |
95 | saveConfig(); |
96 | }); |
97 | |
98 | // Repository configuration |
99 | mOriginalRepoOrder = settings.localValue("GraphSortingOrder" , 0).toInt(); |
100 | ui->cbLogOrder->setCurrentIndex(mOriginalRepoOrder); |
101 | ui->autoFetch->setValue(settings.localValue("AutoFetch" , 5).toInt()); |
102 | ui->pruneOnFetch->setChecked(settings.localValue("PruneOnFetch" , true).toBool()); |
103 | ui->clangFormat->setChecked(settings.localValue("ClangFormatOnCommit" , false).toBool()); |
104 | ui->updateOnPull->setChecked(settings.localValue("UpdateOnPull" , false).toBool()); |
105 | ui->sbMaxCommits->setValue(settings.localValue("MaxCommits" , 0).toInt()); |
106 | |
107 | ui->tabWidget->setCurrentIndex(0); |
108 | connect(ui->pbClearCache, &ButtonLink::clicked, this, &ConfigWidget::clearCache); |
109 | |
110 | ui->cbPomodoroEnabled->setChecked(settings.localValue("Pomodoro/Enabled" , true).toBool()); |
111 | |
112 | ui->cbStash->setChecked(settings.localValue("StashesHeader" , true).toBool()); |
113 | ui->cbSubmodule->setChecked(settings.localValue("SubmodulesHeader" , true).toBool()); |
114 | ui->cbSubtree->setChecked(settings.localValue("SubtreeHeader" , true).toBool()); |
115 | |
116 | // Build System configuration |
117 | const auto isConfigured = settings.localValue("BuildSystemEnabled" , false).toBool(); |
118 | ui->chBoxBuildSystem->setChecked(isConfigured); |
119 | connect(ui->chBoxBuildSystem, &QCheckBox::stateChanged, this, &ConfigWidget::toggleBsAccesInfo); |
120 | |
121 | ui->leBsUser->setVisible(isConfigured); |
122 | ui->leBsUserLabel->setVisible(isConfigured); |
123 | ui->leBsToken->setVisible(isConfigured); |
124 | ui->leBsTokenLabel->setVisible(isConfigured); |
125 | ui->leBsUrl->setVisible(isConfigured); |
126 | ui->leBsUrlLabel->setVisible(isConfigured); |
127 | |
128 | if (isConfigured) |
129 | { |
130 | const auto url = settings.localValue("BuildSystemUrl" , "" ).toString(); |
131 | const auto user = settings.localValue("BuildSystemUser" , "" ).toString(); |
132 | const auto token = settings.localValue("BuildSystemToken" , "" ).toString(); |
133 | |
134 | ui->leBsUrl->setText(url); |
135 | ui->leBsUser->setText(user); |
136 | ui->leBsToken->setText(token); |
137 | } |
138 | |
139 | QScopedPointer<GitConfig> gitConfig(new GitConfig(git)); |
140 | |
141 | const auto url = gitConfig->getServerUrl(); |
142 | ui->credentialsFrames->setVisible(url.startsWith("https" )); |
143 | |
144 | connect(ui->buttonGroup, SIGNAL(buttonClicked(QAbstractButton *)), this, |
145 | SLOT(onCredentialsOptionChanged(QAbstractButton *))); |
146 | connect(ui->pbAddCredentials, &QPushButton::clicked, this, &ConfigWidget::showCredentialsDlg); |
147 | |
148 | // Connects for automatic save |
149 | connect(ui->chDevMode, &CheckBox::stateChanged, this, &ConfigWidget::enableWidgets); |
150 | connect(ui->chDisableLogs, &CheckBox::stateChanged, this, &ConfigWidget::saveConfig); |
151 | connect(ui->cbLogLevel, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig())); |
152 | connect(ui->leGitPath, &QLineEdit::editingFinished, this, &ConfigWidget::saveConfig); |
153 | connect(ui->spCommitTitleLength, SIGNAL(valueChanged(int)), this, SLOT(saveConfig())); |
154 | connect(ui->cbTranslations, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig())); |
155 | connect(ui->sbMaxCommits, SIGNAL(valueChanged(int)), this, SLOT(saveConfig())); |
156 | connect(ui->cbLogOrder, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig())); |
157 | connect(ui->autoFetch, SIGNAL(valueChanged(int)), this, SLOT(saveConfig())); |
158 | connect(ui->pruneOnFetch, &QCheckBox::stateChanged, this, &ConfigWidget::saveConfig); |
159 | connect(ui->updateOnPull, &QCheckBox::stateChanged, this, &ConfigWidget::saveConfig); |
160 | connect(ui->clangFormat, &QCheckBox::stateChanged, this, &ConfigWidget::saveConfig); |
161 | connect(ui->cbPomodoroEnabled, &QCheckBox::stateChanged, this, &ConfigWidget::saveConfig); |
162 | connect(ui->cbStash, &QCheckBox::stateChanged, this, &ConfigWidget::saveConfig); |
163 | connect(ui->cbSubmodule, &QCheckBox::stateChanged, this, &ConfigWidget::saveConfig); |
164 | connect(ui->cbSubtree, &QCheckBox::stateChanged, this, &ConfigWidget::saveConfig); |
165 | connect(ui->leBsUrl, &QLineEdit::editingFinished, this, &ConfigWidget::saveConfig); |
166 | connect(ui->leBsUser, &QLineEdit::editingFinished, this, &ConfigWidget::saveConfig); |
167 | connect(ui->leBsToken, &QLineEdit::editingFinished, this, &ConfigWidget::saveConfig); |
168 | |
169 | calculateCacheSize(); |
170 | } |
171 | |
172 | ConfigWidget::~ConfigWidget() |
173 | { |
174 | delete ui; |
175 | } |
176 | |
177 | void ConfigWidget::onPanelsVisibilityChanged() |
178 | { |
179 | GitQlientSettings settings(mGit->getGitDir()); |
180 | |
181 | ui->cbStash->setChecked(settings.localValue("StashesHeader" , true).toBool()); |
182 | ui->cbSubmodule->setChecked(settings.localValue("SubmodulesHeader" , true).toBool()); |
183 | ui->cbSubtree->setChecked(settings.localValue("SubtreeHeader" , true).toBool()); |
184 | } |
185 | |
186 | void ConfigWidget::onCredentialsOptionChanged(QAbstractButton *button) |
187 | { |
188 | ui->sbTimeout->setEnabled(button == ui->rbCache); |
189 | } |
190 | |
191 | void ConfigWidget::clearCache() |
192 | { |
193 | const auto path = QString("%1" ).arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); |
194 | QProcess p; |
195 | p.setWorkingDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); |
196 | p.start("rm" , { "-rf" , path }); |
197 | |
198 | if (p.waitForFinished()) |
199 | calculateCacheSize(); |
200 | } |
201 | |
202 | void ConfigWidget::calculateCacheSize() |
203 | { |
204 | auto size = 0; |
205 | const auto dirPath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); |
206 | QDir dir(dirPath); |
207 | QDir::Filters dirFilters = QDir::Dirs | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::Files; |
208 | const auto &list = dir.entryInfoList(dirFilters); |
209 | |
210 | for (const QFileInfo &file : list) |
211 | { |
212 | size += file.size(); |
213 | size += dirSize(dirPath + "/" + file.fileName()); |
214 | } |
215 | |
216 | ui->lCacheSize->setText(QString("%1 KB" ).arg(size / 1024.0)); |
217 | } |
218 | |
219 | void ConfigWidget::toggleBsAccesInfo() |
220 | { |
221 | const auto visible = ui->chBoxBuildSystem->isChecked(); |
222 | ui->leBsUser->setVisible(visible); |
223 | ui->leBsUserLabel->setVisible(visible); |
224 | ui->leBsToken->setVisible(visible); |
225 | ui->leBsTokenLabel->setVisible(visible); |
226 | ui->leBsUrl->setVisible(visible); |
227 | ui->leBsUrlLabel->setVisible(visible); |
228 | } |
229 | |
230 | void ConfigWidget::saveConfig() |
231 | { |
232 | mFeedbackTimer->stop(); |
233 | |
234 | ui->lFeedback->setText(tr("Changes saved" )); |
235 | |
236 | GitQlientSettings settings(mGit->getGitDir()); |
237 | |
238 | settings.setGlobalValue("logsDisabled" , ui->chDisableLogs->isChecked()); |
239 | settings.setGlobalValue("logsLevel" , ui->cbLogLevel->currentIndex()); |
240 | settings.setGlobalValue("commitTitleMaxLength" , ui->spCommitTitleLength->value()); |
241 | settings.setGlobalValue("colorSchema" , ui->cbStyle->currentText()); |
242 | settings.setGlobalValue("gitLocation" , ui->leGitPath->text()); |
243 | |
244 | emit commitTitleMaxLenghtChanged(); |
245 | |
246 | if (mShowResetMsg) |
247 | { |
248 | QMessageBox::information(this, tr("Reset needed!" ), |
249 | tr("You need to restart GitQlient to see the changes in the styles applid." )); |
250 | } |
251 | |
252 | const auto logger = QLoggerManager::getInstance(); |
253 | logger->overwriteLogLevel(static_cast<LogLevel>(ui->cbLogLevel->currentIndex())); |
254 | |
255 | if (ui->chDisableLogs->isChecked()) |
256 | logger->pause(); |
257 | else |
258 | logger->resume(); |
259 | |
260 | if (mOriginalRepoOrder != ui->cbLogOrder->currentIndex()) |
261 | { |
262 | settings.setLocalValue("GraphSortingOrder" , ui->cbLogOrder->currentIndex()); |
263 | emit reloadView(); |
264 | } |
265 | |
266 | settings.setLocalValue("AutoFetch" , ui->autoFetch->value()); |
267 | settings.setLocalValue("PruneOnFetch" , ui->pruneOnFetch->isChecked()); |
268 | settings.setLocalValue("ClangFormatOnCommit" , ui->clangFormat->isChecked()); |
269 | settings.setLocalValue("UpdateOnPull" , ui->updateOnPull->isChecked()); |
270 | settings.setLocalValue("MaxCommits" , ui->sbMaxCommits->value()); |
271 | |
272 | settings.setLocalValue("StashesHeader" , ui->cbStash->isChecked()); |
273 | settings.setLocalValue("SubmodulesHeader" , ui->cbSubmodule->isChecked()); |
274 | settings.setLocalValue("SubtreeHeader" , ui->cbSubtree->isChecked()); |
275 | |
276 | emit panelsVisibilityChaned(); |
277 | |
278 | /* POMODORO CONFIG */ |
279 | settings.setLocalValue("Pomodoro/Enabled" , ui->cbPomodoroEnabled->isChecked()); |
280 | |
281 | /* BUILD SYSTEM CONFIG */ |
282 | |
283 | const auto showBs = ui->chBoxBuildSystem->isChecked(); |
284 | const auto bsUser = ui->leBsUser->text(); |
285 | const auto bsToken = ui->leBsToken->text(); |
286 | const auto bsUrl = ui->leBsUrl->text(); |
287 | |
288 | if (showBs && !bsUser.isEmpty() && !bsToken.isEmpty() && !bsUrl.isEmpty()) |
289 | { |
290 | settings.setLocalValue("BuildSystemEnabled" , showBs); |
291 | settings.setLocalValue("BuildSystemUrl" , bsUrl); |
292 | settings.setLocalValue("BuildSystemUser" , bsUser); |
293 | settings.setLocalValue("BuildSystemToken" , bsToken); |
294 | emit buildSystemConfigured(showBs); |
295 | } |
296 | else |
297 | { |
298 | settings.setLocalValue("BuildSystemEnabled" , false); |
299 | emit buildSystemConfigured(false); |
300 | } |
301 | |
302 | mFeedbackTimer->singleShot(3000, ui->lFeedback, &QLabel::clear); |
303 | } |
304 | |
305 | void ConfigWidget::enableWidgets() |
306 | { |
307 | const auto enable = ui->chDevMode->isChecked(); |
308 | |
309 | GitQlientSettings settings(mGit->getGitDir()); |
310 | settings.setLocalValue("DevMode" , enable); |
311 | |
312 | ui->tabWidget->setEnabled(enable); |
313 | } |
314 | |
315 | void ConfigWidget::saveFile() |
316 | { |
317 | const auto id = ui->tabWidget->currentIndex(); |
318 | |
319 | if (id == 0) |
320 | mLocalGit->saveFile(); |
321 | else |
322 | mGlobalGit->saveFile(); |
323 | } |
324 | |
325 | void ConfigWidget::showCredentialsDlg() |
326 | { |
327 | // Store credentials if allowed and the user checked the box |
328 | if (ui->credentialsFrames->isVisible() && ui->chbCredentials->isChecked()) |
329 | { |
330 | if (ui->rbCache->isChecked()) |
331 | GitCredentials::configureCache(ui->sbTimeout->value(), mGit); |
332 | else |
333 | { |
334 | CredentialsDlg dlg(mGit, this); |
335 | dlg.exec(); |
336 | } |
337 | } |
338 | } |
339 | |