merge the formfield patch from ooo-build
[ooovba.git] / basic / source / uno / dlgcont.cxx
blob92294f1023c90668a1d47d7acbdfb674fc218393
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dlgcont.cxx,v $
10 * $Revision: 1.10 $
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>
61 namespace basic
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;
73 using namespace cppu;
74 using namespace rtl;
75 using namespace osl;
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"; }
87 // Ctor for service
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 );
103 return pRet;
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 );
112 return pRet;
115 Any SAL_CALL SfxDialogLibraryContainer::createEmptyLibraryElement( void )
117 Reference< XInputStreamProvider > xISP;
118 Any aRetAny;
119 aRetAny <<= xISP;
120 return aRetAny;
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() );
143 if (! xSMgr.is())
145 return FALSE;
148 Reference< xml::sax::XParser > xParser(
149 xSMgr->createInstanceWithContext(
150 OUString( RTL_CONSTASCII_USTRINGPARAM(
151 "com.sun.star.xml.sax.Parser" ) ),
152 xContext ),
153 UNO_QUERY );
155 Reference< xml::sax::XExtendedDocumentHandler > xWriter(
156 xSMgr->createInstanceWithContext(
157 OUString( RTL_CONSTASCII_USTRINGPARAM(
158 "com.sun.star.xml.sax.Writer" ) ),
159 xContext ),
160 UNO_QUERY );
162 Reference< io::XActiveDataSource > xSource( xWriter, UNO_QUERY );
163 xSource->setOutputStream( xOutput );
165 if ( !xParser.is() || !xWriter.is() )
167 return FALSE;
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" ) ),
177 aArgs, xContext ),
178 UNO_QUERY );
180 xParser->setDocumentHandler( xHandler );
182 xml::sax::InputSource source;
183 source.aInputStream = xInput;
184 source.sSystemId = OUString::createFromAscii( "virtual file" );
186 xParser->parseStream( source );
188 return TRUE;
191 void SAL_CALL SfxDialogLibraryContainer::writeLibraryElement
193 Any aElement,
194 const OUString& /*aElementName*/,
195 Reference< XOutputStream > xOutput
197 throw(Exception)
199 Reference< XInputStreamProvider > xISP;
200 aElement >>= xISP;
201 if( !xISP.is() )
202 return;
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() );
216 for (;;)
218 if( nRead )
219 xOutput->writeBytes( bytes );
221 nRead = xInput->readBytes( bytes, 1024 );
222 if (! nRead)
223 break;
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;
247 catch ( Exception& )
249 // if we cannot get the version then the
250 // Oasis2OOoTransformer will not be used
251 OSL_ASSERT(FALSE);
255 SfxLibraryContainer::storeLibrariesToStorage( xStorage );
257 mbOasis2OOoFormat = sal_False;
261 Any SAL_CALL SfxDialogLibraryContainer::importLibraryElement
262 ( const OUString& aFile, const uno::Reference< io::XInputStream >& xElementStream )
264 Any aRetAny;
266 // TODO: Member because later it will be a component
267 //Reference< XMultiServiceFactory > xMSF( comphelper::getProcessServiceFactory() );
268 //if( !xMSF.is() )
270 // OSL_ENSURE( 0, "### couln't get ProcessServiceFactory\n" );
271 // return aRetAny;
274 Reference< XParser > xParser( mxMSF->createInstance(
275 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
276 if( !xParser.is() )
278 OSL_ENSURE( 0, "### couln't create sax parser component\n" );
279 return aRetAny;
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" );
287 return aRetAny;
290 // Read from storage?
291 sal_Bool bStorage = xElementStream.is();
292 Reference< XInputStream > xInput;
294 if( bStorage )
296 xInput = xElementStream;
298 else
302 xInput = mxSFI->openFileRead( aFile );
304 catch( Exception& )
305 //catch( Exception& e )
307 // TODO:
308 //throw WrappedTargetException( e );
311 if( !xInput.is() )
312 return aRetAny;
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 );
319 InputSource source;
320 source.aInputStream = xInput;
321 source.sSystemId = aFile;
323 try {
324 // start parsing
325 xParser->setDocumentHandler( ::xmlscript::importDialogModel( xDialogModel, xContext, mxOwnerDocument ) );
326 xParser->parseStream( source );
328 catch( Exception& )
330 OSL_ENSURE( 0, "Parsing error\n" );
331 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFile );
332 ULONG nErrorCode = ERRCODE_IO_GENERAL;
333 ErrorHandler::HandleError( nErrorCode );
334 return aRetAny;
337 // Create InputStream, TODO: Implement own InputStreamProvider
338 // to avoid creating the DialogModel here!
339 Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, mxOwnerDocument );
340 aRetAny <<= xISP;
341 return aRetAny;
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 " );
358 // Resource handling
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;
366 // get ui locale
367 ::com::sun ::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
369 OUString aComment = aResourceFileCommentBase;
370 aComment += aLibName;
372 sal_Bool bStorage = mxStorage.is();
373 if( bStorage )
375 Sequence<Any> aArgs( 5 );
376 aArgs[1] <<= bReadOnly;
377 aArgs[2] <<= aLocale;
378 aArgs[3] <<= aResourceFileNameBase;
379 aArgs[4] <<= aComment;
381 // TODO: Ctor
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;
387 try {
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?
403 return xRet;
406 // TODO: Ctor
407 if( xRet.is() )
409 Reference< XInitialization > xInit( xRet, UNO_QUERY );
410 if( xInit.is() )
411 xInit->initialize( aArgs );
414 else
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;
429 // TODO: Ctor
430 xRet = Reference< resource::XStringResourcePersistence >( mxMSF->createInstance
431 ( OUString::createFromAscii( "com.sun.star.resource.StringResourceWithLocation" ) ), UNO_QUERY );
433 // TODO: Ctor
434 if( xRet.is() )
436 Reference< XInitialization > xInit( xRet, UNO_QUERY );
437 if( xInit.is() )
438 xInit->initialize( aArgs );
442 return xRet;
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;
464 try {
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?
487 sal_Bool SAL_CALL
488 SfxDialogLibraryContainer:: HasExecutableCode( const ::rtl::OUString& Library ) throw (uno::RuntimeException)
490 return sal_False; // dialog library has no executable code
492 //============================================================================
493 // Service
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() );
525 if( bNeedsInit )
527 aImplName = OUString::createFromAscii( "com.sun.star.comp.sfx2.DialogLibraryContainer" );
528 bNeedsInit = sal_False;
530 return aImplName;
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()) );
537 return xRet;
541 //============================================================================
542 // Implementation class SfxDialogLibrary
544 // Ctor
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 )
552 , m_aName( aName )
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,
562 sal_Bool ReadOnly,
563 SfxDialogLibraryContainer* pParent )
564 : SfxLibrary( _rModifiable, getCppuType( (const Reference< XInputStreamProvider > *)0 ),
565 xMSF, xSFI, aLibInfoFileURL, aStorageURL, ReadOnly)
566 , m_pParent( pParent )
567 , m_aName( aName )
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
583 return bRet;
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;
596 m_aName = NewName;
597 aComment += m_aName;
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;
614 aComment += m_aName;
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;
627 aComment += m_aName;
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 );
645 return xRet;
648 bool SfxDialogLibrary::containsValidDialog( const ::com::sun::star::uno::Any& aElement )
650 Reference< XInputStreamProvider > xISP;
651 aElement >>= xISP;
652 return xISP.is();
655 bool SAL_CALL SfxDialogLibrary::isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const
657 return SfxDialogLibrary::containsValidDialog( aElement );
661 //============================================================================