diff --git a/core/document.cpp b/core/document.cpp index fd2182366..18cc746e3 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -2701,29 +2701,12 @@ bool Document::canConfigurePrinter() const return false; } -void Document::sign(const NewSignatureData &data) +bool Document::sign(const NewSignatureData &data, const QString &newPath) { if (d->m_generator->canSign()) { - // we technically need to save the document before signing it, - // so let's ask before clobbering - const int res = KMessageBox::warningContinueCancel(d->m_widget, - i18n("Signing this document will modify the file \"%1\" on disk by embedding a " - "digital signature inside it. Do you wish to proceed?", - currentDocument().fileName()), - i18n("Sign Document"), - KStandardGuiItem::ok(), - KStandardGuiItem::cancel(), - QStringLiteral("SignatureAutoClobber")); - - if (res == KMessageBox::Continue) { - // Sign it! - if (!d->m_generator->sign(data, currentDocument().path())) { - KMessageBox::error(d->m_widget, i18nc("%1 is a filename", "Could not sign '%1'. Invalid password or cannot write", currentDocument().fileName())); - } - // no need to - slotAttemptReload() gets called via - // dirty handler anyway: - // swapBackingFile(currentDocument().path(), currentDocument()); - } + return d->m_generator->sign(data, newPath); + } else { + return false; } } diff --git a/core/document.h b/core/document.h index 28d7567ee..91242a785 100644 --- a/core/document.h +++ b/core/document.h @@ -999,7 +999,7 @@ public: * * @since 21.04 */ - void sign(const NewSignatureData &data); + bool sign(const NewSignatureData &data, const QString &newPath); /** * Returns the generator's certificate store (if any) diff --git a/part/pageview.cpp b/part/pageview.cpp index 847e4745a..479c14310 100644 --- a/part/pageview.cpp +++ b/part/pageview.cpp @@ -788,11 +788,10 @@ void PageView::setupActions(KActionCollection *ac) kundo->setEnabled(false); kredo->setEnabled(false); - if (!d->annotator) { - d->annotator = new PageViewAnnotator(this, d->document); - connect(d->annotator, &PageViewAnnotator::toolSelected, d->aMouseNormal, &QAction::trigger); - connect(d->annotator, &PageViewAnnotator::toolSelected, d->mouseAnnotation, &MouseAnnotation::reset); - } + d->annotator = new PageViewAnnotator(this, d->document); + connect(d->annotator, &PageViewAnnotator::toolSelected, d->aMouseNormal, &QAction::trigger); + connect(d->annotator, &PageViewAnnotator::toolSelected, d->mouseAnnotation, &MouseAnnotation::reset); + connect(d->annotator, &PageViewAnnotator::requestOpenFile, this, &PageView::requestOpenFile); d->annotator->setupActions(ac); } @@ -4785,10 +4784,6 @@ void PageView::slotSignature() d->messageWindow->display(i18n("Draw a rectangle to insert the signature field"), QString(), PageViewMessage::Info, -1); - if (!d->annotator) { - d->annotator = new PageViewAnnotator(this, d->document); - } - d->annotator->setSignatureMode(true); // force an update of the cursor diff --git a/part/pageview.h b/part/pageview.h index 3ad324c89..eee98959a 100644 --- a/part/pageview.h +++ b/part/pageview.h @@ -142,6 +142,7 @@ Q_SIGNALS: void escPressed(); void fitWindowToPage(const QSize pageViewPortSize, const QSize pageSize); void triggerSearch(const QString &text); + void requestOpenFile(const QString &filePath); protected: bool event(QEvent *event) override; diff --git a/part/pageviewannotator.cpp b/part/pageviewannotator.cpp index fe496c27f..11b6dd1fd 100644 --- a/part/pageviewannotator.cpp +++ b/part/pageviewannotator.cpp @@ -17,9 +17,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -399,7 +401,7 @@ public: return !certNicknameToUse.isEmpty(); } - void sign() + bool sign(const QString &newFilePath) { Okular::NewSignatureData data; data.setCertNickname(certNicknameToUse); @@ -407,9 +409,8 @@ public: data.setPassword(passToUse); data.setPage(m_page->number()); data.setBoundingRectangle(rect); - m_document->sign(data); - - passToUse = QString(); + passToUse.clear(); + return m_document->sign(data, newFilePath); } private: @@ -993,7 +994,27 @@ QRect PageViewAnnotator::performRouteMouseOrTabletEvent(const AnnotatorEngine::E if (signatureMode()) { auto signEngine = static_cast(m_engine); if (signEngine->isAccepted()) { - static_cast(m_engine)->sign(); + QMimeDatabase db; + const QString typeName = m_document->documentInfo().get(Okular::DocumentInfo::MimeType); + const QMimeType mimeType = db.mimeTypeForName(typeName); + const QString mimeTypeFilter = i18nc("File type name and pattern", "%1 (%2)", mimeType.comment(), mimeType.globPatterns().join(QLatin1Char(' '))); + + const QUrl currentFileUrl = m_document->currentDocument(); + const QFileInfo currentFileInfo(currentFileUrl.fileName()); + const QString localFilePathIfAny = currentFileUrl.isLocalFile() ? QFileInfo(currentFileUrl.path()).canonicalPath() + QLatin1Char('/') : QString(); + const QString newFileName = + localFilePathIfAny + i18nc("Used when suggesting a new name for a digitally signed file. %1 is the old file name and %2 it's extension", "%1_signed.%2", currentFileInfo.baseName(), currentFileInfo.completeSuffix()); + + const QString newFilePath = QFileDialog::getSaveFileName(m_pageView, i18n("Save Signed File As"), newFileName, mimeTypeFilter); + + if (!newFilePath.isEmpty()) { + const bool success = static_cast(m_engine)->sign(newFilePath); + if (success) { + emit requestOpenFile(newFilePath); + } else { + KMessageBox::error(m_pageView, i18nc("%1 is a file path", "Could not sign. Invalid certificate password or could not write to '%1'", newFilePath)); + } + } } m_continuousMode = false; } diff --git a/part/pageviewannotator.h b/part/pageviewannotator.h index 4b7f59214..e19c31131 100644 --- a/part/pageviewannotator.h +++ b/part/pageviewannotator.h @@ -139,6 +139,7 @@ public Q_SLOTS: Q_SIGNALS: void toolSelected(); + void requestOpenFile(const QString &filePath); private: void reparseBuiltinToolsConfig(); diff --git a/part/part.cpp b/part/part.cpp index cddb3c77e..b519ae8d5 100644 --- a/part/part.cpp +++ b/part/part.cpp @@ -539,6 +539,11 @@ Part::Part(QWidget *parentWidget, QObject *parent, const QVariantList &args) connect(m_miniBar, &MiniBar::forwardKeyPressEvent, m_pageView, &PageView::externalKeyPressEvent); connect(m_pageView.data(), &PageView::escPressed, m_findBar, &FindBar::resetSearch); connect(m_pageNumberTool, &MiniBar::forwardKeyPressEvent, m_pageView, &PageView::externalKeyPressEvent); + connect(m_pageView.data(), &PageView::requestOpenFile, this, [this](const QString &filePath) { + // We cheat a bit here reusing the urlsDropped signal, but at the end the output is the same, we want to open some files + // urlsDropped should have just had a different name + Q_EMIT urlsDropped({QUrl::fromLocalFile(filePath)}); + }); connect(m_reviewsWidget.data(), &Reviews::openAnnotationWindow, m_pageView.data(), &PageView::openAnnotationWindow);