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