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