File indexing completed on 2024-04-21 05:41:02

0001 /*
0002     SPDX-FileCopyrightText: 2011 Vishesh Yadav <vishesh3y@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "importdialog.h"
0008 #include "fileviewhgpluginsettings.h"
0009 #include "commititemdelegate.h"
0010 #include "hgwrapper.h"
0011 
0012 #include <QCheckBox>
0013 #include <QGroupBox>
0014 #include <QVBoxLayout>
0015 #include <QGridLayout>
0016 #include <QListWidget>
0017 #include <QProcess>
0018 #include <QTextCodec>
0019 #include <QFile>
0020 #include <QTextStream>
0021 #include <QFileDialog>
0022 #include <KLocalizedString>
0023 #include <KMessageBox>
0024 
0025 HgImportDialog::HgImportDialog(QWidget *parent) :
0026     DialogBase(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, parent)
0027 {
0028     // dialog properties
0029     this->setWindowTitle(xi18nc("@title:window",
0030                 "<application>Hg</application> Import"));
0031     okButton()->setText(xi18nc("@action:button", "Import"));
0032 
0033     //
0034     setupUI();
0035 
0036     // Load saved settings
0037     FileViewHgPluginSettings *settings = FileViewHgPluginSettings::self();
0038     this->resize(QSize(settings->importDialogWidth(),
0039                                settings->importDialogHeight()));
0040 
0041     //
0042     connect(this, SIGNAL(finished(int)), this, SLOT(saveGeometry()));
0043     connect(m_addPatches, &QAbstractButton::clicked,
0044             this, &HgImportDialog::slotAddPatches);
0045     connect(m_removePatches, &QAbstractButton::clicked,
0046             this, &HgImportDialog::slotRemovePatches);
0047 }
0048 
0049 void HgImportDialog::setupUI()
0050 {
0051     QGroupBox *mainGroup = new QGroupBox;
0052     QGridLayout *mainLayout = new QGridLayout;
0053     m_patchList = new QListWidget;
0054 
0055     m_patchList->setSelectionMode(QAbstractItemView::ExtendedSelection);
0056     m_patchList->setItemDelegate(new CommitItemDelegate);
0057     mainLayout->addWidget(m_patchList);
0058     mainGroup->setLayout(mainLayout);
0059 
0060     // options
0061     m_optionGroup = new QGroupBox(xi18nc("@label:group", "Options"));
0062     m_optNoCommit = new QCheckBox(xi18nc("@label",
0063                       "Do not commit, just update the working directory"));
0064     m_optForce = new QCheckBox(xi18nc("@label",
0065                       "Skip test for outstanding uncommitted changes"));
0066     m_optExact = new QCheckBox(xi18nc("@label",
0067                    "Apply patch to the nodes from which it was generated"));
0068     m_optBypass = new QCheckBox(xi18nc("@label",
0069                       "Apply patch without touching working directory"));
0070 
0071     QVBoxLayout *optionLayout = new QVBoxLayout;
0072     optionLayout->addWidget(m_optNoCommit);
0073     optionLayout->addWidget(m_optForce);
0074     optionLayout->addWidget(m_optExact);
0075     optionLayout->addWidget(m_optBypass);
0076     m_optionGroup->setLayout(optionLayout);
0077 
0078     // top buttons
0079     QHBoxLayout *topButtons = new QHBoxLayout;
0080     m_addPatches = new QPushButton(xi18nc("@label:button",
0081                         "Add Patches"));
0082     m_removePatches = new QPushButton(xi18nc("@label:button",
0083                         "Remove Patches"));
0084     topButtons->addWidget(m_addPatches);
0085     topButtons->addWidget(m_removePatches);
0086     topButtons->addStretch();
0087 
0088     //setup main dialog widget
0089     QVBoxLayout *lay = new QVBoxLayout;
0090     lay->addLayout(topButtons);
0091     lay->addWidget(mainGroup);
0092     lay->addWidget(m_optionGroup);
0093     layout()->insertLayout(0, lay);
0094 }
0095 
0096 void HgImportDialog::saveGeometry()
0097 {
0098     FileViewHgPluginSettings *settings = FileViewHgPluginSettings::self();
0099     settings->setImportDialogHeight(this->height());
0100     settings->setImportDialogWidth(this->width());
0101     settings->save();
0102 }
0103 
0104 void HgImportDialog::done(int r)
0105 {
0106     if (r == QDialog::Accepted) {
0107         QStringList args;
0108         if (m_optForce->checkState() == Qt::Checked) {
0109             args << QLatin1String("--force");
0110         }
0111 
0112         if (m_optBypass->checkState() == Qt::Checked) {
0113             args << QLatin1String("--bypass");
0114         }
0115 
0116         if (m_optNoCommit->checkState() == Qt::Checked) {
0117             args << QLatin1String("--no-commit");
0118         }
0119         if (m_optExact->checkState() == Qt::Checked) {
0120             args << QLatin1String("--exact");
0121         }
0122 
0123         int countRows = m_patchList->count();
0124         for (int i=0; i<countRows; i++) {
0125             QListWidgetItem *item = m_patchList->item(i);
0126             args << item->data(Qt::UserRole + 5).toString();
0127         }
0128 
0129         HgWrapper *hgw = HgWrapper::instance();
0130         if (hgw->executeCommandTillFinished(QLatin1String("import"), args)) {
0131             QDialog::done(r);
0132         }
0133         else {
0134             KMessageBox::error(this, hgw->readAllStandardError());
0135         }
0136     }
0137     else {
0138         QDialog::done(r);
0139     }
0140 }
0141 
0142 void HgImportDialog::getPatchInfo(const QString &fileName)
0143 {
0144     QFile file(fileName);
0145     file.open(QFile::ReadOnly);
0146     QTextStream fileStream(&file);
0147 
0148     QListWidgetItem *item = new QListWidgetItem;
0149     item->setData(Qt::UserRole + 1, QString());
0150     item->setData(Qt::UserRole + 2, QString());
0151     item->setData(Qt::UserRole + 5, fileName);
0152 
0153     bool gotInfo = false;
0154 
0155     do {
0156         QString line = fileStream.readLine();
0157         if (line.startsWith(QLatin1String("diff"))) {
0158             break;
0159         }
0160         else if (line.startsWith(QLatin1String("# User"))) {
0161             item->setData(Qt::UserRole + 3, 
0162                     line.remove(QLatin1String("# User")).trimmed());
0163         }
0164         else if (line.startsWith(QLatin1String("# Node ID"))) {
0165             QString node = line.remove(QLatin1String("# Node ID")).trimmed();
0166             if (!m_patchList->findItems(node, Qt::MatchExactly).empty()) {
0167                 return;
0168             }
0169             item->setData(Qt::DisplayRole, node);
0170         }
0171         else if (line.startsWith(QLatin1String("# Parent"))) {
0172             gotInfo = true;
0173         }
0174         else if (gotInfo) {
0175             item->setData(Qt::UserRole + 4, line.trimmed());
0176             break;
0177         }
0178     } while (!fileStream.atEnd());
0179 
0180     m_patchList->addItem(item);
0181 
0182     file.close();
0183 }
0184 
0185 void HgImportDialog::slotAddPatches()
0186 {
0187     const QStringList patches = QFileDialog::getOpenFileNames(this);
0188     for (const QString &fileName : patches) {
0189         getPatchInfo(fileName);
0190     }
0191 }
0192 
0193 void HgImportDialog::slotRemovePatches()
0194 {
0195     int count = m_patchList->count();
0196     for (int i=0; i<count; i++) {
0197         m_patchList->takeItem(i);
0198     }
0199 }
0200 
0201 
0202 
0203 #include "moc_importdialog.cpp"