1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "documentdefinition.hxx"
21 #include "dbastrings.hrc"
22 #include "sdbcoretools.hxx"
23 #include <tools/debug.hxx>
24 #include <tools/diagnose_ex.h>
25 #include <osl/diagnose.h>
26 #include <comphelper/property.hxx>
27 #include <comphelper/sequence.hxx>
28 #include <comphelper/namedvaluecollection.hxx>
29 #include <comphelper/classids.hxx>
30 #include <com/sun/star/frame/XUntitledNumbers.hpp>
31 #include <com/sun/star/awt/XTopWindow.hpp>
32 #include <com/sun/star/awt/Size.hpp>
33 #include <com/sun/star/lang/DisposedException.hpp>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <com/sun/star/frame/Desktop.hpp>
36 #include <com/sun/star/frame/XModel.hpp>
37 #include <com/sun/star/frame/XTitle.hpp>
38 #include <com/sun/star/frame/XController.hpp>
39 #include <com/sun/star/task/XJobExecutor.hpp>
40 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
41 #include <com/sun/star/frame/XFramesSupplier.hpp>
42 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
43 #include <com/sun/star/report/XReportDefinition.hpp>
44 #include <com/sun/star/report/XReportEngine.hpp>
45 #include <com/sun/star/ucb/OpenMode.hpp>
46 #include <com/sun/star/embed/XEmbedObjectFactory.hpp>
47 #include <com/sun/star/embed/EmbeddedObjectCreator.hpp>
48 #include <com/sun/star/embed/Aspects.hpp>
49 #include <com/sun/star/embed/OOoEmbeddedObjectFactory.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>
104 using namespace ::com::sun::star
;
105 using namespace view
;
107 using namespace util
;
109 using namespace beans
;
110 using namespace lang
;
112 using namespace embed
;
113 using namespace frame
;
114 using namespace document
;
115 using namespace sdbc
;
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
;
127 using sdb::application::XDatabaseDocumentUI
;
128 namespace DatabaseObject
= sdb::application::DatabaseObject
;
130 #define DEFAULT_WIDTH 10000
131 #define DEFAULT_HEIGHT 7500
136 typedef ::boost::optional
< bool > optional_bool
;
141 OUString
lcl_determineContentType_nothrow( const Reference
< XStorage
>& _rxContainerStorage
,
142 const OUString
& _rEntityName
)
144 OUString sContentType
;
147 ::utl::SharedUNOComponent
< XPropertySet
> xStorageProps(
148 _rxContainerStorage
->openStorageElement( _rEntityName
, ElementModes::READ
), UNO_QUERY_THROW
);
149 OSL_VERIFY( xStorageProps
->getPropertyValue( INFO_MEDIATYPE
) >>= sContentType
);
151 catch( const Exception
& )
153 DBG_UNHANDLED_EXCEPTION();
159 // OEmbedObjectHolder
160 typedef ::cppu::WeakComponentImplHelper1
< embed::XStateChangeListener
> TEmbedObjectHolder
;
161 class OEmbedObjectHolder
: public ::comphelper::OBaseMutex
162 ,public TEmbedObjectHolder
164 Reference
< XEmbeddedObject
> m_xBroadCaster
;
165 ODocumentDefinition
* m_pDefinition
;
166 bool m_bInStateChange
;
168 virtual void SAL_CALL
disposing() SAL_OVERRIDE
;
170 OEmbedObjectHolder(const Reference
< XEmbeddedObject
>& _xBroadCaster
,ODocumentDefinition
* _pDefinition
)
171 : TEmbedObjectHolder(m_aMutex
)
172 ,m_xBroadCaster(_xBroadCaster
)
173 ,m_pDefinition(_pDefinition
)
174 ,m_bInStateChange(false)
176 osl_atomic_increment( &m_refCount
);
178 if ( m_xBroadCaster
.is() )
179 m_xBroadCaster
->addStateChangeListener(this);
181 osl_atomic_decrement( &m_refCount
);
184 virtual void SAL_CALL
changingState( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) throw (embed::WrongStateException
, uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
185 virtual void SAL_CALL
stateChanged( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
186 virtual void SAL_CALL
disposing( const lang::EventObject
& Source
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
189 void SAL_CALL
OEmbedObjectHolder::disposing()
191 if ( m_xBroadCaster
.is() )
192 m_xBroadCaster
->removeStateChangeListener(this);
193 m_xBroadCaster
= NULL
;
194 m_pDefinition
= NULL
;
197 void SAL_CALL
OEmbedObjectHolder::changingState( const lang::EventObject
& /*aEvent*/, ::sal_Int32
/*nOldState*/, ::sal_Int32
/*nNewState*/ ) throw (embed::WrongStateException
, uno::RuntimeException
, std::exception
)
201 void SAL_CALL
OEmbedObjectHolder::stateChanged( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) throw (uno::RuntimeException
, std::exception
)
203 if ( !m_bInStateChange
&& nNewState
== EmbedStates::RUNNING
&& nOldState
== EmbedStates::ACTIVE
&& m_pDefinition
)
205 m_bInStateChange
= true;
206 Reference
<XInterface
> xInt(static_cast< ::cppu::OWeakObject
* >(m_pDefinition
),UNO_QUERY
);
208 Reference
<XEmbeddedObject
> xEmbeddedObject(aEvent
.Source
,UNO_QUERY
);
209 if ( xEmbeddedObject
.is() )
210 xEmbeddedObject
->changeState(EmbedStates::LOADED
);
212 m_bInStateChange
= false;
216 void SAL_CALL
OEmbedObjectHolder::disposing( const lang::EventObject
& /*Source*/ ) throw (uno::RuntimeException
, std::exception
)
218 m_xBroadCaster
= NULL
;
221 // OEmbeddedClientHelper
222 typedef ::cppu::WeakImplHelper1
< XEmbeddedClient
223 > EmbeddedClientHelper_BASE
;
224 class OEmbeddedClientHelper
: public EmbeddedClientHelper_BASE
226 ODocumentDefinition
* m_pClient
;
228 OEmbeddedClientHelper(ODocumentDefinition
* _pClient
) :m_pClient(_pClient
) {}
230 virtual void SAL_CALL
saveObject( ) throw (ObjectSaveVetoException
, Exception
, RuntimeException
, std::exception
) SAL_OVERRIDE
233 // XComponentSupplier
234 virtual Reference
< util::XCloseable
> SAL_CALL
getComponent( ) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
236 return Reference
< css::util::XCloseable
>();
240 virtual void SAL_CALL
visibilityChanged( sal_Bool
/*bVisible*/ ) throw (WrongStateException
, RuntimeException
, std::exception
) SAL_OVERRIDE
243 inline void resetClient(ODocumentDefinition
* _pClient
) { m_pClient
= _pClient
; }
250 LockModifiable( const Reference
< XInterface
>& i_rModifiable
)
251 :m_xModifiable( i_rModifiable
, UNO_QUERY
)
253 OSL_ENSURE( m_xModifiable
.is(), "LockModifiable::LockModifiable: invalid component!" );
254 if ( m_xModifiable
.is() )
256 if ( !m_xModifiable
->isSetModifiedEnabled() )
258 // somebody already locked that, no need to lock it, again, and no need to unlock it later
259 m_xModifiable
.clear();
263 m_xModifiable
->disableSetModified();
270 if ( m_xModifiable
.is() )
271 m_xModifiable
->enableSetModified();
275 Reference
< XModifiable2
> m_xModifiable
;
279 typedef ::cppu::WeakImplHelper1
< css::lang::XEventListener
280 > LifetimeCoupler_Base
;
281 /** helper class which couples the lifetime of a component to the lifetime
284 Instances of this class are constructed with two components. The first is
285 simply held by reference, and thus kept alive. The second one is observed
286 for <code>disposing</code> calls - if they occur, i.e. if the component dies,
287 the reference to the first component is cleared.
289 This way, you can ensure that a certain component is kept alive as long
290 as a second component is not disposed.
292 class LifetimeCoupler
: public LifetimeCoupler_Base
295 Reference
< XInterface
> m_xClient
;
298 inline static void couple( const Reference
< XInterface
>& _rxClient
, const Reference
< XComponent
>& _rxActor
)
300 Reference
< css::lang::XEventListener
> xEnsureDelete( new LifetimeCoupler( _rxClient
, _rxActor
) );
304 inline LifetimeCoupler( const Reference
< XInterface
>& _rxClient
, const Reference
< XComponent
>& _rxActor
)
305 :m_xClient( _rxClient
)
307 OSL_ENSURE( _rxActor
.is(), "LifetimeCoupler::LifetimeCoupler: this will crash!" );
308 osl_atomic_increment( &m_refCount
);
310 _rxActor
->addEventListener( this );
312 osl_atomic_decrement( &m_refCount
);
313 OSL_ENSURE( m_refCount
, "LifetimeCoupler::LifetimeCoupler: the actor is not holding us by hard ref - this won't work!" );
316 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
320 void SAL_CALL
LifetimeCoupler::disposing( const css::lang::EventObject
& /*Source*/ ) throw (RuntimeException
, std::exception
)
325 // ODocumentSaveContinuation
326 class ODocumentSaveContinuation
: public OInteraction
< XInteractionDocumentSave
>
329 Reference
<XContent
> m_xParentContainer
;
332 ODocumentSaveContinuation() { }
334 inline Reference
<XContent
> getContent() const { return m_xParentContainer
; }
335 inline OUString
getName() const { return m_sName
; }
337 // XInteractionDocumentSave
338 virtual void SAL_CALL
setName( const OUString
& _sName
,const Reference
<XContent
>& _xParent
) throw(RuntimeException
, std::exception
) SAL_OVERRIDE
;
341 void SAL_CALL
ODocumentSaveContinuation::setName( const OUString
& _sName
,const Reference
<XContent
>& _xParent
) throw(RuntimeException
, std::exception
)
344 m_xParentContainer
= _xParent
;
347 OUString
ODocumentDefinition::GetDocumentServiceFromMediaType( const Reference
< XStorage
>& _rxContainerStorage
,
348 const OUString
& _rEntityName
, const Reference
< XComponentContext
>& _rContext
,
349 Sequence
< sal_Int8
>& _rClassId
)
351 return GetDocumentServiceFromMediaType(
352 lcl_determineContentType_nothrow( _rxContainerStorage
, _rEntityName
),
353 _rContext
, _rClassId
);
356 OUString
ODocumentDefinition::GetDocumentServiceFromMediaType( const OUString
& _rMediaType
,
357 const Reference
< XComponentContext
>& _rContext
, Sequence
< sal_Int8
>& _rClassId
)
362 ::comphelper::MimeConfigurationHelper
aConfigHelper( _rContext
);
363 sResult
= aConfigHelper
.GetDocServiceNameFromMediaType( _rMediaType
);
364 _rClassId
= comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation(aConfigHelper
.GetExplicitlyRegisteredObjClassID( _rMediaType
));
365 if ( !_rClassId
.getLength() && !sResult
.isEmpty() )
367 Reference
< XNameAccess
> xObjConfig
= aConfigHelper
.GetObjConfiguration();
368 if ( xObjConfig
.is() )
370 Sequence
< OUString
> aClassIDs
= xObjConfig
->getElementNames();
371 for ( sal_Int32 nInd
= 0; nInd
< aClassIDs
.getLength(); nInd
++ )
373 Reference
< XNameAccess
> xObjectProps
;
374 OUString aEntryDocName
;
376 if ( ( xObjConfig
->getByName( aClassIDs
[nInd
] ) >>= xObjectProps
) && xObjectProps
.is()
377 && ( xObjectProps
->getByName("ObjectDocumentServiceName") >>= aEntryDocName
)
378 && aEntryDocName
.equals( sResult
) )
380 _rClassId
= comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation(aClassIDs
[nInd
]);
386 #if OSL_DEBUG_LEVEL > 0
387 // alternative, shorter approach
388 const Sequence
< NamedValue
> aProps( aConfigHelper
.GetObjectPropsByMediaType( _rMediaType
) );
389 const ::comphelper::NamedValueCollection
aMediaTypeProps( aProps
);
390 const OUString sAlternativeResult
= aMediaTypeProps
.getOrDefault( "ObjectDocumentServiceName", OUString() );
391 OSL_ENSURE( sAlternativeResult
== sResult
, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (1)!" );
392 const Sequence
< sal_Int8
> aAlternativeClassID
= aMediaTypeProps
.getOrDefault( "ClassID", Sequence
< sal_Int8
>() );
393 OSL_ENSURE( aAlternativeClassID
== _rClassId
, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (2)!" );
396 catch ( const Exception
& )
398 DBG_UNHANDLED_EXCEPTION();
403 // ODocumentDefinition
405 ODocumentDefinition::ODocumentDefinition( const Reference
< XInterface
>& _rxContainer
, const Reference
< XComponentContext
>& _xORB
,
406 const TContentPtr
& _pImpl
, bool _bForm
)
407 :OContentHelper(_xORB
,_rxContainer
,_pImpl
)
408 ,OPropertyStateContainer(OContentHelper::rBHelper
)
409 ,m_pInterceptor(NULL
)
411 ,m_bOpenInDesign(false)
413 ,m_bRemoveListener(false)
414 ,m_pClientHelper(NULL
)
416 registerProperties();
419 void ODocumentDefinition::initialLoad( const Sequence
< sal_Int8
>& i_rClassID
, const Sequence
< PropertyValue
>& i_rCreationArgs
,
420 const Reference
< XConnection
>& i_rConnection
)
422 OSL_ENSURE( i_rClassID
.getLength(), "ODocumentDefinition::initialLoad: illegal class ID!" );
423 if ( !i_rClassID
.getLength() )
426 loadEmbeddedObject( i_rConnection
, i_rClassID
, i_rCreationArgs
, false, false );
429 ODocumentDefinition::~ODocumentDefinition()
431 if ( !OContentHelper::rBHelper
.bInDispose
&& !OContentHelper::rBHelper
.bDisposed
)
437 if ( m_pInterceptor
)
439 m_pInterceptor
->dispose();
440 m_pInterceptor
->release();
441 m_pInterceptor
= NULL
;
445 void ODocumentDefinition::closeObject()
447 ::osl::MutexGuard
aGuard(m_aMutex
);
448 if ( m_xEmbeddedObject
.is() )
452 Reference
< com::sun::star::util::XCloseable
> xCloseable(m_xEmbeddedObject
,UNO_QUERY
);
453 if ( xCloseable
.is() )
454 xCloseable
->close(sal_True
);
456 catch(const Exception
&)
459 m_xEmbeddedObject
= NULL
;
460 if ( m_pClientHelper
)
462 m_pClientHelper
->resetClient(NULL
);
463 m_pClientHelper
->release();
464 m_pClientHelper
= NULL
;
469 void SAL_CALL
ODocumentDefinition::disposing()
471 OContentHelper::disposing();
472 ::osl::MutexGuard
aGuard(m_aMutex
);
474 ::comphelper::disposeComponent(m_xListener
);
475 if ( m_bRemoveListener
)
477 Reference
<util::XCloseable
> xCloseable(m_pImpl
->m_pDataSource
->getModel_noCreate(),UNO_QUERY
);
478 if ( xCloseable
.is() )
479 xCloseable
->removeCloseListener(this);
483 css::uno::Sequence
<sal_Int8
> ODocumentDefinition::getImplementationId()
484 throw (css::uno::RuntimeException
, std::exception
)
486 return css::uno::Sequence
<sal_Int8
>();
489 IMPLEMENT_GETTYPES3(ODocumentDefinition
,OContentHelper
,OPropertyStateContainer
,ODocumentDefinition_Base
);
490 IMPLEMENT_FORWARD_XINTERFACE3( ODocumentDefinition
,OContentHelper
,OPropertyStateContainer
,ODocumentDefinition_Base
)
491 IMPLEMENT_SERVICE_INFO1(ODocumentDefinition
,"com.sun.star.comp.dba.ODocumentDefinition",SERVICE_SDB_DOCUMENTDEFINITION
)
493 void ODocumentDefinition::registerProperties()
495 #define REGISTER_PROPERTY( name, location ) \
496 registerProperty( PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::READONLY, &location, cppu::UnoType<decltype(location)>::get() );
498 #define REGISTER_PROPERTY_BV( name, location ) \
499 registerProperty( PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::CONSTRAINED | PropertyAttribute::BOUND | PropertyAttribute::READONLY, &location, cppu::UnoType<decltype(location)>::get() );
501 REGISTER_PROPERTY_BV( NAME
, m_pImpl
->m_aProps
.aTitle
);
502 REGISTER_PROPERTY ( AS_TEMPLATE
, m_pImpl
->m_aProps
.bAsTemplate
);
503 REGISTER_PROPERTY ( PERSISTENT_NAME
, m_pImpl
->m_aProps
.sPersistentName
);
504 REGISTER_PROPERTY ( IS_FORM
, m_bForm
);
507 void SAL_CALL
ODocumentDefinition::getFastPropertyValue( Any
& o_rValue
, sal_Int32 i_nHandle
) const
509 if ( i_nHandle
== PROPERTY_ID_PERSISTENT_PATH
)
511 OUString sPersistentPath
;
512 if ( !m_pImpl
->m_aProps
.sPersistentName
.isEmpty() )
514 OUStringBuffer aBuffer
;
515 aBuffer
.append( ODatabaseModelImpl::getObjectContainerStorageName( m_bForm
? ODatabaseModelImpl::E_FORM
: ODatabaseModelImpl::E_REPORT
) );
516 aBuffer
.append( '/' );
517 aBuffer
.append( m_pImpl
->m_aProps
.sPersistentName
);
518 sPersistentPath
= aBuffer
.makeStringAndClear();
520 o_rValue
<<= sPersistentPath
;
524 OPropertyStateContainer::getFastPropertyValue( o_rValue
, i_nHandle
);
527 Reference
< XPropertySetInfo
> SAL_CALL
ODocumentDefinition::getPropertySetInfo( ) throw(RuntimeException
, std::exception
)
529 Reference
<XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
533 IPropertyArrayHelper
& ODocumentDefinition::getInfoHelper()
535 return *getArrayHelper();
538 IPropertyArrayHelper
* ODocumentDefinition::createArrayHelper( ) const
540 // properties maintained by our base class (see registerProperties)
541 Sequence
< Property
> aProps
;
542 describeProperties( aProps
);
544 // properties not maintained by our base class
545 Sequence
< Property
> aManualProps( 1 );
546 aManualProps
[0].Name
= PROPERTY_PERSISTENT_PATH
;
547 aManualProps
[0].Handle
= PROPERTY_ID_PERSISTENT_PATH
;
548 aManualProps
[0].Type
= ::cppu::UnoType
<OUString
>::get();
549 aManualProps
[0].Attributes
= PropertyAttribute::READONLY
;
551 return new OPropertyArrayHelper( ::comphelper::concatSequences( aProps
, aManualProps
) );
558 OExecuteImpl(bool& _rbSet
) : m_rbSet(_rbSet
){ m_rbSet
=true; }
559 ~OExecuteImpl(){ m_rbSet
= false; }
564 bool lcl_extractOpenMode( const Any
& _rValue
, sal_Int32
& _out_rMode
)
566 OpenCommandArgument aOpenCommand
;
567 if ( _rValue
>>= aOpenCommand
)
568 _out_rMode
= aOpenCommand
.Mode
;
571 OpenCommandArgument2 aOpenCommand2
;
572 if ( _rValue
>>= aOpenCommand2
)
573 _out_rMode
= aOpenCommand2
.Mode
;
581 void ODocumentDefinition::impl_removeFrameFromDesktop_throw( const Reference
<XComponentContext
> & _rxContext
, const Reference
< XFrame
>& _rxFrame
)
583 Reference
< XDesktop2
> xDesktop
= Desktop::create( _rxContext
);
584 Reference
< XFrames
> xFrames( xDesktop
->getFrames(), UNO_QUERY_THROW
);
585 xFrames
->remove( _rxFrame
);
588 void ODocumentDefinition::impl_onActivateEmbeddedObject_nothrow( const bool i_bReactivated
)
592 Reference
< XModel
> xModel( getComponent(), UNO_QUERY
);
593 Reference
< XController
> xController( xModel
.is() ? xModel
->getCurrentController() : Reference
< XController
>() );
594 if ( !xController
.is() )
597 if ( !m_xListener
.is() )
598 // it's the first time the embedded object has been activated
599 // create an OEmbedObjectHolder
600 m_xListener
= new OEmbedObjectHolder( m_xEmbeddedObject
, this );
602 // raise the window to top (especially necessary if this is not the first activation)
603 Reference
< XFrame
> xFrame( xController
->getFrame(), UNO_SET_THROW
);
604 Reference
< XTopWindow
> xTopWindow( xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
605 xTopWindow
->toFront();
607 // remove the frame from the desktop's frame collection because we need full control of it.
608 impl_removeFrameFromDesktop_throw( m_aContext
, xFrame
);
610 // ensure that we ourself are kept alive as long as the embedded object's frame is
612 LifetimeCoupler::couple( *this, xFrame
.get() );
614 // init the edit view
615 if ( m_bForm
&& m_bOpenInDesign
&& !i_bReactivated
)
616 impl_initFormEditView( xController
);
618 catch( const RuntimeException
& )
620 DBG_UNHANDLED_EXCEPTION();
626 // PreserveVisualAreaSize
627 /** stack-guard for preserving the size of the VisArea of an XModel
629 class PreserveVisualAreaSize
632 Reference
< XVisualObject
> m_xVisObject
;
633 awt::Size m_aOriginalSize
;
636 inline PreserveVisualAreaSize( const Reference
< XModel
>& _rxModel
)
637 :m_xVisObject( _rxModel
, UNO_QUERY
)
639 if ( m_xVisObject
.is() )
643 m_aOriginalSize
= m_xVisObject
->getVisualAreaSize( Aspects::MSOLE_CONTENT
);
645 catch ( const Exception
& )
647 OSL_FAIL( "PreserveVisualAreaSize::PreserveVisualAreaSize: caught an exception!" );
652 inline ~PreserveVisualAreaSize()
654 if ( m_xVisObject
.is() && m_aOriginalSize
.Width
&& m_aOriginalSize
.Height
)
658 m_xVisObject
->setVisualAreaSize( Aspects::MSOLE_CONTENT
, m_aOriginalSize
);
660 catch ( const Exception
& )
662 OSL_FAIL( "PreserveVisualAreaSize::~PreserveVisualAreaSize: caught an exception!" );
669 /** helper class for stack-usage which during its lifetime locks a layout manager
671 class LayoutManagerLock
674 Reference
< XLayoutManager
> m_xLayoutManager
;
677 inline LayoutManagerLock( const Reference
< XController
>& _rxController
)
679 OSL_ENSURE( _rxController
.is(), "LayoutManagerLock::LayoutManagerLock: this will crash!" );
680 Reference
< XFrame
> xFrame( _rxController
->getFrame() );
683 Reference
< XPropertySet
> xPropSet( xFrame
, UNO_QUERY_THROW
);
684 m_xLayoutManager
.set(
685 xPropSet
->getPropertyValue( "LayoutManager" ),
687 m_xLayoutManager
->lock();
690 catch( const Exception
& )
692 OSL_FAIL( "LayoutManagerLock::LayoutManagerLock: caught an exception!" );
696 inline ~LayoutManagerLock()
700 // unlock the layout manager
701 if ( m_xLayoutManager
.is() )
702 m_xLayoutManager
->unlock();
704 catch( const Exception
& )
706 OSL_FAIL( "LayoutManagerLock::~LayoutManagerLock: caught an exception!" );
712 void ODocumentDefinition::impl_initFormEditView( const Reference
< XController
>& _rxController
)
716 Reference
< XViewSettingsSupplier
> xSettingsSupplier( _rxController
, UNO_QUERY_THROW
);
717 Reference
< XPropertySet
> xViewSettings( xSettingsSupplier
->getViewSettings(), UNO_QUERY_THROW
);
719 // the below code could indirectly tamper with the "modified" flag of the model, temporarily disable this
720 LockModifiable
aLockModify( _rxController
->getModel() );
722 // The visual area size can be changed by the setting of the following properties
723 // so it should be restored later
724 PreserveVisualAreaSize
aPreserveVisAreaSize( _rxController
->getModel() );
726 // Layout manager should not layout while the size is still not restored
727 // so it will stay locked for this time
728 LayoutManagerLock
aLockLayout( _rxController
);
730 // setting of the visual properties
731 xViewSettings
->setPropertyValue("ShowRulers",makeAny(sal_True
));
732 xViewSettings
->setPropertyValue("ShowVertRuler",makeAny(sal_True
));
733 xViewSettings
->setPropertyValue("ShowHoriRuler",makeAny(sal_True
));
734 xViewSettings
->setPropertyValue("IsRasterVisible",makeAny(sal_True
));
735 xViewSettings
->setPropertyValue("IsSnapToRaster",makeAny(sal_True
));
736 xViewSettings
->setPropertyValue("ShowOnlineLayout",makeAny(sal_True
));
737 xViewSettings
->setPropertyValue("RasterSubdivisionX",makeAny(sal_Int32(5)));
738 xViewSettings
->setPropertyValue("RasterSubdivisionY",makeAny(sal_Int32(5)));
740 catch( const Exception
& )
742 DBG_UNHANDLED_EXCEPTION();
746 void ODocumentDefinition::impl_showOrHideComponent_throw( const bool i_bShow
)
748 const sal_Int32 nCurrentState
= m_xEmbeddedObject
.is() ? m_xEmbeddedObject
->getCurrentState() : EmbedStates::LOADED
;
749 switch ( nCurrentState
)
752 case EmbedStates::LOADED
:
753 throw embed::WrongStateException( OUString(), *this );
755 case EmbedStates::RUNNING
:
757 // fine, a running (and not yet active) object is never visible
760 LockModifiable
aLockModify( impl_getComponent_throw() );
761 m_xEmbeddedObject
->changeState( EmbedStates::ACTIVE
);
762 impl_onActivateEmbeddedObject_nothrow( false );
766 case EmbedStates::ACTIVE
:
768 Reference
< XModel
> xEmbeddedDoc( impl_getComponent_throw( true ), UNO_QUERY_THROW
);
769 Reference
< XController
> xEmbeddedController( xEmbeddedDoc
->getCurrentController(), UNO_SET_THROW
);
770 Reference
< XFrame
> xEmbeddedFrame( xEmbeddedController
->getFrame(), UNO_SET_THROW
);
771 Reference
< XWindow
> xEmbeddedWindow( xEmbeddedFrame
->getContainerWindow(), UNO_SET_THROW
);
772 xEmbeddedWindow
->setVisible( i_bShow
);
778 Any
ODocumentDefinition::onCommandOpenSomething( const Any
& _rOpenArgument
, const bool _bActivate
,
779 const Reference
< XCommandEnvironment
>& _rxEnvironment
)
781 OExecuteImpl
aExecuteGuard( m_bInExecute
);
783 Reference
< XConnection
> xConnection
;
784 sal_Int32 nOpenMode
= OpenMode::DOCUMENT
;
786 ::comphelper::NamedValueCollection aDocumentArgs
;
788 // for the document, default to the interaction handler as used for loading the DB doc
789 // This might be overwritten below, when examining _rOpenArgument.
790 const ::comphelper::NamedValueCollection
& aDBDocArgs( m_pImpl
->m_pDataSource
->getMediaDescriptor() );
791 Reference
< XInteractionHandler
> xHandler( aDBDocArgs
.getOrDefault( "InteractionHandler", Reference
< XInteractionHandler
>() ) );
793 aDocumentArgs
.put( "InteractionHandler", xHandler
);
795 ::boost::optional
< sal_Int16
> aDocumentMacroMode
;
797 if ( !lcl_extractOpenMode( _rOpenArgument
, nOpenMode
) )
799 Sequence
< PropertyValue
> aArguments
;
800 if ( _rOpenArgument
>>= aArguments
)
802 const PropertyValue
* pIter
= aArguments
.getConstArray();
803 const PropertyValue
* pEnd
= pIter
+ aArguments
.getLength();
804 for ( ;pIter
!= pEnd
; ++pIter
)
806 if ( pIter
->Name
== PROPERTY_ACTIVE_CONNECTION
)
808 xConnection
.set( pIter
->Value
, UNO_QUERY
);
812 if ( lcl_extractOpenMode( pIter
->Value
, nOpenMode
) )
815 if ( pIter
->Name
== "MacroExecutionMode" )
817 sal_Int16
nMacroExecMode( !aDocumentMacroMode
? MacroExecMode::USE_CONFIG
: *aDocumentMacroMode
);
818 OSL_VERIFY( pIter
->Value
>>= nMacroExecMode
);
819 aDocumentMacroMode
.reset( nMacroExecMode
);
823 // unknown argument -> pass to the loaded document
824 aDocumentArgs
.put( pIter
->Name
, pIter
->Value
);
829 bool bExecuteDBDocMacros
= m_pImpl
->m_pDataSource
->checkMacrosOnLoading();
830 // Note that this call implies the user might be asked for the macro execution mode.
831 // Normally, this would happen when the database document is loaded, and subsequent calls
832 // will simply use the user's decision from this point in time.
833 // However, it is possible to programmatically load forms/reports, without actually
834 // loading the database document into a frame. In this case, the user will be asked
838 // allow the command arguments to downgrade the macro execution mode, but not to upgrade
840 if ( ( m_pImpl
->m_pDataSource
->getImposedMacroExecMode() == MacroExecMode::USE_CONFIG
)
841 && bExecuteDBDocMacros
844 // while loading the whole database document, USE_CONFIG, was passed.
845 // Additionally, *by now* executing macros from the DB doc is allowed (this is what bExecuteDBDocMacros
846 // indicates). This means either one of:
847 // 1. The DB doc or one of the sub docs contained macros and
848 // 1a. the user explicitly allowed executing them
849 // 1b. the configuration allows executing them without asking the user
850 // 2. Neither the DB doc nor the sub docs contained macros, thus macro
851 // execution was silently enabled, assuming that any macro will be a
852 // user-created macro
854 // The problem with this: If the to-be-opened sub document has macros embedded in
855 // the content.xml (which is valid ODF, but normally not produced by OOo itself),
856 // then this has not been detected while loading the database document - it would
857 // be too expensive, as it effectively would require loading all forms/reports.
859 // So, in such a case, and with 2. above, we would silently execute those macros,
860 // regardless of the global security settings - which would be a security issue, of
862 if ( m_pImpl
->m_pDataSource
->determineEmbeddedMacros() == ODatabaseModelImpl::eNoMacros
)
864 // this is case 2. from above
865 // So, pass a USE_CONFIG to the to-be-loaded document. This means that
866 // the user will be prompted with a security message upon opening this
867 // sub document, in case the settings require this, *and* the document
868 // contains scripts in the content.xml. But this is better than the security
869 // issue we had before ...
870 aDocumentMacroMode
.reset( MacroExecMode::USE_CONFIG
);
874 if ( !aDocumentMacroMode
)
876 // nobody so far felt responsible for setting it
877 // => use the DBDoc-wide macro exec mode for the document, too
878 aDocumentMacroMode
.reset( bExecuteDBDocMacros
? MacroExecMode::ALWAYS_EXECUTE_NO_WARN
: MacroExecMode::NEVER_EXECUTE
);
880 aDocumentArgs
.put( "MacroExecutionMode", *aDocumentMacroMode
);
882 if ( ( nOpenMode
== OpenMode::ALL
)
883 || ( nOpenMode
== OpenMode::FOLDERS
)
884 || ( nOpenMode
== OpenMode::DOCUMENTS
)
885 || ( nOpenMode
== OpenMode::DOCUMENT_SHARE_DENY_NONE
)
886 || ( nOpenMode
== OpenMode::DOCUMENT_SHARE_DENY_WRITE
)
890 ucbhelper::cancelCommandExecution(
891 makeAny( UnsupportedOpenModeException(
893 static_cast< cppu::OWeakObject
* >( this ),
894 sal_Int16( nOpenMode
) ) ),
897 OSL_FAIL( "unreachable" );
900 OSL_ENSURE( !m_pImpl
->m_aProps
.sPersistentName
.isEmpty(),
901 "ODocumentDefinition::onCommandOpenSomething: no persistent name - cannot load!" );
902 if ( m_pImpl
->m_aProps
.sPersistentName
.isEmpty() )
905 // embedded objects themself do not support the hidden flag. We implement support for
906 // it by changing the STATE to RUNNING only, instead of ACTIVE.
907 bool bOpenHidden
= aDocumentArgs
.getOrDefault( "Hidden", false );
908 aDocumentArgs
.remove( "Hidden" );
910 loadEmbeddedObject( xConnection
, Sequence
< sal_Int8
>(), aDocumentArgs
.getPropertyValues(), false, !m_bOpenInDesign
);
911 OSL_ENSURE( m_xEmbeddedObject
.is(), "ODocumentDefinition::onCommandOpenSomething: what's this?" );
912 if ( !m_xEmbeddedObject
.is() )
915 Reference
< XModel
> xModel( getComponent(), UNO_QUERY
);
916 Reference
< report::XReportDefinition
> xReportDefinition(xModel
,UNO_QUERY
);
918 Reference
< XModule
> xModule( xModel
, UNO_QUERY
);
922 xModule
->setIdentifier( "com.sun.star.sdb.FormDesign" );
923 else if ( !xReportDefinition
.is() )
924 xModule
->setIdentifier( "com.sun.star.text.TextDocument" );
926 updateDocumentTitle();
929 bool bIsAliveNewStyleReport
= ( !m_bOpenInDesign
&& xReportDefinition
.is() );
930 if ( bIsAliveNewStyleReport
)
932 // we are in ReadOnly mode
933 // we would like to open the Writer or Calc with the report direct, without design it.
934 Reference
< report::XReportEngine
> xReportEngine( m_aContext
->getServiceManager()->createInstanceWithContext("com.sun.star.comp.report.OReportEngineJFree", m_aContext
), UNO_QUERY_THROW
);
936 xReportEngine
->setReportDefinition(xReportDefinition
);
937 xReportEngine
->setActiveConnection(m_xLastKnownConnection
);
939 return makeAny( xReportEngine
->createDocumentModel() );
940 return makeAny( xReportEngine
->createDocumentAlive( NULL
) );
943 if ( _bActivate
&& !bOpenHidden
)
945 LockModifiable
aLockModify( impl_getComponent_throw() );
946 m_xEmbeddedObject
->changeState( EmbedStates::ACTIVE
);
947 impl_onActivateEmbeddedObject_nothrow( false );
951 // ensure that we ourself are kept alive as long as the document is open
952 LifetimeCoupler::couple( *this, xModel
.get() );
955 if ( !m_bForm
&& m_pImpl
->m_aProps
.bAsTemplate
&& !m_bOpenInDesign
)
956 ODocumentDefinition::fillReportData( m_aContext
, getComponent(), xConnection
);
958 return makeAny( xModel
);
961 Any SAL_CALL
ODocumentDefinition::execute( const Command
& aCommand
, sal_Int32 CommandId
, const Reference
< XCommandEnvironment
>& Environment
) throw (Exception
, CommandAbortedException
, RuntimeException
, std::exception
)
965 bool bOpen
= aCommand
.Name
== "open";
966 bool bOpenInDesign
= aCommand
.Name
== "openDesign";
967 bool bOpenForMail
= aCommand
.Name
== "openForMail";
968 if ( bOpen
|| bOpenInDesign
|| bOpenForMail
)
970 // opening the document involves a lot of VCL code, which is not thread-safe, but needs the SolarMutex locked.
971 // Unfortunately, the DocumentDefinition, as well as the EmbeddedObject implementation, calls into VCL-dependent
972 // components *without* releasing the own mutex, which is a guaranteed recipe for deadlocks.
973 // We have control over this implementation here, and in modifying it to release the own mutex before calling into
974 // the VCL-dependent components is not too difficult (was there, seen it).
975 // However, we do /not/ have control over the EmbeddedObject implementation, and from a first look, it seems as
976 // making it release the own mutex before calling SolarMutex-code is ... difficult, at least.
977 // So, to be on the same side, we lock the SolarMutex here. Yes, it sucks.
978 ::SolarMutexGuard aSolarGuard
;
979 ::osl::ClearableMutexGuard
aGuard(m_aMutex
);
983 bool bActivateObject
= true;
986 OSL_FAIL( "ODocumentDefinition::execute: 'openForMail' should not be used anymore - use the 'Hidden' parameter instead!" );
987 bActivateObject
= false;
990 // if the object is already opened, do nothing
991 if ( m_xEmbeddedObject
.is() )
993 sal_Int32 nCurrentState
= m_xEmbeddedObject
->getCurrentState();
994 bool bIsActive
= ( nCurrentState
== EmbedStates::ACTIVE
);
998 // exception: new-style reports always create a new document when "open" is executed
999 Reference
< report::XReportDefinition
> xReportDefinition( impl_getComponent_throw( false ), UNO_QUERY
);
1000 bool bIsAliveNewStyleReport
= ( xReportDefinition
.is() && ( bOpen
|| bOpenForMail
) );
1002 if ( !bIsAliveNewStyleReport
)
1004 impl_onActivateEmbeddedObject_nothrow( true );
1005 return makeAny( getComponent() );
1010 m_bOpenInDesign
= bOpenInDesign
|| bOpenForMail
;
1011 return onCommandOpenSomething( aCommand
.Argument
, bActivateObject
, Environment
);
1014 ::osl::ClearableMutexGuard
aGuard(m_aMutex
);
1018 if ( aCommand
.Name
== "copyTo" )
1021 aCommand
.Argument
>>= aIni
;
1022 if ( aIni
.getLength() != 2 )
1024 OSL_FAIL( "Wrong argument type!" );
1025 ucbhelper::cancelCommandExecution(
1026 makeAny( IllegalArgumentException(
1028 static_cast< cppu::OWeakObject
* >( this ),
1033 Reference
< XStorage
> xDest(aIni
[0],UNO_QUERY
);
1034 OUString sPersistentName
;
1035 aIni
[1] >>= sPersistentName
;
1036 Reference
< XStorage
> xStorage
= getContainerStorage();
1038 xStorage
->copyElementTo(m_pImpl
->m_aProps
.sPersistentName
,xDest
,sPersistentName
);
1040 else if ( aCommand
.Name
== "preview" )
1042 onCommandPreview(aRet
);
1044 else if ( aCommand
.Name
== "insert" )
1047 aCommand
.Argument
>>= aIni
;
1048 if ( !aIni
.getLength() )
1050 OSL_FAIL( "Wrong argument count!" );
1051 ucbhelper::cancelCommandExecution(
1052 makeAny( IllegalArgumentException(
1054 static_cast< cppu::OWeakObject
* >( this ),
1061 onCommandInsert( sURL
, Environment
);
1063 else if ( aCommand
.Name
== "getdocumentinfo" // compatibility
1064 || aCommand
.Name
== "getDocumentInfo" )
1066 onCommandGetDocumentProperties( aRet
);
1068 else if ( aCommand
.Name
== "delete" )
1072 Reference
< XStorage
> xStorage
= getContainerStorage();
1073 if ( xStorage
.is() )
1074 xStorage
->removeElement(m_pImpl
->m_aProps
.sPersistentName
);
1079 else if ( aCommand
.Name
== "storeOwn" // compatibility
1080 || aCommand
.Name
== "store"
1085 else if ( aCommand
.Name
== "shutdown" // compatibility
1086 || aCommand
.Name
== "close"
1089 aRet
<<= impl_close_throw();
1091 else if ( aCommand
.Name
== "show" )
1093 impl_showOrHideComponent_throw( true );
1095 else if ( aCommand
.Name
== "hide" )
1097 impl_showOrHideComponent_throw( false );
1101 aRet
= OContentHelper::execute(aCommand
,CommandId
,Environment
);
1109 void lcl_resetChildFormsToEmptyDataSource( const Reference
< XIndexAccess
>& _rxFormsContainer
)
1111 OSL_PRECOND( _rxFormsContainer
.is(), "lcl_resetChildFormsToEmptyDataSource: illegal call!" );
1112 sal_Int32 count
= _rxFormsContainer
->getCount();
1113 for ( sal_Int32 i
= 0; i
< count
; ++i
)
1115 Reference
< XForm
> xForm( _rxFormsContainer
->getByIndex( i
), UNO_QUERY
);
1119 // if the element is a form, reset its DataSourceName property to an empty string
1122 Reference
< XPropertySet
> xFormProps( xForm
, UNO_QUERY_THROW
);
1123 xFormProps
->setPropertyValue( PROPERTY_DATASOURCENAME
, makeAny( OUString() ) );
1125 catch( const Exception
& )
1127 DBG_UNHANDLED_EXCEPTION();
1130 // if the element is a container itself, step down the component hierarchy
1131 Reference
< XIndexAccess
> xContainer( xForm
, UNO_QUERY
);
1132 if ( xContainer
.is() )
1133 lcl_resetChildFormsToEmptyDataSource( xContainer
);
1137 void lcl_resetFormsToEmptyDataSource( const Reference
< XEmbeddedObject
>& _rxEmbeddedObject
)
1141 Reference
< XDrawPageSupplier
> xSuppPage( _rxEmbeddedObject
->getComponent(), UNO_QUERY_THROW
);
1142 // if this interface does not exist, then either getComponent returned NULL,
1143 // or the document is a multi-page document. The latter is allowed, but currently
1144 // simply not handled by this code, as it would not normally happen.
1146 Reference
< XFormsSupplier
> xSuppForms( xSuppPage
->getDrawPage(), UNO_QUERY_THROW
);
1147 Reference
< XIndexAccess
> xForms( xSuppForms
->getForms(), UNO_QUERY_THROW
);
1148 lcl_resetChildFormsToEmptyDataSource( xForms
);
1150 catch( const Exception
& )
1152 DBG_UNHANDLED_EXCEPTION();
1158 void ODocumentDefinition::onCommandInsert( const OUString
& _sURL
, const Reference
< XCommandEnvironment
>& Environment
)
1161 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1163 // Check, if all required properties were set.
1164 if ( _sURL
.isEmpty() || m_xEmbeddedObject
.is() )
1166 OSL_FAIL( "Content::onCommandInsert - property value missing!" );
1168 Sequence
< OUString
> aProps( 1 );
1169 aProps
[ 0 ] = PROPERTY_URL
;
1170 ucbhelper::cancelCommandExecution(
1171 makeAny( MissingPropertiesException(
1173 static_cast< cppu::OWeakObject
* >( this ),
1179 if ( !m_xEmbeddedObject
.is() )
1181 Reference
< XStorage
> xStorage
= getContainerStorage();
1182 if ( xStorage
.is() )
1184 Reference
< XEmbeddedObjectCreator
> xEmbedFactory
= EmbeddedObjectCreator::create(m_aContext
);
1185 Sequence
<PropertyValue
> aEmpty
,aMediaDesc(1);
1186 aMediaDesc
[0].Name
= PROPERTY_URL
;
1187 aMediaDesc
[0].Value
<<= _sURL
;
1188 m_xEmbeddedObject
.set(xEmbedFactory
->createInstanceInitFromMediaDescriptor( xStorage
1189 ,m_pImpl
->m_aProps
.sPersistentName
1191 ,aEmpty
),UNO_QUERY
);
1193 lcl_resetFormsToEmptyDataSource( m_xEmbeddedObject
);
1196 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1197 if ( xPersist
.is() )
1199 xPersist
->storeOwn();
1203 Reference
< com::sun::star::util::XCloseable
> xCloseable(m_xEmbeddedObject
,UNO_QUERY
);
1204 if ( xCloseable
.is() )
1205 xCloseable
->close(sal_True
);
1207 catch(const Exception
&)
1210 m_xEmbeddedObject
= NULL
;
1217 bool ODocumentDefinition::save(bool _bApprove
)
1219 // default handling: instantiate an interaction handler and let it handle the parameter request
1220 if ( !m_bOpenInDesign
)
1226 ::SolarMutexGuard aSolarGuard
;
1229 Reference
<XNameAccess
> xName(m_xParentContainer
,UNO_QUERY
);
1230 DocumentSaveRequest aRequest
;
1231 aRequest
.Name
= m_pImpl
->m_aProps
.aTitle
;
1232 if ( aRequest
.Name
.isEmpty() )
1235 aRequest
.Name
= DBACORE_RESSTRING( RID_STR_FORM
);
1237 aRequest
.Name
= DBACORE_RESSTRING( RID_STR_REPORT
);
1238 aRequest
.Name
= ::dbtools::createUniqueName(xName
,aRequest
.Name
);
1241 aRequest
.Content
.set(m_xParentContainer
,UNO_QUERY
);
1242 OInteractionRequest
* pRequest
= new OInteractionRequest(makeAny(aRequest
));
1243 Reference
< XInteractionRequest
> xRequest(pRequest
);
1245 // two continuations allowed: OK and Cancel
1246 ODocumentSaveContinuation
* pDocuSave
= NULL
;
1248 if ( m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1250 pDocuSave
= new ODocumentSaveContinuation
;
1251 pRequest
->addContinuation(pDocuSave
);
1255 OInteraction
< XInteractionApprove
>* pApprove
= new OInteraction
< XInteractionApprove
>;
1256 pRequest
->addContinuation(pApprove
);
1259 OInteraction
< XInteractionDisapprove
>* pDisApprove
= new OInteraction
< XInteractionDisapprove
>;
1260 pRequest
->addContinuation(pDisApprove
);
1262 OInteractionAbort
* pAbort
= new OInteractionAbort
;
1263 pRequest
->addContinuation(pAbort
);
1265 // create the handler, let it handle the request
1266 Reference
< XInteractionHandler2
> xHandler( InteractionHandler::createWithParent(m_aContext
, 0) );
1267 xHandler
->handle(xRequest
);
1269 if ( pAbort
->wasSelected() )
1271 if ( pDisApprove
->wasSelected() )
1273 if ( pDocuSave
&& pDocuSave
->wasSelected() )
1275 Reference
<XNameContainer
> xNC( pDocuSave
->getContent(), UNO_QUERY_THROW
);
1277 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
1278 NameChangeNotifier
aNameChangeAndNotify( *this, pDocuSave
->getName(), aGuard
);
1279 m_pImpl
->m_aProps
.aTitle
= pDocuSave
->getName();
1281 Reference
< XContent
> xContent
= this;
1282 xNC
->insertByName(pDocuSave
->getName(),makeAny(xContent
));
1284 updateDocumentTitle();
1288 ::osl::MutexGuard
aGuard(m_aMutex
);
1289 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1290 if ( xPersist
.is() )
1292 xPersist
->storeOwn();
1293 notifyDataSourceModified();
1296 catch(const Exception
&)
1298 OSL_FAIL("ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1303 bool ODocumentDefinition::saveAs()
1305 // default handling: instantiate an interaction handler and let it handle the parameter request
1306 if ( !m_bOpenInDesign
)
1310 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1311 if ( m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1314 return save(false); // (sal_False) : we don't want an approve dialog
1320 ::SolarMutexGuard aSolarGuard
;
1323 Reference
<XNameAccess
> xName(m_xParentContainer
,UNO_QUERY
);
1324 DocumentSaveRequest aRequest
;
1325 aRequest
.Name
= m_pImpl
->m_aProps
.aTitle
;
1327 aRequest
.Content
.set(m_xParentContainer
,UNO_QUERY
);
1328 OInteractionRequest
* pRequest
= new OInteractionRequest(makeAny(aRequest
));
1329 Reference
< XInteractionRequest
> xRequest(pRequest
);
1331 // two continuations allowed: OK and Cancel
1332 ODocumentSaveContinuation
* pDocuSave
= new ODocumentSaveContinuation
;
1333 pRequest
->addContinuation(pDocuSave
);
1334 OInteraction
< XInteractionDisapprove
>* pDisApprove
= new OInteraction
< XInteractionDisapprove
>;
1335 pRequest
->addContinuation(pDisApprove
);
1336 OInteractionAbort
* pAbort
= new OInteractionAbort
;
1337 pRequest
->addContinuation(pAbort
);
1339 // create the handler, let it handle the request
1340 Reference
< XInteractionHandler2
> xHandler( InteractionHandler::createWithParent(m_aContext
, 0) );
1341 xHandler
->handle(xRequest
);
1343 if ( pAbort
->wasSelected() )
1345 if ( pDisApprove
->wasSelected() )
1347 if ( pDocuSave
->wasSelected() )
1349 ::osl::MutexGuard
aGuard(m_aMutex
);
1350 Reference
<XNameContainer
> xNC(pDocuSave
->getContent(),UNO_QUERY
);
1353 if ( m_pImpl
->m_aProps
.aTitle
!= pDocuSave
->getName() )
1357 Reference
< XStorage
> xStorage
= getContainerStorage();
1358 static const char sBaseName
[] = "Obj";
1360 OUString sPersistentName
= ::dbtools::createUniqueName(xStorage
,sBaseName
);
1361 xStorage
->copyElementTo(m_pImpl
->m_aProps
.sPersistentName
,xStorage
,sPersistentName
);
1363 OUString sOldName
= m_pImpl
->m_aProps
.aTitle
;
1364 rename(pDocuSave
->getName());
1365 updateDocumentTitle();
1367 Sequence
< Any
> aArguments(3);
1368 PropertyValue aValue
;
1370 aValue
.Name
= PROPERTY_NAME
;
1371 aValue
.Value
<<= sOldName
;
1372 aArguments
[0] <<= aValue
;
1374 aValue
.Name
= PROPERTY_PERSISTENT_NAME
;
1375 aValue
.Value
<<= sPersistentName
;
1376 aArguments
[1] <<= aValue
;
1378 aValue
.Name
= PROPERTY_AS_TEMPLATE
;
1379 aValue
.Value
<<= m_pImpl
->m_aProps
.bAsTemplate
;
1380 aArguments
[2] <<= aValue
;
1382 Reference
< XMultiServiceFactory
> xORB( m_xParentContainer
, UNO_QUERY_THROW
);
1383 Reference
< XInterface
> xComponent( xORB
->createInstanceWithArguments( SERVICE_SDB_DOCUMENTDEFINITION
, aArguments
) );
1384 Reference
< XNameContainer
> xNameContainer( m_xParentContainer
, UNO_QUERY_THROW
);
1385 xNameContainer
->insertByName( sOldName
, makeAny( xComponent
) );
1387 catch(const Exception
&)
1389 DBG_UNHANDLED_EXCEPTION();
1392 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1393 if ( xPersist
.is() )
1395 xPersist
->storeOwn();
1396 notifyDataSourceModified();
1403 catch(const Exception
&)
1405 OSL_FAIL("ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1412 void lcl_putLoadArgs( ::comphelper::NamedValueCollection
& _io_rArgs
, const optional_bool
& _bSuppressMacros
, const optional_bool
& _bReadOnly
)
1414 if ( !!_bSuppressMacros
)
1416 if ( *_bSuppressMacros
)
1418 // if we're to suppress macros, do exactly this
1419 _io_rArgs
.put( "MacroExecutionMode", MacroExecMode::NEVER_EXECUTE
);
1423 // otherwise, put the setting only if not already present
1424 if ( !_io_rArgs
.has( "MacroExecutionMode" ) )
1426 _io_rArgs
.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG
);
1432 _io_rArgs
.put( "ReadOnly", *_bReadOnly
);
1438 Reference
< XFrame
> lcl_getDatabaseDocumentFrame( ODatabaseModelImpl
& _rImpl
)
1440 Reference
< XModel
> xDatabaseDocumentModel( _rImpl
.getModel_noCreate() );
1442 Reference
< XController
> xDatabaseDocumentController
;
1443 if ( xDatabaseDocumentModel
.is() )
1444 xDatabaseDocumentController
= xDatabaseDocumentModel
->getCurrentController();
1446 Reference
< XFrame
> xFrame
;
1447 if ( xDatabaseDocumentController
.is() )
1448 xFrame
= xDatabaseDocumentController
->getFrame();
1454 bool ODocumentDefinition::objectSupportsEmbeddedScripts() const
1456 bool bAllowDocumentMacros
= !m_pImpl
->m_pDataSource
1457 || ( m_pImpl
->m_pDataSource
->determineEmbeddedMacros() == ODatabaseModelImpl::eSubDocumentMacros
);
1459 // if *any* of the objects of the database document already has macros, we
1460 // continue to allow it to have them, until the user does a migration.
1461 // If there are no macros, we don't allow them to be created.
1463 return bAllowDocumentMacros
;
1466 OUString
ODocumentDefinition::determineContentType() const
1468 return lcl_determineContentType_nothrow( getContainerStorage(), m_pImpl
->m_aProps
.sPersistentName
);
1471 void ODocumentDefinition::separateOpenCommandArguments( const Sequence
< PropertyValue
>& i_rOpenCommandArguments
,
1472 ::comphelper::NamedValueCollection
& o_rDocumentLoadArgs
, ::comphelper::NamedValueCollection
& o_rEmbeddedObjectDescriptor
)
1474 ::comphelper::NamedValueCollection
aOpenCommandArguments( i_rOpenCommandArguments
);
1476 const sal_Char
* pObjectDescriptorArgs
[] =
1480 for ( size_t i
=0; i
< sizeof( pObjectDescriptorArgs
) / sizeof( pObjectDescriptorArgs
[0] ); ++i
)
1482 if ( aOpenCommandArguments
.has( pObjectDescriptorArgs
[i
] ) )
1484 o_rEmbeddedObjectDescriptor
.put( pObjectDescriptorArgs
[i
], aOpenCommandArguments
.get( pObjectDescriptorArgs
[i
] ) );
1485 aOpenCommandArguments
.remove( pObjectDescriptorArgs
[i
] );
1489 o_rDocumentLoadArgs
.merge( aOpenCommandArguments
, false );
1492 Sequence
< PropertyValue
> ODocumentDefinition::fillLoadArgs( const Reference
< XConnection
>& _xConnection
, const bool _bSuppressMacros
, const bool _bReadOnly
,
1493 const Sequence
< PropertyValue
>& i_rOpenCommandArguments
, Sequence
< PropertyValue
>& _out_rEmbeddedObjectDescriptor
)
1495 // (re-)create interceptor, and put it into the descriptor of the embedded object
1496 if ( m_pInterceptor
)
1498 m_pInterceptor
->dispose();
1499 m_pInterceptor
->release();
1500 m_pInterceptor
= NULL
;
1503 m_pInterceptor
= new OInterceptor( this );
1504 m_pInterceptor
->acquire();
1505 Reference
<XDispatchProviderInterceptor
> xInterceptor
= m_pInterceptor
;
1507 ::comphelper::NamedValueCollection aEmbeddedDescriptor
;
1508 aEmbeddedDescriptor
.put( "OutplaceDispatchInterceptor", xInterceptor
);
1510 ::comphelper::NamedValueCollection aMediaDesc
;
1511 separateOpenCommandArguments( i_rOpenCommandArguments
, aMediaDesc
, aEmbeddedDescriptor
);
1513 // create the OutplaceFrameProperties, and put them into the descriptor of the embedded object
1514 ::comphelper::NamedValueCollection OutplaceFrameProperties
;
1515 OutplaceFrameProperties
.put( "TopWindow", true );
1516 OutplaceFrameProperties
.put( "SupportPersistentWindowState", true );
1518 Reference
< XFrame
> xParentFrame
;
1519 if ( m_pImpl
->m_pDataSource
)
1520 xParentFrame
= lcl_getDatabaseDocumentFrame( *m_pImpl
->m_pDataSource
);
1521 if ( !xParentFrame
.is() )
1522 { // i87957 we need a parent frame
1523 Reference
< XDesktop2
> xDesktop
= Desktop::create( m_aContext
);
1524 xParentFrame
.set( xDesktop
, UNO_QUERY_THROW
);
1525 Reference
<util::XCloseable
> xCloseable(m_pImpl
->m_pDataSource
->getModel_noCreate(),UNO_QUERY
);
1526 if ( xCloseable
.is() )
1528 xCloseable
->addCloseListener(this);
1529 m_bRemoveListener
= true;
1532 OSL_ENSURE( xParentFrame
.is(), "ODocumentDefinition::fillLoadArgs: no parent frame!" );
1533 if ( xParentFrame
.is() )
1534 OutplaceFrameProperties
.put( "ParentFrame", xParentFrame
);
1536 aEmbeddedDescriptor
.put( "OutplaceFrameProperties", OutplaceFrameProperties
.getNamedValues() );
1538 // tell the embedded object to have (or not have) script support
1539 aEmbeddedDescriptor
.put( "EmbeddedScriptSupport", objectSupportsEmbeddedScripts() );
1541 // tell the embedded object to not participate in the document recovery game - the DB doc will handle it
1542 aEmbeddedDescriptor
.put( "DocumentRecoverySupport", false );
1544 // pass the descriptor of the embedded object to the caller
1545 aEmbeddedDescriptor
>>= _out_rEmbeddedObjectDescriptor
;
1547 // create the ComponentData, and put it into the document's media descriptor
1549 ::comphelper::NamedValueCollection aComponentData
;
1550 aComponentData
.put( "ActiveConnection", _xConnection
);
1551 aComponentData
.put( "ApplyFormDesignMode", !_bReadOnly
);
1552 aMediaDesc
.put( "ComponentData", aComponentData
.getPropertyValues() );
1555 if ( !m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1556 aMediaDesc
.put( "DocumentTitle", m_pImpl
->m_aProps
.aTitle
);
1558 aMediaDesc
.put( "DocumentBaseURL", m_pImpl
->m_pDataSource
->getURL() );
1560 // put the common load arguments into the document's media descriptor
1561 lcl_putLoadArgs( aMediaDesc
, optional_bool( _bSuppressMacros
), optional_bool( _bReadOnly
) );
1563 return aMediaDesc
.getPropertyValues();
1566 void ODocumentDefinition::loadEmbeddedObject( const Reference
< XConnection
>& i_rConnection
, const Sequence
< sal_Int8
>& _aClassID
,
1567 const Sequence
< PropertyValue
>& i_rOpenCommandArguments
, const bool _bSuppressMacros
, const bool _bReadOnly
)
1569 if ( !m_xEmbeddedObject
.is() )
1571 Reference
< XStorage
> xStorage
= getContainerStorage();
1572 if ( xStorage
.is() )
1574 Reference
< XEmbeddedObjectCreator
> xEmbedFactory
= OOoEmbeddedObjectFactory::create(m_aContext
);
1575 OUString sDocumentService
;
1576 bool bSetSize
= false;
1577 sal_Int32 nEntryConnectionMode
= EntryInitModes::DEFAULT_INIT
;
1578 Sequence
< sal_Int8
> aClassID
= _aClassID
;
1579 if ( aClassID
.getLength() )
1581 nEntryConnectionMode
= EntryInitModes::TRUNCATE_INIT
;
1586 sDocumentService
= GetDocumentServiceFromMediaType( getContentType(), m_aContext
, aClassID
);
1587 // check if we are not a form and
1588 // the org.libreoffice.report.pentaho.SOReportJobFactory is not present.
1589 if ( !m_bForm
&& !(sDocumentService
== "com.sun.star.text.TextDocument"))
1591 // we seem to be a "new style" report, check if report extension is present.
1592 Reference
< XContentEnumerationAccess
> xEnumAccess( m_aContext
->getServiceManager(), UNO_QUERY
);
1593 const OUString sReportEngineServiceName
= ::dbtools::getDefaultReportEngineServiceName(m_aContext
);
1594 Reference
< XEnumeration
> xEnumDrivers
= xEnumAccess
->createContentEnumeration(sReportEngineServiceName
);
1595 if ( !xEnumDrivers
.is() || !xEnumDrivers
->hasMoreElements() )
1597 com::sun::star::io::WrongFormatException aWFE
;
1598 aWFE
.Message
= DBACORE_RESSTRING( RID_STR_MISSING_EXTENSION
);
1602 if ( !aClassID
.getLength() )
1605 aClassID
= MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID
);
1608 aClassID
= MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90
);
1613 OSL_ENSURE( aClassID
.getLength(),"No Class ID" );
1615 Sequence
< PropertyValue
> aEmbeddedObjectDescriptor
;
1616 Sequence
< PropertyValue
> aLoadArgs( fillLoadArgs(
1617 i_rConnection
, _bSuppressMacros
, _bReadOnly
, i_rOpenCommandArguments
, aEmbeddedObjectDescriptor
) );
1619 m_xEmbeddedObject
.set(xEmbedFactory
->createInstanceUserInit(aClassID
1622 ,m_pImpl
->m_aProps
.sPersistentName
1623 ,nEntryConnectionMode
1625 ,aEmbeddedObjectDescriptor
1627 if ( m_xEmbeddedObject
.is() )
1629 if ( !m_pClientHelper
)
1631 m_pClientHelper
= new OEmbeddedClientHelper(this);
1632 m_pClientHelper
->acquire();
1634 Reference
<XEmbeddedClient
> xClient
= m_pClientHelper
;
1635 m_xEmbeddedObject
->setClientSite(xClient
);
1636 m_xEmbeddedObject
->changeState(EmbedStates::RUNNING
);
1639 LockModifiable
aLockModify( impl_getComponent_throw( false ) );
1641 awt::Size
aSize( DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
1642 m_xEmbeddedObject
->setVisualAreaSize(Aspects::MSOLE_CONTENT
,aSize
);
1649 sal_Int32 nCurrentState
= m_xEmbeddedObject
->getCurrentState();
1650 if ( nCurrentState
== EmbedStates::LOADED
)
1652 if ( !m_pClientHelper
)
1654 m_pClientHelper
= new OEmbeddedClientHelper(this);
1655 m_pClientHelper
->acquire();
1657 Reference
<XEmbeddedClient
> xClient
= m_pClientHelper
;
1658 m_xEmbeddedObject
->setClientSite(xClient
);
1660 Sequence
< PropertyValue
> aEmbeddedObjectDescriptor
;
1661 Sequence
< PropertyValue
> aLoadArgs( fillLoadArgs(
1662 i_rConnection
, _bSuppressMacros
, _bReadOnly
, i_rOpenCommandArguments
, aEmbeddedObjectDescriptor
) );
1664 Reference
<XCommonEmbedPersist
> xCommon(m_xEmbeddedObject
,UNO_QUERY
);
1665 OSL_ENSURE(xCommon
.is(),"unsupported interface!");
1667 xCommon
->reload( aLoadArgs
, aEmbeddedObjectDescriptor
);
1668 m_xEmbeddedObject
->changeState(EmbedStates::RUNNING
);
1672 OSL_ENSURE( ( nCurrentState
== EmbedStates::RUNNING
) || ( nCurrentState
== EmbedStates::ACTIVE
),
1673 "ODocumentDefinition::loadEmbeddedObject: unexpected state!" );
1675 // if the document was already loaded (which means the embedded object is in state RUNNING or ACTIVE),
1676 // then just re-set some model parameters
1679 // ensure the media descriptor doesn't contain any values which are intended for the
1680 // EmbeddedObjectDescriptor only
1681 ::comphelper::NamedValueCollection aEmbeddedObjectDescriptor
;
1682 ::comphelper::NamedValueCollection aNewMediaDesc
;
1683 separateOpenCommandArguments( i_rOpenCommandArguments
, aNewMediaDesc
, aEmbeddedObjectDescriptor
);
1685 // merge the new media descriptor into the existing media descriptor
1686 const Reference
< XModel
> xModel( getComponent(), UNO_QUERY_THROW
);
1687 const Sequence
< PropertyValue
> aArgs
= xModel
->getArgs();
1688 ::comphelper::NamedValueCollection
aExistentMediaDesc( aArgs
);
1689 aExistentMediaDesc
.merge( aNewMediaDesc
, false );
1691 lcl_putLoadArgs( aExistentMediaDesc
, optional_bool(), optional_bool() );
1692 // don't put _bSuppressMacros and _bReadOnly here - if the document was already
1693 // loaded, we should not tamper with its settings.
1694 // #i88977# #i86872#
1696 xModel
->attachResource( xModel
->getURL(), aExistentMediaDesc
.getPropertyValues() );
1698 catch( const Exception
& )
1700 DBG_UNHANDLED_EXCEPTION();
1705 // set the OfficeDatabaseDocument instance as parent of the embedded document
1707 Reference
< XChild
> xDepdendDocAsChild( getComponent(), UNO_QUERY
);
1708 if ( xDepdendDocAsChild
.is() )
1712 if ( !xDepdendDocAsChild
->getParent().is() )
1713 { // first encounter
1714 xDepdendDocAsChild
->setParent( getDataSource( m_xParentContainer
) );
1717 catch( const Exception
& )
1719 DBG_UNHANDLED_EXCEPTION();
1723 if ( i_rConnection
.is() )
1724 m_xLastKnownConnection
= i_rConnection
;
1727 void ODocumentDefinition::onCommandPreview(Any
& _rImage
)
1729 loadEmbeddedObjectForPreview();
1730 if ( m_xEmbeddedObject
.is() )
1734 Reference
<XTransferable
> xTransfer(getComponent(),UNO_QUERY
);
1735 if ( xTransfer
.is() )
1738 aFlavor
.MimeType
= "image/png";
1739 aFlavor
.HumanPresentableName
= "Portable Network Graphics";
1740 aFlavor
.DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
1742 _rImage
= xTransfer
->getTransferData( aFlavor
);
1745 catch( const Exception
& )
1751 void ODocumentDefinition::getPropertyDefaultByHandle( sal_Int32
/*_nHandle*/, Any
& _rDefault
) const
1756 void ODocumentDefinition::onCommandGetDocumentProperties( Any
& _rProps
)
1758 loadEmbeddedObjectForPreview();
1759 if ( m_xEmbeddedObject
.is() )
1763 Reference
<XDocumentPropertiesSupplier
> xDocSup(
1764 getComponent(), UNO_QUERY
);
1766 _rProps
<<= xDocSup
->getDocumentProperties();
1768 catch( const Exception
& )
1770 DBG_UNHANDLED_EXCEPTION();
1775 Reference
< util::XCloseable
> ODocumentDefinition::impl_getComponent_throw( const bool i_ForceCreate
)
1777 OSL_ENSURE(m_xEmbeddedObject
.is(),"Illegal call for embeddedObject");
1778 Reference
< util::XCloseable
> xComp
;
1779 if ( m_xEmbeddedObject
.is() )
1781 int nState
= m_xEmbeddedObject
->getCurrentState();
1782 if ( ( nState
== EmbedStates::LOADED
) && i_ForceCreate
)
1784 m_xEmbeddedObject
->changeState( EmbedStates::RUNNING
);
1785 nState
= m_xEmbeddedObject
->getCurrentState();
1786 OSL_ENSURE( nState
== EmbedStates::RUNNING
, "ODocumentDefinition::impl_getComponent_throw: could not switch to RUNNING!" );
1789 if ( nState
== EmbedStates::ACTIVE
|| nState
== EmbedStates::RUNNING
)
1791 Reference
<XComponentSupplier
> xCompProv(m_xEmbeddedObject
,UNO_QUERY
);
1792 if ( xCompProv
.is() )
1794 xComp
= xCompProv
->getComponent();
1795 OSL_ENSURE(xComp
.is(),"No valid component");
1802 Reference
< util::XCloseable
> ODocumentDefinition::getComponent() throw (RuntimeException
, std::exception
)
1804 ::osl::MutexGuard
aGuard( m_aMutex
);
1805 return impl_getComponent_throw( true );
1810 Reference
< XDatabaseDocumentUI
> lcl_getDatabaseDocumentUI( ODatabaseModelImpl
& _rModelImpl
)
1812 Reference
< XDatabaseDocumentUI
> xUI
;
1814 Reference
< XModel
> xModel( _rModelImpl
.getModel_noCreate() );
1816 xUI
.set( xModel
->getCurrentController(), UNO_QUERY
);
1821 Reference
< XComponent
> ODocumentDefinition::impl_openUI_nolck_throw( bool _bForEditing
)
1823 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
1824 if ( !m_pImpl
|| !m_pImpl
->m_pDataSource
)
1825 throw DisposedException();
1827 Reference
< XComponent
> xComponent
;
1830 Reference
< XDatabaseDocumentUI
> xUI( lcl_getDatabaseDocumentUI( *m_pImpl
->m_pDataSource
) );
1833 // no XDatabaseDocumentUI -> just execute the respective command
1834 m_bOpenInDesign
= _bForEditing
;
1835 xComponent
= Reference
<XComponent
>(onCommandOpenSomething(Any(), true, NULL
), UNO_QUERY
);
1836 OSL_ENSURE( xComponent
.is(), "ODocumentDefinition::impl_openUI_nolck_throw: opening the thingie failed." );
1841 OUString
sName( impl_getHierarchicalName( false ) );
1842 sal_Int32 nObjectType
= m_bForm
? DatabaseObject::FORM
: DatabaseObject::REPORT
;
1845 xComponent
= xUI
->loadComponent(
1846 nObjectType
, sName
, _bForEditing
1849 catch( const RuntimeException
& ) { throw; }
1850 catch( const Exception
& )
1852 throw WrappedTargetException(
1853 OUString(), *this, ::cppu::getCaughtException() );
1859 void ODocumentDefinition::impl_store_throw()
1861 Reference
<XEmbedPersist
> xPersist( m_xEmbeddedObject
, UNO_QUERY
);
1862 if ( xPersist
.is() )
1864 xPersist
->storeOwn();
1865 notifyDataSourceModified();
1869 bool ODocumentDefinition::impl_close_throw()
1871 bool bSuccess
= prepareClose();
1872 if ( bSuccess
&& m_xEmbeddedObject
.is() )
1874 m_xEmbeddedObject
->changeState( EmbedStates::LOADED
);
1875 bSuccess
= m_xEmbeddedObject
->getCurrentState() == EmbedStates::LOADED
;
1880 Reference
< XComponent
> SAL_CALL
ODocumentDefinition::open( ) throw (WrappedTargetException
, RuntimeException
, std::exception
)
1882 return impl_openUI_nolck_throw( false );
1885 Reference
< XComponent
> SAL_CALL
ODocumentDefinition::openDesign( ) throw (WrappedTargetException
, RuntimeException
, std::exception
)
1887 return impl_openUI_nolck_throw( true );
1890 void SAL_CALL
ODocumentDefinition::store( ) throw (WrappedTargetException
, RuntimeException
, std::exception
)
1892 ::osl::MutexGuard
aGuard( m_aMutex
);
1897 catch( const RuntimeException
& ) { throw; }
1898 catch( const Exception
& )
1900 throw WrappedTargetException(
1901 OUString(), *this, ::cppu::getCaughtException() );
1905 sal_Bool SAL_CALL
ODocumentDefinition::close( ) throw (WrappedTargetException
, RuntimeException
, std::exception
)
1907 ::osl::MutexGuard
aGuard( m_aMutex
);
1909 bool bSuccess
= false;
1912 bSuccess
= impl_close_throw();
1914 catch( const RuntimeException
& ) { throw; }
1915 catch( const Exception
& )
1917 throw WrappedTargetException(
1918 OUString(), *this, ::cppu::getCaughtException() );
1923 OUString SAL_CALL
ODocumentDefinition::getHierarchicalName() throw (RuntimeException
, std::exception
)
1925 ::osl::MutexGuard
aGuard( m_aMutex
);
1926 return impl_getHierarchicalName( false );
1929 OUString SAL_CALL
ODocumentDefinition::composeHierarchicalName( const OUString
& i_rRelativeName
) throw (IllegalArgumentException
, NoSupportException
, RuntimeException
, std::exception
)
1931 OUStringBuffer aBuffer
;
1932 aBuffer
.append( getHierarchicalName() );
1933 aBuffer
.append( '/' );
1934 aBuffer
.append( i_rRelativeName
);
1935 return aBuffer
.makeStringAndClear();
1938 void SAL_CALL
ODocumentDefinition::rename( const OUString
& _rNewName
) throw (SQLException
, ElementExistException
, RuntimeException
, std::exception
)
1942 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
1943 if ( _rNewName
.equals( m_pImpl
->m_aProps
.aTitle
) )
1946 // document definitions are organized in a hierarchical way, so reject names
1947 // which contain a /, as this is reserved for hierarchy level separation
1948 if ( _rNewName
.indexOf( '/' ) != -1 )
1949 m_aErrorHelper
.raiseException( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES
, *this );
1951 NameChangeNotifier
aNameChangeAndNotify( *this, _rNewName
, aGuard
);
1952 m_pImpl
->m_aProps
.aTitle
= _rNewName
;
1954 if ( m_xEmbeddedObject
.is() && m_xEmbeddedObject
->getCurrentState() == EmbedStates::ACTIVE
)
1955 updateDocumentTitle();
1957 catch(const PropertyVetoException
&)
1959 throw ElementExistException(_rNewName
,*this);
1963 Reference
< XStorage
> ODocumentDefinition::getContainerStorage() const
1965 return m_pImpl
->m_pDataSource
1966 ? m_pImpl
->m_pDataSource
->getStorage( m_bForm
? ODatabaseModelImpl::E_FORM
: ODatabaseModelImpl::E_REPORT
)
1967 : Reference
< XStorage
>();
1970 bool ODocumentDefinition::isModified()
1972 osl::ClearableGuard
< osl::Mutex
> aGuard(m_aMutex
);
1974 if ( m_xEmbeddedObject
.is() )
1976 Reference
<XModifiable
> xModel(getComponent(),UNO_QUERY
);
1977 bRet
= xModel
.is() && xModel
->isModified();
1982 bool ODocumentDefinition::prepareClose()
1984 if ( !m_xEmbeddedObject
.is() )
1989 // suspend the controller. Embedded objects are not allowed to raise
1990 // own UI at their own discretion, instead, this has always to be triggered
1991 // by the embedding component. Thus, we do the suspend call here.
1994 Reference
< util::XCloseable
> xComponent( impl_getComponent_throw( false ) );
1995 if ( !xComponent
.is() )
1998 Reference
< XModel
> xModel( xComponent
, UNO_QUERY
);
1999 Reference
< XController
> xController
;
2001 xController
= xModel
->getCurrentController();
2003 OSL_ENSURE( xController
.is() || ( m_xEmbeddedObject
->getCurrentState() < EmbedStates::ACTIVE
),
2004 "ODocumentDefinition::prepareClose: no controller!" );
2005 if ( !xController
.is() )
2006 // document has not yet been activated, i.e. has no UI, yet
2009 bool bCouldSuspend
= xController
->suspend( sal_True
);
2010 if ( !bCouldSuspend
)
2011 // controller vetoed the closing
2016 Reference
< XFrame
> xFrame( xController
->getFrame() );
2019 Reference
< XTopWindow
> xTopWindow( xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
2020 xTopWindow
->toFront();
2022 if ( !save( true ) )
2024 if ( bCouldSuspend
)
2025 // revert suspension
2026 xController
->suspend( sal_False
);
2027 // saving failed or was cancelled
2032 catch( const Exception
& )
2034 DBG_UNHANDLED_EXCEPTION();
2040 void ODocumentDefinition::fillReportData( const Reference
< XComponentContext
>& _rContext
,
2041 const Reference
< util::XCloseable
>& _rxComponent
,
2042 const Reference
< XConnection
>& _rxActiveConnection
)
2044 Sequence
< Any
> aArgs(2);
2045 PropertyValue aValue
;
2046 aValue
.Name
= "TextDocument";
2047 aValue
.Value
<<= _rxComponent
;
2048 aArgs
[0] <<= aValue
;
2049 aValue
.Name
= "ActiveConnection";
2050 aValue
.Value
<<= _rxActiveConnection
;
2051 aArgs
[1] <<= aValue
;
2055 Reference
< XJobExecutor
> xExecuteable(
2056 _rContext
->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.wizards.report.CallReportWizard", aArgs
, _rContext
), UNO_QUERY_THROW
);
2057 xExecuteable
->trigger( "fill" );
2059 catch( const Exception
& )
2061 DBG_UNHANDLED_EXCEPTION();
2065 void ODocumentDefinition::updateDocumentTitle()
2067 OUString sName
= m_pImpl
->m_aProps
.aTitle
;
2068 if ( m_pImpl
->m_pDataSource
)
2070 if ( sName
.isEmpty() )
2073 sName
= DBACORE_RESSTRING( RID_STR_FORM
);
2075 sName
= DBACORE_RESSTRING( RID_STR_REPORT
);
2076 Reference
< XUntitledNumbers
> xUntitledProvider(m_pImpl
->m_pDataSource
->getModel_noCreate(), UNO_QUERY
);
2077 if ( xUntitledProvider
.is() )
2078 sName
+= OUString::number( xUntitledProvider
->leaseNumber(getComponent()) );
2081 Reference
< XTitle
> xDatabaseDocumentModel(m_pImpl
->m_pDataSource
->getModel_noCreate(),uno::UNO_QUERY
);
2082 if ( xDatabaseDocumentModel
.is() )
2083 sName
= xDatabaseDocumentModel
->getTitle() + " : " + sName
;
2085 Reference
< XTitle
> xTitle(getComponent(),UNO_QUERY
);
2087 xTitle
->setTitle(sName
);
2090 void SAL_CALL
ODocumentDefinition::queryClosing( const lang::EventObject
& Source
, sal_Bool GetsOwnership
) throw (util::CloseVetoException
, uno::RuntimeException
, std::exception
)
2093 (void) GetsOwnership
;
2097 throw util::CloseVetoException();
2099 catch(const lang::WrappedTargetException
&)
2101 throw util::CloseVetoException();
2105 void SAL_CALL
ODocumentDefinition::notifyClosing( const lang::EventObject
& /*Source*/ ) throw (uno::RuntimeException
, std::exception
)
2109 void SAL_CALL
ODocumentDefinition::disposing( const lang::EventObject
& /*Source*/ ) throw (uno::RuntimeException
, std::exception
)
2113 void ODocumentDefinition::firePropertyChange( sal_Int32 i_nHandle
, const Any
& i_rNewValue
, const Any
& i_rOldValue
,
2114 bool i_bVetoable
, const NotifierAccess
& )
2116 fire( &i_nHandle
, &i_rNewValue
, &i_rOldValue
, 1, i_bVetoable
);
2119 // NameChangeNotifier
2120 NameChangeNotifier::NameChangeNotifier( ODocumentDefinition
& i_rDocumentDefinition
, const OUString
& i_rNewName
,
2121 ::osl::ResettableMutexGuard
& i_rClearForNotify
)
2122 :m_rDocumentDefinition( i_rDocumentDefinition
)
2123 ,m_aOldValue( makeAny( i_rDocumentDefinition
.getCurrentName() ) )
2124 ,m_aNewValue( makeAny( i_rNewName
) )
2125 ,m_rClearForNotify( i_rClearForNotify
)
2127 impl_fireEvent_throw( true );
2130 NameChangeNotifier::~NameChangeNotifier()
2132 impl_fireEvent_throw( false );
2135 void NameChangeNotifier::impl_fireEvent_throw( const bool i_bVetoable
)
2137 m_rClearForNotify
.clear();
2138 m_rDocumentDefinition
.firePropertyChange(
2139 PROPERTY_ID_NAME
, m_aNewValue
, m_aOldValue
, i_bVetoable
, ODocumentDefinition::NotifierAccess() );
2140 m_rClearForNotify
.reset();
2143 } // namespace dbaccess
2145 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */