File indexing completed on 2024-05-05 05:50:42

0001 /*
0002     SPDX-FileCopyrightText: 2008-2009 Harald Hvaal <haraldhv@stud.ntnu.no>
0003 
0004     SPDX-License-Identifier: BSD-2-Clause
0005 */
0006 
0007 #include "queries.h"
0008 #include "ark_debug.h"
0009 
0010 #include <KIO/RenameDialog>
0011 #include <KLocalizedString>
0012 #include <KMessageBox>
0013 #include <KPasswordDialog>
0014 #include <KPasswordLineEdit>
0015 
0016 #include <QApplication>
0017 #include <QDir>
0018 #include <QMessageBox>
0019 #include <QPointer>
0020 #include <QPushButton>
0021 #include <QUrl>
0022 
0023 namespace Kerfuffle
0024 {
0025 Query::Query()
0026 {
0027 }
0028 
0029 QVariant Query::response() const
0030 {
0031     return m_data.value(QStringLiteral("response"));
0032 }
0033 
0034 void Query::waitForResponse()
0035 {
0036     QMutexLocker locker(&m_responseMutex);
0037     // if there is no response set yet, wait
0038     if (!m_data.contains(QLatin1String("response"))) {
0039         m_responseCondition.wait(&m_responseMutex);
0040     }
0041 }
0042 
0043 void Query::setResponse(const QVariant &response)
0044 {
0045     m_data[QStringLiteral("response")] = response;
0046     m_responseCondition.wakeAll();
0047 }
0048 
0049 OverwriteQuery::OverwriteQuery(const QString &filename)
0050     : m_noRenameMode(false)
0051     , m_multiMode(true)
0052 {
0053     m_data[QStringLiteral("filename")] = filename;
0054 }
0055 
0056 void OverwriteQuery::execute()
0057 {
0058     // If we are being called from the KPart, the cursor is probably Qt::WaitCursor
0059     // at the moment (#231974)
0060     QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
0061 
0062     KIO::RenameDialog_Options options = KIO::RenameDialog_Overwrite | KIO::RenameDialog_Skip;
0063     if (m_noRenameMode) {
0064         options = options | KIO::RenameDialog_NoRename;
0065     }
0066     if (m_multiMode) {
0067         options = options | KIO::RenameDialog_MultipleItems;
0068     }
0069 
0070     QUrl destUrl = QUrl::fromLocalFile(QDir::cleanPath(m_data.value(QStringLiteral("filename")).toString()));
0071     const QUrl sourceUrl = QUrl(QStringLiteral("ark://%1").arg(destUrl.fileName()));
0072 
0073     QPointer<KIO::RenameDialog> dialog = new KIO::RenameDialog(nullptr, i18nc("@title:window", "File Already Exists"), sourceUrl, destUrl, options);
0074     dialog.data()->exec();
0075 
0076     m_data[QStringLiteral("newFilename")] = dialog.data()->newDestUrl().toDisplayString(QUrl::PreferLocalFile);
0077 
0078     setResponse(dialog.data()->result());
0079 
0080     delete dialog.data();
0081 
0082     QApplication::restoreOverrideCursor();
0083 }
0084 
0085 bool OverwriteQuery::responseCancelled()
0086 {
0087     return m_data.value(QStringLiteral("response")).toInt() == KIO::Result_Cancel;
0088 }
0089 bool OverwriteQuery::responseOverwriteAll()
0090 {
0091     return m_data.value(QStringLiteral("response")).toInt() == KIO::Result_OverwriteAll;
0092 }
0093 bool OverwriteQuery::responseOverwrite()
0094 {
0095     return m_data.value(QStringLiteral("response")).toInt() == KIO::Result_Overwrite;
0096 }
0097 
0098 bool OverwriteQuery::responseRename()
0099 {
0100     return m_data.value(QStringLiteral("response")).toInt() == KIO::Result_Rename;
0101 }
0102 
0103 bool OverwriteQuery::responseSkip()
0104 {
0105     return m_data.value(QStringLiteral("response")).toInt() == KIO::Result_Skip;
0106 }
0107 
0108 bool OverwriteQuery::responseAutoSkip()
0109 {
0110     return m_data.value(QStringLiteral("response")).toInt() == KIO::Result_AutoSkip;
0111 }
0112 
0113 QString OverwriteQuery::newFilename()
0114 {
0115     return m_data.value(QStringLiteral("newFilename")).toString();
0116 }
0117 
0118 void OverwriteQuery::setNoRenameMode(bool enableNoRenameMode)
0119 {
0120     m_noRenameMode = enableNoRenameMode;
0121 }
0122 
0123 bool OverwriteQuery::noRenameMode()
0124 {
0125     return m_noRenameMode;
0126 }
0127 
0128 void OverwriteQuery::setMultiMode(bool enableMultiMode)
0129 {
0130     m_multiMode = enableMultiMode;
0131 }
0132 
0133 bool OverwriteQuery::multiMode()
0134 {
0135     return m_multiMode;
0136 }
0137 
0138 PasswordNeededQuery::PasswordNeededQuery(const QString &archiveFilename, bool incorrectTryAgain)
0139 {
0140     m_data[QStringLiteral("archiveFilename")] = archiveFilename;
0141     m_data[QStringLiteral("incorrectTryAgain")] = incorrectTryAgain;
0142 }
0143 
0144 void PasswordNeededQuery::execute()
0145 {
0146     qCDebug(ARK) << "Executing password prompt";
0147 
0148     // If we are being called from the KPart, the cursor is probably Qt::WaitCursor
0149     // at the moment (#231974)
0150     QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
0151 
0152     QPointer<KPasswordDialog> dlg = new KPasswordDialog;
0153 
0154     // Disabling Ok button on dialog open
0155     dlg.data()->buttonBox()->button(QDialogButtonBox::Ok)->setEnabled(false);
0156 
0157     auto linePassword = dlg.data()->findChild<KPasswordLineEdit *>(QStringLiteral("passEdit"));
0158 
0159     // If password is non empty, enable submit button
0160     QObject::connect(linePassword->lineEdit(), &QLineEdit::textChanged, linePassword->lineEdit(), [=] {
0161         if (linePassword->lineEdit()->text().isEmpty()) {
0162             dlg.data()->buttonBox()->button(QDialogButtonBox::Ok)->setEnabled(false);
0163         } else {
0164             dlg.data()->buttonBox()->button(QDialogButtonBox::Ok)->setEnabled(true);
0165         }
0166     });
0167 
0168     dlg.data()->setPrompt(xi18nc("@info",
0169                                  "The archive <filename>%1</filename> is password protected. Please enter the password.",
0170                                  m_data.value(QStringLiteral("archiveFilename")).toString()));
0171 
0172     if (m_data.value(QStringLiteral("incorrectTryAgain")).toBool()) {
0173         dlg.data()->showErrorMessage(i18n("Incorrect password, please try again."), KPasswordDialog::PasswordError);
0174     }
0175 
0176     const bool notCancelled = dlg.data()->exec();
0177     const QString password = dlg.data()->password();
0178 
0179     m_data[QStringLiteral("password")] = password;
0180     setResponse(notCancelled && !password.isEmpty());
0181 
0182     QApplication::restoreOverrideCursor();
0183 
0184     delete dlg.data();
0185 }
0186 
0187 QString PasswordNeededQuery::password()
0188 {
0189     return m_data.value(QStringLiteral("password")).toString();
0190 }
0191 
0192 bool PasswordNeededQuery::responseCancelled()
0193 {
0194     return !m_data.value(QStringLiteral("response")).toBool();
0195 }
0196 
0197 LoadCorruptQuery::LoadCorruptQuery(const QString &archiveFilename)
0198 {
0199     m_data[QStringLiteral("archiveFilename")] = archiveFilename;
0200 }
0201 
0202 void LoadCorruptQuery::execute()
0203 {
0204     qCDebug(ARK) << "Executing prompt";
0205     QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
0206 
0207     setResponse(KMessageBox::warningTwoActions(nullptr,
0208                                                xi18nc("@info",
0209                                                       "The archive you're trying to open is corrupt.<nl/>"
0210                                                       "Some files may be missing or damaged."),
0211                                                i18nc("@title:window", "Corrupt archive"),
0212                                                KGuiItem(i18nc("@action:button", "Open as Read-Only")),
0213                                                KGuiItem(i18nc("@action:button", "Don't Open"))));
0214     QApplication::restoreOverrideCursor();
0215 }
0216 
0217 bool LoadCorruptQuery::responseYes()
0218 {
0219     return (m_data.value(QStringLiteral("response")).toInt() == KMessageBox::PrimaryAction);
0220 }
0221 
0222 ContinueExtractionQuery::ContinueExtractionQuery(const QString &error, const QString &archiveEntry)
0223     : m_chkDontAskAgain(i18n("Don't ask again."))
0224 {
0225     m_data[QStringLiteral("error")] = error;
0226     m_data[QStringLiteral("archiveEntry")] = archiveEntry;
0227 }
0228 
0229 void ContinueExtractionQuery::execute()
0230 {
0231     qCDebug(ARK) << "Executing prompt";
0232     QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
0233 
0234     QMessageBox box(QMessageBox::Warning,
0235                     i18n("Error during extraction"),
0236                     xi18n("Extraction of the entry:<nl/>"
0237                           "    <filename>%1</filename><nl/>"
0238                           "failed with the error message:<nl/>    %2<nl/><nl/>"
0239                           "Do you want to continue extraction?<nl/>",
0240                           m_data.value(QStringLiteral("archiveEntry")).toString(),
0241                           m_data.value(QStringLiteral("error")).toString()),
0242                     QMessageBox::Yes | QMessageBox::Cancel);
0243     box.setCheckBox(&m_chkDontAskAgain);
0244     setResponse(box.exec());
0245     QApplication::restoreOverrideCursor();
0246 }
0247 
0248 bool ContinueExtractionQuery::responseCancelled()
0249 {
0250     return (m_data.value(QStringLiteral("response")).toInt() == QMessageBox::Cancel);
0251 }
0252 
0253 bool ContinueExtractionQuery::dontAskAgain()
0254 {
0255     return m_chkDontAskAgain.isChecked();
0256 }
0257 
0258 }