From 68e5ff123e7bca884fcf23cf9f69422eb41fa0f7 Mon Sep 17 00:00:00 2001 From: Tomaž Vajngerl Date: Sun, 26 Jul 2020 21:58:33 +0200 Subject: allow to .uno:Save a PDF doc - divert to SaveAs to the doc. file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To save PDF annotations, we need to allow a .uno:Save if the document was opened from a PDF file. When we get a .uno:Save command, we need to divert that to SaveAs into the same file as the current document was opened with. Change-Id: I0c511c4e5501de03ea8b0efb5aaf37cd09936e6e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99463 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl (cherry picked from commit 6f55a64f002d80a19201e2a9b0171725fb71a7fb) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99883 Tested-by: Jenkins CollaboraOffice --- desktop/source/lib/init.cxx | 52 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'desktop') diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 906d3c4c6baa..fdd92d2d3430 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -105,6 +105,8 @@ #include #include #include +#include +#include #include #include #include @@ -721,6 +723,28 @@ std::string extractPrivateKey(const std::string & privateKey) return privateKey.substr(pos1, pos2); } +OUString lcl_getCurrentDocumentMimeType(LibLODocument_Impl* pDocument) +{ + OUString aMimeType; + SfxBaseModel* pBaseModel = dynamic_cast(pDocument->mxComponent.get()); + if (!pBaseModel) + return aMimeType; + + SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell(); + if (!pObjectShell) + return aMimeType; + + SfxMedium* pMedium = pObjectShell->GetMedium(); + if (!pMedium) + return aMimeType; + + auto pFilter = pMedium->GetFilter(); + if (!pFilter) + return aMimeType; + + return pFilter->GetMimeType(); +} + // Gets an undo manager to enter and exit undo context. Needed by ToggleOrientation css::uno::Reference< css::document::XUndoManager > getUndoManager( const css::uno::Reference< css::frame::XFrame >& rxFrame ) { @@ -2463,6 +2487,9 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha OUString sFormat = getUString(pFormat); OUString aURL(getAbsoluteURL(sUrl)); + + uno::Reference xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW); + if (aURL.isEmpty()) { SetLastExceptionMsg("Filename to save to was not provided."); @@ -2603,7 +2630,6 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha aSaveMediaDescriptor[MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= xInteraction; } - uno::Reference xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW); if (bTakeOwnership) xStorable->storeAsURL(aURL, aSaveMediaDescriptor.getAsConstPropertyValueList()); @@ -3785,6 +3811,30 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma // handle potential interaction if (gImpl && aCommand == ".uno:Save") { + // Check if saving a PDF file + OUString aMimeType = lcl_getCurrentDocumentMimeType(pDocument); + if (aMimeType == "application/pdf") + { + // If we have a PDF file (for saving annotations for example), we need + // to run save-as to the same file as the opened document. Plain save + // doesn't work as the PDF is not a "native" format. + uno::Reference xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW); + OUString aURL = xStorable->getLocation(); + OString aURLUtf8 = OUStringToOString(aURL, RTL_TEXTENCODING_UTF8); + bool bResult = doc_saveAs(pThis, aURLUtf8.getStr(), "pdf", nullptr); + + // Send the result of save + boost::property_tree::ptree aTree; + aTree.put("commandName", pCommand); + aTree.put("success", bResult); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + OString aPayload = aStream.str().c_str(); + pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aPayload.getStr()); + return; + } + + rtl::Reference const pInteraction( new LOKInteractionHandler("save", gImpl, pDocument)); uno::Reference const xInteraction(pInteraction.get()); -- cgit