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