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

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

Generated by: LCOV version 1.10