bump product version to 5.0.4.1
[LibreOffice.git] / basic / source / uno / dlgcont.cxx
blob66becfa53f3c6fcd8d33359fa0cca7b913c90e2c
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 <comphelper/processfactory.hxx>
36 #include <unotools/streamwrap.hxx>
37 #include <osl/mutex.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/settings.hxx>
41 #include <unotools/pathoptions.hxx>
42 #include <xmlscript/xmldlg_imexp.hxx>
43 #include <cppuhelper/factory.hxx>
44 #include <svtools/sfxecode.hxx>
45 #include <svtools/ehdl.hxx>
46 #include <svtools/grfmgr.hxx>
48 namespace basic
51 using namespace com::sun::star::document;
52 using namespace com::sun::star::container;
53 using namespace com::sun::star::io;
54 using namespace com::sun::star::uno;
55 using namespace com::sun::star::ucb;
56 using namespace com::sun::star::lang;
57 using namespace com::sun::star::script;
58 using namespace com::sun::star::xml::sax;
59 using namespace com::sun::star;
60 using namespace cppu;
61 using namespace osl;
63 using com::sun::star::uno::Reference;
66 // Implementation class SfxDialogLibraryContainer
68 const sal_Char* SAL_CALL SfxDialogLibraryContainer::getInfoFileName() const { return "dialog"; }
69 const sal_Char* SAL_CALL SfxDialogLibraryContainer::getOldInfoFileName() const { return "dialogs"; }
70 const sal_Char* SAL_CALL SfxDialogLibraryContainer::getLibElementFileExtension() const { return "xdl"; }
71 const sal_Char* SAL_CALL SfxDialogLibraryContainer::getLibrariesDir() const { return "Dialogs"; }
73 // Ctor for service
74 SfxDialogLibraryContainer::SfxDialogLibraryContainer()
76 // all initialisation has to be done
77 // by calling XInitialization::initialize
80 SfxDialogLibraryContainer::SfxDialogLibraryContainer( const uno::Reference< embed::XStorage >& xStorage )
82 init( OUString(), xStorage );
85 // Methods to get library instances of the correct type
86 SfxLibrary* SfxDialogLibraryContainer::implCreateLibrary( const OUString& aName )
88 SfxLibrary* pRet = new SfxDialogLibrary( maModifiable, aName, mxContext, mxSFI, this );
89 return pRet;
92 SfxLibrary* SfxDialogLibraryContainer::implCreateLibraryLink
93 ( const OUString& aName, const OUString& aLibInfoFileURL,
94 const OUString& StorageURL, bool ReadOnly )
96 SfxLibrary* pRet = new SfxDialogLibrary
97 ( maModifiable, aName, mxContext, mxSFI, aLibInfoFileURL, StorageURL, ReadOnly, this );
98 return pRet;
101 Any SAL_CALL SfxDialogLibraryContainer::createEmptyLibraryElement()
103 Reference< XInputStreamProvider > xISP;
104 Any aRetAny;
105 aRetAny <<= xISP;
106 return aRetAny;
109 bool SAL_CALL SfxDialogLibraryContainer::isLibraryElementValid(const Any& rElement) const
111 return SfxDialogLibrary::containsValidDialog(rElement);
114 bool writeOasis2OOoLibraryElement(
115 Reference< XInputStream > xInput, Reference< XOutputStream > xOutput )
117 Reference< XComponentContext > xContext(
118 comphelper::getProcessComponentContext() );
120 Reference< lang::XMultiComponentFactory > xSMgr(
121 xContext->getServiceManager() );
123 Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(xContext);
125 Reference< xml::sax::XWriter > xWriter = xml::sax::Writer::create(xContext);
127 xWriter->setOutputStream( xOutput );
129 Sequence<Any> aArgs( 1 );
130 aArgs[0] <<= xWriter;
132 Reference< xml::sax::XDocumentHandler > xHandler(
133 xSMgr->createInstanceWithArgumentsAndContext(
134 OUString("com.sun.star.comp.Oasis2OOoTransformer" ) ,
135 aArgs, xContext ),
136 UNO_QUERY );
138 xParser->setDocumentHandler( xHandler );
140 xml::sax::InputSource source;
141 source.aInputStream = xInput;
142 source.sSystemId = "virtual file";
144 xParser->parseStream( source );
146 return true;
149 void SAL_CALL SfxDialogLibraryContainer::writeLibraryElement
151 const Reference < XNameContainer >& xLib,
152 const OUString& aElementName,
153 const Reference< XOutputStream >& xOutput
155 throw(Exception)
157 Any aElement = xLib->getByName( aElementName );
158 Reference< XInputStreamProvider > xISP;
159 aElement >>= xISP;
160 if( !xISP.is() )
161 return;
163 Reference< XInputStream > xInput( xISP->createInputStream() );
165 bool bComplete = false;
166 if ( mbOasis2OOoFormat )
168 bComplete = writeOasis2OOoLibraryElement( xInput, xOutput );
171 if ( !bComplete )
173 Sequence< sal_Int8 > bytes;
174 sal_Int32 nRead = xInput->readBytes( bytes, xInput->available() );
175 for (;;)
177 if( nRead )
178 xOutput->writeBytes( bytes );
180 nRead = xInput->readBytes( bytes, 1024 );
181 if (! nRead)
182 break;
185 xInput->closeInput();
188 void SfxDialogLibraryContainer::storeLibrariesToStorage( const uno::Reference< embed::XStorage >& xStorage ) throw ( RuntimeException, WrappedTargetException, std::exception )
190 LibraryContainerMethodGuard aGuard( *this );
191 mbOasis2OOoFormat = false;
193 if ( mxStorage.is() && xStorage.is() )
197 long nSource = SotStorage::GetVersion( mxStorage );
198 long nTarget = SotStorage::GetVersion( xStorage );
200 if ( nSource == SOFFICE_FILEFORMAT_CURRENT &&
201 nTarget != SOFFICE_FILEFORMAT_CURRENT )
203 mbOasis2OOoFormat = true;
206 catch (const Exception& )
208 // if we cannot get the version then the
209 // Oasis2OOoTransformer will not be used
210 OSL_ASSERT(false);
214 SfxLibraryContainer::storeLibrariesToStorage( xStorage );
216 // we need to export out any embedded image object(s)
217 // associated with any Dialogs. First, we need to actually gather any such urls
218 // for each dialog in this container
219 Sequence< OUString > sLibraries = getElementNames();
220 for ( sal_Int32 i=0; i < sLibraries.getLength(); ++i )
222 loadLibrary( sLibraries[ i ] );
223 Reference< XNameContainer > xLib;
224 getByName( sLibraries[ i ] ) >>= xLib;
225 if ( xLib.is() )
227 Sequence< OUString > sDialogs = xLib->getElementNames();
228 sal_Int32 nDialogs( sDialogs.getLength() );
229 for ( sal_Int32 j=0; j < nDialogs; ++j )
231 // Each Dialog has an associated xISP
232 Reference< io::XInputStreamProvider > xISP;
233 xLib->getByName( sDialogs[ j ] ) >>= xISP;
234 if ( xISP.is() )
236 Reference< io::XInputStream > xInput( xISP->createInputStream() );
237 Reference< XNameContainer > xDialogModel(
238 mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", mxContext),
239 UNO_QUERY );
240 ::xmlscript::importDialogModel( xInput, xDialogModel, mxContext, mxOwnerDocument );
241 std::vector< OUString > vEmbeddedImageURLs;
242 GraphicObject::InspectForGraphicObjectImageURL( Reference<XInterface>(xDialogModel, UNO_QUERY), vEmbeddedImageURLs );
243 if ( !vEmbeddedImageURLs.empty() )
245 // Export the images to the storage
246 Reference< document::XGraphicObjectResolver > xGraphicResolver =
247 document::GraphicObjectResolver::createWithStorage( mxContext, xStorage );
248 std::vector< OUString >::iterator it = vEmbeddedImageURLs.begin();
249 std::vector< OUString >::iterator it_end = vEmbeddedImageURLs.end();
250 if ( xGraphicResolver.is() )
252 for ( sal_Int32 count = 0; it != it_end; ++it, ++count )
253 xGraphicResolver->resolveGraphicObjectURL( *it );
260 mbOasis2OOoFormat = false;
264 Any SAL_CALL SfxDialogLibraryContainer::importLibraryElement
265 ( const Reference < XNameContainer >& /*xLib*/,
266 const OUString& /*aElementName */, const OUString& aFile,
267 const uno::Reference< io::XInputStream >& xElementStream )
269 Any aRetAny;
271 // TODO: Member because later it will be a component
272 //Reference< XMultiServiceFactory > xMSF( comphelper::getProcessServiceFactory() );
273 //if( !xMSF.is() )
275 // OSL_FAIL( "### couldn't get ProcessServiceFactory\n" );
276 // return aRetAny;
279 Reference< XParser > xParser = xml::sax::Parser::create( mxContext );
281 Reference< XNameContainer > xDialogModel(
282 mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", mxContext),
283 UNO_QUERY );
284 if( !xDialogModel.is() )
286 OSL_FAIL( "### couldn't create com.sun.star.awt.UnoControlDialogModel component\n" );
287 return aRetAny;
290 // Read from storage?
291 bool bStorage = xElementStream.is();
292 Reference< XInputStream > xInput;
294 if( bStorage )
296 xInput = xElementStream;
298 else
302 xInput = mxSFI->openFileRead( aFile );
304 catch(const Exception& )
305 //catch( Exception& e )
307 // TODO:
308 //throw WrappedTargetException( e );
311 if( !xInput.is() )
312 return aRetAny;
314 InputSource source;
315 source.aInputStream = xInput;
316 source.sSystemId = aFile;
318 try {
319 // start parsing
320 xParser->setDocumentHandler( ::xmlscript::importDialogModel( xDialogModel, mxContext, mxOwnerDocument ) );
321 xParser->parseStream( source );
323 catch(const Exception& )
325 OSL_FAIL( "Parsing error\n" );
326 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFile );
327 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
328 return aRetAny;
331 // Create InputStream, TODO: Implement own InputStreamProvider
332 // to avoid creating the DialogModel here!
333 Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, mxContext, mxOwnerDocument );
334 aRetAny <<= xISP;
335 return aRetAny;
338 void SAL_CALL SfxDialogLibraryContainer::importFromOldStorage( const OUString& )
340 // Nothing to do here, old dialogs cannot be imported
343 SfxLibraryContainer* SfxDialogLibraryContainer::createInstanceImpl()
345 return new SfxDialogLibraryContainer();
348 const char aResourceFileNameBase[] = "DialogStrings";
349 const char aResourceFileCommentBase[] = "# Strings for Dialog Library ";
351 // Resource handling
352 Reference< ::com::sun::star::resource::XStringResourcePersistence >
353 SfxDialogLibraryContainer::implCreateStringResource( SfxDialogLibrary* pDialogLibrary )
355 Reference< resource::XStringResourcePersistence > xRet;
356 OUString aLibName = pDialogLibrary->getName();
357 bool bReadOnly = pDialogLibrary->mbReadOnly;
359 // get ui locale
360 ::com::sun ::star::lang::Locale aLocale = Application::GetSettings().GetUILanguageTag().getLocale();
362 OUString aComment(aResourceFileCommentBase);
363 aComment += aLibName;
365 bool bStorage = mxStorage.is();
366 if( bStorage )
368 uno::Reference< embed::XStorage > xLibrariesStor;
369 uno::Reference< embed::XStorage > xLibraryStor;
370 try {
371 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
372 // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
373 if ( !xLibrariesStor.is() )
374 throw uno::RuntimeException();
376 xLibraryStor = xLibrariesStor->openStorageElement( aLibName, embed::ElementModes::READ );
377 // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
378 if ( !xLibraryStor.is() )
379 throw uno::RuntimeException();
381 catch(const uno::Exception& )
383 // TODO: Error handling?
384 return xRet;
387 xRet = resource::StringResourceWithStorage::create(mxContext, xLibraryStor, bReadOnly, aLocale, OUString(aResourceFileNameBase), aComment);
389 else
391 OUString aLocation = createAppLibraryFolder( pDialogLibrary, aLibName );
392 // TODO: Real handler?
393 Reference< task::XInteractionHandler > xDummyHandler;
395 xRet = resource::StringResourceWithLocation::create(mxContext, aLocation, bReadOnly, aLocale, OUString(aResourceFileNameBase), aComment, xDummyHandler);
398 return xRet;
401 void SfxDialogLibraryContainer::onNewRootStorage()
403 // the library container is not modified, go through the libraries and check whether they are modified
404 Sequence< OUString > aNames = maNameContainer.getElementNames();
405 const OUString* pNames = aNames.getConstArray();
406 sal_Int32 nNameCount = aNames.getLength();
408 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
410 OUString aName = pNames[ i ];
411 SfxDialogLibrary* pDialogLibrary = static_cast<SfxDialogLibrary*>( getImplLib( aName ) );
413 Reference< resource::XStringResourcePersistence > xStringResourcePersistence =
414 pDialogLibrary->getStringResourcePersistence();
416 if( xStringResourcePersistence.is() )
418 Reference< embed::XStorage > xLibrariesStor;
419 Reference< embed::XStorage > xLibraryStor;
420 try {
421 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READWRITE );
422 if ( !xLibrariesStor.is() )
423 throw uno::RuntimeException();
425 OUString aLibName = pDialogLibrary->getName();
426 xLibraryStor = xLibrariesStor->openStorageElement( aLibName, embed::ElementModes::READWRITE );
427 if ( !xLibraryStor.is() )
428 throw uno::RuntimeException();
430 Reference< resource::XStringResourceWithStorage >
431 xStringResourceWithStorage( xStringResourcePersistence, UNO_QUERY );
432 if( xStringResourceWithStorage.is() )
433 xStringResourceWithStorage->setStorage( xLibraryStor );
435 catch(const uno::Exception& )
437 // TODO: Error handling?
443 sal_Bool SAL_CALL
444 SfxDialogLibraryContainer:: HasExecutableCode( const OUString& /*Library*/ ) throw (uno::RuntimeException, std::exception)
446 return sal_False; // dialog library has no executable code
449 // Service
451 OUString SAL_CALL SfxDialogLibraryContainer::getImplementationName( ) throw (RuntimeException, std::exception)
453 return OUString("com.sun.star.comp.sfx2.DialogLibraryContainer");
456 Sequence< OUString > SAL_CALL SfxDialogLibraryContainer::getSupportedServiceNames( ) throw (RuntimeException, std::exception)
458 Sequence< OUString > aServiceNames( 2 );
459 aServiceNames[0] = "com.sun.star.script.DocumentDialogLibraryContainer";
460 // plus, for compatibility:
461 aServiceNames[1] = "com.sun.star.script.DialogLibraryContainer";
462 return aServiceNames;
465 // Implementation class SfxDialogLibrary
467 // Ctor
468 SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper& _rModifiable,
469 const OUString& aName,
470 const Reference< XComponentContext >& xContext,
471 const Reference< XSimpleFileAccess3 >& xSFI,
472 SfxDialogLibraryContainer* pParent )
473 : SfxLibrary( _rModifiable, cppu::UnoType<XInputStreamProvider>::get(), xContext, xSFI )
474 , m_pParent( pParent )
475 , m_aName( aName )
479 SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper& _rModifiable,
480 const OUString& aName,
481 const Reference< XComponentContext >& xContext,
482 const Reference< XSimpleFileAccess3 >& xSFI,
483 const OUString& aLibInfoFileURL,
484 const OUString& aStorageURL,
485 bool ReadOnly,
486 SfxDialogLibraryContainer* pParent )
487 : SfxLibrary( _rModifiable, cppu::UnoType<XInputStreamProvider>::get(),
488 xContext, xSFI, aLibInfoFileURL, aStorageURL, ReadOnly)
489 , m_pParent( pParent )
490 , m_aName( aName )
494 IMPLEMENT_FORWARD_XINTERFACE2( SfxDialogLibrary, SfxLibrary, SfxDialogLibrary_BASE );
495 IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxDialogLibrary, SfxLibrary, SfxDialogLibrary_BASE );
497 // Provide modify state including resources
498 bool SfxDialogLibrary::isModified()
500 bool bRet = implIsModified();
502 if( !bRet && m_xStringResourcePersistence.is() )
503 bRet = m_xStringResourcePersistence->isModified();
504 // else: Resources not accessed so far -> not modified
506 return bRet;
509 void SfxDialogLibrary::storeResources()
511 if( m_xStringResourcePersistence.is() )
512 m_xStringResourcePersistence->store();
515 void SfxDialogLibrary::storeResourcesAsURL
516 ( const OUString& URL, const OUString& NewName )
518 OUString aComment(aResourceFileCommentBase);
519 m_aName = NewName;
520 aComment += m_aName;
522 if( m_xStringResourcePersistence.is() )
524 m_xStringResourcePersistence->setComment( aComment );
526 Reference< resource::XStringResourceWithLocation >
527 xStringResourceWithLocation( m_xStringResourcePersistence, UNO_QUERY );
528 if( xStringResourceWithLocation.is() )
529 xStringResourceWithLocation->storeAsURL( URL );
533 void SfxDialogLibrary::storeResourcesToURL( const OUString& URL,
534 const Reference< task::XInteractionHandler >& xHandler )
536 OUString aComment(aResourceFileCommentBase);
537 aComment += m_aName;
539 if( m_xStringResourcePersistence.is() )
541 m_xStringResourcePersistence->storeToURL
542 ( URL, OUString(aResourceFileNameBase), aComment, xHandler );
546 void SfxDialogLibrary::storeResourcesToStorage( const ::com::sun::star::uno::Reference
547 < ::com::sun::star::embed::XStorage >& xStorage )
549 OUString aComment(aResourceFileCommentBase);
550 aComment += m_aName;
552 if( m_xStringResourcePersistence.is() )
554 m_xStringResourcePersistence->storeToStorage
555 ( xStorage, OUString(aResourceFileNameBase), aComment );
560 // XStringResourceSupplier
561 Reference< resource::XStringResourceResolver >
562 SAL_CALL SfxDialogLibrary::getStringResource( ) throw (RuntimeException, std::exception)
564 if( !m_xStringResourcePersistence.is() )
565 m_xStringResourcePersistence = m_pParent->implCreateStringResource( this );
567 Reference< resource::XStringResourceResolver > xRet( m_xStringResourcePersistence, UNO_QUERY );
568 return xRet;
571 bool SfxDialogLibrary::containsValidDialog( const ::com::sun::star::uno::Any& aElement )
573 Reference< XInputStreamProvider > xISP;
574 aElement >>= xISP;
575 return xISP.is();
578 bool SAL_CALL SfxDialogLibrary::isLibraryElementValid(const css::uno::Any& rElement) const
580 return SfxDialogLibrary::containsValidDialog(rElement);
585 extern "C" SAL_DLLPUBLIC_EXPORT ::com::sun::star::uno::XInterface* SAL_CALL
586 com_sun_star_comp_sfx2_DialogLibraryContainer_get_implementation(::com::sun::star::uno::XComponentContext*,
587 ::com::sun::star::uno::Sequence<css::uno::Any> const &)
589 return cppu::acquire(new basic::SfxDialogLibraryContainer());
593 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */