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:ada07f303e
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 extension2854362f42
Author Mike Kaganski <mike.kaganski@collabora.com> Date Wed Jan 27 16:05:54 2021 +0100 tdf#123476 filter: Also handle empty ODFdff586735b
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>
This commit is contained in:
parent
15f70da655
commit
064f4fe82c
8 changed files with 170 additions and 115 deletions
|
@ -21,6 +21,7 @@ $(eval $(call gb_CppunitTest_use_libraries,filter_textfilterdetect, \
|
|||
cppu \
|
||||
cppuhelper \
|
||||
sal \
|
||||
sfx \
|
||||
test \
|
||||
textfd \
|
||||
tl \
|
||||
|
|
BIN
filter/qa/unit/data/calc.ots
Normal file
BIN
filter/qa/unit/data/calc.ots
Normal file
Binary file not shown.
BIN
filter/qa/unit/data/impress.otp
Normal file
BIN
filter/qa/unit/data/impress.otp
Normal file
Binary file not shown.
BIN
filter/qa/unit/data/writer.ott
Normal file
BIN
filter/qa/unit/data/writer.ott
Normal file
Binary file not shown.
|
@ -13,8 +13,13 @@
|
|||
#include <com/sun/star/document/XExtendedFilterDetection.hpp>
|
||||
#include <com/sun/star/frame/Desktop.hpp>
|
||||
#include <com/sun/star/lang/XServiceInfo.hpp>
|
||||
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
|
||||
#include <com/sun/star/sheet/XCellRangesAccess.hpp>
|
||||
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
|
||||
#include <com/sun/star/text/XTextDocument.hpp>
|
||||
|
||||
#include <comphelper/propertyvalue.hxx>
|
||||
#include <sfx2/docfac.hxx>
|
||||
#include <unotools/mediadescriptor.hxx>
|
||||
#include <unotools/streamwrap.hxx>
|
||||
#include <tools/stream.hxx>
|
||||
|
@ -31,12 +36,8 @@ namespace
|
|||
/// Test class for PlainTextFilterDetect.
|
||||
class TextFilterDetectTest : public test::BootstrapFixture, public unotest::MacrosTest
|
||||
{
|
||||
uno::Reference<lang::XComponent> mxComponent;
|
||||
|
||||
public:
|
||||
void setUp() override;
|
||||
void tearDown() override;
|
||||
uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
|
||||
};
|
||||
|
||||
void TextFilterDetectTest::setUp()
|
||||
|
@ -46,14 +47,6 @@ void TextFilterDetectTest::setUp()
|
|||
mxDesktop.set(frame::Desktop::create(mxComponentContext));
|
||||
}
|
||||
|
||||
void TextFilterDetectTest::tearDown()
|
||||
{
|
||||
if (mxComponent.is())
|
||||
mxComponent->dispose();
|
||||
|
||||
test::BootstrapFixture::tearDown();
|
||||
}
|
||||
|
||||
constexpr OUStringLiteral DATA_DIRECTORY = u"/filter/qa/unit/data/";
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testTdf114428)
|
||||
|
@ -78,68 +71,126 @@ CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testTdf114428)
|
|||
|
||||
CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testEmptyFile)
|
||||
{
|
||||
// Given an empty file, with a pptx extension
|
||||
OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.pptx";
|
||||
const OUString sDataDirectory = m_directories.getURLFromSrc(DATA_DIRECTORY);
|
||||
auto supportsService = [](const uno::Reference<lang::XComponent>& x, const OUString& s) {
|
||||
return uno::Reference<lang::XServiceInfo>(x, uno::UNO_QUERY_THROW)->supportsService(s);
|
||||
};
|
||||
|
||||
// Given an empty file, with a pptx extension
|
||||
// When loading the file
|
||||
getComponent() = loadFromDesktop(aURL);
|
||||
auto xComponent = loadFromDesktop(sDataDirectory + "empty.pptx");
|
||||
|
||||
// Then make sure it is opened in Impress.
|
||||
uno::Reference<lang::XServiceInfo> xServiceInfo(getComponent(), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT(xServiceInfo.is());
|
||||
|
||||
// Without the accompanying fix in place, this test would have failed, as it was opened in
|
||||
// Writer instead.
|
||||
CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.presentation.PresentationDocument"));
|
||||
|
||||
getComponent()->dispose();
|
||||
CPPUNIT_ASSERT(supportsService(xComponent, "com.sun.star.presentation.PresentationDocument"));
|
||||
xComponent->dispose();
|
||||
|
||||
// Now also test ODT
|
||||
aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.odt";
|
||||
getComponent() = loadFromDesktop(aURL);
|
||||
xServiceInfo.set(getComponent(), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT(xServiceInfo.is());
|
||||
xComponent = loadFromDesktop(sDataDirectory + "empty.odt");
|
||||
// Make sure it opens in Writer.
|
||||
CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextDocument"));
|
||||
getComponent()->dispose();
|
||||
CPPUNIT_ASSERT(supportsService(xComponent, "com.sun.star.text.TextDocument"));
|
||||
xComponent->dispose();
|
||||
|
||||
// ... and ODS
|
||||
aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.ods";
|
||||
getComponent() = loadFromDesktop(aURL);
|
||||
xServiceInfo.set(getComponent(), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT(xServiceInfo.is());
|
||||
xComponent = loadFromDesktop(sDataDirectory + "empty.ods");
|
||||
// Make sure it opens in Calc.
|
||||
CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.sheet.SpreadsheetDocument"));
|
||||
getComponent()->dispose();
|
||||
CPPUNIT_ASSERT(supportsService(xComponent, "com.sun.star.sheet.SpreadsheetDocument"));
|
||||
xComponent->dispose();
|
||||
|
||||
// ... and ODP
|
||||
aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.odp";
|
||||
getComponent() = loadFromDesktop(aURL);
|
||||
xServiceInfo.set(getComponent(), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT(xServiceInfo.is());
|
||||
xComponent = loadFromDesktop(sDataDirectory + "empty.odp");
|
||||
// Without the accompanying fix in place, this test would have failed, as it was opened in
|
||||
// Writer instead.
|
||||
CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.presentation.PresentationDocument"));
|
||||
getComponent()->dispose();
|
||||
CPPUNIT_ASSERT(supportsService(xComponent, "com.sun.star.presentation.PresentationDocument"));
|
||||
xComponent->dispose();
|
||||
|
||||
// ... and DOC
|
||||
aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.doc";
|
||||
// Without the accompanying fix in place, this test would have failed, the import filter aborted
|
||||
// loading.
|
||||
getComponent() = loadFromDesktop(aURL);
|
||||
xServiceInfo.set(getComponent(), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT(xServiceInfo.is());
|
||||
CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextDocument"));
|
||||
uno::Reference<frame::XModel> xModel(getComponent(), uno::UNO_QUERY);
|
||||
uno::Sequence<beans::PropertyValue> aArgs = xModel->getArgs();
|
||||
comphelper::SequenceAsHashMap aMap(aArgs);
|
||||
OUString aFilterName;
|
||||
aMap["FilterName"] >>= aFilterName;
|
||||
// Without the accompanying fix in place, this test would have failed with:
|
||||
// - Expected: MS Word 97
|
||||
// - Actual : MS WinWord 6.0
|
||||
// i.e. opening worked, but saving back failed instead of producing a WW8 binary file.
|
||||
CPPUNIT_ASSERT_EQUAL(OUString("MS Word 97"), aFilterName);
|
||||
xComponent = loadFromDesktop(sDataDirectory + "empty.doc");
|
||||
CPPUNIT_ASSERT(supportsService(xComponent, "com.sun.star.text.TextDocument"));
|
||||
{
|
||||
uno::Reference<frame::XModel> xModel(xComponent, uno::UNO_QUERY);
|
||||
uno::Sequence<beans::PropertyValue> aArgs = xModel->getArgs();
|
||||
comphelper::SequenceAsHashMap aMap(aArgs);
|
||||
OUString aFilterName;
|
||||
aMap["FilterName"] >>= aFilterName;
|
||||
// Without the accompanying fix in place, this test would have failed with:
|
||||
// - Expected: MS Word 97
|
||||
// - Actual : MS WinWord 6.0
|
||||
// i.e. opening worked, but saving back failed instead of producing a WW8 binary file.
|
||||
CPPUNIT_ASSERT_EQUAL(OUString("MS Word 97"), aFilterName);
|
||||
}
|
||||
xComponent->dispose();
|
||||
|
||||
// Now test with default templates set
|
||||
|
||||
SfxObjectFactory::SetStandardTemplate("com.sun.star.presentation.PresentationDocument",
|
||||
sDataDirectory + "impress.otp");
|
||||
SfxObjectFactory::SetStandardTemplate("com.sun.star.text.TextDocument",
|
||||
sDataDirectory + "writer.ott");
|
||||
SfxObjectFactory::SetStandardTemplate("com.sun.star.sheet.SpreadsheetDocument",
|
||||
sDataDirectory + "calc.ots");
|
||||
|
||||
xComponent = loadFromDesktop(sDataDirectory + "empty.pptx");
|
||||
{
|
||||
uno::Reference<drawing::XDrawPagesSupplier> xDoc(xComponent, uno::UNO_QUERY_THROW);
|
||||
uno::Reference<drawing::XDrawPages> xPages(xDoc->getDrawPages(), uno::UNO_SET_THROW);
|
||||
uno::Reference<drawing::XDrawPage> xPage(xPages->getByIndex(0), uno::UNO_QUERY_THROW);
|
||||
uno::Reference<text::XTextRange> xBox(xPage->getByIndex(0), uno::UNO_QUERY_THROW);
|
||||
|
||||
// Make sure the template's text was loaded
|
||||
CPPUNIT_ASSERT_EQUAL(OUString("Title of Impress template"), xBox->getString());
|
||||
}
|
||||
xComponent->dispose();
|
||||
|
||||
xComponent = loadFromDesktop(sDataDirectory + "empty.odt");
|
||||
{
|
||||
uno::Reference<text::XTextDocument> xDoc(xComponent, uno::UNO_QUERY_THROW);
|
||||
uno::Reference<container::XEnumerationAccess> xEA(xDoc->getText(), uno::UNO_QUERY_THROW);
|
||||
uno::Reference<container::XEnumeration> xEnum(xEA->createEnumeration(), uno::UNO_SET_THROW);
|
||||
uno::Reference<text::XTextRange> xParagraph(xEnum->nextElement(), uno::UNO_QUERY_THROW);
|
||||
|
||||
// Make sure the template's text was loaded
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(u"Writer template’s first line"), xParagraph->getString());
|
||||
}
|
||||
xComponent->dispose();
|
||||
|
||||
xComponent = loadFromDesktop(sDataDirectory + "empty.ods");
|
||||
{
|
||||
uno::Reference<sheet::XSpreadsheetDocument> xDoc(xComponent, uno::UNO_QUERY_THROW);
|
||||
uno::Reference<sheet::XCellRangesAccess> xRA(xDoc->getSheets(), uno::UNO_QUERY_THROW);
|
||||
uno::Reference<text::XTextRange> xC(xRA->getCellByPosition(0, 0, 0), uno::UNO_QUERY_THROW);
|
||||
|
||||
// Make sure the template's text was loaded
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(u"Calc template’s first cell"), xC->getString());
|
||||
}
|
||||
xComponent->dispose();
|
||||
|
||||
xComponent = loadFromDesktop(sDataDirectory + "empty.odp");
|
||||
{
|
||||
uno::Reference<drawing::XDrawPagesSupplier> xDoc(xComponent, uno::UNO_QUERY_THROW);
|
||||
uno::Reference<drawing::XDrawPages> xPages(xDoc->getDrawPages(), uno::UNO_SET_THROW);
|
||||
uno::Reference<drawing::XDrawPage> xPage(xPages->getByIndex(0), uno::UNO_QUERY_THROW);
|
||||
uno::Reference<text::XTextRange> xBox(xPage->getByIndex(0), uno::UNO_QUERY_THROW);
|
||||
|
||||
// Make sure the template's text was loaded
|
||||
CPPUNIT_ASSERT_EQUAL(OUString("Title of Impress template"), xBox->getString());
|
||||
}
|
||||
xComponent->dispose();
|
||||
|
||||
xComponent = loadFromDesktop(sDataDirectory + "empty.doc");
|
||||
{
|
||||
uno::Reference<text::XTextDocument> xDoc(xComponent, uno::UNO_QUERY_THROW);
|
||||
uno::Reference<container::XEnumerationAccess> xEA(xDoc->getText(), uno::UNO_QUERY_THROW);
|
||||
uno::Reference<container::XEnumeration> xEnum(xEA->createEnumeration(), uno::UNO_SET_THROW);
|
||||
uno::Reference<text::XTextRange> xParagraph(xEnum->nextElement(), uno::UNO_QUERY_THROW);
|
||||
|
||||
// Make sure the template's text was loaded
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(u"Writer template’s first line"), xParagraph->getString());
|
||||
}
|
||||
xComponent->dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include <com/sun/star/io/XInputStream.hpp>
|
||||
#include <cppuhelper/supportsservice.hxx>
|
||||
#include <memory>
|
||||
#include <sfx2/fcontnr.hxx>
|
||||
#include <sfx2/docfilt.hxx>
|
||||
|
||||
constexpr OUStringLiteral WRITER_TEXT_FILTER = u"Text";
|
||||
constexpr OUStringLiteral CALC_TEXT_FILTER = u"Text - txt - csv (StarCalc)";
|
||||
|
@ -129,45 +127,6 @@ bool IsHTMLStream( const uno::Reference<io::XInputStream>& xInStream )
|
|||
OString aToken = sHeader.copy( nStartOfTagIndex, i - nStartOfTagIndex );
|
||||
return GetHTMLToken( OStringToOUString( aToken.toAsciiLowerCase(), RTL_TEXTENCODING_ASCII_US ) ) != HtmlTokenId::NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an (empty) file URL in rMediaDesc and rExt, looks up the best filter type for it and
|
||||
* writes the type name to rType, the filter name to rMediaDesc.
|
||||
*/
|
||||
bool HandleEmptyFileUrlByExtension(MediaDescriptor& rMediaDesc, const OUString& rExt,
|
||||
OUString& rType, OUString& rService)
|
||||
{
|
||||
OUString aURL = rMediaDesc.getUnpackedValueOrDefault(MediaDescriptor::PROP_URL, OUString());
|
||||
if (!tools::isEmptyFileUrl(aURL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rExt.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Requiring the export+preferred flags helps to find the relevant filter, e.g. .doc -> WW8 (and
|
||||
// not WW6 or Mac_Word).
|
||||
SfxFilterFlags nMust
|
||||
= SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::PREFERED;
|
||||
std::shared_ptr<const SfxFilter> pFilter(SfxFilterMatcher().GetFilter4Extension(rExt, nMust));
|
||||
if (!pFilter)
|
||||
{
|
||||
// retry without PREFERRED so we can find at least something for 0-byte *.ods
|
||||
nMust = SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT;
|
||||
pFilter = SfxFilterMatcher().GetFilter4Extension(rExt, nMust);
|
||||
|
||||
if (!pFilter)
|
||||
return false;
|
||||
}
|
||||
|
||||
rMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= pFilter->GetFilterName();
|
||||
rType = pFilter->GetTypeName();
|
||||
rService = pFilter->GetServiceName();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
PlainTextFilterDetect::PlainTextFilterDetect() {}
|
||||
|
@ -226,15 +185,7 @@ OUString SAL_CALL PlainTextFilterDetect::detect(uno::Sequence<beans::PropertyVal
|
|||
OUString aName = aParser.getName().toAsciiLowerCase();
|
||||
|
||||
// Decide which filter to use based on the document service first,
|
||||
// then on extension if that's not available. Make exception for 0-byte files
|
||||
// whose extensions are handled by the same service as passed document service.
|
||||
OUString aEmptyType, aEmptyService;
|
||||
bool bEmpty = HandleEmptyFileUrlByExtension(aMediaDesc, aExt, aEmptyType, aEmptyService);
|
||||
if (bEmpty && aDocService == aEmptyService)
|
||||
{
|
||||
aDocService.clear(); // don't fallback to text filter, use extension-based match
|
||||
// TODO: maybe reset aExt when it's "xls"
|
||||
}
|
||||
// then on extension if that's not available.
|
||||
|
||||
if (aDocService == CALC_DOCSERVICE)
|
||||
aMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= OUString(CALC_TEXT_FILTER);
|
||||
|
@ -242,8 +193,6 @@ OUString SAL_CALL PlainTextFilterDetect::detect(uno::Sequence<beans::PropertyVal
|
|||
aMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= OUString(WRITER_TEXT_FILTER);
|
||||
else if (aExt == "csv" || aExt == "tsv" || aExt == "tab" || aExt == "xls" || aName.endsWith(".csv.gz"))
|
||||
aMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= OUString(CALC_TEXT_FILTER);
|
||||
else if (bEmpty)
|
||||
aType = aEmptyType; // aMediaDesc is already updated in HandleEmptyFileUrlByExtension
|
||||
else
|
||||
aMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= OUString(WRITER_TEXT_FILTER);
|
||||
}
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in a new issue