diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2022-04-13 08:40:23 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2022-04-13 15:46:59 +0200 |
commit | 064f4fe82c30118a34c4aeb47bf8604f0b8356a1 (patch) | |
tree | 281c28c1b10e6b39c0a330c64928c933818cb77f /sfx2 | |
parent | 15f70da655301be4d66abf91ee788b50e8ab1215 (diff) |
tdf#139991: move 0-byte file handling to SfxFrameLoader_Impl::load
This centralizes the code that handles templates, and allows the empty
files to use default templates.
This partially reverts commits:
ada07f303e7cd1e39c73abe0741aefe7d9d73a57
Author Miklos Vajna <vmiklos@collabora.com>
Date Wed Oct 28 14:54:52 2020 +0100
tdf#123476 filter: try to detect 0-byte files based on extension
2854362f429e476d4a1ab4759c6a1f1c04150280
Author Mike Kaganski <mike.kaganski@collabora.com>
Date Wed Jan 27 16:05:54 2021 +0100
tdf#123476 filter: Also handle empty ODF
dff586735b6618d9b011823594a33287d8f7f223
Author Mike Kaganski <mike.kaganski@collabora.com>
Date Mon May 03 17:04:04 2021 +0200
tdf#123476: also use filter by extension when its service is the same
The unit tests from these commits are retained and extended for templates.
Change-Id: I755738d2d5a6d6955d84d6e12f3accc017e0391f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132938
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'sfx2')
-rw-r--r-- | sfx2/source/doc/objstor.cxx | 12 | ||||
-rw-r--r-- | sfx2/source/view/frmload.cxx | 60 |
2 files changed, 63 insertions, 9 deletions
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 0000a9b4f6df..0dc8cb2d1d5b 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -429,7 +429,7 @@ bool SfxObjectShell::InitNew( const uno::Reference< embed::XStorage >& xStorage bool SfxObjectShell::Load( SfxMedium& rMedium ) { - return GeneralInit_Impl(rMedium.GetStorage(), !tools::isEmptyFileUrl(rMedium.GetName())); + return GeneralInit_Impl(rMedium.GetStorage(), true); } void SfxObjectShell::DoInitUnitTest() @@ -662,9 +662,7 @@ bool SfxObjectShell::DoLoad( SfxMedium *pMed ) bWarnMediaTypeFallback = false; } - if (bWarnMediaTypeFallback - || (!tools::isEmptyFileUrl(pMedium->GetName()) - && !xStorage->getElementNames().hasElements())) + if (bWarnMediaTypeFallback || !xStorage->getElementNames().hasElements()) SetError(ERRCODE_IO_BROKENPACKAGE); } catch( uno::Exception& ) @@ -2260,11 +2258,7 @@ bool SfxObjectShell::ImportFrom(SfxMedium& rMedium, // #i119492# During loading, some OLE objects like chart will be set // modified flag, so needs to reset the flag to false after loading - bool bRtn = true; - if (!tools::isEmptyFileUrl(rMedium.GetName())) - { - bRtn = xLoader->filter(aArgs); - } + bool bRtn = xLoader->filter(aArgs); const uno::Sequence < OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames(); for ( const auto& rName : aNames ) { diff --git a/sfx2/source/view/frmload.cxx b/sfx2/source/view/frmload.cxx index 91b045b2f1a3..bd0329fb2ac3 100644 --- a/sfx2/source/view/frmload.cxx +++ b/sfx2/source/view/frmload.cxx @@ -21,6 +21,7 @@ #include <sfx2/app.hxx> #include <sfx2/bindings.hxx> #include <sfx2/docfac.hxx> +#include <sfx2/docfile.hxx> #include <sfx2/docfilt.hxx> #include <sfx2/doctempl.hxx> #include <sfx2/fcontnr.hxx> @@ -55,8 +56,11 @@ #include <rtl/ref.hxx> #include <sal/log.hxx> #include <svl/eitem.hxx> +#include <svl/stritem.hxx> #include <unotools/moduleoptions.hxx> #include <tools/diagnose_ex.h> +#include <tools/stream.hxx> +#include <tools/urlobj.hxx> #include <vcl/svapp.hxx> using namespace com::sun::star; @@ -585,6 +589,25 @@ Reference< XController2 > SfxFrameLoader_Impl::impl_createDocumentView( const Re return xController; } +std::shared_ptr<const SfxFilter> getEmptyURLFilter(const OUString& sURL) +{ + INetURLObject aParser(sURL); + const OUString aExt = aParser.getExtension(INetURLObject::LAST_SEGMENT, true, + INetURLObject::DecodeMechanism::WithCharset); + const SfxFilterMatcher& rMatcher = SfxGetpApp()->GetFilterMatcher(); + + // Requiring the export+preferred flags helps to find the relevant filter, e.g. .doc -> WW8 (and + // not WW6 or Mac_Word). + std::shared_ptr<const SfxFilter> pFilter = rMatcher.GetFilter4Extension( + aExt, SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::PREFERED); + if (!pFilter) + { + // retry without PREFERED so we can find at least something for 0-byte *.ods + pFilter + = rMatcher.GetFilter4Extension(aExt, SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT); + } + return pFilter; +} sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rArgs, const Reference< XFrame >& _rTargetFrame ) @@ -608,6 +631,7 @@ sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rA // check for factory URLs to create a new doc, instead of loading one const OUString sURL = aDescriptor.getOrDefault( "URL", OUString() ); const bool bIsFactoryURL = sURL.startsWith( "private:factory/" ); + std::shared_ptr<const SfxFilter> pEmptyURLFilter; bool bInitNewModel = bIsFactoryURL; const bool bIsDefault = bIsFactoryURL && !bExternalModel; if (!aDescriptor.has("Replaceable")) @@ -640,6 +664,28 @@ sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rA { // compatibility aDescriptor.put( "FileName", aDescriptor.get( "URL" ) ); + + if (!bIsFactoryURL && !bExternalModel && tools::isEmptyFileUrl(sURL)) + { + pEmptyURLFilter = getEmptyURLFilter(sURL); + if (pEmptyURLFilter) + { + aDescriptor.put("DocumentService", pEmptyURLFilter->GetServiceName()); + if (impl_determineTemplateDocument(aDescriptor)) + { + // if the media descriptor allowed us to determine a template document + // to create the new document from, then do not init a new document model + // from scratch (below), but instead load the template document + bInitNewModel = false; + // Do not try to load from empty UCB content + aDescriptor.remove("UCBContent"); + } + else + { + bInitNewModel = true; + } + } + } } bool bLoadSuccess = false; @@ -692,6 +738,20 @@ sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rA const SfxObjectShellRef xDoc = impl_findObjectShell( xModel ); ENSURE_OR_THROW( xDoc.is(), "no SfxObjectShell for the given model" ); + if (pEmptyURLFilter) + { + // Detach the medium from the template, and set proper document name and filter + auto pMedium = xDoc->GetMedium(); + auto pItemSet = pMedium->GetItemSet(); + pItemSet->ClearItem(SID_TEMPLATE); + pItemSet->Put(SfxStringItem(SID_FILTER_NAME, pEmptyURLFilter->GetFilterName())); + pMedium->SetName(sURL, true); + pMedium->SetFilter(pEmptyURLFilter); + pMedium->GetInitFileDate(true); + xDoc->SetLoading(SfxLoadedFlags::NONE); + xDoc->FinishedLoading(); + } + // ensure the ID of the to-be-created view is in the descriptor, if possible const SfxInterfaceId nViewId = impl_determineEffectiveViewId_nothrow( *xDoc, aDescriptor ); const sal_Int16 nViewNo = xDoc->GetFactory().GetViewNo_Impl( nViewId, 0 ); |