LCOV - code coverage report
Current view: top level - dbaccess/source/core/dataaccess - databasedocument.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 953 0.0 %
Date: 2014-04-14 Functions: 0 123 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10