diff options
Diffstat (limited to 'sfx2/source/view/frmload.cxx')
-rw-r--r-- | sfx2/source/view/frmload.cxx | 60 |
1 files changed, 60 insertions, 0 deletions
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 ); |