22#include <com/sun/star/container/XNameAccess.hpp>
23#include <com/sun/star/drawing/XShape.hpp>
24#include <com/sun/star/frame/XModel.hpp>
25#include <com/sun/star/io/XStream.hpp>
26#include <com/sun/star/lang/XMultiServiceFactory.hpp>
27#include <com/sun/star/task/XInteractionHandler.hpp>
28#include <com/sun/star/task/XStatusIndicator.hpp>
29#include <com/sun/star/uno/XComponentContext.hpp>
35#include <osl/diagnose.h>
60using ::com::sun::star::container::XNameAccess;
62using ::comphelper::SequenceAsHashMap;
63using ::oox::ole::OleObjectHelper;
64using ::oox::ole::VbaProject;
74UrlPool& StaticUrlPool()
76 static UrlPool SINGLETON;
81class DocumentOpenedGuard
84 explicit DocumentOpenedGuard(
const OUString& rUrl );
85 ~DocumentOpenedGuard();
86 DocumentOpenedGuard(
const DocumentOpenedGuard&) =
delete;
87 DocumentOpenedGuard& operator=(
const DocumentOpenedGuard&) =
delete;
89 bool isValid()
const {
return mbValid; }
96DocumentOpenedGuard::DocumentOpenedGuard(
const OUString& rUrl )
98 UrlPool& rUrlPool = StaticUrlPool();
99 std::scoped_lock aGuard( rUrlPool.maMutex );
100 mbValid = rUrl.isEmpty() || (rUrlPool.maUrls.count( rUrl ) == 0);
101 if(
mbValid && !rUrl.isEmpty() )
103 rUrlPool.maUrls.insert( rUrl );
108DocumentOpenedGuard::~DocumentOpenedGuard()
110 UrlPool& rUrlPool = StaticUrlPool();
111 std::scoped_lock aGuard( rUrlPool.maMutex );
112 if( !
maUrl.isEmpty() )
113 rUrlPool.maUrls.erase(
maUrl );
119 FILTERDIRECTION_UNKNOWN,
120 FILTERDIRECTION_IMPORT,
121 FILTERDIRECTION_EXPORT
143 std::map<css::uno::Reference<css::lang::XMultiServiceFactory>,
ModelObjHelperRef>
163 explicit FilterBaseImpl(
const Reference< XComponentContext >& rxContext );
170 meDirection( FILTERDIRECTION_UNKNOWN ),
174 mbExportTemplate(false)
182 mxModel.set( rxComponent, UNO_QUERY_THROW );
187 throw IllegalArgumentException();
202 return mxImpl->meDirection == FILTERDIRECTION_IMPORT;
207 return mxImpl->meDirection == FILTERDIRECTION_EXPORT;
217 return mxImpl->mxComponentContext;
227 return mxImpl->mxModelFactory;
232 return mxImpl->mxTargetFrame;
237 return mxImpl->mxStatusIndicator;
242 return mxImpl->maMediaDesc;
247 return mxImpl->maFilterData;
257bool lclIsDosDrive( std::u16string_view rUrl,
size_t nPos = 0 )
260 (rUrl.size() >= nPos + 3) &&
261 (((
'A' <= rUrl[
nPos ]) && (rUrl[ nPos ] <=
'Z')) || ((
'a' <= rUrl[ nPos ]) && (rUrl[
nPos ] <=
'z'))) &&
262 (rUrl[ nPos + 1 ] ==
':') &&
263 (rUrl[
nPos + 2 ] ==
'/');
272 static constexpr OUStringLiteral aFileSchema =
u"file:";
273 static constexpr OUStringLiteral aFilePrefix =
u"file:///";
274 const sal_Int32 nFilePrefixLen = aFilePrefix.getLength();
275 static constexpr OUStringLiteral aUncPrefix =
u"//";
279 OUString aUrl = rUrl.replace(
'\\',
'/' );
285 if( lclIsDosDrive( aUrl ) )
286 return aFilePrefix + aUrl;
290 if( aUrl.match( aUncPrefix ) )
291 return aFileSchema + aUrl;
295 if( (aUrl.getLength() >= nFilePrefixLen + 2) &&
296 aUrl.match( aFilePrefix ) &&
297 aUrl.match( aUncPrefix, nFilePrefixLen ) )
299 return aFileSchema + aUrl.subView( nFilePrefixLen );
305 if( aUrl.startsWith(
"/") &&
306 mxImpl->maFileUrl.match( aFilePrefix ) &&
307 lclIsDosDrive(
mxImpl->maFileUrl, nFilePrefixLen ) )
309 return OUString::Concat(
mxImpl->maFileUrl.subView( 0, nFilePrefixLen + 3 )) + aUrl.subView( 1 );
314 return ::rtl::Uri::convertRelToAbs(
mxImpl->maFileUrl, aUrl );
316 catch( ::rtl::MalformedUriException& )
331 return mxImpl->mxStorage->openInputStream( rStreamName );
336 return mxImpl->mxStorage->openOutputStream( rStreamName );
341 mxImpl->mxStorage->commit();
348 if( !
mxImpl->mxGraphicHelper )
350 return *
mxImpl->mxGraphicHelper;
355 if( !
mxImpl->mxModelObjHelper )
356 mxImpl->mxModelObjHelper = std::make_shared<ModelObjectHelper>(
mxImpl->mxModelFactory );
357 return *
mxImpl->mxModelObjHelper;
361 const css::uno::Reference<css::lang::XMultiServiceFactory>& xFactory)
const
370 if( !
mxImpl->mxOleObjHelper )
371 mxImpl->mxOleObjHelper = std::make_shared<OleObjectHelper>(
mxImpl->mxModelFactory,
mxImpl->mxModel);
372 return *
mxImpl->mxOleObjHelper;
377 if( !
mxImpl->mxVbaProject )
379 return *
mxImpl->mxVbaProject;
384 OSL_ENSURE( !rStreamName.isEmpty(),
"FilterBase::importBinaryData - empty stream name" );
385 if( rStreamName.isEmpty() )
390 if( aInStrm.
isEof() )
408 return {
"com.sun.star.document.ImportFilter",
"com.sun.star.document.ExportFilter" };
415 if( rArgs.getLength() >= 2 )
try
417 mxImpl->maArguments << rArgs[ 1 ];
423 if (!rArgs.hasElements())
426 Sequence<css::beans::PropertyValue>
aSeq;
428 for (
const auto& rVal : std::as_const(
aSeq))
430 if (rVal.Name ==
"UserData")
432 css::uno::Sequence<OUString> aUserDataSeq;
433 rVal.Value >>= aUserDataSeq;
435 mxImpl->mbExportVBA =
true;
437 else if (rVal.Name ==
"Flags")
440 rVal.Value >>= nFlags;
441 mxImpl->mbExportTemplate = bool(
static_cast<SfxFilterFlags>(nFlags) & SfxFilterFlags::TEMPLATE);
450 mxImpl->setDocumentModel( rxDocument );
451 mxImpl->meDirection = FILTERDIRECTION_IMPORT;
458 mxImpl->setDocumentModel( rxDocument );
459 mxImpl->meDirection = FILTERDIRECTION_EXPORT;
466 if( !
mxImpl->mxModel.is() || !
mxImpl->mxModelFactory.is() || (
mxImpl->meDirection == FILTERDIRECTION_UNKNOWN) )
471 DocumentOpenedGuard aOpenedGuard(
mxImpl->maFileUrl );
472 if( aOpenedGuard.isValid() ||
mxImpl->maFileUrl.isEmpty() )
474 Reference<XModel> xTempModel =
mxImpl->mxModel;
475 xTempModel->lockControllers();
477 xTempModel->unlockControllers();
480 switch(
mxImpl->meDirection )
482 case FILTERDIRECTION_UNKNOWN:
484 case FILTERDIRECTION_IMPORT:
485 if(
mxImpl->mxInStream.is() )
491 case FILTERDIRECTION_EXPORT:
492 if(
mxImpl->mxOutStream.is() )
526 return mxImpl->mxOutStream;
533 mxImpl->maMediaDesc << rMediaDescSeq;
535 switch(
mxImpl->meDirection )
537 case FILTERDIRECTION_UNKNOWN:
538 OSL_FAIL(
"FilterBase::setMediaDescriptor - invalid filter direction" );
540 case FILTERDIRECTION_IMPORT:
541 mxImpl->maMediaDesc.addInputStream();
543 OSL_ENSURE(
mxImpl->mxInStream.is(),
"FilterBase::setMediaDescriptor - missing input stream" );
545 case FILTERDIRECTION_EXPORT:
547 OSL_ENSURE(
mxImpl->mxOutStream.is(),
"FilterBase::setMediaDescriptor - missing output stream" );
555 mxImpl->mxParentShape =
mxImpl->maMediaDesc.getUnpackedValueOrDefault(
"ParentShape",
mxImpl->mxParentShape );
556 mxImpl->maFilterData =
mxImpl->maMediaDesc.getUnpackedValueOrDefault(
"FilterData", Sequence< PropertyValue >() );
559 OUString sFilterName =
mxImpl->maMediaDesc.getUnpackedValueOrDefault(
"FilterName", OUString() );
563 Reference<XNameAccess> xFilters(
xFactory->createInstance(
"com.sun.star.document.FilterFactory" ), UNO_QUERY_THROW );
564 Any aValues = xFilters->getByName( sFilterName );
565 Sequence<PropertyValue > aPropSeq;
566 aValues >>= aPropSeq;
567 SequenceAsHashMap aProps( aPropSeq );
569 sal_Int32
nVersion = aProps.getUnpackedValueOrDefault(
"FileFormatVersion", sal_Int32( 0 ) );
586 return mxImpl->mbExportVBA;
591 return mxImpl->mbExportTemplate;
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
bool isEof() const
Returns true, if the stream position is invalid (EOF).
Provides helper functions for colors, device measurement conversion, graphics, and graphic objects ha...
Contains tables for named drawing objects for a document model.
Wraps a StreamDataSequence and provides convenient access functions.
::comphelper::SequenceAsHashMap & getFilterData() const
Returns the FilterData.
bool importBinaryData(StreamDataSequence &orDataSeq, const OUString &rStreamName)
Imports the raw binary data from the specified stream.
const OUString & getFileUrl() const
Returns the URL of the imported or exported file.
bool isExportFilter() const
Returns true, if filter is an export filter.
void setMediaDescriptor(const css::uno::Sequence< css::beans::PropertyValue > &rMediaDescSeq)
utl::MediaDescriptor & getMediaDescriptor() const
Returns the media descriptor.
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
OUString getAbsoluteUrl(const OUString &rUrl) const
Returns an absolute URL for the passed relative or absolute URL.
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &rArgs) override
Receives user defined arguments.
virtual bool importDocument()=0
Derived classes implement import of the entire document.
virtual ~FilterBase() override
virtual bool exportDocument()=0
Derived classes implement export of the entire document.
virtual void SAL_CALL setTargetDocument(const css::uno::Reference< css::lang::XComponent > &rxDocument) override
const css::uno::Reference< css::frame::XModel > & getModel() const
Returns the document model (always existing).
bool isImportFilter() const
Returns true, if filter is an import filter.
::oox::ole::VbaProject & getVbaProject() const
Returns the VBA project manager.
OoxmlVersion getVersion() const
void commitStorage() const
Commits changes to base storage (and substorages)
const css::uno::Reference< css::lang::XMultiServiceFactory > & getModelFactory() const
Returns the service factory provided by the document model (always existing).
const css::uno::Reference< css::task::XStatusIndicator > & getStatusIndicator() const
Returns the status indicator (may be null).
std::unique_ptr< FilterBaseImpl > mxImpl
css::uno::Reference< css::io::XInputStream > openInputStream(const OUString &rStreamName) const
Opens and returns the specified input stream from the base storage.
virtual css::uno::Reference< css::io::XStream > implGetOutputStream(utl::MediaDescriptor &rMediaDesc) const
::oox::ole::OleObjectHelper & getOleObjectHelper() const
Returns a helper for the handling of OLE objects.
bool isExportTemplate() const
GraphicHelper & getGraphicHelper() const
Returns a helper for the handling of graphics and graphic objects.
ModelObjectHelper & getModelObjectHelperForModel(const css::uno::Reference< css::lang::XMultiServiceFactory > &xFactory) const
ModelObjectHelper & getModelObjectHelper() const
Returns a helper with containers for various named drawing objects for the imported document.
virtual ::oox::ole::VbaProject * implCreateVbaProject() const =0
Derived classes create a VBA project manager object.
virtual GraphicHelper * implCreateGraphicHelper() const
Derived classes may create a specialized graphic helper, e.g.
virtual sal_Bool SAL_CALL filter(const css::uno::Sequence< css::beans::PropertyValue > &rMediaDescSeq) override
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
const css::uno::Reference< css::uno::XComponentContext > & getComponentContext() const
Returns the component context passed in the filter constructor (always existing).
FilterBase(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
virtual bool implFinalizeExport(utl::MediaDescriptor &rMediaDescriptor)
css::uno::Reference< css::io::XStream > const & getMainDocumentStream() const
css::uno::Reference< css::io::XOutputStream > openOutputStream(const OUString &rStreamName) const
Opens and returns the specified output stream from the base storage.
virtual void SAL_CALL cancel() override
StorageRef const & getStorage() const
Returns the base storage of the imported/exported file.
virtual StorageRef implCreateStorage(const css::uno::Reference< css::io::XInputStream > &rxInStream) const =0
const css::uno::Reference< css::frame::XFrame > & getTargetFrame() const
Returns the frame that will contain the document model (may be null).
virtual css::uno::Reference< css::io::XInputStream > implGetInputStream(utl::MediaDescriptor &rMediaDesc) const
virtual void SAL_CALL setSourceDocument(const css::uno::Reference< css::lang::XComponent > &rxDocument) override
Reference< XSingleServiceFactory > xFactory
::std::set< OUString > maUrls
Sequence< sal_Int8 > aSeq
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
@ ECMA_376_1ST_EDITION
There are currently 5 editions of ECMA-376, latest is from 2021.
std::shared_ptr< StorageBase > StorageRef
css::uno::Sequence< sal_Int8 > StreamDataSequence
FilterDirection meDirection
Reference< XMultiServiceFactory > mxModelFactory
MediaDescriptor maMediaDesc
std::shared_ptr< VbaProject > VbaProjectRef
ModelObjHelperRef mxModelObjHelper
Graphic and graphic object handling.
std::shared_ptr< ModelObjectHelper > ModelObjHelperRef
Reference< XFrame > mxTargetFrame
std::shared_ptr< OleObjectHelper > OleObjHelperRef
Reference< XInputStream > mxInStream
OleObjHelperRef mxOleObjHelper
FilterBaseImpl(const Reference< XComponentContext > &rxContext)
SequenceAsHashMap maArguments
Reference< XStream > mxOutStream
VbaProjectRef mxVbaProject
OLE object handling.
Reference< XComponentContext > mxComponentContext
VBA project manager.
std::map< css::uno::Reference< css::lang::XMultiServiceFactory >, ModelObjHelperRef > mxModelObjHelpers
Tables to create new named drawing objects.
Reference< XInteractionHandler > mxInteractionHandler
void setDocumentModel(const Reference< XComponent > &rxComponent)
GraphicHelperRef mxGraphicHelper
Reference< XShape > mxParentShape
std::shared_ptr< GraphicHelper > GraphicHelperRef
Reference< XModel > mxModel
SequenceAsHashMap maFilterData
Reference< XStatusIndicator > mxStatusIndicator