summaryrefslogtreecommitdiff
path: root/sfx2
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2022-04-13 08:40:23 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2022-04-13 15:46:59 +0200
commit064f4fe82c30118a34c4aeb47bf8604f0b8356a1 (patch)
tree281c28c1b10e6b39c0a330c64928c933818cb77f /sfx2
parent15f70da655301be4d66abf91ee788b50e8ab1215 (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.cxx12
-rw-r--r--sfx2/source/view/frmload.cxx60
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 );