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