xref: /trunk/main/dbaccess/source/core/dataaccess/documentdefinition.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 );
342         virtual void SAL_CALL stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState );
343         virtual void SAL_CALL disposing( const lang::EventObject& Source );
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 )
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 )
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*/ )
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(  )
396         {
397         }
onShowWindow(sal_Bool)398         virtual void SAL_CALL onShowWindow( sal_Bool /*bVisible*/ )
399         {
400         }
401         // XComponentSupplier
getComponent()402         virtual Reference< util::XCloseable > SAL_CALL getComponent(  )
403         {
404             return Reference< css::util::XCloseable >();
405         }
406 
407         // XEmbeddedClient
visibilityChanged(::sal_Bool)408         virtual void SAL_CALL visibilityChanged( ::sal_Bool /*bVisible*/ )
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 );
489     protected:
490     };
491 
492     //------------------------------------------------------------------
disposing(const css::lang::EventObject &)493     void SAL_CALL LifetimeCoupler::disposing( const css::lang::EventObject& /*Source*/ )
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);
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)
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(  )
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 )
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 {
1364     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1365 
1366     // Check, if all required properties were set.
1367     if ( !_sURL.getLength() || m_xEmbeddedObject.is() )
1368     {
1369         OSL_ENSURE( sal_False, "Content::onCommandInsert - property value missing!" );
1370 
1371         Sequence< rtl::OUString > aProps( 1 );
1372         aProps[ 0 ] = PROPERTY_URL;
1373         ucbhelper::cancelCommandExecution(
1374             makeAny( MissingPropertiesException(
1375                                 rtl::OUString(),
1376                                 static_cast< cppu::OWeakObject * >( this ),
1377                                 aProps ) ),
1378             Environment );
1379         // Unreachable
1380     }
1381 
1382 
1383     if ( !m_xEmbeddedObject.is() )
1384     {
1385         Reference< XStorage> xStorage = getContainerStorage();
1386         if ( xStorage.is() )
1387         {
1388             Reference< XEmbedObjectCreator> xEmbedFactory( m_aContext.createComponent( "com.sun.star.embed.EmbeddedObjectCreator" ), UNO_QUERY );
1389             if ( xEmbedFactory.is() )
1390             {
1391                 Sequence<PropertyValue> aEmpty,aMediaDesc(1);
1392                 aMediaDesc[0].Name = PROPERTY_URL;
1393                 aMediaDesc[0].Value <<= _sURL;
1394                 m_xEmbeddedObject.set(xEmbedFactory->createInstanceInitFromMediaDescriptor( xStorage
1395                                                                                 ,m_pImpl->m_aProps.sPersistentName
1396                                                                                 ,aMediaDesc
1397                                                                                 ,aEmpty),UNO_QUERY);
1398 
1399                 lcl_resetFormsToEmptyDataSource( m_xEmbeddedObject );
1400                 // #i57669# / 2005-12-01 / frank.schoenheit@sun.com
1401 
1402                 Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY);
1403                 if ( xPersist.is() )
1404                 {
1405                     xPersist->storeOwn();
1406                 }
1407                 try
1408                 {
1409                     Reference< com::sun::star::util::XCloseable> xCloseable(m_xEmbeddedObject,UNO_QUERY);
1410                     if ( xCloseable.is() )
1411                         xCloseable->close(sal_True);
1412                 }
1413                 catch(Exception)
1414                 {
1415                 }
1416                 m_xEmbeddedObject = NULL;
1417             }
1418         }
1419     }
1420 
1421 //  @@@
1422 //  storeData();
1423 
1424     aGuard.clear();
1425 //  inserted();
1426 }
1427 // -----------------------------------------------------------------------------
save(sal_Bool _bApprove)1428 sal_Bool ODocumentDefinition::save(sal_Bool _bApprove)
1429 {
1430     // default handling: instantiate an interaction handler and let it handle the parameter request
1431     if ( !m_bOpenInDesign )
1432         return sal_False;
1433     try
1434     {
1435 
1436         {
1437             ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
1438 
1439             // the request
1440             Reference<XNameAccess> xName(m_xParentContainer,UNO_QUERY);
1441             DocumentSaveRequest aRequest;
1442             aRequest.Name = m_pImpl->m_aProps.aTitle;
1443             if ( !aRequest.Name.getLength() )
1444             {
1445                 if ( m_bForm )
1446                     aRequest.Name = DBACORE_RESSTRING( RID_STR_FORM );
1447                 else
1448                     aRequest.Name = DBACORE_RESSTRING( RID_STR_REPORT );
1449                 aRequest.Name = ::dbtools::createUniqueName(xName,aRequest.Name);
1450             }
1451 
1452             aRequest.Content.set(m_xParentContainer,UNO_QUERY);
1453             OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
1454             Reference< XInteractionRequest > xRequest(pRequest);
1455             // some knittings
1456             // two continuations allowed: OK and Cancel
1457             ODocumentSaveContinuation* pDocuSave = NULL;
1458 
1459             if ( !m_pImpl->m_aProps.aTitle.getLength() )
1460             {
1461                 pDocuSave = new ODocumentSaveContinuation;
1462                 pRequest->addContinuation(pDocuSave);
1463             }
1464             OInteraction< XInteractionApprove >* pApprove = NULL;
1465             if ( _bApprove )
1466             {
1467                 pApprove = new OInteraction< XInteractionApprove >;
1468                 pRequest->addContinuation(pApprove);
1469             }
1470 
1471             OInteraction< XInteractionDisapprove >* pDisApprove = new OInteraction< XInteractionDisapprove >;
1472             pRequest->addContinuation(pDisApprove);
1473 
1474             OInteractionAbort* pAbort = new OInteractionAbort;
1475             pRequest->addContinuation(pAbort);
1476 
1477             // create the handler, let it handle the request
1478             Reference< XInteractionHandler > xHandler( m_aContext.createComponent( (::rtl::OUString)SERVICE_TASK_INTERACTION_HANDLER ), UNO_QUERY );
1479             if ( xHandler.is() )
1480                 xHandler->handle(xRequest);
1481 
1482             if ( pAbort->wasSelected() )
1483                 return sal_False;
1484             if  ( pDisApprove->wasSelected() )
1485                 return sal_True;
1486             if ( pDocuSave && pDocuSave->wasSelected() )
1487             {
1488                 Reference<XNameContainer> xNC( pDocuSave->getContent(), UNO_QUERY_THROW );
1489 
1490                 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1491                 NameChangeNotifier aNameChangeAndNotify( *this, pDocuSave->getName(), aGuard );
1492                 m_pImpl->m_aProps.aTitle = pDocuSave->getName();
1493 
1494                 Reference< XContent> xContent = this;
1495                 xNC->insertByName(pDocuSave->getName(),makeAny(xContent));
1496 
1497                 updateDocumentTitle();
1498             }
1499         }
1500 
1501         ::osl::MutexGuard aGuard(m_aMutex);
1502         Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY);
1503         if ( xPersist.is() )
1504         {
1505             xPersist->storeOwn();
1506             notifyDataSourceModified();
1507         }
1508     }
1509     catch(Exception&)
1510     {
1511         OSL_ENSURE(0,"ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1512     }
1513     return sal_True;
1514 }
1515 // -----------------------------------------------------------------------------
saveAs()1516 sal_Bool ODocumentDefinition::saveAs()
1517 {
1518     // default handling: instantiate an interaction handler and let it handle the parameter request
1519     if ( !m_bOpenInDesign )
1520         return sal_False;
1521 
1522     {
1523         osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1524         if ( !m_pImpl->m_aProps.aTitle.getLength() )
1525         {
1526             aGuard.clear();
1527             return save(sal_False); // (sal_False) : we don't want an approve dialog
1528         }
1529     }
1530     try
1531     {
1532         {
1533             ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
1534 
1535             // the request
1536             Reference<XNameAccess> xName(m_xParentContainer,UNO_QUERY);
1537             DocumentSaveRequest aRequest;
1538             aRequest.Name = m_pImpl->m_aProps.aTitle;
1539 
1540             aRequest.Content.set(m_xParentContainer,UNO_QUERY);
1541             OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
1542             Reference< XInteractionRequest > xRequest(pRequest);
1543             // some knittings
1544             // two continuations allowed: OK and Cancel
1545             ODocumentSaveContinuation* pDocuSave = new ODocumentSaveContinuation;
1546             pRequest->addContinuation(pDocuSave);
1547             OInteraction< XInteractionDisapprove >* pDisApprove = new OInteraction< XInteractionDisapprove >;
1548             pRequest->addContinuation(pDisApprove);
1549             OInteractionAbort* pAbort = new OInteractionAbort;
1550             pRequest->addContinuation(pAbort);
1551 
1552             // create the handler, let it handle the request
1553             Reference< XInteractionHandler > xHandler(m_aContext.createComponent(::rtl::OUString(SERVICE_TASK_INTERACTION_HANDLER)), UNO_QUERY);
1554             if ( xHandler.is() )
1555                 xHandler->handle(xRequest);
1556 
1557             if ( pAbort->wasSelected() )
1558                 return sal_False;
1559             if  ( pDisApprove->wasSelected() )
1560                 return sal_True;
1561             if ( pDocuSave->wasSelected() )
1562             {
1563                 ::osl::MutexGuard aGuard(m_aMutex);
1564                 Reference<XNameContainer> xNC(pDocuSave->getContent(),UNO_QUERY);
1565                 if ( xNC.is() )
1566                 {
1567                     if ( m_pImpl->m_aProps.aTitle != pDocuSave->getName() )
1568                     {
1569                         try
1570                         {
1571                             Reference< XStorage> xStorage = getContainerStorage();
1572                             const static ::rtl::OUString sBaseName(RTL_CONSTASCII_USTRINGPARAM("Obj"));
1573                             // -----------------------------------------------------------------------------
1574                             Reference<XNameAccess> xElements(xStorage,UNO_QUERY_THROW);
1575                             ::rtl::OUString sPersistentName = ::dbtools::createUniqueName(xElements,sBaseName);
1576                             xStorage->copyElementTo(m_pImpl->m_aProps.sPersistentName,xStorage,sPersistentName);
1577 
1578                             ::rtl::OUString sOldName = m_pImpl->m_aProps.aTitle;
1579                             rename(pDocuSave->getName());
1580                             updateDocumentTitle();
1581 
1582                             Sequence< Any > aArguments(3);
1583                             PropertyValue aValue;
1584                             // set as folder
1585                             aValue.Name = PROPERTY_NAME;
1586                             aValue.Value <<= sOldName;
1587                             aArguments[0] <<= aValue;
1588 
1589                             aValue.Name = PROPERTY_PERSISTENT_NAME;
1590                             aValue.Value <<= sPersistentName;
1591                             aArguments[1] <<= aValue;
1592 
1593                             aValue.Name = PROPERTY_AS_TEMPLATE;
1594                             aValue.Value <<= m_pImpl->m_aProps.bAsTemplate;
1595                             aArguments[2] <<= aValue;
1596 
1597                             Reference< XMultiServiceFactory > xORB( m_xParentContainer, UNO_QUERY_THROW );
1598                             Reference< XInterface > xComponent( xORB->createInstanceWithArguments( SERVICE_SDB_DOCUMENTDEFINITION, aArguments ) );
1599                             Reference< XNameContainer > xNameContainer( m_xParentContainer, UNO_QUERY_THROW );
1600                             xNameContainer->insertByName( sOldName, makeAny( xComponent ) );
1601                         }
1602                         catch(Exception&)
1603                         {
1604                             DBG_UNHANDLED_EXCEPTION();
1605                         }
1606                     }
1607                     Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY);
1608                     if ( xPersist.is() )
1609                     {
1610                         xPersist->storeOwn();
1611                         notifyDataSourceModified();
1612                     }
1613                 }
1614             }
1615         }
1616 
1617 
1618     }
1619     catch(Exception&)
1620     {
1621         OSL_ENSURE(0,"ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1622     }
1623     return sal_True;
1624 }
1625 
1626 namespace
1627 {
1628     // .........................................................................
lcl_putLoadArgs(::comphelper::NamedValueCollection & _io_rArgs,const optional_bool _bSuppressMacros,const optional_bool _bReadOnly)1629     void    lcl_putLoadArgs( ::comphelper::NamedValueCollection& _io_rArgs, const optional_bool _bSuppressMacros, const optional_bool _bReadOnly )
1630     {
1631         if ( !!_bSuppressMacros )
1632         {
1633             if ( *_bSuppressMacros )
1634             {
1635                 // if we're to suppress macros, do exactly this
1636                 _io_rArgs.put( "MacroExecutionMode", MacroExecMode::NEVER_EXECUTE );
1637             }
1638             else
1639             {
1640                 // otherwise, put the setting only if not already present
1641                 if ( !_io_rArgs.has( "MacroExecutionMode" ) )
1642                 {
1643                     _io_rArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
1644                 }
1645             }
1646         }
1647 
1648         if ( !!_bReadOnly )
1649             _io_rArgs.put( "ReadOnly", *_bReadOnly );
1650     }
1651 }
1652 
1653 // -----------------------------------------------------------------------------
1654 namespace
1655 {
lcl_getDatabaseDocumentFrame(ODatabaseModelImpl & _rImpl)1656     Reference< XFrame > lcl_getDatabaseDocumentFrame( ODatabaseModelImpl& _rImpl )
1657     {
1658         Reference< XModel > xDatabaseDocumentModel( _rImpl.getModel_noCreate() );
1659 
1660         Reference< XController > xDatabaseDocumentController;
1661         if ( xDatabaseDocumentModel.is() )
1662             xDatabaseDocumentController = xDatabaseDocumentModel->getCurrentController();
1663 
1664         Reference< XFrame > xFrame;
1665         if ( xDatabaseDocumentController.is() )
1666             xFrame = xDatabaseDocumentController->getFrame();
1667 
1668         return xFrame;
1669     }
1670 }
1671 
1672 // -----------------------------------------------------------------------------
objectSupportsEmbeddedScripts() const1673 sal_Bool ODocumentDefinition::objectSupportsEmbeddedScripts() const
1674 {
1675     bool bAllowDocumentMacros = !m_pImpl->m_pDataSource
1676                             ||  ( m_pImpl->m_pDataSource->determineEmbeddedMacros() == ODatabaseModelImpl::eSubDocumentMacros );
1677 
1678     // if *any* of the objects of the database document already has macros, we continue to allow it
1679     // to have them, until the user did a migration.
1680     // If there are no macros, yet, we don't allow to create them
1681 
1682     return bAllowDocumentMacros;
1683 }
1684 
1685 // -----------------------------------------------------------------------------
determineContentType() const1686 ::rtl::OUString ODocumentDefinition::determineContentType() const
1687 {
1688     return lcl_determineContentType_nothrow( getContainerStorage(), m_pImpl->m_aProps.sPersistentName );
1689 }
1690 
1691 // -----------------------------------------------------------------------------
separateOpenCommandArguments(const Sequence<PropertyValue> & i_rOpenCommandArguments,::comphelper::NamedValueCollection & o_rDocumentLoadArgs,::comphelper::NamedValueCollection & o_rEmbeddedObjectDescriptor)1692 void ODocumentDefinition::separateOpenCommandArguments( const Sequence< PropertyValue >& i_rOpenCommandArguments,
1693         ::comphelper::NamedValueCollection& o_rDocumentLoadArgs, ::comphelper::NamedValueCollection& o_rEmbeddedObjectDescriptor )
1694 {
1695     ::comphelper::NamedValueCollection aOpenCommandArguments( i_rOpenCommandArguments );
1696 
1697     const sal_Char* pObjectDescriptorArgs[] =
1698     {
1699         "RecoveryStorage"
1700     };
1701     for ( size_t i=0; i < sizeof( pObjectDescriptorArgs ) / sizeof( pObjectDescriptorArgs[0] ); ++i )
1702     {
1703         if ( aOpenCommandArguments.has( pObjectDescriptorArgs[i] ) )
1704         {
1705             o_rEmbeddedObjectDescriptor.put( pObjectDescriptorArgs[i], aOpenCommandArguments.get( pObjectDescriptorArgs[i] ) );
1706             aOpenCommandArguments.remove( pObjectDescriptorArgs[i] );
1707         }
1708     }
1709 
1710     o_rDocumentLoadArgs.merge( aOpenCommandArguments, false );
1711 }
1712 
1713 // -----------------------------------------------------------------------------
fillLoadArgs(const Reference<XConnection> & _xConnection,const bool _bSuppressMacros,const bool _bReadOnly,const Sequence<PropertyValue> & i_rOpenCommandArguments,Sequence<PropertyValue> & _out_rEmbeddedObjectDescriptor)1714 Sequence< PropertyValue > ODocumentDefinition::fillLoadArgs( const Reference< XConnection>& _xConnection, const bool _bSuppressMacros, const bool _bReadOnly,
1715         const Sequence< PropertyValue >& i_rOpenCommandArguments, Sequence< PropertyValue >& _out_rEmbeddedObjectDescriptor )
1716 {
1717     // .........................................................................
1718     // (re-)create interceptor, and put it into the descriptor of the embedded object
1719     if ( m_pInterceptor )
1720     {
1721         m_pInterceptor->dispose();
1722         m_pInterceptor->release();
1723         m_pInterceptor = NULL;
1724     }
1725 
1726     m_pInterceptor = new OInterceptor( this ,_bReadOnly);
1727     m_pInterceptor->acquire();
1728     Reference<XDispatchProviderInterceptor> xInterceptor = m_pInterceptor;
1729 
1730     ::comphelper::NamedValueCollection aEmbeddedDescriptor;
1731     aEmbeddedDescriptor.put( "OutplaceDispatchInterceptor", xInterceptor );
1732 
1733     // .........................................................................
1734     ::comphelper::NamedValueCollection aMediaDesc;
1735     separateOpenCommandArguments( i_rOpenCommandArguments, aMediaDesc, aEmbeddedDescriptor );
1736 
1737     // .........................................................................
1738     // create the OutplaceFrameProperties, and put them into the descriptor of the embedded object
1739     ::comphelper::NamedValueCollection OutplaceFrameProperties;
1740     OutplaceFrameProperties.put( "TopWindow", (sal_Bool)sal_True );
1741 
1742     Reference< XFrame > xParentFrame;
1743     if ( m_pImpl->m_pDataSource )
1744         xParentFrame = lcl_getDatabaseDocumentFrame( *m_pImpl->m_pDataSource );
1745     if ( !xParentFrame.is() )
1746     { // i87957 we need a parent frame
1747         Reference< XComponentLoader > xDesktop( m_aContext.createComponent( (::rtl::OUString)SERVICE_FRAME_DESKTOP ), UNO_QUERY_THROW );
1748         xParentFrame.set( xDesktop, UNO_QUERY );
1749         if ( xParentFrame.is() )
1750         {
1751             Reference<util::XCloseable> xCloseable(m_pImpl->m_pDataSource->getModel_noCreate(),UNO_QUERY);
1752             if ( xCloseable.is() )
1753             {
1754                 xCloseable->addCloseListener(this);
1755                 m_bRemoveListener = sal_True;
1756             }
1757         }
1758     }
1759     OSL_ENSURE( xParentFrame.is(), "ODocumentDefinition::fillLoadArgs: no parent frame!" );
1760     if  ( xParentFrame.is() )
1761         OutplaceFrameProperties.put( "ParentFrame", xParentFrame );
1762 
1763     aEmbeddedDescriptor.put( "OutplaceFrameProperties", OutplaceFrameProperties.getNamedValues() );
1764 
1765     // .........................................................................
1766     // tell the embedded object to have (or not have) script support
1767     aEmbeddedDescriptor.put( "EmbeddedScriptSupport", (sal_Bool)objectSupportsEmbeddedScripts() );
1768 
1769     // .........................................................................
1770     // tell the embedded object to not participate in the document recovery game - the DB doc will handle it
1771     aEmbeddedDescriptor.put( "DocumentRecoverySupport", (sal_Bool)sal_False );
1772 
1773     // .........................................................................
1774     // pass the descriptor of the embedded object to the caller
1775     aEmbeddedDescriptor >>= _out_rEmbeddedObjectDescriptor;
1776 
1777     // .........................................................................
1778     // create the ComponentData, and put it into the document's media descriptor
1779     {
1780         ::comphelper::NamedValueCollection aComponentData;
1781         aComponentData.put( "ActiveConnection", _xConnection );
1782         aComponentData.put( "ApplyFormDesignMode", !_bReadOnly );
1783         aMediaDesc.put( "ComponentData", aComponentData.getPropertyValues() );
1784     }
1785 
1786     if ( m_pImpl->m_aProps.aTitle.getLength() )
1787         aMediaDesc.put( "DocumentTitle", m_pImpl->m_aProps.aTitle );
1788 
1789     aMediaDesc.put( "DocumentBaseURL", m_pImpl->m_pDataSource->getURL() );
1790 
1791     // .........................................................................
1792     // put the common load arguments into the document's media descriptor
1793     lcl_putLoadArgs( aMediaDesc, optional_bool( _bSuppressMacros ), optional_bool( _bReadOnly ) );
1794 
1795     return aMediaDesc.getPropertyValues();
1796 }
1797 // -----------------------------------------------------------------------------
loadEmbeddedObject(const Reference<XConnection> & i_rConnection,const Sequence<sal_Int8> & _aClassID,const Sequence<PropertyValue> & i_rOpenCommandArguments,const bool _bSuppressMacros,const bool _bReadOnly)1798 void ODocumentDefinition::loadEmbeddedObject( const Reference< XConnection >& i_rConnection, const Sequence< sal_Int8 >& _aClassID,
1799         const Sequence< PropertyValue >& i_rOpenCommandArguments, const bool _bSuppressMacros, const bool _bReadOnly )
1800 {
1801     if ( !m_xEmbeddedObject.is() )
1802     {
1803         Reference< XStorage> xStorage = getContainerStorage();
1804         if ( xStorage.is() )
1805         {
1806             Reference< XEmbedObjectFactory> xEmbedFactory( m_aContext.createComponent( "com.sun.star.embed.OOoEmbeddedObjectFactory" ), UNO_QUERY );
1807             if ( xEmbedFactory.is() )
1808             {
1809                 ::rtl::OUString sDocumentService;
1810                 sal_Bool bSetSize = sal_False;
1811                 sal_Int32 nEntryConnectionMode = EntryInitModes::DEFAULT_INIT;
1812                 Sequence< sal_Int8 > aClassID = _aClassID;
1813                 if ( aClassID.getLength() )
1814                 {
1815                     nEntryConnectionMode = EntryInitModes::TRUNCATE_INIT;
1816                     bSetSize = sal_True;
1817                 }
1818                 else
1819                 {
1820                     sDocumentService = GetDocumentServiceFromMediaType( getContentType(), m_aContext, aClassID );
1821                     // check if we are not a form and
1822                     // the com.sun.star.report.pentaho.SOReportJobFactory is not present.
1823                     if ( !m_bForm && !sDocumentService.equalsAscii("com.sun.star.text.TextDocument"))
1824                     {
1825                         // we seem to be a "new style" report, check if report extension is present.
1826                         Reference< XContentEnumerationAccess > xEnumAccess( m_aContext.getLegacyServiceFactory(), UNO_QUERY );
1827                         const ::rtl::OUString sReportEngineServiceName = ::dbtools::getDefaultReportEngineServiceName(m_aContext.getLegacyServiceFactory());
1828                         Reference< XEnumeration > xEnumDrivers = xEnumAccess->createContentEnumeration(sReportEngineServiceName);
1829                         if ( !xEnumDrivers.is() || !xEnumDrivers->hasMoreElements() )
1830                         {
1831                             com::sun::star::io::WrongFormatException aWFE;
1832                             aWFE.Message = DBACORE_RESSTRING( RID_STR_MISSING_EXTENSION );
1833                             throw aWFE;
1834                         }
1835                     }
1836                     if ( !aClassID.getLength() )
1837                     {
1838                         if ( m_bForm )
1839                             aClassID = MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID);
1840                         else
1841                         {
1842                             aClassID = MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90);
1843                         }
1844                     }
1845                 }
1846 
1847                 OSL_ENSURE( aClassID.getLength(),"No Class ID" );
1848 
1849                 Sequence< PropertyValue > aEmbeddedObjectDescriptor;
1850                 Sequence< PropertyValue > aLoadArgs( fillLoadArgs(
1851                     i_rConnection, _bSuppressMacros, _bReadOnly, i_rOpenCommandArguments, aEmbeddedObjectDescriptor ) );
1852 
1853                 m_xEmbeddedObject.set(xEmbedFactory->createInstanceUserInit(aClassID
1854                                                                             ,sDocumentService
1855                                                                             ,xStorage
1856                                                                             ,m_pImpl->m_aProps.sPersistentName
1857                                                                             ,nEntryConnectionMode
1858                                                                             ,aLoadArgs
1859                                                                             ,aEmbeddedObjectDescriptor
1860                                                                             ),UNO_QUERY);
1861                 if ( m_xEmbeddedObject.is() )
1862                 {
1863                     if ( !m_pClientHelper )
1864                     {
1865                         m_pClientHelper = new OEmbeddedClientHelper(this);
1866                         m_pClientHelper->acquire();
1867                     }
1868                     Reference<XEmbeddedClient> xClient = m_pClientHelper;
1869                     m_xEmbeddedObject->setClientSite(xClient);
1870                     m_xEmbeddedObject->changeState(EmbedStates::RUNNING);
1871                     if ( bSetSize )
1872                     {
1873                         LockModifiable aLockModify( impl_getComponent_throw( false ) );
1874 
1875                         awt::Size aSize( DEFAULT_WIDTH, DEFAULT_HEIGHT );
1876                         m_xEmbeddedObject->setVisualAreaSize(Aspects::MSOLE_CONTENT,aSize);
1877                     }
1878                 }
1879             }
1880         }
1881     }
1882     else
1883     {
1884         sal_Int32 nCurrentState = m_xEmbeddedObject->getCurrentState();
1885         if ( nCurrentState == EmbedStates::LOADED )
1886         {
1887             if ( !m_pClientHelper )
1888             {
1889                 m_pClientHelper = new OEmbeddedClientHelper(this);
1890                 m_pClientHelper->acquire();
1891             }
1892             Reference<XEmbeddedClient> xClient = m_pClientHelper;
1893             m_xEmbeddedObject->setClientSite(xClient);
1894 
1895             Sequence< PropertyValue > aEmbeddedObjectDescriptor;
1896             Sequence< PropertyValue > aLoadArgs( fillLoadArgs(
1897                 i_rConnection, _bSuppressMacros, _bReadOnly, i_rOpenCommandArguments, aEmbeddedObjectDescriptor ) );
1898 
1899             Reference<XCommonEmbedPersist> xCommon(m_xEmbeddedObject,UNO_QUERY);
1900             OSL_ENSURE(xCommon.is(),"unsupported interface!");
1901             if ( xCommon.is() )
1902                 xCommon->reload( aLoadArgs, aEmbeddedObjectDescriptor );
1903             m_xEmbeddedObject->changeState(EmbedStates::RUNNING);
1904         }
1905         else
1906         {
1907             OSL_ENSURE( ( nCurrentState == EmbedStates::RUNNING ) || ( nCurrentState == EmbedStates::ACTIVE ),
1908                 "ODocumentDefinition::loadEmbeddedObject: unexpected state!" );
1909 
1910             // if the document was already loaded (which means the embedded object is in state RUNNING or ACTIVE),
1911             // then just re-set some model parameters
1912             try
1913             {
1914                 // ensure the media descriptor doesn't contain any values which are intended for the
1915                 // EmbeddedObjectDescriptor only
1916                 ::comphelper::NamedValueCollection aEmbeddedObjectDescriptor;
1917                 ::comphelper::NamedValueCollection aNewMediaDesc;
1918                 separateOpenCommandArguments( i_rOpenCommandArguments, aNewMediaDesc, aEmbeddedObjectDescriptor );
1919 
1920                 // merge the new media descriptor into the existing media descriptor
1921                 const Reference< XModel > xModel( getComponent(), UNO_QUERY_THROW );
1922                 const Sequence< PropertyValue > aArgs = xModel->getArgs();
1923                 ::comphelper::NamedValueCollection aExistentMediaDesc( aArgs );
1924                 aExistentMediaDesc.merge( aNewMediaDesc, sal_False );
1925 
1926                 lcl_putLoadArgs( aExistentMediaDesc, optional_bool(), optional_bool() );
1927                     // don't put _bSuppressMacros and _bReadOnly here - if the document was already
1928                     // loaded, we should not tamper with its settings.
1929                     // #i88977# / 2008-05-05 / frank.schoenheit@sun.com
1930                     // #i86872# / 2008-03-13 / frank.schoenheit@sun.com
1931 
1932                 xModel->attachResource( xModel->getURL(), aExistentMediaDesc.getPropertyValues() );
1933             }
1934             catch( const Exception& )
1935             {
1936                 DBG_UNHANDLED_EXCEPTION();
1937             }
1938         }
1939     }
1940 
1941     // set the OfficeDatabaseDocument instance as parent of the embedded document
1942     // #i40358# / 2005-01-19 / frank.schoenheit@sun.com
1943     Reference< XChild > xDepdendDocAsChild( getComponent(), UNO_QUERY );
1944     if ( xDepdendDocAsChild.is() )
1945     {
1946         try
1947         {
1948             if ( !xDepdendDocAsChild->getParent().is() )
1949             {   // first encounter
1950                 xDepdendDocAsChild->setParent( getDataSource( m_xParentContainer ) );
1951             }
1952         }
1953         catch( const Exception& )
1954         {
1955             DBG_UNHANDLED_EXCEPTION();
1956         }
1957     }
1958 
1959     if ( i_rConnection.is() )
1960         m_xLastKnownConnection = i_rConnection;
1961 }
1962 
1963 // -----------------------------------------------------------------------------
onCommandPreview(Any & _rImage)1964 void ODocumentDefinition::onCommandPreview(Any& _rImage)
1965 {
1966     loadEmbeddedObjectForPreview();
1967     if ( m_xEmbeddedObject.is() )
1968     {
1969         try
1970         {
1971             Reference<XTransferable> xTransfer(getComponent(),UNO_QUERY);
1972             if ( xTransfer.is() )
1973             {
1974                 DataFlavor aFlavor;
1975                 aFlavor.MimeType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("image/png"));
1976                 aFlavor.HumanPresentableName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Portable Network Graphics"));
1977                 aFlavor.DataType = ::getCppuType(static_cast< const Sequence < sal_Int8 >* >(NULL));
1978 
1979                 _rImage = xTransfer->getTransferData( aFlavor );
1980             }
1981         }
1982         catch( Exception )
1983         {
1984         }
1985     }
1986 }
1987 // -----------------------------------------------------------------------------
getPropertyDefaultByHandle(sal_Int32,Any & _rDefault) const1988 void ODocumentDefinition::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, Any& _rDefault ) const
1989 {
1990     _rDefault.clear();
1991 }
1992 // -----------------------------------------------------------------------------
onCommandGetDocumentProperties(Any & _rProps)1993 void ODocumentDefinition::onCommandGetDocumentProperties( Any& _rProps )
1994 {
1995     loadEmbeddedObjectForPreview();
1996     if ( m_xEmbeddedObject.is() )
1997     {
1998         try
1999         {
2000             Reference<XDocumentPropertiesSupplier> xDocSup(
2001                 getComponent(), UNO_QUERY );
2002             if ( xDocSup.is() )
2003                 _rProps <<= xDocSup->getDocumentProperties();
2004         }
2005         catch( const Exception& )
2006         {
2007             DBG_UNHANDLED_EXCEPTION();
2008         }
2009     }
2010 }
2011 // -----------------------------------------------------------------------------
impl_getComponent_throw(const bool i_ForceCreate)2012 Reference< util::XCloseable > ODocumentDefinition::impl_getComponent_throw( const bool i_ForceCreate )
2013 {
2014     OSL_ENSURE(m_xEmbeddedObject.is(),"Illegal call for embeddedObject");
2015     Reference< util::XCloseable > xComp;
2016     if ( m_xEmbeddedObject.is() )
2017     {
2018         int nState = m_xEmbeddedObject->getCurrentState();
2019         if ( ( nState == EmbedStates::LOADED ) && i_ForceCreate )
2020         {
2021             m_xEmbeddedObject->changeState( EmbedStates::RUNNING );
2022             nState = m_xEmbeddedObject->getCurrentState();
2023             OSL_ENSURE( nState == EmbedStates::RUNNING, "ODocumentDefinition::impl_getComponent_throw: could not switch to RUNNING!" );
2024         }
2025 
2026         if ( nState == EmbedStates::ACTIVE || nState == EmbedStates::RUNNING )
2027         {
2028             Reference<XComponentSupplier> xCompProv(m_xEmbeddedObject,UNO_QUERY);
2029             if ( xCompProv.is() )
2030             {
2031                 xComp = xCompProv->getComponent();
2032                 OSL_ENSURE(xComp.is(),"No valid component");
2033             }
2034         }
2035     }
2036     return xComp;
2037 }
2038 
2039 // -----------------------------------------------------------------------------
getComponent()2040 Reference< util::XCloseable > ODocumentDefinition::getComponent()
2041 {
2042     ::osl::MutexGuard aGuard( m_aMutex );
2043     return impl_getComponent_throw( true );
2044 }
2045 
2046 // -----------------------------------------------------------------------------
2047 namespace
2048 {
lcl_getDatabaseDocumentUI(ODatabaseModelImpl & _rModelImpl)2049     Reference< XDatabaseDocumentUI > lcl_getDatabaseDocumentUI( ODatabaseModelImpl& _rModelImpl )
2050     {
2051         Reference< XDatabaseDocumentUI > xUI;
2052 
2053         Reference< XModel > xModel( _rModelImpl.getModel_noCreate() );
2054         if ( xModel.is() )
2055             xUI.set( xModel->getCurrentController(), UNO_QUERY );
2056         return xUI;
2057     }
2058 }
2059 
2060 // -----------------------------------------------------------------------------
impl_openUI_nolck_throw(bool _bForEditing)2061 Reference< XComponent > ODocumentDefinition::impl_openUI_nolck_throw( bool _bForEditing )
2062 {
2063     ::osl::ClearableMutexGuard aGuard( m_aMutex );
2064     if ( !m_pImpl || !m_pImpl->m_pDataSource )
2065         throw DisposedException();
2066 
2067     Reference< XDatabaseDocumentUI > xUI( lcl_getDatabaseDocumentUI( *m_pImpl->m_pDataSource ) );
2068     if ( !xUI.is() )
2069     {
2070         // no XDatabaseDocumentUI -> just execute the respective command
2071         m_bOpenInDesign = _bForEditing;
2072         Reference< XComponent > xComponent( onCommandOpenSomething( Any(), true, NULL ), UNO_QUERY );
2073         OSL_ENSURE( xComponent.is(), "ODocumentDefinition::impl_openUI_nolck_throw: opening the thingie failed." );
2074         return xComponent;
2075     }
2076 
2077     Reference< XComponent > xComponent;
2078     try
2079     {
2080         ::rtl::OUString sName( impl_getHierarchicalName( false ) );
2081         sal_Int32 nObjectType = m_bForm ? DatabaseObject::FORM : DatabaseObject::REPORT;
2082         aGuard.clear();
2083 
2084         xComponent = xUI->loadComponent(
2085             nObjectType, sName, _bForEditing
2086         );
2087     }
2088     catch( RuntimeException& ) { throw; }
2089     catch( const Exception& )
2090     {
2091         throw WrappedTargetException(
2092             ::rtl::OUString(), *this, ::cppu::getCaughtException() );
2093     }
2094     return xComponent;
2095 }
2096 
2097 // -----------------------------------------------------------------------------
impl_store_throw()2098 void ODocumentDefinition::impl_store_throw()
2099 {
2100     Reference<XEmbedPersist> xPersist( m_xEmbeddedObject, UNO_QUERY );
2101     if ( xPersist.is() )
2102     {
2103         xPersist->storeOwn();
2104         notifyDataSourceModified();
2105     }
2106 }
2107 
2108 // -----------------------------------------------------------------------------
impl_close_throw()2109 bool ODocumentDefinition::impl_close_throw()
2110 {
2111     bool bSuccess = prepareClose();
2112     if ( bSuccess && m_xEmbeddedObject.is() )
2113     {
2114         m_xEmbeddedObject->changeState( EmbedStates::LOADED );
2115         bSuccess = m_xEmbeddedObject->getCurrentState() == EmbedStates::LOADED;
2116     }
2117     return bSuccess;
2118 }
2119 
2120 // -----------------------------------------------------------------------------
open()2121 Reference< XComponent > SAL_CALL ODocumentDefinition::open(  )
2122 {
2123     return impl_openUI_nolck_throw( false );
2124 }
2125 
2126 // -----------------------------------------------------------------------------
openDesign()2127 Reference< XComponent > SAL_CALL ODocumentDefinition::openDesign(  )
2128 {
2129     return impl_openUI_nolck_throw( true );
2130 }
2131 
2132 // -----------------------------------------------------------------------------
store()2133 void SAL_CALL ODocumentDefinition::store(  )
2134 {
2135     ::osl::MutexGuard aGuard( m_aMutex );
2136     try
2137     {
2138         impl_store_throw();
2139     }
2140     catch( RuntimeException& ) { throw; }
2141     catch( const Exception& )
2142     {
2143         throw WrappedTargetException(
2144             ::rtl::OUString(), *this, ::cppu::getCaughtException() );
2145     }
2146 }
2147 
2148 // -----------------------------------------------------------------------------
close()2149 ::sal_Bool SAL_CALL ODocumentDefinition::close(  )
2150 {
2151     ::osl::MutexGuard aGuard( m_aMutex );
2152 
2153     sal_Bool bSuccess = sal_False;
2154     try
2155     {
2156         bSuccess = impl_close_throw();
2157     }
2158     catch( RuntimeException& ) { throw; }
2159     catch( const Exception& )
2160     {
2161         throw WrappedTargetException(
2162             ::rtl::OUString(), *this, ::cppu::getCaughtException() );
2163     }
2164     return bSuccess;
2165 }
2166 
2167 // -----------------------------------------------------------------------------
getHierarchicalName()2168 ::rtl::OUString SAL_CALL ODocumentDefinition::getHierarchicalName()
2169 {
2170     ::osl::MutexGuard aGuard( m_aMutex );
2171     return impl_getHierarchicalName( false );
2172 }
2173 
2174 // -----------------------------------------------------------------------------
composeHierarchicalName(const::rtl::OUString & i_rRelativeName)2175 ::rtl::OUString SAL_CALL ODocumentDefinition::composeHierarchicalName( const ::rtl::OUString& i_rRelativeName )
2176 {
2177     ::rtl::OUStringBuffer aBuffer;
2178     aBuffer.append( getHierarchicalName() );
2179     aBuffer.append( sal_Unicode( '/' ) );
2180     aBuffer.append( i_rRelativeName );
2181     return aBuffer.makeStringAndClear();
2182 }
2183 
2184 // -----------------------------------------------------------------------------
rename(const::rtl::OUString & _rNewName)2185 void SAL_CALL ODocumentDefinition::rename( const ::rtl::OUString& _rNewName )
2186 {
2187     try
2188     {
2189         ::osl::ResettableMutexGuard aGuard(m_aMutex);
2190         if ( _rNewName.equals( m_pImpl->m_aProps.aTitle ) )
2191             return;
2192 
2193         // document definitions are organized in a hierarchical way, so reject names
2194         // which contain a /, as this is reserved for hierarchy level separation
2195         if ( _rNewName.indexOf( '/' ) != -1 )
2196             m_aErrorHelper.raiseException( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES, *this );
2197 
2198         NameChangeNotifier aNameChangeAndNotify( *this, _rNewName, aGuard );
2199         m_pImpl->m_aProps.aTitle = _rNewName;
2200 
2201         if ( m_xEmbeddedObject.is() && m_xEmbeddedObject->getCurrentState() == EmbedStates::ACTIVE )
2202             updateDocumentTitle();
2203     }
2204     catch(const PropertyVetoException&)
2205     {
2206         throw ElementExistException(_rNewName,*this);
2207     }
2208 }
2209 // -----------------------------------------------------------------------------
getContainerStorage() const2210 Reference< XStorage> ODocumentDefinition::getContainerStorage() const
2211 {
2212     return  m_pImpl->m_pDataSource
2213         ?   m_pImpl->m_pDataSource->getStorage( m_bForm ? ODatabaseModelImpl::E_FORM : ODatabaseModelImpl::E_REPORT )
2214         :   Reference< XStorage>();
2215 }
2216 // -----------------------------------------------------------------------------
isModified()2217 sal_Bool ODocumentDefinition::isModified()
2218 {
2219     osl::ClearableGuard< osl::Mutex > aGuard(m_aMutex);
2220     sal_Bool bRet = sal_False;
2221     if ( m_xEmbeddedObject.is() )
2222     {
2223         Reference<XModifiable> xModel(getComponent(),UNO_QUERY);
2224         bRet = xModel.is() && xModel->isModified();
2225     }
2226     return bRet;
2227 }
2228 // -----------------------------------------------------------------------------
prepareClose()2229 bool ODocumentDefinition::prepareClose()
2230 {
2231     if ( !m_xEmbeddedObject.is() )
2232         return true;
2233 
2234     try
2235     {
2236         // suspend the controller. Embedded objects are not allowed to raise
2237         // own UI at their own discretion, instead, this has always to be triggered
2238         // by the embedding component. Thus, we do the suspend call here.
2239         // #i49370# / 2005-06-09 / frank.schoenheit@sun.com
2240 
2241         Reference< util::XCloseable > xComponent( impl_getComponent_throw( false ) );
2242         if ( !xComponent.is() )
2243             return true;
2244 
2245         Reference< XModel > xModel( xComponent, UNO_QUERY );
2246         Reference< XController > xController;
2247         if ( xModel.is() )
2248             xController = xModel->getCurrentController();
2249 
2250         OSL_ENSURE( xController.is() || ( m_xEmbeddedObject->getCurrentState() < EmbedStates::ACTIVE ),
2251             "ODocumentDefinition::prepareClose: no controller!" );
2252         if ( !xController.is() )
2253             // document has not yet been activated, i.e. has no UI, yet
2254             return true;
2255 
2256         sal_Bool bCouldSuspend = xController->suspend( sal_True );
2257         if ( !bCouldSuspend )
2258             // controller vetoed the closing
2259             return false;
2260 
2261         if ( isModified() )
2262         {
2263             Reference< XFrame > xFrame( xController->getFrame() );
2264             if ( xFrame.is() )
2265             {
2266                 Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW );
2267                 xTopWindow->toFront();
2268             }
2269             if ( !save( sal_True ) )
2270             {
2271                 if ( bCouldSuspend )
2272                     // revert suspension
2273                     xController->suspend( sal_False );
2274                 // saving failed or was cancelled
2275                 return false;
2276             }
2277         }
2278     }
2279     catch( const Exception& )
2280     {
2281         DBG_UNHANDLED_EXCEPTION();
2282     }
2283 
2284     return true;
2285 }
2286 // -----------------------------------------------------------------------------
fillReportData(const::comphelper::ComponentContext & _rContext,const Reference<util::XCloseable> & _rxComponent,const Reference<XConnection> & _rxActiveConnection)2287 void ODocumentDefinition::fillReportData( const ::comphelper::ComponentContext& _rContext,
2288                                                const Reference< util::XCloseable >& _rxComponent,
2289                                                const Reference< XConnection >& _rxActiveConnection )
2290 {
2291     Sequence< Any > aArgs(2);
2292     PropertyValue aValue;
2293     aValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TextDocument" ) );
2294     aValue.Value <<= _rxComponent;
2295     aArgs[0] <<= aValue;
2296     aValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) );
2297     aValue.Value <<= _rxActiveConnection;
2298     aArgs[1] <<= aValue;
2299 
2300     try
2301     {
2302         Reference< XJobExecutor > xExecuteable(
2303             _rContext.createComponentWithArguments( "com.sun.star.wizards.report.CallReportWizard", aArgs ), UNO_QUERY_THROW );
2304         xExecuteable->trigger( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "fill" ) ) );
2305     }
2306     catch( const Exception& )
2307     {
2308         DBG_UNHANDLED_EXCEPTION();
2309     }
2310 }
2311 // -----------------------------------------------------------------------------
updateDocumentTitle()2312 void ODocumentDefinition::updateDocumentTitle()
2313 {
2314     ::rtl::OUString sName = m_pImpl->m_aProps.aTitle;
2315     if ( m_pImpl->m_pDataSource )
2316     {
2317         if ( !sName.getLength() )
2318         {
2319             if ( m_bForm )
2320                 sName = DBACORE_RESSTRING( RID_STR_FORM );
2321             else
2322                 sName = DBACORE_RESSTRING( RID_STR_REPORT );
2323             Reference< XUntitledNumbers > xUntitledProvider(m_pImpl->m_pDataSource->getModel_noCreate(), UNO_QUERY      );
2324             if ( xUntitledProvider.is() )
2325                 sName += ::rtl::OUString::valueOf( xUntitledProvider->leaseNumber(getComponent()) );
2326         }
2327 
2328         Reference< XTitle > xDatabaseDocumentModel(m_pImpl->m_pDataSource->getModel_noCreate(),uno::UNO_QUERY);
2329         if ( xDatabaseDocumentModel.is() )
2330             sName = xDatabaseDocumentModel->getTitle() + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : ")) + sName;
2331     }
2332     Reference< XTitle> xTitle(getComponent(),UNO_QUERY);
2333     if ( xTitle.is() )
2334         xTitle->setTitle(sName);
2335 }
2336 // -----------------------------------------------------------------------------
queryClosing(const lang::EventObject & Source,::sal_Bool GetsOwnership)2337 void SAL_CALL ODocumentDefinition::queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership )
2338 {
2339     (void) Source;
2340     (void) GetsOwnership;
2341     try
2342     {
2343         if ( !close() )
2344             throw util::CloseVetoException();
2345     }
2346     catch(const lang::WrappedTargetException&)
2347     {
2348         throw util::CloseVetoException();
2349     }
2350 }
2351 // -----------------------------------------------------------------------------
notifyClosing(const lang::EventObject &)2352 void SAL_CALL ODocumentDefinition::notifyClosing( const lang::EventObject& /*Source*/ )
2353 {
2354 }
2355 // -----------------------------------------------------------------------------
disposing(const lang::EventObject &)2356 void SAL_CALL ODocumentDefinition::disposing( const lang::EventObject& /*Source*/ )
2357 {
2358 }
2359 
2360 // -----------------------------------------------------------------------------
firePropertyChange(sal_Int32 i_nHandle,const Any & i_rNewValue,const Any & i_rOldValue,sal_Bool i_bVetoable,const NotifierAccess)2361 void ODocumentDefinition::firePropertyChange( sal_Int32 i_nHandle, const Any& i_rNewValue, const Any& i_rOldValue,
2362         sal_Bool i_bVetoable, const NotifierAccess )
2363 {
2364     fire( &i_nHandle, &i_rNewValue, &i_rOldValue, 1, i_bVetoable );
2365 }
2366 
2367 // =============================================================================
2368 // NameChangeNotifier
2369 // =============================================================================
2370 // -----------------------------------------------------------------------------
NameChangeNotifier(ODocumentDefinition & i_rDocumentDefinition,const::rtl::OUString & i_rNewName,::osl::ResettableMutexGuard & i_rClearForNotify)2371 NameChangeNotifier::NameChangeNotifier( ODocumentDefinition& i_rDocumentDefinition, const ::rtl::OUString& i_rNewName,
2372                                   ::osl::ResettableMutexGuard& i_rClearForNotify )
2373     :m_rDocumentDefinition( i_rDocumentDefinition )
2374     ,m_aOldValue( makeAny( i_rDocumentDefinition.getCurrentName() ) )
2375     ,m_aNewValue( makeAny( i_rNewName ) )
2376     ,m_rClearForNotify( i_rClearForNotify )
2377 {
2378     impl_fireEvent_throw( sal_True );
2379 }
2380 
2381 // -----------------------------------------------------------------------------
~NameChangeNotifier()2382 NameChangeNotifier::~NameChangeNotifier()
2383 {
2384     impl_fireEvent_throw( sal_False );
2385 }
2386 
2387 // -----------------------------------------------------------------------------
impl_fireEvent_throw(const sal_Bool i_bVetoable)2388 void NameChangeNotifier::impl_fireEvent_throw( const sal_Bool i_bVetoable )
2389 {
2390     m_rClearForNotify.clear();
2391     m_rDocumentDefinition.firePropertyChange(
2392         PROPERTY_ID_NAME, m_aNewValue, m_aOldValue, i_bVetoable, ODocumentDefinition::NotifierAccess() );
2393     m_rClearForNotify.reset();
2394 }
2395 
2396 //........................................................................
2397 }   // namespace dbaccess
2398 //........................................................................
2399