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