File indexing completed on 2024-05-05 10:02:24

0001 /*
0002     SPDX-FileCopyrightText: 2011 Vishesh Yadav <vishesh3y@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "clonedialog.h"
0008 #include "fileviewhgpluginsettings.h"
0009 
0010 #include <QGroupBox>
0011 #include <QGridLayout>
0012 #include <QVBoxLayout>
0013 #include <QLabel>
0014 #include <QFrame>
0015 #include <QStackedLayout>
0016 #include <QApplication>
0017 #include <QCheckBox>
0018 #include <QTextCodec>
0019 #include <QFileDialog>
0020 #include <QLineEdit>
0021 #include <KTextEdit>
0022 #include <KLocalizedString>
0023 #include <KMessageBox>
0024 
0025 HgCloneDialog::HgCloneDialog(const QString &directory, QWidget *parent):
0026     DialogBase(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, parent),
0027     m_cloned(false),
0028     m_terminated(true),
0029     m_workingDirectory(directory)
0030 {
0031     // dialog properties
0032     this->setWindowTitle(xi18nc("@title:window",
0033                 "<application>Hg</application> Clone"));
0034     okButton()->setText(xi18nc("@action:button", "Clone"));
0035     okButton()->setDisabled(true);
0036 
0037 
0038     //////////////
0039     // Setup UI //
0040     //////////////
0041 
0042     QGroupBox *urlGroup = new QGroupBox(i18n("URLs"));
0043     QGridLayout *urlLayout = new QGridLayout;
0044     QLabel *sourceLabel = new QLabel(xi18nc("@label", "Source"));
0045     QLabel *destLabel = new QLabel(xi18nc("@lobel", "Destination"));
0046     QPushButton *m_browse_dest = new QPushButton(xi18nc("@button", "Browse"));
0047     QPushButton *m_browse_source = new QPushButton(xi18nc("@button", "Browse"));
0048     m_source = new QLineEdit;
0049     m_destination = new QLineEdit;
0050     urlLayout->addWidget(sourceLabel, 0, 0);
0051     urlLayout->addWidget(m_source, 0, 1);
0052     urlLayout->addWidget(m_browse_source, 0, 2);
0053     urlLayout->addWidget(destLabel, 1, 0);
0054     urlLayout->addWidget(m_destination, 1, 1);
0055     urlLayout->addWidget(m_browse_dest, 1, 2);
0056     urlGroup->setLayout(urlLayout);
0057 
0058     // Options Group
0059     QGroupBox *optionGroup = new QGroupBox(i18nc("@label", "Options"));
0060     QVBoxLayout *optionLayout = new QVBoxLayout;
0061 
0062     m_optNoUpdate = new QCheckBox(i18n("Do not update the new working directory."));
0063     m_optUsePull = new QCheckBox(i18n("Use pull protocol to copy metadata."));
0064     m_optUseUncmprdTrans = new QCheckBox(i18n("Use uncompressed transfer."));
0065     m_optNoVerifyServCert = new QCheckBox(i18n("Do not verify server certificate (ignoring web.cacerts config)."));
0066 
0067     optionLayout->addWidget(m_optNoUpdate);
0068     optionLayout->addWidget(m_optUsePull);
0069     optionLayout->addWidget(m_optUseUncmprdTrans);
0070     optionLayout->addWidget(m_optNoVerifyServCert);
0071     optionGroup->setLayout(optionLayout);
0072     // end options
0073 
0074     QFrame *frame = new QFrame;
0075     QVBoxLayout *mainLayout = new QVBoxLayout;
0076     mainLayout->addWidget(urlGroup);
0077     mainLayout->addWidget(optionGroup);
0078     mainLayout->addStretch();
0079     frame->setLayout(mainLayout);
0080     
0081     m_stackLayout = new  QStackedLayout;
0082     m_outputEdit = new KTextEdit;
0083     m_outputEdit->setReadOnly(true);
0084     m_outputEdit->setFontFamily(QLatin1String("Monospace"));
0085     m_stackLayout->addWidget(frame);
0086     m_stackLayout->addWidget(m_outputEdit);
0087     m_stackLayout->setCurrentIndex(0);
0088 
0089     layout()->insertLayout(0, m_stackLayout);
0090     // Load saved settings
0091     FileViewHgPluginSettings *settings = FileViewHgPluginSettings::self();
0092     this->resize(QSize(settings->cloneDialogWidth(),
0093                                settings->cloneDialogHeight()));
0094     
0095     connect(this, SIGNAL(finished(int)), this, SLOT(saveGeometry()));
0096     connect(m_source, &QLineEdit::textChanged,
0097             this, &HgCloneDialog::slotUpdateOkButton);
0098     connect(m_browse_dest, &QAbstractButton::clicked,
0099                 this, &HgCloneDialog::slotBrowseDestClicked);
0100     connect(m_browse_source, &QAbstractButton::clicked,
0101                 this, &HgCloneDialog::slotBrowseSourceClicked);
0102     connect(&m_process, &QProcess::started, this, &HgCloneDialog::slotCloningStarted);
0103     connect(&m_process, &QProcess::finished,
0104             this, &HgCloneDialog::slotCloningFinished);
0105     connect(&m_process, &QProcess::readyReadStandardOutput,
0106                 this, &HgCloneDialog::slotUpdateCloneOutput);
0107 }
0108 
0109 void HgCloneDialog::browseDirectory(QLineEdit *dest)
0110 {
0111     QString result = QFileDialog::getExistingDirectory(this);
0112     if (result.length() > 0) {
0113         dest->setText(result);
0114     }
0115 }
0116 
0117 void HgCloneDialog::slotBrowseDestClicked()
0118 {
0119     browseDirectory(m_destination);
0120 }
0121 
0122 void HgCloneDialog::slotBrowseSourceClicked()
0123 {
0124     browseDirectory(m_source);
0125 }
0126 
0127 void HgCloneDialog::done(int r)
0128 {
0129     if (r == QDialog::Accepted && !m_cloned) {
0130         // Will execute 'stdbuf' command to make the output of
0131         // mercurial command line buffered and enable us to show 
0132         // output of cloning as soon as new line is available
0133         QStringList args;
0134         args << QLatin1String("-oL"); //argument for stdbuf. 
0135         args << QLatin1String("hg");
0136         args << QLatin1String("clone");
0137         args << QLatin1String("--verbose");
0138         appendOptionArguments(args);
0139         args << m_source->text();
0140 
0141         if (!m_destination->text().isEmpty()) {
0142             args << m_destination->text();
0143         }
0144 
0145         m_outputEdit->clear();
0146         m_stackLayout->setCurrentIndex(1);
0147         QApplication::processEvents();
0148         okButton()->setDisabled(true);
0149 
0150         m_process.setWorkingDirectory(m_workingDirectory);
0151         m_process.start(QLatin1String("stdbuf"), args);
0152     }
0153     else if (r == QDialog::Accepted && m_cloned) {
0154         QDialog::done(r);
0155     }
0156     else {
0157         if (m_process.state() == QProcess::Running) {
0158             KMessageBox::error(this, i18n("Terminating cloning!"));
0159             okButton()->setDisabled(false);
0160             m_terminated = true;
0161             m_process.terminate();
0162             m_stackLayout->setCurrentIndex(0);
0163         }
0164         else {
0165             QDialog::done(r);
0166         }
0167     }
0168 }
0169 
0170 void HgCloneDialog::slotCloningStarted()
0171 {
0172     m_terminated = false;
0173 }
0174 
0175 void HgCloneDialog::slotUpdateCloneOutput()
0176 {
0177     m_outputEdit->insertPlainText(QTextCodec::codecForLocale()->toUnicode(m_process.readAllStandardOutput()));
0178 }
0179 
0180 void HgCloneDialog::slotCloningFinished(int exitCode, QProcess::ExitStatus exitStatus)
0181 {
0182     if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
0183         m_cloned = true;
0184         okButton()->setText(xi18nc("@action:button", "Close"));
0185         okButton()->setDisabled(false);
0186     }
0187     else if (!m_terminated) {
0188         KMessageBox::error(this, xi18nc("@message:error",
0189                                         "Error Cloning Repository!"));
0190     }
0191 }
0192 
0193 void HgCloneDialog::appendOptionArguments(QStringList &args)
0194 {
0195     if (m_optNoUpdate->checkState() == Qt::Checked) {
0196         args << QLatin1String("-U");
0197     }
0198     if (m_optUsePull->checkState() == Qt::Checked) {
0199         args << QLatin1String("--pull");
0200     }
0201     if (m_optUseUncmprdTrans->checkState() == Qt::Checked) {
0202         args << QLatin1String("--uncompressed");
0203     }
0204     if (m_optNoVerifyServCert->checkState() == Qt::Checked) {
0205         args << QLatin1String("--insecure");
0206     }
0207 }
0208 
0209 void HgCloneDialog::saveGeometry()
0210 {
0211     FileViewHgPluginSettings *settings = FileViewHgPluginSettings::self();
0212     settings->setCloneDialogHeight(this->height());
0213     settings->setCloneDialogWidth(this->width());
0214     settings->save();
0215 }
0216 
0217 void HgCloneDialog::slotUpdateOkButton()
0218 {
0219     if (m_source->text().length() > 0) {
0220         okButton()->setDisabled(false);
0221     }
0222     else {
0223         okButton()->setDisabled(true);
0224     }
0225 }
0226 
0227 
0228 
0229 #include "moc_clonedialog.cpp"