File indexing completed on 2024-06-23 05:13:49
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 crypto/gui/decryptverifywizard.cpp 0003 0004 This file is part of Kleopatra, the KDE keymanager 0005 SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include <config-kleopatra.h> 0011 0012 #include "decryptverifyfileswizard.h" 0013 0014 #include "decryptverifyoperationwidget.h" 0015 0016 #include <crypto/gui/resultpage.h> 0017 #include <crypto/gui/wizardpage.h> 0018 0019 #include <crypto/task.h> 0020 #include <crypto/taskcollection.h> 0021 0022 #include <utils/kleo_assert.h> 0023 #include <utils/scrollarea.h> 0024 0025 #include <Libkleo/FileNameRequester> 0026 #include <Libkleo/Stl_Util> 0027 0028 #include <KGuiItem> 0029 #include <KLocalizedString> 0030 0031 #include <QBoxLayout> 0032 #include <QCheckBox> 0033 #include <QLabel> 0034 #include <QTimer> 0035 #include <QTreeView> 0036 0037 #include <vector> 0038 0039 using namespace Kleo; 0040 using namespace Kleo::Crypto; 0041 using namespace Kleo::Crypto::Gui; 0042 0043 namespace 0044 { 0045 0046 class HLine : public QFrame 0047 { 0048 Q_OBJECT 0049 public: 0050 explicit HLine(QWidget *p = nullptr, Qt::WindowFlags f = {}) 0051 : QFrame(p, f) 0052 { 0053 setFrameStyle(static_cast<int>(QFrame::HLine) | static_cast<int>(QFrame::Sunken)); 0054 } 0055 }; 0056 0057 class OperationsWidget : public WizardPage 0058 { 0059 Q_OBJECT 0060 public: 0061 explicit OperationsWidget(QWidget *p = nullptr); 0062 ~OperationsWidget() override; 0063 0064 void setOutputDirectory(const QString &dir) 0065 { 0066 m_ui.outputDirectoryFNR.setFileName(dir); 0067 } 0068 0069 QString outputDirectory() const 0070 { 0071 return m_ui.outputDirectoryFNR.fileName(); 0072 } 0073 0074 bool useOutputDirectory() const 0075 { 0076 return m_ui.useOutputDirectoryCB.isChecked(); 0077 } 0078 0079 void ensureIndexAvailable(unsigned int idx); 0080 0081 DecryptVerifyOperationWidget *widget(unsigned int idx) 0082 { 0083 return m_widgets.at(idx); 0084 } 0085 0086 bool isComplete() const override 0087 { 0088 return std::all_of(m_widgets.cbegin(), m_widgets.cend(), [](const auto &w) { 0089 switch (w->mode()) { 0090 case DecryptVerifyOperationWidget::VerifyDetachedWithSignature: 0091 case DecryptVerifyOperationWidget::VerifyDetachedWithSignedData: { 0092 const QString sigFileName = w->inputFileName(); 0093 const QString dataFileName = w->signedDataFileName(); 0094 return !sigFileName.isEmpty() && !dataFileName.isEmpty() && QFile::exists(sigFileName) && QFile::exists(dataFileName); 0095 } 0096 case DecryptVerifyOperationWidget::DecryptVerifyOpaque:; 0097 } 0098 return true; 0099 }); 0100 } 0101 0102 private: 0103 std::vector<DecryptVerifyOperationWidget *> m_widgets; 0104 0105 struct UI { 0106 QCheckBox useOutputDirectoryCB; 0107 QLabel outputDirectoryLB; 0108 FileNameRequester outputDirectoryFNR; 0109 ScrollArea scrollArea; // ### replace with KDScrollArea when done 0110 QVBoxLayout vlay; 0111 QHBoxLayout hlay; 0112 0113 explicit UI(OperationsWidget *q); 0114 } m_ui; 0115 }; 0116 } 0117 0118 class DecryptVerifyFilesWizard::Private 0119 { 0120 friend class ::Kleo::Crypto::Gui::DecryptVerifyFilesWizard; 0121 DecryptVerifyFilesWizard *const q; 0122 0123 public: 0124 Private(DecryptVerifyFilesWizard *qq); 0125 ~Private(); 0126 0127 void ensureIndexAvailable(unsigned int idx) 0128 { 0129 operationsPage.ensureIndexAvailable(idx); 0130 } 0131 0132 private: 0133 OperationsWidget operationsPage; 0134 Gui::ResultPage resultPage; 0135 }; 0136 0137 DecryptVerifyFilesWizard::DecryptVerifyFilesWizard(QWidget *p, Qt::WindowFlags f) 0138 : Wizard(p, f) 0139 , d(new Private(this)) 0140 { 0141 } 0142 0143 DecryptVerifyFilesWizard::~DecryptVerifyFilesWizard() 0144 { 0145 } 0146 0147 void DecryptVerifyFilesWizard::setOutputDirectory(const QString &dir) 0148 { 0149 d->operationsPage.setOutputDirectory(dir); 0150 } 0151 0152 QString DecryptVerifyFilesWizard::outputDirectory() const 0153 { 0154 return d->operationsPage.outputDirectory(); 0155 } 0156 0157 bool DecryptVerifyFilesWizard::useOutputDirectory() const 0158 { 0159 return d->operationsPage.useOutputDirectory(); 0160 } 0161 0162 DecryptVerifyOperationWidget *DecryptVerifyFilesWizard::operationWidget(unsigned int idx) 0163 { 0164 d->ensureIndexAvailable(idx); 0165 return d->operationsPage.widget(idx); 0166 } 0167 0168 void DecryptVerifyFilesWizard::onNext(int id) 0169 { 0170 if (id == OperationsPage) { 0171 QTimer::singleShot(0, this, &DecryptVerifyFilesWizard::operationPrepared); 0172 } 0173 Wizard::onNext(id); 0174 } 0175 0176 void DecryptVerifyFilesWizard::setTaskCollection(const std::shared_ptr<TaskCollection> &coll) 0177 { 0178 kleo_assert(coll); 0179 d->resultPage.setTaskCollection(coll); 0180 } 0181 0182 DecryptVerifyFilesWizard::Private::Private(DecryptVerifyFilesWizard *qq) 0183 : q(qq) 0184 , operationsPage(q) 0185 , resultPage(q) 0186 { 0187 q->setPage(DecryptVerifyFilesWizard::OperationsPage, &operationsPage); 0188 q->setPage(DecryptVerifyFilesWizard::ResultPage, &resultPage); 0189 0190 std::vector<int> order; 0191 order.push_back(DecryptVerifyFilesWizard::OperationsPage); 0192 order.push_back(DecryptVerifyFilesWizard::ResultPage); 0193 q->setPageOrder(order); 0194 operationsPage.setCommitPage(true); 0195 } 0196 0197 DecryptVerifyFilesWizard::Private::~Private() 0198 { 0199 } 0200 0201 OperationsWidget::OperationsWidget(QWidget *p) 0202 : WizardPage(p) 0203 , m_widgets() 0204 , m_ui(this) 0205 { 0206 setTitle(i18n("<b>Choose operations to be performed</b>")); 0207 setSubTitle( 0208 i18n("Here you can check and, if needed, override " 0209 "the operations Kleopatra detected for the input given.")); 0210 setCommitPage(true); 0211 setCustomNextButton(KGuiItem(i18n("&Decrypt/Verify"))); 0212 } 0213 0214 OperationsWidget::~OperationsWidget() 0215 { 0216 } 0217 0218 OperationsWidget::UI::UI(OperationsWidget *q) 0219 : useOutputDirectoryCB(i18n("Create all output files in a single folder"), q) 0220 , outputDirectoryLB(i18n("&Output folder:"), q) 0221 , outputDirectoryFNR(q) 0222 , scrollArea(q) 0223 , vlay(q) 0224 , hlay() 0225 { 0226 KDAB_SET_OBJECT_NAME(useOutputDirectoryCB); 0227 KDAB_SET_OBJECT_NAME(outputDirectoryLB); 0228 KDAB_SET_OBJECT_NAME(outputDirectoryFNR); 0229 KDAB_SET_OBJECT_NAME(scrollArea); 0230 0231 KDAB_SET_OBJECT_NAME(vlay); 0232 KDAB_SET_OBJECT_NAME(hlay); 0233 0234 outputDirectoryFNR.setFilter(QDir::Dirs); 0235 0236 useOutputDirectoryCB.setChecked(true); 0237 connect(&useOutputDirectoryCB, &QCheckBox::toggled, &outputDirectoryLB, &QLabel::setEnabled); 0238 connect(&useOutputDirectoryCB, &QCheckBox::toggled, &outputDirectoryFNR, &FileNameRequester::setEnabled); 0239 0240 Q_ASSERT(qobject_cast<QBoxLayout *>(scrollArea.widget()->layout())); 0241 static_cast<QBoxLayout *>(scrollArea.widget()->layout())->addStretch(1); 0242 outputDirectoryLB.setBuddy(&outputDirectoryFNR); 0243 0244 hlay.setContentsMargins(0, 0, 0, 0); 0245 0246 vlay.addWidget(&scrollArea, 1); 0247 vlay.addWidget(&useOutputDirectoryCB); 0248 vlay.addLayout(&hlay); 0249 hlay.addWidget(&outputDirectoryLB); 0250 hlay.addWidget(&outputDirectoryFNR); 0251 } 0252 0253 void OperationsWidget::ensureIndexAvailable(unsigned int idx) 0254 { 0255 if (idx < m_widgets.size()) { 0256 return; 0257 } 0258 0259 Q_ASSERT(m_ui.scrollArea.widget()); 0260 Q_ASSERT(qobject_cast<QBoxLayout *>(m_ui.scrollArea.widget()->layout())); 0261 QBoxLayout &blay = *static_cast<QBoxLayout *>(m_ui.scrollArea.widget()->layout()); 0262 0263 for (unsigned int i = m_widgets.size(); i < idx + 1; ++i) { 0264 if (i) { 0265 blay.insertWidget(blay.count() - 1, new HLine(m_ui.scrollArea.widget())); 0266 } 0267 auto w = new DecryptVerifyOperationWidget(m_ui.scrollArea.widget()); 0268 blay.insertWidget(blay.count() - 1, w); 0269 w->show(); 0270 connect(w, &DecryptVerifyOperationWidget::changed, this, &WizardPage::completeChanged); 0271 m_widgets.push_back(w); 0272 } 0273 } 0274 0275 #include "decryptverifyfileswizard.moc" 0276 0277 #include "moc_decryptverifyfileswizard.cpp"