LCOV - code coverage report
Current view: top level - libreoffice/dbaccess/source/core/dataaccess - databasedocument.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 12 962 1.2 %
Date: 2012-12-27 Functions: 5 121 4.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : 
      21             : #include "core_resource.hxx"
      22             : #include "core_resource.hrc"
      23             : #include "datasource.hxx"
      24             : #include "databasedocument.hxx"
      25             : #include "dbastrings.hrc"
      26             : #include "module_dba.hxx"
      27             : #include "documenteventexecutor.hxx"
      28             : #include "databasecontext.hxx"
      29             : #include "documentcontainer.hxx"
      30             : #include "sdbcoretools.hxx"
      31             : #include "recovery/dbdocrecovery.hxx"
      32             : 
      33             : #include <com/sun/star/beans/Optional.hpp>
      34             : #include <com/sun/star/document/XExporter.hpp>
      35             : #include <com/sun/star/document/XFilter.hpp>
      36             : #include <com/sun/star/document/XImporter.hpp>
      37             : #include <com/sun/star/embed/EntryInitModes.hpp>
      38             : #include <com/sun/star/embed/XEmbedPersist.hpp>
      39             : #include <com/sun/star/embed/XTransactedObject.hpp>
      40             : #include <com/sun/star/embed/XTransactionBroadcaster.hpp>
      41             : #include <com/sun/star/frame/Desktop.hpp>
      42             : #include <com/sun/star/frame/ModuleManager.hpp>
      43             : #include <com/sun/star/io/XActiveDataSource.hpp>
      44             : #include <com/sun/star/io/XSeekable.hpp>
      45             : #include <com/sun/star/io/XOutputStream.hpp>
      46             : #include <com/sun/star/io/XTruncate.hpp>
      47             : #include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
      48             : #include <com/sun/star/task/ErrorCodeIOException.hpp>
      49             : #include <com/sun/star/task/XStatusIndicator.hpp>
      50             : #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
      51             : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
      52             : #include <com/sun/star/ui/XUIConfigurationStorage.hpp>
      53             : #include <com/sun/star/view/XSelectionSupplier.hpp>
      54             : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
      55             : #include <com/sun/star/xml/sax/Writer.hpp>
      56             : #include <com/sun/star/ucb/XContent.hpp>
      57             : #include <com/sun/star/sdb/DatabaseContext.hpp>
      58             : #include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp>
      59             : 
      60             : #include <com/sun/star/script/XStorageBasedLibraryContainer.hpp>
      61             : #include <com/sun/star/awt/XControl.hpp>
      62             : #include <com/sun/star/awt/XDialogProvider.hpp>
      63             : #include <com/sun/star/document/XGraphicObjectResolver.hpp>
      64             : 
      65             : 
      66             : #include <comphelper/documentconstants.hxx>
      67             : #include <comphelper/enumhelper.hxx>
      68             : #include <comphelper/genericpropertyset.hxx>
      69             : #include <comphelper/interaction.hxx>
      70             : #include <comphelper/mediadescriptor.hxx>
      71             : #include <comphelper/namedvaluecollection.hxx>
      72             : #include <comphelper/numberedcollection.hxx>
      73             : #include <comphelper/property.hxx>
      74             : #include <comphelper/storagehelper.hxx>
      75             : 
      76             : #include <connectivity/dbtools.hxx>
      77             : 
      78             : #include <cppuhelper/exc_hlp.hxx>
      79             : #include <framework/titlehelper.hxx>
      80             : #include <unotools/saveopt.hxx>
      81             : #include <tools/debug.hxx>
      82             : #include <tools/diagnose_ex.h>
      83             : #include <osl/diagnose.h>
      84             : #include <tools/errcode.hxx>
      85             : 
      86             : #include <boost/bind.hpp>
      87             : 
      88             : #include <algorithm>
      89             : #include <functional>
      90             : #include <list>
      91             : 
      92             : #include <svtools/grfmgr.hxx>
      93             : #define MAP_LEN(x) x, sizeof(x) - 1
      94             : 
      95             : using namespace ::com::sun::star::uno;
      96             : using namespace ::com::sun::star::beans;
      97             : using namespace ::com::sun::star::frame;
      98             : using namespace ::com::sun::star::lang;
      99             : using namespace ::com::sun::star::container;
     100             : using namespace ::com::sun::star::document;
     101             : using namespace ::com::sun::star::io;
     102             : using namespace ::com::sun::star::util;
     103             : using namespace ::com::sun::star::embed;
     104             : using namespace ::com::sun::star::task;
     105             : using namespace ::com::sun::star::view;
     106             : using namespace ::com::sun::star::sdb;
     107             : using namespace ::com::sun::star::sdbc;
     108             : using namespace ::com::sun::star;
     109             : using namespace ::com::sun::star::xml::sax;
     110             : using namespace ::com::sun::star::script;
     111             : using namespace ::com::sun::star::script::provider;
     112             : using namespace ::com::sun::star::ui;
     113             : using namespace ::cppu;
     114             : using namespace ::osl;
     115             : 
     116             : using ::com::sun::star::awt::XWindow;
     117             : using ::com::sun::star::ucb::XContent;
     118             : using ::com::sun::star::sdb::application::XDatabaseDocumentUI;
     119             : 
     120             : namespace dbaccess
     121             : {
     122             : 
     123             : //============================================================
     124             : //= ViewMonitor
     125             : //============================================================
     126             : 
     127           0 : bool ViewMonitor::onControllerConnected( const Reference< XController >& _rxController )
     128             : {
     129           0 :     bool bFirstControllerEver = ( m_bEverHadController == false );
     130           0 :     m_bEverHadController = true;
     131             : 
     132           0 :     m_xLastConnectedController = _rxController;
     133           0 :     m_bLastIsFirstEverController = bFirstControllerEver;
     134             : 
     135           0 :     return bFirstControllerEver;
     136             : }
     137             : 
     138           0 : bool ViewMonitor::onSetCurrentController( const Reference< XController >& _rxController )
     139             : {
     140             :     // we interpret this as "loading the document (including UI) is finished",
     141             :     // if and only if this is the controller which was last connected, and it was the
     142             :     // first controller ever connected
     143           0 :     bool bLoadFinished = ( _rxController == m_xLastConnectedController ) && m_bLastIsFirstEverController;
     144             : 
     145             :     // notify the respective events
     146           0 :     if ( bLoadFinished )
     147           0 :         m_rEventNotifier.notifyDocumentEventAsync( m_bIsNewDocument ? "OnNew" : "OnLoad" );
     148             : 
     149           0 :     return bLoadFinished;
     150             : }
     151             : 
     152             : //============================================================
     153             : //= ODatabaseDocument
     154             : //============================================================
     155             : DBG_NAME(ODatabaseDocument)
     156             : 
     157           3 : extern "C" void SAL_CALL createRegistryInfo_ODatabaseDocument()
     158             : {
     159           3 :     static ::dba::OAutoRegistration< ODatabaseDocument > aAutoRegistration;
     160           3 : }
     161             : 
     162           0 : ODatabaseDocument::ODatabaseDocument(const ::rtl::Reference<ODatabaseModelImpl>& _pImpl )
     163             :             :ModelDependentComponent( _pImpl )
     164           0 :             ,ODatabaseDocument_OfficeDocument( getMutex() )
     165           0 :             ,m_aModifyListeners( getMutex() )
     166           0 :             ,m_aCloseListener( getMutex() )
     167           0 :             ,m_aStorageListeners( getMutex() )
     168           0 :             ,m_pEventContainer( new DocumentEvents( *this, getMutex(), _pImpl->getDocumentEvents() ) )
     169             :             ,m_pEventExecutor( NULL )   // initialized below, ref-count-protected
     170           0 :             ,m_aEventNotifier( *this, getMutex() )
     171             :             ,m_aViewMonitor( m_aEventNotifier )
     172             :             ,m_eInitState( NotInitialized )
     173             :             ,m_bClosing( false )
     174             :             ,m_bAllowDocumentScripting( false )
     175           0 :             ,m_bHasBeenRecovered( false )
     176             : {
     177             :     DBG_CTOR(ODatabaseDocument,NULL);
     178             :     OSL_TRACE( "DD: ctor: %p: %p", this, m_pImpl.get() );
     179             : 
     180           0 :     osl_atomic_increment( &m_refCount );
     181             :     {
     182           0 :         impl_reparent_nothrow( m_xForms );
     183           0 :         impl_reparent_nothrow( m_xReports );
     184           0 :         impl_reparent_nothrow( m_pImpl->m_xTableDefinitions );
     185           0 :         impl_reparent_nothrow( m_pImpl->m_xCommandDefinitions );
     186             : 
     187           0 :         m_pEventExecutor = new DocumentEventExecutor( m_pImpl->m_aContext, this );
     188             :     }
     189           0 :     osl_atomic_decrement( &m_refCount );
     190             : 
     191             :     // if there previously was a document instance for the same Impl which was already initialized,
     192             :     // then consider ourself initialized, too.
     193             :     // #i94840#
     194           0 :     if ( m_pImpl->hadInitializedDocument() )
     195             :     {
     196             :         // Note we set our init-state to "Initializing", not "Initialized". We're created from inside the ModelImpl,
     197             :         // which is expected to call attachResource in case there was a previous incarnation of the document,
     198             :         // so we can properly finish our initialization then.
     199           0 :         impl_setInitializing();
     200             : 
     201           0 :         if ( !m_pImpl->getURL().isEmpty() )
     202             :         {
     203             :             // if the previous incarnation of the DatabaseDocument already had an URL, then creating this incarnation
     204             :             // here is effectively loading the document.
     205             :             // #i105505#
     206           0 :             m_aViewMonitor.onLoadedDocument();
     207             :         }
     208             :     }
     209           0 : }
     210             : 
     211           0 : ODatabaseDocument::~ODatabaseDocument()
     212             : {
     213             :     OSL_TRACE( "DD: dtor: %p: %p", this, m_pImpl.get() );
     214             :     DBG_DTOR(ODatabaseDocument,NULL);
     215           0 :     if ( !ODatabaseDocument_OfficeDocument::rBHelper.bInDispose && !ODatabaseDocument_OfficeDocument::rBHelper.bDisposed )
     216             :     {
     217           0 :         acquire();
     218           0 :         dispose();
     219             :     }
     220             : 
     221           0 :     delete m_pEventContainer, m_pEventContainer = NULL;
     222           0 : }
     223             : 
     224           0 : Any SAL_CALL ODatabaseDocument::queryInterface( const Type& _rType ) throw (RuntimeException)
     225             : {
     226             :     // strip XEmbeddedScripts and XScriptInvocationContext if we have any form/report
     227             :     // which already contains macros. In this case, the database document itself is not
     228             :     // allowed to contain macros, too.
     229           0 :     if  (   !m_bAllowDocumentScripting
     230           0 :         &&  (   _rType.equals( XEmbeddedScripts::static_type() )
     231           0 :             ||  _rType.equals( XScriptInvocationContext::static_type() )
     232             :             )
     233             :         )
     234           0 :         return Any();
     235             : 
     236           0 :     Any aReturn = ODatabaseDocument_OfficeDocument::queryInterface(_rType);
     237           0 :     if (!aReturn.hasValue())
     238           0 :         aReturn = ODatabaseDocument_Title::queryInterface(_rType);
     239           0 :     return aReturn;
     240             : }
     241             : 
     242           0 : void SAL_CALL ODatabaseDocument::acquire(  ) throw ()
     243             : {
     244           0 :     ODatabaseDocument_OfficeDocument::acquire();
     245           0 : }
     246             : 
     247           0 : void SAL_CALL ODatabaseDocument::release(  ) throw ()
     248             : {
     249           0 :     ODatabaseDocument_OfficeDocument::release();
     250           0 : }
     251             : 
     252           0 : Sequence< Type > SAL_CALL ODatabaseDocument::getTypes(  ) throw (RuntimeException)
     253             : {
     254             :     Sequence< Type > aTypes = ::comphelper::concatSequences(
     255             :         ODatabaseDocument_OfficeDocument::getTypes(),
     256             :         ODatabaseDocument_Title::getTypes()
     257           0 :     );
     258             : 
     259             :     // strip XEmbeddedScripts and XScriptInvocationContext if we have any form/report
     260             :     // which already contains macros. In this case, the database document itself is not
     261             :     // allowed to contain macros, too.
     262           0 :     if ( !m_bAllowDocumentScripting )
     263             :     {
     264           0 :         Sequence< Type > aStrippedTypes( aTypes.getLength() );
     265           0 :         Type* pStripTo( aStrippedTypes.getArray() );
     266             : 
     267             :         // strip XEmbeddedScripts, and immediately re-assign to aTypes
     268             :         aTypes = Sequence< Type >(
     269             :             pStripTo,
     270             :             ::std::remove_copy_if(
     271             :                 aTypes.getConstArray(),
     272           0 :                 aTypes.getConstArray() + aTypes.getLength(),
     273             :                 pStripTo,
     274           0 :                 ::std::bind2nd( ::std::equal_to< Type >(), XEmbeddedScripts::static_type() )
     275           0 :             ) - pStripTo
     276           0 :         );
     277             : 
     278             :         // strip XScriptInvocationContext, and immediately re-assign to aTypes
     279             :         aTypes = Sequence< Type >(
     280             :             pStripTo,
     281             :             ::std::remove_copy_if(
     282             :                 aTypes.getConstArray(),
     283           0 :                 aTypes.getConstArray() + aTypes.getLength(),
     284             :                 pStripTo,
     285           0 :                 ::std::bind2nd( ::std::equal_to< Type >(), XScriptInvocationContext::static_type() )
     286           0 :             ) - pStripTo
     287           0 :         );
     288             :     }
     289             : 
     290           0 :     return aTypes;
     291             : }
     292             : 
     293           0 : Sequence< sal_Int8 > SAL_CALL ODatabaseDocument::getImplementationId(  ) throw (RuntimeException)
     294             : {
     295             :     static ::cppu::OImplementationId * pId = 0;
     296           0 :     if (! pId)
     297             :     {
     298           0 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
     299           0 :         if (! pId)
     300             :         {
     301           0 :             static ::cppu::OImplementationId aId;
     302           0 :             pId = &aId;
     303           0 :         }
     304             :     }
     305           0 :     return pId->getImplementationId();
     306             : }
     307             : 
     308             : // local functions
     309             : namespace
     310             : {
     311           0 :     Reference< XStatusIndicator > lcl_extractStatusIndicator( const ::comphelper::NamedValueCollection& _rArguments )
     312             :     {
     313           0 :         Reference< XStatusIndicator > xStatusIndicator;
     314           0 :         return _rArguments.getOrDefault( "StatusIndicator", xStatusIndicator );
     315             :     }
     316             : 
     317           0 :     static void lcl_triggerStatusIndicator_throw( const ::comphelper::NamedValueCollection& _rArguments, DocumentGuard& _rGuard, const bool _bStart )
     318             :     {
     319           0 :         Reference< XStatusIndicator > xStatusIndicator( lcl_extractStatusIndicator( _rArguments ) );
     320           0 :         if ( !xStatusIndicator.is() )
     321           0 :             return;
     322             : 
     323           0 :         _rGuard.clear();
     324             :         try
     325             :         {
     326           0 :             if ( _bStart )
     327           0 :                 xStatusIndicator->start( ::rtl::OUString(), (sal_Int32)1000000 );
     328             :             else
     329           0 :                 xStatusIndicator->end();
     330             :         }
     331           0 :         catch( const Exception& )
     332             :         {
     333             :             DBG_UNHANDLED_EXCEPTION();
     334             :         }
     335           0 :         _rGuard.reset();
     336             :             // note that |reset| can throw a DisposedException
     337             :     }
     338             : 
     339           0 :     static void lcl_extractStatusIndicator( const ::comphelper::NamedValueCollection& _rArguments, Sequence< Any >& _rCallArgs )
     340             :     {
     341           0 :         Reference< XStatusIndicator > xStatusIndicator( lcl_extractStatusIndicator( _rArguments ) );
     342           0 :         if ( !xStatusIndicator.is() )
     343           0 :             return;
     344             : 
     345           0 :         sal_Int32 nLength = _rCallArgs.getLength();
     346           0 :         _rCallArgs.realloc( nLength + 1 );
     347           0 :         _rCallArgs[ nLength ] <<= xStatusIndicator;
     348             :     }
     349             : 
     350           0 :     static void lcl_extractAndStartStatusIndicator( const ::comphelper::NamedValueCollection& _rArguments, Reference< XStatusIndicator >& _rxStatusIndicator,
     351             :         Sequence< Any >& _rCallArgs )
     352             :     {
     353           0 :         _rxStatusIndicator = lcl_extractStatusIndicator( _rArguments );
     354           0 :         if ( !_rxStatusIndicator.is() )
     355           0 :             return;
     356             : 
     357             :         try
     358             :         {
     359           0 :             _rxStatusIndicator->start( ::rtl::OUString(), (sal_Int32)1000000 );
     360             : 
     361           0 :             sal_Int32 nLength = _rCallArgs.getLength();
     362           0 :             _rCallArgs.realloc( nLength + 1 );
     363           0 :             _rCallArgs[ nLength ] <<= _rxStatusIndicator;
     364             :         }
     365           0 :         catch( const Exception& )
     366             :         {
     367             :             DBG_UNHANDLED_EXCEPTION();
     368             :         }
     369             :     }
     370             : 
     371           0 :     static Sequence< PropertyValue > lcl_appendFileNameToDescriptor( const ::comphelper::NamedValueCollection& _rDescriptor, const ::rtl::OUString _rURL )
     372             :     {
     373           0 :         ::comphelper::NamedValueCollection aMutableDescriptor( _rDescriptor );
     374           0 :         if ( !_rURL.isEmpty() )
     375             :         {
     376           0 :             aMutableDescriptor.put( "FileName", _rURL );
     377           0 :             aMutableDescriptor.put( "URL", _rURL );
     378             :         }
     379           0 :         return aMutableDescriptor.getPropertyValues();
     380             :     }
     381             : }
     382             : 
     383           3 : static rtl::OUString sPictures( RTL_CONSTASCII_USTRINGPARAM("Pictures") );
     384             : 
     385             : // base documents seem to have a different behaviour to other documents, the
     386             : // root storage contents at least seem to be re-used over different saves, thus if there is a
     387             : // top level Picture directory it is never cleared.
     388             : // If we delete the 'Pictures' directory then the dialog library storage which does store
     389             : // any embed images will not work properly. ( this is due to the fact it will
     390             : // try to load the dialog which will try and access the embed images, if those images are not cached in
     391             : //  memory it will try to read them from the Picture directory which is now gone, so... we have to use this
     392             : // inglorious hack below which basically will
     393             : // a) create a temp storage
     394             : // b) introspect any dialogs for any embed graphics and grab the associate URL(s)
     395             : // c) populate the temp storage with the associated embed images ( will be stored in a 'Pictures' folder )
     396             : // d) delete the 'Picture' element from the root storage
     397             : // e) copy the Pictures element of the temp storage to the root storage
     398             : //
     399             : // this assumes that we don't use the Pictures folder in the root of the base
     400             : // document for anything, I believe this is a valid assumption ( as much as
     401             : // I could check anyway )
     402             : 
     403           0 : void lcl_uglyHackToStoreDialogeEmbedImages( const Reference< XStorageBasedLibraryContainer >& xDlgCont, const Reference< XStorage >& xStorage, const Reference< XModel >& rxModel, const ::comphelper::ComponentContext& aContext ) throw ( RuntimeException )
     404             : {
     405           0 :     Sequence< rtl::OUString > sLibraries = xDlgCont->getElementNames();
     406           0 :     Reference< XStorage > xTmpPic = xStorage->openStorageElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("tempPictures") ), ElementModes::READWRITE  );
     407             : 
     408           0 :     std::vector< rtl::OUString > vEmbedImgUrls;
     409           0 :     for ( sal_Int32 i=0; i < sLibraries.getLength(); ++i )
     410             :     {
     411           0 :         rtl::OUString sLibrary( sLibraries[ i ] );
     412           0 :         xDlgCont->loadLibrary( sLibrary );
     413           0 :         Reference< XNameContainer > xLib;
     414           0 :         xDlgCont->getByName( sLibrary ) >>= xLib;
     415           0 :         if ( xLib.is() )
     416             :         {
     417           0 :             Sequence< rtl::OUString > sDialogs = xLib->getElementNames();
     418           0 :             sal_Int32 nDialogs( sDialogs.getLength() );
     419           0 :             for ( sal_Int32 j=0; j < nDialogs; ++j )
     420             :             {
     421           0 :                 Reference < ::com::sun::star::awt::XDialogProvider > xDlgPrv;
     422           0 :                 Sequence< Any > aArgs(1);
     423           0 :                 aArgs[ 0 ] <<= rxModel;
     424           0 :                 xDlgPrv.set( aContext.createComponentWithArguments( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.DialogProvider")) , aArgs), UNO_QUERY );
     425           0 :                 rtl::OUString sDialogUrl = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:") );
     426           0 :                 sDialogUrl = sDialogUrl.concat( sLibraries[ i ] ).concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("." ) ) ).concat (  sDialogs[ j ]  ).concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("?location=document") ) );
     427             : 
     428           0 :                 Reference< ::com::sun::star::awt::XControl > xDialog( xDlgPrv->createDialog( sDialogUrl ), UNO_QUERY );
     429           0 :                 Reference< XInterface > xModel( xDialog->getModel() );
     430           0 :                 GraphicObject::InspectForGraphicObjectImageURL( xModel, vEmbedImgUrls );
     431           0 :             }
     432             :         }
     433           0 :     }
     434             :     // if we have any image urls, make sure we copy the associated images into tempPictures
     435           0 :     if ( !vEmbedImgUrls.empty() )
     436             :     {
     437             :         // Export the images to the storage
     438           0 :         Sequence< Any > aArgs( 1 );
     439           0 :         aArgs[ 0 ] <<= xTmpPic;
     440             :         Reference< XGraphicObjectResolver > xGraphicResolver(
     441           0 :                 aContext.createComponentWithArguments( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Svx.GraphicExportHelper" ) ), aArgs ), UNO_QUERY );
     442           0 :         std::vector< rtl::OUString >::iterator it = vEmbedImgUrls.begin();
     443           0 :         std::vector< rtl::OUString >::iterator it_end = vEmbedImgUrls.end();
     444           0 :         if ( xGraphicResolver.is() )
     445             :         {
     446           0 :             for ( sal_Int32 count = 0; it != it_end; ++it, ++count )
     447           0 :                 xGraphicResolver->resolveGraphicObjectURL( *it );
     448             :         }
     449             : 
     450             :         // delete old 'Pictures' storage and copy the contents of tempPictures into xStorage
     451           0 :         xStorage->removeElement( sPictures );
     452           0 :         xTmpPic->copyElementTo( sPictures, xStorage, sPictures );
     453             :     }
     454             :     else
     455             :     {
     456             :         // clean up an existing Pictures dir
     457           0 :         if ( xStorage->isStorageElement( sPictures ) )
     458           0 :             xStorage->removeElement( sPictures );
     459           0 :     }
     460           0 : }
     461             : 
     462           0 : void ODatabaseDocument::impl_setInitialized()
     463             : {
     464           0 :     m_eInitState = Initialized;
     465             : 
     466             :     // start event notifications
     467           0 :     m_aEventNotifier.onDocumentInitialized();
     468           0 : }
     469             : 
     470           0 : void ODatabaseDocument::impl_reset_nothrow()
     471             : {
     472             :     try
     473             :     {
     474           0 :         m_pImpl->clearConnections();
     475           0 :         m_pImpl->disposeStorages();
     476           0 :         m_pImpl->resetRootStroage();
     477             : 
     478           0 :         clearObjectContainer( m_xForms );
     479           0 :         clearObjectContainer( m_xReports );
     480           0 :         clearObjectContainer( m_pImpl->m_xTableDefinitions );
     481           0 :         clearObjectContainer( m_pImpl->m_xCommandDefinitions );
     482             : 
     483           0 :         m_eInitState = NotInitialized;
     484             : 
     485           0 :         m_pImpl->reset();
     486             :     }
     487           0 :     catch(const Exception&)
     488             :     {
     489             :         DBG_UNHANDLED_EXCEPTION();
     490             :     }
     491           0 :     m_pImpl->m_bDocumentReadOnly = sal_False;
     492           0 : }
     493             : 
     494           0 : void ODatabaseDocument::impl_import_nolck_throw( const ::comphelper::ComponentContext _rContext, const Reference< XInterface >& _rxTargetComponent,
     495             :                                                  const ::comphelper::NamedValueCollection& _rResource )
     496             : {
     497           0 :     Sequence< Any > aFilterCreationArgs;
     498           0 :     Reference< XStatusIndicator > xStatusIndicator;
     499           0 :     lcl_extractAndStartStatusIndicator( _rResource, xStatusIndicator, aFilterCreationArgs );
     500             : 
     501             :     /** property map for import info set */
     502             :     comphelper::PropertyMapEntry aExportInfoMap[] =
     503             :      {
     504           0 :         { MAP_LEN( "BaseURI"), 0,&::getCppuType( (::rtl::OUString *)0 ),beans::PropertyAttribute::MAYBEVOID, 0 },
     505           0 :         { MAP_LEN( "StreamName"), 0,&::getCppuType( (::rtl::OUString *)0 ),beans::PropertyAttribute::MAYBEVOID, 0 },
     506             :           { NULL, 0, 0, NULL, 0, 0 }
     507           0 :      };
     508           0 :      uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) ) );
     509           0 :     xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI")), uno::makeAny(_rResource.getOrDefault("URL",::rtl::OUString())));
     510           0 :     xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamName")), uno::makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("content.xml"))));
     511             : 
     512           0 :     const sal_Int32 nCount = aFilterCreationArgs.getLength();
     513           0 :     aFilterCreationArgs.realloc(nCount + 1);
     514           0 :     aFilterCreationArgs[nCount] <<= xInfoSet;
     515             : 
     516             :     Reference< XImporter > xImporter(
     517             :         _rContext.createComponentWithArguments( "com.sun.star.comp.sdb.DBFilter", aFilterCreationArgs ),
     518           0 :         UNO_QUERY_THROW );
     519             : 
     520           0 :     Reference< XComponent > xComponent( _rxTargetComponent, UNO_QUERY_THROW );
     521           0 :     xImporter->setTargetDocument( xComponent );
     522             : 
     523           0 :     Reference< XFilter > xFilter( xImporter, UNO_QUERY_THROW );
     524           0 :     Sequence< PropertyValue > aFilterArgs( ODatabaseModelImpl::stripLoadArguments( _rResource ).getPropertyValues() );
     525           0 :     xFilter->filter( aFilterArgs );
     526             : 
     527           0 :     if ( xStatusIndicator.is() )
     528           0 :         xStatusIndicator->end();
     529           0 : }
     530             : 
     531           0 : void SAL_CALL ODatabaseDocument::initNew(  ) throw (DoubleInitializationException, IOException, Exception, RuntimeException)
     532             : {
     533             :     // SYNCHRONIZED ->
     534           0 :     DocumentGuard aGuard( *this, DocumentGuard::InitMethod );
     535             : 
     536           0 :     impl_reset_nothrow();
     537             : 
     538           0 :     impl_setInitializing();
     539             : 
     540             :     // create a temporary storage
     541             :     Reference< XStorage > xTempStor( ::comphelper::OStorageHelper::GetTemporaryStorage(
     542           0 :         m_pImpl->m_aContext.getUNOContext() ) );
     543             : 
     544             :     // store therein
     545           0 :     impl_storeToStorage_throw( xTempStor, Sequence< PropertyValue >(), aGuard );
     546             : 
     547             :     // let the impl know we're now based on this storage
     548           0 :     m_pImpl->switchToStorage( xTempStor );
     549             : 
     550             :     // for the newly created document, allow document-wide scripting
     551           0 :     m_bAllowDocumentScripting = true;
     552             : 
     553           0 :     impl_setInitialized();
     554             : 
     555           0 :     m_aEventNotifier.notifyDocumentEventAsync( "OnTitleChanged" );
     556             : 
     557           0 :     impl_setModified_nothrow( sal_False, aGuard );
     558             :     // <- SYNCHRONIZED
     559             : 
     560           0 :     m_aEventNotifier.notifyDocumentEvent( "OnCreate" );
     561             : 
     562           0 :     impl_notifyStorageChange_nolck_nothrow( xTempStor );
     563           0 : }
     564             : 
     565           0 : void SAL_CALL ODatabaseDocument::load( const Sequence< PropertyValue >& _Arguments ) throw (DoubleInitializationException, IOException, Exception, RuntimeException)
     566             : {
     567             :     // SYNCHRONIZED ->
     568           0 :     DocumentGuard aGuard( *this, DocumentGuard::InitMethod );
     569             : 
     570           0 :     impl_reset_nothrow();
     571             : 
     572           0 :     ::comphelper::NamedValueCollection aResource( _Arguments );
     573           0 :     if ( aResource.has( "FileName" ) && !aResource.has( "URL" ) )
     574             :         // FileName is the compatibility name for URL, so we might have clients passing
     575             :         // a FileName only. However, some of our code works with the URL only, so ensure
     576             :         // we have one.
     577           0 :         aResource.put( "URL", aResource.get( "FileName" ) );
     578           0 :     if ( aResource.has( "URL" ) && !aResource.has( "FileName" ) )
     579             :         // similar ... just in case there is legacy code which expects a FileName only
     580           0 :         aResource.put( "FileName", aResource.get( "URL" ) );
     581             : 
     582             :     // now that somebody (perhaps) told us an macro execution mode, remember it as
     583             :     // ImposedMacroExecMode
     584             :     m_pImpl->setImposedMacroExecMode(
     585           0 :         aResource.getOrDefault( "MacroExecutionMode", m_pImpl->getImposedMacroExecMode() ) );
     586             : 
     587           0 :     impl_setInitializing();
     588             :     try
     589             :     {
     590           0 :         aGuard.clear();
     591           0 :         impl_import_nolck_throw( m_pImpl->m_aContext, *this, aResource );
     592           0 :         aGuard.reset();
     593             :     }
     594           0 :     catch( const Exception& )
     595             :     {
     596           0 :         impl_reset_nothrow();
     597           0 :         throw;
     598             :     }
     599             :     // tell our view monitor that the document has been loaded - this way it will fire the proper
     600             :     // event (OnLoad instead of OnCreate) later on
     601           0 :     m_aViewMonitor.onLoadedDocument();
     602             : 
     603             :     // note that we do *not* call impl_setInitialized() here: The initialization is only complete
     604             :     // when the XModel::attachResource has been called, not sooner.
     605             : 
     606           0 :     impl_setModified_nothrow( sal_False, aGuard );
     607             :     // <- SYNCHRONIZED
     608           0 : }
     609             : 
     610             : namespace
     611             : {
     612           0 :     bool lcl_hasAnyModifiedSubComponent_throw( const Reference< XController >& i_rController )
     613             :     {
     614           0 :         Reference< XDatabaseDocumentUI > xDatabaseUI( i_rController, UNO_QUERY_THROW );
     615             : 
     616           0 :         Sequence< Reference< XComponent > > aComponents( xDatabaseUI->getSubComponents() );
     617           0 :         const Reference< XComponent >* component = aComponents.getConstArray();
     618           0 :         const Reference< XComponent >* componentsEnd = aComponents.getConstArray() + aComponents.getLength();
     619             : 
     620           0 :         bool isAnyModified = false;
     621           0 :         for ( ; component != componentsEnd; ++component )
     622             :         {
     623           0 :             Reference< XModifiable > xModify( *component, UNO_QUERY );
     624           0 :             if ( xModify.is() )
     625             :             {
     626           0 :                 isAnyModified = xModify->isModified();
     627           0 :                 continue;
     628             :             }
     629             : 
     630             :             // TODO: clarify: anything else to care for? Both the sub componbents with and without model
     631             :             // should support the XModifiable interface, so I think nothing more is needed here.
     632             :             OSL_FAIL( "lcl_hasAnyModifiedSubComponent_throw: anything left to do here?" );
     633           0 :         }
     634             : 
     635           0 :         return isAnyModified;
     636             :     }
     637             : }
     638             : 
     639           0 : ::sal_Bool SAL_CALL ODatabaseDocument::wasModifiedSinceLastSave() throw ( RuntimeException )
     640             : {
     641           0 :     DocumentGuard aGuard( *this );
     642             : 
     643             :     // The implementation here is somewhat sloppy, in that it returns whether *any* part of the whole
     644             :     // database document, including opened sub components, is modified. This is more than what is requested:
     645             :     // We need to return <TRUE/> if the doc itself, or any of the opened sub components, has been modified
     646             :     // since the last call to any of the save* methods, or since the document has been loaded/created.
     647             :     // However, the API definition explicitly allows to be that sloppy ...
     648             : 
     649           0 :     if ( isModified() )
     650           0 :         return sal_True;
     651             : 
     652             :     // auto recovery is an "UI feature", it is to restore the UI the user knows. Thus,
     653             :     // we ask our connected controllers, not simply our existing form/report definitions.
     654             :     // (There is some information which even cannot be obtained without asking the controller.
     655             :     // For instance, newly created, but not yet saved, forms/reports are acessible via the
     656             :     // controller only, but not via the model.)
     657             : 
     658             :     try
     659             :     {
     660           0 :         for (   Controllers::const_iterator ctrl = m_aControllers.begin();
     661           0 :                 ctrl != m_aControllers.end();
     662             :                 ++ctrl
     663             :             )
     664             :         {
     665           0 :             if ( lcl_hasAnyModifiedSubComponent_throw( *ctrl ) )
     666           0 :                 return sal_True;
     667             :         }
     668             :     }
     669           0 :     catch( const Exception& )
     670             :     {
     671             :         DBG_UNHANDLED_EXCEPTION();
     672             :     }
     673             : 
     674           0 :     return sal_False;
     675             : }
     676             : 
     677           0 : void SAL_CALL ODatabaseDocument::storeToRecoveryFile( const ::rtl::OUString& i_TargetLocation, const Sequence< PropertyValue >& i_MediaDescriptor ) throw ( RuntimeException, IOException, WrappedTargetException )
     678             : {
     679           0 :     DocumentGuard aGuard( *this );
     680           0 :     ModifyLock aLock( *this );
     681             : 
     682             :     try
     683             :     {
     684             :         // create a storage for the target location
     685           0 :         Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( i_TargetLocation ) );
     686             : 
     687             :         // first store the document as a whole into this storage
     688           0 :         impl_storeToStorage_throw( xTargetStorage, i_MediaDescriptor, aGuard );
     689             : 
     690             :         // save the sub components which need saving
     691           0 :         DatabaseDocumentRecovery aDocRecovery( m_pImpl->m_aContext);
     692           0 :         aDocRecovery.saveModifiedSubComponents( xTargetStorage, m_aControllers );
     693             : 
     694             :         // commit the root storage
     695           0 :         tools::stor::commitStorageIfWriteable( xTargetStorage );
     696             :     }
     697           0 :     catch( const Exception& )
     698             :     {
     699           0 :         Any aError = ::cppu::getCaughtException();
     700           0 :         if  (   aError.isExtractableTo( ::cppu::UnoType< IOException >::get() )
     701           0 :             ||  aError.isExtractableTo( ::cppu::UnoType< RuntimeException >::get() )
     702           0 :             ||  aError.isExtractableTo( ::cppu::UnoType< WrappedTargetException >::get() )
     703             :             )
     704             :         {
     705             :             // allowed to leave
     706           0 :             throw;
     707             :         }
     708             : 
     709           0 :         throw WrappedTargetException( ::rtl::OUString(), *this, aError );
     710           0 :     }
     711           0 : }
     712             : 
     713           0 : void SAL_CALL ODatabaseDocument::recoverFromFile( const ::rtl::OUString& i_SourceLocation, const ::rtl::OUString& i_SalvagedFile, const Sequence< PropertyValue >& i_MediaDescriptor ) throw ( RuntimeException, IOException, WrappedTargetException )
     714             : {
     715           0 :     DocumentGuard aGuard( *this, DocumentGuard::InitMethod );
     716             : 
     717           0 :     if ( i_SourceLocation.isEmpty() )
     718           0 :         throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
     719             : 
     720             :     try
     721             :     {
     722             :         // load the document itself, by simply delegating to our "load" method
     723             : 
     724             :         // our load implementation expects the SalvagedFile and URL to be in the media descriptor
     725           0 :         ::comphelper::NamedValueCollection aMediaDescriptor( i_MediaDescriptor );
     726           0 :         aMediaDescriptor.put( "SalvagedFile", i_SalvagedFile );
     727           0 :         aMediaDescriptor.put( "URL", i_SourceLocation );
     728             : 
     729           0 :         aGuard.clear(); // (load has an own guarding scheme)
     730           0 :         load( aMediaDescriptor.getPropertyValues() );
     731             : 
     732             :         // Without a controller, we are unable to recover the sub components, as they're always tied to a controller.
     733             :         // So, everything else is done when the first controller is connected.
     734           0 :         m_bHasBeenRecovered = true;
     735             : 
     736             :         // tell the impl that we've been loaded from the given location
     737           0 :         m_pImpl->setDocFileLocation( i_SourceLocation );
     738             : 
     739             :         // by definition (of XDocumentRecovery), we're responsible for delivering a fully-initialized document,
     740             :         // which includes an attachResource call.
     741           0 :         const ::rtl::OUString sLogicalDocumentURL( i_SalvagedFile.isEmpty() ?  i_SourceLocation : i_SalvagedFile  );
     742           0 :         impl_attachResource( sLogicalDocumentURL, aMediaDescriptor.getPropertyValues(), aGuard );
     743             :         // <- SYNCHRONIZED
     744             :     }
     745           0 :     catch( const Exception& )
     746             :     {
     747           0 :         Any aError = ::cppu::getCaughtException();
     748           0 :         if  (   aError.isExtractableTo( ::cppu::UnoType< IOException >::get() )
     749           0 :             ||  aError.isExtractableTo( ::cppu::UnoType< RuntimeException >::get() )
     750           0 :             ||  aError.isExtractableTo( ::cppu::UnoType< WrappedTargetException >::get() )
     751             :             )
     752             :         {
     753             :             // allowed to leave
     754           0 :             throw;
     755             :         }
     756             : 
     757           0 :         throw WrappedTargetException( ::rtl::OUString(), *this, aError );
     758           0 :     }
     759           0 : }
     760             : 
     761             : // XModel
     762           0 : sal_Bool SAL_CALL ODatabaseDocument::attachResource( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (RuntimeException)
     763             : {
     764           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
     765           0 :     return impl_attachResource( _rURL, _rArguments, aGuard );
     766             : }
     767             : 
     768           0 : sal_Bool ODatabaseDocument::impl_attachResource( const ::rtl::OUString& i_rLogicalDocumentURL,
     769             :             const Sequence< PropertyValue >& i_rMediaDescriptor, DocumentGuard& _rDocGuard )
     770             : {
     771           0 :     if  (   ( i_rLogicalDocumentURL == getURL() )
     772           0 :         &&  ( i_rMediaDescriptor.getLength() == 1 )
     773           0 :         &&  ( i_rMediaDescriptor[0].Name.compareToAscii( "BreakMacroSignature" ) == 0 )
     774             :         )
     775             :     {
     776             :         // this is a BAD hack of the Basic importer code ... there should be a dedicated API for this,
     777             :         // not this bad mis-using of existing interfaces
     778           0 :         return sal_False;
     779             :             // (we do not support macro signatures, so we can ignore this call)
     780             :     }
     781             : 
     782             :     // if no URL has been provided, the caller was lazy enough to not call our getURL - which is not allowed anymore,
     783             :     // now since getURL and getLocation both return the same, so calling one of those should be simple.
     784           0 :     ::rtl::OUString sDocumentURL( i_rLogicalDocumentURL );
     785             :     OSL_ENSURE( !sDocumentURL.isEmpty(), "ODatabaseDocument::impl_attachResource: invalid URL!" );
     786           0 :     if ( sDocumentURL.isEmpty() )
     787           0 :         sDocumentURL = getURL();
     788             : 
     789           0 :     m_pImpl->setResource( sDocumentURL, i_rMediaDescriptor );
     790             : 
     791           0 :     if ( impl_isInitializing() )
     792             :     {   // this means we've just been loaded, and this is the attachResource call which follows
     793             :         // the load call.
     794           0 :         impl_setInitialized();
     795             : 
     796             :         // determine whether the document as a whole, or sub documents, have macros. Especially the latter
     797             :         // controls the availability of our XEmbeddedScripts and XScriptInvocationContext interfaces, and we
     798             :         // should know this before anybody actually uses the object.
     799           0 :         m_bAllowDocumentScripting = ( m_pImpl->determineEmbeddedMacros() != ODatabaseModelImpl::eSubDocumentMacros );
     800             : 
     801           0 :         _rDocGuard.clear();
     802             :         // <- SYNCHRONIZED
     803           0 :         m_aEventNotifier.notifyDocumentEvent( "OnLoadFinished" );
     804             :     }
     805             : 
     806           0 :     return sal_True;
     807             : }
     808             : 
     809           0 : ::rtl::OUString SAL_CALL ODatabaseDocument::getURL(  ) throw (RuntimeException)
     810             : {
     811           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
     812           0 :     return m_pImpl->getURL();
     813             : }
     814             : 
     815           0 : Sequence< PropertyValue > SAL_CALL ODatabaseDocument::getArgs(  ) throw (RuntimeException)
     816             : {
     817           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
     818           0 :     return m_pImpl->getMediaDescriptor().getPropertyValues();
     819             : }
     820             : 
     821           0 : void SAL_CALL ODatabaseDocument::connectController( const Reference< XController >& _xController ) throw (RuntimeException)
     822             : {
     823           0 :     DocumentGuard aGuard( *this );
     824             : 
     825             : #if OSL_DEBUG_LEVEL > 0
     826             :     for (   Controllers::const_iterator controller = m_aControllers.begin();
     827             :             controller != m_aControllers.end();
     828             :             ++controller
     829             :         )
     830             :     {
     831             :         OSL_ENSURE( *controller != _xController, "ODatabaseDocument::connectController: this controller is already connected!" );
     832             :     }
     833             : #endif
     834             : 
     835           0 :     m_aControllers.push_back( _xController );
     836             : 
     837           0 :     m_aEventNotifier.notifyDocumentEventAsync( "OnViewCreated", Reference< XController2 >( _xController, UNO_QUERY ) );
     838             : 
     839           0 :     bool bFirstControllerEver = m_aViewMonitor.onControllerConnected( _xController );
     840           0 :     if ( !bFirstControllerEver )
     841           0 :         return;
     842             : 
     843             :     // check/adjust our macro mode.
     844           0 :     m_pImpl->checkMacrosOnLoading();
     845             : }
     846             : 
     847           0 : void SAL_CALL ODatabaseDocument::disconnectController( const Reference< XController >& _xController ) throw (RuntimeException)
     848             : {
     849           0 :     bool bNotifyViewClosed = false;
     850           0 :     bool bLastControllerGone = false;
     851           0 :     bool bIsClosing = false;
     852             : 
     853             :     // SYNCHRONIZED ->
     854             :     {
     855           0 :         DocumentGuard aGuard( *this );
     856             : 
     857           0 :         Controllers::iterator pos = ::std::find( m_aControllers.begin(), m_aControllers.end(), _xController );
     858             :         OSL_ENSURE( pos != m_aControllers.end(), "ODatabaseDocument::disconnectController: don't know this controller!" );
     859           0 :         if ( pos != m_aControllers.end() )
     860             :         {
     861           0 :             m_aControllers.erase( pos );
     862           0 :             bNotifyViewClosed = true;
     863             :         }
     864             : 
     865           0 :         if ( m_xCurrentController == _xController )
     866           0 :             m_xCurrentController = NULL;
     867             : 
     868           0 :         bLastControllerGone = m_aControllers.empty();
     869           0 :         bIsClosing = m_bClosing;
     870             :     }
     871             :     // <- SYNCHRONIZED
     872             : 
     873           0 :     if ( bNotifyViewClosed )
     874           0 :         m_aEventNotifier.notifyDocumentEvent( "OnViewClosed", Reference< XController2 >( _xController, UNO_QUERY ) );
     875             : 
     876           0 :     if ( bLastControllerGone && !bIsClosing )
     877             :     {
     878             :         // if this was the last view, close the document as a whole
     879             :         // #i51157#
     880             :         try
     881             :         {
     882           0 :             close( sal_True );
     883             :         }
     884           0 :         catch( const CloseVetoException& )
     885             :         {
     886             :             // okay, somebody vetoed and took ownership
     887             :         }
     888             :     }
     889           0 : }
     890             : 
     891           0 : void SAL_CALL ODatabaseDocument::lockControllers(  ) throw (RuntimeException)
     892             : {
     893           0 :     DocumentGuard aGuard( *this );
     894             : 
     895           0 :     ++m_pImpl->m_nControllerLockCount;
     896           0 : }
     897             : 
     898           0 : void SAL_CALL ODatabaseDocument::unlockControllers(  ) throw (RuntimeException)
     899             : {
     900           0 :     DocumentGuard aGuard( *this );
     901             : 
     902           0 :     --m_pImpl->m_nControllerLockCount;
     903           0 : }
     904             : 
     905           0 : sal_Bool SAL_CALL ODatabaseDocument::hasControllersLocked(  ) throw (RuntimeException)
     906             : {
     907           0 :     DocumentGuard aGuard( *this );
     908             : 
     909           0 :     return m_pImpl->m_nControllerLockCount != 0;
     910             : }
     911             : 
     912           0 : Reference< XController > SAL_CALL ODatabaseDocument::getCurrentController() throw (RuntimeException)
     913             : {
     914           0 :     DocumentGuard aGuard( *this );
     915             : 
     916           0 :     return m_xCurrentController.is() ? m_xCurrentController : ( m_aControllers.empty() ? Reference< XController >() : *m_aControllers.begin() );
     917             : }
     918             : 
     919           0 : void SAL_CALL ODatabaseDocument::setCurrentController( const Reference< XController >& _xController ) throw (NoSuchElementException, RuntimeException)
     920             : {
     921           0 :     DocumentGuard aGuard( *this );
     922             : 
     923           0 :     m_xCurrentController = _xController;
     924             : 
     925           0 :     if ( !m_aViewMonitor.onSetCurrentController( _xController ) )
     926             :         return;
     927             : 
     928             :     // check if there are sub components to recover from our document storage
     929           0 :     bool bAttemptRecovery = m_bHasBeenRecovered;
     930           0 :     if ( !bAttemptRecovery && m_pImpl->getMediaDescriptor().has( "ForceRecovery" ) )
     931             :         // do not use getOrDefault, it will throw for invalid types, which is not desired here
     932           0 :         m_pImpl->getMediaDescriptor().get( "ForceRecovery" ) >>= bAttemptRecovery;
     933             : 
     934           0 :     if ( !bAttemptRecovery )
     935             :         return;
     936             : 
     937             :     try
     938             :     {
     939           0 :         DatabaseDocumentRecovery aDocRecovery( m_pImpl->m_aContext );
     940           0 :         aDocRecovery.recoverSubDocuments( m_pImpl->getRootStorage(), _xController );
     941             :     }
     942           0 :     catch( const Exception& )
     943             :     {
     944             :         DBG_UNHANDLED_EXCEPTION();
     945           0 :     }
     946             : }
     947             : 
     948           0 : Reference< XInterface > SAL_CALL ODatabaseDocument::getCurrentSelection(  ) throw (RuntimeException)
     949             : {
     950           0 :     DocumentGuard aGuard( *this );
     951             : 
     952           0 :     Reference< XInterface > xRet;
     953           0 :     Reference< XSelectionSupplier >  xDocView( getCurrentController(), UNO_QUERY );
     954           0 :     if ( xDocView.is() )
     955           0 :         xRet.set(xDocView->getSelection(),UNO_QUERY);
     956             : 
     957           0 :     return xRet;
     958             : }
     959             : 
     960             : // XStorable
     961           0 : sal_Bool SAL_CALL ODatabaseDocument::hasLocation(  ) throw (RuntimeException)
     962             : {
     963           0 :     return !getLocation().isEmpty();
     964             : }
     965             : 
     966           0 : ::rtl::OUString SAL_CALL ODatabaseDocument::getLocation(  ) throw (RuntimeException)
     967             : {
     968           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
     969           0 :     return m_pImpl->getURL();
     970             :         // both XStorable::getLocation and XModel::getURL have to return the URL of the document, *not*
     971             :         // the location of the file which the docunment was possibly recovered from (which would be getDocFileLocation)
     972             : }
     973             : 
     974           0 : sal_Bool SAL_CALL ODatabaseDocument::isReadonly(  ) throw (RuntimeException)
     975             : {
     976           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
     977           0 :     return m_pImpl->m_bDocumentReadOnly;
     978             : }
     979             : 
     980           0 : void SAL_CALL ODatabaseDocument::store(  ) throw (IOException, RuntimeException)
     981             : {
     982           0 :     DocumentGuard aGuard( *this );
     983             : 
     984           0 :     ::rtl::OUString sDocumentURL( m_pImpl->getURL() );
     985           0 :     if ( !sDocumentURL.isEmpty() )
     986             :     {
     987           0 :         if ( m_pImpl->getDocFileLocation() == m_pImpl->getURL() )
     988           0 :             if ( m_pImpl->m_bDocumentReadOnly )
     989           0 :                 throw IOException();
     990             : 
     991           0 :         impl_storeAs_throw( m_pImpl->getURL(), m_pImpl->getMediaDescriptor(), SAVE, aGuard );
     992           0 :         return;
     993             :     }
     994             : 
     995             :     // if we have no URL, but did survive the DocumentGuard above, then we've been inited via XLoadable::initNew,
     996             :     // i.e. we're based on a temporary storage
     997             :     OSL_ENSURE( m_pImpl->getDocFileLocation().isEmpty(), "ODatabaseDocument::store: unexpected URL inconsistency!" );
     998             : 
     999             :     try
    1000             :     {
    1001           0 :         impl_storeToStorage_throw( m_pImpl->getRootStorage(), m_pImpl->getMediaDescriptor().getPropertyValues(), aGuard );
    1002             :     }
    1003           0 :     catch( const Exception& )
    1004             :     {
    1005           0 :         Any aError = ::cppu::getCaughtException();
    1006           0 :         if  (   aError.isExtractableTo( ::cppu::UnoType< IOException >::get() )
    1007           0 :             ||  aError.isExtractableTo( ::cppu::UnoType< RuntimeException >::get() )
    1008             :             )
    1009             :         {
    1010             :             // allowed to leave
    1011           0 :             throw;
    1012             :         }
    1013           0 :         impl_throwIOExceptionCausedBySave_throw( aError, ::rtl::OUString() );
    1014           0 :     }
    1015             : }
    1016             : 
    1017           0 : void ODatabaseDocument::impl_throwIOExceptionCausedBySave_throw( const Any& i_rError, const ::rtl::OUString& i_rTargetURL ) const
    1018             : {
    1019           0 :     ::rtl::OUString sErrorMessage = extractExceptionMessage( m_pImpl->m_aContext, i_rError );
    1020             :     sErrorMessage = ResourceManager::loadString(
    1021             :         RID_STR_ERROR_WHILE_SAVING,
    1022             :         "$location$", i_rTargetURL,
    1023             :         "$message$", sErrorMessage
    1024           0 :     );
    1025           0 :     throw IOException( sErrorMessage, *const_cast< ODatabaseDocument* >( this ) );
    1026             : }
    1027             : 
    1028           0 : void ODatabaseDocument::impl_storeAs_throw( const ::rtl::OUString& _rURL, const ::comphelper::NamedValueCollection& _rArguments,
    1029             :     const StoreType _eType, DocumentGuard& _rGuard ) throw ( IOException, RuntimeException )
    1030             : {
    1031             :     OSL_PRECOND( ( _eType == SAVE ) || ( _eType == SAVE_AS ),
    1032             :         "ODatabaseDocument::impl_storeAs_throw: you introduced a new type which cannot be handled here!" );
    1033             : 
    1034             :     // if we're in the process of initializing the document (which effectively means it is an implicit
    1035             :     // initialization triggered in storeAsURL), the we do not notify events, since to an observer, the SaveAs
    1036             :     // should not be noticable
    1037           0 :     bool bIsInitializationProcess = impl_isInitializing();
    1038             : 
    1039           0 :     if ( !bIsInitializationProcess )
    1040             :     {
    1041           0 :         _rGuard.clear();
    1042           0 :         m_aEventNotifier.notifyDocumentEvent( _eType == SAVE ? "OnSave" : "OnSaveAs", NULL, makeAny( _rURL ) );
    1043           0 :         _rGuard.reset();
    1044             :     }
    1045             : 
    1046           0 :     Reference< XStorage > xNewRootStorage;
    1047             :         // will be non-NULL if our storage changed
    1048             : 
    1049             :     try
    1050             :     {
    1051           0 :         ModifyLock aLock( *this );
    1052             :             // ignore all changes of our "modified" state during storing
    1053             : 
    1054           0 :         sal_Bool bLocationChanged = ( _rURL != m_pImpl->getDocFileLocation() );
    1055           0 :         if ( bLocationChanged )
    1056             :         {
    1057             :             // create storage for target URL
    1058           0 :             Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( _rURL ) );
    1059             : 
    1060           0 :             if ( m_pImpl->isEmbeddedDatabase() )
    1061           0 :                 m_pImpl->clearConnections();
    1062             : 
    1063             :             // commit everything
    1064           0 :             m_pImpl->commitEmbeddedStorage();
    1065           0 :             m_pImpl->commitStorages();
    1066             : 
    1067             :             // copy own storage to target storage
    1068           0 :             Reference< XStorage > xCurrentStorage( m_pImpl->getRootStorage() );
    1069           0 :             if ( xCurrentStorage.is() )
    1070           0 :                 xCurrentStorage->copyToStorage( xTargetStorage );
    1071             : 
    1072           0 :             m_pImpl->disposeStorages();
    1073             : 
    1074             :             // each and every document definition obtained via m_xForms and m_xReports depends
    1075             :             // on the sub storages which we just disposed. So, dispose the forms/reports collections, too.
    1076             :             // This ensures that they're re-created when needed.
    1077           0 :             clearObjectContainer( m_xForms );
    1078           0 :             clearObjectContainer( m_xReports );
    1079             : 
    1080           0 :             xNewRootStorage = m_pImpl->switchToStorage( xTargetStorage );
    1081             : 
    1082           0 :             m_pImpl->m_bDocumentReadOnly = sal_False;
    1083             :         }
    1084             : 
    1085             :         // store to current storage
    1086           0 :         Reference< XStorage > xCurrentStorage( m_pImpl->getOrCreateRootStorage(), UNO_QUERY_THROW );
    1087           0 :         Sequence< PropertyValue > aMediaDescriptor( lcl_appendFileNameToDescriptor( _rArguments, _rURL ) );
    1088           0 :         impl_storeToStorage_throw( xCurrentStorage, aMediaDescriptor, _rGuard );
    1089             : 
    1090             :         // success - tell our impl
    1091           0 :         m_pImpl->setDocFileLocation( _rURL );
    1092           0 :         m_pImpl->setResource( _rURL, aMediaDescriptor );
    1093             : 
    1094             :         // if we are in an initialization process, then this is finished, now that we stored the document
    1095           0 :         if ( bIsInitializationProcess )
    1096           0 :             impl_setInitialized();
    1097             :     }
    1098           0 :     catch( const Exception& )
    1099             :     {
    1100           0 :         Any aError = ::cppu::getCaughtException();
    1101             : 
    1102             :         // notify the failure
    1103           0 :         if ( !bIsInitializationProcess )
    1104           0 :             m_aEventNotifier.notifyDocumentEventAsync( _eType == SAVE ? "OnSaveFailed" : "OnSaveAsFailed", NULL, makeAny( _rURL ) );
    1105             : 
    1106           0 :         if  (   aError.isExtractableTo( ::cppu::UnoType< IOException >::get() )
    1107           0 :             ||  aError.isExtractableTo( ::cppu::UnoType< RuntimeException >::get() )
    1108             :             )
    1109             :         {
    1110             :             // allowed to leave
    1111           0 :             throw;
    1112             :         }
    1113             : 
    1114           0 :         impl_throwIOExceptionCausedBySave_throw( aError, _rURL );
    1115             :     }
    1116             : 
    1117             :     // notify the document event
    1118           0 :     if ( !bIsInitializationProcess )
    1119           0 :         m_aEventNotifier.notifyDocumentEventAsync( _eType == SAVE ? "OnSaveDone" : "OnSaveAsDone", NULL, makeAny( _rURL ) );
    1120             : 
    1121             :     // reset our "modified" flag, and clear the guard
    1122           0 :     impl_setModified_nothrow( sal_False, _rGuard );
    1123             :     // <- SYNCHRONIZED
    1124             : 
    1125             :     // notify storage listeners
    1126           0 :     if ( xNewRootStorage.is() )
    1127           0 :         impl_notifyStorageChange_nolck_nothrow( xNewRootStorage );
    1128           0 : }
    1129             : 
    1130           0 : Reference< XStorage > ODatabaseDocument::impl_createStorageFor_throw( const ::rtl::OUString& _rURL ) const
    1131             : {
    1132           0 :     Reference< ucb::XSimpleFileAccess3 > xTempAccess(ucb::SimpleFileAccess::create(m_pImpl->m_aContext.getUNOContext()));
    1133           0 :     Reference< io::XStream > xStream = xTempAccess->openFileReadWrite( _rURL );
    1134           0 :     Reference< io::XTruncate > xTruncate(xStream,UNO_QUERY);
    1135           0 :     if ( xTruncate.is() )
    1136             :     {
    1137           0 :         xTruncate->truncate();
    1138             :     }
    1139           0 :     Sequence<Any> aParam(2);
    1140           0 :     aParam[0] <<= xStream;
    1141           0 :     aParam[1] <<= ElementModes::READWRITE | ElementModes::TRUNCATE;
    1142             : 
    1143           0 :     Reference< XSingleServiceFactory > xStorageFactory( m_pImpl->createStorageFactory(), UNO_SET_THROW );
    1144           0 :     return Reference< XStorage >( xStorageFactory->createInstanceWithArguments( aParam ), UNO_QUERY_THROW );
    1145             : }
    1146             : 
    1147           0 : void SAL_CALL ODatabaseDocument::storeAsURL( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (IOException, RuntimeException)
    1148             : {
    1149             :     // SYNCHRONIZED ->
    1150           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
    1151             : 
    1152             :     // Normally, a document initialization is done via XLoadable::load or XLoadable::initNew. For convenience
    1153             :     // reasons, and to not break existing API clients, it's allowed to call storeAsURL without having initialized
    1154             :     // the document, in which case the initialization will be done implicitly.
    1155           0 :     bool bImplicitInitialization = !impl_isInitialized();
    1156             :     // implicit initialization while another initialization is just running is not possible
    1157           0 :     if ( bImplicitInitialization && impl_isInitializing() )
    1158           0 :         throw DoubleInitializationException();
    1159             : 
    1160           0 :     if ( bImplicitInitialization )
    1161           0 :         impl_setInitializing();
    1162             : 
    1163             :     try
    1164             :     {
    1165           0 :         impl_storeAs_throw( _rURL, _rArguments, SAVE_AS, aGuard );
    1166             :         // <- SYNCHRONIZED
    1167             : 
    1168             :         // impl_storeAs_throw cleared the lock on our mutex, but the below lines need this lock
    1169             :         // SYNCHRONIZED ->
    1170           0 :         aGuard.reset();
    1171             : 
    1172             :         // our title might have changed, potentially at least
    1173             :         // Sadly, we cannot check this: Calling getTitle here and now would not deliver
    1174             :         // an up-to-date result, as the call is delegated to our TitleHelper instance, which itself
    1175             :         // updates its title only if it gets the OnSaveAsDone event (which was sent asynchronously
    1176             :         // by impl_storeAs_throw). So, we simply notify always, and also asynchronously
    1177           0 :         m_aEventNotifier.notifyDocumentEventAsync( "OnTitleChanged" );
    1178             :     }
    1179           0 :     catch( const Exception& )
    1180             :     {
    1181           0 :         impl_reset_nothrow();
    1182           0 :         throw;
    1183             :     }
    1184             : 
    1185           0 :     if ( bImplicitInitialization )
    1186           0 :         m_bAllowDocumentScripting = true;
    1187             : 
    1188           0 :     aGuard.clear();
    1189             :     // <- SYNCHRONIZED
    1190             : 
    1191           0 :     if ( bImplicitInitialization )
    1192           0 :         m_aEventNotifier.notifyDocumentEvent( "OnCreate" );
    1193           0 : }
    1194             : 
    1195           0 : void ODatabaseDocument::impl_storeToStorage_throw( const Reference< XStorage >& _rxTargetStorage, const Sequence< PropertyValue >& _rMediaDescriptor,
    1196             :                                                    DocumentGuard& _rDocGuard ) const
    1197             : {
    1198           0 :     if ( !_rxTargetStorage.is() )
    1199           0 :         throw IllegalArgumentException( ::rtl::OUString(), *const_cast< ODatabaseDocument* >( this ), 1 );
    1200             : 
    1201           0 :     if ( !m_pImpl.is() )
    1202           0 :         throw DisposedException( ::rtl::OUString(), *const_cast< ODatabaseDocument* >( this ) );
    1203             : 
    1204             :     try
    1205             :     {
    1206             :         // commit everything
    1207           0 :         m_pImpl->commitEmbeddedStorage();
    1208           0 :         m_pImpl->commitStorages();
    1209             : 
    1210             :         // copy own storage to target storage
    1211           0 :         if ( impl_isInitialized() )
    1212             :         {
    1213           0 :             Reference< XStorage > xCurrentStorage( m_pImpl->getOrCreateRootStorage(), UNO_QUERY_THROW );
    1214           0 :             if ( xCurrentStorage != _rxTargetStorage )
    1215           0 :                 xCurrentStorage->copyToStorage( _rxTargetStorage );
    1216             :         }
    1217             : 
    1218             :         // write into target storage
    1219           0 :         ::comphelper::NamedValueCollection aWriteArgs( _rMediaDescriptor );
    1220           0 :         lcl_triggerStatusIndicator_throw( aWriteArgs, _rDocGuard, true );
    1221           0 :         impl_writeStorage_throw( _rxTargetStorage, aWriteArgs );
    1222           0 :         lcl_triggerStatusIndicator_throw( aWriteArgs, _rDocGuard, false );
    1223             : 
    1224             :         // commit target storage
    1225           0 :         OSL_VERIFY( tools::stor::commitStorageIfWriteable( _rxTargetStorage ) );
    1226             :     }
    1227           0 :     catch( const IOException& ) { throw; }
    1228           0 :     catch( const RuntimeException& ) { throw; }
    1229           0 :     catch ( const Exception& e )
    1230             :     {
    1231           0 :         throw IOException( e.Message, *const_cast< ODatabaseDocument* >( this ) );
    1232             :     }
    1233           0 : }
    1234             : 
    1235           0 : void SAL_CALL ODatabaseDocument::storeToURL( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (IOException, RuntimeException)
    1236             : {
    1237           0 :     DocumentGuard aGuard( *this );
    1238           0 :     ModifyLock aLock( *this );
    1239             : 
    1240             :     {
    1241           0 :         aGuard.clear();
    1242           0 :         m_aEventNotifier.notifyDocumentEvent( "OnSaveTo", NULL, makeAny( _rURL ) );
    1243           0 :         aGuard.reset();
    1244             :     }
    1245             : 
    1246             :     try
    1247             :     {
    1248             :         // create storage for target URL
    1249           0 :         Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( _rURL ) );
    1250             : 
    1251             :         // extend media descriptor with URL
    1252           0 :         Sequence< PropertyValue > aMediaDescriptor( lcl_appendFileNameToDescriptor( _rArguments, _rURL ) );
    1253             : 
    1254             :         // store to this storage
    1255           0 :         impl_storeToStorage_throw( xTargetStorage, aMediaDescriptor, aGuard );
    1256             :     }
    1257           0 :     catch( const Exception& )
    1258             :     {
    1259           0 :         Any aError = ::cppu::getCaughtException();
    1260           0 :         m_aEventNotifier.notifyDocumentEventAsync( "OnSaveToFailed", NULL, aError );
    1261             : 
    1262           0 :         if  (   aError.isExtractableTo( ::cppu::UnoType< IOException >::get() )
    1263           0 :             ||  aError.isExtractableTo( ::cppu::UnoType< RuntimeException >::get() )
    1264             :             )
    1265             :         {
    1266             :             // allowed to leave
    1267           0 :             throw;
    1268             :         }
    1269             : 
    1270           0 :         impl_throwIOExceptionCausedBySave_throw( aError, _rURL );
    1271             :     }
    1272             : 
    1273           0 :     m_aEventNotifier.notifyDocumentEventAsync( "OnSaveToDone", NULL, makeAny( _rURL ) );
    1274           0 : }
    1275             : 
    1276             : // XModifyBroadcaster
    1277           0 : void SAL_CALL ODatabaseDocument::addModifyListener( const Reference< XModifyListener >& _xListener ) throw (RuntimeException)
    1278             : {
    1279           0 :     DocumentGuard aGuard( *this );
    1280           0 :     m_aModifyListeners.addInterface(_xListener);
    1281           0 : }
    1282             : 
    1283           0 : void SAL_CALL ODatabaseDocument::removeModifyListener( const Reference< XModifyListener >& _xListener ) throw (RuntimeException)
    1284             : {
    1285           0 :     DocumentGuard aGuard( *this );
    1286           0 :     m_aModifyListeners.removeInterface(_xListener);
    1287           0 : }
    1288             : 
    1289             : // XModifiable
    1290           0 : sal_Bool SAL_CALL ODatabaseDocument::isModified(  ) throw (RuntimeException)
    1291             : {
    1292           0 :     DocumentGuard aGuard( *this );
    1293             : 
    1294           0 :     return m_pImpl->m_bModified;
    1295             : }
    1296             : 
    1297           0 : void SAL_CALL ODatabaseDocument::setModified( sal_Bool _bModified ) throw (PropertyVetoException, RuntimeException)
    1298             : {
    1299           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
    1300           0 :     if ( impl_isInitialized() )
    1301           0 :         impl_setModified_nothrow( _bModified, aGuard );
    1302             :     // it's allowed to call setModified without the document being initialized already. In this case,
    1303             :     // we simply ignore the call - when the initialization is finished, the respective code will set
    1304             :     // a proper "modified" flag
    1305           0 : }
    1306             : 
    1307           0 : void ODatabaseDocument::impl_setModified_nothrow( sal_Bool _bModified, DocumentGuard& _rGuard )
    1308             : {
    1309             :     // SYNCHRONIZED ->
    1310           0 :     bool bModifiedChanged = ( m_pImpl->m_bModified != _bModified ) && ( !m_pImpl->isModifyLocked() );
    1311             : 
    1312           0 :     if ( bModifiedChanged )
    1313             :     {
    1314           0 :         m_pImpl->m_bModified = _bModified;
    1315           0 :         m_aEventNotifier.notifyDocumentEventAsync( "OnModifyChanged" );
    1316             :     }
    1317           0 :     _rGuard.clear();
    1318             :     // <- SYNCHRONIZED
    1319             : 
    1320           0 :     if ( bModifiedChanged )
    1321             :     {
    1322           0 :         lang::EventObject aEvent( *this );
    1323           0 :         m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvent );
    1324             :     }
    1325           0 : }
    1326             : 
    1327             : // ::com::sun::star::document::XEventBroadcaster
    1328           0 : void SAL_CALL ODatabaseDocument::addEventListener(const uno::Reference< document::XEventListener >& _Listener ) throw (uno::RuntimeException)
    1329             : {
    1330           0 :     m_aEventNotifier.addLegacyEventListener( _Listener );
    1331           0 : }
    1332             : 
    1333           0 : void SAL_CALL ODatabaseDocument::removeEventListener( const uno::Reference< document::XEventListener >& _Listener ) throw (uno::RuntimeException)
    1334             : {
    1335           0 :     m_aEventNotifier.removeLegacyEventListener( _Listener );
    1336           0 : }
    1337             : 
    1338           0 : void SAL_CALL ODatabaseDocument::addDocumentEventListener( const Reference< XDocumentEventListener >& _Listener ) throw (RuntimeException)
    1339             : {
    1340           0 :     m_aEventNotifier.addDocumentEventListener( _Listener );
    1341           0 : }
    1342             : 
    1343           0 : void SAL_CALL ODatabaseDocument::removeDocumentEventListener( const Reference< XDocumentEventListener >& _Listener ) throw (RuntimeException)
    1344             : {
    1345           0 :     m_aEventNotifier.removeDocumentEventListener( _Listener );
    1346           0 : }
    1347             : 
    1348           0 : void SAL_CALL ODatabaseDocument::notifyDocumentEvent( const ::rtl::OUString& _EventName, const Reference< XController2 >& _ViewController, const Any& _Supplement ) throw (IllegalArgumentException, NoSupportException, RuntimeException)
    1349             : {
    1350           0 :     if ( _EventName.isEmpty() )
    1351           0 :         throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
    1352             : 
    1353             :     // SYNCHRONIZED ->
    1354           0 :     DocumentGuard aGuard( *this );
    1355             : 
    1356           0 :     if ( !DocumentEvents::needsSynchronousNotification( _EventName ) )
    1357             :     {
    1358           0 :         m_aEventNotifier.notifyDocumentEventAsync( _EventName, _ViewController, _Supplement );
    1359           0 :         return;
    1360             :     }
    1361           0 :     aGuard.clear();
    1362             :     // <- SYNCHRONIZED
    1363             : 
    1364           0 :     m_aEventNotifier.notifyDocumentEvent( _EventName, _ViewController, _Supplement );
    1365             : }
    1366             : 
    1367           0 : Sequence< PropertyValue > SAL_CALL ODatabaseDocument::getPrinter(  ) throw (RuntimeException)
    1368             : {
    1369             :     OSL_FAIL( "ODatabaseDocument::getPrinter: not supported!" );
    1370           0 :     return Sequence< PropertyValue >();
    1371             : }
    1372             : 
    1373           0 : void SAL_CALL ODatabaseDocument::setPrinter( const Sequence< PropertyValue >& /*aPrinter*/ ) throw (IllegalArgumentException, RuntimeException)
    1374             : {
    1375             :     OSL_FAIL( "ODatabaseDocument::setPrinter: not supported!" );
    1376           0 : }
    1377             : 
    1378           0 : void SAL_CALL ODatabaseDocument::print( const Sequence< PropertyValue >& /*xOptions*/ ) throw (IllegalArgumentException, RuntimeException)
    1379             : {
    1380             :     OSL_FAIL( "ODatabaseDocument::print: not supported!" );
    1381           0 : }
    1382             : 
    1383           0 : void ODatabaseDocument::impl_reparent_nothrow( const WeakReference< XNameAccess >& _rxContainer )
    1384             : {
    1385           0 :     Reference< XChild > xChild( _rxContainer.get(), UNO_QUERY );
    1386           0 :     if  ( xChild.is() )
    1387           0 :         xChild->setParent( *this );
    1388           0 : }
    1389             : 
    1390           0 : void ODatabaseDocument::clearObjectContainer( WeakReference< XNameAccess >& _rxContainer)
    1391             : {
    1392           0 :     Reference< XNameAccess > xContainer = _rxContainer;
    1393           0 :     ::comphelper::disposeComponent( xContainer );
    1394             : 
    1395           0 :     Reference< XChild > xChild( _rxContainer.get(),UNO_QUERY );
    1396           0 :     if ( xChild.is() )
    1397           0 :         xChild->setParent( NULL );
    1398           0 :     _rxContainer = Reference< XNameAccess >();
    1399           0 : }
    1400             : 
    1401           0 : Reference< XNameAccess > ODatabaseDocument::impl_getDocumentContainer_throw( ODatabaseModelImpl::ObjectType _eType )
    1402             : {
    1403           0 :     if ( ( _eType != ODatabaseModelImpl::E_FORM ) && ( _eType != ODatabaseModelImpl::E_REPORT ) )
    1404           0 :         throw IllegalArgumentException();
    1405             : 
    1406           0 :     bool bFormsContainer = _eType == ODatabaseModelImpl::E_FORM;
    1407             : 
    1408           0 :     WeakReference< XNameAccess >& rContainerRef( bFormsContainer ? m_xForms : m_xReports );
    1409           0 :     Reference< XNameAccess > xContainer = rContainerRef;
    1410           0 :     if ( !xContainer.is() )
    1411             :     {
    1412           0 :         Any aValue;
    1413           0 :         ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xMy(*this);
    1414           0 :         if ( dbtools::getDataSourceSetting(xMy,bFormsContainer ? "Forms" : "Reports",aValue) )
    1415             :         {
    1416           0 :             ::rtl::OUString sSupportService;
    1417           0 :             aValue >>= sSupportService;
    1418           0 :             if ( !sSupportService.isEmpty() )
    1419             :             {
    1420           0 :                 Sequence<Any> aArgs(1);
    1421           0 :                 aArgs[0] <<= NamedValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DatabaseDocument")),makeAny(xMy));
    1422           0 :                 xContainer.set(m_pImpl->m_aContext.createComponentWithArguments(sSupportService,aArgs),UNO_QUERY);
    1423           0 :                 rContainerRef = xContainer;
    1424           0 :             }
    1425             :         }
    1426           0 :         if ( !xContainer.is() )
    1427             :         {
    1428           0 :             TContentPtr& rContainerData( m_pImpl->getObjectContainer( _eType ) );
    1429           0 :             rContainerRef = xContainer = new ODocumentContainer( m_pImpl->m_aContext.getLegacyServiceFactory(), *this, rContainerData, bFormsContainer );
    1430             :         }
    1431           0 :         impl_reparent_nothrow( xContainer );
    1432             :     }
    1433           0 :     return xContainer;
    1434             : }
    1435             : 
    1436           0 : void ODatabaseDocument::impl_closeControllerFrames_nolck_throw( sal_Bool _bDeliverOwnership )
    1437             : {
    1438           0 :     Controllers aCopy = m_aControllers;
    1439             : 
    1440           0 :     Controllers::iterator aEnd = aCopy.end();
    1441           0 :     for ( Controllers::iterator aIter = aCopy.begin(); aIter != aEnd ; ++aIter )
    1442             :     {
    1443           0 :         if ( !aIter->is() )
    1444           0 :             continue;
    1445             : 
    1446             :         try
    1447             :         {
    1448           0 :             Reference< XCloseable> xFrame( (*aIter)->getFrame(), UNO_QUERY );
    1449           0 :             if ( xFrame.is() )
    1450           0 :                 xFrame->close( _bDeliverOwnership );
    1451             :         }
    1452           0 :         catch( const CloseVetoException& ) { throw; }
    1453           0 :         catch( const Exception& )
    1454             :         {
    1455             :             DBG_UNHANDLED_EXCEPTION();
    1456             :         }
    1457           0 :     }
    1458           0 : }
    1459             : 
    1460             : struct DisposeControllerFrame : public ::std::unary_function< Reference< XController >, void >
    1461             : {
    1462           0 :     void operator()( const Reference< XController >& _rxController ) const
    1463             :     {
    1464             :         try
    1465             :         {
    1466           0 :             if ( !_rxController.is() )
    1467           0 :                 return;
    1468             : 
    1469           0 :             Reference< XFrame > xFrame( _rxController->getFrame() );
    1470           0 :             ::comphelper::disposeComponent( xFrame );
    1471             :         }
    1472           0 :         catch( const Exception& )
    1473             :         {
    1474             :             DBG_UNHANDLED_EXCEPTION();
    1475             :         }
    1476             :     };
    1477             : };
    1478             : 
    1479           0 : void ODatabaseDocument::impl_disposeControllerFrames_nothrow()
    1480             : {
    1481           0 :     Controllers aCopy;
    1482           0 :     aCopy.swap( m_aControllers );   // ensure m_aControllers is empty afterwards
    1483           0 :     ::std::for_each( aCopy.begin(), aCopy.end(), DisposeControllerFrame() );
    1484           0 : }
    1485             : 
    1486           0 : void SAL_CALL ODatabaseDocument::close( sal_Bool _bDeliverOwnership ) throw (CloseVetoException, RuntimeException)
    1487             : {
    1488             :     // nearly everything below can/must be done without our mutex locked, the below is just for
    1489             :     // the checks for being disposed and the like
    1490             :     // SYNCHRONIZED ->
    1491             :     {
    1492           0 :         DocumentGuard aGuard( *this );
    1493           0 :         m_bClosing = true;
    1494             :     }
    1495             :     // <- SYNCHRONIZED
    1496             : 
    1497             :     try
    1498             :     {
    1499             :         // allow listeners to veto
    1500           0 :         lang::EventObject aEvent( *this );
    1501             :         m_aCloseListener.forEach< XCloseListener >(
    1502           0 :             boost::bind( &XCloseListener::queryClosing, _1, boost::cref( aEvent ), boost::cref( _bDeliverOwnership ) ) );
    1503             : 
    1504             :         // notify that we're going to unload
    1505           0 :         m_aEventNotifier.notifyDocumentEvent( "OnPrepareUnload" );
    1506             : 
    1507           0 :         impl_closeControllerFrames_nolck_throw( _bDeliverOwnership );
    1508             : 
    1509           0 :         m_aCloseListener.notifyEach( &XCloseListener::notifyClosing, (const lang::EventObject&)aEvent );
    1510             : 
    1511           0 :         dispose();
    1512             :     }
    1513           0 :     catch ( const Exception& )
    1514             :     {
    1515           0 :         ::osl::MutexGuard aGuard( m_aMutex );
    1516           0 :         m_bClosing = false;
    1517           0 :         throw;
    1518             :     }
    1519             : 
    1520             :     // SYNCHRONIZED ->
    1521           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1522           0 :     m_bClosing = false;
    1523             :     // <- SYNCHRONIZED
    1524           0 : }
    1525             : 
    1526           0 : void SAL_CALL ODatabaseDocument::addCloseListener( const Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (RuntimeException)
    1527             : {
    1528           0 :     DocumentGuard aGuard( *this );
    1529           0 :     m_aCloseListener.addInterface(Listener);
    1530           0 : }
    1531             : 
    1532           0 : void SAL_CALL ODatabaseDocument::removeCloseListener( const Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (RuntimeException)
    1533             : {
    1534           0 :     DocumentGuard aGuard( *this );
    1535           0 :     m_aCloseListener.removeInterface(Listener);
    1536           0 : }
    1537             : 
    1538           0 : Reference< XNameAccess > SAL_CALL ODatabaseDocument::getFormDocuments(  ) throw (RuntimeException)
    1539             : {
    1540           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
    1541           0 :     return impl_getDocumentContainer_throw( ODatabaseModelImpl::E_FORM );
    1542             : }
    1543             : 
    1544           0 : Reference< XNameAccess > SAL_CALL ODatabaseDocument::getReportDocuments(  ) throw (RuntimeException)
    1545             : {
    1546           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
    1547           0 :     return impl_getDocumentContainer_throw( ODatabaseModelImpl::E_REPORT );
    1548             : }
    1549             : 
    1550           0 : void ODatabaseDocument::WriteThroughComponent( const Reference< XComponent >& xComponent, const sal_Char* pStreamName,
    1551             :     const sal_Char* pServiceName, const Sequence< Any >& _rArguments, const Sequence< PropertyValue >& rMediaDesc,
    1552             :     const Reference<XStorage>& _xStorageToSaveTo ) const
    1553             : {
    1554             :     OSL_ENSURE( pStreamName, "Need stream name!" );
    1555             :     OSL_ENSURE( pServiceName, "Need service name!" );
    1556             : 
    1557             :     // open stream
    1558           0 :     ::rtl::OUString sStreamName = ::rtl::OUString::createFromAscii( pStreamName );
    1559           0 :     Reference< XStream > xStream = _xStorageToSaveTo->openStreamElement( sStreamName, ElementModes::READWRITE | ElementModes::TRUNCATE );
    1560           0 :     if ( !xStream.is() )
    1561             :         return;
    1562             : 
    1563           0 :     Reference< XOutputStream > xOutputStream( xStream->getOutputStream() );
    1564             :     OSL_ENSURE( xOutputStream.is(), "Can't create output stream in package!" );
    1565           0 :     if ( !xOutputStream.is() )
    1566             :         return;
    1567             : 
    1568           0 :     Reference< XSeekable > xSeek( xOutputStream, UNO_QUERY );
    1569           0 :     if ( xSeek.is() )
    1570           0 :         xSeek->seek(0);
    1571             : 
    1572           0 :     Reference< XPropertySet > xStreamProp( xOutputStream, UNO_QUERY_THROW );
    1573           0 :     xStreamProp->setPropertyValue( INFO_MEDIATYPE, makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "text/xml" ) ) ) );
    1574           0 :     xStreamProp->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), makeAny( (sal_Bool)sal_True ) );
    1575             : 
    1576             :     // write the stuff
    1577           0 :     WriteThroughComponent( xOutputStream, xComponent, pServiceName, _rArguments, rMediaDesc );
    1578             : }
    1579             : 
    1580           0 : void ODatabaseDocument::WriteThroughComponent( const Reference< XOutputStream >& xOutputStream,
    1581             :     const Reference< XComponent >& xComponent, const sal_Char* pServiceName, const Sequence< Any >& _rArguments,
    1582             :     const Sequence< PropertyValue >& rMediaDesc ) const
    1583             : {
    1584             :     OSL_ENSURE( xOutputStream.is(), "I really need an output stream!" );
    1585             :     OSL_ENSURE( xComponent.is(), "Need component!" );
    1586             :     OSL_ENSURE( NULL != pServiceName, "Need component name!" );
    1587             : 
    1588             :     // get component
    1589           0 :     Reference< XWriter > xSaxWriter = xml::sax::Writer::create( m_pImpl->m_aContext.getUNOContext() );
    1590             : 
    1591             :     // connect XML writer to output stream
    1592           0 :     xSaxWriter->setOutputStream( xOutputStream );
    1593             : 
    1594             :     // prepare arguments (prepend doc handler to given arguments)
    1595           0 :     Reference< XDocumentHandler > xDocHandler( xSaxWriter,UNO_QUERY);
    1596           0 :     Sequence<Any> aArgs( 1 + _rArguments.getLength() );
    1597           0 :     aArgs[0] <<= xDocHandler;
    1598           0 :     for ( sal_Int32 i = 0; i < _rArguments.getLength(); ++i )
    1599           0 :         aArgs[ i+1 ] = _rArguments[i];
    1600             : 
    1601             :     // get filter component
    1602           0 :     Reference< XExporter > xExporter;
    1603           0 :     OSL_VERIFY( m_pImpl->m_aContext.createComponentWithArguments( pServiceName, aArgs, xExporter ) );
    1604           0 :     if ( !xExporter.is() )
    1605           0 :         return;
    1606             : 
    1607             :     // connect model and filter
    1608           0 :     xExporter->setSourceDocument( xComponent );
    1609             : 
    1610             :     // filter
    1611           0 :     Reference< XFilter > xFilter( xExporter, UNO_QUERY_THROW );
    1612           0 :     xFilter->filter( rMediaDesc );
    1613             : }
    1614             : 
    1615           0 : void ODatabaseDocument::impl_writeStorage_throw( const Reference< XStorage >& _rxTargetStorage, const ::comphelper::NamedValueCollection& _rMediaDescriptor ) const
    1616             : {
    1617             :     // extract status indicator
    1618           0 :     Sequence< Any > aDelegatorArguments;
    1619           0 :     lcl_extractStatusIndicator( _rMediaDescriptor, aDelegatorArguments );
    1620             : 
    1621             :     /** property map for export info set */
    1622             :     comphelper::PropertyMapEntry aExportInfoMap[] =
    1623             :     {
    1624           0 :         { MAP_LEN( "BaseURI"), 0,&::getCppuType( (::rtl::OUString *)0 ),beans::PropertyAttribute::MAYBEVOID, 0 },
    1625           0 :         { MAP_LEN( "StreamName"), 0,&::getCppuType( (::rtl::OUString *)0 ),beans::PropertyAttribute::MAYBEVOID, 0 },
    1626           0 :         { MAP_LEN( "UsePrettyPrinting" ), 0, &::getCppuType((sal_Bool*)0), beans::PropertyAttribute::MAYBEVOID, 0},
    1627             :         { NULL, 0, 0, NULL, 0, 0 }
    1628           0 :     };
    1629           0 :     uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) ) );
    1630             : 
    1631           0 :     SvtSaveOptions aSaveOpt;
    1632           0 :     xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting")), uno::makeAny(aSaveOpt.IsPrettyPrinting()));
    1633           0 :     if ( aSaveOpt.IsSaveRelFSys() )
    1634           0 :         xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI")), uno::makeAny(_rMediaDescriptor.getOrDefault("URL",::rtl::OUString())));
    1635             : 
    1636           0 :     ::rtl::OUString aVersion;
    1637           0 :     SvtSaveOptions::ODFDefaultVersion nDefVersion = aSaveOpt.GetODFDefaultVersion();
    1638             : 
    1639             :     // older versions can not have this property set, it exists only starting from ODF1.2
    1640           0 :     if ( nDefVersion >= SvtSaveOptions::ODFVER_012 )
    1641           0 :         aVersion = ODFVER_012_TEXT;
    1642             : 
    1643           0 :     if ( !aVersion.isEmpty() )
    1644             :     {
    1645             :         try
    1646             :         {
    1647           0 :             xInfoSet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Version" )), uno::makeAny( aVersion ) );
    1648             :         }
    1649           0 :         catch( const uno::Exception& )
    1650             :         {
    1651             :         }
    1652             :     }
    1653             : 
    1654           0 :     sal_Int32 nArgsLen = aDelegatorArguments.getLength();
    1655           0 :     aDelegatorArguments.realloc(nArgsLen+1);
    1656           0 :     aDelegatorArguments[nArgsLen++] <<= xInfoSet;
    1657             : 
    1658           0 :     Reference< XPropertySet > xProp( _rxTargetStorage, UNO_QUERY_THROW );
    1659           0 :     xProp->setPropertyValue( INFO_MEDIATYPE, makeAny( (rtl::OUString)MIMETYPE_OASIS_OPENDOCUMENT_DATABASE ) );
    1660             : 
    1661           0 :     Reference< XComponent > xComponent( *const_cast< ODatabaseDocument* >( this ), UNO_QUERY_THROW );
    1662             : 
    1663           0 :     Sequence< PropertyValue > aMediaDescriptor;
    1664           0 :     _rMediaDescriptor >>= aMediaDescriptor;
    1665             : 
    1666           0 :     xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamName")), uno::makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("settings.xml"))));
    1667             :     WriteThroughComponent( xComponent, "settings.xml", "com.sun.star.comp.sdb.XMLSettingsExporter",
    1668           0 :         aDelegatorArguments, aMediaDescriptor, _rxTargetStorage );
    1669             : 
    1670           0 :     xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamName")), uno::makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("content.xml"))));
    1671             :     WriteThroughComponent( xComponent, "content.xml", "com.sun.star.comp.sdb.DBExportFilter",
    1672           0 :         aDelegatorArguments, aMediaDescriptor, _rxTargetStorage );
    1673             : 
    1674           0 :     if ( _rxTargetStorage->hasByName ( sPictures ) )
    1675             :     {
    1676             :         try
    1677             :         {
    1678             :            // Delete any previously existing Pictures folder and regenerate
    1679             :            // any needed content if needed
    1680           0 :            Reference< XStorageBasedLibraryContainer > xDlgs = m_pImpl->getLibraryContainer( false );
    1681           0 :            if ( xDlgs.is() )
    1682             :            {
    1683           0 :                Reference< XModel > xModel(const_cast< ODatabaseDocument*>(this));
    1684           0 :                lcl_uglyHackToStoreDialogeEmbedImages( m_pImpl->getLibraryContainer(false), _rxTargetStorage, xModel, m_pImpl->m_aContext );
    1685           0 :            }
    1686             :        }
    1687           0 :        catch ( const Exception& )
    1688             :        {
    1689             :             DBG_UNHANDLED_EXCEPTION();
    1690             :        }
    1691             :     }
    1692           0 :     m_pImpl->storeLibraryContainersTo( _rxTargetStorage );
    1693           0 : }
    1694             : 
    1695           0 : Reference< XUIConfigurationManager > SAL_CALL ODatabaseDocument::getUIConfigurationManager(  ) throw (RuntimeException)
    1696             : {
    1697           0 :     DocumentGuard aGuard( *this );
    1698             : 
    1699           0 :     if ( !m_xUIConfigurationManager.is() )
    1700             :     {
    1701           0 :         m_pImpl->m_aContext.createComponent( "com.sun.star.ui.UIConfigurationManager", m_xUIConfigurationManager );
    1702           0 :         Reference< XUIConfigurationStorage > xUIConfigStorage( m_xUIConfigurationManager, UNO_QUERY );
    1703           0 :         if ( xUIConfigStorage.is() )
    1704             :         {
    1705           0 :             rtl::OUString aUIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations2" ));
    1706           0 :             Reference< XStorage > xConfigStorage;
    1707             : 
    1708             :             // First try to open with READWRITE and then READ
    1709           0 :             xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, ElementModes::READWRITE );
    1710           0 :             if ( xConfigStorage.is() )
    1711             :             {
    1712           0 :                 rtl::OUString aUIConfigMediaType( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.xml.ui.configuration" ));
    1713           0 :                 rtl::OUString aMediaType;
    1714           0 :                 Reference< XPropertySet > xPropSet( xConfigStorage, UNO_QUERY );
    1715           0 :                 Any a = xPropSet->getPropertyValue( INFO_MEDIATYPE );
    1716           0 :                 if ( !( a >>= aMediaType ) ||  aMediaType.isEmpty() )
    1717             :                 {
    1718           0 :                     a <<= aUIConfigMediaType;
    1719           0 :                     xPropSet->setPropertyValue( INFO_MEDIATYPE, a );
    1720           0 :                 }
    1721             :             }
    1722             :             else
    1723           0 :                 xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, ElementModes::READ );
    1724             : 
    1725             :             // initialize ui configuration manager with document substorage
    1726           0 :             xUIConfigStorage->setStorage( xConfigStorage );
    1727           0 :         }
    1728             :     }
    1729             : 
    1730           0 :     return m_xUIConfigurationManager;
    1731             : }
    1732             : 
    1733           0 : Reference< XStorage > SAL_CALL ODatabaseDocument::getDocumentSubStorage( const ::rtl::OUString& aStorageName, sal_Int32 nMode ) throw (RuntimeException)
    1734             : {
    1735           0 :     DocumentGuard aGuard( *this );
    1736             : 
    1737           0 :     Reference< XDocumentSubStorageSupplier > xStorageAccess( m_pImpl->getDocumentSubStorageSupplier() );
    1738           0 :     return xStorageAccess->getDocumentSubStorage( aStorageName, nMode );
    1739             : }
    1740             : 
    1741           0 : Sequence< ::rtl::OUString > SAL_CALL ODatabaseDocument::getDocumentSubStoragesNames(  ) throw (::com::sun::star::io::IOException, RuntimeException)
    1742             : {
    1743           0 :     Reference< XDocumentSubStorageSupplier > xStorageAccess( m_pImpl->getDocumentSubStorageSupplier() );
    1744           0 :     return xStorageAccess->getDocumentSubStoragesNames();
    1745             : }
    1746             : 
    1747           0 : void ODatabaseDocument::impl_notifyStorageChange_nolck_nothrow( const Reference< XStorage >& _rxNewRootStorage )
    1748             : {
    1749           0 :     Reference< XInterface > xMe( *const_cast< ODatabaseDocument* >( this ) );
    1750             : 
    1751             :     m_aStorageListeners.forEach< XStorageChangeListener >(
    1752           0 :         boost::bind( &XStorageChangeListener::notifyStorageChange, _1, boost::cref( xMe ), boost::cref( _rxNewRootStorage ) ) );
    1753           0 : }
    1754             : 
    1755           0 : void ODatabaseDocument::disposing()
    1756             : {
    1757             :     OSL_TRACE( "DD: disp: %p: %p", this, m_pImpl.get() );
    1758           0 :     if ( !m_pImpl.is() )
    1759             :     {
    1760             :         // this means that we're already disposed
    1761             :         OSL_ENSURE( ODatabaseDocument_OfficeDocument::rBHelper.bDisposed, "ODatabaseDocument::disposing: no impl anymore, but not yet disposed!" );
    1762           0 :         return;
    1763             :     }
    1764             : 
    1765           0 :     if ( impl_isInitialized() )
    1766           0 :         m_aEventNotifier.notifyDocumentEvent( "OnUnload" );
    1767             : 
    1768           0 :     Reference< XModel > xHoldAlive( this );
    1769             : 
    1770           0 :     m_aEventNotifier.disposing();
    1771             : 
    1772           0 :     lang::EventObject aDisposeEvent(static_cast<XWeak*>(this));
    1773           0 :     m_aModifyListeners.disposeAndClear( aDisposeEvent );
    1774           0 :     m_aCloseListener.disposeAndClear( aDisposeEvent );
    1775           0 :     m_aStorageListeners.disposeAndClear( aDisposeEvent );
    1776             : 
    1777             :     // this is the list of objects which we currently hold as member. Upon resetting
    1778             :     // those members, we can (potentially) release the last reference to them, in which
    1779             :     // case they will be deleted - if they're C++ implementations, that is :).
    1780             :     // Some of those implementations are offending enough to require the SolarMutex, which
    1781             :     // means we should not release the last reference while our own mutex is locked ...
    1782           0 :     ::std::list< Reference< XInterface > > aKeepAlive;
    1783             : 
    1784             :     // SYNCHRONIZED ->
    1785           0 :     ::osl::ClearableMutexGuard aGuard( m_aMutex );
    1786             : 
    1787             :     OSL_ENSURE( m_aControllers.empty(), "ODatabaseDocument::disposing: there still are controllers!" );
    1788             :     // normally, nobody should explicitly dispose, but only XCloseable::close
    1789             :     // the document. And upon closing, our controllers are closed, too
    1790             : 
    1791             :     {
    1792           0 :         uno::Reference<uno::XInterface> xUIInterface( m_xUIConfigurationManager );
    1793           0 :         aKeepAlive.push_back( xUIInterface );
    1794             :     }
    1795           0 :     m_xUIConfigurationManager = NULL;
    1796             : 
    1797           0 :     clearObjectContainer( m_xForms );
    1798           0 :     clearObjectContainer( m_xReports );
    1799             : 
    1800             :     // reset the macro mode: in case the our impl struct stays alive (e.g. because our DataSource
    1801             :     // object still exists), and somebody subsequently re-opens the document, we want to have
    1802             :     // the security warning, again.
    1803           0 :     m_pImpl->resetMacroExecutionMode();
    1804             : 
    1805             :     // similar arguing for our ViewMonitor
    1806           0 :     m_aViewMonitor.reset();
    1807             : 
    1808             :     // tell our Impl to forget us
    1809           0 :     m_pImpl->modelIsDisposing( impl_isInitialized(), ODatabaseModelImpl::ResetModelAccess() );
    1810             : 
    1811             :     // now, at the latest, the controller array should be empty. Controllers are
    1812             :     // expected to listen for our disposal, and disconnect then
    1813             :     OSL_ENSURE( m_aControllers.empty(), "ODatabaseDocument::disposing: there still are controllers!" );
    1814           0 :     impl_disposeControllerFrames_nothrow();
    1815             : 
    1816             :     {
    1817           0 :         uno::Reference<uno::XInterface> xModuleInterface( m_xModuleManager );
    1818           0 :         aKeepAlive.push_back( xModuleInterface );
    1819             :     }
    1820           0 :     m_xModuleManager.clear();
    1821             : 
    1822             :     {
    1823           0 :         uno::Reference<uno::XInterface> xTitleInterface( m_xTitleHelper );
    1824           0 :         aKeepAlive.push_back( xTitleInterface );
    1825             :     }
    1826           0 :     m_xTitleHelper.clear();
    1827             : 
    1828           0 :     m_pImpl.clear();
    1829             : 
    1830           0 :     aGuard.clear();
    1831             :     // <- SYNCHRONIZED
    1832             : 
    1833           0 :     aKeepAlive.clear();
    1834             : }
    1835             : 
    1836             : // XComponent
    1837           0 : void SAL_CALL ODatabaseDocument::dispose(  ) throw (RuntimeException)
    1838             : {
    1839           0 :     ::cppu::WeakComponentImplHelperBase::dispose();
    1840           0 : }
    1841             : 
    1842           0 : void SAL_CALL ODatabaseDocument::addEventListener( const Reference< lang::XEventListener >& _xListener ) throw (RuntimeException)
    1843             : {
    1844           0 :     ::cppu::WeakComponentImplHelperBase::addEventListener( _xListener );
    1845           0 : }
    1846             : 
    1847           0 : void SAL_CALL ODatabaseDocument::removeEventListener( const Reference< lang::XEventListener >& _xListener ) throw (RuntimeException)
    1848             : {
    1849           0 :     ::cppu::WeakComponentImplHelperBase::removeEventListener( _xListener );
    1850           0 : }
    1851             : 
    1852             : // XServiceInfo
    1853           0 : rtl::OUString ODatabaseDocument::getImplementationName(  ) throw(RuntimeException)
    1854             : {
    1855           0 :     return getImplementationName_static();
    1856             : }
    1857             : 
    1858           3 : rtl::OUString ODatabaseDocument::getImplementationName_static(  ) throw(RuntimeException)
    1859             : {
    1860           3 :     return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.dba.ODatabaseDocument"));
    1861             : }
    1862             : 
    1863           0 : Sequence< ::rtl::OUString > ODatabaseDocument::getSupportedServiceNames(  ) throw (RuntimeException)
    1864             : {
    1865           0 :     return getSupportedServiceNames_static();
    1866             : }
    1867             : 
    1868           0 : Reference< XInterface > ODatabaseDocument::Create( const Reference< XComponentContext >& _rxContext )
    1869             : {
    1870           0 :     ::comphelper::ComponentContext aContext( _rxContext );
    1871           0 :     Reference< XUnoTunnel > xDBContextTunnel( DatabaseContext::create(_rxContext), UNO_QUERY_THROW );
    1872           0 :     ODatabaseContext* pContext = reinterpret_cast< ODatabaseContext* >( xDBContextTunnel->getSomething( ODatabaseContext::getUnoTunnelImplementationId() ) );
    1873             : 
    1874           0 :     ::rtl::Reference<ODatabaseModelImpl> pImpl( new ODatabaseModelImpl( aContext.getLegacyServiceFactory(), *pContext ) );
    1875           0 :     Reference< XModel > xModel( pImpl->createNewModel_deliverOwnership( false ) );
    1876           0 :     return xModel.get();
    1877             : }
    1878             : 
    1879           3 : Sequence< ::rtl::OUString > ODatabaseDocument::getSupportedServiceNames_static(  ) throw (RuntimeException)
    1880             : {
    1881           3 :     Sequence< ::rtl::OUString > aSNS( 2 );
    1882           3 :     aSNS[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.OfficeDatabaseDocument"));
    1883           3 :     aSNS[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.OfficeDocument"));
    1884           3 :     return aSNS;
    1885             : }
    1886             : 
    1887           0 : sal_Bool ODatabaseDocument::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
    1888             : {
    1889           0 :     return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
    1890             : }
    1891             : 
    1892           0 : Reference< XDataSource > SAL_CALL ODatabaseDocument::getDataSource() throw (RuntimeException)
    1893             : {
    1894           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
    1895           0 :     return m_pImpl->getOrCreateDataSource();
    1896             : }
    1897             : 
    1898           0 : void SAL_CALL ODatabaseDocument::loadFromStorage( const Reference< XStorage >& /*xStorage*/, const Sequence< PropertyValue >& /*aMediaDescriptor*/ ) throw (IllegalArgumentException, DoubleInitializationException, IOException, Exception, RuntimeException)
    1899             : {
    1900           0 :     DocumentGuard aGuard( *this );
    1901             : 
    1902             :     throw Exception(
    1903             :         DBACORE_RESSTRING( RID_STR_NO_EMBEDDING ),
    1904             :         *this
    1905           0 :     );
    1906             : }
    1907             : 
    1908           0 : void SAL_CALL ODatabaseDocument::storeToStorage( const Reference< XStorage >& _rxStorage, const Sequence< PropertyValue >& _rMediaDescriptor ) throw (IllegalArgumentException, IOException, Exception, RuntimeException)
    1909             : {
    1910           0 :     DocumentGuard aGuard( *this );
    1911           0 :     impl_storeToStorage_throw( _rxStorage, _rMediaDescriptor, aGuard );
    1912           0 : }
    1913             : 
    1914           0 : void SAL_CALL ODatabaseDocument::switchToStorage( const Reference< XStorage >& _rxNewRootStorage ) throw (IllegalArgumentException, IOException, Exception, RuntimeException)
    1915             : {
    1916           0 :     DocumentGuard aGuard( *this );
    1917             : 
    1918           0 :     Reference< XStorage > xNewRootStorage( m_pImpl->switchToStorage( _rxNewRootStorage ) );
    1919             : 
    1920           0 :     aGuard.clear();
    1921           0 :     impl_notifyStorageChange_nolck_nothrow( xNewRootStorage );
    1922           0 : }
    1923             : 
    1924           0 : Reference< XStorage > SAL_CALL ODatabaseDocument::getDocumentStorage(  ) throw (IOException, Exception, RuntimeException)
    1925             : {
    1926           0 :     DocumentGuard aGuard( *this );
    1927           0 :     return m_pImpl->getOrCreateRootStorage();
    1928             : }
    1929             : 
    1930           0 : void SAL_CALL ODatabaseDocument::addStorageChangeListener( const Reference< XStorageChangeListener >& _Listener ) throw (RuntimeException)
    1931             : {
    1932           0 :     DocumentGuard aGuard( *this );
    1933           0 :     m_aStorageListeners.addInterface( _Listener );
    1934           0 : }
    1935             : 
    1936           0 : void SAL_CALL ODatabaseDocument::removeStorageChangeListener( const Reference< XStorageChangeListener >& _Listener ) throw (RuntimeException)
    1937             : {
    1938           0 :     DocumentGuard aGuard( *this );
    1939           0 :     m_aStorageListeners.addInterface( _Listener );
    1940           0 : }
    1941             : 
    1942           0 : Reference< XStorageBasedLibraryContainer > SAL_CALL ODatabaseDocument::getBasicLibraries() throw (RuntimeException)
    1943             : {
    1944           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
    1945           0 :     return m_pImpl->getLibraryContainer( true );
    1946             : }
    1947             : 
    1948           0 : Reference< XStorageBasedLibraryContainer > SAL_CALL ODatabaseDocument::getDialogLibraries() throw (RuntimeException)
    1949             : {
    1950           0 :     DocumentGuard aGuard( *this );
    1951           0 :     return m_pImpl->getLibraryContainer( false );
    1952             : }
    1953             : 
    1954           0 : ::sal_Bool SAL_CALL ODatabaseDocument::getAllowMacroExecution() throw (RuntimeException)
    1955             : {
    1956           0 :     DocumentGuard aGuard( *this );
    1957           0 :     return m_pImpl->adjustMacroMode_AutoReject();
    1958             : }
    1959             : 
    1960           0 : Reference< XEmbeddedScripts > SAL_CALL ODatabaseDocument::getScriptContainer() throw (RuntimeException)
    1961             : {
    1962           0 :     DocumentGuard aGuard( *this );
    1963           0 :     return this;
    1964             : }
    1965             : 
    1966           0 : Reference< provider::XScriptProvider > SAL_CALL ODatabaseDocument::getScriptProvider(  ) throw (RuntimeException)
    1967             : {
    1968           0 :     DocumentGuard aGuard( *this );
    1969             : 
    1970           0 :     Reference< XScriptProvider > xScriptProvider( m_xScriptProvider );
    1971           0 :     if ( !xScriptProvider.is() )
    1972             :     {
    1973             :         Reference < XScriptProviderFactory > xFactory(
    1974           0 :             m_pImpl->m_aContext.getSingleton( "com.sun.star.script.provider.theMasterScriptProviderFactory" ), UNO_QUERY_THROW );
    1975             : 
    1976           0 :         Any aScriptProviderContext;
    1977           0 :         if ( m_bAllowDocumentScripting )
    1978           0 :             aScriptProviderContext <<= Reference< XModel >( this );
    1979             : 
    1980           0 :         xScriptProvider.set( xFactory->createScriptProvider( aScriptProviderContext ), UNO_SET_THROW );
    1981           0 :         m_xScriptProvider = xScriptProvider;
    1982             :     }
    1983             : 
    1984           0 :     return xScriptProvider;
    1985             : }
    1986             : 
    1987           0 : Reference< XNameReplace > SAL_CALL ODatabaseDocument::getEvents(  ) throw (RuntimeException)
    1988             : {
    1989           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
    1990           0 :     return m_pEventContainer;
    1991             : }
    1992             : 
    1993           0 : void SAL_CALL ODatabaseDocument::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException)
    1994             : {
    1995           0 :     if ( m_pImpl.is() )
    1996           0 :         m_pImpl->disposing(Source);
    1997           0 : }
    1998             : 
    1999           0 : Reference< XInterface > ODatabaseDocument::getThis() const
    2000             : {
    2001           0 :     return *const_cast< ODatabaseDocument* >( this );
    2002             : }
    2003             : 
    2004             : struct CreateAny : public ::std::unary_function< Reference<XController>, Any>
    2005             : {
    2006           0 :     Any operator() (const Reference<XController>& lhs) const
    2007             :     {
    2008           0 :         return makeAny(lhs);
    2009             :     }
    2010             : };
    2011             : 
    2012             : // XModel2
    2013           0 : Reference< XEnumeration > SAL_CALL ODatabaseDocument::getControllers(  ) throw (RuntimeException)
    2014             : {
    2015           0 :     DocumentGuard aGuard( *this );
    2016           0 :     uno::Sequence< Any> aController( m_aControllers.size() );
    2017           0 :     ::std::transform( m_aControllers.begin(), m_aControllers.end(), aController.getArray(), CreateAny() );
    2018           0 :     return new ::comphelper::OAnyEnumeration(aController);
    2019             : }
    2020             : 
    2021           0 : Sequence< ::rtl::OUString > SAL_CALL ODatabaseDocument::getAvailableViewControllerNames(  ) throw (RuntimeException)
    2022             : {
    2023           0 :     Sequence< ::rtl::OUString > aNames(1);
    2024           0 :     aNames[0] = SERVICE_SDB_APPLICATIONCONTROLLER;
    2025           0 :     return aNames;
    2026             : }
    2027             : 
    2028           0 : Reference< XController2 > SAL_CALL ODatabaseDocument::createDefaultViewController( const Reference< XFrame >& _Frame ) throw (IllegalArgumentException, Exception, RuntimeException)
    2029             : {
    2030             :     return createViewController(
    2031             :         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Default" ) ),
    2032             :         Sequence< PropertyValue >(),
    2033             :         _Frame
    2034           0 :     );
    2035             : }
    2036             : 
    2037           0 : Reference< XController2 > SAL_CALL ODatabaseDocument::createViewController( const ::rtl::OUString& _ViewName, const Sequence< PropertyValue >& _Arguments, const Reference< XFrame >& _Frame ) throw (IllegalArgumentException, Exception, RuntimeException)
    2038             : {
    2039           0 :     if ( _ViewName != "Default" && _ViewName != "Preview" )
    2040           0 :         throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
    2041           0 :     if ( !_Frame.is() )
    2042           0 :         throw IllegalArgumentException( ::rtl::OUString(), *this, 3 );
    2043             : 
    2044           0 :     DocumentGuard aGuard( *this );
    2045           0 :     ::comphelper::ComponentContext aContext( m_pImpl->m_aContext );
    2046           0 :     aGuard.clear();
    2047             : 
    2048           0 :     Reference< XController2 > xController;
    2049           0 :     aContext.createComponent( "org.openoffice.comp.dbu.OApplicationController", xController );
    2050             : 
    2051           0 :     ::comphelper::NamedValueCollection aInitArgs( _Arguments );
    2052           0 :     aInitArgs.put( "Frame", _Frame );
    2053           0 :     if ( _ViewName == "Preview" )
    2054           0 :         aInitArgs.put( "Preview", sal_Bool( sal_True ) );
    2055           0 :     Reference< XInitialization > xInitController( xController, UNO_QUERY_THROW );
    2056           0 :     xInitController->initialize( aInitArgs.getWrappedPropertyValues() );
    2057             : 
    2058           0 :     return xController;
    2059             : }
    2060             : 
    2061           0 : Reference< XTitle > ODatabaseDocument::impl_getTitleHelper_throw()
    2062             : {
    2063           0 :     if ( ! m_xTitleHelper.is ())
    2064             :     {
    2065           0 :         Reference< XUntitledNumbers >  xDesktop(Desktop::create(m_pImpl->m_aContext.getUNOContext()), uno::UNO_QUERY_THROW);
    2066           0 :         Reference< frame::XModel >     xThis   (getThis(), uno::UNO_QUERY_THROW);
    2067             : 
    2068           0 :         ::framework::TitleHelper* pHelper = new ::framework::TitleHelper(m_pImpl->m_aContext.getUNOContext());
    2069           0 :         m_xTitleHelper.set(static_cast< ::cppu::OWeakObject* >(pHelper), uno::UNO_QUERY_THROW);
    2070           0 :         pHelper->setOwner                   (xThis   );
    2071           0 :         pHelper->connectWithUntitledNumbers (xDesktop);
    2072             :     }
    2073             : 
    2074           0 :     return m_xTitleHelper;
    2075             : }
    2076             : 
    2077           0 : uno::Reference< frame::XUntitledNumbers > ODatabaseDocument::impl_getUntitledHelper_throw(const uno::Reference< uno::XInterface >& _xComponent)
    2078             : {
    2079           0 :     if ( !m_xModuleManager.is() )
    2080           0 :         m_xModuleManager.set( ModuleManager::create(m_pImpl->m_aContext.getUNOContext()) );
    2081             : 
    2082           0 :     ::rtl::OUString sModuleId;
    2083             :     try
    2084             :     {
    2085           0 :         sModuleId = m_xModuleManager->identify( _xComponent );
    2086             :     }
    2087           0 :     catch(const uno::Exception&)
    2088             :     {
    2089             :     }
    2090           0 :     uno::Reference< frame::XUntitledNumbers > xNumberedControllers;
    2091             : 
    2092           0 :     TNumberedController::iterator aFind = m_aNumberedControllers.find(sModuleId);
    2093           0 :     if ( aFind == m_aNumberedControllers.end() )
    2094             :     {
    2095           0 :         uno::Reference< frame::XModel > xThis(static_cast< frame::XModel* >(this), uno::UNO_QUERY_THROW);
    2096           0 :         ::comphelper::NumberedCollection* pHelper = new ::comphelper::NumberedCollection();
    2097           0 :         xNumberedControllers.set(static_cast< ::cppu::OWeakObject* >(pHelper), uno::UNO_QUERY_THROW);
    2098             : 
    2099           0 :         pHelper->setOwner          (xThis);
    2100             :         //pHelper->setUntitledPrefix (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : ")));
    2101             : 
    2102           0 :         m_aNumberedControllers.insert(TNumberedController::value_type(sModuleId,xNumberedControllers));
    2103             :     }
    2104             :     else
    2105           0 :         xNumberedControllers = aFind->second;
    2106             : 
    2107           0 :     return xNumberedControllers;
    2108             : }
    2109             : 
    2110             : // css.frame.XTitle
    2111           0 : ::rtl::OUString SAL_CALL ODatabaseDocument::getTitle()
    2112             :     throw (uno::RuntimeException)
    2113             : {
    2114             :     // SYNCHRONIZED ->
    2115           0 :     DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
    2116           0 :     return impl_getTitleHelper_throw()->getTitle();
    2117             : }
    2118             : 
    2119             : // css.frame.XTitle
    2120           0 : void SAL_CALL ODatabaseDocument::setTitle( const ::rtl::OUString& sTitle )
    2121             :     throw (uno::RuntimeException)
    2122             : {
    2123             :     // SYNCHRONIZED ->
    2124           0 :     DocumentGuard aGuard( *this );
    2125           0 :     impl_getTitleHelper_throw()->setTitle( sTitle );
    2126           0 :     m_aEventNotifier.notifyDocumentEventAsync( "OnTitleChanged" );
    2127             :     // <- SYNCHRONIZED
    2128           0 : }
    2129             : 
    2130             : // css.frame.XTitleChangeBroadcaster
    2131           0 : void SAL_CALL ODatabaseDocument::addTitleChangeListener( const uno::Reference< frame::XTitleChangeListener >& xListener )
    2132             :     throw (uno::RuntimeException)
    2133             : {
    2134             :     // SYNCHRONIZED ->
    2135           0 :     DocumentGuard aGuard( *this );
    2136             : 
    2137           0 :     uno::Reference< frame::XTitleChangeBroadcaster > xBroadcaster( impl_getTitleHelper_throw(), uno::UNO_QUERY_THROW );
    2138           0 :     xBroadcaster->addTitleChangeListener( xListener );
    2139           0 : }
    2140             : 
    2141             : // css.frame.XTitleChangeBroadcaster
    2142           0 : void SAL_CALL ODatabaseDocument::removeTitleChangeListener( const uno::Reference< frame::XTitleChangeListener >& xListener )
    2143             :     throw (uno::RuntimeException)
    2144             : {
    2145             :     // SYNCHRONIZED ->
    2146           0 :     DocumentGuard aGuard( *this );
    2147             : 
    2148           0 :     uno::Reference< frame::XTitleChangeBroadcaster > xBroadcaster( impl_getTitleHelper_throw(), uno::UNO_QUERY_THROW );
    2149           0 :     xBroadcaster->removeTitleChangeListener( xListener );
    2150           0 : }
    2151             : 
    2152             : // css.frame.XUntitledNumbers
    2153           0 : ::sal_Int32 SAL_CALL ODatabaseDocument::leaseNumber( const uno::Reference< uno::XInterface >& xComponent )
    2154             :     throw (lang::IllegalArgumentException,
    2155             :            uno::RuntimeException         )
    2156             : {
    2157           0 :     DocumentGuard aGuard( *this );
    2158           0 :     return impl_getUntitledHelper_throw(xComponent)->leaseNumber (xComponent);
    2159             : }
    2160             : 
    2161             : // css.frame.XUntitledNumbers
    2162           0 : void SAL_CALL ODatabaseDocument::releaseNumber( ::sal_Int32 nNumber )
    2163             :     throw (lang::IllegalArgumentException,
    2164             :            uno::RuntimeException         )
    2165             : {
    2166           0 :     DocumentGuard aGuard( *this );
    2167           0 :     impl_getUntitledHelper_throw()->releaseNumber (nNumber);
    2168           0 : }
    2169             : 
    2170             : // css.frame.XUntitledNumbers
    2171           0 : void SAL_CALL ODatabaseDocument::releaseNumberForComponent( const uno::Reference< uno::XInterface >& xComponent )
    2172             :     throw (lang::IllegalArgumentException,
    2173             :            uno::RuntimeException         )
    2174             : {
    2175           0 :     DocumentGuard aGuard( *this );
    2176           0 :     impl_getUntitledHelper_throw(xComponent)->releaseNumberForComponent (xComponent);
    2177           0 : }
    2178             : 
    2179             : // css.frame.XUntitledNumbers
    2180           0 : ::rtl::OUString SAL_CALL ODatabaseDocument::getUntitledPrefix()    throw (uno::RuntimeException)
    2181             : {
    2182           0 :     return ::rtl::OUString();/*RTL_CONSTASCII_USTRINGPARAM(" : "));*/
    2183             : }
    2184             : 
    2185           9 : }   // namespace dbaccess
    2186             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10