nss: upgrade to release 3.73
[LibreOffice.git] / basic / source / uno / dlgcont.cxx
blobb303349fa00991020a07103500b6a0155ebfbbd4
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/io/XInputStreamProvider.hpp>
27 #include <com/sun/star/embed/ElementModes.hpp>
28 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
29 #include <com/sun/star/resource/StringResourceWithStorage.hpp>
30 #include <com/sun/star/resource/StringResourceWithLocation.hpp>
31 #include <com/sun/star/document/GraphicStorageHandler.hpp>
32 #include <com/sun/star/document/XGraphicStorageHandler.hpp>
33 #include <dlgcont.hxx>
34 #include <comphelper/fileformat.h>
35 #include <comphelper/processfactory.hxx>
36 #include <tools/diagnose_ex.h>
37 #include <vcl/svapp.hxx>
38 #include <vcl/settings.hxx>
39 #include <xmlscript/xmldlg_imexp.hxx>
40 #include <sot/storage.hxx>
41 #include <svtools/sfxecode.hxx>
42 #include <svtools/ehdl.hxx>
43 #include <vcl/GraphicObject.hxx>
44 #include <i18nlangtag/languagetag.hxx>
46 namespace basic
49 using namespace com::sun::star::document;
50 using namespace com::sun::star::container;
51 using namespace com::sun::star::io;
52 using namespace com::sun::star::uno;
53 using namespace com::sun::star::ucb;
54 using namespace com::sun::star::lang;
55 using namespace com::sun::star::script;
56 using namespace com::sun::star::xml::sax;
57 using namespace com::sun::star;
58 using namespace cppu;
60 using com::sun::star::uno::Reference;
63 // Implementation class SfxDialogLibraryContainer
65 const char* SfxDialogLibraryContainer::getInfoFileName() const { return "dialog"; }
66 const char* SfxDialogLibraryContainer::getOldInfoFileName() const { return "dialogs"; }
67 const char* SfxDialogLibraryContainer::getLibElementFileExtension() const { return "xdl"; }
68 const char* SfxDialogLibraryContainer::getLibrariesDir() const { return "Dialogs"; }
70 // Ctor for service
71 SfxDialogLibraryContainer::SfxDialogLibraryContainer()
73 // all initialisation has to be done
74 // by calling XInitialization::initialize
77 SfxDialogLibraryContainer::SfxDialogLibraryContainer( const uno::Reference< embed::XStorage >& xStorage )
79 init( OUString(), xStorage );
82 // Methods to get library instances of the correct type
83 SfxLibrary* SfxDialogLibraryContainer::implCreateLibrary( const OUString& aName )
85 SfxLibrary* pRet = new SfxDialogLibrary( maModifiable, aName, mxSFI, this );
86 return pRet;
89 SfxLibrary* SfxDialogLibraryContainer::implCreateLibraryLink
90 ( const OUString& aName, const OUString& aLibInfoFileURL,
91 const OUString& StorageURL, bool ReadOnly )
93 SfxLibrary* pRet = new SfxDialogLibrary
94 ( maModifiable, aName, mxSFI, aLibInfoFileURL, StorageURL, ReadOnly, this );
95 return pRet;
98 Any SfxDialogLibraryContainer::createEmptyLibraryElement()
100 Reference< XInputStreamProvider > xISP;
101 Any aRetAny;
102 aRetAny <<= xISP;
103 return aRetAny;
106 bool SfxDialogLibraryContainer::isLibraryElementValid(const Any& rElement) const
108 return SfxDialogLibrary::containsValidDialog(rElement);
111 static bool writeOasis2OOoLibraryElement(
112 const Reference< XInputStream >& xInput, const Reference< XOutputStream >& xOutput )
114 Reference< XComponentContext > xContext(
115 comphelper::getProcessComponentContext() );
117 Reference< lang::XMultiComponentFactory > xSMgr(
118 xContext->getServiceManager() );
120 Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(xContext);
122 Reference< xml::sax::XWriter > xWriter = xml::sax::Writer::create(xContext);
124 xWriter->setOutputStream( xOutput );
126 Sequence<Any> aArgs( 1 );
127 aArgs[0] <<= xWriter;
129 Reference< xml::sax::XDocumentHandler > xHandler(
130 xSMgr->createInstanceWithArgumentsAndContext(
131 "com.sun.star.comp.Oasis2OOoTransformer",
132 aArgs, xContext ),
133 UNO_QUERY );
135 xParser->setDocumentHandler( xHandler );
137 xml::sax::InputSource source;
138 source.aInputStream = xInput;
139 source.sSystemId = "virtual file";
141 xParser->parseStream( source );
143 return true;
146 void SfxDialogLibraryContainer::writeLibraryElement
148 const Reference < XNameContainer >& xLib,
149 const OUString& aElementName,
150 const Reference< XOutputStream >& xOutput
153 Any aElement = xLib->getByName( aElementName );
154 Reference< XInputStreamProvider > xISP;
155 aElement >>= xISP;
156 if( !xISP.is() )
157 return;
159 Reference< XInputStream > xInput( xISP->createInputStream() );
161 bool bComplete = false;
162 if ( mbOasis2OOoFormat )
164 bComplete = writeOasis2OOoLibraryElement( xInput, xOutput );
167 if ( !bComplete )
169 Sequence< sal_Int8 > bytes;
170 sal_Int32 nRead = xInput->readBytes( bytes, xInput->available() );
171 for (;;)
173 if( nRead )
174 xOutput->writeBytes( bytes );
176 nRead = xInput->readBytes( bytes, 1024 );
177 if (! nRead)
178 break;
181 xInput->closeInput();
184 void SfxDialogLibraryContainer::storeLibrariesToStorage( const uno::Reference< embed::XStorage >& xStorage )
186 LibraryContainerMethodGuard aGuard( *this );
187 mbOasis2OOoFormat = false;
189 if ( mxStorage.is() && xStorage.is() )
193 tools::Long nSource = SotStorage::GetVersion( mxStorage );
194 tools::Long nTarget = SotStorage::GetVersion( xStorage );
196 if ( nSource == SOFFICE_FILEFORMAT_CURRENT &&
197 nTarget != SOFFICE_FILEFORMAT_CURRENT )
199 mbOasis2OOoFormat = true;
202 catch (const Exception& )
204 TOOLS_WARN_EXCEPTION("basic", "");
205 // if we cannot get the version then the
206 // Oasis2OOoTransformer will not be used
207 assert(false);
211 SfxLibraryContainer::storeLibrariesToStorage( xStorage );
213 // we need to export out any embedded image object(s)
214 // associated with any Dialogs. First, we need to actually gather any such urls
215 // for each dialog in this container
216 const Sequence< OUString > sLibraries = getElementNames();
217 for ( const OUString& rName : sLibraries )
219 loadLibrary( rName );
220 Reference< XNameContainer > xLib;
221 getByName( rName ) >>= xLib;
222 if ( xLib.is() )
224 Sequence< OUString > sDialogs = xLib->getElementNames();
225 sal_Int32 nDialogs( sDialogs.getLength() );
226 for ( sal_Int32 j=0; j < nDialogs; ++j )
228 // Each Dialog has an associated xISP
229 Reference< io::XInputStreamProvider > xISP;
230 xLib->getByName( sDialogs[ j ] ) >>= xISP;
231 if ( xISP.is() )
233 Reference< io::XInputStream > xInput( xISP->createInputStream() );
234 Reference< XNameContainer > xDialogModel(
235 mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", mxContext),
236 UNO_QUERY );
237 ::xmlscript::importDialogModel( xInput, xDialogModel, mxContext, mxOwnerDocument );
238 std::vector<uno::Reference<graphic::XGraphic>> vxGraphicList;
239 vcl::graphic::SearchForGraphics(Reference<XInterface>(xDialogModel, UNO_QUERY), vxGraphicList);
240 if (!vxGraphicList.empty())
242 // Export the images to the storage
243 Reference<document::XGraphicStorageHandler> xGraphicStorageHandler;
244 xGraphicStorageHandler.set(document::GraphicStorageHandler::createWithStorage(mxContext, xStorage));
245 if (xGraphicStorageHandler.is())
247 for (uno::Reference<graphic::XGraphic> const & rxGraphic : vxGraphicList)
249 xGraphicStorageHandler->saveGraphic(rxGraphic);
257 mbOasis2OOoFormat = false;
261 Any SfxDialogLibraryContainer::importLibraryElement
262 ( const Reference < XNameContainer >& /*xLib*/,
263 const OUString& /*aElementName */, const OUString& aFile,
264 const uno::Reference< io::XInputStream >& xElementStream )
266 Any aRetAny;
268 // TODO: Member because later it will be a component
269 //Reference< XMultiServiceFactory > xMSF( comphelper::getProcessServiceFactory() );
270 //if( !xMSF.is() )
272 // OSL_FAIL( "### couldn't get ProcessServiceFactory" );
273 // return aRetAny;
276 Reference< XParser > xParser = xml::sax::Parser::create( mxContext );
278 Reference< XNameContainer > xDialogModel(
279 mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", mxContext),
280 UNO_QUERY );
281 if( !xDialogModel.is() )
283 OSL_FAIL( "### couldn't create com.sun.star.awt.UnoControlDialogModel component" );
284 return aRetAny;
287 // Read from storage?
288 bool bStorage = xElementStream.is();
289 Reference< XInputStream > xInput;
291 if( bStorage )
293 xInput = xElementStream;
295 else
299 xInput = mxSFI->openFileRead( aFile );
301 catch(const Exception& )
302 //catch( Exception& e )
304 // TODO:
305 //throw WrappedTargetException( e );
308 if( !xInput.is() )
309 return aRetAny;
311 InputSource source;
312 source.aInputStream = xInput;
313 source.sSystemId = aFile;
315 try {
316 // start parsing
317 xParser->setDocumentHandler( ::xmlscript::importDialogModel( xDialogModel, mxContext, mxOwnerDocument ) );
318 xParser->parseStream( source );
320 catch(const Exception& )
322 OSL_FAIL( "Parsing error" );
323 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFile );
324 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
325 return aRetAny;
328 // Create InputStream, TODO: Implement own InputStreamProvider
329 // to avoid creating the DialogModel here!
330 Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, mxContext, mxOwnerDocument );
331 aRetAny <<= xISP;
332 return aRetAny;
335 void SfxDialogLibraryContainer::importFromOldStorage( const OUString& )
337 // Nothing to do here, old dialogs cannot be imported
340 SfxLibraryContainer* SfxDialogLibraryContainer::createInstanceImpl()
342 return new SfxDialogLibraryContainer();
345 const char aResourceFileNameBase[] = "DialogStrings";
346 const char aResourceFileCommentBase[] = "# Strings for Dialog Library ";
348 // Resource handling
349 Reference< css::resource::XStringResourcePersistence >
350 SfxDialogLibraryContainer::implCreateStringResource( SfxDialogLibrary* pDialogLibrary )
352 Reference< resource::XStringResourcePersistence > xRet;
353 OUString aLibName = pDialogLibrary->getName();
354 bool bReadOnly = pDialogLibrary->mbReadOnly;
356 // get ui locale
357 ::com::sun ::star::lang::Locale aLocale = Application::GetSettings().GetUILanguageTag().getLocale();
359 OUString aComment= aResourceFileCommentBase + aLibName;
361 bool bStorage = mxStorage.is();
362 if( bStorage )
364 uno::Reference< embed::XStorage > xLibrariesStor;
365 uno::Reference< embed::XStorage > xLibraryStor;
366 try {
367 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
368 // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
369 if ( !xLibrariesStor.is() )
370 throw uno::RuntimeException("null returned from openStorageElement");
372 xLibraryStor = xLibrariesStor->openStorageElement( aLibName, embed::ElementModes::READ );
373 // TODO: Should be READWRITE with new storage concept using store() instead of storeTo()
374 if ( !xLibraryStor.is() )
375 throw uno::RuntimeException("null returned from openStorageElement");
377 catch(const uno::Exception& )
379 // Something went wrong while trying to get the storage library.
380 // Return an object that supports StringResourceWithStorage, give it a storage location later.
381 xRet = Reference< resource::XStringResourcePersistence >(
382 mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.resource.StringResourceWithStorage", mxContext),
383 UNO_QUERY );
384 return xRet;
387 xRet = resource::StringResourceWithStorage::create(mxContext, xLibraryStor, bReadOnly, aLocale, 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, 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("null returned from openStorageElement");
425 OUString aLibName = pDialogLibrary->getName();
426 xLibraryStor = xLibrariesStor->openStorageElement( aLibName, embed::ElementModes::READWRITE );
427 if ( !xLibraryStor.is() )
428 throw uno::RuntimeException("null returned from openStorageElement");
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*/ )
446 return false; // dialog library has no executable code
449 // Service
451 OUString SAL_CALL SfxDialogLibraryContainer::getImplementationName( )
453 return "com.sun.star.comp.sfx2.DialogLibraryContainer";
456 Sequence< OUString > SAL_CALL SfxDialogLibraryContainer::getSupportedServiceNames( )
458 return {"com.sun.star.script.DocumentDialogLibraryContainer",
459 "com.sun.star.script.DialogLibraryContainer"}; // for compatibility
462 // Implementation class SfxDialogLibrary
464 // Ctor
465 SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper& _rModifiable,
466 const OUString& aName,
467 const Reference< XSimpleFileAccess3 >& xSFI,
468 SfxDialogLibraryContainer* pParent )
469 : SfxLibrary( _rModifiable, cppu::UnoType<XInputStreamProvider>::get(), xSFI )
470 , m_pParent( pParent )
471 , m_aName( aName )
475 SfxDialogLibrary::SfxDialogLibrary( ModifiableHelper& _rModifiable,
476 const OUString& aName,
477 const Reference< XSimpleFileAccess3 >& xSFI,
478 const OUString& aLibInfoFileURL,
479 const OUString& aStorageURL,
480 bool ReadOnly,
481 SfxDialogLibraryContainer* pParent )
482 : SfxLibrary( _rModifiable, cppu::UnoType<XInputStreamProvider>::get(),
483 xSFI, aLibInfoFileURL, aStorageURL, ReadOnly)
484 , m_pParent( pParent )
485 , m_aName( aName )
489 IMPLEMENT_FORWARD_XINTERFACE2( SfxDialogLibrary, SfxLibrary, SfxDialogLibrary_BASE );
490 IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxDialogLibrary, SfxLibrary, SfxDialogLibrary_BASE );
492 // Provide modify state including resources
493 bool SfxDialogLibrary::isModified()
495 bool bRet = implIsModified();
497 if( !bRet && m_xStringResourcePersistence.is() )
498 bRet = m_xStringResourcePersistence->isModified();
499 // else: Resources not accessed so far -> not modified
501 return bRet;
504 void SfxDialogLibrary::storeResources()
506 if( m_xStringResourcePersistence.is() )
507 m_xStringResourcePersistence->store();
510 void SfxDialogLibrary::storeResourcesAsURL
511 ( const OUString& URL, const OUString& NewName )
513 OUString aComment(aResourceFileCommentBase);
514 m_aName = NewName;
515 aComment += m_aName;
517 if( m_xStringResourcePersistence.is() )
519 m_xStringResourcePersistence->setComment( aComment );
521 Reference< resource::XStringResourceWithLocation >
522 xStringResourceWithLocation( m_xStringResourcePersistence, UNO_QUERY );
523 if( xStringResourceWithLocation.is() )
524 xStringResourceWithLocation->storeAsURL( URL );
528 void SfxDialogLibrary::storeResourcesToURL( const OUString& URL,
529 const Reference< task::XInteractionHandler >& xHandler )
531 OUString aComment = aResourceFileCommentBase + m_aName;
533 if( m_xStringResourcePersistence.is() )
535 m_xStringResourcePersistence->storeToURL
536 ( URL, aResourceFileNameBase, aComment, xHandler );
540 void SfxDialogLibrary::storeResourcesToStorage( const css::uno::Reference< css::embed::XStorage >& xStorage )
542 OUString aComment = aResourceFileCommentBase + m_aName;
544 if( m_xStringResourcePersistence.is() )
546 m_xStringResourcePersistence->storeToStorage
547 ( xStorage, aResourceFileNameBase, aComment );
552 // XStringResourceSupplier
553 Reference< resource::XStringResourceResolver >
554 SAL_CALL SfxDialogLibrary::getStringResource( )
556 if( !m_xStringResourcePersistence.is() )
557 m_xStringResourcePersistence = m_pParent->implCreateStringResource( this );
559 return m_xStringResourcePersistence;
562 bool SfxDialogLibrary::containsValidDialog( const css::uno::Any& aElement )
564 Reference< XInputStreamProvider > xISP;
565 aElement >>= xISP;
566 return xISP.is();
569 bool SfxDialogLibrary::isLibraryElementValid(const css::uno::Any& rElement) const
571 return SfxDialogLibrary::containsValidDialog(rElement);
576 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
577 com_sun_star_comp_sfx2_DialogLibraryContainer_get_implementation(css::uno::XComponentContext*,
578 css::uno::Sequence<css::uno::Any> const &)
580 return cppu::acquire(new basic::SfxDialogLibraryContainer());
584 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */