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/compbase.hxx>
93 #include <cppuhelper/exc_hlp.hxx>
94 #include <cppuhelper/implbase.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>
105 using namespace ::com::sun::star
;
106 using namespace view
;
108 using namespace util
;
110 using namespace beans
;
111 using namespace lang
;
113 using namespace embed
;
114 using namespace frame
;
115 using namespace document
;
116 using namespace sdbc
;
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
;
128 using sdb::application::XDatabaseDocumentUI
;
129 namespace DatabaseObject
= sdb::application::DatabaseObject
;
131 #define DEFAULT_WIDTH 10000
132 #define DEFAULT_HEIGHT 7500
137 typedef ::boost::optional
< bool > optional_bool
;
142 OUString
lcl_determineContentType_nothrow( const Reference
< XStorage
>& _rxContainerStorage
,
143 const OUString
& _rEntityName
)
145 OUString sContentType
;
148 ::utl::SharedUNOComponent
< XPropertySet
> xStorageProps(
149 _rxContainerStorage
->openStorageElement( _rEntityName
, ElementModes::READ
), UNO_QUERY_THROW
);
150 OSL_VERIFY( xStorageProps
->getPropertyValue( INFO_MEDIATYPE
) >>= sContentType
);
152 catch( const Exception
& )
154 DBG_UNHANDLED_EXCEPTION();
160 // OEmbedObjectHolder
161 typedef ::cppu::WeakComponentImplHelper
< embed::XStateChangeListener
> TEmbedObjectHolder
;
162 class OEmbedObjectHolder
: public ::cppu::BaseMutex
163 ,public TEmbedObjectHolder
165 Reference
< XEmbeddedObject
> m_xBroadCaster
;
166 ODocumentDefinition
* m_pDefinition
;
167 bool m_bInStateChange
;
169 virtual void SAL_CALL
disposing() override
;
171 OEmbedObjectHolder(const Reference
< XEmbeddedObject
>& _xBroadCaster
,ODocumentDefinition
* _pDefinition
)
172 : TEmbedObjectHolder(m_aMutex
)
173 ,m_xBroadCaster(_xBroadCaster
)
174 ,m_pDefinition(_pDefinition
)
175 ,m_bInStateChange(false)
177 osl_atomic_increment( &m_refCount
);
179 if ( m_xBroadCaster
.is() )
180 m_xBroadCaster
->addStateChangeListener(this);
182 osl_atomic_decrement( &m_refCount
);
185 virtual void SAL_CALL
changingState( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) throw (embed::WrongStateException
, uno::RuntimeException
, std::exception
) override
;
186 virtual void SAL_CALL
stateChanged( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) throw (uno::RuntimeException
, std::exception
) override
;
187 virtual void SAL_CALL
disposing( const lang::EventObject
& Source
) throw (uno::RuntimeException
, std::exception
) override
;
190 void SAL_CALL
OEmbedObjectHolder::disposing()
192 if ( m_xBroadCaster
.is() )
193 m_xBroadCaster
->removeStateChangeListener(this);
194 m_xBroadCaster
= nullptr;
195 m_pDefinition
= nullptr;
198 void SAL_CALL
OEmbedObjectHolder::changingState( const lang::EventObject
& /*aEvent*/, ::sal_Int32
/*nOldState*/, ::sal_Int32
/*nNewState*/ ) throw (embed::WrongStateException
, uno::RuntimeException
, std::exception
)
202 void SAL_CALL
OEmbedObjectHolder::stateChanged( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) throw (uno::RuntimeException
, std::exception
)
204 if ( !m_bInStateChange
&& nNewState
== EmbedStates::RUNNING
&& nOldState
== EmbedStates::ACTIVE
&& m_pDefinition
)
206 m_bInStateChange
= true;
207 Reference
<XInterface
> xInt(static_cast< ::cppu::OWeakObject
* >(m_pDefinition
),UNO_QUERY
);
209 Reference
<XEmbeddedObject
> xEmbeddedObject(aEvent
.Source
,UNO_QUERY
);
210 if ( xEmbeddedObject
.is() )
211 xEmbeddedObject
->changeState(EmbedStates::LOADED
);
213 m_bInStateChange
= false;
217 void SAL_CALL
OEmbedObjectHolder::disposing( const lang::EventObject
& /*Source*/ ) throw (uno::RuntimeException
, std::exception
)
219 m_xBroadCaster
= nullptr;
222 // OEmbeddedClientHelper
223 typedef ::cppu::WeakImplHelper
< XEmbeddedClient
224 > EmbeddedClientHelper_BASE
;
225 class OEmbeddedClientHelper
: public EmbeddedClientHelper_BASE
227 ODocumentDefinition
* m_pClient
;
229 explicit OEmbeddedClientHelper(ODocumentDefinition
* _pClient
) :m_pClient(_pClient
) {}
231 virtual void SAL_CALL
saveObject( ) throw (ObjectSaveVetoException
, Exception
, RuntimeException
, std::exception
) override
234 // XComponentSupplier
235 virtual Reference
< util::XCloseable
> SAL_CALL
getComponent( ) throw (RuntimeException
, std::exception
) override
237 return Reference
< css::util::XCloseable
>();
241 virtual void SAL_CALL
visibilityChanged( sal_Bool
/*bVisible*/ ) throw (WrongStateException
, RuntimeException
, std::exception
) override
244 inline void resetClient() { m_pClient
= nullptr; }
251 explicit LockModifiable( const Reference
< XInterface
>& i_rModifiable
)
252 :m_xModifiable( i_rModifiable
, UNO_QUERY
)
254 OSL_ENSURE( m_xModifiable
.is(), "LockModifiable::LockModifiable: invalid component!" );
255 if ( m_xModifiable
.is() )
257 if ( !m_xModifiable
->isSetModifiedEnabled() )
259 // somebody already locked that, no need to lock it, again, and no need to unlock it later
260 m_xModifiable
.clear();
264 m_xModifiable
->disableSetModified();
271 if ( m_xModifiable
.is() )
272 m_xModifiable
->enableSetModified();
276 Reference
< XModifiable2
> m_xModifiable
;
280 typedef ::cppu::WeakImplHelper
< css::lang::XEventListener
281 > LifetimeCoupler_Base
;
282 /** helper class which couples the lifetime of a component to the lifetime
285 Instances of this class are constructed with two components. The first is
286 simply held by reference, and thus kept alive. The second one is observed
287 for <code>disposing</code> calls - if they occur, i.e. if the component dies,
288 the reference to the first component is cleared.
290 This way, you can ensure that a certain component is kept alive as long
291 as a second component is not disposed.
293 class LifetimeCoupler
: public LifetimeCoupler_Base
296 Reference
< XInterface
> m_xClient
;
299 inline static void couple( const Reference
< XInterface
>& _rxClient
, const Reference
< XComponent
>& _rxActor
)
301 Reference
< css::lang::XEventListener
> xEnsureDelete( new LifetimeCoupler( _rxClient
, _rxActor
) );
305 inline LifetimeCoupler( const Reference
< XInterface
>& _rxClient
, const Reference
< XComponent
>& _rxActor
)
306 :m_xClient( _rxClient
)
308 OSL_ENSURE( _rxActor
.is(), "LifetimeCoupler::LifetimeCoupler: this will crash!" );
309 osl_atomic_increment( &m_refCount
);
311 _rxActor
->addEventListener( this );
313 osl_atomic_decrement( &m_refCount
);
314 OSL_ENSURE( m_refCount
, "LifetimeCoupler::LifetimeCoupler: the actor is not holding us by hard ref - this won't work!" );
317 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) throw (RuntimeException
, std::exception
) override
;
321 void SAL_CALL
LifetimeCoupler::disposing( const css::lang::EventObject
& /*Source*/ ) throw (RuntimeException
, std::exception
)
326 // ODocumentSaveContinuation
327 class ODocumentSaveContinuation
: public OInteraction
< XInteractionDocumentSave
>
330 Reference
<XContent
> m_xParentContainer
;
333 ODocumentSaveContinuation() { }
335 const Reference
<XContent
>& getContent() const { return m_xParentContainer
; }
336 const OUString
& getName() const { return m_sName
; }
338 // XInteractionDocumentSave
339 virtual void SAL_CALL
setName( const OUString
& _sName
,const Reference
<XContent
>& _xParent
) throw(RuntimeException
, std::exception
) override
;
342 void SAL_CALL
ODocumentSaveContinuation::setName( const OUString
& _sName
,const Reference
<XContent
>& _xParent
) throw(RuntimeException
, std::exception
)
345 m_xParentContainer
= _xParent
;
348 OUString
ODocumentDefinition::GetDocumentServiceFromMediaType( const Reference
< XStorage
>& _rxContainerStorage
,
349 const OUString
& _rEntityName
, const Reference
< XComponentContext
>& _rContext
,
350 Sequence
< sal_Int8
>& _rClassId
)
352 return GetDocumentServiceFromMediaType(
353 lcl_determineContentType_nothrow( _rxContainerStorage
, _rEntityName
),
354 _rContext
, _rClassId
);
357 OUString
ODocumentDefinition::GetDocumentServiceFromMediaType( const OUString
& _rMediaType
,
358 const Reference
< XComponentContext
>& _rContext
, Sequence
< sal_Int8
>& _rClassId
)
363 ::comphelper::MimeConfigurationHelper
aConfigHelper( _rContext
);
364 sResult
= aConfigHelper
.GetDocServiceNameFromMediaType( _rMediaType
);
365 _rClassId
= comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation(aConfigHelper
.GetExplicitlyRegisteredObjClassID( _rMediaType
));
366 if ( !_rClassId
.getLength() && !sResult
.isEmpty() )
368 Reference
< XNameAccess
> xObjConfig
= aConfigHelper
.GetObjConfiguration();
369 if ( xObjConfig
.is() )
371 Sequence
< OUString
> aClassIDs
= xObjConfig
->getElementNames();
372 for ( sal_Int32 nInd
= 0; nInd
< aClassIDs
.getLength(); nInd
++ )
374 Reference
< XNameAccess
> xObjectProps
;
375 OUString aEntryDocName
;
377 if ( ( xObjConfig
->getByName( aClassIDs
[nInd
] ) >>= xObjectProps
) && xObjectProps
.is()
378 && ( xObjectProps
->getByName("ObjectDocumentServiceName") >>= aEntryDocName
)
379 && aEntryDocName
.equals( sResult
) )
381 _rClassId
= comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation(aClassIDs
[nInd
]);
387 #if OSL_DEBUG_LEVEL > 0
388 // alternative, shorter approach
389 const Sequence
< NamedValue
> aProps( aConfigHelper
.GetObjectPropsByMediaType( _rMediaType
) );
390 const ::comphelper::NamedValueCollection
aMediaTypeProps( aProps
);
391 const OUString sAlternativeResult
= aMediaTypeProps
.getOrDefault( "ObjectDocumentServiceName", OUString() );
392 OSL_ENSURE( sAlternativeResult
== sResult
, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (1)!" );
393 const Sequence
< sal_Int8
> aAlternativeClassID
= aMediaTypeProps
.getOrDefault( "ClassID", Sequence
< sal_Int8
>() );
394 OSL_ENSURE( aAlternativeClassID
== _rClassId
, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (2)!" );
397 catch ( const Exception
& )
399 DBG_UNHANDLED_EXCEPTION();
404 // ODocumentDefinition
406 ODocumentDefinition::ODocumentDefinition( const Reference
< XInterface
>& _rxContainer
, const Reference
< XComponentContext
>& _xORB
,
407 const TContentPtr
& _pImpl
, bool _bForm
)
408 :OContentHelper(_xORB
,_rxContainer
,_pImpl
)
409 ,OPropertyStateContainer(OContentHelper::rBHelper
)
411 ,m_bOpenInDesign(false)
413 ,m_bRemoveListener(false)
415 registerProperties();
418 void ODocumentDefinition::initialLoad( const Sequence
< sal_Int8
>& i_rClassID
, const Sequence
< PropertyValue
>& i_rCreationArgs
,
419 const Reference
< XConnection
>& i_rConnection
)
421 OSL_ENSURE( i_rClassID
.getLength(), "ODocumentDefinition::initialLoad: illegal class ID!" );
422 if ( !i_rClassID
.getLength() )
425 loadEmbeddedObject( i_rConnection
, i_rClassID
, i_rCreationArgs
, false, false );
428 ODocumentDefinition::~ODocumentDefinition()
430 if ( !OContentHelper::rBHelper
.bInDispose
&& !OContentHelper::rBHelper
.bDisposed
)
436 if ( m_pInterceptor
.is() )
438 m_pInterceptor
->dispose();
439 m_pInterceptor
.clear();
443 void ODocumentDefinition::closeObject()
445 ::osl::MutexGuard
aGuard(m_aMutex
);
446 if ( m_xEmbeddedObject
.is() )
450 Reference
< css::util::XCloseable
> xCloseable(m_xEmbeddedObject
,UNO_QUERY
);
451 if ( xCloseable
.is() )
452 xCloseable
->close(true);
454 catch(const Exception
&)
457 m_xEmbeddedObject
= nullptr;
458 if ( m_pClientHelper
.is() )
460 m_pClientHelper
->resetClient();
461 m_pClientHelper
.clear();
466 void SAL_CALL
ODocumentDefinition::disposing()
468 OContentHelper::disposing();
469 ::osl::MutexGuard
aGuard(m_aMutex
);
471 ::comphelper::disposeComponent(m_xListener
);
472 if ( m_bRemoveListener
)
474 Reference
<util::XCloseable
> xCloseable(m_pImpl
->m_pDataSource
->getModel_noCreate(),UNO_QUERY
);
475 if ( xCloseable
.is() )
476 xCloseable
->removeCloseListener(this);
480 css::uno::Sequence
<sal_Int8
> ODocumentDefinition::getImplementationId()
481 throw (css::uno::RuntimeException
, std::exception
)
483 return css::uno::Sequence
<sal_Int8
>();
486 IMPLEMENT_GETTYPES3(ODocumentDefinition
,OContentHelper
,OPropertyStateContainer
,ODocumentDefinition_Base
);
487 IMPLEMENT_FORWARD_XINTERFACE3( ODocumentDefinition
,OContentHelper
,OPropertyStateContainer
,ODocumentDefinition_Base
)
489 void ODocumentDefinition::registerProperties()
491 #define REGISTER_PROPERTY( name, location ) \
492 registerProperty( PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::READONLY, &location, cppu::UnoType<decltype(location)>::get() );
494 #define REGISTER_PROPERTY_BV( name, location ) \
495 registerProperty( PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::CONSTRAINED | PropertyAttribute::BOUND | PropertyAttribute::READONLY, &location, cppu::UnoType<decltype(location)>::get() );
497 REGISTER_PROPERTY_BV( NAME
, m_pImpl
->m_aProps
.aTitle
);
498 REGISTER_PROPERTY ( AS_TEMPLATE
, m_pImpl
->m_aProps
.bAsTemplate
);
499 REGISTER_PROPERTY ( PERSISTENT_NAME
, m_pImpl
->m_aProps
.sPersistentName
);
500 REGISTER_PROPERTY ( IS_FORM
, m_bForm
);
503 void SAL_CALL
ODocumentDefinition::getFastPropertyValue( Any
& o_rValue
, sal_Int32 i_nHandle
) const
505 if ( i_nHandle
== PROPERTY_ID_PERSISTENT_PATH
)
507 OUString sPersistentPath
;
508 if ( !m_pImpl
->m_aProps
.sPersistentName
.isEmpty() )
510 OUStringBuffer aBuffer
;
511 aBuffer
.append( ODatabaseModelImpl::getObjectContainerStorageName( m_bForm
? ODatabaseModelImpl::E_FORM
: ODatabaseModelImpl::E_REPORT
) );
512 aBuffer
.append( '/' );
513 aBuffer
.append( m_pImpl
->m_aProps
.sPersistentName
);
514 sPersistentPath
= aBuffer
.makeStringAndClear();
516 o_rValue
<<= sPersistentPath
;
520 OPropertyStateContainer::getFastPropertyValue( o_rValue
, i_nHandle
);
523 Reference
< XPropertySetInfo
> SAL_CALL
ODocumentDefinition::getPropertySetInfo( ) throw(RuntimeException
, std::exception
)
525 Reference
<XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
529 IPropertyArrayHelper
& ODocumentDefinition::getInfoHelper()
531 return *getArrayHelper();
534 IPropertyArrayHelper
* ODocumentDefinition::createArrayHelper( ) const
536 // properties maintained by our base class (see registerProperties)
537 Sequence
< Property
> aProps
;
538 describeProperties( aProps
);
540 // properties not maintained by our base class
541 Sequence
< Property
> aManualProps( 1 );
542 aManualProps
[0].Name
= PROPERTY_PERSISTENT_PATH
;
543 aManualProps
[0].Handle
= PROPERTY_ID_PERSISTENT_PATH
;
544 aManualProps
[0].Type
= ::cppu::UnoType
<OUString
>::get();
545 aManualProps
[0].Attributes
= PropertyAttribute::READONLY
;
547 return new OPropertyArrayHelper( ::comphelper::concatSequences( aProps
, aManualProps
) );
554 explicit OExecuteImpl(bool& _rbSet
) : m_rbSet(_rbSet
){ m_rbSet
=true; }
555 ~OExecuteImpl(){ m_rbSet
= false; }
560 bool lcl_extractOpenMode( const Any
& _rValue
, sal_Int32
& _out_rMode
)
562 OpenCommandArgument aOpenCommand
;
563 if ( _rValue
>>= aOpenCommand
)
564 _out_rMode
= aOpenCommand
.Mode
;
567 OpenCommandArgument2 aOpenCommand2
;
568 if ( _rValue
>>= aOpenCommand2
)
569 _out_rMode
= aOpenCommand2
.Mode
;
577 void ODocumentDefinition::impl_removeFrameFromDesktop_throw( const Reference
<XComponentContext
> & _rxContext
, const Reference
< XFrame
>& _rxFrame
)
579 Reference
< XDesktop2
> xDesktop
= Desktop::create( _rxContext
);
580 Reference
< XFrames
> xFrames( xDesktop
->getFrames(), UNO_QUERY_THROW
);
581 xFrames
->remove( _rxFrame
);
584 void ODocumentDefinition::impl_onActivateEmbeddedObject_nothrow( const bool i_bReactivated
)
588 Reference
< XModel
> xModel( getComponent(), UNO_QUERY
);
589 Reference
< XController
> xController( xModel
.is() ? xModel
->getCurrentController() : Reference
< XController
>() );
590 if ( !xController
.is() )
593 if ( !m_xListener
.is() )
594 // it's the first time the embedded object has been activated
595 // create an OEmbedObjectHolder
596 m_xListener
= new OEmbedObjectHolder( m_xEmbeddedObject
, this );
598 // raise the window to top (especially necessary if this is not the first activation)
599 Reference
< XFrame
> xFrame( xController
->getFrame(), UNO_SET_THROW
);
600 Reference
< XTopWindow
> xTopWindow( xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
601 xTopWindow
->toFront();
603 // remove the frame from the desktop's frame collection because we need full control of it.
604 impl_removeFrameFromDesktop_throw( m_aContext
, xFrame
);
606 // ensure that we ourself are kept alive as long as the embedded object's frame is
608 LifetimeCoupler::couple( *this, xFrame
.get() );
610 // init the edit view
611 if ( m_bForm
&& m_bOpenInDesign
&& !i_bReactivated
)
612 impl_initFormEditView( xController
);
614 catch( const RuntimeException
& )
616 DBG_UNHANDLED_EXCEPTION();
622 // PreserveVisualAreaSize
623 /** stack-guard for preserving the size of the VisArea of an XModel
625 class PreserveVisualAreaSize
628 Reference
< XVisualObject
> m_xVisObject
;
629 awt::Size m_aOriginalSize
;
632 explicit PreserveVisualAreaSize( const Reference
< XModel
>& _rxModel
)
633 :m_xVisObject( _rxModel
, UNO_QUERY
)
635 if ( m_xVisObject
.is() )
639 m_aOriginalSize
= m_xVisObject
->getVisualAreaSize( Aspects::MSOLE_CONTENT
);
641 catch ( const Exception
& )
643 OSL_FAIL( "PreserveVisualAreaSize::PreserveVisualAreaSize: caught an exception!" );
648 inline ~PreserveVisualAreaSize()
650 if ( m_xVisObject
.is() && m_aOriginalSize
.Width
&& m_aOriginalSize
.Height
)
654 m_xVisObject
->setVisualAreaSize( Aspects::MSOLE_CONTENT
, m_aOriginalSize
);
656 catch ( const Exception
& )
658 OSL_FAIL( "PreserveVisualAreaSize::~PreserveVisualAreaSize: caught an exception!" );
665 /** helper class for stack-usage which during its lifetime locks a layout manager
667 class LayoutManagerLock
670 Reference
< XLayoutManager
> m_xLayoutManager
;
673 explicit LayoutManagerLock( const Reference
< XController
>& _rxController
)
675 OSL_ENSURE( _rxController
.is(), "LayoutManagerLock::LayoutManagerLock: this will crash!" );
676 Reference
< XFrame
> xFrame( _rxController
->getFrame() );
679 Reference
< XPropertySet
> xPropSet( xFrame
, UNO_QUERY_THROW
);
680 m_xLayoutManager
.set(
681 xPropSet
->getPropertyValue( "LayoutManager" ),
683 m_xLayoutManager
->lock();
686 catch( const Exception
& )
688 OSL_FAIL( "LayoutManagerLock::LayoutManagerLock: caught an exception!" );
692 inline ~LayoutManagerLock()
696 // unlock the layout manager
697 if ( m_xLayoutManager
.is() )
698 m_xLayoutManager
->unlock();
700 catch( const Exception
& )
702 OSL_FAIL( "LayoutManagerLock::~LayoutManagerLock: caught an exception!" );
708 void ODocumentDefinition::impl_initFormEditView( const Reference
< XController
>& _rxController
)
712 Reference
< XViewSettingsSupplier
> xSettingsSupplier( _rxController
, UNO_QUERY_THROW
);
713 Reference
< XPropertySet
> xViewSettings( xSettingsSupplier
->getViewSettings(), UNO_QUERY_THROW
);
715 // the below code could indirectly tamper with the "modified" flag of the model, temporarily disable this
716 LockModifiable
aLockModify( _rxController
->getModel() );
718 // The visual area size can be changed by the setting of the following properties
719 // so it should be restored later
720 PreserveVisualAreaSize
aPreserveVisAreaSize( _rxController
->getModel() );
722 // Layout manager should not layout while the size is still not restored
723 // so it will stay locked for this time
724 LayoutManagerLock
aLockLayout( _rxController
);
726 // setting of the visual properties
727 xViewSettings
->setPropertyValue("ShowRulers",makeAny(true));
728 xViewSettings
->setPropertyValue("ShowVertRuler",makeAny(true));
729 xViewSettings
->setPropertyValue("ShowHoriRuler",makeAny(true));
730 xViewSettings
->setPropertyValue("IsRasterVisible",makeAny(true));
731 xViewSettings
->setPropertyValue("IsSnapToRaster",makeAny(true));
732 xViewSettings
->setPropertyValue("ShowOnlineLayout",makeAny(true));
733 xViewSettings
->setPropertyValue("RasterSubdivisionX",makeAny(sal_Int32(5)));
734 xViewSettings
->setPropertyValue("RasterSubdivisionY",makeAny(sal_Int32(5)));
736 catch( const Exception
& )
738 DBG_UNHANDLED_EXCEPTION();
742 void ODocumentDefinition::impl_showOrHideComponent_throw( const bool i_bShow
)
744 const sal_Int32 nCurrentState
= m_xEmbeddedObject
.is() ? m_xEmbeddedObject
->getCurrentState() : EmbedStates::LOADED
;
745 switch ( nCurrentState
)
748 case EmbedStates::LOADED
:
749 throw embed::WrongStateException( OUString(), *this );
751 case EmbedStates::RUNNING
:
753 // fine, a running (and not yet active) object is never visible
756 LockModifiable
aLockModify( impl_getComponent_throw() );
757 m_xEmbeddedObject
->changeState( EmbedStates::ACTIVE
);
758 impl_onActivateEmbeddedObject_nothrow( false );
762 case EmbedStates::ACTIVE
:
764 Reference
< XModel
> xEmbeddedDoc( impl_getComponent_throw(), UNO_QUERY_THROW
);
765 Reference
< XController
> xEmbeddedController( xEmbeddedDoc
->getCurrentController(), UNO_SET_THROW
);
766 Reference
< XFrame
> xEmbeddedFrame( xEmbeddedController
->getFrame(), UNO_SET_THROW
);
767 Reference
< XWindow
> xEmbeddedWindow( xEmbeddedFrame
->getContainerWindow(), UNO_SET_THROW
);
768 xEmbeddedWindow
->setVisible( i_bShow
);
774 Any
ODocumentDefinition::onCommandOpenSomething( const Any
& _rOpenArgument
, const bool _bActivate
,
775 const Reference
< XCommandEnvironment
>& _rxEnvironment
)
777 OExecuteImpl
aExecuteGuard( m_bInExecute
);
779 Reference
< XConnection
> xConnection
;
780 sal_Int32 nOpenMode
= OpenMode::DOCUMENT
;
782 ::comphelper::NamedValueCollection aDocumentArgs
;
784 // for the document, default to the interaction handler as used for loading the DB doc
785 // This might be overwritten below, when examining _rOpenArgument.
786 const ::comphelper::NamedValueCollection
& aDBDocArgs( m_pImpl
->m_pDataSource
->getMediaDescriptor() );
787 Reference
< XInteractionHandler
> xHandler( aDBDocArgs
.getOrDefault( "InteractionHandler", Reference
< XInteractionHandler
>() ) );
789 aDocumentArgs
.put( "InteractionHandler", xHandler
);
791 ::boost::optional
< sal_Int16
> aDocumentMacroMode
;
793 if ( !lcl_extractOpenMode( _rOpenArgument
, nOpenMode
) )
795 Sequence
< PropertyValue
> aArguments
;
796 if ( _rOpenArgument
>>= aArguments
)
798 const PropertyValue
* pIter
= aArguments
.getConstArray();
799 const PropertyValue
* pEnd
= pIter
+ aArguments
.getLength();
800 for ( ;pIter
!= pEnd
; ++pIter
)
802 if ( pIter
->Name
== PROPERTY_ACTIVE_CONNECTION
)
804 xConnection
.set( pIter
->Value
, UNO_QUERY
);
808 if ( lcl_extractOpenMode( pIter
->Value
, nOpenMode
) )
811 if ( pIter
->Name
== "MacroExecutionMode" )
813 sal_Int16
nMacroExecMode( !aDocumentMacroMode
? MacroExecMode::USE_CONFIG
: *aDocumentMacroMode
);
814 OSL_VERIFY( pIter
->Value
>>= nMacroExecMode
);
815 aDocumentMacroMode
.reset( nMacroExecMode
);
819 // unknown argument -> pass to the loaded document
820 aDocumentArgs
.put( pIter
->Name
, pIter
->Value
);
825 bool bExecuteDBDocMacros
= m_pImpl
->m_pDataSource
->checkMacrosOnLoading();
826 // Note that this call implies the user might be asked for the macro execution mode.
827 // Normally, this would happen when the database document is loaded, and subsequent calls
828 // will simply use the user's decision from this point in time.
829 // However, it is possible to programmatically load forms/reports, without actually
830 // loading the database document into a frame. In this case, the user will be asked
834 // allow the command arguments to downgrade the macro execution mode, but not to upgrade
836 if ( ( m_pImpl
->m_pDataSource
->getImposedMacroExecMode() == MacroExecMode::USE_CONFIG
)
837 && bExecuteDBDocMacros
840 // while loading the whole database document, USE_CONFIG, was passed.
841 // Additionally, *by now* executing macros from the DB doc is allowed (this is what bExecuteDBDocMacros
842 // indicates). This means either one of:
843 // 1. The DB doc or one of the sub docs contained macros and
844 // 1a. the user explicitly allowed executing them
845 // 1b. the configuration allows executing them without asking the user
846 // 2. Neither the DB doc nor the sub docs contained macros, thus macro
847 // execution was silently enabled, assuming that any macro will be a
848 // user-created macro
850 // The problem with this: If the to-be-opened sub document has macros embedded in
851 // the content.xml (which is valid ODF, but normally not produced by OOo itself),
852 // then this has not been detected while loading the database document - it would
853 // be too expensive, as it effectively would require loading all forms/reports.
855 // So, in such a case, and with 2. above, we would silently execute those macros,
856 // regardless of the global security settings - which would be a security issue, of
858 if ( m_pImpl
->m_pDataSource
->determineEmbeddedMacros() == ODatabaseModelImpl::eNoMacros
)
860 // this is case 2. from above
861 // So, pass a USE_CONFIG to the to-be-loaded document. This means that
862 // the user will be prompted with a security message upon opening this
863 // sub document, in case the settings require this, *and* the document
864 // contains scripts in the content.xml. But this is better than the security
865 // issue we had before ...
866 aDocumentMacroMode
.reset( MacroExecMode::USE_CONFIG
);
870 if ( !aDocumentMacroMode
)
872 // nobody so far felt responsible for setting it
873 // => use the DBDoc-wide macro exec mode for the document, too
874 aDocumentMacroMode
.reset( bExecuteDBDocMacros
? MacroExecMode::ALWAYS_EXECUTE_NO_WARN
: MacroExecMode::NEVER_EXECUTE
);
876 aDocumentArgs
.put( "MacroExecutionMode", *aDocumentMacroMode
);
878 if ( ( nOpenMode
== OpenMode::ALL
)
879 || ( nOpenMode
== OpenMode::FOLDERS
)
880 || ( nOpenMode
== OpenMode::DOCUMENTS
)
881 || ( nOpenMode
== OpenMode::DOCUMENT_SHARE_DENY_NONE
)
882 || ( nOpenMode
== OpenMode::DOCUMENT_SHARE_DENY_WRITE
)
886 ucbhelper::cancelCommandExecution(
887 makeAny( UnsupportedOpenModeException(
889 static_cast< cppu::OWeakObject
* >( this ),
890 sal_Int16( nOpenMode
) ) ),
893 OSL_FAIL( "unreachable" );
896 OSL_ENSURE( !m_pImpl
->m_aProps
.sPersistentName
.isEmpty(),
897 "ODocumentDefinition::onCommandOpenSomething: no persistent name - cannot load!" );
898 if ( m_pImpl
->m_aProps
.sPersistentName
.isEmpty() )
901 // embedded objects themself do not support the hidden flag. We implement support for
902 // it by changing the STATE to RUNNING only, instead of ACTIVE.
903 bool bOpenHidden
= aDocumentArgs
.getOrDefault( "Hidden", false );
904 aDocumentArgs
.remove( "Hidden" );
906 loadEmbeddedObject( xConnection
, Sequence
< sal_Int8
>(), aDocumentArgs
.getPropertyValues(), false, !m_bOpenInDesign
);
907 OSL_ENSURE( m_xEmbeddedObject
.is(), "ODocumentDefinition::onCommandOpenSomething: what's this?" );
908 if ( !m_xEmbeddedObject
.is() )
911 Reference
< XModel
> xModel( getComponent(), UNO_QUERY
);
912 Reference
< report::XReportDefinition
> xReportDefinition(xModel
,UNO_QUERY
);
914 Reference
< XModule
> xModule( xModel
, UNO_QUERY
);
918 xModule
->setIdentifier( "com.sun.star.sdb.FormDesign" );
919 else if ( !xReportDefinition
.is() )
920 xModule
->setIdentifier( "com.sun.star.text.TextDocument" );
922 updateDocumentTitle();
925 bool bIsAliveNewStyleReport
= ( !m_bOpenInDesign
&& xReportDefinition
.is() );
926 if ( bIsAliveNewStyleReport
)
928 // we are in ReadOnly mode
929 // we would like to open the Writer or Calc with the report direct, without design it.
930 Reference
< report::XReportEngine
> xReportEngine( m_aContext
->getServiceManager()->createInstanceWithContext("com.sun.star.comp.report.OReportEngineJFree", m_aContext
), UNO_QUERY_THROW
);
932 xReportEngine
->setReportDefinition(xReportDefinition
);
933 xReportEngine
->setActiveConnection(m_xLastKnownConnection
);
935 return makeAny( xReportEngine
->createDocumentModel() );
936 return makeAny( xReportEngine
->createDocumentAlive( nullptr ) );
939 if ( _bActivate
&& !bOpenHidden
)
941 LockModifiable
aLockModify( impl_getComponent_throw() );
942 m_xEmbeddedObject
->changeState( EmbedStates::ACTIVE
);
943 impl_onActivateEmbeddedObject_nothrow( false );
947 // ensure that we ourself are kept alive as long as the document is open
948 LifetimeCoupler::couple( *this, xModel
.get() );
951 if ( !m_bForm
&& m_pImpl
->m_aProps
.bAsTemplate
&& !m_bOpenInDesign
)
952 ODocumentDefinition::fillReportData( m_aContext
, getComponent(), xConnection
);
954 return makeAny( xModel
);
957 Any SAL_CALL
ODocumentDefinition::execute( const Command
& aCommand
, sal_Int32 CommandId
, const Reference
< XCommandEnvironment
>& Environment
) throw (Exception
, CommandAbortedException
, RuntimeException
, std::exception
)
961 bool bOpen
= aCommand
.Name
== "open";
962 bool bOpenInDesign
= aCommand
.Name
== "openDesign";
963 bool bOpenForMail
= aCommand
.Name
== "openForMail";
964 if ( bOpen
|| bOpenInDesign
|| bOpenForMail
)
966 // opening the document involves a lot of VCL code, which is not thread-safe, but needs the SolarMutex locked.
967 // Unfortunately, the DocumentDefinition, as well as the EmbeddedObject implementation, calls into VCL-dependent
968 // components *without* releasing the own mutex, which is a guaranteed recipe for deadlocks.
969 // We have control over this implementation here, and in modifying it to release the own mutex before calling into
970 // the VCL-dependent components is not too difficult (was there, seen it).
971 // However, we do /not/ have control over the EmbeddedObject implementation, and from a first look, it seems as
972 // making it release the own mutex before calling SolarMutex-code is ... difficult, at least.
973 // So, to be on the same side, we lock the SolarMutex here. Yes, it sucks.
974 ::SolarMutexGuard aSolarGuard
;
975 ::osl::ClearableMutexGuard
aGuard(m_aMutex
);
979 bool bActivateObject
= true;
982 OSL_FAIL( "ODocumentDefinition::execute: 'openForMail' should not be used anymore - use the 'Hidden' parameter instead!" );
983 bActivateObject
= false;
986 // if the object is already opened, do nothing
987 if ( m_xEmbeddedObject
.is() )
989 sal_Int32 nCurrentState
= m_xEmbeddedObject
->getCurrentState();
990 bool bIsActive
= ( nCurrentState
== EmbedStates::ACTIVE
);
994 // exception: new-style reports always create a new document when "open" is executed
995 Reference
< report::XReportDefinition
> xReportDefinition( impl_getComponent_throw( false ), UNO_QUERY
);
996 bool bIsAliveNewStyleReport
= ( xReportDefinition
.is() && ( bOpen
|| bOpenForMail
) );
998 if ( !bIsAliveNewStyleReport
)
1000 impl_onActivateEmbeddedObject_nothrow( true );
1001 return makeAny( getComponent() );
1006 m_bOpenInDesign
= bOpenInDesign
|| bOpenForMail
;
1007 return onCommandOpenSomething( aCommand
.Argument
, bActivateObject
, Environment
);
1010 ::osl::ClearableMutexGuard
aGuard(m_aMutex
);
1014 if ( aCommand
.Name
== "copyTo" )
1017 aCommand
.Argument
>>= aIni
;
1018 if ( aIni
.getLength() != 2 )
1020 OSL_FAIL( "Wrong argument type!" );
1021 ucbhelper::cancelCommandExecution(
1022 makeAny( IllegalArgumentException(
1024 static_cast< cppu::OWeakObject
* >( this ),
1029 Reference
< XStorage
> xDest(aIni
[0],UNO_QUERY
);
1030 OUString sPersistentName
;
1031 aIni
[1] >>= sPersistentName
;
1032 Reference
< XStorage
> xStorage
= getContainerStorage();
1034 xStorage
->copyElementTo(m_pImpl
->m_aProps
.sPersistentName
,xDest
,sPersistentName
);
1036 else if ( aCommand
.Name
== "preview" )
1038 onCommandPreview(aRet
);
1040 else if ( aCommand
.Name
== "insert" )
1043 aCommand
.Argument
>>= aIni
;
1044 if ( !aIni
.getLength() )
1046 OSL_FAIL( "Wrong argument count!" );
1047 ucbhelper::cancelCommandExecution(
1048 makeAny( IllegalArgumentException(
1050 static_cast< cppu::OWeakObject
* >( this ),
1057 onCommandInsert( sURL
, Environment
);
1059 else if ( aCommand
.Name
== "getdocumentinfo" // compatibility
1060 || aCommand
.Name
== "getDocumentInfo" )
1062 onCommandGetDocumentProperties( aRet
);
1064 else if ( aCommand
.Name
== "delete" )
1068 Reference
< XStorage
> xStorage
= getContainerStorage();
1069 if ( xStorage
.is() )
1070 xStorage
->removeElement(m_pImpl
->m_aProps
.sPersistentName
);
1075 else if ( aCommand
.Name
== "storeOwn" // compatibility
1076 || aCommand
.Name
== "store"
1081 else if ( aCommand
.Name
== "shutdown" // compatibility
1082 || aCommand
.Name
== "close"
1085 aRet
<<= impl_close_throw();
1087 else if ( aCommand
.Name
== "show" )
1089 impl_showOrHideComponent_throw( true );
1091 else if ( aCommand
.Name
== "hide" )
1093 impl_showOrHideComponent_throw( false );
1097 aRet
= OContentHelper::execute(aCommand
,CommandId
,Environment
);
1105 void lcl_resetChildFormsToEmptyDataSource( const Reference
< XIndexAccess
>& _rxFormsContainer
)
1107 OSL_PRECOND( _rxFormsContainer
.is(), "lcl_resetChildFormsToEmptyDataSource: illegal call!" );
1108 sal_Int32 count
= _rxFormsContainer
->getCount();
1109 for ( sal_Int32 i
= 0; i
< count
; ++i
)
1111 Reference
< XForm
> xForm( _rxFormsContainer
->getByIndex( i
), UNO_QUERY
);
1115 // if the element is a form, reset its DataSourceName property to an empty string
1118 Reference
< XPropertySet
> xFormProps( xForm
, UNO_QUERY_THROW
);
1119 xFormProps
->setPropertyValue( PROPERTY_DATASOURCENAME
, makeAny( OUString() ) );
1121 catch( const Exception
& )
1123 DBG_UNHANDLED_EXCEPTION();
1126 // if the element is a container itself, step down the component hierarchy
1127 Reference
< XIndexAccess
> xContainer( xForm
, UNO_QUERY
);
1128 if ( xContainer
.is() )
1129 lcl_resetChildFormsToEmptyDataSource( xContainer
);
1133 void lcl_resetFormsToEmptyDataSource( const Reference
< XEmbeddedObject
>& _rxEmbeddedObject
)
1137 Reference
< XDrawPageSupplier
> xSuppPage( _rxEmbeddedObject
->getComponent(), UNO_QUERY_THROW
);
1138 // if this interface does not exist, then either getComponent returned NULL,
1139 // or the document is a multi-page document. The latter is allowed, but currently
1140 // simply not handled by this code, as it would not normally happen.
1142 Reference
< XFormsSupplier
> xSuppForms( xSuppPage
->getDrawPage(), UNO_QUERY_THROW
);
1143 Reference
< XIndexAccess
> xForms( xSuppForms
->getForms(), UNO_QUERY_THROW
);
1144 lcl_resetChildFormsToEmptyDataSource( xForms
);
1146 catch( const Exception
& )
1148 DBG_UNHANDLED_EXCEPTION();
1154 void ODocumentDefinition::onCommandInsert( const OUString
& _sURL
, const Reference
< XCommandEnvironment
>& Environment
)
1157 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1159 // Check, if all required properties were set.
1160 if ( _sURL
.isEmpty() || m_xEmbeddedObject
.is() )
1162 OSL_FAIL( "Content::onCommandInsert - property value missing!" );
1164 Sequence
<OUString
> aProps
{ PROPERTY_URL
};
1165 ucbhelper::cancelCommandExecution(
1166 makeAny( MissingPropertiesException(
1168 static_cast< cppu::OWeakObject
* >( this ),
1174 if ( !m_xEmbeddedObject
.is() )
1176 Reference
< XStorage
> xStorage
= getContainerStorage();
1177 if ( xStorage
.is() )
1179 Reference
< XEmbeddedObjectCreator
> xEmbedFactory
= EmbeddedObjectCreator::create(m_aContext
);
1180 Sequence
<PropertyValue
> aEmpty
,aMediaDesc(1);
1181 aMediaDesc
[0].Name
= PROPERTY_URL
;
1182 aMediaDesc
[0].Value
<<= _sURL
;
1183 m_xEmbeddedObject
.set(xEmbedFactory
->createInstanceInitFromMediaDescriptor( xStorage
1184 ,m_pImpl
->m_aProps
.sPersistentName
1186 ,aEmpty
),UNO_QUERY
);
1188 lcl_resetFormsToEmptyDataSource( m_xEmbeddedObject
);
1191 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1192 if ( xPersist
.is() )
1194 xPersist
->storeOwn();
1198 Reference
< css::util::XCloseable
> xCloseable(m_xEmbeddedObject
,UNO_QUERY
);
1199 if ( xCloseable
.is() )
1200 xCloseable
->close(true);
1202 catch(const Exception
&)
1205 m_xEmbeddedObject
= nullptr;
1212 bool ODocumentDefinition::save(bool _bApprove
)
1214 // default handling: instantiate an interaction handler and let it handle the parameter request
1215 if ( !m_bOpenInDesign
)
1221 ::SolarMutexGuard aSolarGuard
;
1224 Reference
<XNameAccess
> xName(m_xParentContainer
,UNO_QUERY
);
1225 DocumentSaveRequest aRequest
;
1226 aRequest
.Name
= m_pImpl
->m_aProps
.aTitle
;
1227 if ( aRequest
.Name
.isEmpty() )
1230 aRequest
.Name
= DBACORE_RESSTRING( RID_STR_FORM
);
1232 aRequest
.Name
= DBACORE_RESSTRING( RID_STR_REPORT
);
1233 aRequest
.Name
= ::dbtools::createUniqueName(xName
,aRequest
.Name
);
1236 aRequest
.Content
.set(m_xParentContainer
,UNO_QUERY
);
1237 OInteractionRequest
* pRequest
= new OInteractionRequest(makeAny(aRequest
));
1238 Reference
< XInteractionRequest
> xRequest(pRequest
);
1240 // two continuations allowed: OK and Cancel
1241 ODocumentSaveContinuation
* pDocuSave
= nullptr;
1243 if ( m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1245 pDocuSave
= new ODocumentSaveContinuation
;
1246 pRequest
->addContinuation(pDocuSave
);
1250 OInteraction
< XInteractionApprove
>* pApprove
= new OInteraction
< XInteractionApprove
>;
1251 pRequest
->addContinuation(pApprove
);
1254 OInteraction
< XInteractionDisapprove
>* pDisApprove
= new OInteraction
< XInteractionDisapprove
>;
1255 pRequest
->addContinuation(pDisApprove
);
1257 OInteractionAbort
* pAbort
= new OInteractionAbort
;
1258 pRequest
->addContinuation(pAbort
);
1260 // create the handler, let it handle the request
1261 Reference
< XInteractionHandler2
> xHandler( InteractionHandler::createWithParent(m_aContext
, nullptr) );
1262 xHandler
->handle(xRequest
);
1264 if ( pAbort
->wasSelected() )
1266 if ( pDisApprove
->wasSelected() )
1268 if ( pDocuSave
&& pDocuSave
->wasSelected() )
1270 Reference
<XNameContainer
> xNC( pDocuSave
->getContent(), UNO_QUERY_THROW
);
1272 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
1273 NameChangeNotifier
aNameChangeAndNotify( *this, pDocuSave
->getName(), aGuard
);
1274 m_pImpl
->m_aProps
.aTitle
= pDocuSave
->getName();
1276 Reference
< XContent
> xContent
= this;
1277 xNC
->insertByName(pDocuSave
->getName(),makeAny(xContent
));
1279 updateDocumentTitle();
1283 ::osl::MutexGuard
aGuard(m_aMutex
);
1284 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1285 if ( xPersist
.is() )
1287 xPersist
->storeOwn();
1288 notifyDataSourceModified();
1291 catch(const Exception
&)
1293 OSL_FAIL("ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1298 void ODocumentDefinition::saveAs()
1300 // default handling: instantiate an interaction handler and let it handle the parameter request
1301 if ( !m_bOpenInDesign
)
1305 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1306 if ( m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1309 save(false); // (sal_False) : we don't want an approve dialog
1316 ::SolarMutexGuard aSolarGuard
;
1319 Reference
<XNameAccess
> xName(m_xParentContainer
,UNO_QUERY
);
1320 DocumentSaveRequest aRequest
;
1321 aRequest
.Name
= m_pImpl
->m_aProps
.aTitle
;
1323 aRequest
.Content
.set(m_xParentContainer
,UNO_QUERY
);
1324 OInteractionRequest
* pRequest
= new OInteractionRequest(makeAny(aRequest
));
1325 Reference
< XInteractionRequest
> xRequest(pRequest
);
1327 // two continuations allowed: OK and Cancel
1328 ODocumentSaveContinuation
* pDocuSave
= new ODocumentSaveContinuation
;
1329 pRequest
->addContinuation(pDocuSave
);
1330 OInteraction
< XInteractionDisapprove
>* pDisApprove
= new OInteraction
< XInteractionDisapprove
>;
1331 pRequest
->addContinuation(pDisApprove
);
1332 OInteractionAbort
* pAbort
= new OInteractionAbort
;
1333 pRequest
->addContinuation(pAbort
);
1335 // create the handler, let it handle the request
1336 Reference
< XInteractionHandler2
> xHandler( InteractionHandler::createWithParent(m_aContext
, nullptr) );
1337 xHandler
->handle(xRequest
);
1339 if ( pAbort
->wasSelected() )
1341 if ( pDisApprove
->wasSelected() )
1343 if ( pDocuSave
->wasSelected() )
1345 ::osl::MutexGuard
aGuard(m_aMutex
);
1346 Reference
<XNameContainer
> xNC(pDocuSave
->getContent(),UNO_QUERY
);
1349 if ( m_pImpl
->m_aProps
.aTitle
!= pDocuSave
->getName() )
1353 Reference
< XStorage
> xStorage
= getContainerStorage();
1355 OUString sPersistentName
= ::dbtools::createUniqueName(xStorage
,"Obj");
1356 xStorage
->copyElementTo(m_pImpl
->m_aProps
.sPersistentName
,xStorage
,sPersistentName
);
1358 OUString sOldName
= m_pImpl
->m_aProps
.aTitle
;
1359 rename(pDocuSave
->getName());
1360 updateDocumentTitle();
1362 Sequence
< Any
> aArguments(3);
1363 PropertyValue aValue
;
1365 aValue
.Name
= PROPERTY_NAME
;
1366 aValue
.Value
<<= sOldName
;
1367 aArguments
[0] <<= aValue
;
1369 aValue
.Name
= PROPERTY_PERSISTENT_NAME
;
1370 aValue
.Value
<<= sPersistentName
;
1371 aArguments
[1] <<= aValue
;
1373 aValue
.Name
= PROPERTY_AS_TEMPLATE
;
1374 aValue
.Value
<<= m_pImpl
->m_aProps
.bAsTemplate
;
1375 aArguments
[2] <<= aValue
;
1377 Reference
< XMultiServiceFactory
> xORB( m_xParentContainer
, UNO_QUERY_THROW
);
1378 Reference
< XInterface
> xComponent( xORB
->createInstanceWithArguments( SERVICE_SDB_DOCUMENTDEFINITION
, aArguments
) );
1379 Reference
< XNameContainer
> xNameContainer( m_xParentContainer
, UNO_QUERY_THROW
);
1380 xNameContainer
->insertByName( sOldName
, makeAny( xComponent
) );
1382 catch(const Exception
&)
1384 DBG_UNHANDLED_EXCEPTION();
1387 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1388 if ( xPersist
.is() )
1390 xPersist
->storeOwn();
1391 notifyDataSourceModified();
1398 catch(const Exception
&)
1400 OSL_FAIL("ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1406 void lcl_putLoadArgs( ::comphelper::NamedValueCollection
& _io_rArgs
, const optional_bool
& _bSuppressMacros
, const optional_bool
& _bReadOnly
)
1408 if ( !!_bSuppressMacros
)
1410 if ( *_bSuppressMacros
)
1412 // if we're to suppress macros, do exactly this
1413 _io_rArgs
.put( "MacroExecutionMode", MacroExecMode::NEVER_EXECUTE
);
1417 // otherwise, put the setting only if not already present
1418 if ( !_io_rArgs
.has( "MacroExecutionMode" ) )
1420 _io_rArgs
.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG
);
1426 _io_rArgs
.put( "ReadOnly", *_bReadOnly
);
1432 Reference
< XFrame
> lcl_getDatabaseDocumentFrame( ODatabaseModelImpl
& _rImpl
)
1434 Reference
< XModel
> xDatabaseDocumentModel( _rImpl
.getModel_noCreate() );
1436 Reference
< XController
> xDatabaseDocumentController
;
1437 if ( xDatabaseDocumentModel
.is() )
1438 xDatabaseDocumentController
= xDatabaseDocumentModel
->getCurrentController();
1440 Reference
< XFrame
> xFrame
;
1441 if ( xDatabaseDocumentController
.is() )
1442 xFrame
= xDatabaseDocumentController
->getFrame();
1448 bool ODocumentDefinition::objectSupportsEmbeddedScripts() const
1450 bool bAllowDocumentMacros
= !m_pImpl
->m_pDataSource
1451 || ( m_pImpl
->m_pDataSource
->determineEmbeddedMacros() == ODatabaseModelImpl::eSubDocumentMacros
);
1453 // if *any* of the objects of the database document already has macros, we
1454 // continue to allow it to have them, until the user does a migration.
1455 // If there are no macros, we don't allow them to be created.
1457 return bAllowDocumentMacros
;
1460 OUString
ODocumentDefinition::determineContentType() const
1462 return lcl_determineContentType_nothrow( getContainerStorage(), m_pImpl
->m_aProps
.sPersistentName
);
1465 void ODocumentDefinition::separateOpenCommandArguments( const Sequence
< PropertyValue
>& i_rOpenCommandArguments
,
1466 ::comphelper::NamedValueCollection
& o_rDocumentLoadArgs
, ::comphelper::NamedValueCollection
& o_rEmbeddedObjectDescriptor
)
1468 ::comphelper::NamedValueCollection
aOpenCommandArguments( i_rOpenCommandArguments
);
1470 const char* pObjectDescriptorArgs
[] =
1474 for (const char* pObjectDescriptorArg
: pObjectDescriptorArgs
)
1476 if ( aOpenCommandArguments
.has( pObjectDescriptorArg
) )
1478 o_rEmbeddedObjectDescriptor
.put( pObjectDescriptorArg
, aOpenCommandArguments
.get( pObjectDescriptorArg
) );
1479 aOpenCommandArguments
.remove( pObjectDescriptorArg
);
1483 o_rDocumentLoadArgs
.merge( aOpenCommandArguments
, false );
1486 Sequence
< PropertyValue
> ODocumentDefinition::fillLoadArgs( const Reference
< XConnection
>& _xConnection
, const bool _bSuppressMacros
, const bool _bReadOnly
,
1487 const Sequence
< PropertyValue
>& i_rOpenCommandArguments
, Sequence
< PropertyValue
>& _out_rEmbeddedObjectDescriptor
)
1489 // (re-)create interceptor, and put it into the descriptor of the embedded object
1490 if ( m_pInterceptor
.is() )
1492 m_pInterceptor
->dispose();
1493 m_pInterceptor
.clear();
1496 m_pInterceptor
= new OInterceptor( this );
1497 Reference
<XDispatchProviderInterceptor
> xInterceptor
= m_pInterceptor
.get();
1499 ::comphelper::NamedValueCollection aEmbeddedDescriptor
;
1500 aEmbeddedDescriptor
.put( "OutplaceDispatchInterceptor", xInterceptor
);
1502 ::comphelper::NamedValueCollection aMediaDesc
;
1503 separateOpenCommandArguments( i_rOpenCommandArguments
, aMediaDesc
, aEmbeddedDescriptor
);
1505 // create the OutplaceFrameProperties, and put them into the descriptor of the embedded object
1506 ::comphelper::NamedValueCollection OutplaceFrameProperties
;
1507 OutplaceFrameProperties
.put( "TopWindow", true );
1508 OutplaceFrameProperties
.put( "SupportPersistentWindowState", true );
1510 Reference
< XFrame
> xParentFrame
;
1511 if ( m_pImpl
->m_pDataSource
)
1512 xParentFrame
= lcl_getDatabaseDocumentFrame( *m_pImpl
->m_pDataSource
);
1513 if ( !xParentFrame
.is() )
1514 { // i87957 we need a parent frame
1515 Reference
< XDesktop2
> xDesktop
= Desktop::create( m_aContext
);
1516 xParentFrame
.set( xDesktop
, UNO_QUERY_THROW
);
1517 Reference
<util::XCloseable
> xCloseable(m_pImpl
->m_pDataSource
->getModel_noCreate(),UNO_QUERY
);
1518 if ( xCloseable
.is() )
1520 xCloseable
->addCloseListener(this);
1521 m_bRemoveListener
= true;
1524 OSL_ENSURE( xParentFrame
.is(), "ODocumentDefinition::fillLoadArgs: no parent frame!" );
1525 if ( xParentFrame
.is() )
1526 OutplaceFrameProperties
.put( "ParentFrame", xParentFrame
);
1528 aEmbeddedDescriptor
.put( "OutplaceFrameProperties", OutplaceFrameProperties
.getNamedValues() );
1530 // tell the embedded object to have (or not have) script support
1531 aEmbeddedDescriptor
.put( "EmbeddedScriptSupport", objectSupportsEmbeddedScripts() );
1533 // tell the embedded object to not participate in the document recovery game - the DB doc will handle it
1534 aEmbeddedDescriptor
.put( "DocumentRecoverySupport", false );
1536 // pass the descriptor of the embedded object to the caller
1537 aEmbeddedDescriptor
>>= _out_rEmbeddedObjectDescriptor
;
1539 // create the ComponentData, and put it into the document's media descriptor
1541 ::comphelper::NamedValueCollection aComponentData
;
1542 aComponentData
.put( "ActiveConnection", _xConnection
);
1543 aComponentData
.put( "ApplyFormDesignMode", !_bReadOnly
);
1544 aMediaDesc
.put( "ComponentData", aComponentData
.getPropertyValues() );
1547 if ( !m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1548 aMediaDesc
.put( "DocumentTitle", m_pImpl
->m_aProps
.aTitle
);
1550 aMediaDesc
.put( "DocumentBaseURL", m_pImpl
->m_pDataSource
->getURL() );
1552 // put the common load arguments into the document's media descriptor
1553 lcl_putLoadArgs( aMediaDesc
, optional_bool( _bSuppressMacros
), optional_bool( _bReadOnly
) );
1555 return aMediaDesc
.getPropertyValues();
1558 void ODocumentDefinition::loadEmbeddedObject( const Reference
< XConnection
>& i_rConnection
, const Sequence
< sal_Int8
>& _aClassID
,
1559 const Sequence
< PropertyValue
>& i_rOpenCommandArguments
, const bool _bSuppressMacros
, const bool _bReadOnly
)
1561 if ( !m_xEmbeddedObject
.is() )
1563 Reference
< XStorage
> xStorage
= getContainerStorage();
1564 if ( xStorage
.is() )
1566 Reference
< XEmbeddedObjectCreator
> xEmbedFactory
= OOoEmbeddedObjectFactory::create(m_aContext
);
1567 OUString sDocumentService
;
1568 bool bSetSize
= false;
1569 sal_Int32 nEntryConnectionMode
= EntryInitModes::DEFAULT_INIT
;
1570 Sequence
< sal_Int8
> aClassID
= _aClassID
;
1571 if ( aClassID
.getLength() )
1573 nEntryConnectionMode
= EntryInitModes::TRUNCATE_INIT
;
1578 sDocumentService
= GetDocumentServiceFromMediaType( getContentType(), m_aContext
, aClassID
);
1579 // check if we are not a form and
1580 // the org.libreoffice.report.pentaho.SOReportJobFactory is not present.
1581 if ( !m_bForm
&& !(sDocumentService
== "com.sun.star.text.TextDocument"))
1583 // we seem to be a "new style" report, check if report extension is present.
1584 Reference
< XContentEnumerationAccess
> xEnumAccess( m_aContext
->getServiceManager(), UNO_QUERY
);
1585 const OUString sReportEngineServiceName
= ::dbtools::getDefaultReportEngineServiceName(m_aContext
);
1586 Reference
< XEnumeration
> xEnumDrivers
= xEnumAccess
->createContentEnumeration(sReportEngineServiceName
);
1587 if ( !xEnumDrivers
.is() || !xEnumDrivers
->hasMoreElements() )
1589 css::io::WrongFormatException aWFE
;
1590 aWFE
.Message
= DBACORE_RESSTRING( RID_STR_MISSING_EXTENSION
);
1594 if ( !aClassID
.getLength() )
1597 aClassID
= MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID
);
1600 aClassID
= MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90
);
1605 OSL_ENSURE( aClassID
.getLength(),"No Class ID" );
1607 Sequence
< PropertyValue
> aEmbeddedObjectDescriptor
;
1608 Sequence
< PropertyValue
> aLoadArgs( fillLoadArgs(
1609 i_rConnection
, _bSuppressMacros
, _bReadOnly
, i_rOpenCommandArguments
, aEmbeddedObjectDescriptor
) );
1611 m_xEmbeddedObject
.set(xEmbedFactory
->createInstanceUserInit(aClassID
1614 ,m_pImpl
->m_aProps
.sPersistentName
1615 ,nEntryConnectionMode
1617 ,aEmbeddedObjectDescriptor
1619 if ( m_xEmbeddedObject
.is() )
1621 if ( !m_pClientHelper
.is() )
1623 m_pClientHelper
= new OEmbeddedClientHelper(this);
1625 Reference
<XEmbeddedClient
> xClient
= m_pClientHelper
.get();
1626 m_xEmbeddedObject
->setClientSite(xClient
);
1627 m_xEmbeddedObject
->changeState(EmbedStates::RUNNING
);
1630 LockModifiable
aLockModify( impl_getComponent_throw( false ) );
1632 awt::Size
aSize( DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
1633 m_xEmbeddedObject
->setVisualAreaSize(Aspects::MSOLE_CONTENT
,aSize
);
1640 sal_Int32 nCurrentState
= m_xEmbeddedObject
->getCurrentState();
1641 if ( nCurrentState
== EmbedStates::LOADED
)
1643 if ( !m_pClientHelper
.is() )
1645 m_pClientHelper
= new OEmbeddedClientHelper(this);
1647 Reference
<XEmbeddedClient
> xClient
= m_pClientHelper
.get();
1648 m_xEmbeddedObject
->setClientSite(xClient
);
1650 Sequence
< PropertyValue
> aEmbeddedObjectDescriptor
;
1651 Sequence
< PropertyValue
> aLoadArgs( fillLoadArgs(
1652 i_rConnection
, _bSuppressMacros
, _bReadOnly
, i_rOpenCommandArguments
, aEmbeddedObjectDescriptor
) );
1654 Reference
<XCommonEmbedPersist
> xCommon(m_xEmbeddedObject
,UNO_QUERY
);
1655 OSL_ENSURE(xCommon
.is(),"unsupported interface!");
1657 xCommon
->reload( aLoadArgs
, aEmbeddedObjectDescriptor
);
1658 m_xEmbeddedObject
->changeState(EmbedStates::RUNNING
);
1662 OSL_ENSURE( ( nCurrentState
== EmbedStates::RUNNING
) || ( nCurrentState
== EmbedStates::ACTIVE
),
1663 "ODocumentDefinition::loadEmbeddedObject: unexpected state!" );
1665 // if the document was already loaded (which means the embedded object is in state RUNNING or ACTIVE),
1666 // then just re-set some model parameters
1669 // ensure the media descriptor doesn't contain any values which are intended for the
1670 // EmbeddedObjectDescriptor only
1671 ::comphelper::NamedValueCollection aEmbeddedObjectDescriptor
;
1672 ::comphelper::NamedValueCollection aNewMediaDesc
;
1673 separateOpenCommandArguments( i_rOpenCommandArguments
, aNewMediaDesc
, aEmbeddedObjectDescriptor
);
1675 // merge the new media descriptor into the existing media descriptor
1676 const Reference
< XModel
> xModel( getComponent(), UNO_QUERY_THROW
);
1677 const Sequence
< PropertyValue
> aArgs
= xModel
->getArgs();
1678 ::comphelper::NamedValueCollection
aExistentMediaDesc( aArgs
);
1679 aExistentMediaDesc
.merge( aNewMediaDesc
, false );
1681 lcl_putLoadArgs( aExistentMediaDesc
, optional_bool(), optional_bool() );
1682 // don't put _bSuppressMacros and _bReadOnly here - if the document was already
1683 // loaded, we should not tamper with its settings.
1684 // #i88977# #i86872#
1686 xModel
->attachResource( xModel
->getURL(), aExistentMediaDesc
.getPropertyValues() );
1688 catch( const Exception
& )
1690 DBG_UNHANDLED_EXCEPTION();
1695 // set the OfficeDatabaseDocument instance as parent of the embedded document
1697 Reference
< XChild
> xDepdendDocAsChild( getComponent(), UNO_QUERY
);
1698 if ( xDepdendDocAsChild
.is() )
1702 if ( !xDepdendDocAsChild
->getParent().is() )
1703 { // first encounter
1704 xDepdendDocAsChild
->setParent( getDataSource( m_xParentContainer
) );
1707 catch( const Exception
& )
1709 DBG_UNHANDLED_EXCEPTION();
1713 if ( i_rConnection
.is() )
1714 m_xLastKnownConnection
= i_rConnection
;
1717 void ODocumentDefinition::onCommandPreview(Any
& _rImage
)
1719 loadEmbeddedObjectForPreview();
1720 if ( m_xEmbeddedObject
.is() )
1724 Reference
<XTransferable
> xTransfer(getComponent(),UNO_QUERY
);
1725 if ( xTransfer
.is() )
1728 aFlavor
.MimeType
= "image/png";
1729 aFlavor
.HumanPresentableName
= "Portable Network Graphics";
1730 aFlavor
.DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
1732 _rImage
= xTransfer
->getTransferData( aFlavor
);
1735 catch( const Exception
& )
1741 void ODocumentDefinition::getPropertyDefaultByHandle( sal_Int32
/*_nHandle*/, Any
& _rDefault
) const
1746 void ODocumentDefinition::onCommandGetDocumentProperties( Any
& _rProps
)
1748 loadEmbeddedObjectForPreview();
1749 if ( m_xEmbeddedObject
.is() )
1753 Reference
<XDocumentPropertiesSupplier
> xDocSup(
1754 getComponent(), UNO_QUERY
);
1756 _rProps
<<= xDocSup
->getDocumentProperties();
1758 catch( const Exception
& )
1760 DBG_UNHANDLED_EXCEPTION();
1765 Reference
< util::XCloseable
> ODocumentDefinition::impl_getComponent_throw( const bool i_ForceCreate
)
1767 OSL_ENSURE(m_xEmbeddedObject
.is(),"Illegal call for embeddedObject");
1768 Reference
< util::XCloseable
> xComp
;
1769 if ( m_xEmbeddedObject
.is() )
1771 int nState
= m_xEmbeddedObject
->getCurrentState();
1772 if ( ( nState
== EmbedStates::LOADED
) && i_ForceCreate
)
1774 m_xEmbeddedObject
->changeState( EmbedStates::RUNNING
);
1775 nState
= m_xEmbeddedObject
->getCurrentState();
1776 OSL_ENSURE( nState
== EmbedStates::RUNNING
, "ODocumentDefinition::impl_getComponent_throw: could not switch to RUNNING!" );
1779 if ( nState
== EmbedStates::ACTIVE
|| nState
== EmbedStates::RUNNING
)
1781 Reference
<XComponentSupplier
> xCompProv(m_xEmbeddedObject
,UNO_QUERY
);
1782 if ( xCompProv
.is() )
1784 xComp
= xCompProv
->getComponent();
1785 OSL_ENSURE(xComp
.is(),"No valid component");
1792 Reference
< util::XCloseable
> ODocumentDefinition::getComponent() throw (RuntimeException
, std::exception
)
1794 ::osl::MutexGuard
aGuard( m_aMutex
);
1795 return impl_getComponent_throw();
1800 Reference
< XDatabaseDocumentUI
> lcl_getDatabaseDocumentUI( ODatabaseModelImpl
& _rModelImpl
)
1802 Reference
< XDatabaseDocumentUI
> xUI
;
1804 Reference
< XModel
> xModel( _rModelImpl
.getModel_noCreate() );
1806 xUI
.set( xModel
->getCurrentController(), UNO_QUERY
);
1811 Reference
< XComponent
> ODocumentDefinition::impl_openUI_nolck_throw( bool _bForEditing
)
1813 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
1814 if ( !m_pImpl
|| !m_pImpl
->m_pDataSource
)
1815 throw DisposedException();
1817 Reference
< XComponent
> xComponent
;
1820 Reference
< XDatabaseDocumentUI
> xUI( lcl_getDatabaseDocumentUI( *m_pImpl
->m_pDataSource
) );
1823 // no XDatabaseDocumentUI -> just execute the respective command
1824 m_bOpenInDesign
= _bForEditing
;
1825 xComponent
= Reference
<XComponent
>(onCommandOpenSomething(Any(), true, nullptr), UNO_QUERY
);
1826 OSL_ENSURE( xComponent
.is(), "ODocumentDefinition::impl_openUI_nolck_throw: opening the thingie failed." );
1831 OUString
sName( impl_getHierarchicalName( false ) );
1832 sal_Int32 nObjectType
= m_bForm
? DatabaseObject::FORM
: DatabaseObject::REPORT
;
1835 xComponent
= xUI
->loadComponent(
1836 nObjectType
, sName
, _bForEditing
1839 catch( const RuntimeException
& ) { throw; }
1840 catch( const Exception
& )
1842 throw WrappedTargetException(
1843 OUString(), *this, ::cppu::getCaughtException() );
1849 void ODocumentDefinition::impl_store_throw()
1851 Reference
<XEmbedPersist
> xPersist( m_xEmbeddedObject
, UNO_QUERY
);
1852 if ( xPersist
.is() )
1854 xPersist
->storeOwn();
1855 notifyDataSourceModified();
1859 bool ODocumentDefinition::impl_close_throw()
1861 bool bSuccess
= prepareClose();
1862 if ( bSuccess
&& m_xEmbeddedObject
.is() )
1864 m_xEmbeddedObject
->changeState( EmbedStates::LOADED
);
1865 bSuccess
= m_xEmbeddedObject
->getCurrentState() == EmbedStates::LOADED
;
1870 Reference
< XComponent
> SAL_CALL
ODocumentDefinition::open( ) throw (WrappedTargetException
, RuntimeException
, std::exception
)
1872 return impl_openUI_nolck_throw( false );
1875 Reference
< XComponent
> SAL_CALL
ODocumentDefinition::openDesign( ) throw (WrappedTargetException
, RuntimeException
, std::exception
)
1877 return impl_openUI_nolck_throw( true );
1880 void SAL_CALL
ODocumentDefinition::store( ) throw (WrappedTargetException
, RuntimeException
, std::exception
)
1882 ::osl::MutexGuard
aGuard( m_aMutex
);
1887 catch( const RuntimeException
& ) { throw; }
1888 catch( const Exception
& )
1890 throw WrappedTargetException(
1891 OUString(), *this, ::cppu::getCaughtException() );
1895 sal_Bool SAL_CALL
ODocumentDefinition::close( ) throw (WrappedTargetException
, RuntimeException
, std::exception
)
1897 ::osl::MutexGuard
aGuard( m_aMutex
);
1899 bool bSuccess
= false;
1902 bSuccess
= impl_close_throw();
1904 catch( const RuntimeException
& ) { throw; }
1905 catch( const Exception
& )
1907 throw WrappedTargetException(
1908 OUString(), *this, ::cppu::getCaughtException() );
1913 OUString SAL_CALL
ODocumentDefinition::getHierarchicalName() throw (RuntimeException
, std::exception
)
1915 ::osl::MutexGuard
aGuard( m_aMutex
);
1916 return impl_getHierarchicalName( false );
1919 OUString SAL_CALL
ODocumentDefinition::composeHierarchicalName( const OUString
& i_rRelativeName
) throw (IllegalArgumentException
, NoSupportException
, RuntimeException
, std::exception
)
1921 OUStringBuffer aBuffer
;
1922 aBuffer
.append( getHierarchicalName() );
1923 aBuffer
.append( '/' );
1924 aBuffer
.append( i_rRelativeName
);
1925 return aBuffer
.makeStringAndClear();
1928 void SAL_CALL
ODocumentDefinition::rename( const OUString
& _rNewName
) throw (SQLException
, ElementExistException
, RuntimeException
, std::exception
)
1932 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
1933 if ( _rNewName
.equals( m_pImpl
->m_aProps
.aTitle
) )
1936 // document definitions are organized in a hierarchical way, so reject names
1937 // which contain a /, as this is reserved for hierarchy level separation
1938 if ( _rNewName
.indexOf( '/' ) != -1 )
1939 m_aErrorHelper
.raiseException( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES
, *this );
1941 NameChangeNotifier
aNameChangeAndNotify( *this, _rNewName
, aGuard
);
1942 m_pImpl
->m_aProps
.aTitle
= _rNewName
;
1944 if ( m_xEmbeddedObject
.is() && m_xEmbeddedObject
->getCurrentState() == EmbedStates::ACTIVE
)
1945 updateDocumentTitle();
1947 catch(const PropertyVetoException
&)
1949 throw ElementExistException(_rNewName
,*this);
1953 Reference
< XStorage
> ODocumentDefinition::getContainerStorage() const
1955 return m_pImpl
->m_pDataSource
1956 ? m_pImpl
->m_pDataSource
->getStorage( m_bForm
? ODatabaseModelImpl::E_FORM
: ODatabaseModelImpl::E_REPORT
)
1957 : Reference
< XStorage
>();
1960 bool ODocumentDefinition::isModified()
1962 osl::ClearableGuard
< osl::Mutex
> aGuard(m_aMutex
);
1964 if ( m_xEmbeddedObject
.is() )
1966 Reference
<XModifiable
> xModel(getComponent(),UNO_QUERY
);
1967 bRet
= xModel
.is() && xModel
->isModified();
1972 bool ODocumentDefinition::prepareClose()
1974 if ( !m_xEmbeddedObject
.is() )
1979 // suspend the controller. Embedded objects are not allowed to raise
1980 // own UI at their own discretion, instead, this has always to be triggered
1981 // by the embedding component. Thus, we do the suspend call here.
1984 Reference
< util::XCloseable
> xComponent( impl_getComponent_throw( false ) );
1985 if ( !xComponent
.is() )
1988 Reference
< XModel
> xModel( xComponent
, UNO_QUERY
);
1989 Reference
< XController
> xController
;
1991 xController
= xModel
->getCurrentController();
1993 OSL_ENSURE( xController
.is() || ( m_xEmbeddedObject
->getCurrentState() < EmbedStates::ACTIVE
),
1994 "ODocumentDefinition::prepareClose: no controller!" );
1995 if ( !xController
.is() )
1996 // document has not yet been activated, i.e. has no UI, yet
1999 bool bCouldSuspend
= xController
->suspend( true );
2000 if ( !bCouldSuspend
)
2001 // controller vetoed the closing
2006 Reference
< XFrame
> xFrame( xController
->getFrame() );
2009 Reference
< XTopWindow
> xTopWindow( xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
2010 xTopWindow
->toFront();
2012 if ( !save( true ) )
2014 if ( bCouldSuspend
)
2015 // revert suspension
2016 xController
->suspend( false );
2017 // saving failed or was cancelled
2022 catch( const Exception
& )
2024 DBG_UNHANDLED_EXCEPTION();
2030 void ODocumentDefinition::fillReportData( const Reference
< XComponentContext
>& _rContext
,
2031 const Reference
< util::XCloseable
>& _rxComponent
,
2032 const Reference
< XConnection
>& _rxActiveConnection
)
2034 Sequence
< Any
> aArgs(2);
2035 PropertyValue aValue
;
2036 aValue
.Name
= "TextDocument";
2037 aValue
.Value
<<= _rxComponent
;
2038 aArgs
[0] <<= aValue
;
2039 aValue
.Name
= "ActiveConnection";
2040 aValue
.Value
<<= _rxActiveConnection
;
2041 aArgs
[1] <<= aValue
;
2045 Reference
< XJobExecutor
> xExecuteable(
2046 _rContext
->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.wizards.report.CallReportWizard", aArgs
, _rContext
), UNO_QUERY_THROW
);
2047 xExecuteable
->trigger( "fill" );
2049 catch( const Exception
& )
2051 DBG_UNHANDLED_EXCEPTION();
2055 void ODocumentDefinition::updateDocumentTitle()
2057 OUString sName
= m_pImpl
->m_aProps
.aTitle
;
2058 if ( m_pImpl
->m_pDataSource
)
2060 if ( sName
.isEmpty() )
2063 sName
= DBACORE_RESSTRING( RID_STR_FORM
);
2065 sName
= DBACORE_RESSTRING( RID_STR_REPORT
);
2066 Reference
< XUntitledNumbers
> xUntitledProvider(m_pImpl
->m_pDataSource
->getModel_noCreate(), UNO_QUERY
);
2067 if ( xUntitledProvider
.is() )
2068 sName
+= OUString::number( xUntitledProvider
->leaseNumber(getComponent()) );
2071 Reference
< XTitle
> xDatabaseDocumentModel(m_pImpl
->m_pDataSource
->getModel_noCreate(),uno::UNO_QUERY
);
2072 if ( xDatabaseDocumentModel
.is() )
2073 sName
= xDatabaseDocumentModel
->getTitle() + " : " + sName
;
2075 Reference
< XTitle
> xTitle(getComponent(),UNO_QUERY
);
2077 xTitle
->setTitle(sName
);
2080 void SAL_CALL
ODocumentDefinition::queryClosing( const lang::EventObject
& Source
, sal_Bool GetsOwnership
) throw (util::CloseVetoException
, uno::RuntimeException
, std::exception
)
2083 (void) GetsOwnership
;
2087 throw util::CloseVetoException();
2089 catch(const lang::WrappedTargetException
&)
2091 throw util::CloseVetoException();
2095 void SAL_CALL
ODocumentDefinition::notifyClosing( const lang::EventObject
& /*Source*/ ) throw (uno::RuntimeException
, std::exception
)
2099 void SAL_CALL
ODocumentDefinition::disposing( const lang::EventObject
& /*Source*/ ) throw (uno::RuntimeException
, std::exception
)
2103 void ODocumentDefinition::firePropertyChange( sal_Int32 i_nHandle
, const Any
& i_rNewValue
, const Any
& i_rOldValue
,
2104 bool i_bVetoable
, const NotifierAccess
& )
2106 fire( &i_nHandle
, &i_rNewValue
, &i_rOldValue
, 1, i_bVetoable
);
2109 // NameChangeNotifier
2110 NameChangeNotifier::NameChangeNotifier( ODocumentDefinition
& i_rDocumentDefinition
, const OUString
& i_rNewName
,
2111 ::osl::ResettableMutexGuard
& i_rClearForNotify
)
2112 :m_rDocumentDefinition( i_rDocumentDefinition
)
2113 ,m_aOldValue( makeAny( i_rDocumentDefinition
.getCurrentName() ) )
2114 ,m_aNewValue( makeAny( i_rNewName
) )
2115 ,m_rClearForNotify( i_rClearForNotify
)
2117 impl_fireEvent_throw( true );
2120 NameChangeNotifier::~NameChangeNotifier()
2122 impl_fireEvent_throw( false );
2125 void NameChangeNotifier::impl_fireEvent_throw( const bool i_bVetoable
)
2127 m_rClearForNotify
.clear();
2128 m_rDocumentDefinition
.firePropertyChange(
2129 PROPERTY_ID_NAME
, m_aNewValue
, m_aOldValue
, i_bVetoable
, ODocumentDefinition::NotifierAccess() );
2130 m_rClearForNotify
.reset();
2133 } // namespace dbaccess
2135 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */