File indexing completed on 2024-06-23 05:13:52
0001 /* crypto/gui/signencryptfileswizard.cpp 0002 0003 This file is part of Kleopatra, the KDE keymanager 0004 SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB 0005 0006 SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik 0007 SPDX-FileContributor: Intevation GmbH 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #include <config-kleopatra.h> 0013 0014 #include "signencryptfileswizard.h" 0015 #include "signencryptwidget.h" 0016 0017 #include "newresultpage.h" 0018 0019 #include <fileoperationspreferences.h> 0020 #include <settings.h> 0021 0022 #include <KColorScheme> 0023 #include <KConfigGroup> 0024 #include <KLocalizedString> 0025 #include <KMessageBox> 0026 #include <KMessageWidget> 0027 #include <KSharedConfig> 0028 #include <KWindowConfig> 0029 0030 #include "kleopatra_debug.h" 0031 #include <Libkleo/Compliance> 0032 #include <Libkleo/Formatting> 0033 #include <Libkleo/GnuPG> 0034 #include <Libkleo/SystemInfo> 0035 0036 #include <Libkleo/FileNameRequester> 0037 #include <QCheckBox> 0038 #include <QGroupBox> 0039 #include <QIcon> 0040 #include <QLabel> 0041 #include <QPushButton> 0042 #include <QStyle> 0043 #include <QVBoxLayout> 0044 #include <QWindow> 0045 #include <QWizardPage> 0046 0047 #include <gpgme++/key.h> 0048 0049 #include <array> 0050 0051 using namespace GpgME; 0052 using namespace Kleo; 0053 using namespace Kleo::Crypto::Gui; 0054 0055 enum Page { 0056 SigEncPageId, 0057 ResultPageId, 0058 0059 NumPages 0060 }; 0061 0062 class FileNameRequesterWithIcon : public QWidget 0063 { 0064 Q_OBJECT 0065 0066 public: 0067 explicit FileNameRequesterWithIcon(QDir::Filters filter, QWidget *parent = nullptr) 0068 : QWidget(parent) 0069 { 0070 auto layout = new QHBoxLayout{this}; 0071 layout->setContentsMargins(0, 0, 0, 0); 0072 mIconLabel = new QLabel{this}; 0073 mRequester = new FileNameRequester{filter, this}; 0074 mRequester->setExistingOnly(false); 0075 layout->addWidget(mIconLabel); 0076 layout->addWidget(mRequester); 0077 0078 setFocusPolicy(mRequester->focusPolicy()); 0079 setFocusProxy(mRequester); 0080 0081 connect(mRequester, &FileNameRequester::fileNameChanged, this, &FileNameRequesterWithIcon::fileNameChanged); 0082 } 0083 0084 void setIcon(const QIcon &icon) 0085 { 0086 mIconLabel->setPixmap(icon.pixmap(32, 32)); 0087 } 0088 0089 void setFileName(const QString &name) 0090 { 0091 mRequester->setFileName(name); 0092 } 0093 0094 QString fileName() const 0095 { 0096 return mRequester->fileName(); 0097 } 0098 0099 void setNameFilter(const QString &nameFilter) 0100 { 0101 mRequester->setNameFilter(nameFilter); 0102 } 0103 0104 QString nameFilter() const 0105 { 0106 return mRequester->nameFilter(); 0107 } 0108 0109 FileNameRequester *requester() 0110 { 0111 return mRequester; 0112 } 0113 0114 Q_SIGNALS: 0115 void fileNameChanged(const QString &filename); 0116 0117 protected: 0118 bool event(QEvent *e) override 0119 { 0120 if (e->type() == QEvent::ToolTipChange) { 0121 mRequester->setToolTip(toolTip()); 0122 } 0123 return QWidget::event(e); 0124 } 0125 0126 private: 0127 QLabel *mIconLabel; 0128 FileNameRequester *mRequester; 0129 }; 0130 0131 class SigEncPage : public QWizardPage 0132 { 0133 Q_OBJECT 0134 0135 public: 0136 explicit SigEncPage(QWidget *parent = nullptr) 0137 : QWizardPage(parent) 0138 , mParent((SignEncryptFilesWizard *)parent) 0139 , mWidget(new SignEncryptWidget) 0140 , mOutLayout(new QVBoxLayout) 0141 , mOutputLabel{nullptr} 0142 , mArchive(false) 0143 , mUseOutputDir(false) 0144 , mSingleFile{true} 0145 { 0146 setTitle(i18nc("@title", "Sign / Encrypt Files")); 0147 auto vLay = new QVBoxLayout(this); 0148 vLay->setContentsMargins(0, 0, 0, 0); 0149 if (!Settings{}.cmsEnabled()) { 0150 mWidget->setProtocol(GpgME::OpenPGP); 0151 } 0152 mWidget->setSignAsText(i18nc("@option:check on SignEncryptPage", "&Sign as:")); 0153 mWidget->setEncryptForMeText(i18nc("@option:check on SignEncryptPage", "Encrypt for &me:")); 0154 mWidget->setEncryptForOthersText(i18nc("@option:check on SignEncryptPage", "Encrypt for &others:")); 0155 mWidget->setEncryptWithPasswordText( 0156 i18nc("@option:check on SignEncryptPage", "Encrypt with &password. Anyone you share the password with can read the data.")); 0157 vLay->addWidget(mWidget); 0158 connect(mWidget, &SignEncryptWidget::operationChanged, this, &SigEncPage::updateCommitButton); 0159 connect(mWidget, &SignEncryptWidget::keysChanged, this, &SigEncPage::updateFileWidgets); 0160 0161 auto outputGrp = new QGroupBox(i18nc("@title:group", "Output")); 0162 outputGrp->setLayout(mOutLayout); 0163 0164 mPlaceholderWidget = new QLabel(i18n("Please select an action.")); 0165 mOutLayout->addWidget(mPlaceholderWidget); 0166 0167 mOutputLabel = new QLabel(i18nc("@label on SignEncryptPage", "Output &files/folder:")); 0168 mOutLayout->addWidget(mOutputLabel); 0169 0170 createRequesters(mOutLayout); 0171 0172 mUseOutputDirChk = new QCheckBox(i18nc("@option:check on SignEncryptPage", "Encrypt / Sign &each file separately.")); 0173 mUseOutputDirChk->setToolTip(i18nc("@info:tooltip", "Keep each file separate instead of creating an archive for all.")); 0174 mOutLayout->addWidget(mUseOutputDirChk); 0175 connect(mUseOutputDirChk, &QCheckBox::toggled, this, [this](bool state) { 0176 mUseOutputDir = state; 0177 mArchive = !mUseOutputDir && !mSingleFile; 0178 updateFileWidgets(); 0179 }); 0180 0181 vLay->addWidget(outputGrp); 0182 0183 auto messageWidget = new KMessageWidget; 0184 messageWidget->setMessageType(KMessageWidget::Error); 0185 messageWidget->setIcon(style()->standardIcon(QStyle::SP_MessageBoxCritical, nullptr, this)); 0186 messageWidget->setText(i18n("Invalid compliance settings for signing and encrypting files.")); 0187 messageWidget->setToolTip(xi18nc("@info %1 is a placeholder for the name of a compliance mode. E.g. NATO RESTRICTED compliant or VS-NfD compliant", 0188 "<para>You cannot use <application>Kleopatra</application> for signing or encrypting files " 0189 "because the <application>GnuPG</application> system used by <application>Kleopatra</application> is not %1.</para>", 0190 DeVSCompliance::name(true))); 0191 messageWidget->setCloseButtonVisible(false); 0192 messageWidget->setVisible(DeVSCompliance::isActive() && !DeVSCompliance::isCompliant()); 0193 vLay->addWidget(messageWidget); 0194 0195 setMinimumHeight(300); 0196 } 0197 0198 void setEncryptionPreset(bool value) 0199 { 0200 mWidget->setEncryptionChecked(value); 0201 } 0202 0203 void setSigningPreset(bool value) 0204 { 0205 mWidget->setSigningChecked(value); 0206 } 0207 0208 bool isComplete() const override 0209 { 0210 if (DeVSCompliance::isActive() && !DeVSCompliance::isCompliant()) { 0211 return false; 0212 } 0213 return mWidget->isComplete(); 0214 } 0215 0216 int nextId() const override 0217 { 0218 return ResultPageId; 0219 } 0220 0221 void initializePage() override 0222 { 0223 setCommitPage(true); 0224 updateCommitButton(mWidget->currentOp()); 0225 } 0226 0227 void setArchiveForced(bool archive) 0228 { 0229 mArchive = archive; 0230 setArchiveMutable(!archive); 0231 } 0232 0233 void setArchiveMutable(bool archive) 0234 { 0235 mUseOutputDirChk->setVisible(archive); 0236 if (archive) { 0237 const KConfigGroup archCfg(KSharedConfig::openConfig(), QStringLiteral("SignEncryptFilesWizard")); 0238 mUseOutputDirChk->setChecked(archCfg.readEntry("LastUseOutputDir", false)); 0239 } else { 0240 mUseOutputDirChk->setChecked(false); 0241 } 0242 } 0243 0244 void setSingleFile(bool singleFile) 0245 { 0246 mSingleFile = singleFile; 0247 mArchive = !mUseOutputDir && !mSingleFile; 0248 } 0249 0250 bool validatePage() override 0251 { 0252 if (DeVSCompliance::isActive() && !DeVSCompliance::isCompliant()) { 0253 KMessageBox::error(topLevelWidget(), 0254 xi18nc("@info %1 is a placeholder for the name of a compliance mode. E.g. NATO RESTRICTED compliant or VS-NfD compliant", 0255 "<para>Sorry! You cannot use <application>Kleopatra</application> for signing or encrypting files " 0256 "because the <application>GnuPG</application> system used by <application>Kleopatra</application> is not %1.</para>", 0257 DeVSCompliance::name(true))); 0258 return false; 0259 } 0260 bool sign = !mWidget->signKey().isNull(); 0261 bool encrypt = !mWidget->selfKey().isNull() || !mWidget->recipients().empty(); 0262 if (!mWidget->validate()) { 0263 return false; 0264 } 0265 mWidget->saveOwnKeys(); 0266 if (mUseOutputDirChk->isVisible()) { 0267 KConfigGroup archCfg(KSharedConfig::openConfig(), QStringLiteral("SignEncryptFilesWizard")); 0268 archCfg.writeEntry("LastUseOutputDir", mUseOutputDir); 0269 } 0270 0271 if (sign && !encrypt && mArchive) { 0272 return KMessageBox::warningContinueCancel( 0273 this, 0274 xi18nc("@info", 0275 "<para>Archiving in combination with sign-only currently requires what are known as opaque signatures - " 0276 "unlike detached ones, these embed the content in the signature.</para>" 0277 "<para>This format is rather unusual. You might want to archive the files separately, " 0278 "and then sign the archive as one file with Kleopatra.</para>" 0279 "<para>Future versions of Kleopatra are expected to also support detached signatures in this case.</para>"), 0280 i18nc("@title:window", "Unusual Signature Warning"), 0281 KStandardGuiItem::cont(), 0282 KStandardGuiItem::cancel(), 0283 QStringLiteral("signencryptfileswizard-archive+sign-only-warning")) 0284 == KMessageBox::Continue; 0285 } else if (sign && !encrypt) { 0286 return true; 0287 } 0288 0289 if (!mWidget->selfKey().isNull() || mWidget->encryptSymmetric()) { 0290 return true; 0291 } 0292 const auto recipientKeys = recipients(); 0293 const bool hasSecret = std::any_of(std::begin(recipientKeys), std::end(recipientKeys), [](const auto &k) { 0294 return k.hasSecret(); 0295 }); 0296 if (!hasSecret) { 0297 if (KMessageBox::warningContinueCancel(this, 0298 xi18nc("@info", 0299 "<para>None of the recipients you are encrypting to seems to be your own.</para>" 0300 "<para>This means that you will not be able to decrypt the data anymore, once encrypted.</para>" 0301 "<para>Do you want to continue, or cancel to change the recipient selection?</para>"), 0302 i18nc("@title:window", "Encrypt-To-Self Warning"), 0303 KStandardGuiItem::cont(), 0304 KStandardGuiItem::cancel(), 0305 QStringLiteral("warn-encrypt-to-non-self"), 0306 KMessageBox::Notify | KMessageBox::Dangerous) 0307 == KMessageBox::Cancel) { 0308 return false; 0309 } 0310 } 0311 return true; 0312 } 0313 0314 std::vector<Key> recipients() const 0315 { 0316 return mWidget->recipients(); 0317 } 0318 0319 /* In the future we might find a usecase for multiple 0320 * signers */ 0321 std::vector<Key> signers() const 0322 { 0323 const Key k = mWidget->signKey(); 0324 if (!k.isNull()) { 0325 return {k}; 0326 } 0327 return {}; 0328 } 0329 0330 private: 0331 struct RequesterInfo { 0332 SignEncryptFilesWizard::KindNames id; 0333 QString icon; 0334 QString toolTip; 0335 QString accessibleName; 0336 QString nameFilterBinary; 0337 QString nameFilterAscii; 0338 }; 0339 void createRequesters(QBoxLayout *lay) 0340 { 0341 static const std::array<RequesterInfo, 6> requestersInfo = {{ 0342 { 0343 SignEncryptFilesWizard::SignatureCMS, 0344 QStringLiteral("document-sign"), 0345 i18nc("@info:tooltip", "This is the filename of the S/MIME signature."), 0346 i18nc("Lineedit accessible name", "S/MIME signature file"), 0347 i18nc("Name filter binary", "S/MIME Signatures (*.p7s)"), 0348 i18nc("Name filter ASCII", "S/MIME Signatures (*.p7s *.pem)"), 0349 }, 0350 { 0351 SignEncryptFilesWizard::SignaturePGP, 0352 QStringLiteral("document-sign"), 0353 i18nc("@info:tooltip", "This is the filename of the detached OpenPGP signature."), 0354 i18nc("Lineedit accessible name", "OpenPGP signature file"), 0355 i18nc("Name filter binary", "OpenPGP Signatures (*.sig *.pgp)"), 0356 i18nc("Name filter ASCII", "OpenPGP Signatures (*.asc *.sig)"), 0357 }, 0358 { 0359 SignEncryptFilesWizard::CombinedPGP, 0360 QStringLiteral("document-edit-sign-encrypt"), 0361 i18nc("@info:tooltip", "This is the filename of the OpenPGP-signed and encrypted file."), 0362 i18nc("Lineedit accessible name", "OpenPGP signed and encrypted file"), 0363 i18nc("Name filter binary", "OpenPGP Files (*.gpg *.pgp)"), 0364 i18nc("Name filter ASCII", "OpenPGP Files (*.asc)"), 0365 }, 0366 { 0367 SignEncryptFilesWizard::EncryptedPGP, 0368 QStringLiteral("document-encrypt"), 0369 i18nc("@info:tooltip", "This is the filename of the OpenPGP encrypted file."), 0370 i18nc("Lineedit accessible name", "OpenPGP encrypted file"), 0371 i18nc("Name filter binary", "OpenPGP Files (*.gpg *.pgp)"), 0372 i18nc("Name filter ASCII", "OpenPGP Files (*.asc)"), 0373 }, 0374 { 0375 SignEncryptFilesWizard::EncryptedCMS, 0376 QStringLiteral("document-encrypt"), 0377 i18nc("@info:tooltip", "This is the filename of the S/MIME encrypted file."), 0378 i18nc("Lineedit accessible name", "S/MIME encrypted file"), 0379 i18nc("Name filter binary", "S/MIME Files (*.p7m)"), 0380 i18nc("Name filter ASCII", "S/MIME Files (*.p7m *.pem)"), 0381 }, 0382 { 0383 SignEncryptFilesWizard::Directory, 0384 QStringLiteral("folder"), 0385 i18nc("@info:tooltip", "The resulting files are written to this directory."), 0386 i18nc("Lineedit accessible name", "Output directory"), 0387 {}, 0388 {}, 0389 }, 0390 }}; 0391 0392 if (!mRequesters.empty()) { 0393 return; 0394 } 0395 const bool isAscii = FileOperationsPreferences().addASCIIArmor(); 0396 for (const auto &requester : requestersInfo) { 0397 const auto id = requester.id; 0398 auto requesterWithIcon = new FileNameRequesterWithIcon{id == SignEncryptFilesWizard::Directory ? QDir::Dirs : QDir::Files, this}; 0399 requesterWithIcon->setIcon(QIcon::fromTheme(requester.icon)); 0400 requesterWithIcon->setToolTip(requester.toolTip); 0401 requesterWithIcon->requester()->setAccessibleNameOfLineEdit(requester.accessibleName); 0402 requesterWithIcon->setNameFilter(isAscii ? requester.nameFilterAscii : requester.nameFilterBinary); 0403 lay->addWidget(requesterWithIcon); 0404 0405 connect(requesterWithIcon, &FileNameRequesterWithIcon::fileNameChanged, this, [this, id](const QString &newName) { 0406 mOutNames[id] = newName; 0407 }); 0408 0409 mRequesters.insert(id, requesterWithIcon); 0410 } 0411 } 0412 0413 public: 0414 void setOutputNames(const QMap<int, QString> &names) 0415 { 0416 Q_ASSERT(mOutNames.isEmpty()); 0417 for (auto it = std::begin(names); it != std::end(names); ++it) { 0418 mRequesters.value(it.key())->setFileName(it.value()); 0419 } 0420 mOutNames = names; 0421 updateFileWidgets(); 0422 } 0423 0424 QMap<int, QString> outputNames() const 0425 { 0426 if (!mUseOutputDir) { 0427 auto ret = mOutNames; 0428 ret.remove(SignEncryptFilesWizard::Directory); 0429 return ret; 0430 } 0431 return mOutNames; 0432 } 0433 0434 bool encryptSymmetric() const 0435 { 0436 return mWidget->encryptSymmetric(); 0437 } 0438 0439 private Q_SLOTS: 0440 void updateCommitButton(const SignEncryptWidget::Operations op) 0441 { 0442 if (mParent->currentPage() != this) { 0443 return; 0444 } 0445 QString label; 0446 switch (op) { 0447 case SignEncryptWidget::Sign: 0448 label = i18nc("@action:button", "Sign"); 0449 break; 0450 case SignEncryptWidget::Encrypt: 0451 label = i18nc("@action:button", "Encrypt"); 0452 break; 0453 case SignEncryptWidget::SignAndEncrypt: 0454 label = i18nc("@action:button", "Sign / Encrypt"); 0455 break; 0456 default:; 0457 }; 0458 auto btn = qobject_cast<QPushButton *>(mParent->button(QWizard::CommitButton)); 0459 if (!label.isEmpty()) { 0460 mParent->setButtonText(QWizard::CommitButton, label); 0461 if (DeVSCompliance::isActive()) { 0462 const bool de_vs = DeVSCompliance::isCompliant() && mWidget->isDeVsAndValid(); 0463 DeVSCompliance::decorate(btn, de_vs); 0464 mParent->setLabelText(DeVSCompliance::name(de_vs)); 0465 } 0466 } else { 0467 mParent->setButtonText(QWizard::CommitButton, i18n("Next")); 0468 btn->setIcon(QIcon()); 0469 btn->setStyleSheet(QString()); 0470 } 0471 Q_EMIT completeChanged(); 0472 } 0473 0474 void updateFileWidgets() 0475 { 0476 if (mRequesters.isEmpty()) { 0477 return; 0478 } 0479 const std::vector<Key> recipients = mWidget->recipients(); 0480 const Key sigKey = mWidget->signKey(); 0481 const bool pgp = mWidget->encryptSymmetric() || std::any_of(std::cbegin(recipients), std::cend(recipients), [](const auto &k) { 0482 return k.protocol() == Protocol::OpenPGP; 0483 }); 0484 const bool cms = std::any_of(std::cbegin(recipients), std::cend(recipients), [](const auto &k) { 0485 return k.protocol() == Protocol::CMS; 0486 }); 0487 0488 mOutLayout->setEnabled(false); 0489 if (cms || pgp || !sigKey.isNull()) { 0490 mPlaceholderWidget->setVisible(false); 0491 mOutputLabel->setVisible(true); 0492 mRequesters[SignEncryptFilesWizard::SignatureCMS]->setVisible(!mUseOutputDir && sigKey.protocol() == Protocol::CMS); 0493 mRequesters[SignEncryptFilesWizard::EncryptedCMS]->setVisible(!mUseOutputDir && cms); 0494 mRequesters[SignEncryptFilesWizard::CombinedPGP]->setVisible(!mUseOutputDir && sigKey.protocol() == Protocol::OpenPGP && pgp); 0495 mRequesters[SignEncryptFilesWizard::EncryptedPGP]->setVisible(!mUseOutputDir && sigKey.protocol() != Protocol::OpenPGP && pgp); 0496 mRequesters[SignEncryptFilesWizard::SignaturePGP]->setVisible(!mUseOutputDir && sigKey.protocol() == Protocol::OpenPGP && !pgp); 0497 mRequesters[SignEncryptFilesWizard::Directory]->setVisible(mUseOutputDir); 0498 auto firstNotHidden = std::find_if(std::cbegin(mRequesters), std::cend(mRequesters), [](auto w) { 0499 return !w->isHidden(); 0500 }); 0501 mOutputLabel->setBuddy(*firstNotHidden); 0502 } else { 0503 mPlaceholderWidget->setVisible(true); 0504 mOutputLabel->setVisible(false); 0505 std::for_each(std::cbegin(mRequesters), std::cend(mRequesters), [](auto w) { 0506 w->setVisible(false); 0507 }); 0508 mOutputLabel->setBuddy(nullptr); 0509 } 0510 mOutLayout->setEnabled(true); 0511 } 0512 0513 private: 0514 SignEncryptFilesWizard *mParent; 0515 SignEncryptWidget *mWidget; 0516 QMap<int, QString> mOutNames; 0517 QMap<int, FileNameRequesterWithIcon *> mRequesters; 0518 QVBoxLayout *mOutLayout; 0519 QWidget *mPlaceholderWidget; 0520 QCheckBox *mUseOutputDirChk; 0521 QLabel *mOutputLabel; 0522 bool mArchive; 0523 bool mUseOutputDir; 0524 bool mSingleFile; 0525 }; 0526 0527 class ResultPage : public NewResultPage 0528 { 0529 Q_OBJECT 0530 0531 public: 0532 explicit ResultPage(QWidget *parent = nullptr) 0533 : NewResultPage(parent) 0534 , mParent((SignEncryptFilesWizard *)parent) 0535 { 0536 setTitle(i18nc("@title", "Results")); 0537 setSubTitle(i18nc("@title", "Status and progress of the crypto operations is shown here.")); 0538 } 0539 0540 void initializePage() override 0541 { 0542 mParent->setLabelText(QString()); 0543 } 0544 0545 private: 0546 SignEncryptFilesWizard *mParent; 0547 }; 0548 0549 SignEncryptFilesWizard::SignEncryptFilesWizard(QWidget *parent, Qt::WindowFlags f) 0550 : QWizard(parent, f) 0551 { 0552 readConfig(); 0553 0554 const bool de_vs = DeVSCompliance::isActive(); 0555 #ifdef Q_OS_WIN 0556 // Enforce modern style to avoid vista style ugliness. 0557 setWizardStyle(QWizard::ModernStyle); 0558 #endif 0559 mSigEncPage = new SigEncPage(this); 0560 mResultPage = new ResultPage(this); 0561 0562 connect(this, &QWizard::currentIdChanged, this, &SignEncryptFilesWizard::slotCurrentIdChanged); 0563 setPage(SigEncPageId, mSigEncPage); 0564 setPage(ResultPageId, mResultPage); 0565 setOptions(QWizard::IndependentPages | // 0566 (de_vs ? QWizard::HaveCustomButton1 : QWizard::WizardOption(0)) | // 0567 QWizard::NoBackButtonOnLastPage | // 0568 QWizard::NoBackButtonOnStartPage); 0569 0570 if (de_vs) { 0571 /* We use a custom button to display a label next to the 0572 buttons. */ 0573 auto btn = button(QWizard::CustomButton1); 0574 /* We style the button so that it looks and acts like a 0575 label. */ 0576 btn->setStyleSheet(QStringLiteral("border: none")); 0577 btn->setFocusPolicy(Qt::NoFocus); 0578 } 0579 } 0580 0581 void SignEncryptFilesWizard::setLabelText(const QString &label) 0582 { 0583 button(QWizard::CommitButton)->setToolTip(label); 0584 setButtonText(QWizard::CustomButton1, label); 0585 } 0586 0587 void SignEncryptFilesWizard::slotCurrentIdChanged(int id) 0588 { 0589 if (id == ResultPageId) { 0590 Q_EMIT operationPrepared(); 0591 } 0592 } 0593 0594 SignEncryptFilesWizard::~SignEncryptFilesWizard() 0595 { 0596 qCDebug(KLEOPATRA_LOG) << this << __func__; 0597 writeConfig(); 0598 } 0599 0600 void SignEncryptFilesWizard::setSigningPreset(bool preset) 0601 { 0602 mSigEncPage->setSigningPreset(preset); 0603 } 0604 0605 void SignEncryptFilesWizard::setSigningUserMutable(bool mut) 0606 { 0607 if (mut == mSigningUserMutable) { 0608 return; 0609 } 0610 mSigningUserMutable = mut; 0611 } 0612 0613 void SignEncryptFilesWizard::setEncryptionPreset(bool preset) 0614 { 0615 mSigEncPage->setEncryptionPreset(preset); 0616 } 0617 0618 void SignEncryptFilesWizard::setEncryptionUserMutable(bool mut) 0619 { 0620 if (mut == mEncryptionUserMutable) { 0621 return; 0622 } 0623 mEncryptionUserMutable = mut; 0624 } 0625 0626 void SignEncryptFilesWizard::setArchiveForced(bool archive) 0627 { 0628 mSigEncPage->setArchiveForced(archive); 0629 } 0630 0631 void SignEncryptFilesWizard::setArchiveMutable(bool archive) 0632 { 0633 mSigEncPage->setArchiveMutable(archive); 0634 } 0635 0636 void SignEncryptFilesWizard::setSingleFile(bool singleFile) 0637 { 0638 mSigEncPage->setSingleFile(singleFile); 0639 } 0640 0641 std::vector<Key> SignEncryptFilesWizard::resolvedRecipients() const 0642 { 0643 return mSigEncPage->recipients(); 0644 } 0645 0646 std::vector<Key> SignEncryptFilesWizard::resolvedSigners() const 0647 { 0648 return mSigEncPage->signers(); 0649 } 0650 0651 void SignEncryptFilesWizard::setTaskCollection(const std::shared_ptr<Kleo::Crypto::TaskCollection> &coll) 0652 { 0653 mResultPage->setTaskCollection(coll); 0654 } 0655 0656 void SignEncryptFilesWizard::setOutputNames(const QMap<int, QString> &map) const 0657 { 0658 mSigEncPage->setOutputNames(map); 0659 } 0660 0661 QMap<int, QString> SignEncryptFilesWizard::outputNames() const 0662 { 0663 return mSigEncPage->outputNames(); 0664 } 0665 0666 bool SignEncryptFilesWizard::encryptSymmetric() const 0667 { 0668 return mSigEncPage->encryptSymmetric(); 0669 } 0670 0671 void SignEncryptFilesWizard::readConfig() 0672 { 0673 winId(); // ensure there's a window created 0674 0675 // set default window size 0676 windowHandle()->resize(640, 480); 0677 0678 // restore size from config file 0679 KConfigGroup cfgGroup(KSharedConfig::openConfig(), QStringLiteral("SignEncryptFilesWizard")); 0680 KWindowConfig::restoreWindowSize(windowHandle(), cfgGroup); 0681 0682 // NOTICE: QWindow::setGeometry() does NOT impact the backing QWidget geometry even if the platform 0683 // window was created -> QTBUG-40584. We therefore copy the size here. 0684 // TODO: remove once this was resolved in QWidget QPA 0685 resize(windowHandle()->size()); 0686 } 0687 0688 void SignEncryptFilesWizard::writeConfig() 0689 { 0690 KConfigGroup cfgGroup(KSharedConfig::openConfig(), QStringLiteral("SignEncryptFilesWizard")); 0691 KWindowConfig::saveWindowSize(windowHandle(), cfgGroup); 0692 cfgGroup.sync(); 0693 } 0694 0695 #include "signencryptfileswizard.moc" 0696 0697 #include "moc_signencryptfileswizard.cpp"