xref: /trunk/main/dbaccess/source/core/dataaccess/documentdefinition.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 #ifndef _DBA_COREDATAACCESS_DOCUMENTDEFINITION_HXX_
32 #include "documentdefinition.hxx"
33 #endif
34 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
35 #include "dbastrings.hrc"
36 #endif
37 #ifndef DBACORE_SDBCORETOOLS_HXX
38 #include "sdbcoretools.hxx"
39 #endif
40 #ifndef _TOOLS_DEBUG_HXX
41 #include <tools/debug.hxx>
42 #endif
43 #ifndef TOOLS_DIAGNOSE_EX_H
44 #include <tools/diagnose_ex.h>
45 #endif
46 #ifndef _COMPHELPER_PROPERTY_HXX_
47 #include <comphelper/property.hxx>
48 #endif
49 #ifndef _COMPHELPER_SEQUENCE_HXX_
50 #include <comphelper/sequence.hxx>
51 #endif
52 #ifndef _COMPHELPER_MEDIADESCRIPTOR_HXX_
53 #include <comphelper/mediadescriptor.hxx>
54 #endif
55 #ifndef COMPHELPER_NAMEDVALUECOLLECTION_HXX
56 #include <comphelper/namedvaluecollection.hxx>
57 #endif
58 #ifndef _COMPHELPER_CLASSIDS_HXX
59 #include <comphelper/classids.hxx>
60 #endif
61 #include <com/sun/star/frame/XUntitledNumbers.hpp>
62 #ifndef _COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
63 #include <com/sun/star/awt/XTopWindow.hpp>
64 #endif
65 #ifndef _COM_SUN_STAR_AWT_SIZE_HPP_
66 #include <com/sun/star/awt/Size.hpp>
67 #endif
68 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
69 #include <com/sun/star/lang/DisposedException.hpp>
70 #endif
71 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
72 #include <com/sun/star/beans/PropertyAttribute.hpp>
73 #endif
74 #ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
75 #include <com/sun/star/frame/XModel.hpp>
76 #endif
77 #include <com/sun/star/frame/XTitle.hpp>
78 #ifndef _COM_SUN_STAR_FRAME_XCONTROLLER_HPP_
79 #include <com/sun/star/frame/XController.hpp>
80 #endif
81 #ifndef _COM_SUN_STAR_TASK_XJOBEXECUTOR_HPP_
82 #include <com/sun/star/task/XJobExecutor.hpp>
83 #endif
84 #ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDERINTERCEPTION_HPP_
85 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
86 #endif
87 #ifndef _COM_SUN_STAR_FRAME_XFRAMESSUPPLIER_HPP_
88 #include <com/sun/star/frame/XFramesSupplier.hpp>
89 #endif
90 #ifndef _COM_SUN_STAR_UCB_INSERTCOMMANDARGUMENT_HPP_
91 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
92 #endif
93 #include <com/sun/star/report/XReportDefinition.hpp>
94 #include <com/sun/star/report/XReportEngine.hpp>
95 #ifndef _COM_SUN_STAR_UCB_OPENMODE_HPP_
96 #include <com/sun/star/ucb/OpenMode.hpp>
97 #endif
98 #ifndef _COM_SUN_STAR_XEMBEDOBJECTFACTORY_HPP_
99 #include <com/sun/star/embed/XEmbedObjectFactory.hpp>
100 #endif
101 #ifndef _COM_SUN_STAR_XEMBEDOBJECTCREATOR_HPP_
102 #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
103 #endif
104 #ifndef _COM_SUN_STAR_EMBED_ASPECTS_HPP_
105 #include <com/sun/star/embed/Aspects.hpp>
106 #endif
107 #ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_
108 #include <ucbhelper/cancelcommandexecution.hxx>
109 #endif
110 #ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDDATASINKEXCEPTION_HPP_
111 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
112 #endif
113 #ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDOPENMODEEXCEPTION_HPP_
114 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
115 #endif
116 #ifndef _COM_SUN_STAR_ELEMENTMODES_HPP_
117 #include <com/sun/star/embed/ElementModes.hpp>
118 #endif
119 #ifndef _COM_SUN_STAR_XEMBEDPERSIST_HPP_
120 #include <com/sun/star/embed/XEmbedPersist.hpp>
121 #endif
122 #ifndef _COM_SUN_STAR_EMBEDSTATES_HPP_
123 #include <com/sun/star/embed/EmbedStates.hpp>
124 #endif
125 #ifndef _COM_SUN_STAR_XCOMPONENTSUPPLIER_HPP_
126 #include <com/sun/star/embed/XComponentSupplier.hpp>
127 #endif
128 #ifndef _COM_SUN_STAR_ENTRYINITMODES_HPP_
129 #include <com/sun/star/embed/EntryInitModes.hpp>
130 #endif
131 #ifndef _COM_SUN_STAR_UCB_MISSINGPROPERTIESEXCEPTION_HPP_
132 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
133 #endif
134 #ifndef _COM_SUN_STAR_UCB_MISSINGINPUTSTREAMEXCEPTION_HPP_
135 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
136 #endif
137 #ifndef _COM_SUN_STAR_UCB_OPENCOMMANDARGUMENT2_HPP_
138 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
139 #endif
140 #ifndef _COM_SUN_STAR_UTIL_XCLOSEBROADCASTER_HPP_
141 #include <com/sun/star/util/XCloseBroadcaster.hpp>
142 #endif
143 #ifndef _COM_SUN_STAR_FRAME_XMODULE_HPP_
144 #include <com/sun/star/frame/XModule.hpp>
145 #endif
146 #ifndef _COM_SUN_STAR_DATATRANSFER_DATAFLAVOR_HPP_
147 #include <com/sun/star/datatransfer/DataFlavor.hpp>
148 #endif
149 #ifndef _COM_SUN_STAR_DATATRANSFER_XTRANSFERABLE_HPP_
150 #include <com/sun/star/datatransfer/XTransferable.hpp>
151 #endif
152 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
153 #include <com/sun/star/container/XNameContainer.hpp>
154 #endif
155 #ifndef _COM_SUN_STAR_XTRANSACTEDOBJECT_HPP_
156 #include <com/sun/star/embed/XTransactedObject.hpp>
157 #endif
158 #ifndef _COM_SUN_STAR_EMBED_XCOMMONEMBEDPERSIST_HPP_
159 #include <com/sun/star/embed/XCommonEmbedPersist.hpp>
160 #endif
161 #ifndef DBA_INTERCEPT_HXX
162 #include "intercept.hxx"
163 #endif
164 #ifndef _COM_SUN_STAR_SDB_ERRORCONDITION_HPP_
165 #include <com/sun/star/sdb/ErrorCondition.hpp>
166 #endif
167 #ifndef _COM_SUN_STAR_SDB_XINTERACTIONDOCUMENTSAVE_HPP_
168 #include <com/sun/star/sdb/XInteractionDocumentSave.hpp>
169 #endif
170 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
171 #include <com/sun/star/task/XInteractionHandler.hpp>
172 #endif
173 #ifndef _COM_SUN_STAR_SDB_DOCUMENTSAVEREQUEST_HPP_
174 #include <com/sun/star/sdb/DocumentSaveRequest.hpp>
175 #endif
176 #ifndef _COM_SUN_STAR_DOCUMENT_XDOCUMENTPROPERTIESSUPPLIER_HPP_
177 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
178 #endif
179 #ifndef _COM_SUN_STAR_DOCUMENT_MACROEXECMODE_HPP_
180 #include <com/sun/star/document/MacroExecMode.hpp>
181 #endif
182 #ifndef _COM_SUN_STAR_DRAWING_XDRAWPAGESUPPLIER_HPP_
183 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
184 #endif
185 #ifndef _COM_SUN_STAR_CONTAINER_XINDEXCONTAINER_HPP_
186 #include <com/sun/star/container/XIndexContainer.hpp>
187 #endif
188 #ifndef _COM_SUN_STAR_FORM_XFORMSSUPPLIER_HPP_
189 #include <com/sun/star/form/XFormsSupplier.hpp>
190 #endif
191 #ifndef _COM_SUN_STAR_FORM_XFORM_HPP_
192 #include <com/sun/star/form/XForm.hpp>
193 #endif
194 #ifndef _COMPHELPER_INTERACTION_HXX_
195 #include <comphelper/interaction.hxx>
196 #endif
197 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
198 #include <connectivity/dbtools.hxx>
199 #endif
200 #ifndef _SV_SVAPP_HXX
201 #include <vcl/svapp.hxx>
202 #endif
203 #ifndef _VOS_MUTEX_HXX_
204 #include <vos/mutex.hxx>
205 #endif
206 #ifndef _COM_SUN_STAR_VIEW_XVIEWSETTINGSSUPPLIER_HPP_
207 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
208 #endif
209 #ifndef _DBA_CORE_RESOURCE_HXX_
210 #include "core_resource.hxx"
211 #endif
212 #ifndef _DBA_CORE_RESOURCE_HRC_
213 #include "core_resource.hrc"
214 #endif
215 #ifndef _DBA_COREDATAACCESS_DATASOURCE_HXX_
216 #include "datasource.hxx"
217 #endif
218 #ifndef _COM_SUN_STAR_EMBED_XSTATECHANGEBROADCASTER_HPP_
219 #include <com/sun/star/embed/XStateChangeBroadcaster.hpp>
220 #endif
221 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONAPPROVE_HPP_
222 #include <com/sun/star/task/XInteractionApprove.hpp>
223 #endif
224 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONDISAPPROVE_HPP_
225 #include <com/sun/star/task/XInteractionDisapprove.hpp>
226 #endif
227 #ifndef _COM_SUN_STAR_FRAME_XLAYOUTMANAGER_HPP_
228 #include <com/sun/star/frame/XLayoutManager.hpp>
229 #endif
230 #ifndef _CPPUHELPER_COMPBASE1_HXX_
231 #include <cppuhelper/compbase1.hxx>
232 #endif
233 #include <cppuhelper/exc_hlp.hxx>
234 #ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_
235 #include <com/sun/star/frame/FrameSearchFlag.hpp>
236 #endif
237 #ifndef _COMPHELPER_SEQUENCEASHASHMAP_HXX_
238 #include <comphelper/sequenceashashmap.hxx>
239 #endif
240 #ifndef _COMPHELPER_MIMECONFIGHELPER_HXX_
241 #include <comphelper/mimeconfighelper.hxx>
242 #endif
243 #ifndef _COMPHELPER_STORAGEHELPER_HXX
244 #include <comphelper/storagehelper.hxx>
245 #endif
246 #ifndef _COM_SUN_STAR_CONTAINER_XCONTENTENUMERATIONACCESS_HPP_
247 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
248 #endif
249 #include <com/sun/star/io/WrongFormatException.hpp>
250 #include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp>
251 #include <com/sun/star/sdb/application/DatabaseObject.hpp>
252 #include <com/sun/star/util/XModifiable2.hpp>
253 
254 using namespace ::com::sun::star;
255 using namespace view;
256 using namespace uno;
257 using namespace util;
258 using namespace ucb;
259 using namespace beans;
260 using namespace lang;
261 using namespace awt;
262 using namespace embed;
263 using namespace frame;
264 using namespace document;
265 using namespace sdbc;
266 using namespace sdb;
267 using namespace io;
268 using namespace container;
269 using namespace datatransfer;
270 using namespace task;
271 using namespace form;
272 using namespace drawing;
273 using namespace ::osl;
274 using namespace ::comphelper;
275 using namespace ::cppu;
276 namespace css = ::com::sun::star;
277 
278 using sdb::application::XDatabaseDocumentUI;
279 namespace DatabaseObject = sdb::application::DatabaseObject;
280 
281 
282 #define DEFAULT_WIDTH  10000
283 #define DEFAULT_HEIGHT  7500
284 //.............................................................................
285 namespace dbaccess
286 {
287 //.............................................................................
288 
289     typedef ::boost::optional< bool > optional_bool;
290 
291     //=========================================================================
292     //= helper
293     //=========================================================================
294     namespace
295     {
296         // --------------------------------------------------------------------
297         ::rtl::OUString lcl_determineContentType_nothrow( const Reference< XStorage >& _rxContainerStorage,
298             const ::rtl::OUString& _rEntityName )
299         {
300             ::rtl::OUString sContentType;
301             try
302             {
303                 Reference< XStorage > xContainerStorage( _rxContainerStorage, UNO_QUERY_THROW );
304                 ::utl::SharedUNOComponent< XPropertySet > xStorageProps(
305                     xContainerStorage->openStorageElement( _rEntityName, ElementModes::READ ), UNO_QUERY_THROW );
306                 OSL_VERIFY( xStorageProps->getPropertyValue( INFO_MEDIATYPE ) >>= sContentType );
307             }
308             catch( const Exception& )
309             {
310                 DBG_UNHANDLED_EXCEPTION();
311             }
312             return sContentType;
313         }
314     }
315 
316     //==================================================================
317     // OEmbedObjectHolder
318     //==================================================================
319     typedef ::cppu::WeakComponentImplHelper1<   embed::XStateChangeListener > TEmbedObjectHolder;
320     class OEmbedObjectHolder :   public ::comphelper::OBaseMutex
321                                 ,public TEmbedObjectHolder
322     {
323         Reference< XEmbeddedObject >    m_xBroadCaster;
324         ODocumentDefinition*            m_pDefinition;
325         bool                            m_bInStateChange;
326         bool                            m_bInChangingState;
327     protected:
328         virtual void SAL_CALL disposing();
329     public:
330         OEmbedObjectHolder(const Reference< XEmbeddedObject >& _xBroadCaster,ODocumentDefinition* _pDefinition)
331             : TEmbedObjectHolder(m_aMutex)
332             ,m_xBroadCaster(_xBroadCaster)
333             ,m_pDefinition(_pDefinition)
334             ,m_bInStateChange(false)
335             ,m_bInChangingState(false)
336         {
337             osl_incrementInterlockedCount( &m_refCount );
338             {
339                 if ( m_xBroadCaster.is() )
340                     m_xBroadCaster->addStateChangeListener(this);
341             }
342             osl_decrementInterlockedCount( &m_refCount );
343         }
344 
345         virtual void SAL_CALL changingState( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (embed::WrongStateException, uno::RuntimeException);
346         virtual void SAL_CALL stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (uno::RuntimeException);
347         virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (uno::RuntimeException);
348     };
349     //------------------------------------------------------------------
350     void SAL_CALL OEmbedObjectHolder::disposing()
351     {
352         if ( m_xBroadCaster.is() )
353             m_xBroadCaster->removeStateChangeListener(this);
354         m_xBroadCaster = NULL;
355         m_pDefinition = NULL;
356     }
357     //------------------------------------------------------------------
358     void SAL_CALL OEmbedObjectHolder::changingState( const lang::EventObject& /*aEvent*/, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (embed::WrongStateException, uno::RuntimeException)
359     {
360         if ( !m_bInChangingState && nNewState == EmbedStates::RUNNING && nOldState == EmbedStates::ACTIVE && m_pDefinition )
361         {
362             m_bInChangingState = true;
363             //m_pDefinition->save(sal_False);
364             m_bInChangingState = false;
365         }
366     }
367     //------------------------------------------------------------------
368     void SAL_CALL OEmbedObjectHolder::stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (uno::RuntimeException)
369     {
370         if ( !m_bInStateChange && nNewState == EmbedStates::RUNNING && nOldState == EmbedStates::ACTIVE && m_pDefinition )
371         {
372             m_bInStateChange = true;
373             Reference<XInterface> xInt(static_cast< ::cppu::OWeakObject* >(m_pDefinition),UNO_QUERY);
374             {
375                 Reference<XEmbeddedObject> xEmbeddedObject(aEvent.Source,UNO_QUERY);
376                 if ( xEmbeddedObject.is() )
377                     xEmbeddedObject->changeState(EmbedStates::LOADED);
378             }
379             m_bInStateChange = false;
380         }
381     }
382     //------------------------------------------------------------------
383     void SAL_CALL OEmbedObjectHolder::disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
384     {
385         m_xBroadCaster = NULL;
386     }
387 
388     //==================================================================
389     // OEmbeddedClientHelper
390     //==================================================================
391     typedef ::cppu::WeakImplHelper1 <   XEmbeddedClient
392                                     >   EmbeddedClientHelper_BASE;
393     class OEmbeddedClientHelper : public EmbeddedClientHelper_BASE
394     {
395         ODocumentDefinition* m_pClient;
396     public:
397         OEmbeddedClientHelper(ODocumentDefinition* _pClient) :m_pClient(_pClient) {}
398 
399         virtual void SAL_CALL saveObject(  ) throw (ObjectSaveVetoException, Exception, RuntimeException)
400         {
401         }
402         virtual void SAL_CALL onShowWindow( sal_Bool /*bVisible*/ ) throw (RuntimeException)
403         {
404         }
405         // XComponentSupplier
406         virtual Reference< util::XCloseable > SAL_CALL getComponent(  ) throw (RuntimeException)
407         {
408             return Reference< css::util::XCloseable >();
409         }
410 
411         // XEmbeddedClient
412         virtual void SAL_CALL visibilityChanged( ::sal_Bool /*bVisible*/ ) throw (WrongStateException, RuntimeException)
413         {
414         }
415         inline void resetClient(ODocumentDefinition* _pClient) { m_pClient = _pClient; }
416     };
417 
418     //==================================================================
419     // LockModifiable
420     //==================================================================
421     class LockModifiable
422     {
423     public:
424         LockModifiable( const Reference< XInterface >& i_rModifiable )
425             :m_xModifiable( i_rModifiable, UNO_QUERY )
426         {
427             OSL_ENSURE( m_xModifiable.is(), "LockModifiable::LockModifiable: invalid component!" );
428             if ( m_xModifiable.is() )
429             {
430                 if ( !m_xModifiable->isSetModifiedEnabled() )
431                 {
432                     // somebody already locked that, no need to lock it, again, and no need to unlock it later
433                     m_xModifiable.clear();
434                 }
435                 else
436                 {
437                     m_xModifiable->disableSetModified();
438                 }
439             }
440         }
441 
442         ~LockModifiable()
443         {
444             if ( m_xModifiable.is() )
445                 m_xModifiable->enableSetModified();
446         }
447 
448     private:
449         Reference< XModifiable2 >   m_xModifiable;
450     };
451 
452     //==================================================================
453     // LifetimeCoupler
454     //==================================================================
455     typedef ::cppu::WeakImplHelper1 <   css::lang::XEventListener
456                                     >   LifetimeCoupler_Base;
457     /** helper class which couples the lifetime of a component to the lifetime
458         of another component
459 
460         Instances of this class are constructed with two components. The first is
461         simply held by reference, and thus kept alive. The second one is observed
462         for <code>disposing</code> calls - if they occur, i.e. if the component dies,
463         the reference to the first component is cleared.
464 
465         This way, you can ensure that a certain component is kept alive as long
466         as a second component is not disposed.
467     */
468     class LifetimeCoupler : public LifetimeCoupler_Base
469     {
470     private:
471         Reference< XInterface > m_xClient;
472 
473     public:
474         inline static void couple( const Reference< XInterface >& _rxClient, const Reference< XComponent >& _rxActor )
475         {
476             Reference< css::lang::XEventListener > xEnsureDelete( new LifetimeCoupler( _rxClient, _rxActor ) );
477         }
478 
479     private:
480         inline LifetimeCoupler( const Reference< XInterface >& _rxClient, const Reference< XComponent >& _rxActor )
481             :m_xClient( _rxClient )
482         {
483             DBG_ASSERT( _rxActor.is(), "LifetimeCoupler::LifetimeCoupler: this will crash!" );
484             osl_incrementInterlockedCount( &m_refCount );
485             {
486                 _rxActor->addEventListener( this );
487             }
488             osl_decrementInterlockedCount( &m_refCount );
489             DBG_ASSERT( m_refCount, "LifetimeCoupler::LifetimeCoupler: the actor is not holding us by hard ref - this won't work!" );
490         }
491 
492         virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) throw (RuntimeException);
493     protected:
494     };
495 
496     //------------------------------------------------------------------
497     void SAL_CALL LifetimeCoupler::disposing( const css::lang::EventObject& /*Source*/ ) throw (RuntimeException)
498     {
499         m_xClient.clear();
500     }
501 
502     //==================================================================
503     // ODocumentSaveContinuation
504     //==================================================================
505     class ODocumentSaveContinuation : public OInteraction< XInteractionDocumentSave >
506     {
507         ::rtl::OUString     m_sName;
508         Reference<XContent> m_xParentContainer;
509 
510     public:
511         ODocumentSaveContinuation() { }
512 
513         inline Reference<XContent>  getContent() const { return m_xParentContainer; }
514         inline ::rtl::OUString      getName() const { return m_sName; }
515 
516         // XInteractionDocumentSave
517         virtual void SAL_CALL setName( const ::rtl::OUString& _sName,const Reference<XContent>& _xParent) throw(RuntimeException);
518     };
519 
520     //------------------------------------------------------------------
521     void SAL_CALL ODocumentSaveContinuation::setName( const ::rtl::OUString& _sName,const Reference<XContent>& _xParent) throw(RuntimeException)
522     {
523         m_sName = _sName;
524         m_xParentContainer = _xParent;
525     }
526 
527 // -----------------------------------------------------------------------------
528 ::rtl::OUString ODocumentDefinition::GetDocumentServiceFromMediaType( const Reference< XStorage >& _rxContainerStorage,
529     const ::rtl::OUString& _rEntityName, const ::comphelper::ComponentContext& _rContext,
530     Sequence< sal_Int8 >& _rClassId )
531 {
532     return GetDocumentServiceFromMediaType(
533         lcl_determineContentType_nothrow( _rxContainerStorage, _rEntityName ),
534         _rContext, _rClassId );
535 }
536 
537 // -----------------------------------------------------------------------------
538 ::rtl::OUString ODocumentDefinition::GetDocumentServiceFromMediaType( const ::rtl::OUString& _rMediaType,
539     const ::comphelper::ComponentContext& _rContext, Sequence< sal_Int8 >& _rClassId )
540 {
541     ::rtl::OUString sResult;
542     try
543     {
544         ::comphelper::MimeConfigurationHelper aConfigHelper( _rContext.getLegacyServiceFactory() );
545         sResult = aConfigHelper.GetDocServiceNameFromMediaType( _rMediaType );
546         _rClassId = aConfigHelper.GetSequenceClassIDRepresentation(aConfigHelper.GetExplicitlyRegisteredObjClassID( _rMediaType ));
547         if ( !_rClassId.getLength() && sResult.getLength() )
548         {
549             Reference< XNameAccess > xObjConfig = aConfigHelper.GetObjConfiguration();
550             if ( xObjConfig.is() )
551             {
552                 Sequence< ::rtl::OUString > aClassIDs = xObjConfig->getElementNames();
553                 for ( sal_Int32 nInd = 0; nInd < aClassIDs.getLength(); nInd++ )
554                 {
555                     Reference< XNameAccess > xObjectProps;
556                     ::rtl::OUString aEntryDocName;
557 
558                     if (    ( xObjConfig->getByName( aClassIDs[nInd] ) >>= xObjectProps ) && xObjectProps.is()
559                          && ( xObjectProps->getByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectDocumentServiceName"))
560                                     ) >>= aEntryDocName )
561                          && aEntryDocName.equals( sResult ) )
562                     {
563                         _rClassId = aConfigHelper.GetSequenceClassIDRepresentation(aClassIDs[nInd]);
564                         break;
565                     }
566                 }
567             }
568         }
569 #if OSL_DEBUG_LEVEL > 0
570         // alternative, shorter approach
571         const Sequence< NamedValue > aProps( aConfigHelper.GetObjectPropsByMediaType( _rMediaType ) );
572         const ::comphelper::NamedValueCollection aMediaTypeProps( aProps );
573         const ::rtl::OUString sAlternativeResult = aMediaTypeProps.getOrDefault( "ObjectDocumentServiceName", ::rtl::OUString() );
574         OSL_ENSURE( sAlternativeResult == sResult, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (1)!" );
575         const Sequence< sal_Int8 > aAlternativeClassID = aMediaTypeProps.getOrDefault( "ClassID", Sequence< sal_Int8 >() );
576         OSL_ENSURE( aAlternativeClassID == _rClassId, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (2)!" );
577 #endif
578     }
579     catch ( Exception& )
580     {
581         DBG_UNHANDLED_EXCEPTION();
582     }
583     return sResult;
584 }
585 // -----------------------------------------------------------------------------
586 //==========================================================================
587 //= ODocumentDefinition
588 //==========================================================================
589 DBG_NAME(ODocumentDefinition)
590 
591 //--------------------------------------------------------------------------
592 ODocumentDefinition::ODocumentDefinition( const Reference< XInterface >& _rxContainer, const Reference< XMultiServiceFactory >& _xORB,
593                                           const TContentPtr& _pImpl, sal_Bool _bForm )
594     :OContentHelper(_xORB,_rxContainer,_pImpl)
595     ,OPropertyStateContainer(OContentHelper::rBHelper)
596     ,m_pInterceptor(NULL)
597     ,m_bForm(_bForm)
598     ,m_bOpenInDesign(sal_False)
599     ,m_bInExecute(sal_False)
600     ,m_bRemoveListener(sal_False)
601     ,m_pClientHelper(NULL)
602 {
603     DBG_CTOR(ODocumentDefinition, NULL);
604     registerProperties();
605 }
606 
607 //--------------------------------------------------------------------------
608 void ODocumentDefinition::initialLoad( const Sequence< sal_Int8 >& i_rClassID, const Sequence< PropertyValue >& i_rCreationArgs,
609                                        const Reference< XConnection >& i_rConnection )
610 {
611     OSL_ENSURE( i_rClassID.getLength(), "ODocumentDefinition::initialLoad: illegal class ID!" );
612     if ( !i_rClassID.getLength() )
613         return;
614 
615     loadEmbeddedObject( i_rConnection, i_rClassID, i_rCreationArgs, false, false );
616 }
617 
618 //--------------------------------------------------------------------------
619 ODocumentDefinition::~ODocumentDefinition()
620 {
621     DBG_DTOR(ODocumentDefinition, NULL);
622     if ( !OContentHelper::rBHelper.bInDispose && !OContentHelper::rBHelper.bDisposed )
623     {
624         acquire();
625         dispose();
626     }
627 
628     if ( m_pInterceptor )
629     {
630         m_pInterceptor->dispose();
631         m_pInterceptor->release();
632         m_pInterceptor = NULL;
633     }
634 }
635 // -----------------------------------------------------------------------------
636 void ODocumentDefinition::closeObject()
637 {
638     ::osl::MutexGuard aGuard(m_aMutex);
639     if ( m_xEmbeddedObject.is() )
640     {
641         try
642         {
643             Reference< com::sun::star::util::XCloseable> xCloseable(m_xEmbeddedObject,UNO_QUERY);
644             if ( xCloseable.is() )
645                 xCloseable->close(sal_True);
646         }
647         catch(Exception)
648         {
649         }
650         m_xEmbeddedObject = NULL;
651         if ( m_pClientHelper )
652         {
653             m_pClientHelper->resetClient(NULL);
654             m_pClientHelper->release();
655             m_pClientHelper = NULL;
656         }
657     }
658 }
659 // -----------------------------------------------------------------------------
660 void SAL_CALL ODocumentDefinition::disposing()
661 {
662     OContentHelper::disposing();
663     ::osl::MutexGuard aGuard(m_aMutex);
664     closeObject();
665     ::comphelper::disposeComponent(m_xListener);
666     if ( m_bRemoveListener )
667     {
668         Reference<util::XCloseable> xCloseable(m_pImpl->m_pDataSource->getModel_noCreate(),UNO_QUERY);
669         if ( xCloseable.is() )
670             xCloseable->removeCloseListener(this);
671     }
672 }
673 // -----------------------------------------------------------------------------
674 IMPLEMENT_TYPEPROVIDER3(ODocumentDefinition,OContentHelper,OPropertyStateContainer,ODocumentDefinition_Base);
675 IMPLEMENT_FORWARD_XINTERFACE3( ODocumentDefinition,OContentHelper,OPropertyStateContainer,ODocumentDefinition_Base)
676 IMPLEMENT_SERVICE_INFO1(ODocumentDefinition,"com.sun.star.comp.dba.ODocumentDefinition",SERVICE_SDB_DOCUMENTDEFINITION)
677 //--------------------------------------------------------------------------
678 void ODocumentDefinition::registerProperties()
679 {
680 #define REGISTER_PROPERTY( name, location ) \
681     registerProperty(   PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::READONLY, &location, ::getCppuType( &location ) );
682 
683 #define REGISTER_PROPERTY_BV( name, location ) \
684     registerProperty(   PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::CONSTRAINED | PropertyAttribute::BOUND | PropertyAttribute::READONLY, &location, ::getCppuType( &location ) );
685 
686     REGISTER_PROPERTY_BV( NAME,            m_pImpl->m_aProps.aTitle            );
687     REGISTER_PROPERTY   ( AS_TEMPLATE,     m_pImpl->m_aProps.bAsTemplate       );
688     REGISTER_PROPERTY   ( PERSISTENT_NAME, m_pImpl->m_aProps.sPersistentName   );
689     REGISTER_PROPERTY   ( IS_FORM,         m_bForm                             );
690 }
691 
692 // -----------------------------------------------------------------------------
693 void SAL_CALL ODocumentDefinition::getFastPropertyValue( Any& o_rValue, sal_Int32 i_nHandle ) const
694 {
695     if ( i_nHandle == PROPERTY_ID_PERSISTENT_PATH )
696     {
697         ::rtl::OUString sPersistentPath;
698         if ( m_pImpl->m_aProps.sPersistentName.getLength() )
699         {
700             ::rtl::OUStringBuffer aBuffer;
701             aBuffer.append( ODatabaseModelImpl::getObjectContainerStorageName( m_bForm ? ODatabaseModelImpl::E_FORM : ODatabaseModelImpl::E_REPORT ) );
702             aBuffer.append( sal_Unicode( '/' ) );
703             aBuffer.append( m_pImpl->m_aProps.sPersistentName );
704             sPersistentPath = aBuffer.makeStringAndClear();
705         }
706         o_rValue <<= sPersistentPath;
707         return;
708     }
709 
710     OPropertyStateContainer::getFastPropertyValue( o_rValue, i_nHandle );
711 }
712 
713 // -----------------------------------------------------------------------------
714 Reference< XPropertySetInfo > SAL_CALL ODocumentDefinition::getPropertySetInfo(  ) throw(RuntimeException)
715 {
716     Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) );
717     return xInfo;
718 }
719 
720 //--------------------------------------------------------------------------
721 IPropertyArrayHelper& ODocumentDefinition::getInfoHelper()
722 {
723     return *getArrayHelper();
724 }
725 
726 
727 //--------------------------------------------------------------------------
728 IPropertyArrayHelper* ODocumentDefinition::createArrayHelper( ) const
729 {
730     // properties maintained by our base class (see registerProperties)
731     Sequence< Property > aProps;
732     describeProperties( aProps );
733 
734     // properties not maintained by our base class
735     Sequence< Property > aManualProps( 1 );
736     aManualProps[0].Name = PROPERTY_PERSISTENT_PATH;
737     aManualProps[0].Handle = PROPERTY_ID_PERSISTENT_PATH;
738     aManualProps[0].Type = ::getCppuType( static_cast< const ::rtl::OUString* >( NULL ) );
739     aManualProps[0].Attributes = PropertyAttribute::READONLY;
740 
741     return new OPropertyArrayHelper( ::comphelper::concatSequences( aProps, aManualProps ) );
742 }
743 
744 // -----------------------------------------------------------------------------
745 class OExecuteImpl
746 {
747     sal_Bool& m_rbSet;
748 public:
749     OExecuteImpl(sal_Bool& _rbSet) : m_rbSet(_rbSet){ m_rbSet=sal_True; }
750     ~OExecuteImpl(){ m_rbSet = sal_False; }
751 };
752 
753 // -----------------------------------------------------------------------------
754 namespace
755 {
756     bool lcl_extractOpenMode( const Any& _rValue, sal_Int32& _out_rMode )
757     {
758         OpenCommandArgument aOpenCommand;
759         if ( _rValue >>= aOpenCommand )
760             _out_rMode = aOpenCommand.Mode;
761         else
762         {
763             OpenCommandArgument2 aOpenCommand2;
764             if ( _rValue >>= aOpenCommand2 )
765                 _out_rMode = aOpenCommand2.Mode;
766             else
767                 return false;
768         }
769         return true;
770     }
771 }
772 
773 // -----------------------------------------------------------------------------
774 void ODocumentDefinition::impl_removeFrameFromDesktop_throw( const ::comphelper::ComponentContext& _rContxt, const Reference< XFrame >& _rxFrame )
775 {
776     Reference< XFramesSupplier > xDesktop( _rContxt.createComponent( (::rtl::OUString)SERVICE_FRAME_DESKTOP ), UNO_QUERY_THROW );
777     Reference< XFrames > xFrames( xDesktop->getFrames(), UNO_QUERY_THROW );
778     xFrames->remove( _rxFrame );
779 }
780 
781 // -----------------------------------------------------------------------------
782 void ODocumentDefinition::impl_onActivateEmbeddedObject_nothrow( const bool i_bReactivated )
783 {
784     try
785     {
786         Reference< XModel > xModel( getComponent(), UNO_QUERY );
787         Reference< XController > xController( xModel.is() ? xModel->getCurrentController() : Reference< XController >() );
788         if ( !xController.is() )
789             return;
790 
791         if ( !m_xListener.is() )
792             // it's the first time the embedded object has been activated
793             // create an OEmbedObjectHolder
794             m_xListener = new OEmbedObjectHolder( m_xEmbeddedObject, this );
795 
796         // raise the window to top (especially necessary if this is not the first activation)
797         Reference< XFrame > xFrame( xController->getFrame(), UNO_SET_THROW );
798         Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW );
799         xTopWindow->toFront();
800 
801         // remove the frame from the desktop's frame collection because we need full control of it.
802         impl_removeFrameFromDesktop_throw( m_aContext, xFrame );
803 
804         // ensure that we ourself are kept alive as long as the embedded object's frame is
805         // opened
806         LifetimeCoupler::couple( *this, xFrame.get() );
807 
808         // init the edit view
809         if ( m_bForm && m_bOpenInDesign && !i_bReactivated )
810             impl_initFormEditView( xController );
811     }
812     catch( const RuntimeException& )
813     {
814         DBG_UNHANDLED_EXCEPTION();
815     }
816 }
817 
818 // -----------------------------------------------------------------------------
819 namespace
820 {
821     // =========================================================================
822     // = PreserveVisualAreaSize
823     // =========================================================================
824     /** stack-guard for preserving the size of the VisArea of an XModel
825     */
826     class PreserveVisualAreaSize
827     {
828     private:
829         Reference< XVisualObject >  m_xVisObject;
830         awt::Size m_aOriginalSize;
831 
832     public:
833         inline PreserveVisualAreaSize( const Reference< XModel >& _rxModel )
834             :m_xVisObject( _rxModel, UNO_QUERY )
835         {
836             if ( m_xVisObject.is() )
837             {
838                 try
839                 {
840                     m_aOriginalSize = m_xVisObject->getVisualAreaSize( Aspects::MSOLE_CONTENT );
841                 }
842                 catch ( Exception& )
843                 {
844                     DBG_ERROR( "PreserveVisualAreaSize::PreserveVisualAreaSize: caught an exception!" );
845                 }
846             }
847         }
848 
849         inline ~PreserveVisualAreaSize()
850         {
851             if ( m_xVisObject.is() && m_aOriginalSize.Width && m_aOriginalSize.Height )
852             {
853                 try
854                 {
855                     m_xVisObject->setVisualAreaSize( Aspects::MSOLE_CONTENT, m_aOriginalSize );
856                 }
857                 catch ( Exception& )
858                 {
859                     DBG_ERROR( "PreserveVisualAreaSize::~PreserveVisualAreaSize: caught an exception!" );
860                 }
861             }
862         }
863     };
864 
865     // =========================================================================
866     // = LayoutManagerLock
867     // =========================================================================
868     /** helper class for stack-usage which during its lifetime locks a layout manager
869     */
870     class LayoutManagerLock
871     {
872     private:
873         Reference< XLayoutManager > m_xLayoutManager;
874 
875     public:
876         inline LayoutManagerLock( const Reference< XController >& _rxController )
877         {
878             DBG_ASSERT( _rxController.is(), "LayoutManagerLock::LayoutManagerLock: this will crash!" );
879             Reference< XFrame > xFrame( _rxController->getFrame() );
880             try
881             {
882                 Reference< XPropertySet > xPropSet( xFrame, UNO_QUERY_THROW );
883                 m_xLayoutManager.set(
884                     xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) ),
885                     UNO_QUERY_THROW );
886                 m_xLayoutManager->lock();
887 
888             }
889             catch( Exception& )
890             {
891                 DBG_ERROR( "LayoutManagerLock::LayoutManagerLock: caught an exception!" );
892             }
893         }
894 
895         inline ~LayoutManagerLock()
896         {
897             try
898             {
899                 // unlock the layout manager
900                 if ( m_xLayoutManager.is() )
901                     m_xLayoutManager->unlock();
902             }
903             catch( Exception& )
904             {
905                 DBG_ERROR( "LayoutManagerLock::~LayoutManagerLock: caught an exception!" );
906             }
907         }
908     };
909 }
910 
911 // -----------------------------------------------------------------------------
912 void ODocumentDefinition::impl_initFormEditView( const Reference< XController >& _rxController )
913 {
914     try
915     {
916         Reference< XViewSettingsSupplier > xSettingsSupplier( _rxController, UNO_QUERY_THROW );
917         Reference< XPropertySet > xViewSettings( xSettingsSupplier->getViewSettings(), UNO_QUERY_THROW );
918 
919         // the below code could indirectly tamper with the "modified" flag of the model, temporarily disable this
920         LockModifiable aLockModify( _rxController->getModel() );
921 
922         // The visual area size can be changed by the setting of the following properties
923         // so it should be restored later
924         PreserveVisualAreaSize aPreserveVisAreaSize( _rxController->getModel() );
925 
926         // Layout manager should not layout while the size is still not restored
927         // so it will stay locked for this time
928         LayoutManagerLock aLockLayout( _rxController );
929 
930         // setting of the visual properties
931         xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowRulers")),makeAny(sal_True));
932         xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowVertRuler")),makeAny(sal_True));
933         xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowHoriRuler")),makeAny(sal_True));
934         xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsRasterVisible")),makeAny(sal_True));
935         xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsSnapToRaster")),makeAny(sal_True));
936         xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowOnlineLayout")),makeAny(sal_True));
937         xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RasterSubdivisionX")),makeAny(sal_Int32(5)));
938         xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RasterSubdivisionY")),makeAny(sal_Int32(5)));
939     }
940     catch( const Exception& )
941     {
942         DBG_UNHANDLED_EXCEPTION();
943     }
944 }
945 
946 // -----------------------------------------------------------------------------
947 void ODocumentDefinition::impl_showOrHideComponent_throw( const bool i_bShow )
948 {
949     const sal_Int32 nCurrentState = m_xEmbeddedObject.is() ? m_xEmbeddedObject->getCurrentState() : EmbedStates::LOADED;
950     switch ( nCurrentState )
951     {
952     default:
953     case EmbedStates::LOADED:
954         throw embed::WrongStateException( ::rtl::OUString(), *this );
955 
956     case EmbedStates::RUNNING:
957         if ( !i_bShow )
958             // fine, a running (and not yet active) object is never visible
959             return;
960         {
961             LockModifiable aLockModify( impl_getComponent_throw() );
962             m_xEmbeddedObject->changeState( EmbedStates::ACTIVE );
963             impl_onActivateEmbeddedObject_nothrow( false );
964         }
965         break;
966 
967     case EmbedStates::ACTIVE:
968     {
969         Reference< XModel > xEmbeddedDoc( impl_getComponent_throw( true ), UNO_QUERY_THROW );
970         Reference< XController > xEmbeddedController( xEmbeddedDoc->getCurrentController(), UNO_SET_THROW );
971         Reference< XFrame > xEmbeddedFrame( xEmbeddedController->getFrame(), UNO_SET_THROW );
972         Reference< XWindow > xEmbeddedWindow( xEmbeddedFrame->getContainerWindow(), UNO_SET_THROW );
973         xEmbeddedWindow->setVisible( i_bShow );
974     }
975     break;
976     }
977 }
978 
979 // -----------------------------------------------------------------------------
980 Any ODocumentDefinition::onCommandOpenSomething( const Any& _rOpenArgument, const bool _bActivate,
981         const Reference< XCommandEnvironment >& _rxEnvironment )
982 {
983     OExecuteImpl aExecuteGuard( m_bInExecute );
984 
985     Reference< XConnection > xConnection;
986     sal_Int32 nOpenMode = OpenMode::DOCUMENT;
987 
988     ::comphelper::NamedValueCollection aDocumentArgs;
989 
990     // for the document, default to the interaction handler as used for loading the DB doc
991     // This might be overwritten below, when examining _rOpenArgument.
992     const ::comphelper::NamedValueCollection& aDBDocArgs( m_pImpl->m_pDataSource->getMediaDescriptor() );
993     Reference< XInteractionHandler > xHandler( aDBDocArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) );
994     if ( xHandler.is() )
995         aDocumentArgs.put( "InteractionHandler", xHandler );
996 
997     ::boost::optional< sal_Int16 > aDocumentMacroMode;
998 
999     if ( !lcl_extractOpenMode( _rOpenArgument, nOpenMode ) )
1000     {
1001         Sequence< PropertyValue > aArguments;
1002         if ( _rOpenArgument >>= aArguments )
1003         {
1004             const PropertyValue* pIter = aArguments.getConstArray();
1005             const PropertyValue* pEnd  = pIter + aArguments.getLength();
1006             for ( ;pIter != pEnd; ++pIter )
1007             {
1008                 if ( pIter->Name == PROPERTY_ACTIVE_CONNECTION )
1009                 {
1010                     xConnection.set( pIter->Value, UNO_QUERY );
1011                     continue;
1012                 }
1013 
1014                 if ( lcl_extractOpenMode( pIter->Value, nOpenMode ) )
1015                     continue;
1016 
1017                 if ( pIter->Name.equalsAscii( "MacroExecutionMode" ) )
1018                 {
1019                     sal_Int16 nMacroExecMode( !aDocumentMacroMode ? MacroExecMode::USE_CONFIG : *aDocumentMacroMode );
1020                     OSL_VERIFY( pIter->Value >>= nMacroExecMode );
1021                     aDocumentMacroMode.reset( nMacroExecMode );
1022                     continue;
1023                 }
1024 
1025                 // unknown argument -> pass to the loaded document
1026                 aDocumentArgs.put( pIter->Name, pIter->Value );
1027             }
1028         }
1029     }
1030 
1031     bool bExecuteDBDocMacros = m_pImpl->m_pDataSource->checkMacrosOnLoading();
1032         // Note that this call implies the user might be asked for the macro execution mode.
1033         // Normally, this would happen when the database document is loaded, and subsequent calls
1034         // will simply use the user's decision from this point in time.
1035         // However, it is possible to programmatically load forms/reports, without actually
1036         // loading the database document into a frame. In this case, the user will be asked
1037         // here and now.
1038         // #i87741# / 2008-05-05 / frank.schoenheit@sun.com
1039 
1040     // allow the command arguments to downgrade the macro execution mode, but not to upgrade
1041     // it
1042     if  (   ( m_pImpl->m_pDataSource->getImposedMacroExecMode() == MacroExecMode::USE_CONFIG )
1043         &&  bExecuteDBDocMacros
1044         )
1045     {
1046         // while loading the whole database document, USE_CONFIG, was passed.
1047         // Additionally, *by now* executing macros from the DB doc is allowed (this is what bExecuteDBDocMacros
1048         // indicates). This means either one of:
1049         // 1. The DB doc or one of the sub docs contained macros and
1050         // 1a. the user explicitly allowed executing them
1051         // 1b. the configuration allows executing them without asking the user
1052         // 2. Neither the DB doc nor the sub docs contained macros, thus macro
1053         //    execution was silently enabled, assuming that any macro will be a
1054         //    user-created macro
1055         //
1056         // The problem with this: If the to-be-opened sub document has macros embedded in
1057         // the content.xml (which is valid ODF, but normally not produced by OOo itself),
1058         // then this has not been detected while loading the database document - it would
1059         // be too expensive, as it effectively would require loading all forms/reports.
1060         //
1061         // So, in such a case, and with 2. above, we would silently execute those macros,
1062         // regardless of the global security settings - which would be a security issue, of
1063         // course.
1064         if ( m_pImpl->m_pDataSource->determineEmbeddedMacros() == ODatabaseModelImpl::eNoMacros )
1065         {
1066             // this is case 2. from above
1067             // So, pass a USE_CONFIG to the to-be-loaded document. This means that
1068             // the user will be prompted with a security message upon opening this
1069             // sub document, in case the settings require this, *and* the document
1070             // contains scripts in the content.xml. But this is better than the security
1071             // issue we had before ...
1072             aDocumentMacroMode.reset( MacroExecMode::USE_CONFIG );
1073         }
1074     }
1075 
1076     if ( !aDocumentMacroMode )
1077     {
1078         // nobody so far felt responsible for setting it
1079         // => use the DBDoc-wide macro exec mode for the document, too
1080         aDocumentMacroMode.reset( bExecuteDBDocMacros ? MacroExecMode::ALWAYS_EXECUTE_NO_WARN : MacroExecMode::NEVER_EXECUTE );
1081     }
1082     aDocumentArgs.put( "MacroExecutionMode", *aDocumentMacroMode );
1083 
1084     if  (   ( nOpenMode == OpenMode::ALL )
1085         ||  ( nOpenMode == OpenMode::FOLDERS )
1086         ||  ( nOpenMode == OpenMode::DOCUMENTS )
1087         ||  ( nOpenMode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
1088         ||  ( nOpenMode == OpenMode::DOCUMENT_SHARE_DENY_WRITE )
1089         )
1090     {
1091         // not supported
1092         ucbhelper::cancelCommandExecution(
1093                 makeAny( UnsupportedOpenModeException(
1094                                 rtl::OUString(),
1095                                 static_cast< cppu::OWeakObject * >( this ),
1096                                 sal_Int16( nOpenMode ) ) ),
1097                 _rxEnvironment );
1098         // Unreachable
1099         DBG_ERROR( "unreachable" );
1100     }
1101 
1102     OSL_ENSURE( m_pImpl->m_aProps.sPersistentName.getLength(),
1103         "ODocumentDefinition::onCommandOpenSomething: no persistent name - cannot load!" );
1104     if ( !m_pImpl->m_aProps.sPersistentName.getLength() )
1105         return Any();
1106 
1107     // embedded objects themself do not support the hidden flag. We implement support for
1108     // it by changing the STATE to RUNNING only, instead of ACTIVE.
1109     bool bOpenHidden = aDocumentArgs.getOrDefault( "Hidden", false );
1110     aDocumentArgs.remove( "Hidden" );
1111 
1112     loadEmbeddedObject( xConnection, Sequence< sal_Int8 >(), aDocumentArgs.getPropertyValues(), false, !m_bOpenInDesign );
1113     OSL_ENSURE( m_xEmbeddedObject.is(), "ODocumentDefinition::onCommandOpenSomething: what's this?" );
1114     if ( !m_xEmbeddedObject.is() )
1115         return Any();
1116 
1117     Reference< XModel > xModel( getComponent(), UNO_QUERY );
1118     Reference< report::XReportDefinition > xReportDefinition(xModel,UNO_QUERY);
1119 
1120     Reference< XModule > xModule( xModel, UNO_QUERY );
1121     if ( xModule.is() )
1122     {
1123         if ( m_bForm )
1124             xModule->setIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.FormDesign" ) ) );
1125         else if ( !xReportDefinition.is() )
1126             xModule->setIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TextReportDesign" ) ) );
1127 
1128         updateDocumentTitle();
1129     }
1130 
1131     bool bIsAliveNewStyleReport = ( !m_bOpenInDesign && xReportDefinition.is() );
1132     if ( bIsAliveNewStyleReport )
1133     {
1134         // we are in ReadOnly mode
1135         // we would like to open the Writer or Calc with the report direct, without design it.
1136         Reference< report::XReportEngine > xReportEngine( m_aContext.createComponent( "com.sun.star.comp.report.OReportEngineJFree" ), UNO_QUERY_THROW );
1137 
1138         xReportEngine->setReportDefinition(xReportDefinition);
1139         xReportEngine->setActiveConnection(m_xLastKnownConnection);
1140         if ( bOpenHidden )
1141             return makeAny( xReportEngine->createDocumentModel() );
1142         return makeAny( xReportEngine->createDocumentAlive( NULL ) );
1143     }
1144 
1145     if ( _bActivate && !bOpenHidden )
1146     {
1147         LockModifiable aLockModify( impl_getComponent_throw() );
1148         m_xEmbeddedObject->changeState( EmbedStates::ACTIVE );
1149         impl_onActivateEmbeddedObject_nothrow( false );
1150     }
1151     else
1152     {
1153         // ensure that we ourself are kept alive as long as the document is open
1154         LifetimeCoupler::couple( *this, xModel.get() );
1155     }
1156 
1157     if ( !m_bForm && m_pImpl->m_aProps.bAsTemplate && !m_bOpenInDesign )
1158         ODocumentDefinition::fillReportData( m_aContext, getComponent(), xConnection );
1159 
1160     return makeAny( xModel );
1161 }
1162 
1163 // -----------------------------------------------------------------------------
1164 Any SAL_CALL ODocumentDefinition::execute( const Command& aCommand, sal_Int32 CommandId, const Reference< XCommandEnvironment >& Environment ) throw (Exception, CommandAbortedException, RuntimeException)
1165 {
1166     Any aRet;
1167 
1168     sal_Bool bOpen = aCommand.Name.equalsAscii( "open" );
1169     sal_Bool bOpenInDesign = aCommand.Name.equalsAscii( "openDesign" );
1170     sal_Bool bOpenForMail = aCommand.Name.equalsAscii( "openForMail" );
1171     if ( bOpen || bOpenInDesign || bOpenForMail )
1172     {
1173         // opening the document involves a lot of VCL code, which is not thread-safe, but needs the SolarMutex locked.
1174         // Unfortunately, the DocumentDefinition, as well as the EmbeddedObject implementation, calls into VCL-dependent
1175         // components *without* releasing the own mutex, which is a guaranteed recipe for deadlocks.
1176         // We have control over this implementation here, and in modifying it to release the own mutex before calling into
1177         // the VCL-dependent components is not too difficult (was there, seen it).
1178         // However, we do /not/ have control over the EmbeddedObject implementation, and from a first look, it seems as
1179         // making it release the own mutex before calling SolarMutex-code is ... difficult, at least.
1180         // So, to be on the same side, we lock the SolarMutex here. Yes, it sucks.
1181         ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1182         ::osl::ClearableMutexGuard aGuard(m_aMutex);
1183         if ( m_bInExecute )
1184             return aRet;
1185 
1186         bool bActivateObject = true;
1187         if ( bOpenForMail )
1188         {
1189             OSL_ENSURE( false, "ODocumentDefinition::execute: 'openForMail' should not be used anymore - use the 'Hidden' parameter instead!" );
1190             bActivateObject = false;
1191         }
1192 
1193         // if the object is already opened, do nothing
1194         // #i89509# / 2008-05-22 / frank.schoenheit@sun.com
1195         if ( m_xEmbeddedObject.is() )
1196         {
1197             sal_Int32 nCurrentState = m_xEmbeddedObject->getCurrentState();
1198             bool bIsActive = ( nCurrentState == EmbedStates::ACTIVE );
1199 
1200             if ( bIsActive )
1201             {
1202                 // exception: new-style reports always create a new document when "open" is executed
1203                 Reference< report::XReportDefinition > xReportDefinition( impl_getComponent_throw( false ), UNO_QUERY );
1204                 bool bIsAliveNewStyleReport = ( xReportDefinition.is() && ( bOpen || bOpenForMail ) );
1205 
1206                 if ( !bIsAliveNewStyleReport )
1207                 {
1208                     impl_onActivateEmbeddedObject_nothrow( true );
1209                     return makeAny( getComponent() );
1210                 }
1211             }
1212         }
1213 
1214         m_bOpenInDesign = bOpenInDesign || bOpenForMail;
1215         return onCommandOpenSomething( aCommand.Argument, bActivateObject, Environment );
1216     }
1217 
1218     ::osl::ClearableMutexGuard aGuard(m_aMutex);
1219     if ( m_bInExecute )
1220         return aRet;
1221 
1222     if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "copyTo" ) ) )
1223     {
1224         Sequence<Any> aIni;
1225         aCommand.Argument >>= aIni;
1226         if ( aIni.getLength() != 2 )
1227         {
1228             OSL_ENSURE( sal_False, "Wrong argument type!" );
1229             ucbhelper::cancelCommandExecution(
1230                 makeAny( IllegalArgumentException(
1231                                     rtl::OUString(),
1232                                     static_cast< cppu::OWeakObject * >( this ),
1233                                     -1 ) ),
1234                 Environment );
1235             // Unreachable
1236         }
1237         Reference< XStorage> xDest(aIni[0],UNO_QUERY);
1238         ::rtl::OUString sPersistentName;
1239         aIni[1] >>= sPersistentName;
1240         Reference< XStorage> xStorage = getContainerStorage();
1241         // -----------------------------------------------------------------------------
1242         xStorage->copyElementTo(m_pImpl->m_aProps.sPersistentName,xDest,sPersistentName);
1243     }
1244     else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "preview" ) ) )
1245     {
1246         onCommandPreview(aRet);
1247     }
1248     else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
1249     {
1250         Sequence<Any> aIni;
1251         aCommand.Argument >>= aIni;
1252         if ( !aIni.getLength() )
1253         {
1254             OSL_ENSURE( sal_False, "Wrong argument count!" );
1255             ucbhelper::cancelCommandExecution(
1256                 makeAny( IllegalArgumentException(
1257                                     rtl::OUString(),
1258                                     static_cast< cppu::OWeakObject * >( this ),
1259                                     -1 ) ),
1260                 Environment );
1261             // Unreachable
1262         }
1263         ::rtl::OUString sURL;
1264         aIni[0] >>= sURL;
1265         onCommandInsert( sURL, Environment );
1266     }
1267     else if (   aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getdocumentinfo" ) )   // compatibility
1268             ||  aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getDocumentInfo" ) )
1269             )
1270     {
1271         onCommandGetDocumentProperties( aRet );
1272     }
1273     else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
1274     {
1275         //////////////////////////////////////////////////////////////////
1276         // delete
1277         //////////////////////////////////////////////////////////////////
1278         closeObject();
1279         Reference< XStorage> xStorage = getContainerStorage();
1280         if ( xStorage.is() )
1281             xStorage->removeElement(m_pImpl->m_aProps.sPersistentName);
1282 
1283         dispose();
1284 
1285     }
1286     else if (   ( aCommand.Name.compareToAscii( "storeOwn" ) == 0 ) // compatibility
1287             ||  ( aCommand.Name.compareToAscii( "store" ) == 0 )
1288             )
1289     {
1290         impl_store_throw();
1291     }
1292     else if (   ( aCommand.Name.compareToAscii( "shutdown" ) == 0 ) // compatibility
1293             ||  ( aCommand.Name.compareToAscii( "close" ) == 0 )
1294             )
1295     {
1296         aRet <<= impl_close_throw();
1297     }
1298     else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "show" ) ) )
1299     {
1300         impl_showOrHideComponent_throw( true );
1301     }
1302     else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "hide" ) ) )
1303     {
1304         impl_showOrHideComponent_throw( false );
1305     }
1306     else
1307     {
1308         aRet = OContentHelper::execute(aCommand,CommandId,Environment);
1309     }
1310 
1311     return aRet;
1312 }
1313 // -----------------------------------------------------------------------------
1314 namespace
1315 {
1316     void lcl_resetChildFormsToEmptyDataSource( const Reference< XIndexAccess>& _rxFormsContainer )
1317     {
1318         OSL_PRECOND( _rxFormsContainer.is(), "lcl_resetChildFormsToEmptyDataSource: illegal call!" );
1319         sal_Int32 count = _rxFormsContainer->getCount();
1320         for ( sal_Int32 i = 0; i < count; ++i )
1321         {
1322             Reference< XForm > xForm( _rxFormsContainer->getByIndex( i ), UNO_QUERY );
1323             if ( !xForm.is() )
1324                 continue;
1325 
1326             // if the element is a form, reset its DataSourceName property to an empty string
1327             try
1328             {
1329                 Reference< XPropertySet > xFormProps( xForm, UNO_QUERY_THROW );
1330                 xFormProps->setPropertyValue( PROPERTY_DATASOURCENAME, makeAny( ::rtl::OUString() ) );
1331             }
1332             catch( const Exception& )
1333             {
1334                 DBG_UNHANDLED_EXCEPTION();
1335             }
1336 
1337             // if the element is a container itself, step down the component hierarchy
1338             Reference< XIndexAccess > xContainer( xForm, UNO_QUERY );
1339             if ( xContainer.is() )
1340                 lcl_resetChildFormsToEmptyDataSource( xContainer );
1341         }
1342     }
1343 
1344     void lcl_resetFormsToEmptyDataSource( const Reference< XEmbeddedObject>& _rxEmbeddedObject )
1345     {
1346         try
1347         {
1348             Reference< XComponentSupplier > xCompProv( _rxEmbeddedObject, UNO_QUERY_THROW );
1349             Reference< XDrawPageSupplier > xSuppPage( xCompProv->getComponent(), UNO_QUERY_THROW );
1350                 // if this interface does not exist, then either getComponent returned NULL,
1351                 // or the document is a multi-page document. The latter is allowed, but currently
1352                 // simply not handled by this code, as it would not normally happen.
1353 
1354             Reference< XFormsSupplier > xSuppForms( xSuppPage->getDrawPage(), UNO_QUERY_THROW );
1355             Reference< XIndexAccess > xForms( xSuppForms->getForms(), UNO_QUERY_THROW );
1356             lcl_resetChildFormsToEmptyDataSource( xForms );
1357         }
1358         catch( const Exception& )
1359         {
1360             DBG_UNHANDLED_EXCEPTION();
1361         }
1362 
1363     }
1364 }
1365 // -----------------------------------------------------------------------------
1366 void ODocumentDefinition::onCommandInsert( const ::rtl::OUString& _sURL, const Reference< XCommandEnvironment >& Environment )
1367     throw( Exception )
1368 {
1369     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1370 
1371     // Check, if all required properties were set.
1372     if ( !_sURL.getLength() || m_xEmbeddedObject.is() )
1373     {
1374         OSL_ENSURE( sal_False, "Content::onCommandInsert - property value missing!" );
1375 
1376         Sequence< rtl::OUString > aProps( 1 );
1377         aProps[ 0 ] = PROPERTY_URL;
1378         ucbhelper::cancelCommandExecution(
1379             makeAny( MissingPropertiesException(
1380                                 rtl::OUString(),
1381                                 static_cast< cppu::OWeakObject * >( this ),
1382                                 aProps ) ),
1383             Environment );
1384         // Unreachable
1385     }
1386 
1387 
1388     if ( !m_xEmbeddedObject.is() )
1389     {
1390         Reference< XStorage> xStorage = getContainerStorage();
1391         if ( xStorage.is() )
1392         {
1393             Reference< XEmbedObjectCreator> xEmbedFactory( m_aContext.createComponent( "com.sun.star.embed.EmbeddedObjectCreator" ), UNO_QUERY );
1394             if ( xEmbedFactory.is() )
1395             {
1396                 Sequence<PropertyValue> aEmpty,aMediaDesc(1);
1397                 aMediaDesc[0].Name = PROPERTY_URL;
1398                 aMediaDesc[0].Value <<= _sURL;
1399                 m_xEmbeddedObject.set(xEmbedFactory->createInstanceInitFromMediaDescriptor( xStorage
1400                                                                                 ,m_pImpl->m_aProps.sPersistentName
1401                                                                                 ,aMediaDesc
1402                                                                                 ,aEmpty),UNO_QUERY);
1403 
1404                 lcl_resetFormsToEmptyDataSource( m_xEmbeddedObject );
1405                 // #i57669# / 2005-12-01 / frank.schoenheit@sun.com
1406 
1407                 Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY);
1408                 if ( xPersist.is() )
1409                 {
1410                     xPersist->storeOwn();
1411                 }
1412                 try
1413                 {
1414                     Reference< com::sun::star::util::XCloseable> xCloseable(m_xEmbeddedObject,UNO_QUERY);
1415                     if ( xCloseable.is() )
1416                         xCloseable->close(sal_True);
1417                 }
1418                 catch(Exception)
1419                 {
1420                 }
1421                 m_xEmbeddedObject = NULL;
1422             }
1423         }
1424     }
1425 
1426 //  @@@
1427 //  storeData();
1428 
1429     aGuard.clear();
1430 //  inserted();
1431 }
1432 // -----------------------------------------------------------------------------
1433 sal_Bool ODocumentDefinition::save(sal_Bool _bApprove)
1434 {
1435     // default handling: instantiate an interaction handler and let it handle the parameter request
1436     if ( !m_bOpenInDesign )
1437         return sal_False;
1438     try
1439     {
1440 
1441         {
1442             ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
1443 
1444             // the request
1445             Reference<XNameAccess> xName(m_xParentContainer,UNO_QUERY);
1446             DocumentSaveRequest aRequest;
1447             aRequest.Name = m_pImpl->m_aProps.aTitle;
1448             if ( !aRequest.Name.getLength() )
1449             {
1450                 if ( m_bForm )
1451                     aRequest.Name = DBACORE_RESSTRING( RID_STR_FORM );
1452                 else
1453                     aRequest.Name = DBACORE_RESSTRING( RID_STR_REPORT );
1454                 aRequest.Name = ::dbtools::createUniqueName(xName,aRequest.Name);
1455             }
1456 
1457             aRequest.Content.set(m_xParentContainer,UNO_QUERY);
1458             OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
1459             Reference< XInteractionRequest > xRequest(pRequest);
1460             // some knittings
1461             // two continuations allowed: OK and Cancel
1462             ODocumentSaveContinuation* pDocuSave = NULL;
1463 
1464             if ( !m_pImpl->m_aProps.aTitle.getLength() )
1465             {
1466                 pDocuSave = new ODocumentSaveContinuation;
1467                 pRequest->addContinuation(pDocuSave);
1468             }
1469             OInteraction< XInteractionApprove >* pApprove = NULL;
1470             if ( _bApprove )
1471             {
1472                 pApprove = new OInteraction< XInteractionApprove >;
1473                 pRequest->addContinuation(pApprove);
1474             }
1475 
1476             OInteraction< XInteractionDisapprove >* pDisApprove = new OInteraction< XInteractionDisapprove >;
1477             pRequest->addContinuation(pDisApprove);
1478 
1479             OInteractionAbort* pAbort = new OInteractionAbort;
1480             pRequest->addContinuation(pAbort);
1481 
1482             // create the handler, let it handle the request
1483             Reference< XInteractionHandler > xHandler( m_aContext.createComponent( (::rtl::OUString)SERVICE_TASK_INTERACTION_HANDLER ), UNO_QUERY );
1484             if ( xHandler.is() )
1485                 xHandler->handle(xRequest);
1486 
1487             if ( pAbort->wasSelected() )
1488                 return sal_False;
1489             if  ( pDisApprove->wasSelected() )
1490                 return sal_True;
1491             if ( pDocuSave && pDocuSave->wasSelected() )
1492             {
1493                 Reference<XNameContainer> xNC( pDocuSave->getContent(), UNO_QUERY_THROW );
1494 
1495                 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1496                 NameChangeNotifier aNameChangeAndNotify( *this, pDocuSave->getName(), aGuard );
1497                 m_pImpl->m_aProps.aTitle = pDocuSave->getName();
1498 
1499                 Reference< XContent> xContent = this;
1500                 xNC->insertByName(pDocuSave->getName(),makeAny(xContent));
1501 
1502                 updateDocumentTitle();
1503             }
1504         }
1505 
1506         ::osl::MutexGuard aGuard(m_aMutex);
1507         Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY);
1508         if ( xPersist.is() )
1509         {
1510             xPersist->storeOwn();
1511             notifyDataSourceModified();
1512         }
1513     }
1514     catch(Exception&)
1515     {
1516         OSL_ENSURE(0,"ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1517     }
1518     return sal_True;
1519 }
1520 // -----------------------------------------------------------------------------
1521 sal_Bool ODocumentDefinition::saveAs()
1522 {
1523     // default handling: instantiate an interaction handler and let it handle the parameter request
1524     if ( !m_bOpenInDesign )
1525         return sal_False;
1526 
1527     {
1528         osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1529         if ( !m_pImpl->m_aProps.aTitle.getLength() )
1530         {
1531             aGuard.clear();
1532             return save(sal_False); // (sal_False) : we don't want an approve dialog
1533         }
1534     }
1535     try
1536     {
1537         {
1538             ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
1539 
1540             // the request
1541             Reference<XNameAccess> xName(m_xParentContainer,UNO_QUERY);
1542             DocumentSaveRequest aRequest;
1543             aRequest.Name = m_pImpl->m_aProps.aTitle;
1544 
1545             aRequest.Content.set(m_xParentContainer,UNO_QUERY);
1546             OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
1547             Reference< XInteractionRequest > xRequest(pRequest);
1548             // some knittings
1549             // two continuations allowed: OK and Cancel
1550             ODocumentSaveContinuation* pDocuSave = new ODocumentSaveContinuation;
1551             pRequest->addContinuation(pDocuSave);
1552             OInteraction< XInteractionDisapprove >* pDisApprove = new OInteraction< XInteractionDisapprove >;
1553             pRequest->addContinuation(pDisApprove);
1554             OInteractionAbort* pAbort = new OInteractionAbort;
1555             pRequest->addContinuation(pAbort);
1556 
1557             // create the handler, let it handle the request
1558             Reference< XInteractionHandler > xHandler(m_aContext.createComponent(::rtl::OUString(SERVICE_TASK_INTERACTION_HANDLER)), UNO_QUERY);
1559             if ( xHandler.is() )
1560                 xHandler->handle(xRequest);
1561 
1562             if ( pAbort->wasSelected() )
1563                 return sal_False;
1564             if  ( pDisApprove->wasSelected() )
1565                 return sal_True;
1566             if ( pDocuSave->wasSelected() )
1567             {
1568                 ::osl::MutexGuard aGuard(m_aMutex);
1569                 Reference<XNameContainer> xNC(pDocuSave->getContent(),UNO_QUERY);
1570                 if ( xNC.is() )
1571                 {
1572                     if ( m_pImpl->m_aProps.aTitle != pDocuSave->getName() )
1573                     {
1574                         try
1575                         {
1576                             Reference< XStorage> xStorage = getContainerStorage();
1577                             const static ::rtl::OUString sBaseName(RTL_CONSTASCII_USTRINGPARAM("Obj"));
1578                             // -----------------------------------------------------------------------------
1579                             Reference<XNameAccess> xElements(xStorage,UNO_QUERY_THROW);
1580                             ::rtl::OUString sPersistentName = ::dbtools::createUniqueName(xElements,sBaseName);
1581                             xStorage->copyElementTo(m_pImpl->m_aProps.sPersistentName,xStorage,sPersistentName);
1582 
1583                             ::rtl::OUString sOldName = m_pImpl->m_aProps.aTitle;
1584                             rename(pDocuSave->getName());
1585                             updateDocumentTitle();
1586 
1587                             Sequence< Any > aArguments(3);
1588                             PropertyValue aValue;
1589                             // set as folder
1590                             aValue.Name = PROPERTY_NAME;
1591                             aValue.Value <<= sOldName;
1592                             aArguments[0] <<= aValue;
1593 
1594                             aValue.Name = PROPERTY_PERSISTENT_NAME;
1595                             aValue.Value <<= sPersistentName;
1596                             aArguments[1] <<= aValue;
1597 
1598                             aValue.Name = PROPERTY_AS_TEMPLATE;
1599                             aValue.Value <<= m_pImpl->m_aProps.bAsTemplate;
1600                             aArguments[2] <<= aValue;
1601 
1602                             Reference< XMultiServiceFactory > xORB( m_xParentContainer, UNO_QUERY_THROW );
1603                             Reference< XInterface > xComponent( xORB->createInstanceWithArguments( SERVICE_SDB_DOCUMENTDEFINITION, aArguments ) );
1604                             Reference< XNameContainer > xNameContainer( m_xParentContainer, UNO_QUERY_THROW );
1605                             xNameContainer->insertByName( sOldName, makeAny( xComponent ) );
1606                         }
1607                         catch(Exception&)
1608                         {
1609                             DBG_UNHANDLED_EXCEPTION();
1610                         }
1611                     }
1612                     Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY);
1613                     if ( xPersist.is() )
1614                     {
1615                         xPersist->storeOwn();
1616                         notifyDataSourceModified();
1617                     }
1618                 }
1619             }
1620         }
1621 
1622 
1623     }
1624     catch(Exception&)
1625     {
1626         OSL_ENSURE(0,"ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1627     }
1628     return sal_True;
1629 }
1630 
1631 namespace
1632 {
1633     // .........................................................................
1634     void    lcl_putLoadArgs( ::comphelper::NamedValueCollection& _io_rArgs, const optional_bool _bSuppressMacros, const optional_bool _bReadOnly )
1635     {
1636         if ( !!_bSuppressMacros )
1637         {
1638             if ( *_bSuppressMacros )
1639             {
1640                 // if we're to suppress macros, do exactly this
1641                 _io_rArgs.put( "MacroExecutionMode", MacroExecMode::NEVER_EXECUTE );
1642             }
1643             else
1644             {
1645                 // otherwise, put the setting only if not already present
1646                 if ( !_io_rArgs.has( "MacroExecutionMode" ) )
1647                 {
1648                     _io_rArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
1649                 }
1650             }
1651         }
1652 
1653         if ( !!_bReadOnly )
1654             _io_rArgs.put( "ReadOnly", *_bReadOnly );
1655     }
1656 }
1657 
1658 // -----------------------------------------------------------------------------
1659 namespace
1660 {
1661     Reference< XFrame > lcl_getDatabaseDocumentFrame( ODatabaseModelImpl& _rImpl )
1662     {
1663         Reference< XModel > xDatabaseDocumentModel( _rImpl.getModel_noCreate() );
1664 
1665         Reference< XController > xDatabaseDocumentController;
1666         if ( xDatabaseDocumentModel.is() )
1667             xDatabaseDocumentController = xDatabaseDocumentModel->getCurrentController();
1668 
1669         Reference< XFrame > xFrame;
1670         if ( xDatabaseDocumentController.is() )
1671             xFrame = xDatabaseDocumentController->getFrame();
1672 
1673         return xFrame;
1674     }
1675 }
1676 
1677 // -----------------------------------------------------------------------------
1678 sal_Bool ODocumentDefinition::objectSupportsEmbeddedScripts() const
1679 {
1680     bool bAllowDocumentMacros = !m_pImpl->m_pDataSource
1681                             ||  ( m_pImpl->m_pDataSource->determineEmbeddedMacros() == ODatabaseModelImpl::eSubDocumentMacros );
1682 
1683     // if *any* of the objects of the database document already has macros, we continue to allow it
1684     // to have them, until the user did a migration.
1685     // If there are no macros, yet, we don't allow to create them
1686 
1687     return bAllowDocumentMacros;
1688 }
1689 
1690 // -----------------------------------------------------------------------------
1691 ::rtl::OUString ODocumentDefinition::determineContentType() const
1692 {
1693     return lcl_determineContentType_nothrow( getContainerStorage(), m_pImpl->m_aProps.sPersistentName );
1694 }
1695 
1696 // -----------------------------------------------------------------------------
1697 void ODocumentDefinition::separateOpenCommandArguments( const Sequence< PropertyValue >& i_rOpenCommandArguments,
1698         ::comphelper::NamedValueCollection& o_rDocumentLoadArgs, ::comphelper::NamedValueCollection& o_rEmbeddedObjectDescriptor )
1699 {
1700     ::comphelper::NamedValueCollection aOpenCommandArguments( i_rOpenCommandArguments );
1701 
1702     const sal_Char* pObjectDescriptorArgs[] =
1703     {
1704         "RecoveryStorage"
1705     };
1706     for ( size_t i=0; i < sizeof( pObjectDescriptorArgs ) / sizeof( pObjectDescriptorArgs[0] ); ++i )
1707     {
1708         if ( aOpenCommandArguments.has( pObjectDescriptorArgs[i] ) )
1709         {
1710             o_rEmbeddedObjectDescriptor.put( pObjectDescriptorArgs[i], aOpenCommandArguments.get( pObjectDescriptorArgs[i] ) );
1711             aOpenCommandArguments.remove( pObjectDescriptorArgs[i] );
1712         }
1713     }
1714 
1715     o_rDocumentLoadArgs.merge( aOpenCommandArguments, false );
1716 }
1717 
1718 // -----------------------------------------------------------------------------
1719 Sequence< PropertyValue > ODocumentDefinition::fillLoadArgs( const Reference< XConnection>& _xConnection, const bool _bSuppressMacros, const bool _bReadOnly,
1720         const Sequence< PropertyValue >& i_rOpenCommandArguments, Sequence< PropertyValue >& _out_rEmbeddedObjectDescriptor )
1721 {
1722     // .........................................................................
1723     // (re-)create interceptor, and put it into the descriptor of the embedded object
1724     if ( m_pInterceptor )
1725     {
1726         m_pInterceptor->dispose();
1727         m_pInterceptor->release();
1728         m_pInterceptor = NULL;
1729     }
1730 
1731     m_pInterceptor = new OInterceptor( this ,_bReadOnly);
1732     m_pInterceptor->acquire();
1733     Reference<XDispatchProviderInterceptor> xInterceptor = m_pInterceptor;
1734 
1735     ::comphelper::NamedValueCollection aEmbeddedDescriptor;
1736     aEmbeddedDescriptor.put( "OutplaceDispatchInterceptor", xInterceptor );
1737 
1738     // .........................................................................
1739     ::comphelper::NamedValueCollection aMediaDesc;
1740     separateOpenCommandArguments( i_rOpenCommandArguments, aMediaDesc, aEmbeddedDescriptor );
1741 
1742     // .........................................................................
1743     // create the OutplaceFrameProperties, and put them into the descriptor of the embedded object
1744     ::comphelper::NamedValueCollection OutplaceFrameProperties;
1745     OutplaceFrameProperties.put( "TopWindow", (sal_Bool)sal_True );
1746 
1747     Reference< XFrame > xParentFrame;
1748     if ( m_pImpl->m_pDataSource )
1749         xParentFrame = lcl_getDatabaseDocumentFrame( *m_pImpl->m_pDataSource );
1750     if ( !xParentFrame.is() )
1751     { // i87957 we need a parent frame
1752         Reference< XComponentLoader > xDesktop( m_aContext.createComponent( (::rtl::OUString)SERVICE_FRAME_DESKTOP ), UNO_QUERY_THROW );
1753         xParentFrame.set( xDesktop, UNO_QUERY );
1754         if ( xParentFrame.is() )
1755         {
1756             Reference<util::XCloseable> xCloseable(m_pImpl->m_pDataSource->getModel_noCreate(),UNO_QUERY);
1757             if ( xCloseable.is() )
1758             {
1759                 xCloseable->addCloseListener(this);
1760                 m_bRemoveListener = sal_True;
1761             }
1762         }
1763     }
1764     OSL_ENSURE( xParentFrame.is(), "ODocumentDefinition::fillLoadArgs: no parent frame!" );
1765     if  ( xParentFrame.is() )
1766         OutplaceFrameProperties.put( "ParentFrame", xParentFrame );
1767 
1768     aEmbeddedDescriptor.put( "OutplaceFrameProperties", OutplaceFrameProperties.getNamedValues() );
1769 
1770     // .........................................................................
1771     // tell the embedded object to have (or not have) script support
1772     aEmbeddedDescriptor.put( "EmbeddedScriptSupport", (sal_Bool)objectSupportsEmbeddedScripts() );
1773 
1774     // .........................................................................
1775     // tell the embedded object to not participate in the document recovery game - the DB doc will handle it
1776     aEmbeddedDescriptor.put( "DocumentRecoverySupport", (sal_Bool)sal_False );
1777 
1778     // .........................................................................
1779     // pass the descriptor of the embedded object to the caller
1780     aEmbeddedDescriptor >>= _out_rEmbeddedObjectDescriptor;
1781 
1782     // .........................................................................
1783     // create the ComponentData, and put it into the document's media descriptor
1784     {
1785         ::comphelper::NamedValueCollection aComponentData;
1786         aComponentData.put( "ActiveConnection", _xConnection );
1787         aComponentData.put( "ApplyFormDesignMode", !_bReadOnly );
1788         aMediaDesc.put( "ComponentData", aComponentData.getPropertyValues() );
1789     }
1790 
1791     if ( m_pImpl->m_aProps.aTitle.getLength() )
1792         aMediaDesc.put( "DocumentTitle", m_pImpl->m_aProps.aTitle );
1793 
1794     aMediaDesc.put( "DocumentBaseURL", m_pImpl->m_pDataSource->getURL() );
1795 
1796     // .........................................................................
1797     // put the common load arguments into the document's media descriptor
1798     lcl_putLoadArgs( aMediaDesc, optional_bool( _bSuppressMacros ), optional_bool( _bReadOnly ) );
1799 
1800     return aMediaDesc.getPropertyValues();
1801 }
1802 // -----------------------------------------------------------------------------
1803 void ODocumentDefinition::loadEmbeddedObject( const Reference< XConnection >& i_rConnection, const Sequence< sal_Int8 >& _aClassID,
1804         const Sequence< PropertyValue >& i_rOpenCommandArguments, const bool _bSuppressMacros, const bool _bReadOnly )
1805 {
1806     if ( !m_xEmbeddedObject.is() )
1807     {
1808         Reference< XStorage> xStorage = getContainerStorage();
1809         if ( xStorage.is() )
1810         {
1811             Reference< XEmbedObjectFactory> xEmbedFactory( m_aContext.createComponent( "com.sun.star.embed.OOoEmbeddedObjectFactory" ), UNO_QUERY );
1812             if ( xEmbedFactory.is() )
1813             {
1814                 ::rtl::OUString sDocumentService;
1815                 sal_Bool bSetSize = sal_False;
1816                 sal_Int32 nEntryConnectionMode = EntryInitModes::DEFAULT_INIT;
1817                 Sequence< sal_Int8 > aClassID = _aClassID;
1818                 if ( aClassID.getLength() )
1819                 {
1820                     nEntryConnectionMode = EntryInitModes::TRUNCATE_INIT;
1821                     bSetSize = sal_True;
1822                 }
1823                 else
1824                 {
1825                     sDocumentService = GetDocumentServiceFromMediaType( getContentType(), m_aContext, aClassID );
1826                     // check if we are not a form and
1827                     // the com.sun.star.report.pentaho.SOReportJobFactory is not present.
1828                     if ( !m_bForm && !sDocumentService.equalsAscii("com.sun.star.text.TextDocument"))
1829                     {
1830                         // we seem to be a "new style" report, check if report extension is present.
1831                         Reference< XContentEnumerationAccess > xEnumAccess( m_aContext.getLegacyServiceFactory(), UNO_QUERY );
1832                         const ::rtl::OUString sReportEngineServiceName = ::dbtools::getDefaultReportEngineServiceName(m_aContext.getLegacyServiceFactory());
1833                         Reference< XEnumeration > xEnumDrivers = xEnumAccess->createContentEnumeration(sReportEngineServiceName);
1834                         if ( !xEnumDrivers.is() || !xEnumDrivers->hasMoreElements() )
1835                         {
1836                             com::sun::star::io::WrongFormatException aWFE;
1837                             aWFE.Message = DBACORE_RESSTRING( RID_STR_MISSING_EXTENSION );
1838                             throw aWFE;
1839                         }
1840                     }
1841                     if ( !aClassID.getLength() )
1842                     {
1843                         if ( m_bForm )
1844                             aClassID = MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID);
1845                         else
1846                         {
1847                             aClassID = MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90);
1848                         }
1849                     }
1850                 }
1851 
1852                 OSL_ENSURE( aClassID.getLength(),"No Class ID" );
1853 
1854                 Sequence< PropertyValue > aEmbeddedObjectDescriptor;
1855                 Sequence< PropertyValue > aLoadArgs( fillLoadArgs(
1856                     i_rConnection, _bSuppressMacros, _bReadOnly, i_rOpenCommandArguments, aEmbeddedObjectDescriptor ) );
1857 
1858                 m_xEmbeddedObject.set(xEmbedFactory->createInstanceUserInit(aClassID
1859                                                                             ,sDocumentService
1860                                                                             ,xStorage
1861                                                                             ,m_pImpl->m_aProps.sPersistentName
1862                                                                             ,nEntryConnectionMode
1863                                                                             ,aLoadArgs
1864                                                                             ,aEmbeddedObjectDescriptor
1865                                                                             ),UNO_QUERY);
1866                 if ( m_xEmbeddedObject.is() )
1867                 {
1868                     if ( !m_pClientHelper )
1869                     {
1870                         m_pClientHelper = new OEmbeddedClientHelper(this);
1871                         m_pClientHelper->acquire();
1872                     }
1873                     Reference<XEmbeddedClient> xClient = m_pClientHelper;
1874                     m_xEmbeddedObject->setClientSite(xClient);
1875                     m_xEmbeddedObject->changeState(EmbedStates::RUNNING);
1876                     if ( bSetSize )
1877                     {
1878                         LockModifiable aLockModify( impl_getComponent_throw( false ) );
1879 
1880                         awt::Size aSize( DEFAULT_WIDTH, DEFAULT_HEIGHT );
1881                         m_xEmbeddedObject->setVisualAreaSize(Aspects::MSOLE_CONTENT,aSize);
1882                     }
1883                 }
1884             }
1885         }
1886     }
1887     else
1888     {
1889         sal_Int32 nCurrentState = m_xEmbeddedObject->getCurrentState();
1890         if ( nCurrentState == EmbedStates::LOADED )
1891         {
1892             if ( !m_pClientHelper )
1893             {
1894                 m_pClientHelper = new OEmbeddedClientHelper(this);
1895                 m_pClientHelper->acquire();
1896             }
1897             Reference<XEmbeddedClient> xClient = m_pClientHelper;
1898             m_xEmbeddedObject->setClientSite(xClient);
1899 
1900             Sequence< PropertyValue > aEmbeddedObjectDescriptor;
1901             Sequence< PropertyValue > aLoadArgs( fillLoadArgs(
1902                 i_rConnection, _bSuppressMacros, _bReadOnly, i_rOpenCommandArguments, aEmbeddedObjectDescriptor ) );
1903 
1904             Reference<XCommonEmbedPersist> xCommon(m_xEmbeddedObject,UNO_QUERY);
1905             OSL_ENSURE(xCommon.is(),"unsupported interface!");
1906             if ( xCommon.is() )
1907                 xCommon->reload( aLoadArgs, aEmbeddedObjectDescriptor );
1908             m_xEmbeddedObject->changeState(EmbedStates::RUNNING);
1909         }
1910         else
1911         {
1912             OSL_ENSURE( ( nCurrentState == EmbedStates::RUNNING ) || ( nCurrentState == EmbedStates::ACTIVE ),
1913                 "ODocumentDefinition::loadEmbeddedObject: unexpected state!" );
1914 
1915             // if the document was already loaded (which means the embedded object is in state RUNNING or ACTIVE),
1916             // then just re-set some model parameters
1917             try
1918             {
1919                 // ensure the media descriptor doesn't contain any values which are intended for the
1920                 // EmbeddedObjectDescriptor only
1921                 ::comphelper::NamedValueCollection aEmbeddedObjectDescriptor;
1922                 ::comphelper::NamedValueCollection aNewMediaDesc;
1923                 separateOpenCommandArguments( i_rOpenCommandArguments, aNewMediaDesc, aEmbeddedObjectDescriptor );
1924 
1925                 // merge the new media descriptor into the existing media descriptor
1926                 const Reference< XModel > xModel( getComponent(), UNO_QUERY_THROW );
1927                 const Sequence< PropertyValue > aArgs = xModel->getArgs();
1928                 ::comphelper::NamedValueCollection aExistentMediaDesc( aArgs );
1929                 aExistentMediaDesc.merge( aNewMediaDesc, sal_False );
1930 
1931                 lcl_putLoadArgs( aExistentMediaDesc, optional_bool(), optional_bool() );
1932                     // don't put _bSuppressMacros and _bReadOnly here - if the document was already
1933                     // loaded, we should not tamper with its settings.
1934                     // #i88977# / 2008-05-05 / frank.schoenheit@sun.com
1935                     // #i86872# / 2008-03-13 / frank.schoenheit@sun.com
1936 
1937                 xModel->attachResource( xModel->getURL(), aExistentMediaDesc.getPropertyValues() );
1938             }
1939             catch( const Exception& )
1940             {
1941                 DBG_UNHANDLED_EXCEPTION();
1942             }
1943         }
1944     }
1945 
1946     // set the OfficeDatabaseDocument instance as parent of the embedded document
1947     // #i40358# / 2005-01-19 / frank.schoenheit@sun.com
1948     Reference< XChild > xDepdendDocAsChild( getComponent(), UNO_QUERY );
1949     if ( xDepdendDocAsChild.is() )
1950     {
1951         try
1952         {
1953             if ( !xDepdendDocAsChild->getParent().is() )
1954             {   // first encounter
1955                 xDepdendDocAsChild->setParent( getDataSource( m_xParentContainer ) );
1956             }
1957         }
1958         catch( const Exception& )
1959         {
1960             DBG_UNHANDLED_EXCEPTION();
1961         }
1962     }
1963 
1964     if ( i_rConnection.is() )
1965         m_xLastKnownConnection = i_rConnection;
1966 }
1967 
1968 // -----------------------------------------------------------------------------
1969 void ODocumentDefinition::onCommandPreview(Any& _rImage)
1970 {
1971     loadEmbeddedObjectForPreview();
1972     if ( m_xEmbeddedObject.is() )
1973     {
1974         try
1975         {
1976             Reference<XTransferable> xTransfer(getComponent(),UNO_QUERY);
1977             if ( xTransfer.is() )
1978             {
1979                 DataFlavor aFlavor;
1980                 aFlavor.MimeType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("image/png"));
1981                 aFlavor.HumanPresentableName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Portable Network Graphics"));
1982                 aFlavor.DataType = ::getCppuType(static_cast< const Sequence < sal_Int8 >* >(NULL));
1983 
1984                 _rImage = xTransfer->getTransferData( aFlavor );
1985             }
1986         }
1987         catch( Exception )
1988         {
1989         }
1990     }
1991 }
1992 // -----------------------------------------------------------------------------
1993 void ODocumentDefinition::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, Any& _rDefault ) const
1994 {
1995     _rDefault.clear();
1996 }
1997 // -----------------------------------------------------------------------------
1998 void ODocumentDefinition::onCommandGetDocumentProperties( Any& _rProps )
1999 {
2000     loadEmbeddedObjectForPreview();
2001     if ( m_xEmbeddedObject.is() )
2002     {
2003         try
2004         {
2005             Reference<XDocumentPropertiesSupplier> xDocSup(
2006                 getComponent(), UNO_QUERY );
2007             if ( xDocSup.is() )
2008                 _rProps <<= xDocSup->getDocumentProperties();
2009         }
2010         catch( const Exception& )
2011         {
2012             DBG_UNHANDLED_EXCEPTION();
2013         }
2014     }
2015 }
2016 // -----------------------------------------------------------------------------
2017 Reference< util::XCloseable > ODocumentDefinition::impl_getComponent_throw( const bool i_ForceCreate )
2018 {
2019     OSL_ENSURE(m_xEmbeddedObject.is(),"Illegal call for embeddedObject");
2020     Reference< util::XCloseable > xComp;
2021     if ( m_xEmbeddedObject.is() )
2022     {
2023         int nState = m_xEmbeddedObject->getCurrentState();
2024         if ( ( nState == EmbedStates::LOADED ) && i_ForceCreate )
2025         {
2026             m_xEmbeddedObject->changeState( EmbedStates::RUNNING );
2027             nState = m_xEmbeddedObject->getCurrentState();
2028             OSL_ENSURE( nState == EmbedStates::RUNNING, "ODocumentDefinition::impl_getComponent_throw: could not switch to RUNNING!" );
2029         }
2030 
2031         if ( nState == EmbedStates::ACTIVE || nState == EmbedStates::RUNNING )
2032         {
2033             Reference<XComponentSupplier> xCompProv(m_xEmbeddedObject,UNO_QUERY);
2034             if ( xCompProv.is() )
2035             {
2036                 xComp = xCompProv->getComponent();
2037                 OSL_ENSURE(xComp.is(),"No valid component");
2038             }
2039         }
2040     }
2041     return xComp;
2042 }
2043 
2044 // -----------------------------------------------------------------------------
2045 Reference< util::XCloseable > ODocumentDefinition::getComponent() throw (RuntimeException)
2046 {
2047     ::osl::MutexGuard aGuard( m_aMutex );
2048     return impl_getComponent_throw( true );
2049 }
2050 
2051 // -----------------------------------------------------------------------------
2052 namespace
2053 {
2054     Reference< XDatabaseDocumentUI > lcl_getDatabaseDocumentUI( ODatabaseModelImpl& _rModelImpl )
2055     {
2056         Reference< XDatabaseDocumentUI > xUI;
2057 
2058         Reference< XModel > xModel( _rModelImpl.getModel_noCreate() );
2059         if ( xModel.is() )
2060             xUI.set( xModel->getCurrentController(), UNO_QUERY );
2061         return xUI;
2062     }
2063 }
2064 
2065 // -----------------------------------------------------------------------------
2066 Reference< XComponent > ODocumentDefinition::impl_openUI_nolck_throw( bool _bForEditing )
2067 {
2068     ::osl::ClearableMutexGuard aGuard( m_aMutex );
2069     if ( !m_pImpl || !m_pImpl->m_pDataSource )
2070         throw DisposedException();
2071 
2072     Reference< XDatabaseDocumentUI > xUI( lcl_getDatabaseDocumentUI( *m_pImpl->m_pDataSource ) );
2073     if ( !xUI.is() )
2074     {
2075         // no XDatabaseDocumentUI -> just execute the respective command
2076         m_bOpenInDesign = _bForEditing;
2077         Reference< XComponent > xComponent( onCommandOpenSomething( Any(), true, NULL ), UNO_QUERY );
2078         OSL_ENSURE( xComponent.is(), "ODocumentDefinition::impl_openUI_nolck_throw: opening the thingie failed." );
2079         return xComponent;
2080     }
2081 
2082     Reference< XComponent > xComponent;
2083     try
2084     {
2085         ::rtl::OUString sName( impl_getHierarchicalName( false ) );
2086         sal_Int32 nObjectType = m_bForm ? DatabaseObject::FORM : DatabaseObject::REPORT;
2087         aGuard.clear();
2088 
2089         xComponent = xUI->loadComponent(
2090             nObjectType, sName, _bForEditing
2091         );
2092     }
2093     catch( RuntimeException& ) { throw; }
2094     catch( const Exception& )
2095     {
2096         throw WrappedTargetException(
2097             ::rtl::OUString(), *this, ::cppu::getCaughtException() );
2098     }
2099     return xComponent;
2100 }
2101 
2102 // -----------------------------------------------------------------------------
2103 void ODocumentDefinition::impl_store_throw()
2104 {
2105     Reference<XEmbedPersist> xPersist( m_xEmbeddedObject, UNO_QUERY );
2106     if ( xPersist.is() )
2107     {
2108         xPersist->storeOwn();
2109         notifyDataSourceModified();
2110     }
2111 }
2112 
2113 // -----------------------------------------------------------------------------
2114 bool ODocumentDefinition::impl_close_throw()
2115 {
2116     bool bSuccess = prepareClose();
2117     if ( bSuccess && m_xEmbeddedObject.is() )
2118     {
2119         m_xEmbeddedObject->changeState( EmbedStates::LOADED );
2120         bSuccess = m_xEmbeddedObject->getCurrentState() == EmbedStates::LOADED;
2121     }
2122     return bSuccess;
2123 }
2124 
2125 // -----------------------------------------------------------------------------
2126 Reference< XComponent > SAL_CALL ODocumentDefinition::open(  ) throw (WrappedTargetException, RuntimeException)
2127 {
2128     return impl_openUI_nolck_throw( false );
2129 }
2130 
2131 // -----------------------------------------------------------------------------
2132 Reference< XComponent > SAL_CALL ODocumentDefinition::openDesign(  ) throw (WrappedTargetException, RuntimeException)
2133 {
2134     return impl_openUI_nolck_throw( true );
2135 }
2136 
2137 // -----------------------------------------------------------------------------
2138 void SAL_CALL ODocumentDefinition::store(  ) throw (WrappedTargetException, RuntimeException)
2139 {
2140     ::osl::MutexGuard aGuard( m_aMutex );
2141     try
2142     {
2143         impl_store_throw();
2144     }
2145     catch( RuntimeException& ) { throw; }
2146     catch( const Exception& )
2147     {
2148         throw WrappedTargetException(
2149             ::rtl::OUString(), *this, ::cppu::getCaughtException() );
2150     }
2151 }
2152 
2153 // -----------------------------------------------------------------------------
2154 ::sal_Bool SAL_CALL ODocumentDefinition::close(  ) throw (WrappedTargetException, RuntimeException)
2155 {
2156     ::osl::MutexGuard aGuard( m_aMutex );
2157 
2158     sal_Bool bSuccess = sal_False;
2159     try
2160     {
2161         bSuccess = impl_close_throw();
2162     }
2163     catch( RuntimeException& ) { throw; }
2164     catch( const Exception& )
2165     {
2166         throw WrappedTargetException(
2167             ::rtl::OUString(), *this, ::cppu::getCaughtException() );
2168     }
2169     return bSuccess;
2170 }
2171 
2172 // -----------------------------------------------------------------------------
2173 ::rtl::OUString SAL_CALL ODocumentDefinition::getHierarchicalName() throw (RuntimeException)
2174 {
2175     ::osl::MutexGuard aGuard( m_aMutex );
2176     return impl_getHierarchicalName( false );
2177 }
2178 
2179 // -----------------------------------------------------------------------------
2180 ::rtl::OUString SAL_CALL ODocumentDefinition::composeHierarchicalName( const ::rtl::OUString& i_rRelativeName ) throw (IllegalArgumentException, NoSupportException, RuntimeException)
2181 {
2182     ::rtl::OUStringBuffer aBuffer;
2183     aBuffer.append( getHierarchicalName() );
2184     aBuffer.append( sal_Unicode( '/' ) );
2185     aBuffer.append( i_rRelativeName );
2186     return aBuffer.makeStringAndClear();
2187 }
2188 
2189 // -----------------------------------------------------------------------------
2190 void SAL_CALL ODocumentDefinition::rename( const ::rtl::OUString& _rNewName ) throw (SQLException, ElementExistException, RuntimeException)
2191 {
2192     try
2193     {
2194         ::osl::ResettableMutexGuard aGuard(m_aMutex);
2195         if ( _rNewName.equals( m_pImpl->m_aProps.aTitle ) )
2196             return;
2197 
2198         // document definitions are organized in a hierarchical way, so reject names
2199         // which contain a /, as this is reserved for hierarchy level separation
2200         if ( _rNewName.indexOf( '/' ) != -1 )
2201             m_aErrorHelper.raiseException( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES, *this );
2202 
2203         NameChangeNotifier aNameChangeAndNotify( *this, _rNewName, aGuard );
2204         m_pImpl->m_aProps.aTitle = _rNewName;
2205 
2206         if ( m_xEmbeddedObject.is() && m_xEmbeddedObject->getCurrentState() == EmbedStates::ACTIVE )
2207             updateDocumentTitle();
2208     }
2209     catch(const PropertyVetoException&)
2210     {
2211         throw ElementExistException(_rNewName,*this);
2212     }
2213 }
2214 // -----------------------------------------------------------------------------
2215 Reference< XStorage> ODocumentDefinition::getContainerStorage() const
2216 {
2217     return  m_pImpl->m_pDataSource
2218         ?   m_pImpl->m_pDataSource->getStorage( m_bForm ? ODatabaseModelImpl::E_FORM : ODatabaseModelImpl::E_REPORT )
2219         :   Reference< XStorage>();
2220 }
2221 // -----------------------------------------------------------------------------
2222 sal_Bool ODocumentDefinition::isModified()
2223 {
2224     osl::ClearableGuard< osl::Mutex > aGuard(m_aMutex);
2225     sal_Bool bRet = sal_False;
2226     if ( m_xEmbeddedObject.is() )
2227     {
2228         Reference<XModifiable> xModel(getComponent(),UNO_QUERY);
2229         bRet = xModel.is() && xModel->isModified();
2230     }
2231     return bRet;
2232 }
2233 // -----------------------------------------------------------------------------
2234 bool ODocumentDefinition::prepareClose()
2235 {
2236     if ( !m_xEmbeddedObject.is() )
2237         return true;
2238 
2239     try
2240     {
2241         // suspend the controller. Embedded objects are not allowed to raise
2242         // own UI at their own discretion, instead, this has always to be triggered
2243         // by the embedding component. Thus, we do the suspend call here.
2244         // #i49370# / 2005-06-09 / frank.schoenheit@sun.com
2245 
2246         Reference< util::XCloseable > xComponent( impl_getComponent_throw( false ) );
2247         if ( !xComponent.is() )
2248             return true;
2249 
2250         Reference< XModel > xModel( xComponent, UNO_QUERY );
2251         Reference< XController > xController;
2252         if ( xModel.is() )
2253             xController = xModel->getCurrentController();
2254 
2255         OSL_ENSURE( xController.is() || ( m_xEmbeddedObject->getCurrentState() < EmbedStates::ACTIVE ),
2256             "ODocumentDefinition::prepareClose: no controller!" );
2257         if ( !xController.is() )
2258             // document has not yet been activated, i.e. has no UI, yet
2259             return true;
2260 
2261         sal_Bool bCouldSuspend = xController->suspend( sal_True );
2262         if ( !bCouldSuspend )
2263             // controller vetoed the closing
2264             return false;
2265 
2266         if ( isModified() )
2267         {
2268             Reference< XFrame > xFrame( xController->getFrame() );
2269             if ( xFrame.is() )
2270             {
2271                 Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW );
2272                 xTopWindow->toFront();
2273             }
2274             if ( !save( sal_True ) )
2275             {
2276                 if ( bCouldSuspend )
2277                     // revert suspension
2278                     xController->suspend( sal_False );
2279                 // saving failed or was cancelled
2280                 return false;
2281             }
2282         }
2283     }
2284     catch( const Exception& )
2285     {
2286         DBG_UNHANDLED_EXCEPTION();
2287     }
2288 
2289     return true;
2290 }
2291 // -----------------------------------------------------------------------------
2292 void ODocumentDefinition::fillReportData( const ::comphelper::ComponentContext& _rContext,
2293                                                const Reference< util::XCloseable >& _rxComponent,
2294                                                const Reference< XConnection >& _rxActiveConnection )
2295 {
2296     Sequence< Any > aArgs(2);
2297     PropertyValue aValue;
2298     aValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TextDocument" ) );
2299     aValue.Value <<= _rxComponent;
2300     aArgs[0] <<= aValue;
2301     aValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) );
2302     aValue.Value <<= _rxActiveConnection;
2303     aArgs[1] <<= aValue;
2304 
2305     try
2306     {
2307         Reference< XJobExecutor > xExecuteable(
2308             _rContext.createComponentWithArguments( "com.sun.star.wizards.report.CallReportWizard", aArgs ), UNO_QUERY_THROW );
2309         xExecuteable->trigger( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "fill" ) ) );
2310     }
2311     catch( const Exception& )
2312     {
2313         DBG_UNHANDLED_EXCEPTION();
2314     }
2315 }
2316 // -----------------------------------------------------------------------------
2317 void ODocumentDefinition::updateDocumentTitle()
2318 {
2319     ::rtl::OUString sName = m_pImpl->m_aProps.aTitle;
2320     if ( m_pImpl->m_pDataSource )
2321     {
2322         if ( !sName.getLength() )
2323         {
2324             if ( m_bForm )
2325                 sName = DBACORE_RESSTRING( RID_STR_FORM );
2326             else
2327                 sName = DBACORE_RESSTRING( RID_STR_REPORT );
2328             Reference< XUntitledNumbers > xUntitledProvider(m_pImpl->m_pDataSource->getModel_noCreate(), UNO_QUERY      );
2329             if ( xUntitledProvider.is() )
2330                 sName += ::rtl::OUString::valueOf( xUntitledProvider->leaseNumber(getComponent()) );
2331         }
2332 
2333         Reference< XTitle > xDatabaseDocumentModel(m_pImpl->m_pDataSource->getModel_noCreate(),uno::UNO_QUERY);
2334         if ( xDatabaseDocumentModel.is() )
2335             sName = xDatabaseDocumentModel->getTitle() + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : ")) + sName;
2336     }
2337     Reference< XTitle> xTitle(getComponent(),UNO_QUERY);
2338     if ( xTitle.is() )
2339         xTitle->setTitle(sName);
2340 }
2341 // -----------------------------------------------------------------------------
2342 void SAL_CALL ODocumentDefinition::queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException)
2343 {
2344     (void) Source;
2345     (void) GetsOwnership;
2346     try
2347     {
2348         if ( !close() )
2349             throw util::CloseVetoException();
2350     }
2351     catch(const lang::WrappedTargetException&)
2352     {
2353         throw util::CloseVetoException();
2354     }
2355 }
2356 // -----------------------------------------------------------------------------
2357 void SAL_CALL ODocumentDefinition::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
2358 {
2359 }
2360 // -----------------------------------------------------------------------------
2361 void SAL_CALL ODocumentDefinition::disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
2362 {
2363 }
2364 
2365 // -----------------------------------------------------------------------------
2366 void ODocumentDefinition::firePropertyChange( sal_Int32 i_nHandle, const Any& i_rNewValue, const Any& i_rOldValue,
2367         sal_Bool i_bVetoable, const NotifierAccess )
2368 {
2369     fire( &i_nHandle, &i_rNewValue, &i_rOldValue, 1, i_bVetoable );
2370 }
2371 
2372 // =============================================================================
2373 // NameChangeNotifier
2374 // =============================================================================
2375 // -----------------------------------------------------------------------------
2376 NameChangeNotifier::NameChangeNotifier( ODocumentDefinition& i_rDocumentDefinition, const ::rtl::OUString& i_rNewName,
2377                                   ::osl::ResettableMutexGuard& i_rClearForNotify )
2378     :m_rDocumentDefinition( i_rDocumentDefinition )
2379     ,m_aOldValue( makeAny( i_rDocumentDefinition.getCurrentName() ) )
2380     ,m_aNewValue( makeAny( i_rNewName ) )
2381     ,m_rClearForNotify( i_rClearForNotify )
2382 {
2383     impl_fireEvent_throw( sal_True );
2384 }
2385 
2386 // -----------------------------------------------------------------------------
2387 NameChangeNotifier::~NameChangeNotifier()
2388 {
2389     impl_fireEvent_throw( sal_False );
2390 }
2391 
2392 // -----------------------------------------------------------------------------
2393 void NameChangeNotifier::impl_fireEvent_throw( const sal_Bool i_bVetoable )
2394 {
2395     m_rClearForNotify.clear();
2396     m_rDocumentDefinition.firePropertyChange(
2397         PROPERTY_ID_NAME, m_aNewValue, m_aOldValue, i_bVetoable, ODocumentDefinition::NotifierAccess() );
2398     m_rClearForNotify.reset();
2399 }
2400 
2401 //........................................................................
2402 }   // namespace dbaccess
2403 //........................................................................
2404 
2405