include/sfx2/docfile.hxx | 3 ++ include/sfx2/objsh.hxx | 12 ++++++++--- sfx2/source/doc/docfile.cxx | 9 +++++++- sfx2/source/doc/objserv.cxx | 5 ++-- sfx2/source/doc/objstor.cxx | 12 ++++++++--- sfx2/source/doc/sfxbasemodel.cxx | 2 - sw/qa/extras/htmlexport/htmlexport.cxx | 35 +++++++++++++++++++++++++++++++++ sw/source/filter/html/htmlplug.cxx | 14 +++++++++++-- sw/source/filter/html/wrthtml.cxx | 10 +++++++++ sw/source/filter/html/wrthtml.hxx | 2 + 10 files changed, 92 insertions(+), 12 deletions(-)
New commits: commit 38e00e1dc967ebc7d94c5360ad57a3ae98d1cddb Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Dec 17 17:54:21 2019 +0100 Commit: Gülşah Köse <gulsah.k...@collabora.com> CommitDate: Tue Jun 16 21:52:52 2020 +0200 sw reqif-xhtml export: add a new RTFOLEMimeType parameter This is similar to commit e0f20211a8048a87b078aa4cf0f28c0c847487ad (sw reqif-xhtml import: add a new AllowedRTFOLEMimeTypes parameter, 2019-12-16), except that was for the import and this is for the import. The situation was similar, SfxBaseModel::impl_store() still had the custom store parameters, but later functions lost it, so at the end OutHTML_FrameFormatOLENodeGrf() in the sw HTML export could not respect it. Fix the problem in a similar way, so the SfxMedium instance created for the duration of the export provides the custom options via SfxMedium::GetArgs(). Change-Id: I71d2c7920f42d98133f345703cfdfd50f0e8550c Reviewed-on: https://gerrit.libreoffice.org/85321 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96477 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Gülşah Köse <gulsah.k...@collabora.com> diff --git a/include/sfx2/docfile.hxx b/include/sfx2/docfile.hxx index 2019b5738c01..ce5a71271046 100644 --- a/include/sfx2/docfile.hxx +++ b/include/sfx2/docfile.hxx @@ -107,6 +107,9 @@ public: const std::shared_ptr<const SfxFilter>& GetFilter() const; const OUString& GetOrigURL() const; + void SetArgs(const css::uno::Sequence<css::beans::PropertyValue>& rArgs); + css::uno::Sequence<css::beans::PropertyValue> GetArgs() const; + SfxItemSet * GetItemSet() const; void Close(bool bInDestruction = false); void CloseAndRelease(); diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx index b5b626c6c713..19c615f8d7c1 100644 --- a/include/sfx2/objsh.hxx +++ b/include/sfx2/objsh.hxx @@ -721,9 +721,15 @@ public: SAL_DLLPRIVATE void SetNamedVisibility_Impl(); SAL_DLLPRIVATE bool DoSave_Impl( const SfxItemSet* pSet ); SAL_DLLPRIVATE bool Save_Impl( const SfxItemSet* pSet ); - SAL_DLLPRIVATE bool PreDoSaveAs_Impl(const OUString& rFileName, const OUString& rFiltName, SfxItemSet const & rItemSet); - SAL_DLLPRIVATE bool APISaveAs_Impl(const OUString& aFileName, SfxItemSet& rItemSet); - SAL_DLLPRIVATE bool CommonSaveAs_Impl(const INetURLObject& aURL, const OUString& aFilterName, SfxItemSet& rItemSet); + SAL_DLLPRIVATE bool + PreDoSaveAs_Impl(const OUString& rFileName, const OUString& rFiltName, + SfxItemSet const& rItemSet, + const css::uno::Sequence<css::beans::PropertyValue>& rArgs); + SAL_DLLPRIVATE bool APISaveAs_Impl(const OUString& aFileName, SfxItemSet& rItemSet, + const css::uno::Sequence<css::beans::PropertyValue>& rArgs); + SAL_DLLPRIVATE bool + CommonSaveAs_Impl(const INetURLObject& aURL, const OUString& aFilterName, SfxItemSet& rItemSet, + const css::uno::Sequence<css::beans::PropertyValue>& rArgs); SAL_DLLPRIVATE bool GeneralInit_Impl( const css::uno::Reference< css::embed::XStorage >& xStorage, bool bTypeMustBeSetAlready ); diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 5d00d39bd837..b1ef5fa0e5f2 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -306,7 +306,6 @@ public: uno::Sequence < util::RevisionTag > aVersions; std::unique_ptr<::utl::TempFile> pTempFile; - uno::Reference<embed::XStorage> xStorage; uno::Reference<embed::XStorage> m_xZipStorage; uno::Reference<io::XInputStream> m_xInputStreamToLoadFrom; @@ -328,6 +327,8 @@ public: util::DateTime m_aDateTime; + uno::Sequence<beans::PropertyValue> m_aArgs; + explicit SfxMedium_Impl(); ~SfxMedium_Impl(); SfxMedium_Impl(const SfxMedium_Impl&) = delete; @@ -3301,6 +3302,12 @@ SfxMedium::SfxMedium( const uno::Sequence<beans::PropertyValue>& aArgs ) : Init_Impl(); } +void SfxMedium::SetArgs(const uno::Sequence<beans::PropertyValue>& rArgs) +{ + pImpl->m_aArgs = rArgs; +} + +uno::Sequence<beans::PropertyValue> SfxMedium::GetArgs() const { return pImpl->m_aArgs; } SfxMedium::SfxMedium( const uno::Reference < embed::XStorage >& rStor, const OUString& rBaseURL, const std::shared_ptr<SfxItemSet>& p ) : pImpl(new SfxMedium_Impl) diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index b2c7d07be18f..929f26098644 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -282,7 +282,8 @@ void SfxObjectShell::PrintState_Impl(SfxItemSet &rSet) rSet.Put( SfxBoolItem( SID_PRINTOUT, bPrinting ) ); } -bool SfxObjectShell::APISaveAs_Impl(const OUString& aFileName, SfxItemSet& rItemSet) +bool SfxObjectShell::APISaveAs_Impl(const OUString& aFileName, SfxItemSet& rItemSet, + const css::uno::Sequence<css::beans::PropertyValue>& rArgs) { bool bOk = false; @@ -326,7 +327,7 @@ bool SfxObjectShell::APISaveAs_Impl(const OUString& aFileName, SfxItemSet& rItem if ( pDocTitleItem ) getDocProperties()->setTitle( pDocTitleItem->GetValue() ); - bOk = CommonSaveAs_Impl(INetURLObject(aFileName), aFilterName, rItemSet); + bOk = CommonSaveAs_Impl(INetURLObject(aFileName), aFilterName, rItemSet, rArgs); } } diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 8f86d559226c..41019d1bdc0f 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -2621,7 +2621,9 @@ bool SfxObjectShell::Save_Impl( const SfxItemSet* pSet ) return bSaved; } -bool SfxObjectShell::CommonSaveAs_Impl(const INetURLObject& aURL, const OUString& aFilterName, SfxItemSet& rItemSet) +bool SfxObjectShell::CommonSaveAs_Impl(const INetURLObject& aURL, const OUString& aFilterName, + SfxItemSet& rItemSet, + const uno::Sequence<beans::PropertyValue>& rArgs) { if( aURL.HasError() ) { @@ -2695,7 +2697,8 @@ bool SfxObjectShell::CommonSaveAs_Impl(const INetURLObject& aURL, const OUString if ( IsDocShared() ) aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ); - if (PreDoSaveAs_Impl(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), aFilterName, rItemSet)) + if (PreDoSaveAs_Impl(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), aFilterName, + rItemSet, rArgs)) { // Update Data on media SfxItemSet *pSet = GetMedium()->GetItemSet(); @@ -2759,7 +2762,9 @@ bool SfxObjectShell::CommonSaveAs_Impl(const INetURLObject& aURL, const OUString return false; } -bool SfxObjectShell::PreDoSaveAs_Impl(const OUString& rFileName, const OUString& aFilterName, SfxItemSet const & rItemSet) +bool SfxObjectShell::PreDoSaveAs_Impl(const OUString& rFileName, const OUString& aFilterName, + SfxItemSet const& rItemSet, + const uno::Sequence<beans::PropertyValue>& rArgs) { // copy all items stored in the itemset of the current medium std::unique_ptr<SfxAllItemSet> pMergedParams(new SfxAllItemSet( *pMedium->GetItemSet() )); @@ -2796,6 +2801,7 @@ bool SfxObjectShell::PreDoSaveAs_Impl(const OUString& rFileName, const OUString& // create a medium for the target URL auto pMergedParamsTmp = pMergedParams.get(); SfxMedium *pNewFile = new SfxMedium( rFileName, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE | StreamMode::TRUNC, nullptr, std::move(pMergedParams) ); + pNewFile->SetArgs(rArgs); const SfxBoolItem* pNoFileSync = pMergedParamsTmp->GetItem<SfxBoolItem>(SID_NO_FILE_SYNC, false); if (pNoFileSync && pNoFileSync->GetValue()) diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index 9849ac86d642..0f2a44e176e3 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -3076,7 +3076,7 @@ void SfxBaseModel::impl_store( const OUString& sURL m_pData->m_xDocumentProperties = xNewDocProps; } - bool bRet = m_pData->m_pObjectShell->APISaveAs_Impl(sURL, *pItemSet); + bool bRet = m_pData->m_pObjectShell->APISaveAs_Impl(sURL, *pItemSet, seqArguments); if ( bCopyTo ) { diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx index fadd91b728fb..c2ef9bc7961b 100644 --- a/sw/qa/extras/htmlexport/htmlexport.cxx +++ b/sw/qa/extras/htmlexport/htmlexport.cxx @@ -22,6 +22,7 @@ #include <test/htmltesttools.hxx> #include <tools/urlobj.hxx> #include <svtools/rtfkeywd.hxx> +#include <comphelper/propertyvalue.hxx> class HtmlExportTest : public SwModelTestBase, public HtmlTestTools { @@ -107,6 +108,8 @@ class SwHtmlDomExportTest : public SwModelTestBase, public HtmlTestTools { }; +char const DATA_DIRECTORY[] = "/sw/qa/extras/htmlexport/data/"; + DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testFdo81276, "fdo81276.html") { uno::Reference<container::XNameAccess> xPageStyles(getStyles("PageStyles")); @@ -726,6 +729,38 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testBlockQuoteReqIf) assertXPath(pDoc, "/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:blockquote/reqif-xhtml:p", 1); } +CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testRTFOLEMimeType) +{ + // Import a document with an embedded object. + OUString aType("test/rtf"); + uno::Sequence<beans::PropertyValue> aLoadProperties = { + comphelper::makePropertyValue("FilterName", OUString("HTML (StarWriter)")), + comphelper::makePropertyValue("FilterOptions", OUString("xhtmlns=reqif-xhtml")), + }; + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "reqif-ole-data.xhtml"; + mxComponent = loadFromDesktop(aURL, "com.sun.star.text.TextDocument", aLoadProperties); + + // Export it. + uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); + uno::Sequence<beans::PropertyValue> aStoreProperties = { + comphelper::makePropertyValue("FilterName", OUString("HTML (StarWriter)")), + comphelper::makePropertyValue("FilterOptions", OUString("xhtmlns=reqif-xhtml")), + comphelper::makePropertyValue("RTFOLEMimeType", aType), + }; + xStorable->storeToURL(maTempFile.GetURL(), aStoreProperties); + SvMemoryStream aStream; + HtmlExportTest::wrapFragment(maTempFile, aStream); + xmlDocPtr pDoc = parseXmlStream(&aStream); + CPPUNIT_ASSERT(pDoc); + + // Without the accompanying fix in place, this test would have failed with: + // - Expected: test/rtf + // - Actual : text/rtf + // i.e. the MIME type was always text/rtf, not taking the store parameter into account. + assertXPath(pDoc, "/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:p/reqif-xhtml:object", "type", + aType); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/html/htmlplug.cxx b/sw/source/filter/html/htmlplug.cxx index a0da671de733..ce22cfcd274e 100644 --- a/sw/source/filter/html/htmlplug.cxx +++ b/sw/source/filter/html/htmlplug.cxx @@ -1513,6 +1513,12 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame SwDocShell* pDocSh = rHTMLWrt.m_pDoc->GetDocShell(); bool bObjectOpened = false; + OUString aRTFType = "text/rtf"; + if (!rHTMLWrt.m_aRTFOLEMimeType.isEmpty()) + { + aRTFType = rHTMLWrt.m_aRTFOLEMimeType; + } + if (rHTMLWrt.mbXHTML && pDocSh) { // Map native data to an outer <object> element. @@ -1543,7 +1549,7 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame if (SwReqIfReader::WrapOleInRtf(*pStream, aOutStream, *pOLENd)) { // Data always wrapped in RTF. - aFileType = "text/rtf"; + aFileType = aRTFType; } } } @@ -1562,7 +1568,7 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame if (SwReqIfReader::WrapOleInRtf(aMemory, aOutStream, *pOLENd)) { // Data always wrapped in RTF. - aFileType = "text/rtf"; + aFileType = aRTFType; } } else @@ -1589,6 +1595,10 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, const SwFrameFormat& rFrame uno::Reference<beans::XPropertySet> xOutStreamProps(xInStream, uno::UNO_QUERY); if (xOutStreamProps.is()) xOutStreamProps->getPropertyValue("MediaType") >>= aFileType; + if (!aRTFType.isEmpty()) + { + aFileType = aRTFType; + } } aFileName = URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), aFileName); diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx index 76ce6fb781a6..1157b27dd29d 100644 --- a/sw/source/filter/html/wrthtml.cxx +++ b/sw/source/filter/html/wrthtml.cxx @@ -82,6 +82,7 @@ #include <osl/file.hxx> #include <comphelper/scopeguard.hxx> #include <unotools/tempfile.hxx> +#include <comphelper/sequenceashashmap.hxx> #define MAX_INDENT_LEVEL 20 @@ -188,6 +189,15 @@ void SwHTMLWriter::SetupFilterOptions(SfxMedium& rMedium) const OUString sFilterOptions = static_cast<const SfxStringItem*>(pItem)->GetValue(); SetupFilterOptions(sFilterOptions); + + comphelper::SequenceAsHashMap aStoreMap(rMedium.GetArgs()); + auto it = aStoreMap.find("RTFOLEMimeType"); + if (it == aStoreMap.end()) + { + return; + } + + it->second >>= m_aRTFOLEMimeType; } void SwHTMLWriter::SetupFilterOptions(const OUString& rFilterOptions) diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx index 805643817003..8cc06647016b 100644 --- a/sw/source/filter/html/wrthtml.hxx +++ b/sw/source/filter/html/wrthtml.hxx @@ -405,6 +405,8 @@ public: /// Tracks which text portion attributes are currently open: a which id -> open count map. std::map<sal_uInt16, int> maStartedAttributes; + OUString m_aRTFOLEMimeType; + /// Construct an instance of SwHTMLWriter and optionally give it /// the filter options directly, which can also be set via SetupFilterOptions(). explicit SwHTMLWriter( const OUString& rBaseURL, const OUString& rFilterOptions = "" ); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits