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