1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dlgcont.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
33 #include <com/sun/star/container/XNameContainer.hpp>
34 #include <com/sun/star/xml/sax/XParser.hpp>
35 #include <com/sun/star/xml/sax/InputSource.hpp>
36 #include <com/sun/star/io/XOutputStream.hpp>
37 #include <com/sun/star/io/XInputStream.hpp>
38 #include <com/sun/star/embed/ElementModes.hpp>
39 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/io/XActiveDataSource.hpp>
42 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
43 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
44 #include "com/sun/star/resource/XStringResourceWithStorage.hpp"
45 #include "com/sun/star/resource/XStringResourceWithLocation.hpp"
46 #include "dlgcont.hxx"
47 #include "sbmodule.hxx"
48 #include <comphelper/processfactory.hxx>
49 #include <unotools/streamwrap.hxx>
50 #include <osl/mutex.hxx>
52 #include <vcl/svapp.hxx>
53 #include <vcl/settings.hxx>
54 #include <svtools/pathoptions.hxx>
55 #include <xmlscript/xmldlg_imexp.hxx>
56 #include <cppuhelper/factory.hxx>
57 #include <svtools/sfxecode.hxx>
58 #include <svtools/ehdl.hxx>
64 using namespace com::sun::star::document
;
65 using namespace com::sun::star::container
;
66 using namespace com::sun::star::io
;
67 using namespace com::sun::star::uno
;
68 using namespace com::sun::star::ucb
;
69 using namespace com::sun::star::lang
;
70 using namespace com::sun::star::script
;
71 using namespace com::sun::star::xml::sax
;
72 using namespace com::sun::star
;
77 using com::sun::star::uno::Reference
;
79 //============================================================================
80 // Implementation class SfxDialogLibraryContainer
82 const sal_Char
* SAL_CALL
SfxDialogLibraryContainer::getInfoFileName() const { return "dialog"; }
83 const sal_Char
* SAL_CALL
SfxDialogLibraryContainer::getOldInfoFileName() const { return "dialogs"; }
84 const sal_Char
* SAL_CALL
SfxDialogLibraryContainer::getLibElementFileExtension() const { return "xdl"; }
85 const sal_Char
* SAL_CALL
SfxDialogLibraryContainer::getLibrariesDir() const { return "Dialogs"; }
88 SfxDialogLibraryContainer::SfxDialogLibraryContainer( void )
90 // all initialisation has to be done
91 // by calling XInitialization::initialize
94 SfxDialogLibraryContainer::SfxDialogLibraryContainer( const uno::Reference
< embed::XStorage
>& xStorage
)
96 init( OUString(), xStorage
);
99 // Methods to get library instances of the correct type
100 SfxLibrary
* SfxDialogLibraryContainer::implCreateLibrary( const ::rtl::OUString
& aName
)
102 SfxLibrary
* pRet
= new SfxDialogLibrary( maModifiable
, aName
, mxMSF
, mxSFI
, this );
106 SfxLibrary
* SfxDialogLibraryContainer::implCreateLibraryLink
107 ( const ::rtl::OUString
& aName
, const OUString
& aLibInfoFileURL
,
108 const OUString
& StorageURL
, sal_Bool ReadOnly
)
110 SfxLibrary
* pRet
= new SfxDialogLibrary
111 ( maModifiable
, aName
, mxMSF
, mxSFI
, aLibInfoFileURL
, StorageURL
, ReadOnly
, this );
115 Any SAL_CALL
SfxDialogLibraryContainer::createEmptyLibraryElement( void )
117 Reference
< XInputStreamProvider
> xISP
;
123 bool SAL_CALL
SfxDialogLibraryContainer::isLibraryElementValid( Any aElement
) const
125 return SfxDialogLibrary::containsValidDialog( aElement
);
128 bool writeOasis2OOoLibraryElement(
129 Reference
< XInputStream
> xInput
, Reference
< XOutputStream
> xOutput
)
131 Reference
< XMultiServiceFactory
> xMSF(
132 comphelper::getProcessServiceFactory() );
134 Reference
< XComponentContext
> xContext
;
135 Reference
< beans::XPropertySet
> xProps( xMSF
, UNO_QUERY
);
136 OSL_ASSERT( xProps
.is() );
137 OSL_VERIFY( xProps
->getPropertyValue(
138 OUString::createFromAscii(("DefaultContext")) ) >>= xContext
);
140 Reference
< lang::XMultiComponentFactory
> xSMgr(
141 xContext
->getServiceManager() );
148 Reference
< xml::sax::XParser
> xParser(
149 xSMgr
->createInstanceWithContext(
150 OUString( RTL_CONSTASCII_USTRINGPARAM(
151 "com.sun.star.xml.sax.Parser" ) ),
155 Reference
< xml::sax::XExtendedDocumentHandler
> xWriter(
156 xSMgr
->createInstanceWithContext(
157 OUString( RTL_CONSTASCII_USTRINGPARAM(
158 "com.sun.star.xml.sax.Writer" ) ),
162 Reference
< io::XActiveDataSource
> xSource( xWriter
, UNO_QUERY
);
163 xSource
->setOutputStream( xOutput
);
165 if ( !xParser
.is() || !xWriter
.is() )
170 Sequence
<Any
> aArgs( 1 );
171 aArgs
[0] <<= xWriter
;
173 Reference
< xml::sax::XDocumentHandler
> xHandler(
174 xSMgr
->createInstanceWithArgumentsAndContext(
175 OUString( RTL_CONSTASCII_USTRINGPARAM(
176 "com.sun.star.comp.Oasis2OOoTransformer" ) ),
180 xParser
->setDocumentHandler( xHandler
);
182 xml::sax::InputSource source
;
183 source
.aInputStream
= xInput
;
184 source
.sSystemId
= OUString::createFromAscii( "virtual file" );
186 xParser
->parseStream( source
);
191 void SAL_CALL
SfxDialogLibraryContainer::writeLibraryElement
194 const OUString
& /*aElementName*/,
195 Reference
< XOutputStream
> xOutput
199 Reference
< XInputStreamProvider
> xISP
;
204 Reference
< XInputStream
> xInput( xISP
->createInputStream() );
206 bool bComplete
= FALSE
;
207 if ( mbOasis2OOoFormat
)
209 bComplete
= writeOasis2OOoLibraryElement( xInput
, xOutput
);
212 if ( bComplete
== FALSE
)
214 Sequence
< sal_Int8
> bytes
;
215 sal_Int32 nRead
= xInput
->readBytes( bytes
, xInput
->available() );
219 xOutput
->writeBytes( bytes
);
221 nRead
= xInput
->readBytes( bytes
, 1024 );
226 xInput
->closeInput();
229 void SfxDialogLibraryContainer::storeLibrariesToStorage( const uno::Reference
< embed::XStorage
>& xStorage
) throw ( RuntimeException
)
231 LibraryContainerMethodGuard
aGuard( *this );
232 mbOasis2OOoFormat
= sal_False
;
234 if ( mxStorage
.is() && xStorage
.is() )
238 long nSource
= SotStorage::GetVersion( mxStorage
);
239 long nTarget
= SotStorage::GetVersion( xStorage
);
241 if ( nSource
== SOFFICE_FILEFORMAT_CURRENT
&&
242 nTarget
!= SOFFICE_FILEFORMAT_CURRENT
)
244 mbOasis2OOoFormat
= sal_True
;
249 // if we cannot get the version then the
250 // Oasis2OOoTransformer will not be used
255 SfxLibraryContainer::storeLibrariesToStorage( xStorage
);
257 mbOasis2OOoFormat
= sal_False
;
261 Any SAL_CALL
SfxDialogLibraryContainer::importLibraryElement
262 ( const OUString
& aFile
, const uno::Reference
< io::XInputStream
>& xElementStream
)
266 // TODO: Member because later it will be a component
267 //Reference< XMultiServiceFactory > xMSF( comphelper::getProcessServiceFactory() );
270 // OSL_ENSURE( 0, "### couln't get ProcessServiceFactory\n" );
274 Reference
< XParser
> xParser( mxMSF
->createInstance(
275 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY
);
278 OSL_ENSURE( 0, "### couln't create sax parser component\n" );
282 Reference
< XNameContainer
> xDialogModel( mxMSF
->createInstance
283 ( OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialogModel" ) ) ), UNO_QUERY
);
284 if( !xDialogModel
.is() )
286 OSL_ENSURE( 0, "### couln't create com.sun.star.awt.UnoControlDialogModel component\n" );
290 // Read from storage?
291 sal_Bool bStorage
= xElementStream
.is();
292 Reference
< XInputStream
> xInput
;
296 xInput
= xElementStream
;
302 xInput
= mxSFI
->openFileRead( aFile
);
305 //catch( Exception& e )
308 //throw WrappedTargetException( e );
314 Reference
< XComponentContext
> xContext
;
315 Reference
< beans::XPropertySet
> xProps( mxMSF
, UNO_QUERY
);
316 OSL_ASSERT( xProps
.is() );
317 OSL_VERIFY( xProps
->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext
);
320 source
.aInputStream
= xInput
;
321 source
.sSystemId
= aFile
;
325 xParser
->setDocumentHandler( ::xmlscript::importDialogModel( xDialogModel
, xContext
, mxOwnerDocument
) );
326 xParser
->parseStream( source
);
330 OSL_ENSURE( 0, "Parsing error\n" );
331 SfxErrorContext
aEc( ERRCTX_SFX_LOADBASIC
, aFile
);
332 ULONG nErrorCode
= ERRCODE_IO_GENERAL
;
333 ErrorHandler::HandleError( nErrorCode
);
337 // Create InputStream, TODO: Implement own InputStreamProvider
338 // to avoid creating the DialogModel here!
339 Reference
< XInputStreamProvider
> xISP
= ::xmlscript::exportDialogModel( xDialogModel
, xContext
, mxOwnerDocument
);
344 void SAL_CALL
SfxDialogLibraryContainer::importFromOldStorage( const OUString
& )
346 // Nothing to do here, old dialogs cannot be imported
349 SfxLibraryContainer
* SfxDialogLibraryContainer::createInstanceImpl( void )
351 return new SfxDialogLibraryContainer();
355 static OUString aResourceFileNameBase
= OUString::createFromAscii( "DialogStrings" );
356 static OUString aResourceFileCommentBase
= OUString::createFromAscii( "# Strings for Dialog Library " );
359 Reference
< ::com::sun::star::resource::XStringResourcePersistence
>
360 SfxDialogLibraryContainer::implCreateStringResource( SfxDialogLibrary
* pDialogLibrary
)
362 Reference
< resource::XStringResourcePersistence
> xRet
;
363 OUString aLibName
= pDialogLibrary
->getName();
364 bool bReadOnly
= pDialogLibrary
->mbReadOnly
;
367 ::com::sun ::star::lang::Locale aLocale
= Application::GetSettings().GetUILocale();
369 OUString aComment
= aResourceFileCommentBase
;
370 aComment
+= aLibName
;
372 sal_Bool bStorage
= mxStorage
.is();
375 Sequence
<Any
> aArgs( 5 );
376 aArgs
[1] <<= bReadOnly
;
377 aArgs
[2] <<= aLocale
;
378 aArgs
[3] <<= aResourceFileNameBase
;
379 aArgs
[4] <<= aComment
;
382 xRet
= Reference
< resource::XStringResourcePersistence
>( mxMSF
->createInstance
383 ( OUString::createFromAscii( "com.sun.star.resource.StringResourceWithStorage" ) ), UNO_QUERY
);
385 uno::Reference
< embed::XStorage
> xLibrariesStor
;
386 uno::Reference
< embed::XStorage
> xLibraryStor
;
388 xLibrariesStor
= mxStorage
->openStorageElement( maLibrariesDir
, embed::ElementModes::READ
);
389 // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
390 if ( !xLibrariesStor
.is() )
391 throw uno::RuntimeException();
393 xLibraryStor
= xLibrariesStor
->openStorageElement( aLibName
, embed::ElementModes::READ
);
394 // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
395 if ( !xLibraryStor
.is() )
396 throw uno::RuntimeException();
398 aArgs
[0] <<= xLibraryStor
;
400 catch( uno::Exception
& )
402 // TODO: Error handling?
409 Reference
< XInitialization
> xInit( xRet
, UNO_QUERY
);
411 xInit
->initialize( aArgs
);
416 Sequence
<Any
> aArgs( 6 );
418 OUString aLocation
= createAppLibraryFolder( pDialogLibrary
, aLibName
);
419 aArgs
[0] <<= aLocation
;
420 aArgs
[1] <<= bReadOnly
;
421 aArgs
[2] <<= aLocale
;
422 aArgs
[3] <<= aResourceFileNameBase
;
423 aArgs
[4] <<= aComment
;
425 // TODO: Real handler?
426 Reference
< task::XInteractionHandler
> xDummyHandler
;
427 aArgs
[5] <<= xDummyHandler
;
430 xRet
= Reference
< resource::XStringResourcePersistence
>( mxMSF
->createInstance
431 ( OUString::createFromAscii( "com.sun.star.resource.StringResourceWithLocation" ) ), UNO_QUERY
);
436 Reference
< XInitialization
> xInit( xRet
, UNO_QUERY
);
438 xInit
->initialize( aArgs
);
445 void SfxDialogLibraryContainer::onNewRootStorage()
447 // the library container is not modified, go through the libraries and check whether they are modified
448 Sequence
< OUString
> aNames
= maNameContainer
.getElementNames();
449 const OUString
* pNames
= aNames
.getConstArray();
450 sal_Int32 nNameCount
= aNames
.getLength();
452 for( sal_Int32 i
= 0 ; i
< nNameCount
; i
++ )
454 OUString aName
= pNames
[ i
];
455 SfxDialogLibrary
* pDialogLibrary
= static_cast<SfxDialogLibrary
*>( getImplLib( aName
) );
457 Reference
< resource::XStringResourcePersistence
> xStringResourcePersistence
=
458 pDialogLibrary
->getStringResourcePersistence();
460 if( xStringResourcePersistence
.is() )
462 Reference
< embed::XStorage
> xLibrariesStor
;
463 Reference
< embed::XStorage
> xLibraryStor
;
465 xLibrariesStor
= mxStorage
->openStorageElement( maLibrariesDir
, embed::ElementModes::READWRITE
);
466 if ( !xLibrariesStor
.is() )
467 throw uno::RuntimeException();
469 OUString aLibName
= pDialogLibrary
->getName();
470 xLibraryStor
= xLibrariesStor
->openStorageElement( aLibName
, embed::ElementModes::READWRITE
);
471 if ( !xLibraryStor
.is() )
472 throw uno::RuntimeException();
474 Reference
< resource::XStringResourceWithStorage
>
475 xStringResourceWithStorage( xStringResourcePersistence
, UNO_QUERY
);
476 if( xStringResourceWithStorage
.is() )
477 xStringResourceWithStorage
->setStorage( xLibraryStor
);
479 catch( uno::Exception
& )
481 // TODO: Error handling?
488 SfxDialogLibraryContainer:: HasExecutableCode( const ::rtl::OUString
& Library
) throw (uno::RuntimeException
)
490 return sal_False
; // dialog library has no executable code
492 //============================================================================
495 void createRegistryInfo_SfxDialogLibraryContainer()
497 static OAutoRegistration
< SfxDialogLibraryContainer
> aAutoRegistration
;
500 ::rtl::OUString SAL_CALL
SfxDialogLibraryContainer::getImplementationName( ) throw (RuntimeException
)
502 return getImplementationName_static();
505 Sequence
< ::rtl::OUString
> SAL_CALL
SfxDialogLibraryContainer::getSupportedServiceNames( ) throw (RuntimeException
)
507 return getSupportedServiceNames_static();
510 Sequence
< OUString
> SfxDialogLibraryContainer::getSupportedServiceNames_static()
512 Sequence
< OUString
> aServiceNames( 2 );
513 aServiceNames
[0] = OUString::createFromAscii( "com.sun.star.script.DocumentDialogLibraryContainer" );
514 // plus, for compatibility:
515 aServiceNames
[1] = OUString::createFromAscii( "com.sun.star.script.DialogLibraryContainer" );
516 return aServiceNames
;
519 OUString
SfxDialogLibraryContainer::getImplementationName_static()
521 static OUString aImplName
;
522 static sal_Bool bNeedsInit
= sal_True
;
524 MutexGuard
aGuard( Mutex::getGlobalMutex() );
527 aImplName
= OUString::createFromAscii( "com.sun.star.comp.sfx2.DialogLibraryContainer" );
528 bNeedsInit
= sal_False
;
533 Reference
< XInterface
> SAL_CALL
SfxDialogLibraryContainer::Create( const Reference
< XComponentContext
>& ) throw( Exception
)
535 Reference
< XInterface
> xRet
=
536 static_cast< XInterface
* >( static_cast< OWeakObject
* >(new SfxDialogLibraryContainer()) );
541 //============================================================================
542 // Implementation class SfxDialogLibrary
545 SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper
& _rModifiable
,
546 const ::rtl::OUString
& aName
,
547 const Reference
< XMultiServiceFactory
>& xMSF
,
548 const Reference
< XSimpleFileAccess
>& xSFI
,
549 SfxDialogLibraryContainer
* pParent
)
550 : SfxLibrary( _rModifiable
, getCppuType( (const Reference
< XInputStreamProvider
> *)0 ), xMSF
, xSFI
)
551 , m_pParent( pParent
)
556 SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper
& _rModifiable
,
557 const ::rtl::OUString
& aName
,
558 const Reference
< XMultiServiceFactory
>& xMSF
,
559 const Reference
< XSimpleFileAccess
>& xSFI
,
560 const OUString
& aLibInfoFileURL
,
561 const OUString
& aStorageURL
,
563 SfxDialogLibraryContainer
* pParent
)
564 : SfxLibrary( _rModifiable
, getCppuType( (const Reference
< XInputStreamProvider
> *)0 ),
565 xMSF
, xSFI
, aLibInfoFileURL
, aStorageURL
, ReadOnly
)
566 , m_pParent( pParent
)
571 IMPLEMENT_FORWARD_XINTERFACE2( SfxDialogLibrary
, SfxLibrary
, SfxDialogLibrary_BASE
);
572 IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxDialogLibrary
, SfxLibrary
, SfxDialogLibrary_BASE
);
574 // Provide modify state including resources
575 sal_Bool
SfxDialogLibrary::isModified( void )
577 sal_Bool bRet
= implIsModified();
579 if( !bRet
&& m_xStringResourcePersistence
.is() )
580 bRet
= m_xStringResourcePersistence
->isModified();
581 // else: Resources not accessed so far -> not modified
586 void SfxDialogLibrary::storeResources( void )
588 if( m_xStringResourcePersistence
.is() )
589 m_xStringResourcePersistence
->store();
592 void SfxDialogLibrary::storeResourcesAsURL
593 ( const ::rtl::OUString
& URL
, const ::rtl::OUString
& NewName
)
595 OUString aComment
= aResourceFileCommentBase
;
599 if( m_xStringResourcePersistence
.is() )
601 m_xStringResourcePersistence
->setComment( aComment
);
603 Reference
< resource::XStringResourceWithLocation
>
604 xStringResourceWithLocation( m_xStringResourcePersistence
, UNO_QUERY
);
605 if( xStringResourceWithLocation
.is() )
606 xStringResourceWithLocation
->storeAsURL( URL
);
610 void SfxDialogLibrary::storeResourcesToURL( const OUString
& URL
,
611 const Reference
< task::XInteractionHandler
>& xHandler
)
613 OUString aComment
= aResourceFileCommentBase
;
616 if( m_xStringResourcePersistence
.is() )
618 m_xStringResourcePersistence
->storeToURL
619 ( URL
, aResourceFileNameBase
, aComment
, xHandler
);
623 void SfxDialogLibrary::storeResourcesToStorage( const ::com::sun::star::uno::Reference
624 < ::com::sun::star::embed::XStorage
>& xStorage
)
626 OUString aComment
= aResourceFileCommentBase
;
629 if( m_xStringResourcePersistence
.is() )
631 m_xStringResourcePersistence
->storeToStorage
632 ( xStorage
, aResourceFileNameBase
, aComment
);
637 // XStringResourceSupplier
638 Reference
< resource::XStringResourceResolver
>
639 SAL_CALL
SfxDialogLibrary::getStringResource( ) throw (RuntimeException
)
641 if( !m_xStringResourcePersistence
.is() )
642 m_xStringResourcePersistence
= m_pParent
->implCreateStringResource( this );
644 Reference
< resource::XStringResourceResolver
> xRet( m_xStringResourcePersistence
, UNO_QUERY
);
648 bool SfxDialogLibrary::containsValidDialog( const ::com::sun::star::uno::Any
& aElement
)
650 Reference
< XInputStreamProvider
> xISP
;
655 bool SAL_CALL
SfxDialogLibrary::isLibraryElementValid( ::com::sun::star::uno::Any aElement
) const
657 return SfxDialogLibrary::containsValidDialog( aElement
);
661 //============================================================================