1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/container/XNameContainer.hpp>
21 #include <com/sun/star/xml/sax/Parser.hpp>
22 #include <com/sun/star/xml/sax/InputSource.hpp>
23 #include <com/sun/star/xml/sax/Writer.hpp>
24 #include <com/sun/star/io/XOutputStream.hpp>
25 #include <com/sun/star/io/XInputStream.hpp>
26 #include <com/sun/star/embed/ElementModes.hpp>
27 #include <com/sun/star/ucb/XSimpleFileAccess2.hpp>
28 #include <com/sun/star/io/XActiveDataSource.hpp>
29 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
30 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
31 #include "com/sun/star/resource/XStringResourceWithStorage.hpp"
32 #include "com/sun/star/resource/XStringResourceWithLocation.hpp"
33 #include "com/sun/star/document/XGraphicObjectResolver.hpp"
34 #include "dlgcont.hxx"
35 #include "sbmodule.hxx"
36 #include <comphelper/componentcontext.hxx>
37 #include <comphelper/processfactory.hxx>
38 #include <unotools/streamwrap.hxx>
39 #include <osl/mutex.hxx>
41 #include <vcl/svapp.hxx>
42 #include <vcl/settings.hxx>
43 #include <unotools/pathoptions.hxx>
44 #include <xmlscript/xmldlg_imexp.hxx>
45 #include <cppuhelper/factory.hxx>
46 #include <svtools/sfxecode.hxx>
47 #include <svtools/ehdl.hxx>
48 #include <svtools/grfmgr.hxx>
53 using namespace com::sun::star::document
;
54 using namespace com::sun::star::container
;
55 using namespace com::sun::star::io
;
56 using namespace com::sun::star::uno
;
57 using namespace com::sun::star::ucb
;
58 using namespace com::sun::star::lang
;
59 using namespace com::sun::star::script
;
60 using namespace com::sun::star::xml::sax
;
61 using namespace com::sun::star
;
65 using ::rtl::OUString
;
67 using com::sun::star::uno::Reference
;
69 //============================================================================
70 // Implementation class SfxDialogLibraryContainer
72 const sal_Char
* SAL_CALL
SfxDialogLibraryContainer::getInfoFileName() const { return "dialog"; }
73 const sal_Char
* SAL_CALL
SfxDialogLibraryContainer::getOldInfoFileName() const { return "dialogs"; }
74 const sal_Char
* SAL_CALL
SfxDialogLibraryContainer::getLibElementFileExtension() const { return "xdl"; }
75 const sal_Char
* SAL_CALL
SfxDialogLibraryContainer::getLibrariesDir() const { return "Dialogs"; }
78 SfxDialogLibraryContainer::SfxDialogLibraryContainer( void )
80 // all initialisation has to be done
81 // by calling XInitialization::initialize
84 SfxDialogLibraryContainer::SfxDialogLibraryContainer( const uno::Reference
< embed::XStorage
>& xStorage
)
86 init( OUString(), xStorage
);
89 // Methods to get library instances of the correct type
90 SfxLibrary
* SfxDialogLibraryContainer::implCreateLibrary( const ::rtl::OUString
& aName
)
92 SfxLibrary
* pRet
= new SfxDialogLibrary( maModifiable
, aName
, mxMSF
, mxSFI
, this );
96 SfxLibrary
* SfxDialogLibraryContainer::implCreateLibraryLink
97 ( const ::rtl::OUString
& aName
, const OUString
& aLibInfoFileURL
,
98 const OUString
& StorageURL
, sal_Bool ReadOnly
)
100 SfxLibrary
* pRet
= new SfxDialogLibrary
101 ( maModifiable
, aName
, mxMSF
, mxSFI
, aLibInfoFileURL
, StorageURL
, ReadOnly
, this );
105 Any SAL_CALL
SfxDialogLibraryContainer::createEmptyLibraryElement( void )
107 Reference
< XInputStreamProvider
> xISP
;
113 bool SAL_CALL
SfxDialogLibraryContainer::isLibraryElementValid( Any aElement
) const
115 return SfxDialogLibrary::containsValidDialog( aElement
);
118 bool writeOasis2OOoLibraryElement(
119 Reference
< XInputStream
> xInput
, Reference
< XOutputStream
> xOutput
)
121 Reference
< XComponentContext
> xContext(
122 comphelper::getProcessComponentContext() );
124 Reference
< lang::XMultiComponentFactory
> xSMgr(
125 xContext
->getServiceManager() );
127 Reference
< xml::sax::XParser
> xParser
= xml::sax::Parser::create(xContext
);
129 Reference
< xml::sax::XWriter
> xWriter
= xml::sax::Writer::create(xContext
);
131 xWriter
->setOutputStream( xOutput
);
133 Sequence
<Any
> aArgs( 1 );
134 aArgs
[0] <<= xWriter
;
136 Reference
< xml::sax::XDocumentHandler
> xHandler(
137 xSMgr
->createInstanceWithArgumentsAndContext(
138 OUString( RTL_CONSTASCII_USTRINGPARAM(
139 "com.sun.star.comp.Oasis2OOoTransformer" ) ),
143 xParser
->setDocumentHandler( xHandler
);
145 xml::sax::InputSource source
;
146 source
.aInputStream
= xInput
;
147 source
.sSystemId
= OUString(RTL_CONSTASCII_USTRINGPARAM("virtual file"));
149 xParser
->parseStream( source
);
154 void SAL_CALL
SfxDialogLibraryContainer::writeLibraryElement
156 const Reference
< XNameContainer
>& xLib
,
157 const OUString
& aElementName
,
158 const Reference
< XOutputStream
>& xOutput
162 Any aElement
= xLib
->getByName( aElementName
);
163 Reference
< XInputStreamProvider
> xISP
;
168 Reference
< XInputStream
> xInput( xISP
->createInputStream() );
170 bool bComplete
= false;
171 if ( mbOasis2OOoFormat
)
173 bComplete
= writeOasis2OOoLibraryElement( xInput
, xOutput
);
176 if ( bComplete
== sal_False
)
178 Sequence
< sal_Int8
> bytes
;
179 sal_Int32 nRead
= xInput
->readBytes( bytes
, xInput
->available() );
183 xOutput
->writeBytes( bytes
);
185 nRead
= xInput
->readBytes( bytes
, 1024 );
190 xInput
->closeInput();
193 void SfxDialogLibraryContainer::storeLibrariesToStorage( const uno::Reference
< embed::XStorage
>& xStorage
) throw ( RuntimeException
)
195 LibraryContainerMethodGuard
aGuard( *this );
196 mbOasis2OOoFormat
= false;
198 if ( mxStorage
.is() && xStorage
.is() )
202 long nSource
= SotStorage::GetVersion( mxStorage
);
203 long nTarget
= SotStorage::GetVersion( xStorage
);
205 if ( nSource
== SOFFICE_FILEFORMAT_CURRENT
&&
206 nTarget
!= SOFFICE_FILEFORMAT_CURRENT
)
208 mbOasis2OOoFormat
= true;
211 catch (const Exception
& )
213 // if we cannot get the version then the
214 // Oasis2OOoTransformer will not be used
215 OSL_ASSERT(sal_False
);
219 SfxLibraryContainer::storeLibrariesToStorage( xStorage
);
221 // we need to export out any embedded image object(s)
222 // associated with any Dialogs. First, we need to actually gather any such urls
223 // for each dialog in this container
224 Sequence
< OUString
> sLibraries
= getElementNames();
225 for ( sal_Int32 i
=0; i
< sLibraries
.getLength(); ++i
)
227 loadLibrary( sLibraries
[ i
] );
228 Reference
< XNameContainer
> xLib
;
229 getByName( sLibraries
[ i
] ) >>= xLib
;
232 Sequence
< OUString
> sDialogs
= xLib
->getElementNames();
233 sal_Int32
nDialogs( sDialogs
.getLength() );
234 for ( sal_Int32 j
=0; j
< nDialogs
; ++j
)
236 // Each Dialog has an associated xISP
237 Reference
< io::XInputStreamProvider
> xISP
;
238 xLib
->getByName( sDialogs
[ j
] ) >>= xISP
;
241 Reference
< io::XInputStream
> xInput( xISP
->createInputStream() );
242 Reference
< XNameContainer
> xDialogModel( mxMSF
->createInstance
243 ( OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialogModel" ) ) ), UNO_QUERY
);
244 Reference
< XComponentContext
> xContext(
245 comphelper::getComponentContext( mxMSF
) );
246 ::xmlscript::importDialogModel( xInput
, xDialogModel
, xContext
, mxOwnerDocument
);
247 std::vector
< rtl::OUString
> vEmbeddedImageURLs
;
248 GraphicObject::InspectForGraphicObjectImageURL( Reference
< XInterface
>( xDialogModel
, UNO_QUERY
), vEmbeddedImageURLs
);
249 if ( !vEmbeddedImageURLs
.empty() )
251 // Export the images to the storage
252 Sequence
< Any
> aArgs( 1 );
253 aArgs
[ 0 ] <<= xStorage
;
254 Reference
< document::XGraphicObjectResolver
> xGraphicResolver( mxMSF
->createInstanceWithArguments( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Svx.GraphicExportHelper" ) ), aArgs
), UNO_QUERY
);
255 std::vector
< rtl::OUString
>::iterator it
= vEmbeddedImageURLs
.begin();
256 std::vector
< rtl::OUString
>::iterator it_end
= vEmbeddedImageURLs
.end();
257 if ( xGraphicResolver
.is() )
259 for ( sal_Int32 count
= 0; it
!= it_end
; ++it
, ++count
)
260 xGraphicResolver
->resolveGraphicObjectURL( *it
);
267 mbOasis2OOoFormat
= false;
271 Any SAL_CALL
SfxDialogLibraryContainer::importLibraryElement
272 ( const Reference
< XNameContainer
>& /*xLib*/,
273 const OUString
& /*aElementName */, const OUString
& aFile
,
274 const uno::Reference
< io::XInputStream
>& xElementStream
)
278 // TODO: Member because later it will be a component
279 //Reference< XMultiServiceFactory > xMSF( comphelper::getProcessServiceFactory() );
282 // OSL_FAIL( "### couldn't get ProcessServiceFactory\n" );
286 Reference
< XParser
> xParser
= xml::sax::Parser::create( comphelper::getComponentContext(mxMSF
) );
288 Reference
< XNameContainer
> xDialogModel( mxMSF
->createInstance
289 ( OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialogModel" ) ) ), UNO_QUERY
);
290 if( !xDialogModel
.is() )
292 OSL_FAIL( "### couldn't create com.sun.star.awt.UnoControlDialogModel component\n" );
296 // Read from storage?
297 sal_Bool bStorage
= xElementStream
.is();
298 Reference
< XInputStream
> xInput
;
302 xInput
= xElementStream
;
308 xInput
= mxSFI
->openFileRead( aFile
);
310 catch(const Exception
& )
311 //catch( Exception& e )
314 //throw WrappedTargetException( e );
320 Reference
< XComponentContext
> xContext(
321 comphelper::getComponentContext( mxMSF
) );
324 source
.aInputStream
= xInput
;
325 source
.sSystemId
= aFile
;
329 xParser
->setDocumentHandler( ::xmlscript::importDialogModel( xDialogModel
, xContext
, mxOwnerDocument
) );
330 xParser
->parseStream( source
);
332 catch(const Exception
& )
334 OSL_FAIL( "Parsing error\n" );
335 SfxErrorContext
aEc( ERRCTX_SFX_LOADBASIC
, aFile
);
336 sal_uIntPtr nErrorCode
= ERRCODE_IO_GENERAL
;
337 ErrorHandler::HandleError( nErrorCode
);
341 // Create InputStream, TODO: Implement own InputStreamProvider
342 // to avoid creating the DialogModel here!
343 Reference
< XInputStreamProvider
> xISP
= ::xmlscript::exportDialogModel( xDialogModel
, xContext
, mxOwnerDocument
);
348 void SAL_CALL
SfxDialogLibraryContainer::importFromOldStorage( const OUString
& )
350 // Nothing to do here, old dialogs cannot be imported
353 SfxLibraryContainer
* SfxDialogLibraryContainer::createInstanceImpl( void )
355 return new SfxDialogLibraryContainer();
358 const char aResourceFileNameBase
[] = "DialogStrings";
359 const char aResourceFileCommentBase
[] = "# Strings for Dialog Library ";
362 Reference
< ::com::sun::star::resource::XStringResourcePersistence
>
363 SfxDialogLibraryContainer::implCreateStringResource( SfxDialogLibrary
* pDialogLibrary
)
365 Reference
< resource::XStringResourcePersistence
> xRet
;
366 OUString aLibName
= pDialogLibrary
->getName();
367 bool bReadOnly
= pDialogLibrary
->mbReadOnly
;
370 ::com::sun ::star::lang::Locale aLocale
= Application::GetSettings().GetUILanguageTag().getLocale();
372 OUString
aComment(aResourceFileCommentBase
);
373 aComment
+= aLibName
;
375 sal_Bool bStorage
= mxStorage
.is();
378 Sequence
<Any
> aArgs( 5 );
379 aArgs
[1] <<= bReadOnly
;
380 aArgs
[2] <<= aLocale
;
381 aArgs
[3] <<= rtl::OUString(aResourceFileNameBase
);
382 aArgs
[4] <<= aComment
;
385 xRet
= Reference
< resource::XStringResourcePersistence
>( mxMSF
->createInstance
386 ( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.resource.StringResourceWithStorage")) ), UNO_QUERY
);
388 uno::Reference
< embed::XStorage
> xLibrariesStor
;
389 uno::Reference
< embed::XStorage
> xLibraryStor
;
391 xLibrariesStor
= mxStorage
->openStorageElement( maLibrariesDir
, embed::ElementModes::READ
);
392 // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
393 if ( !xLibrariesStor
.is() )
394 throw uno::RuntimeException();
396 xLibraryStor
= xLibrariesStor
->openStorageElement( aLibName
, embed::ElementModes::READ
);
397 // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
398 if ( !xLibraryStor
.is() )
399 throw uno::RuntimeException();
401 aArgs
[0] <<= xLibraryStor
;
403 catch(const uno::Exception
& )
405 // TODO: Error handling?
412 Reference
< XInitialization
> xInit( xRet
, UNO_QUERY
);
414 xInit
->initialize( aArgs
);
419 Sequence
<Any
> aArgs( 6 );
421 OUString aLocation
= createAppLibraryFolder( pDialogLibrary
, aLibName
);
422 aArgs
[0] <<= aLocation
;
423 aArgs
[1] <<= bReadOnly
;
424 aArgs
[2] <<= aLocale
;
425 aArgs
[3] <<= rtl::OUString(aResourceFileNameBase
);
426 aArgs
[4] <<= aComment
;
428 // TODO: Real handler?
429 Reference
< task::XInteractionHandler
> xDummyHandler
;
430 aArgs
[5] <<= xDummyHandler
;
433 xRet
= Reference
< resource::XStringResourcePersistence
>( mxMSF
->createInstance
434 ( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.resource.StringResourceWithLocation")) ), UNO_QUERY
);
439 Reference
< XInitialization
> xInit( xRet
, UNO_QUERY
);
441 xInit
->initialize( aArgs
);
448 void SfxDialogLibraryContainer::onNewRootStorage()
450 // the library container is not modified, go through the libraries and check whether they are modified
451 Sequence
< OUString
> aNames
= maNameContainer
.getElementNames();
452 const OUString
* pNames
= aNames
.getConstArray();
453 sal_Int32 nNameCount
= aNames
.getLength();
455 for( sal_Int32 i
= 0 ; i
< nNameCount
; i
++ )
457 OUString aName
= pNames
[ i
];
458 SfxDialogLibrary
* pDialogLibrary
= static_cast<SfxDialogLibrary
*>( getImplLib( aName
) );
460 Reference
< resource::XStringResourcePersistence
> xStringResourcePersistence
=
461 pDialogLibrary
->getStringResourcePersistence();
463 if( xStringResourcePersistence
.is() )
465 Reference
< embed::XStorage
> xLibrariesStor
;
466 Reference
< embed::XStorage
> xLibraryStor
;
468 xLibrariesStor
= mxStorage
->openStorageElement( maLibrariesDir
, embed::ElementModes::READWRITE
);
469 if ( !xLibrariesStor
.is() )
470 throw uno::RuntimeException();
472 OUString aLibName
= pDialogLibrary
->getName();
473 xLibraryStor
= xLibrariesStor
->openStorageElement( aLibName
, embed::ElementModes::READWRITE
);
474 if ( !xLibraryStor
.is() )
475 throw uno::RuntimeException();
477 Reference
< resource::XStringResourceWithStorage
>
478 xStringResourceWithStorage( xStringResourcePersistence
, UNO_QUERY
);
479 if( xStringResourceWithStorage
.is() )
480 xStringResourceWithStorage
->setStorage( xLibraryStor
);
482 catch(const uno::Exception
& )
484 // TODO: Error handling?
491 SfxDialogLibraryContainer:: HasExecutableCode( const ::rtl::OUString
& /*Library*/ ) throw (uno::RuntimeException
)
493 return sal_False
; // dialog library has no executable code
495 //============================================================================
498 void createRegistryInfo_SfxDialogLibraryContainer()
500 static OAutoRegistration
< SfxDialogLibraryContainer
> aAutoRegistration
;
503 ::rtl::OUString SAL_CALL
SfxDialogLibraryContainer::getImplementationName( ) throw (RuntimeException
)
505 return getImplementationName_static();
508 Sequence
< ::rtl::OUString
> SAL_CALL
SfxDialogLibraryContainer::getSupportedServiceNames( ) throw (RuntimeException
)
510 return getSupportedServiceNames_static();
513 Sequence
< OUString
> SfxDialogLibraryContainer::getSupportedServiceNames_static()
515 Sequence
< OUString
> aServiceNames( 2 );
516 aServiceNames
[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.DocumentDialogLibraryContainer"));
517 // plus, for compatibility:
518 aServiceNames
[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.DialogLibraryContainer"));
519 return aServiceNames
;
522 OUString
SfxDialogLibraryContainer::getImplementationName_static()
524 return OUString("com.sun.star.comp.sfx2.DialogLibraryContainer");
527 Reference
< XInterface
> SAL_CALL
SfxDialogLibraryContainer::Create( const Reference
< XComponentContext
>& ) throw( Exception
)
529 Reference
< XInterface
> xRet
=
530 static_cast< XInterface
* >( static_cast< OWeakObject
* >(new SfxDialogLibraryContainer()) );
535 //============================================================================
536 // Implementation class SfxDialogLibrary
539 SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper
& _rModifiable
,
540 const ::rtl::OUString
& aName
,
541 const Reference
< XMultiServiceFactory
>& xMSF
,
542 const Reference
< XSimpleFileAccess3
>& xSFI
,
543 SfxDialogLibraryContainer
* pParent
)
544 : SfxLibrary( _rModifiable
, getCppuType( (const Reference
< XInputStreamProvider
> *)0 ), xMSF
, xSFI
)
545 , m_pParent( pParent
)
550 SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper
& _rModifiable
,
551 const ::rtl::OUString
& aName
,
552 const Reference
< XMultiServiceFactory
>& xMSF
,
553 const Reference
< XSimpleFileAccess3
>& xSFI
,
554 const OUString
& aLibInfoFileURL
,
555 const OUString
& aStorageURL
,
557 SfxDialogLibraryContainer
* pParent
)
558 : SfxLibrary( _rModifiable
, getCppuType( (const Reference
< XInputStreamProvider
> *)0 ),
559 xMSF
, xSFI
, aLibInfoFileURL
, aStorageURL
, ReadOnly
)
560 , m_pParent( pParent
)
565 IMPLEMENT_FORWARD_XINTERFACE2( SfxDialogLibrary
, SfxLibrary
, SfxDialogLibrary_BASE
);
566 IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxDialogLibrary
, SfxLibrary
, SfxDialogLibrary_BASE
);
568 // Provide modify state including resources
569 sal_Bool
SfxDialogLibrary::isModified( void )
571 sal_Bool bRet
= implIsModified();
573 if( !bRet
&& m_xStringResourcePersistence
.is() )
574 bRet
= m_xStringResourcePersistence
->isModified();
575 // else: Resources not accessed so far -> not modified
580 void SfxDialogLibrary::storeResources( void )
582 if( m_xStringResourcePersistence
.is() )
583 m_xStringResourcePersistence
->store();
586 void SfxDialogLibrary::storeResourcesAsURL
587 ( const ::rtl::OUString
& URL
, const ::rtl::OUString
& NewName
)
589 OUString
aComment(aResourceFileCommentBase
);
593 if( m_xStringResourcePersistence
.is() )
595 m_xStringResourcePersistence
->setComment( aComment
);
597 Reference
< resource::XStringResourceWithLocation
>
598 xStringResourceWithLocation( m_xStringResourcePersistence
, UNO_QUERY
);
599 if( xStringResourceWithLocation
.is() )
600 xStringResourceWithLocation
->storeAsURL( URL
);
604 void SfxDialogLibrary::storeResourcesToURL( const OUString
& URL
,
605 const Reference
< task::XInteractionHandler
>& xHandler
)
607 OUString
aComment(aResourceFileCommentBase
);
610 if( m_xStringResourcePersistence
.is() )
612 m_xStringResourcePersistence
->storeToURL
613 ( URL
, rtl::OUString(aResourceFileNameBase
), aComment
, xHandler
);
617 void SfxDialogLibrary::storeResourcesToStorage( const ::com::sun::star::uno::Reference
618 < ::com::sun::star::embed::XStorage
>& xStorage
)
620 OUString
aComment(aResourceFileCommentBase
);
623 if( m_xStringResourcePersistence
.is() )
625 m_xStringResourcePersistence
->storeToStorage
626 ( xStorage
, rtl::OUString(aResourceFileNameBase
), aComment
);
631 // XStringResourceSupplier
632 Reference
< resource::XStringResourceResolver
>
633 SAL_CALL
SfxDialogLibrary::getStringResource( ) throw (RuntimeException
)
635 if( !m_xStringResourcePersistence
.is() )
636 m_xStringResourcePersistence
= m_pParent
->implCreateStringResource( this );
638 Reference
< resource::XStringResourceResolver
> xRet( m_xStringResourcePersistence
, UNO_QUERY
);
642 bool SfxDialogLibrary::containsValidDialog( const ::com::sun::star::uno::Any
& aElement
)
644 Reference
< XInputStreamProvider
> xISP
;
649 bool SAL_CALL
SfxDialogLibrary::isLibraryElementValid( ::com::sun::star::uno::Any aElement
) const
651 return SfxDialogLibrary::containsValidDialog( aElement
);
656 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */