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

Generated by: LCOV version 1.10