File indexing completed on 2024-04-28 04:38:52

0001 /*
0002     SPDX-FileCopyrightText: 2010 Aleix Pol Gonzalez <aleixpol@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "stashmanagerdialog.h"
0008 #include "ui_stashmanagerdialog.h"
0009 #include "gitplugin.h"
0010 #include "stashpatchsource.h"
0011 #include <interfaces/icore.h>
0012 #include <interfaces/iruncontroller.h>
0013 #include <interfaces/iplugincontroller.h>
0014 #include <interfaces/idocumentcontroller.h>
0015 #include <vcs/dvcs/dvcsjob.h>
0016 
0017 #include <QDialogButtonBox>
0018 #include <QInputDialog>
0019 #include <QPushButton>
0020 
0021 #include <KLocalizedString>
0022 #include <KMessageBox>
0023 #include <KMessageBox_KDevCompat>
0024 #include <KTextEditor/Document>
0025 
0026 using namespace KDevelop;
0027 
0028 StashManagerDialog::StashManagerDialog(const QDir& stashed, GitPlugin* plugin, QWidget* parent)
0029     : QDialog(parent), m_plugin(plugin), m_dir(stashed)
0030 {
0031     setWindowTitle(i18nc("@title:window", "Stash Manager"));
0032 
0033     m_ui = new Ui::StashManager;
0034     m_ui->setupUi(this);
0035 
0036     auto* m = new StashModel(stashed, plugin, this);
0037     m_ui->stashView->setModel(m);
0038 
0039     connect(m_ui->show,   &QPushButton::clicked, this, &StashManagerDialog::showStash);
0040     connect(m_ui->apply,  &QPushButton::clicked, this, &StashManagerDialog::applyClicked);
0041     connect(m_ui->branch, &QPushButton::clicked, this, &StashManagerDialog::branchClicked);
0042     connect(m_ui->pop,    &QPushButton::clicked, this, &StashManagerDialog::popClicked);
0043     connect(m_ui->drop,   &QPushButton::clicked, this, &StashManagerDialog::dropClicked);
0044     connect(m, &StashModel::rowsInserted, this, &StashManagerDialog::stashesFound);
0045 
0046     connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &StashManagerDialog::reject);
0047 
0048     setEnabled(false); //we won't enable it until we have the model with data and selection
0049 }
0050 
0051 StashManagerDialog::~StashManagerDialog()
0052 {
0053     delete m_ui;
0054 }
0055 
0056 void StashManagerDialog::stashesFound()
0057 {
0058     QModelIndex firstIdx=m_ui->stashView->model()->index(0, 0);
0059     m_ui->stashView->setCurrentIndex(firstIdx);
0060     setEnabled(true);
0061 }
0062 
0063 QString StashManagerDialog::selection() const
0064 {
0065     QModelIndex idx = m_ui->stashView->currentIndex();
0066     Q_ASSERT(idx.isValid());
0067     return idx.data(StashModel::RefRole).toString();
0068 }
0069 
0070 void StashManagerDialog::runStash(const QStringList& arguments)
0071 {
0072     VcsJob* job = m_plugin->gitStash(m_dir, arguments, OutputJob::Verbose);
0073     connect(job, &VcsJob::result, this, &StashManagerDialog::accept);
0074 
0075     setEnabled(false);
0076 
0077     ICore::self()->runController()->registerJob(job);
0078 }
0079 
0080 void StashManagerDialog::showStash()
0081 {
0082     IPatchSource::Ptr stashPatch(new StashPatchSource(selection(), m_plugin, m_dir));
0083 
0084     if (auto * review = ICore::self()->pluginController()->extensionForPlugin<IPatchReview>()) {
0085         review->startReview(stashPatch);
0086     } else {
0087         auto* docCtrl = ICore::self()->documentController();
0088         connect(stashPatch, &StashPatchSource::patchChanged, docCtrl, [=] {
0089             auto* doc = docCtrl->openDocument(
0090                 stashPatch->file(),
0091                 KTextEditor::Range::invalid(),
0092                 IDocumentController::DoNotAddToRecentOpen
0093             );
0094             doc->setPrettyName(stashPatch->name());
0095             doc->textDocument()->setReadWrite(false);
0096             doc->textDocument()->setMode(QStringLiteral("diff"));
0097             doc->textDocument()->setHighlightingMode(QStringLiteral("diff"));
0098             docCtrl->activateDocument(doc);
0099             connect(ICore::self(), &ICore::aboutToShutdown, docCtrl, [=] {doc->close();});
0100         });
0101     }
0102     accept();
0103 }
0104 
0105 void StashManagerDialog::applyClicked()
0106 {
0107     runStash(QStringList{QStringLiteral("apply"), selection()});
0108 }
0109 
0110 void StashManagerDialog::popClicked()
0111 {
0112     runStash(QStringList{QStringLiteral("pop"), selection()});
0113 }
0114 
0115 void StashManagerDialog::dropClicked()
0116 {
0117     QString sel = selection();
0118     int ret = KMessageBox::questionTwoActions(this, i18n("Are you sure you want to drop the stash '%1'?", sel), {},
0119                                               KGuiItem(i18nc("@action:button", "Drop"), QStringLiteral("edit-delete")),
0120                                               KStandardGuiItem::cancel());
0121 
0122     if (ret == KMessageBox::PrimaryAction)
0123         runStash(QStringList{QStringLiteral("drop"), sel});
0124 }
0125 
0126 void StashManagerDialog::branchClicked()
0127 {
0128     QString branchName = QInputDialog::getText(this, i18nc("@title:window", "Git Stash"), i18nc("@label:textbox", "Name for the new branch:"));
0129 
0130     if(!branchName.isEmpty())
0131         runStash(QStringList{QStringLiteral("branch"), branchName, selection()});
0132 }
0133 
0134 //////////////////StashModel
0135 
0136 StashModel::StashModel(const QDir& dir, GitPlugin* git, QObject* parent)
0137     : QStandardItemModel(parent)
0138 {
0139     auto job = git->stashList(dir, OutputJob::Silent);
0140     connect(job, &VcsJob::finished, this, &StashModel::stashListReady);
0141     ICore::self()->runController()->registerJob(job);
0142 }
0143 
0144 void StashModel::stashListReady(KJob* _job)
0145 {
0146     auto* job = qobject_cast<VcsJob*>(_job);
0147 
0148     for(const auto& s_item: job->fetchResults().value<QList<GitPlugin::StashItem>>()) {
0149         const QString itemValue = i18nc("%1: stack depth, %2: branch, %3: parent description", "%1. %2: %3",
0150                                         QString::number(s_item.stackDepth), s_item.branch, s_item.parentDescription);
0151         auto* item = new QStandardItem(itemValue);
0152         item->setData(s_item.shortRef, StashModel::RefRole);
0153         item->setData(s_item.parentSHA, StashModel::CommitHashRole);
0154         item->setData(s_item.parentDescription, StashModel::CommitDescRole);
0155         item->setData(s_item.branch, StashModel::BranchRole);
0156         item->setData(s_item.message, StashModel::MessageRole);
0157         item->setData(s_item.creationTime, StashModel::DateRole);
0158         item->setData(
0159             i18n("%1 created on %2", s_item.branch, s_item.creationTime.toString()),
0160             Qt::ToolTipRole
0161         );
0162         appendRow(item);
0163     };
0164 }
0165 
0166 #include "moc_stashmanagerdialog.cpp"