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