bump product version to 4.1.6.2
[LibreOffice.git] / basic / source / uno / dlgcont.cxx
bloba9b28cebb1a1012014ffe5698062fa76b2629040
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/StringResourceWithStorage.hpp>
32 #include <com/sun/star/resource/StringResourceWithLocation.hpp>
33 #include <com/sun/star/document/GraphicObjectResolver.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>
50 namespace basic
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;
62 using namespace cppu;
63 using namespace osl;
65 using com::sun::star::uno::Reference;
67 //============================================================================
68 // Implementation class SfxDialogLibraryContainer
70 const sal_Char* SAL_CALL SfxDialogLibraryContainer::getInfoFileName() const { return "dialog"; }
71 const sal_Char* SAL_CALL SfxDialogLibraryContainer::getOldInfoFileName() const { return "dialogs"; }
72 const sal_Char* SAL_CALL SfxDialogLibraryContainer::getLibElementFileExtension() const { return "xdl"; }
73 const sal_Char* SAL_CALL SfxDialogLibraryContainer::getLibrariesDir() const { return "Dialogs"; }
75 // Ctor for service
76 SfxDialogLibraryContainer::SfxDialogLibraryContainer( void )
78 // all initialisation has to be done
79 // by calling XInitialization::initialize
82 SfxDialogLibraryContainer::SfxDialogLibraryContainer( const uno::Reference< embed::XStorage >& xStorage )
84 init( OUString(), xStorage );
87 // Methods to get library instances of the correct type
88 SfxLibrary* SfxDialogLibraryContainer::implCreateLibrary( const OUString& aName )
90 SfxLibrary* pRet = new SfxDialogLibrary( maModifiable, aName, mxContext, mxSFI, this );
91 return pRet;
94 SfxLibrary* SfxDialogLibraryContainer::implCreateLibraryLink
95 ( const OUString& aName, const OUString& aLibInfoFileURL,
96 const OUString& StorageURL, sal_Bool ReadOnly )
98 SfxLibrary* pRet = new SfxDialogLibrary
99 ( maModifiable, aName, mxContext, mxSFI, aLibInfoFileURL, StorageURL, ReadOnly, this );
100 return pRet;
103 Any SAL_CALL SfxDialogLibraryContainer::createEmptyLibraryElement( void )
105 Reference< XInputStreamProvider > xISP;
106 Any aRetAny;
107 aRetAny <<= xISP;
108 return aRetAny;
111 bool SAL_CALL SfxDialogLibraryContainer::isLibraryElementValid( Any aElement ) const
113 return SfxDialogLibrary::containsValidDialog( aElement );
116 bool writeOasis2OOoLibraryElement(
117 Reference< XInputStream > xInput, Reference< XOutputStream > xOutput )
119 Reference< XComponentContext > xContext(
120 comphelper::getProcessComponentContext() );
122 Reference< lang::XMultiComponentFactory > xSMgr(
123 xContext->getServiceManager() );
125 Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(xContext);
127 Reference< xml::sax::XWriter > xWriter = xml::sax::Writer::create(xContext);
129 xWriter->setOutputStream( xOutput );
131 Sequence<Any> aArgs( 1 );
132 aArgs[0] <<= xWriter;
134 Reference< xml::sax::XDocumentHandler > xHandler(
135 xSMgr->createInstanceWithArgumentsAndContext(
136 OUString("com.sun.star.comp.Oasis2OOoTransformer" ) ,
137 aArgs, xContext ),
138 UNO_QUERY );
140 xParser->setDocumentHandler( xHandler );
142 xml::sax::InputSource source;
143 source.aInputStream = xInput;
144 source.sSystemId = OUString("virtual file");
146 xParser->parseStream( source );
148 return sal_True;
151 void SAL_CALL SfxDialogLibraryContainer::writeLibraryElement
153 const Reference < XNameContainer >& xLib,
154 const OUString& aElementName,
155 const Reference< XOutputStream >& xOutput
157 throw(Exception)
159 Any aElement = xLib->getByName( aElementName );
160 Reference< XInputStreamProvider > xISP;
161 aElement >>= xISP;
162 if( !xISP.is() )
163 return;
165 Reference< XInputStream > xInput( xISP->createInputStream() );
167 bool bComplete = false;
168 if ( mbOasis2OOoFormat )
170 bComplete = writeOasis2OOoLibraryElement( xInput, xOutput );
173 if ( bComplete == sal_False )
175 Sequence< sal_Int8 > bytes;
176 sal_Int32 nRead = xInput->readBytes( bytes, xInput->available() );
177 for (;;)
179 if( nRead )
180 xOutput->writeBytes( bytes );
182 nRead = xInput->readBytes( bytes, 1024 );
183 if (! nRead)
184 break;
187 xInput->closeInput();
190 void SfxDialogLibraryContainer::storeLibrariesToStorage( const uno::Reference< embed::XStorage >& xStorage ) throw ( RuntimeException )
192 LibraryContainerMethodGuard aGuard( *this );
193 mbOasis2OOoFormat = false;
195 if ( mxStorage.is() && xStorage.is() )
199 long nSource = SotStorage::GetVersion( mxStorage );
200 long nTarget = SotStorage::GetVersion( xStorage );
202 if ( nSource == SOFFICE_FILEFORMAT_CURRENT &&
203 nTarget != SOFFICE_FILEFORMAT_CURRENT )
205 mbOasis2OOoFormat = true;
208 catch (const Exception& )
210 // if we cannot get the version then the
211 // Oasis2OOoTransformer will not be used
212 OSL_ASSERT(sal_False);
216 SfxLibraryContainer::storeLibrariesToStorage( xStorage );
218 // we need to export out any embedded image object(s)
219 // associated with any Dialogs. First, we need to actually gather any such urls
220 // for each dialog in this container
221 Sequence< OUString > sLibraries = getElementNames();
222 for ( sal_Int32 i=0; i < sLibraries.getLength(); ++i )
224 loadLibrary( sLibraries[ i ] );
225 Reference< XNameContainer > xLib;
226 getByName( sLibraries[ i ] ) >>= xLib;
227 if ( xLib.is() )
229 Sequence< OUString > sDialogs = xLib->getElementNames();
230 sal_Int32 nDialogs( sDialogs.getLength() );
231 for ( sal_Int32 j=0; j < nDialogs; ++j )
233 // Each Dialog has an associated xISP
234 Reference< io::XInputStreamProvider > xISP;
235 xLib->getByName( sDialogs[ j ] ) >>= xISP;
236 if ( xISP.is() )
238 Reference< io::XInputStream > xInput( xISP->createInputStream() );
239 Reference< XNameContainer > xDialogModel(
240 mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", mxContext),
241 UNO_QUERY );
242 ::xmlscript::importDialogModel( xInput, xDialogModel, mxContext, mxOwnerDocument );
243 std::vector< OUString > vEmbeddedImageURLs;
244 GraphicObject::InspectForGraphicObjectImageURL( Reference< XInterface >( xDialogModel, UNO_QUERY ), vEmbeddedImageURLs );
245 if ( !vEmbeddedImageURLs.empty() )
247 // Export the images to the storage
248 Reference< document::XGraphicObjectResolver > xGraphicResolver =
249 document::GraphicObjectResolver::createWithStorage( mxContext, xStorage );
250 std::vector< OUString >::iterator it = vEmbeddedImageURLs.begin();
251 std::vector< OUString >::iterator it_end = vEmbeddedImageURLs.end();
252 if ( xGraphicResolver.is() )
254 for ( sal_Int32 count = 0; it != it_end; ++it, ++count )
255 xGraphicResolver->resolveGraphicObjectURL( *it );
262 mbOasis2OOoFormat = false;
266 Any SAL_CALL SfxDialogLibraryContainer::importLibraryElement
267 ( const Reference < XNameContainer >& /*xLib*/,
268 const OUString& /*aElementName */, const OUString& aFile,
269 const uno::Reference< io::XInputStream >& xElementStream )
271 Any aRetAny;
273 // TODO: Member because later it will be a component
274 //Reference< XMultiServiceFactory > xMSF( comphelper::getProcessServiceFactory() );
275 //if( !xMSF.is() )
277 // OSL_FAIL( "### couldn't get ProcessServiceFactory\n" );
278 // return aRetAny;
281 Reference< XParser > xParser = xml::sax::Parser::create( mxContext );
283 Reference< XNameContainer > xDialogModel(
284 mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", mxContext),
285 UNO_QUERY );
286 if( !xDialogModel.is() )
288 OSL_FAIL( "### couldn't create com.sun.star.awt.UnoControlDialogModel component\n" );
289 return aRetAny;
292 // Read from storage?
293 sal_Bool bStorage = xElementStream.is();
294 Reference< XInputStream > xInput;
296 if( bStorage )
298 xInput = xElementStream;
300 else
304 xInput = mxSFI->openFileRead( aFile );
306 catch(const Exception& )
307 //catch( Exception& e )
309 // TODO:
310 //throw WrappedTargetException( e );
313 if( !xInput.is() )
314 return aRetAny;
316 InputSource source;
317 source.aInputStream = xInput;
318 source.sSystemId = aFile;
320 try {
321 // start parsing
322 xParser->setDocumentHandler( ::xmlscript::importDialogModel( xDialogModel, mxContext, mxOwnerDocument ) );
323 xParser->parseStream( source );
325 catch(const Exception& )
327 OSL_FAIL( "Parsing error\n" );
328 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFile );
329 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
330 ErrorHandler::HandleError( nErrorCode );
331 return aRetAny;
334 // Create InputStream, TODO: Implement own InputStreamProvider
335 // to avoid creating the DialogModel here!
336 Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, mxContext, mxOwnerDocument );
337 aRetAny <<= xISP;
338 return aRetAny;
341 void SAL_CALL SfxDialogLibraryContainer::importFromOldStorage( const OUString& )
343 // Nothing to do here, old dialogs cannot be imported
346 SfxLibraryContainer* SfxDialogLibraryContainer::createInstanceImpl( void )
348 return new SfxDialogLibraryContainer();
351 const char aResourceFileNameBase[] = "DialogStrings";
352 const char aResourceFileCommentBase[] = "# Strings for Dialog Library ";
354 // Resource handling
355 Reference< ::com::sun::star::resource::XStringResourcePersistence >
356 SfxDialogLibraryContainer::implCreateStringResource( SfxDialogLibrary* pDialogLibrary )
358 Reference< resource::XStringResourcePersistence > xRet;
359 OUString aLibName = pDialogLibrary->getName();
360 bool bReadOnly = pDialogLibrary->mbReadOnly;
362 // get ui locale
363 ::com::sun ::star::lang::Locale aLocale = Application::GetSettings().GetUILanguageTag().getLocale();
365 OUString aComment(aResourceFileCommentBase);
366 aComment += aLibName;
368 sal_Bool bStorage = mxStorage.is();
369 if( bStorage )
371 uno::Reference< embed::XStorage > xLibrariesStor;
372 uno::Reference< embed::XStorage > xLibraryStor;
373 try {
374 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
375 // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
376 if ( !xLibrariesStor.is() )
377 throw uno::RuntimeException();
379 xLibraryStor = xLibrariesStor->openStorageElement( aLibName, embed::ElementModes::READ );
380 // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
381 if ( !xLibraryStor.is() )
382 throw uno::RuntimeException();
384 catch(const uno::Exception& )
386 // TODO: Error handling?
387 return xRet;
390 xRet = resource::StringResourceWithStorage::create(mxContext, xLibraryStor, bReadOnly, aLocale, OUString(aResourceFileNameBase), aComment);
392 else
394 OUString aLocation = createAppLibraryFolder( pDialogLibrary, aLibName );
395 // TODO: Real handler?
396 Reference< task::XInteractionHandler > xDummyHandler;
398 xRet = resource::StringResourceWithLocation::create(mxContext, aLocation, bReadOnly, aLocale, OUString(aResourceFileNameBase), aComment, xDummyHandler);
401 return xRet;
404 void SfxDialogLibraryContainer::onNewRootStorage()
406 // the library container is not modified, go through the libraries and check whether they are modified
407 Sequence< OUString > aNames = maNameContainer.getElementNames();
408 const OUString* pNames = aNames.getConstArray();
409 sal_Int32 nNameCount = aNames.getLength();
411 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
413 OUString aName = pNames[ i ];
414 SfxDialogLibrary* pDialogLibrary = static_cast<SfxDialogLibrary*>( getImplLib( aName ) );
416 Reference< resource::XStringResourcePersistence > xStringResourcePersistence =
417 pDialogLibrary->getStringResourcePersistence();
419 if( xStringResourcePersistence.is() )
421 Reference< embed::XStorage > xLibrariesStor;
422 Reference< embed::XStorage > xLibraryStor;
423 try {
424 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READWRITE );
425 if ( !xLibrariesStor.is() )
426 throw uno::RuntimeException();
428 OUString aLibName = pDialogLibrary->getName();
429 xLibraryStor = xLibrariesStor->openStorageElement( aLibName, embed::ElementModes::READWRITE );
430 if ( !xLibraryStor.is() )
431 throw uno::RuntimeException();
433 Reference< resource::XStringResourceWithStorage >
434 xStringResourceWithStorage( xStringResourcePersistence, UNO_QUERY );
435 if( xStringResourceWithStorage.is() )
436 xStringResourceWithStorage->setStorage( xLibraryStor );
438 catch(const uno::Exception& )
440 // TODO: Error handling?
446 sal_Bool SAL_CALL
447 SfxDialogLibraryContainer:: HasExecutableCode( const OUString& /*Library*/ ) throw (uno::RuntimeException)
449 return sal_False; // dialog library has no executable code
451 //============================================================================
452 // Service
454 void createRegistryInfo_SfxDialogLibraryContainer()
456 static OAutoRegistration< SfxDialogLibraryContainer > aAutoRegistration;
459 OUString SAL_CALL SfxDialogLibraryContainer::getImplementationName( ) throw (RuntimeException)
461 return getImplementationName_static();
464 Sequence< OUString > SAL_CALL SfxDialogLibraryContainer::getSupportedServiceNames( ) throw (RuntimeException)
466 return getSupportedServiceNames_static();
469 Sequence< OUString > SfxDialogLibraryContainer::getSupportedServiceNames_static()
471 Sequence< OUString > aServiceNames( 2 );
472 aServiceNames[0] = OUString("com.sun.star.script.DocumentDialogLibraryContainer");
473 // plus, for compatibility:
474 aServiceNames[1] = OUString("com.sun.star.script.DialogLibraryContainer");
475 return aServiceNames;
478 OUString SfxDialogLibraryContainer::getImplementationName_static()
480 return OUString("com.sun.star.comp.sfx2.DialogLibraryContainer");
483 Reference< XInterface > SAL_CALL SfxDialogLibraryContainer::Create( const Reference< XComponentContext >& ) throw( Exception )
485 Reference< XInterface > xRet =
486 static_cast< XInterface* >( static_cast< OWeakObject* >(new SfxDialogLibraryContainer()) );
487 return xRet;
491 //============================================================================
492 // Implementation class SfxDialogLibrary
494 // Ctor
495 SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper& _rModifiable,
496 const OUString& aName,
497 const Reference< XComponentContext >& xContext,
498 const Reference< XSimpleFileAccess3 >& xSFI,
499 SfxDialogLibraryContainer* pParent )
500 : SfxLibrary( _rModifiable, getCppuType( (const Reference< XInputStreamProvider > *)0 ), xContext, xSFI )
501 , m_pParent( pParent )
502 , m_aName( aName )
506 SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper& _rModifiable,
507 const OUString& aName,
508 const Reference< XComponentContext >& xContext,
509 const Reference< XSimpleFileAccess3 >& xSFI,
510 const OUString& aLibInfoFileURL,
511 const OUString& aStorageURL,
512 sal_Bool ReadOnly,
513 SfxDialogLibraryContainer* pParent )
514 : SfxLibrary( _rModifiable, getCppuType( (const Reference< XInputStreamProvider > *)0 ),
515 xContext, xSFI, aLibInfoFileURL, aStorageURL, ReadOnly)
516 , m_pParent( pParent )
517 , m_aName( aName )
521 IMPLEMENT_FORWARD_XINTERFACE2( SfxDialogLibrary, SfxLibrary, SfxDialogLibrary_BASE );
522 IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxDialogLibrary, SfxLibrary, SfxDialogLibrary_BASE );
524 // Provide modify state including resources
525 sal_Bool SfxDialogLibrary::isModified( void )
527 sal_Bool bRet = implIsModified();
529 if( !bRet && m_xStringResourcePersistence.is() )
530 bRet = m_xStringResourcePersistence->isModified();
531 // else: Resources not accessed so far -> not modified
533 return bRet;
536 void SfxDialogLibrary::storeResources( void )
538 if( m_xStringResourcePersistence.is() )
539 m_xStringResourcePersistence->store();
542 void SfxDialogLibrary::storeResourcesAsURL
543 ( const OUString& URL, const OUString& NewName )
545 OUString aComment(aResourceFileCommentBase);
546 m_aName = NewName;
547 aComment += m_aName;
549 if( m_xStringResourcePersistence.is() )
551 m_xStringResourcePersistence->setComment( aComment );
553 Reference< resource::XStringResourceWithLocation >
554 xStringResourceWithLocation( m_xStringResourcePersistence, UNO_QUERY );
555 if( xStringResourceWithLocation.is() )
556 xStringResourceWithLocation->storeAsURL( URL );
560 void SfxDialogLibrary::storeResourcesToURL( const OUString& URL,
561 const Reference< task::XInteractionHandler >& xHandler )
563 OUString aComment(aResourceFileCommentBase);
564 aComment += m_aName;
566 if( m_xStringResourcePersistence.is() )
568 m_xStringResourcePersistence->storeToURL
569 ( URL, OUString(aResourceFileNameBase), aComment, xHandler );
573 void SfxDialogLibrary::storeResourcesToStorage( const ::com::sun::star::uno::Reference
574 < ::com::sun::star::embed::XStorage >& xStorage )
576 OUString aComment(aResourceFileCommentBase);
577 aComment += m_aName;
579 if( m_xStringResourcePersistence.is() )
581 m_xStringResourcePersistence->storeToStorage
582 ( xStorage, OUString(aResourceFileNameBase), aComment );
587 // XStringResourceSupplier
588 Reference< resource::XStringResourceResolver >
589 SAL_CALL SfxDialogLibrary::getStringResource( ) throw (RuntimeException)
591 if( !m_xStringResourcePersistence.is() )
592 m_xStringResourcePersistence = m_pParent->implCreateStringResource( this );
594 Reference< resource::XStringResourceResolver > xRet( m_xStringResourcePersistence, UNO_QUERY );
595 return xRet;
598 bool SfxDialogLibrary::containsValidDialog( const ::com::sun::star::uno::Any& aElement )
600 Reference< XInputStreamProvider > xISP;
601 aElement >>= xISP;
602 return xISP.is();
605 bool SAL_CALL SfxDialogLibrary::isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const
607 return SfxDialogLibrary::containsValidDialog( aElement );
612 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */