1 | #include "HistoryWidget.h" |
2 | |
3 | #include <AmendWidget.h> |
4 | #include <BranchesWidget.h> |
5 | #include <CheckBox.h> |
6 | #include <CommitHistoryModel.h> |
7 | #include <CommitHistoryView.h> |
8 | #include <CommitInfo.h> |
9 | #include <CommitInfoWidget.h> |
10 | #include <FileDiffWidget.h> |
11 | #include <FileEditor.h> |
12 | #include <FullDiffWidget.h> |
13 | #include <GitBase.h> |
14 | #include <GitBranches.h> |
15 | #include <GitCache.h> |
16 | #include <GitConfig.h> |
17 | #include <GitHistory.h> |
18 | #include <GitLocal.h> |
19 | #include <GitMerge.h> |
20 | #include <GitQlientSettings.h> |
21 | #include <GitQlientStyles.h> |
22 | #include <GitRemote.h> |
23 | #include <GitRepoLoader.h> |
24 | #include <GitWip.h> |
25 | #include <RepositoryViewDelegate.h> |
26 | #include <WipWidget.h> |
27 | |
28 | #include <QLogger.h> |
29 | |
30 | #include <QApplication> |
31 | #include <QGridLayout> |
32 | #include <QLabel> |
33 | #include <QLineEdit> |
34 | #include <QMenu> |
35 | #include <QMessageBox> |
36 | #include <QPushButton> |
37 | #include <QScreen> |
38 | #include <QSplitter> |
39 | #include <QStackedWidget> |
40 | |
41 | using namespace QLogger; |
42 | |
43 | HistoryWidget::HistoryWidget(const QSharedPointer<GitCache> &cache, const QSharedPointer<GitBase> git, |
44 | const QSharedPointer<GitServerCache> &gitServerCache, |
45 | const QSharedPointer<GitQlientSettings> &settings, QWidget *parent) |
46 | : QFrame(parent) |
47 | , mGit(git) |
48 | , mCache(cache) |
49 | , mGitServerCache(gitServerCache) |
50 | , mSettings(settings) |
51 | , mWipWidget(new WipWidget(mCache, mGit)) |
52 | , mAmendWidget(new AmendWidget(mCache, mGit)) |
53 | , mCommitInfoWidget(new CommitInfoWidget(mCache, mGit)) |
54 | , mReturnFromFull(new QPushButton()) |
55 | , mUserName(new QLabel()) |
56 | , mUserEmail(new QLabel()) |
57 | , mSplitter(new QSplitter()) |
58 | { |
59 | setAttribute(Qt::WA_DeleteOnClose); |
60 | |
61 | QScopedPointer<GitConfig> gitConfig(new GitConfig(mGit)); |
62 | const auto localUserInfo = gitConfig->getLocalUserInfo(); |
63 | const auto globalUserInfo = gitConfig->getGlobalUserInfo(); |
64 | |
65 | mUserName->setText(localUserInfo.mUserName.isEmpty() ? globalUserInfo.mUserName : localUserInfo.mUserName); |
66 | mUserEmail->setText(localUserInfo.mUserEmail.isEmpty() ? globalUserInfo.mUserEmail : localUserInfo.mUserEmail); |
67 | |
68 | const auto wipInfoFrame = new QFrame(); |
69 | wipInfoFrame->setObjectName("wipInfoFrame" ); |
70 | const auto wipInfoLayout = new QVBoxLayout(wipInfoFrame); |
71 | wipInfoLayout->setContentsMargins(QMargins()); |
72 | wipInfoLayout->setSpacing(10); |
73 | wipInfoLayout->addWidget(mUserName); |
74 | wipInfoLayout->addWidget(mUserEmail); |
75 | |
76 | mCommitStackedWidget = new QStackedWidget(); |
77 | mCommitStackedWidget->setCurrentIndex(0); |
78 | mCommitStackedWidget->addWidget(mCommitInfoWidget); |
79 | mCommitStackedWidget->addWidget(mWipWidget); |
80 | mCommitStackedWidget->addWidget(mAmendWidget); |
81 | |
82 | const auto wipLayout = new QVBoxLayout(); |
83 | wipLayout->setContentsMargins(QMargins()); |
84 | wipLayout->setSpacing(5); |
85 | wipLayout->addWidget(wipInfoFrame); |
86 | wipLayout->addWidget(mCommitStackedWidget); |
87 | |
88 | const auto wipFrame = new QFrame(); |
89 | wipFrame->setLayout(wipLayout); |
90 | wipFrame->setMinimumWidth(200); |
91 | wipFrame->setMaximumWidth(500); |
92 | |
93 | connect(mWipWidget, &CommitChangesWidget::signalShowDiff, this, &HistoryWidget::showFileDiff); |
94 | connect(mWipWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::returnToView); |
95 | connect(mWipWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::changesCommitted); |
96 | connect(mWipWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::cleanCommitPanels); |
97 | connect(mWipWidget, &CommitChangesWidget::signalCheckoutPerformed, this, &HistoryWidget::onRevertedChanges); |
98 | connect(mWipWidget, &CommitChangesWidget::signalShowFileHistory, this, &HistoryWidget::signalShowFileHistory); |
99 | connect(mWipWidget, &CommitChangesWidget::signalUpdateWip, this, &HistoryWidget::signalUpdateWip); |
100 | connect(mWipWidget, &CommitChangesWidget::changeReverted, this, [this](const QString &revertedFile) { |
101 | if (mFileDiff->getCurrentFile().contains(revertedFile)) |
102 | { |
103 | returnToView(); |
104 | onRevertedChanges(); |
105 | } |
106 | }); |
107 | |
108 | connect(mAmendWidget, &CommitChangesWidget::logReload, this, &HistoryWidget::logReload); |
109 | connect(mAmendWidget, &CommitChangesWidget::signalShowDiff, this, &HistoryWidget::showFileDiff); |
110 | connect(mAmendWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::returnToView); |
111 | connect(mAmendWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::changesCommitted); |
112 | connect(mAmendWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::cleanCommitPanels); |
113 | connect(mAmendWidget, &CommitChangesWidget::signalCheckoutPerformed, this, &HistoryWidget::onRevertedChanges); |
114 | connect(mAmendWidget, &CommitChangesWidget::signalShowFileHistory, this, &HistoryWidget::signalShowFileHistory); |
115 | connect(mAmendWidget, &CommitChangesWidget::signalUpdateWip, this, &HistoryWidget::signalUpdateWip); |
116 | connect(mAmendWidget, &CommitChangesWidget::signalCancelAmend, this, &HistoryWidget::selectCommit); |
117 | |
118 | connect(mCommitInfoWidget, &CommitInfoWidget::signalOpenFileCommit, this, &HistoryWidget::showFileDiff); |
119 | connect(mCommitInfoWidget, &CommitInfoWidget::signalShowFileHistory, this, &HistoryWidget::signalShowFileHistory); |
120 | |
121 | mSearchInput = new QLineEdit(); |
122 | mSearchInput->setObjectName("SearchInput" ); |
123 | mSearchInput->setPlaceholderText(tr("Press Enter to search by SHA or log message..." )); |
124 | connect(mSearchInput, &QLineEdit::returnPressed, this, &HistoryWidget::search); |
125 | |
126 | mRepositoryModel = new CommitHistoryModel(mCache, mGit, mGitServerCache); |
127 | mRepositoryView = new CommitHistoryView(mCache, mGit, mSettings, mGitServerCache); |
128 | |
129 | connect(mRepositoryView, &CommitHistoryView::fullReload, this, &HistoryWidget::fullReload); |
130 | connect(mRepositoryView, &CommitHistoryView::referencesReload, this, &HistoryWidget::referencesReload); |
131 | connect(mRepositoryView, &CommitHistoryView::logReload, this, &HistoryWidget::logReload); |
132 | |
133 | connect(mRepositoryView, &CommitHistoryView::signalOpenDiff, this, &HistoryWidget::onOpenFullDiff); |
134 | connect(mRepositoryView, &CommitHistoryView::signalOpenCompareDiff, this, &HistoryWidget::signalOpenCompareDiff); |
135 | connect(mRepositoryView, &CommitHistoryView::clicked, this, &HistoryWidget::commitSelected); |
136 | connect(mRepositoryView, &CommitHistoryView::customContextMenuRequested, this, [this](const QPoint &pos) { |
137 | const auto rowIndex = mRepositoryView->indexAt(pos); |
138 | commitSelected(rowIndex); |
139 | }); |
140 | connect(mRepositoryView, &CommitHistoryView::signalAmendCommit, this, &HistoryWidget::onAmendCommit); |
141 | connect(mRepositoryView, &CommitHistoryView::signalMergeRequired, this, &HistoryWidget::mergeBranch); |
142 | connect(mRepositoryView, &CommitHistoryView::mergeSqushRequested, this, &HistoryWidget::mergeSquashBranch); |
143 | connect(mRepositoryView, &CommitHistoryView::signalCherryPickConflict, this, |
144 | &HistoryWidget::signalCherryPickConflict); |
145 | connect(mRepositoryView, &CommitHistoryView::signalPullConflict, this, &HistoryWidget::signalPullConflict); |
146 | connect(mRepositoryView, &CommitHistoryView::showPrDetailedView, this, &HistoryWidget::showPrDetailedView); |
147 | |
148 | mRepositoryView->setObjectName("historyGraphView" ); |
149 | mRepositoryView->setModel(mRepositoryModel); |
150 | mRepositoryView->setItemDelegate(mItemDelegate |
151 | = new RepositoryViewDelegate(cache, mGit, mGitServerCache, mRepositoryView)); |
152 | mRepositoryView->setEnabled(true); |
153 | |
154 | mBranchesWidget = new BranchesWidget(mCache, mGit); |
155 | |
156 | connect(mBranchesWidget, &BranchesWidget::fullReload, this, &HistoryWidget::fullReload); |
157 | connect(mBranchesWidget, &BranchesWidget::logReload, this, &HistoryWidget::logReload); |
158 | |
159 | connect(mBranchesWidget, &BranchesWidget::signalSelectCommit, mRepositoryView, &CommitHistoryView::focusOnCommit); |
160 | connect(mBranchesWidget, &BranchesWidget::signalSelectCommit, this, &HistoryWidget::goToSha); |
161 | connect(mBranchesWidget, &BranchesWidget::signalOpenSubmodule, this, &HistoryWidget::signalOpenSubmodule); |
162 | connect(mBranchesWidget, &BranchesWidget::signalMergeRequired, this, &HistoryWidget::mergeBranch); |
163 | connect(mBranchesWidget, &BranchesWidget::mergeSqushRequested, this, &HistoryWidget::mergeSquashBranch); |
164 | connect(mBranchesWidget, &BranchesWidget::signalPullConflict, this, &HistoryWidget::signalPullConflict); |
165 | connect(mBranchesWidget, &BranchesWidget::panelsVisibilityChanged, this, &HistoryWidget::panelsVisibilityChanged); |
166 | |
167 | const auto cherryPickBtn = new QPushButton(tr("Cherry-pick" )); |
168 | cherryPickBtn->setEnabled(false); |
169 | cherryPickBtn->setObjectName("cherryPickBtn" ); |
170 | cherryPickBtn->setToolTip("Cherry-pick the commit" ); |
171 | connect(cherryPickBtn, &QPushButton::clicked, this, &HistoryWidget::cherryPickCommit); |
172 | connect(mSearchInput, &QLineEdit::textChanged, this, |
173 | [cherryPickBtn](const QString &text) { cherryPickBtn->setEnabled(!text.isEmpty()); }); |
174 | |
175 | mChShowAllBranches = new CheckBox(tr("Show all branches" )); |
176 | mChShowAllBranches->setChecked(mSettings->localValue("ShowAllBranches" , true).toBool()); |
177 | connect(mChShowAllBranches, &CheckBox::toggled, this, &HistoryWidget::onShowAllUpdated); |
178 | |
179 | const auto graphOptionsLayout = new QHBoxLayout(); |
180 | graphOptionsLayout->setContentsMargins(QMargins()); |
181 | graphOptionsLayout->setSpacing(10); |
182 | graphOptionsLayout->addWidget(mSearchInput); |
183 | graphOptionsLayout->addWidget(cherryPickBtn); |
184 | graphOptionsLayout->addWidget(mChShowAllBranches); |
185 | |
186 | const auto viewLayout = new QVBoxLayout(); |
187 | viewLayout->setContentsMargins(QMargins()); |
188 | viewLayout->setSpacing(5); |
189 | viewLayout->addLayout(graphOptionsLayout); |
190 | viewLayout->addWidget(mRepositoryView); |
191 | |
192 | mGraphFrame = new QFrame(); |
193 | mGraphFrame->setLayout(viewLayout); |
194 | |
195 | mFileDiff = new FileDiffWidget(mGit, mCache); |
196 | |
197 | mReturnFromFull->setIcon(QIcon(":/icons/back" )); |
198 | connect(mReturnFromFull, &QPushButton::clicked, this, &HistoryWidget::returnToView); |
199 | mFullDiffWidget = new FullDiffWidget(mGit, mCache); |
200 | |
201 | const auto fullFrame = new QFrame(); |
202 | const auto fullLayout = new QGridLayout(fullFrame); |
203 | fullLayout->setSpacing(10); |
204 | fullLayout->setContentsMargins(QMargins()); |
205 | fullLayout->addWidget(mReturnFromFull, 0, 0); |
206 | fullLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed), 0, 1); |
207 | fullLayout->addWidget(mFullDiffWidget, 1, 0, 1, 2); |
208 | |
209 | mCenterStackedWidget = new QStackedWidget(); |
210 | mCenterStackedWidget->setMinimumWidth(600); |
211 | mCenterStackedWidget->insertWidget(static_cast<int>(Pages::Graph), mGraphFrame); |
212 | mCenterStackedWidget->insertWidget(static_cast<int>(Pages::FileDiff), mFileDiff); |
213 | mCenterStackedWidget->insertWidget(static_cast<int>(Pages::FullDiff), fullFrame); |
214 | |
215 | connect(mFileDiff, &FileDiffWidget::exitRequested, this, &HistoryWidget::returnToView); |
216 | connect(mFileDiff, &FileDiffWidget::fileStaged, this, &HistoryWidget::signalUpdateWip); |
217 | connect(mFileDiff, &FileDiffWidget::fileReverted, this, &HistoryWidget::signalUpdateWip); |
218 | |
219 | connect(mWipWidget, &WipWidget::signalEditFile, mFileDiff, [this](const QString &fileName) { |
220 | showFileDiffEdition(CommitInfo::ZERO_SHA, mCache->commitInfo(CommitInfo::ZERO_SHA).firstParent(), fileName); |
221 | }); |
222 | |
223 | mSplitter->insertWidget(0, wipFrame); |
224 | mSplitter->insertWidget(1, mCenterStackedWidget); |
225 | mSplitter->setCollapsible(1, false); |
226 | mSplitter->insertWidget(2, mBranchesWidget); |
227 | |
228 | const auto minimalActive = mBranchesWidget->isMinimalViewActive(); |
229 | const auto branchesWidth = minimalActive ? 50 : 200; |
230 | |
231 | rearrangeSplittrer(minimalActive); |
232 | |
233 | connect(mBranchesWidget, &BranchesWidget::minimalViewStateChanged, this, &HistoryWidget::rearrangeSplittrer); |
234 | |
235 | const auto splitterSate = mSettings->localValue("HistoryWidgetState" , QByteArray()).toByteArray(); |
236 | |
237 | if (splitterSate.isEmpty()) |
238 | mSplitter->setSizes({ 200, 500, branchesWidth }); |
239 | else |
240 | mSplitter->restoreState(splitterSate); |
241 | |
242 | const auto layout = new QHBoxLayout(this); |
243 | layout->setContentsMargins(QMargins()); |
244 | layout->addWidget(mSplitter); |
245 | |
246 | mCenterStackedWidget->setCurrentIndex(static_cast<int>(Pages::Graph)); |
247 | mCenterStackedWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
248 | mBranchesWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); |
249 | } |
250 | |
251 | HistoryWidget::~HistoryWidget() |
252 | { |
253 | mSettings->setLocalValue("HistoryWidgetState" , mSplitter->saveState()); |
254 | |
255 | delete mItemDelegate; |
256 | delete mRepositoryModel; |
257 | } |
258 | |
259 | void HistoryWidget::clear() |
260 | { |
261 | mRepositoryView->clear(); |
262 | resetWip(); |
263 | mBranchesWidget->clear(); |
264 | mCommitInfoWidget->clear(); |
265 | mAmendWidget->clear(); |
266 | |
267 | mCommitStackedWidget->setCurrentIndex(mCommitStackedWidget->currentIndex()); |
268 | } |
269 | |
270 | void HistoryWidget::resetWip() |
271 | { |
272 | mWipWidget->clear(); |
273 | } |
274 | |
275 | void HistoryWidget::loadBranches(bool fullReload) |
276 | { |
277 | if (fullReload) |
278 | mBranchesWidget->showBranches(); |
279 | else |
280 | mBranchesWidget->refreshCurrentBranchLink(); |
281 | } |
282 | |
283 | void HistoryWidget::updateUiFromWatcher() |
284 | { |
285 | if (const auto widget = dynamic_cast<CommitChangesWidget *>(mCommitStackedWidget->currentWidget())) |
286 | widget->reload(); |
287 | |
288 | if (const auto widget = dynamic_cast<IDiffWidget *>(mCenterStackedWidget->currentWidget())) |
289 | widget->reload(); |
290 | } |
291 | |
292 | void HistoryWidget::focusOnCommit(const QString &sha) |
293 | { |
294 | mRepositoryView->focusOnCommit(sha); |
295 | } |
296 | |
297 | void HistoryWidget::updateGraphView(int totalCommits) |
298 | { |
299 | mRepositoryModel->onNewRevisions(totalCommits); |
300 | |
301 | selectCommit(CommitInfo::ZERO_SHA); |
302 | |
303 | mRepositoryView->selectionModel()->select( |
304 | QItemSelection(mRepositoryModel->index(0, 0), mRepositoryModel->index(0, mRepositoryModel->columnCount() - 1)), |
305 | QItemSelectionModel::Select); |
306 | } |
307 | |
308 | void HistoryWidget::keyPressEvent(QKeyEvent *event) |
309 | { |
310 | if (event->key() == Qt::Key_Shift) |
311 | mReverseSearch = true; |
312 | |
313 | QFrame::keyPressEvent(event); |
314 | } |
315 | |
316 | void HistoryWidget::keyReleaseEvent(QKeyEvent *event) |
317 | { |
318 | if (event->key() == Qt::Key_Shift) |
319 | mReverseSearch = false; |
320 | |
321 | QFrame::keyReleaseEvent(event); |
322 | } |
323 | |
324 | void HistoryWidget::onOpenFullDiff(const QString &sha) |
325 | { |
326 | if (sha == CommitInfo::ZERO_SHA) |
327 | { |
328 | const auto commit = mCache->commitInfo(CommitInfo::ZERO_SHA); |
329 | QScopedPointer<GitHistory> git(new GitHistory(mGit)); |
330 | const auto ret = git->getCommitDiff(CommitInfo::ZERO_SHA, commit.firstParent()); |
331 | |
332 | if (ret.success && !ret.output.isEmpty()) |
333 | { |
334 | mFullDiffWidget->loadDiff(CommitInfo::ZERO_SHA, commit.firstParent(), ret.output); |
335 | mCenterStackedWidget->setCurrentIndex(static_cast<int>(Pages::FullDiff)); |
336 | } |
337 | else |
338 | QMessageBox::warning(this, tr("No diff available!" ), tr("There is no diff to show." )); |
339 | } |
340 | else |
341 | emit signalOpenDiff(sha); |
342 | } |
343 | |
344 | void HistoryWidget::rearrangeSplittrer(bool minimalActive) |
345 | { |
346 | if (minimalActive) |
347 | { |
348 | mBranchesWidget->setFixedWidth(50); |
349 | mSplitter->setCollapsible(2, false); |
350 | } |
351 | else |
352 | { |
353 | mBranchesWidget->setMinimumWidth(250); |
354 | mBranchesWidget->setMaximumWidth(500); |
355 | mSplitter->setCollapsible(2, true); |
356 | } |
357 | } |
358 | |
359 | void HistoryWidget::cleanCommitPanels() |
360 | { |
361 | mWipWidget->clearStaged(); |
362 | mAmendWidget->clearStaged(); |
363 | } |
364 | |
365 | void HistoryWidget::onRevertedChanges() |
366 | { |
367 | QScopedPointer<GitWip> git(new GitWip(mGit, mCache)); |
368 | git->updateWip(); |
369 | |
370 | updateUiFromWatcher(); |
371 | } |
372 | |
373 | void HistoryWidget::onCommitTitleMaxLenghtChanged() |
374 | { |
375 | mWipWidget->setCommitTitleMaxLength(); |
376 | mAmendWidget->setCommitTitleMaxLength(); |
377 | } |
378 | |
379 | void HistoryWidget::onPanelsVisibilityChanged() |
380 | { |
381 | mBranchesWidget->onPanelsVisibilityChaned(); |
382 | } |
383 | |
384 | void HistoryWidget::search() |
385 | { |
386 | if (const auto text = mSearchInput->text(); !text.isEmpty()) |
387 | { |
388 | auto commitInfo = mCache->commitInfo(text); |
389 | |
390 | if (commitInfo.isValid()) |
391 | goToSha(text); |
392 | else |
393 | { |
394 | auto selectedItems = mRepositoryView->selectedIndexes(); |
395 | auto startingRow = 0; |
396 | |
397 | if (!selectedItems.isEmpty()) |
398 | { |
399 | std::sort(selectedItems.begin(), selectedItems.end(), |
400 | [](const QModelIndex index1, const QModelIndex index2) { return index1.row() <= index2.row(); }); |
401 | startingRow = selectedItems.constFirst().row(); |
402 | } |
403 | |
404 | commitInfo = mCache->searchCommitInfo(text, startingRow + 1, mReverseSearch); |
405 | |
406 | if (commitInfo.isValid()) |
407 | goToSha(commitInfo.sha); |
408 | else |
409 | QMessageBox::information(this, tr("Not found!" ), tr("No commits where found based on the search text." )); |
410 | } |
411 | } |
412 | } |
413 | |
414 | void HistoryWidget::goToSha(const QString &sha) |
415 | { |
416 | mRepositoryView->focusOnCommit(sha); |
417 | |
418 | selectCommit(sha); |
419 | } |
420 | |
421 | void HistoryWidget::commitSelected(const QModelIndex &index) |
422 | { |
423 | const auto sha = mRepositoryModel->sha(index.row()); |
424 | |
425 | selectCommit(sha); |
426 | } |
427 | |
428 | void HistoryWidget::onShowAllUpdated(bool showAll) |
429 | { |
430 | GitQlientSettings settings(mGit->getGitDir()); |
431 | settings.setLocalValue("ShowAllBranches" , showAll); |
432 | |
433 | emit signalAllBranchesActive(showAll); |
434 | emit logReload(); |
435 | } |
436 | |
437 | void HistoryWidget::mergeBranch(const QString ¤t, const QString &branchToMerge) |
438 | { |
439 | QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); |
440 | QScopedPointer<GitMerge> git(new GitMerge(mGit, mCache)); |
441 | const auto ret = git->merge(current, { branchToMerge }); |
442 | |
443 | QScopedPointer<GitWip> gitWip(new GitWip(mGit, mCache)); |
444 | gitWip->updateWip(); |
445 | |
446 | QApplication::restoreOverrideCursor(); |
447 | |
448 | processMergeResponse(ret); |
449 | } |
450 | |
451 | void HistoryWidget::mergeSquashBranch(const QString ¤t, const QString &branchToMerge) |
452 | { |
453 | QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); |
454 | QScopedPointer<GitMerge> git(new GitMerge(mGit, mCache)); |
455 | const auto ret = git->squashMerge(current, { branchToMerge }); |
456 | |
457 | QScopedPointer<GitWip> gitWip(new GitWip(mGit, mCache)); |
458 | gitWip->updateWip(); |
459 | |
460 | QApplication::restoreOverrideCursor(); |
461 | |
462 | processMergeResponse(ret); |
463 | } |
464 | |
465 | void HistoryWidget::processMergeResponse(const GitExecResult &ret) |
466 | { |
467 | if (!ret.success) |
468 | { |
469 | QMessageBox msgBox( |
470 | QMessageBox::Critical, tr("Merge failed" ), |
471 | QString(tr("There were problems during the merge. Please, see the detailed description for more " |
472 | "information.<br><br>GitQlient will show the merge helper tool." )), |
473 | QMessageBox::Ok, this); |
474 | msgBox.setDetailedText(ret.output); |
475 | msgBox.setStyleSheet(GitQlientStyles::getStyles()); |
476 | msgBox.exec(); |
477 | |
478 | emit signalMergeConflicts(); |
479 | } |
480 | else |
481 | { |
482 | if (!ret.output.isEmpty()) |
483 | { |
484 | if (ret.output.contains("error: could not apply" , Qt::CaseInsensitive) |
485 | || ret.output.contains(" conflict" , Qt::CaseInsensitive)) |
486 | { |
487 | QMessageBox msgBox( |
488 | QMessageBox::Warning, tr("Merge status" ), |
489 | tr("There were problems during the merge. Please, see the detailed description for more information." ), |
490 | QMessageBox::Ok, this); |
491 | msgBox.setDetailedText(ret.output); |
492 | msgBox.setStyleSheet(GitQlientStyles::getStyles()); |
493 | msgBox.exec(); |
494 | |
495 | emit signalMergeConflicts(); |
496 | } |
497 | else |
498 | { |
499 | emit fullReload(); |
500 | |
501 | QMessageBox msgBox( |
502 | QMessageBox::Information, tr("Merge successful" ), |
503 | tr("The merge was successfully done. See the detailed description for more information." ), |
504 | QMessageBox::Ok, this); |
505 | msgBox.setDetailedText(ret.output); |
506 | msgBox.setStyleSheet(GitQlientStyles::getStyles()); |
507 | msgBox.exec(); |
508 | } |
509 | } |
510 | } |
511 | } |
512 | |
513 | void HistoryWidget::selectCommit(const QString &goToSha) |
514 | { |
515 | const auto isWip = goToSha == CommitInfo::ZERO_SHA; |
516 | mCommitStackedWidget->setCurrentIndex(isWip); |
517 | |
518 | QLog_Info("UI" , QString("Selected commit {%1}" ).arg(goToSha)); |
519 | |
520 | if (isWip) |
521 | mWipWidget->reload(); |
522 | else |
523 | mCommitInfoWidget->configure(goToSha); |
524 | } |
525 | |
526 | void HistoryWidget::onAmendCommit(const QString &sha) |
527 | { |
528 | mCommitStackedWidget->setCurrentIndex(2); |
529 | mAmendWidget->configure(sha); |
530 | } |
531 | |
532 | void HistoryWidget::returnToView() |
533 | { |
534 | mCenterStackedWidget->setCurrentIndex(static_cast<int>(Pages::Graph)); |
535 | mBranchesWidget->returnToSavedView(); |
536 | } |
537 | |
538 | void HistoryWidget::cherryPickCommit() |
539 | { |
540 | if (auto commit = mCache->commitInfo(mSearchInput->text()); commit.isValid()) |
541 | { |
542 | const auto lastShaBeforeCommit = mGit->getLastCommit().output.trimmed(); |
543 | const auto git = QScopedPointer<GitLocal>(new GitLocal(mGit)); |
544 | const auto ret = git->cherryPickCommit(commit.sha); |
545 | |
546 | if (ret.success) |
547 | { |
548 | mSearchInput->clear(); |
549 | |
550 | commit.sha = mGit->getLastCommit().output.trimmed(); |
551 | |
552 | mCache->insertCommit(commit); |
553 | mCache->deleteReference(lastShaBeforeCommit, References::Type::LocalBranch, mGit->getCurrentBranch()); |
554 | mCache->insertReference(commit.sha, References::Type::LocalBranch, mGit->getCurrentBranch()); |
555 | |
556 | QScopedPointer<GitHistory> gitHistory(new GitHistory(mGit)); |
557 | const auto ret = gitHistory->getDiffFiles(commit.sha, lastShaBeforeCommit); |
558 | |
559 | mCache->insertRevisionFiles(commit.sha, lastShaBeforeCommit, RevisionFiles(ret.output)); |
560 | |
561 | emit mCache->signalCacheUpdated(); |
562 | emit logReload(); |
563 | } |
564 | else |
565 | { |
566 | if (ret.output.contains("error: could not apply" , Qt::CaseInsensitive) |
567 | || ret.output.contains(" conflict" , Qt::CaseInsensitive)) |
568 | { |
569 | emit signalCherryPickConflict(QStringList()); |
570 | } |
571 | else |
572 | { |
573 | QMessageBox msgBox(QMessageBox::Critical, tr("Error while cherry-pick" ), |
574 | tr("There were problems during the cherry-pick operation. Please, see the detailed " |
575 | "description for more information." ), |
576 | QMessageBox::Ok, this); |
577 | msgBox.setDetailedText(ret.output); |
578 | msgBox.setStyleSheet(GitQlientStyles::getStyles()); |
579 | msgBox.exec(); |
580 | } |
581 | } |
582 | } |
583 | else |
584 | { |
585 | const auto git = QScopedPointer<GitLocal>(new GitLocal(mGit)); |
586 | const auto ret = git->cherryPickCommit(mSearchInput->text()); |
587 | |
588 | if (ret.success) |
589 | { |
590 | mSearchInput->clear(); |
591 | emit logReload(); |
592 | } |
593 | } |
594 | } |
595 | |
596 | void HistoryWidget::showFileDiff(const QString &sha, const QString &parentSha, const QString &fileName, bool isCached) |
597 | { |
598 | if (sha == CommitInfo::ZERO_SHA) |
599 | { |
600 | mFileDiff->configure(sha, parentSha, fileName, isCached); |
601 | mCenterStackedWidget->setCurrentIndex(static_cast<int>(Pages::FileDiff)); |
602 | mBranchesWidget->forceMinimalView(); |
603 | } |
604 | else |
605 | emit signalShowDiff(sha, parentSha, fileName, isCached); |
606 | } |
607 | |
608 | void HistoryWidget::showFileDiffEdition(const QString &sha, const QString &parentSha, const QString &fileName) |
609 | { |
610 | if (sha == CommitInfo::ZERO_SHA) |
611 | { |
612 | mFileDiff->configure(sha, parentSha, fileName, true); |
613 | mCenterStackedWidget->setCurrentIndex(static_cast<int>(Pages::FileDiff)); |
614 | mBranchesWidget->forceMinimalView(); |
615 | } |
616 | else |
617 | emit signalShowDiff(sha, parentSha, fileName, false); |
618 | } |
619 | |