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 "databasedocument.hxx"
22 #include <ModelImpl.hxx>
23 #include <stringconstants.hxx>
24 #include <sdbcoretools.hxx>
25 #include <comphelper/diagnose_ex.hxx>
26 #include <osl/diagnose.h>
27 #include <comphelper/compbase.hxx>
28 #include <comphelper/sequence.hxx>
29 #include <comphelper/namedvaluecollection.hxx>
30 #include <comphelper/classids.hxx>
31 #include <comphelper/propertysequence.hxx>
32 #include <comphelper/propertyvalue.hxx>
33 #include <comphelper/types.hxx>
34 #include <com/sun/star/frame/XUntitledNumbers.hpp>
35 #include <com/sun/star/awt/Size.hpp>
36 #include <com/sun/star/lang/DisposedException.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/beans/PropertyAttribute.hpp>
39 #include <com/sun/star/frame/Desktop.hpp>
40 #include <com/sun/star/frame/XModel.hpp>
41 #include <com/sun/star/frame/XTitle.hpp>
42 #include <com/sun/star/frame/XController.hpp>
43 #include <com/sun/star/task/XJobExecutor.hpp>
44 #include <com/sun/star/report/XReportDefinition.hpp>
45 #include <com/sun/star/report/XReportEngine.hpp>
46 #include <com/sun/star/ucb/OpenMode.hpp>
47 #include <com/sun/star/embed/WrongStateException.hpp>
48 #include <com/sun/star/embed/EmbeddedObjectCreator.hpp>
49 #include <com/sun/star/embed/Aspects.hpp>
50 #include <com/sun/star/embed/OOoEmbeddedObjectFactory.hpp>
51 #include <ucbhelper/cancelcommandexecution.hxx>
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/EntryInitModes.hpp>
57 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
58 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
59 #include <com/sun/star/util/CloseVetoException.hpp>
60 #include <com/sun/star/frame/XModule.hpp>
61 #include <com/sun/star/datatransfer/DataFlavor.hpp>
62 #include <com/sun/star/datatransfer/XTransferable.hpp>
63 #include <com/sun/star/container/XNameContainer.hpp>
64 #include <com/sun/star/embed/XCommonEmbedPersist.hpp>
65 #include "intercept.hxx"
66 #include <com/sun/star/sdb/ErrorCondition.hpp>
67 #include <com/sun/star/sdb/XInteractionDocumentSave.hpp>
68 #include <com/sun/star/task/InteractionHandler.hpp>
69 #include <com/sun/star/sdb/DocumentSaveRequest.hpp>
70 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
71 #include <com/sun/star/document/MacroExecMode.hpp>
72 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
73 #include <com/sun/star/form/XFormsSupplier.hpp>
74 #include <com/sun/star/form/XForm.hpp>
75 #include <comphelper/interaction.hxx>
76 #include <connectivity/dbtools.hxx>
77 #include <vcl/svapp.hxx>
78 #include <osl/mutex.hxx>
79 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
80 #include <core_resource.hxx>
81 #include <strings.hrc>
82 #include <strings.hxx>
83 #include <com/sun/star/task/XInteractionApprove.hpp>
84 #include <com/sun/star/task/XInteractionDisapprove.hpp>
85 #include <com/sun/star/frame/XLayoutManager.hpp>
86 #include <cppuhelper/compbase.hxx>
87 #include <cppuhelper/exc_hlp.hxx>
88 #include <cppuhelper/implbase.hxx>
89 #include <comphelper/mimeconfighelper.hxx>
90 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
91 #include <com/sun/star/io/WrongFormatException.hpp>
92 #include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp>
93 #include <com/sun/star/sdb/application/DatabaseObject.hpp>
94 #include <com/sun/star/util/XModifiable2.hpp>
96 using namespace ::com::sun::star
;
101 using namespace beans
;
102 using namespace lang
;
104 using namespace embed
;
105 using namespace frame
;
106 using namespace document
;
107 using namespace sdbc
;
110 using namespace container
;
111 using namespace datatransfer
;
112 using namespace task
;
113 using namespace form
;
114 using namespace drawing
;
115 using namespace ::osl
;
116 using namespace ::comphelper
;
117 using namespace ::cppu
;
119 using sdb::application::XDatabaseDocumentUI
;
120 namespace DatabaseObject
= sdb::application::DatabaseObject
;
122 #define DEFAULT_WIDTH 10000
123 #define DEFAULT_HEIGHT 7500
128 typedef ::std::optional
< bool > optional_bool
;
133 OUString
lcl_determineContentType_nothrow( const Reference
< XStorage
>& _rxContainerStorage
,
134 const OUString
& _rEntityName
)
136 OUString sContentType
;
139 ::utl::SharedUNOComponent
< XPropertySet
> xStorageProps(
140 _rxContainerStorage
->openStorageElement( _rEntityName
, ElementModes::READ
), UNO_QUERY_THROW
);
141 OSL_VERIFY( xStorageProps
->getPropertyValue( INFO_MEDIATYPE
) >>= sContentType
);
143 catch( const Exception
& )
145 DBG_UNHANDLED_EXCEPTION("dbaccess");
151 // OEmbedObjectHolder
152 typedef ::comphelper::WeakComponentImplHelper
< embed::XStateChangeListener
> TEmbedObjectHolder
;
154 class OEmbedObjectHolder
: public TEmbedObjectHolder
156 Reference
< XEmbeddedObject
> m_xBroadCaster
;
157 ODocumentDefinition
* m_pDefinition
;
158 bool m_bInStateChange
;
160 virtual void disposing(std::unique_lock
<std::mutex
>& rGuard
) override
;
162 OEmbedObjectHolder(const Reference
< XEmbeddedObject
>& _xBroadCaster
,ODocumentDefinition
* _pDefinition
)
163 : m_xBroadCaster(_xBroadCaster
)
164 ,m_pDefinition(_pDefinition
)
165 ,m_bInStateChange(false)
167 osl_atomic_increment( &m_refCount
);
169 if ( m_xBroadCaster
.is() )
170 m_xBroadCaster
->addStateChangeListener(this);
172 osl_atomic_decrement( &m_refCount
);
175 virtual void SAL_CALL
changingState( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) override
;
176 virtual void SAL_CALL
stateChanged( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) override
;
177 virtual void SAL_CALL
disposing( const lang::EventObject
& Source
) override
;
180 void OEmbedObjectHolder::disposing(std::unique_lock
<std::mutex
>& /*rGuard*/)
182 if ( m_xBroadCaster
.is() )
183 m_xBroadCaster
->removeStateChangeListener(this);
184 m_xBroadCaster
= nullptr;
185 m_pDefinition
= nullptr;
188 void SAL_CALL
OEmbedObjectHolder::changingState( const lang::EventObject
& /*aEvent*/, ::sal_Int32
/*nOldState*/, ::sal_Int32
/*nNewState*/ )
192 void SAL_CALL
OEmbedObjectHolder::stateChanged( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
)
194 if ( !m_bInStateChange
&& nNewState
== EmbedStates::RUNNING
&& nOldState
== EmbedStates::ACTIVE
&& m_pDefinition
)
196 m_bInStateChange
= true;
197 Reference
<XInterface
> xHoldAlive(static_cast< ::cppu::OWeakObject
* >(m_pDefinition
),UNO_QUERY
);
199 Reference
<XEmbeddedObject
> xEmbeddedObject(aEvent
.Source
,UNO_QUERY
);
200 if ( xEmbeddedObject
.is() )
201 xEmbeddedObject
->changeState(EmbedStates::LOADED
);
203 m_bInStateChange
= false;
207 void SAL_CALL
OEmbedObjectHolder::disposing( const lang::EventObject
& /*Source*/ )
209 m_xBroadCaster
= nullptr;
212 // OEmbeddedClientHelper
213 class OEmbeddedClientHelper
: public ::cppu::WeakImplHelper
<XEmbeddedClient
>
216 virtual void SAL_CALL
saveObject( ) override
219 // XComponentSupplier
220 virtual Reference
< util::XCloseable
> SAL_CALL
getComponent( ) override
222 return Reference
< css::util::XCloseable
>();
226 virtual void SAL_CALL
visibilityChanged( sal_Bool
/*bVisible*/ ) override
237 explicit LockModifiable( const Reference
< XInterface
>& i_rModifiable
)
238 :m_xModifiable( i_rModifiable
, UNO_QUERY
)
240 OSL_ENSURE( m_xModifiable
.is(), "LockModifiable::LockModifiable: invalid component!" );
241 if ( m_xModifiable
.is() )
243 if ( !m_xModifiable
->isSetModifiedEnabled() )
245 // somebody already locked that, no need to lock it, again, and no need to unlock it later
246 m_xModifiable
.clear();
250 m_xModifiable
->disableSetModified();
257 if ( m_xModifiable
.is() )
258 m_xModifiable
->enableSetModified();
262 Reference
< XModifiable2
> m_xModifiable
;
268 typedef ::cppu::WeakImplHelper
< css::lang::XEventListener
269 > LifetimeCoupler_Base
;
273 /** helper class which couples the lifetime of a component to the lifetime
276 Instances of this class are constructed with two components. The first is
277 simply held by reference, and thus kept alive. The second one is observed
278 for <code>disposing</code> calls - if they occur, i.e. if the component dies,
279 the reference to the first component is cleared.
281 This way, you can ensure that a certain component is kept alive as long
282 as a second component is not disposed.
284 class LifetimeCoupler
: public LifetimeCoupler_Base
287 Reference
< XInterface
> m_xClient
;
290 static void couple( const Reference
< XInterface
>& _rxClient
, const Reference
< XComponent
>& _rxActor
)
292 new LifetimeCoupler( _rxClient
, _rxActor
);
296 LifetimeCoupler( const Reference
< XInterface
>& _rxClient
, const Reference
< XComponent
>& _rxActor
)
297 :m_xClient( _rxClient
)
299 OSL_ENSURE( _rxActor
.is(), "LifetimeCoupler::LifetimeCoupler: this will crash!" );
300 osl_atomic_increment( &m_refCount
);
302 _rxActor
->addEventListener( this );
304 osl_atomic_decrement( &m_refCount
);
305 OSL_ENSURE( m_refCount
, "LifetimeCoupler::LifetimeCoupler: the actor is not holding us by hard ref - this won't work!" );
308 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) override
;
314 void SAL_CALL
LifetimeCoupler::disposing( const css::lang::EventObject
& /*Source*/ )
321 // ODocumentSaveContinuation
322 class ODocumentSaveContinuation
: public OInteraction
< XInteractionDocumentSave
>
325 Reference
<XContent
> m_xParentContainer
;
328 ODocumentSaveContinuation() { }
330 const Reference
<XContent
>& getContent() const { return m_xParentContainer
; }
331 const OUString
& getName() const { return m_sName
; }
333 // XInteractionDocumentSave
334 virtual void SAL_CALL
setName( const OUString
& _sName
,const Reference
<XContent
>& _xParent
) override
;
339 void SAL_CALL
ODocumentSaveContinuation::setName( const OUString
& _sName
,const Reference
<XContent
>& _xParent
)
342 m_xParentContainer
= _xParent
;
345 OUString
ODocumentDefinition::GetDocumentServiceFromMediaType( const Reference
< XStorage
>& _rxContainerStorage
,
346 const OUString
& _rEntityName
, const Reference
< XComponentContext
>& _rContext
,
347 Sequence
< sal_Int8
>& _rClassId
)
349 return GetDocumentServiceFromMediaType(
350 lcl_determineContentType_nothrow( _rxContainerStorage
, _rEntityName
),
351 _rContext
, _rClassId
);
354 OUString
ODocumentDefinition::GetDocumentServiceFromMediaType( const OUString
& _rMediaType
,
355 const Reference
< XComponentContext
>& _rContext
, Sequence
< sal_Int8
>& _rClassId
)
360 ::comphelper::MimeConfigurationHelper
aConfigHelper( _rContext
);
361 sResult
= aConfigHelper
.GetDocServiceNameFromMediaType( _rMediaType
);
362 _rClassId
= comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation(aConfigHelper
.GetExplicitlyRegisteredObjClassID( _rMediaType
));
363 if ( !_rClassId
.hasElements() && !sResult
.isEmpty() )
365 Reference
< XNameAccess
> xObjConfig
= aConfigHelper
.GetObjConfiguration();
366 if ( xObjConfig
.is() )
368 const Sequence
< OUString
> aClassIDs
= xObjConfig
->getElementNames();
369 for ( OUString
const & classId
: aClassIDs
)
371 Reference
< XNameAccess
> xObjectProps
;
372 OUString aEntryDocName
;
374 if ( ( xObjConfig
->getByName( classId
) >>= xObjectProps
) && xObjectProps
.is()
375 && ( xObjectProps
->getByName(u
"ObjectDocumentServiceName"_ustr
) >>= aEntryDocName
)
376 && aEntryDocName
== sResult
)
378 _rClassId
= comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation(classId
);
384 #if OSL_DEBUG_LEVEL > 0
385 // alternative, shorter approach
386 const Sequence
< NamedValue
> aProps( aConfigHelper
.GetObjectPropsByMediaType( _rMediaType
) );
387 const ::comphelper::NamedValueCollection
aMediaTypeProps( aProps
);
388 const OUString sAlternativeResult
= aMediaTypeProps
.getOrDefault( u
"ObjectDocumentServiceName"_ustr
, OUString() );
389 OSL_ENSURE( sAlternativeResult
== sResult
, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (1)!" );
390 const Sequence
< sal_Int8
> aAlternativeClassID
= aMediaTypeProps
.getOrDefault( u
"ClassID"_ustr
, Sequence
< sal_Int8
>() );
391 OSL_ENSURE( aAlternativeClassID
== _rClassId
, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (2)!" );
394 catch ( const Exception
& )
396 DBG_UNHANDLED_EXCEPTION("dbaccess");
401 // ODocumentDefinition
403 ODocumentDefinition::ODocumentDefinition( const Reference
< XInterface
>& _rxContainer
, const Reference
< XComponentContext
>& _xORB
,
404 const TContentPtr
& _pImpl
, bool _bForm
)
405 :OContentHelper(_xORB
,_rxContainer
,_pImpl
)
406 ,OPropertyStateContainer(OContentHelper::rBHelper
)
408 ,m_bOpenInDesign(false)
410 ,m_bRemoveListener(false)
412 registerProperties();
415 void ODocumentDefinition::initialLoad( const Sequence
< sal_Int8
>& i_rClassID
, const Sequence
< PropertyValue
>& i_rCreationArgs
,
416 const Reference
< XConnection
>& i_rConnection
)
418 OSL_ENSURE( i_rClassID
.hasElements(), "ODocumentDefinition::initialLoad: illegal class ID!" );
419 if ( !i_rClassID
.hasElements() )
422 loadEmbeddedObject( i_rConnection
, i_rClassID
, i_rCreationArgs
, false, false );
425 ODocumentDefinition::~ODocumentDefinition()
427 if ( !OContentHelper::rBHelper
.bInDispose
&& !OContentHelper::rBHelper
.bDisposed
)
433 if ( m_pInterceptor
.is() )
435 m_pInterceptor
->dispose();
436 m_pInterceptor
.clear();
440 void ODocumentDefinition::closeObject()
442 ::osl::MutexGuard
aGuard(m_aMutex
);
443 if ( m_xEmbeddedObject
.is() )
447 m_xEmbeddedObject
->close(true);
449 catch(const Exception
&)
452 m_xEmbeddedObject
= nullptr;
453 m_pClientHelper
.clear();
457 void SAL_CALL
ODocumentDefinition::disposing()
459 OContentHelper::disposing();
460 ::osl::MutexGuard
aGuard(m_aMutex
);
462 ::comphelper::disposeComponent(m_xListener
);
463 if ( m_bRemoveListener
)
465 rtl::Reference
<ODatabaseDocument
> xCloseable(m_pImpl
->m_pDataSource
->getModel_noCreate());
466 if ( xCloseable
.is() )
467 xCloseable
->removeCloseListener(this);
471 css::uno::Sequence
<sal_Int8
> ODocumentDefinition::getImplementationId()
473 return css::uno::Sequence
<sal_Int8
>();
476 css::uno::Sequence
< css::uno::Type
> ODocumentDefinition::getTypes()
478 return ::comphelper::concatSequences(
479 OContentHelper::getTypes( ),
480 OPropertyStateContainer::getTypes( ),
481 ODocumentDefinition_Base::getTypes( )
484 IMPLEMENT_FORWARD_XINTERFACE3( ODocumentDefinition
,OContentHelper
,OPropertyStateContainer
,ODocumentDefinition_Base
)
486 void ODocumentDefinition::registerProperties()
488 registerProperty(PROPERTY_NAME
, PROPERTY_ID_NAME
, PropertyAttribute::CONSTRAINED
| PropertyAttribute::BOUND
| PropertyAttribute::READONLY
,
489 &m_pImpl
->m_aProps
.aTitle
, cppu::UnoType
<decltype(m_pImpl
->m_aProps
.aTitle
)>::get());
491 registerProperty(PROPERTY_AS_TEMPLATE
, PROPERTY_ID_AS_TEMPLATE
, PropertyAttribute::READONLY
, &m_pImpl
->m_aProps
.bAsTemplate
,
492 cppu::UnoType
<decltype(m_pImpl
->m_aProps
.bAsTemplate
)>::get());
494 registerProperty(PROPERTY_PERSISTENT_NAME
, PROPERTY_ID_PERSISTENT_NAME
, PropertyAttribute::READONLY
, &m_pImpl
->m_aProps
.sPersistentName
,
495 cppu::UnoType
<decltype(m_pImpl
->m_aProps
.sPersistentName
)>::get());
497 registerProperty(PROPERTY_IS_FORM
, PROPERTY_ID_IS_FORM
, PropertyAttribute::READONLY
, &m_bForm
, cppu::UnoType
<decltype(m_bForm
)>::get());
500 void SAL_CALL
ODocumentDefinition::getFastPropertyValue( Any
& o_rValue
, sal_Int32 i_nHandle
) const
502 if ( i_nHandle
== PROPERTY_ID_PERSISTENT_PATH
)
504 OUString sPersistentPath
;
505 if ( !m_pImpl
->m_aProps
.sPersistentName
.isEmpty() )
507 sPersistentPath
= ODatabaseModelImpl::getObjectContainerStorageName( m_bForm
? ODatabaseModelImpl::ObjectType::Form
: ODatabaseModelImpl::ObjectType::Report
)
508 + "/" + m_pImpl
->m_aProps
.sPersistentName
;
510 o_rValue
<<= sPersistentPath
;
514 OPropertyStateContainer::getFastPropertyValue( o_rValue
, i_nHandle
);
517 Reference
< XPropertySetInfo
> SAL_CALL
ODocumentDefinition::getPropertySetInfo( )
519 Reference
<XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
523 IPropertyArrayHelper
& ODocumentDefinition::getInfoHelper()
525 return *getArrayHelper();
528 IPropertyArrayHelper
* ODocumentDefinition::createArrayHelper( ) const
530 // properties maintained by our base class (see registerProperties)
531 Sequence
< Property
> aProps
;
532 describeProperties( aProps
);
534 // properties not maintained by our base class
535 Sequence
< Property
> aManualProps
{ { /* Name */ PROPERTY_PERSISTENT_PATH
,
536 /* Handle */ PROPERTY_ID_PERSISTENT_PATH
,
537 /* Type */ ::cppu::UnoType
<OUString
>::get(),
538 /* Attributes */ PropertyAttribute::READONLY
} };
540 return new OPropertyArrayHelper( ::comphelper::concatSequences( aProps
, aManualProps
) );
549 explicit OExecuteImpl(bool& _rbSet
) : m_rbSet(_rbSet
){ m_rbSet
=true; }
550 ~OExecuteImpl(){ m_rbSet
= false; }
553 bool lcl_extractOpenMode( const Any
& _rValue
, sal_Int32
& _out_rMode
)
555 OpenCommandArgument aOpenCommand
;
556 if ( _rValue
>>= aOpenCommand
)
557 _out_rMode
= aOpenCommand
.Mode
;
560 OpenCommandArgument2 aOpenCommand2
;
561 if ( _rValue
>>= aOpenCommand2
)
562 _out_rMode
= aOpenCommand2
.Mode
;
570 void ODocumentDefinition::impl_removeFrameFromDesktop_throw( const Reference
<XComponentContext
> & _rxContext
, const Reference
< XFrame
>& _rxFrame
)
572 Reference
< XDesktop2
> xDesktop
= Desktop::create( _rxContext
);
573 Reference
< XFrames
> xFrames( xDesktop
->getFrames(), UNO_SET_THROW
);
574 xFrames
->remove( _rxFrame
);
577 void ODocumentDefinition::impl_onActivateEmbeddedObject_nothrow( const bool i_bReactivated
)
581 Reference
< XModel
> xModel( getComponent(), UNO_QUERY
);
582 Reference
< XController
> xController( xModel
.is() ? xModel
->getCurrentController() : Reference
< XController
>() );
583 if ( !xController
.is() )
586 if ( !m_xListener
.is() )
587 // it's the first time the embedded object has been activated
588 // create an OEmbedObjectHolder
589 m_xListener
= new OEmbedObjectHolder( m_xEmbeddedObject
, this );
591 // raise the window to top (especially necessary if this is not the first activation)
592 Reference
< XFrame
> xFrame( xController
->getFrame(), UNO_SET_THROW
);
593 Reference
< XTopWindow
> xTopWindow( xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
594 xTopWindow
->toFront();
596 // remove the frame from the desktop's frame collection because we need full control of it.
597 impl_removeFrameFromDesktop_throw( m_aContext
, xFrame
);
599 // ensure that we ourself are kept alive as long as the embedded object's frame is
601 LifetimeCoupler::couple( *this, xFrame
);
603 // init the edit view
604 if ( m_bForm
&& m_bOpenInDesign
&& !i_bReactivated
)
605 impl_initFormEditView( xController
);
607 catch( const RuntimeException
& )
609 DBG_UNHANDLED_EXCEPTION("dbaccess");
615 // PreserveVisualAreaSize
616 /** stack-guard for preserving the size of the VisArea of an XModel
618 class PreserveVisualAreaSize
621 Reference
< XVisualObject
> m_xVisObject
;
622 awt::Size m_aOriginalSize
;
625 explicit PreserveVisualAreaSize( const Reference
< XModel
>& _rxModel
)
626 :m_xVisObject( _rxModel
, UNO_QUERY
)
628 if ( m_xVisObject
.is() )
632 m_aOriginalSize
= m_xVisObject
->getVisualAreaSize( Aspects::MSOLE_CONTENT
);
634 catch ( const Exception
& )
636 TOOLS_WARN_EXCEPTION( "dbaccess", "PreserveVisualAreaSize::PreserveVisualAreaSize" );
641 ~PreserveVisualAreaSize()
643 if ( m_xVisObject
.is() && m_aOriginalSize
.Width
&& m_aOriginalSize
.Height
)
647 m_xVisObject
->setVisualAreaSize( Aspects::MSOLE_CONTENT
, m_aOriginalSize
);
649 catch ( const Exception
& )
651 TOOLS_WARN_EXCEPTION( "dbaccess", "PreserveVisualAreaSize::~PreserveVisualAreaSize" );
658 /** helper class for stack-usage which during its lifetime locks a layout manager
660 class LayoutManagerLock
663 Reference
< XLayoutManager
> m_xLayoutManager
;
666 explicit LayoutManagerLock( const Reference
< XController
>& _rxController
)
668 OSL_ENSURE( _rxController
.is(), "LayoutManagerLock::LayoutManagerLock: this will crash!" );
669 Reference
< XFrame
> xFrame( _rxController
->getFrame() );
672 Reference
< XPropertySet
> xPropSet( xFrame
, UNO_QUERY_THROW
);
673 m_xLayoutManager
.set(
674 xPropSet
->getPropertyValue( u
"LayoutManager"_ustr
),
676 m_xLayoutManager
->lock();
679 catch( const Exception
& )
681 TOOLS_WARN_EXCEPTION( "dbaccess", "LayoutManagerLock::LayoutManagerLock" );
689 // unlock the layout manager
690 if ( m_xLayoutManager
.is() )
691 m_xLayoutManager
->unlock();
693 catch( const Exception
& )
695 TOOLS_WARN_EXCEPTION( "dbaccess", "LayoutManagerLock::~LayoutManagerLock" );
701 void ODocumentDefinition::impl_initFormEditView( const Reference
< XController
>& _rxController
)
705 Reference
< XViewSettingsSupplier
> xSettingsSupplier( _rxController
, UNO_QUERY_THROW
);
706 Reference
< XPropertySet
> xViewSettings( xSettingsSupplier
->getViewSettings(), UNO_SET_THROW
);
708 // the below code could indirectly tamper with the "modified" flag of the model, temporarily disable this
709 LockModifiable
aLockModify( _rxController
->getModel() );
711 // The visual area size can be changed by the setting of the following properties
712 // so it should be restored later
713 PreserveVisualAreaSize
aPreserveVisAreaSize( _rxController
->getModel() );
715 // Layout manager should not layout while the size is still not restored
716 // so it will stay locked for this time
717 LayoutManagerLock
aLockLayout( _rxController
);
719 // setting of the visual properties
720 xViewSettings
->setPropertyValue(u
"ShowRulers"_ustr
,Any(true));
721 xViewSettings
->setPropertyValue(u
"ShowVertRuler"_ustr
,Any(true));
722 xViewSettings
->setPropertyValue(u
"ShowHoriRuler"_ustr
,Any(true));
723 xViewSettings
->setPropertyValue(u
"IsRasterVisible"_ustr
,Any(true));
724 xViewSettings
->setPropertyValue(u
"IsSnapToRaster"_ustr
,Any(true));
725 xViewSettings
->setPropertyValue(u
"ShowOnlineLayout"_ustr
,Any(true));
726 xViewSettings
->setPropertyValue(u
"RasterSubdivisionX"_ustr
,Any(sal_Int32(5)));
727 xViewSettings
->setPropertyValue(u
"RasterSubdivisionY"_ustr
,Any(sal_Int32(5)));
729 catch( const Exception
& )
731 DBG_UNHANDLED_EXCEPTION("dbaccess");
735 void ODocumentDefinition::impl_showOrHideComponent_throw( const bool i_bShow
)
737 const sal_Int32 nCurrentState
= m_xEmbeddedObject
.is() ? m_xEmbeddedObject
->getCurrentState() : EmbedStates::LOADED
;
738 switch ( nCurrentState
)
741 case EmbedStates::LOADED
:
742 throw embed::WrongStateException( OUString(), *this );
744 case EmbedStates::RUNNING
:
746 // fine, a running (and not yet active) object is never visible
749 LockModifiable
aLockModify( impl_getComponent_throw() );
750 m_xEmbeddedObject
->changeState( EmbedStates::ACTIVE
);
751 impl_onActivateEmbeddedObject_nothrow( false );
755 case EmbedStates::ACTIVE
:
757 Reference
< XModel
> xEmbeddedDoc( impl_getComponent_throw(), UNO_QUERY_THROW
);
758 Reference
< XController
> xEmbeddedController( xEmbeddedDoc
->getCurrentController(), UNO_SET_THROW
);
759 Reference
< XFrame
> xEmbeddedFrame( xEmbeddedController
->getFrame(), UNO_SET_THROW
);
760 Reference
< XWindow
> xEmbeddedWindow( xEmbeddedFrame
->getContainerWindow(), UNO_SET_THROW
);
761 xEmbeddedWindow
->setVisible( i_bShow
);
767 Any
ODocumentDefinition::onCommandOpenSomething( const Any
& _rOpenArgument
, const bool _bActivate
,
768 const Reference
< XCommandEnvironment
>& _rxEnvironment
)
770 OExecuteImpl
aExecuteGuard( m_bInExecute
);
772 Reference
< XConnection
> xConnection
;
773 sal_Int32 nOpenMode
= OpenMode::DOCUMENT
;
775 ::comphelper::NamedValueCollection aDocumentArgs
;
777 // for the document, default to the interaction handler as used for loading the DB doc
778 // This might be overwritten below, when examining _rOpenArgument.
779 const ::comphelper::NamedValueCollection
& aDBDocArgs( m_pImpl
->m_pDataSource
->getMediaDescriptor() );
780 Reference
< XInteractionHandler
> xHandler( aDBDocArgs
.getOrDefault( u
"InteractionHandler"_ustr
, Reference
< XInteractionHandler
>() ) );
782 aDocumentArgs
.put( u
"InteractionHandler"_ustr
, xHandler
);
784 ::std::optional
< sal_Int16
> aDocumentMacroMode
;
786 if ( !lcl_extractOpenMode( _rOpenArgument
, nOpenMode
) )
788 Sequence
< PropertyValue
> aArguments
;
789 if ( _rOpenArgument
>>= aArguments
)
791 for (auto& arg
: aArguments
)
793 if (arg
.Name
== PROPERTY_ACTIVE_CONNECTION
)
795 xConnection
.set(arg
.Value
, UNO_QUERY
);
799 if (lcl_extractOpenMode(arg
.Value
, nOpenMode
))
802 if (arg
.Name
== "MacroExecutionMode")
804 sal_Int16
nMacroExecMode( !aDocumentMacroMode
? MacroExecMode::USE_CONFIG
: *aDocumentMacroMode
);
805 OSL_VERIFY(arg
.Value
>>= nMacroExecMode
);
806 aDocumentMacroMode
= nMacroExecMode
;
810 // unknown argument -> pass to the loaded document
811 aDocumentArgs
.put(arg
.Name
, arg
.Value
);
816 bool bExecuteDBDocMacros
= m_pImpl
->m_pDataSource
->checkMacrosOnLoading();
817 // Note that this call implies the user might be asked for the macro execution mode.
818 // Normally, this would happen when the database document is loaded, and subsequent calls
819 // will simply use the user's decision from this point in time.
820 // However, it is possible to programmatically load forms/reports, without actually
821 // loading the database document into a frame. In this case, the user will be asked
825 // allow the command arguments to downgrade the macro execution mode, but not to upgrade
827 if ( ( m_pImpl
->m_pDataSource
->getImposedMacroExecMode() == MacroExecMode::USE_CONFIG
)
828 && bExecuteDBDocMacros
831 // while loading the whole database document, USE_CONFIG, was passed.
832 // Additionally, *by now* executing macros from the DB doc is allowed (this is what bExecuteDBDocMacros
833 // indicates). This means either one of:
834 // 1. The DB doc or one of the sub docs contained macros and
835 // 1a. the user explicitly allowed executing them
836 // 1b. the configuration allows executing them without asking the user
837 // 2. Neither the DB doc nor the sub docs contained macros, thus macro
838 // execution was silently enabled, assuming that any macro will be a
839 // user-created macro
841 // The problem with this: If the to-be-opened sub document has macros embedded in
842 // the content.xml (which is valid ODF, but normally not produced by OOo itself),
843 // then this has not been detected while loading the database document - it would
844 // be too expensive, as it effectively would require loading all forms/reports.
846 // So, in such a case, and with 2. above, we would silently execute those macros,
847 // regardless of the global security settings - which would be a security issue, of
849 if ( m_pImpl
->m_pDataSource
->determineEmbeddedMacros() == ODatabaseModelImpl::EmbeddedMacros::NONE
)
851 // this is case 2. from above
852 // So, pass a USE_CONFIG to the to-be-loaded document. This means that
853 // the user will be prompted with a security message upon opening this
854 // sub document, in case the settings require this, *and* the document
855 // contains scripts in the content.xml. But this is better than the security
856 // issue we had before ...
857 aDocumentMacroMode
= MacroExecMode::USE_CONFIG
;
861 if ( !aDocumentMacroMode
)
863 // nobody so far felt responsible for setting it
864 // => use the DBDoc-wide macro exec mode for the document, too
865 aDocumentMacroMode
= bExecuteDBDocMacros
? MacroExecMode::ALWAYS_EXECUTE_NO_WARN
866 : MacroExecMode::NEVER_EXECUTE
;
868 aDocumentArgs
.put( u
"MacroExecutionMode"_ustr
, *aDocumentMacroMode
);
870 if ( ( nOpenMode
== OpenMode::ALL
)
871 || ( nOpenMode
== OpenMode::FOLDERS
)
872 || ( nOpenMode
== OpenMode::DOCUMENTS
)
873 || ( nOpenMode
== OpenMode::DOCUMENT_SHARE_DENY_NONE
)
874 || ( nOpenMode
== OpenMode::DOCUMENT_SHARE_DENY_WRITE
)
878 ucbhelper::cancelCommandExecution(
879 Any( UnsupportedOpenModeException(
881 static_cast< cppu::OWeakObject
* >( this ),
882 sal_Int16( nOpenMode
) ) ),
885 OSL_FAIL( "unreachable" );
888 OSL_ENSURE( !m_pImpl
->m_aProps
.sPersistentName
.isEmpty(),
889 "ODocumentDefinition::onCommandOpenSomething: no persistent name - cannot load!" );
890 if ( m_pImpl
->m_aProps
.sPersistentName
.isEmpty() )
893 // embedded objects themself do not support the hidden flag. We implement support for
894 // it by changing the STATE to RUNNING only, instead of ACTIVE.
895 bool bOpenHidden
= aDocumentArgs
.getOrDefault( u
"Hidden"_ustr
, false );
896 aDocumentArgs
.remove( u
"Hidden"_ustr
);
898 loadEmbeddedObject( xConnection
, Sequence
< sal_Int8
>(), aDocumentArgs
.getPropertyValues(), false, !m_bOpenInDesign
);
899 OSL_ENSURE( m_xEmbeddedObject
.is(), "ODocumentDefinition::onCommandOpenSomething: what's this?" );
900 if ( !m_xEmbeddedObject
.is() )
903 Reference
< XModel
> xModel( getComponent(), UNO_QUERY
);
904 Reference
< report::XReportDefinition
> xReportDefinition(xModel
,UNO_QUERY
);
906 Reference
< XModule
> xModule( xModel
, UNO_QUERY
);
910 xModule
->setIdentifier( u
"com.sun.star.sdb.FormDesign"_ustr
);
911 else if ( !xReportDefinition
.is() )
912 xModule
->setIdentifier( u
"com.sun.star.text.TextDocument"_ustr
);
914 updateDocumentTitle();
917 bool bIsAliveNewStyleReport
= ( !m_bOpenInDesign
&& xReportDefinition
.is() );
918 if ( bIsAliveNewStyleReport
)
920 // we are in ReadOnly mode
921 // we would like to open the Writer or Calc with the report direct, without design it.
922 Reference
< report::XReportEngine
> xReportEngine( m_aContext
->getServiceManager()->createInstanceWithContext(u
"com.sun.star.comp.report.OReportEngineJFree"_ustr
, m_aContext
), UNO_QUERY_THROW
);
924 xReportEngine
->setReportDefinition(xReportDefinition
);
925 xReportEngine
->setActiveConnection(m_xLastKnownConnection
);
927 return Any( xReportEngine
->createDocumentModel() );
928 return Any( xReportEngine
->createDocumentAlive( nullptr ) );
931 if ( _bActivate
&& !bOpenHidden
)
933 LockModifiable
aLockModify( impl_getComponent_throw() );
934 m_xEmbeddedObject
->changeState( EmbedStates::ACTIVE
);
935 impl_onActivateEmbeddedObject_nothrow( false );
939 // ensure that we ourself are kept alive as long as the document is open
940 LifetimeCoupler::couple( *this, xModel
);
943 if ( !m_bForm
&& m_pImpl
->m_aProps
.bAsTemplate
&& !m_bOpenInDesign
)
944 ODocumentDefinition::fillReportData( m_aContext
, getComponent(), xConnection
);
946 return Any( xModel
);
949 Any SAL_CALL
ODocumentDefinition::execute( const Command
& aCommand
, sal_Int32 CommandId
, const Reference
< XCommandEnvironment
>& Environment
)
953 bool bOpen
= aCommand
.Name
== "open";
954 bool bOpenInDesign
= aCommand
.Name
== "openDesign";
955 bool bOpenForMail
= aCommand
.Name
== "openForMail";
956 if ( bOpen
|| bOpenInDesign
|| bOpenForMail
)
958 // opening the document involves a lot of VCL code, which is not thread-safe, but needs the SolarMutex locked.
959 // Unfortunately, the DocumentDefinition, as well as the EmbeddedObject implementation, calls into VCL-dependent
960 // components *without* releasing the own mutex, which is a guaranteed recipe for deadlocks.
961 // We have control over this implementation here, and in modifying it to release the own mutex before calling into
962 // the VCL-dependent components is not too difficult (was there, seen it).
963 // However, we do /not/ have control over the EmbeddedObject implementation, and from a first look, it seems as
964 // making it release the own mutex before calling SolarMutex-code is ... difficult, at least.
965 // So, to be on the same side, we lock the SolarMutex here. Yes, it sucks.
966 ::SolarMutexGuard aSolarGuard
;
967 osl::MutexGuard
aGuard(m_aMutex
);
971 bool bActivateObject
= true;
974 OSL_FAIL( "ODocumentDefinition::execute: 'openForMail' should not be used anymore - use the 'Hidden' parameter instead!" );
975 bActivateObject
= false;
978 // if the object is already opened, do nothing
979 if ( m_xEmbeddedObject
.is() )
981 sal_Int32 nCurrentState
= m_xEmbeddedObject
->getCurrentState();
982 bool bIsActive
= ( nCurrentState
== EmbedStates::ACTIVE
);
986 // exception: new-style reports always create a new document when "open" is executed
987 Reference
< report::XReportDefinition
> xReportDefinition( impl_getComponent_throw( false ), UNO_QUERY
);
988 bool bIsAliveNewStyleReport
= ( xReportDefinition
.is() && ( bOpen
|| bOpenForMail
) );
990 if ( !bIsAliveNewStyleReport
)
992 impl_onActivateEmbeddedObject_nothrow( true );
993 return Any( getComponent() );
998 m_bOpenInDesign
= bOpenInDesign
|| bOpenForMail
;
999 return onCommandOpenSomething( aCommand
.Argument
, bActivateObject
, Environment
);
1002 osl::MutexGuard
aGuard(m_aMutex
);
1006 if ( aCommand
.Name
== "copyTo" )
1009 aCommand
.Argument
>>= aIni
;
1010 if ( aIni
.getLength() != 2 )
1012 OSL_FAIL( "Wrong argument type!" );
1013 ucbhelper::cancelCommandExecution(
1014 Any( IllegalArgumentException(
1016 static_cast< cppu::OWeakObject
* >( this ),
1021 Reference
< XStorage
> xDest(aIni
[0],UNO_QUERY
);
1022 OUString sPersistentName
;
1023 aIni
[1] >>= sPersistentName
;
1024 Reference
< XStorage
> xStorage
= getContainerStorage();
1026 xStorage
->copyElementTo(m_pImpl
->m_aProps
.sPersistentName
,xDest
,sPersistentName
);
1028 else if ( aCommand
.Name
== "preview" )
1030 onCommandPreview(aRet
);
1032 else if ( aCommand
.Name
== "insert" )
1035 aCommand
.Argument
>>= aIni
;
1036 if ( !aIni
.hasElements() )
1038 OSL_FAIL( "Wrong argument count!" );
1039 ucbhelper::cancelCommandExecution(
1040 Any( IllegalArgumentException(
1042 static_cast< cppu::OWeakObject
* >( this ),
1049 onCommandInsert( sURL
, Environment
);
1051 else if ( aCommand
.Name
== "getdocumentinfo" // compatibility
1052 || aCommand
.Name
== "getDocumentInfo" )
1054 onCommandGetDocumentProperties( aRet
);
1056 else if ( aCommand
.Name
== "delete" )
1060 Reference
< XStorage
> xStorage
= getContainerStorage();
1061 if ( xStorage
.is() )
1062 xStorage
->removeElement(m_pImpl
->m_aProps
.sPersistentName
);
1067 else if ( aCommand
.Name
== "storeOwn" // compatibility
1068 || aCommand
.Name
== "store"
1073 else if ( aCommand
.Name
== "shutdown" // compatibility
1074 || aCommand
.Name
== "close"
1077 aRet
<<= impl_close_throw();
1079 else if ( aCommand
.Name
== "show" )
1081 impl_showOrHideComponent_throw( true );
1083 else if ( aCommand
.Name
== "hide" )
1085 impl_showOrHideComponent_throw( false );
1089 aRet
= OContentHelper::execute(aCommand
,CommandId
,Environment
);
1097 void lcl_resetChildFormsToEmptyDataSource( const Reference
< XIndexAccess
>& _rxFormsContainer
)
1099 OSL_PRECOND( _rxFormsContainer
.is(), "lcl_resetChildFormsToEmptyDataSource: illegal call!" );
1100 sal_Int32 count
= _rxFormsContainer
->getCount();
1101 for ( sal_Int32 i
= 0; i
< count
; ++i
)
1103 Reference
< XForm
> xForm( _rxFormsContainer
->getByIndex( i
), UNO_QUERY
);
1107 // if the element is a form, reset its DataSourceName property to an empty string
1110 Reference
< XPropertySet
> xFormProps( xForm
, UNO_QUERY_THROW
);
1111 xFormProps
->setPropertyValue( PROPERTY_DATASOURCENAME
, Any( OUString() ) );
1113 catch( const Exception
& )
1115 DBG_UNHANDLED_EXCEPTION("dbaccess");
1118 // if the element is a container itself, step down the component hierarchy
1119 Reference
< XIndexAccess
> xContainer( xForm
, UNO_QUERY
);
1120 if ( xContainer
.is() )
1121 lcl_resetChildFormsToEmptyDataSource( xContainer
);
1125 void lcl_resetFormsToEmptyDataSource( const Reference
< XEmbeddedObject
>& _rxEmbeddedObject
)
1129 Reference
< XDrawPageSupplier
> xSuppPage( _rxEmbeddedObject
->getComponent(), UNO_QUERY_THROW
);
1130 // if this interface does not exist, then either getComponent returned NULL,
1131 // or the document is a multi-page document. The latter is allowed, but currently
1132 // simply not handled by this code, as it would not normally happen.
1134 Reference
< XFormsSupplier
> xSuppForms( xSuppPage
->getDrawPage(), UNO_QUERY_THROW
);
1135 Reference
< XIndexAccess
> xForms( xSuppForms
->getForms(), UNO_QUERY_THROW
);
1136 lcl_resetChildFormsToEmptyDataSource( xForms
);
1138 catch( const Exception
& )
1140 DBG_UNHANDLED_EXCEPTION("dbaccess");
1146 void ODocumentDefinition::onCommandInsert( const OUString
& _sURL
, const Reference
< XCommandEnvironment
>& Environment
)
1148 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1150 // Check, if all required properties were set.
1151 if ( _sURL
.isEmpty() || m_xEmbeddedObject
.is() )
1153 OSL_FAIL( "Content::onCommandInsert - property value missing!" );
1155 Sequence
<OUString
> aProps
{ PROPERTY_URL
};
1156 ucbhelper::cancelCommandExecution(
1157 Any( MissingPropertiesException(
1159 static_cast< cppu::OWeakObject
* >( this ),
1165 if ( !m_xEmbeddedObject
.is() )
1167 Reference
< XStorage
> xStorage
= getContainerStorage();
1168 if ( xStorage
.is() )
1170 Reference
< XEmbeddedObjectCreator
> xEmbedFactory
= EmbeddedObjectCreator::create(m_aContext
);
1171 Sequence
<PropertyValue
> aEmpty
;
1172 Sequence
<PropertyValue
> aMediaDesc
{ comphelper::makePropertyValue(PROPERTY_URL
,
1174 m_xEmbeddedObject
.set(xEmbedFactory
->createInstanceInitFromMediaDescriptor( xStorage
1175 ,m_pImpl
->m_aProps
.sPersistentName
1177 ,aEmpty
),UNO_QUERY
);
1179 lcl_resetFormsToEmptyDataSource( m_xEmbeddedObject
);
1182 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1183 if ( xPersist
.is() )
1185 xPersist
->storeOwn();
1189 if ( m_xEmbeddedObject
.is() )
1190 m_xEmbeddedObject
->close(true);
1192 catch(const Exception
&)
1195 m_xEmbeddedObject
= nullptr;
1202 bool ODocumentDefinition::save(bool _bApprove
, const css::uno::Reference
<css::awt::XTopWindow
>& rDialogParent
)
1204 // default handling: instantiate an interaction handler and let it handle the parameter request
1205 if ( !m_bOpenInDesign
)
1211 ::SolarMutexGuard aSolarGuard
;
1214 Reference
<XNameAccess
> xName(m_xParentContainer
,UNO_QUERY
);
1215 DocumentSaveRequest aRequest
;
1216 aRequest
.Name
= m_pImpl
->m_aProps
.aTitle
;
1217 if ( aRequest
.Name
.isEmpty() )
1220 aRequest
.Name
= DBA_RES( RID_STR_FORM
);
1222 aRequest
.Name
= DBA_RES( RID_STR_REPORT
);
1223 aRequest
.Name
= ::dbtools::createUniqueName(xName
,aRequest
.Name
);
1226 aRequest
.Content
.set(m_xParentContainer
,UNO_QUERY
);
1227 rtl::Reference
<OInteractionRequest
> pRequest
= new OInteractionRequest(Any(aRequest
));
1229 // two continuations allowed: OK and Cancel
1230 rtl::Reference
<ODocumentSaveContinuation
> pDocuSave
;
1232 if ( m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1234 pDocuSave
= new ODocumentSaveContinuation
;
1235 pRequest
->addContinuation(pDocuSave
);
1239 rtl::Reference
<OInteraction
< XInteractionApprove
>> pApprove
= new OInteraction
< XInteractionApprove
>;
1240 pRequest
->addContinuation(pApprove
);
1243 rtl::Reference
<OInteraction
< XInteractionDisapprove
>> pDisApprove
= new OInteraction
< XInteractionDisapprove
>;
1244 pRequest
->addContinuation(pDisApprove
);
1246 rtl::Reference
<OInteractionAbort
> pAbort
= new OInteractionAbort
;
1247 pRequest
->addContinuation(pAbort
);
1249 Reference
<XWindow
> xDialogParent(rDialogParent
, UNO_QUERY
);
1251 // create the handler, let it handle the request
1252 Reference
<XInteractionHandler2
> xHandler(InteractionHandler::createWithParent(m_aContext
, xDialogParent
));
1253 xHandler
->handle(pRequest
);
1255 if ( pAbort
->wasSelected() )
1257 if ( pDisApprove
->wasSelected() )
1259 if ( pDocuSave
&& pDocuSave
->wasSelected() )
1261 Reference
<XNameContainer
> xNC( pDocuSave
->getContent(), UNO_QUERY_THROW
);
1263 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
1264 NameChangeNotifier
aNameChangeAndNotify( *this, pDocuSave
->getName(), aGuard
);
1265 m_pImpl
->m_aProps
.aTitle
= pDocuSave
->getName();
1267 Reference
< XContent
> xContent
= this;
1268 xNC
->insertByName(pDocuSave
->getName(),Any(xContent
));
1270 updateDocumentTitle();
1274 ::osl::MutexGuard
aGuard(m_aMutex
);
1275 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1276 if ( xPersist
.is() )
1278 xPersist
->storeOwn();
1279 notifyDataSourceModified();
1282 catch(const Exception
&)
1284 TOOLS_WARN_EXCEPTION( "dbaccess", "ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1289 void ODocumentDefinition::saveAs()
1291 // default handling: instantiate an interaction handler and let it handle the parameter request
1292 if ( !m_bOpenInDesign
)
1296 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1297 if ( m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1300 save(false, css::uno::Reference
<css::awt::XTopWindow
>()); // (sal_False) : we don't want an approve dialog
1306 ::SolarMutexGuard aSolarGuard
;
1309 DocumentSaveRequest aRequest
;
1310 aRequest
.Name
= m_pImpl
->m_aProps
.aTitle
;
1312 aRequest
.Content
.set(m_xParentContainer
,UNO_QUERY
);
1313 rtl::Reference
<OInteractionRequest
> pRequest
= new OInteractionRequest(Any(aRequest
));
1315 // two continuations allowed: OK and Cancel
1316 rtl::Reference
<ODocumentSaveContinuation
> pDocuSave
= new ODocumentSaveContinuation
;
1317 pRequest
->addContinuation(pDocuSave
);
1318 rtl::Reference
<OInteraction
< XInteractionDisapprove
>> pDisApprove
= new OInteraction
< XInteractionDisapprove
>;
1319 pRequest
->addContinuation(pDisApprove
);
1320 rtl::Reference
<OInteractionAbort
> pAbort
= new OInteractionAbort
;
1321 pRequest
->addContinuation(pAbort
);
1323 // create the handler, let it handle the request
1324 Reference
< XInteractionHandler2
> xHandler( InteractionHandler::createWithParent(m_aContext
, nullptr) );
1325 xHandler
->handle(pRequest
);
1327 if ( pAbort
->wasSelected() )
1329 if ( pDisApprove
->wasSelected() )
1331 if ( pDocuSave
->wasSelected() )
1333 ::osl::MutexGuard
aGuard(m_aMutex
);
1334 Reference
<XNameContainer
> xNC(pDocuSave
->getContent(),UNO_QUERY
);
1337 if ( m_pImpl
->m_aProps
.aTitle
!= pDocuSave
->getName() )
1341 Reference
< XStorage
> xStorage
= getContainerStorage();
1343 OUString sPersistentName
= ::dbtools::createUniqueName(xStorage
,u
"Obj"_ustr
);
1344 xStorage
->copyElementTo(m_pImpl
->m_aProps
.sPersistentName
,xStorage
,sPersistentName
);
1346 OUString sOldName
= m_pImpl
->m_aProps
.aTitle
;
1347 rename(pDocuSave
->getName());
1348 updateDocumentTitle();
1350 uno::Sequence
<uno::Any
> aArguments(comphelper::InitAnyPropertySequence(
1352 {PROPERTY_NAME
, uno::Any(sOldName
)}, // set as folder
1353 {PROPERTY_PERSISTENT_NAME
, uno::Any(sPersistentName
)},
1354 {PROPERTY_AS_TEMPLATE
, uno::Any(m_pImpl
->m_aProps
.bAsTemplate
)},
1356 Reference
< XMultiServiceFactory
> xORB( m_xParentContainer
, UNO_QUERY_THROW
);
1357 Reference
< XInterface
> xComponent( xORB
->createInstanceWithArguments( SERVICE_SDB_DOCUMENTDEFINITION
, aArguments
) );
1358 Reference
< XNameContainer
> xNameContainer( m_xParentContainer
, UNO_QUERY_THROW
);
1359 xNameContainer
->insertByName( sOldName
, Any( xComponent
) );
1361 catch(const Exception
&)
1363 DBG_UNHANDLED_EXCEPTION("dbaccess");
1366 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1367 if ( xPersist
.is() )
1369 xPersist
->storeOwn();
1370 notifyDataSourceModified();
1375 catch(const Exception
&)
1377 TOOLS_WARN_EXCEPTION( "dbaccess", "ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1383 void lcl_putLoadArgs( ::comphelper::NamedValueCollection
& _io_rArgs
, const optional_bool
& _bSuppressMacros
, const optional_bool
& _bReadOnly
)
1385 if ( _bSuppressMacros
.has_value() )
1387 if ( *_bSuppressMacros
)
1389 // if we're to suppress macros, do exactly this
1390 _io_rArgs
.put( u
"MacroExecutionMode"_ustr
, MacroExecMode::NEVER_EXECUTE
);
1394 // otherwise, put the setting only if not already present
1395 if ( !_io_rArgs
.has( u
"MacroExecutionMode"_ustr
) )
1397 _io_rArgs
.put( u
"MacroExecutionMode"_ustr
, MacroExecMode::USE_CONFIG
);
1402 if ( _bReadOnly
.has_value() )
1403 _io_rArgs
.put( u
"ReadOnly"_ustr
, *_bReadOnly
);
1409 Reference
< XFrame
> lcl_getDatabaseDocumentFrame( ODatabaseModelImpl
const & _rImpl
)
1411 Reference
< XModel
> xDatabaseDocumentModel( _rImpl
.getModel_noCreate() );
1413 Reference
< XController
> xDatabaseDocumentController
;
1414 if ( xDatabaseDocumentModel
.is() )
1415 xDatabaseDocumentController
= xDatabaseDocumentModel
->getCurrentController();
1417 Reference
< XFrame
> xFrame
;
1418 if ( xDatabaseDocumentController
.is() )
1419 xFrame
= xDatabaseDocumentController
->getFrame();
1425 bool ODocumentDefinition::objectSupportsEmbeddedScripts() const
1427 bool bAllowDocumentMacros
= !m_pImpl
->m_pDataSource
1428 || ( m_pImpl
->m_pDataSource
->determineEmbeddedMacros() == ODatabaseModelImpl::EmbeddedMacros::SubDocument
);
1430 // if *any* of the objects of the database document already has macros, we
1431 // continue to allow it to have them, until the user does a migration.
1432 // If there are no macros, we don't allow them to be created.
1434 return bAllowDocumentMacros
;
1437 OUString
ODocumentDefinition::determineContentType() const
1439 return lcl_determineContentType_nothrow( getContainerStorage(), m_pImpl
->m_aProps
.sPersistentName
);
1442 void ODocumentDefinition::separateOpenCommandArguments( const Sequence
< PropertyValue
>& i_rOpenCommandArguments
,
1443 ::comphelper::NamedValueCollection
& o_rDocumentLoadArgs
, ::comphelper::NamedValueCollection
& o_rEmbeddedObjectDescriptor
)
1445 ::comphelper::NamedValueCollection
aOpenCommandArguments( i_rOpenCommandArguments
);
1447 static const std::u16string_view sObjectDescriptorArgs
[] = { u
"RecoveryStorage" };
1448 for (const auto& rObjectDescriptorArg
: sObjectDescriptorArgs
)
1450 const OUString
sObjectDescriptorArg(rObjectDescriptorArg
);
1451 if ( aOpenCommandArguments
.has( sObjectDescriptorArg
) )
1453 o_rEmbeddedObjectDescriptor
.put( sObjectDescriptorArg
, aOpenCommandArguments
.get( sObjectDescriptorArg
) );
1454 aOpenCommandArguments
.remove( sObjectDescriptorArg
);
1458 o_rDocumentLoadArgs
.merge( aOpenCommandArguments
, false );
1461 Sequence
< PropertyValue
> ODocumentDefinition::fillLoadArgs( const Reference
< XConnection
>& _xConnection
, const bool _bSuppressMacros
, const bool _bReadOnly
,
1462 const Sequence
< PropertyValue
>& i_rOpenCommandArguments
, Sequence
< PropertyValue
>& _out_rEmbeddedObjectDescriptor
)
1464 // (re-)create interceptor, and put it into the descriptor of the embedded object
1465 if ( m_pInterceptor
.is() )
1467 m_pInterceptor
->dispose();
1468 m_pInterceptor
.clear();
1471 m_pInterceptor
= new OInterceptor( this );
1472 Reference
<XDispatchProviderInterceptor
> xInterceptor
= m_pInterceptor
;
1474 ::comphelper::NamedValueCollection aEmbeddedDescriptor
;
1475 aEmbeddedDescriptor
.put( u
"OutplaceDispatchInterceptor"_ustr
, xInterceptor
);
1477 ::comphelper::NamedValueCollection aMediaDesc
;
1478 separateOpenCommandArguments( i_rOpenCommandArguments
, aMediaDesc
, aEmbeddedDescriptor
);
1480 // create the OutplaceFrameProperties, and put them into the descriptor of the embedded object
1481 ::comphelper::NamedValueCollection OutplaceFrameProperties
;
1482 OutplaceFrameProperties
.put( u
"TopWindow"_ustr
, true );
1483 OutplaceFrameProperties
.put( u
"SupportPersistentWindowState"_ustr
, true );
1485 Reference
< XFrame
> xParentFrame
;
1486 if ( m_pImpl
->m_pDataSource
)
1487 xParentFrame
= lcl_getDatabaseDocumentFrame( *m_pImpl
->m_pDataSource
);
1488 if ( !xParentFrame
.is() )
1489 { // i87957 we need a parent frame
1490 Reference
< XDesktop2
> xDesktop
= Desktop::create( m_aContext
);
1491 xParentFrame
.set( xDesktop
, UNO_QUERY_THROW
);
1492 rtl::Reference
<ODatabaseDocument
> xCloseable(m_pImpl
->m_pDataSource
->getModel_noCreate());
1493 if ( xCloseable
.is() )
1495 xCloseable
->addCloseListener(this);
1496 m_bRemoveListener
= true;
1499 OSL_ENSURE( xParentFrame
.is(), "ODocumentDefinition::fillLoadArgs: no parent frame!" );
1500 if ( xParentFrame
.is() )
1501 OutplaceFrameProperties
.put( u
"ParentFrame"_ustr
, xParentFrame
);
1503 aEmbeddedDescriptor
.put( u
"OutplaceFrameProperties"_ustr
, OutplaceFrameProperties
.getNamedValues() );
1505 // tell the embedded object to have (or not have) script support
1506 aEmbeddedDescriptor
.put( u
"EmbeddedScriptSupport"_ustr
, objectSupportsEmbeddedScripts() );
1508 // tell the embedded object to not participate in the document recovery game - the DB doc will handle it
1509 aEmbeddedDescriptor
.put( u
"DocumentRecoverySupport"_ustr
, false );
1511 // pass the descriptor of the embedded object to the caller
1512 aEmbeddedDescriptor
>>= _out_rEmbeddedObjectDescriptor
;
1514 // create the ComponentData, and put it into the document's media descriptor
1516 ::comphelper::NamedValueCollection aComponentData
;
1517 aComponentData
.put( u
"ActiveConnection"_ustr
, _xConnection
);
1518 aComponentData
.put( u
"ApplyFormDesignMode"_ustr
, !_bReadOnly
);
1519 aMediaDesc
.put( u
"ComponentData"_ustr
, aComponentData
.getPropertyValues() );
1522 if ( !m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1523 aMediaDesc
.put( u
"DocumentTitle"_ustr
, m_pImpl
->m_aProps
.aTitle
);
1525 aMediaDesc
.put( u
"DocumentBaseURL"_ustr
, m_pImpl
->m_pDataSource
->getURL() );
1527 // put the common load arguments into the document's media descriptor
1528 lcl_putLoadArgs( aMediaDesc
, optional_bool( _bSuppressMacros
), optional_bool( _bReadOnly
) );
1530 return aMediaDesc
.getPropertyValues();
1533 void ODocumentDefinition::loadEmbeddedObject( const Reference
< XConnection
>& i_rConnection
, const Sequence
< sal_Int8
>& _aClassID
,
1534 const Sequence
< PropertyValue
>& i_rOpenCommandArguments
, const bool _bSuppressMacros
, const bool _bReadOnly
)
1536 if ( !m_xEmbeddedObject
.is() )
1538 Reference
< XStorage
> xStorage
= getContainerStorage();
1539 if ( xStorage
.is() )
1541 Reference
< XEmbeddedObjectCreator
> xEmbedFactory
= OOoEmbeddedObjectFactory::create(m_aContext
);
1542 OUString sDocumentService
;
1543 bool bSetSize
= false;
1544 sal_Int32 nEntryConnectionMode
= EntryInitModes::DEFAULT_INIT
;
1545 Sequence
< sal_Int8
> aClassID
= _aClassID
;
1546 if ( aClassID
.hasElements() )
1548 nEntryConnectionMode
= EntryInitModes::TRUNCATE_INIT
;
1553 sDocumentService
= GetDocumentServiceFromMediaType( getContentType(), m_aContext
, aClassID
);
1554 // check if we are not a form and
1555 // the org.libreoffice.report.pentaho.SOReportJobFactory is not present.
1556 if ( !m_bForm
&& sDocumentService
!= "com.sun.star.text.TextDocument")
1558 // we seem to be a "new style" report, check if report extension is present.
1559 Reference
< XContentEnumerationAccess
> xEnumAccess( m_aContext
->getServiceManager(), UNO_QUERY
);
1560 const OUString sReportEngineServiceName
= ::dbtools::getDefaultReportEngineServiceName(m_aContext
);
1561 Reference
< XEnumeration
> xEnumDrivers
= xEnumAccess
->createContentEnumeration(sReportEngineServiceName
);
1562 if ( !xEnumDrivers
.is() || !xEnumDrivers
->hasMoreElements() )
1564 throw css::io::WrongFormatException(DBA_RES(RID_STR_MISSING_EXTENSION
));
1567 if ( !aClassID
.hasElements() )
1570 aClassID
= MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID
);
1573 aClassID
= MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90
);
1578 OSL_ENSURE( aClassID
.hasElements(),"No Class ID" );
1580 Sequence
< PropertyValue
> aEmbeddedObjectDescriptor
;
1581 Sequence
< PropertyValue
> aLoadArgs( fillLoadArgs(
1582 i_rConnection
, _bSuppressMacros
, _bReadOnly
, i_rOpenCommandArguments
, aEmbeddedObjectDescriptor
) );
1584 m_xEmbeddedObject
.set(xEmbedFactory
->createInstanceUserInit(aClassID
1587 ,m_pImpl
->m_aProps
.sPersistentName
1588 ,nEntryConnectionMode
1590 ,aEmbeddedObjectDescriptor
1592 if ( m_xEmbeddedObject
.is() )
1594 if ( !m_pClientHelper
.is() )
1596 m_pClientHelper
= new OEmbeddedClientHelper
;
1598 m_xEmbeddedObject
->setClientSite(m_pClientHelper
);
1599 m_xEmbeddedObject
->changeState(EmbedStates::RUNNING
);
1602 LockModifiable
aLockModify( impl_getComponent_throw( false ) );
1604 awt::Size
aSize( DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
1605 m_xEmbeddedObject
->setVisualAreaSize(Aspects::MSOLE_CONTENT
,aSize
);
1612 sal_Int32 nCurrentState
= m_xEmbeddedObject
->getCurrentState();
1613 if ( nCurrentState
== EmbedStates::LOADED
)
1615 if ( !m_pClientHelper
.is() )
1617 m_pClientHelper
= new OEmbeddedClientHelper
;
1619 m_xEmbeddedObject
->setClientSite(m_pClientHelper
);
1621 Sequence
< PropertyValue
> aEmbeddedObjectDescriptor
;
1622 Sequence
< PropertyValue
> aLoadArgs( fillLoadArgs(
1623 i_rConnection
, _bSuppressMacros
, _bReadOnly
, i_rOpenCommandArguments
, aEmbeddedObjectDescriptor
) );
1625 Reference
<XCommonEmbedPersist
> xCommon(m_xEmbeddedObject
,UNO_QUERY
);
1626 OSL_ENSURE(xCommon
.is(),"unsupported interface!");
1628 xCommon
->reload( aLoadArgs
, aEmbeddedObjectDescriptor
);
1629 m_xEmbeddedObject
->changeState(EmbedStates::RUNNING
);
1633 OSL_ENSURE( ( nCurrentState
== EmbedStates::RUNNING
) || ( nCurrentState
== EmbedStates::ACTIVE
),
1634 "ODocumentDefinition::loadEmbeddedObject: unexpected state!" );
1636 // if the document was already loaded (which means the embedded object is in state RUNNING or ACTIVE),
1637 // then just re-set some model parameters
1640 // ensure the media descriptor doesn't contain any values which are intended for the
1641 // EmbeddedObjectDescriptor only
1642 ::comphelper::NamedValueCollection aEmbeddedObjectDescriptor
;
1643 ::comphelper::NamedValueCollection aNewMediaDesc
;
1644 separateOpenCommandArguments( i_rOpenCommandArguments
, aNewMediaDesc
, aEmbeddedObjectDescriptor
);
1646 // merge the new media descriptor into the existing media descriptor
1647 const Reference
< XModel
> xModel( getComponent(), UNO_QUERY_THROW
);
1648 const Sequence
< PropertyValue
> aArgs
= xModel
->getArgs();
1649 ::comphelper::NamedValueCollection
aExistentMediaDesc( aArgs
);
1650 aExistentMediaDesc
.merge( aNewMediaDesc
, false );
1652 lcl_putLoadArgs( aExistentMediaDesc
, optional_bool(), optional_bool() );
1653 // don't put _bSuppressMacros and _bReadOnly here - if the document was already
1654 // loaded, we should not tamper with its settings.
1655 // #i88977# #i86872#
1657 xModel
->attachResource( xModel
->getURL(), aExistentMediaDesc
.getPropertyValues() );
1659 catch( const Exception
& )
1661 DBG_UNHANDLED_EXCEPTION("dbaccess");
1666 // set the OfficeDatabaseDocument instance as parent of the embedded document
1668 Reference
< XChild
> xDepdendDocAsChild( getComponent(), UNO_QUERY
);
1669 if ( xDepdendDocAsChild
.is() )
1673 if ( !xDepdendDocAsChild
->getParent().is() )
1674 { // first encounter
1675 xDepdendDocAsChild
->setParent( getDataSource( m_xParentContainer
) );
1678 catch( const Exception
& )
1680 DBG_UNHANDLED_EXCEPTION("dbaccess");
1684 if ( i_rConnection
.is() )
1685 m_xLastKnownConnection
= i_rConnection
;
1688 void ODocumentDefinition::onCommandPreview(Any
& _rImage
)
1690 loadEmbeddedObjectForPreview();
1691 if ( !m_xEmbeddedObject
.is() )
1696 Reference
<XTransferable
> xTransfer(getComponent(),UNO_QUERY
);
1697 if ( xTransfer
.is() )
1700 aFlavor
.MimeType
= "image/png";
1701 aFlavor
.HumanPresentableName
= "Portable Network Graphics";
1702 aFlavor
.DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
1704 _rImage
= xTransfer
->getTransferData( aFlavor
);
1707 catch( const Exception
& )
1712 void ODocumentDefinition::getPropertyDefaultByHandle( sal_Int32
/*_nHandle*/, Any
& _rDefault
) const
1717 void ODocumentDefinition::onCommandGetDocumentProperties( Any
& _rProps
)
1719 loadEmbeddedObjectForPreview();
1720 if ( !m_xEmbeddedObject
.is() )
1725 Reference
<XDocumentPropertiesSupplier
> xDocSup(
1726 getComponent(), UNO_QUERY
);
1728 _rProps
<<= xDocSup
->getDocumentProperties();
1730 catch( const Exception
& )
1732 DBG_UNHANDLED_EXCEPTION("dbaccess");
1736 Reference
< util::XCloseable
> ODocumentDefinition::impl_getComponent_throw( const bool i_ForceCreate
)
1738 OSL_ENSURE(m_xEmbeddedObject
.is(),"Illegal call for embeddedObject");
1739 Reference
< util::XCloseable
> xComp
;
1740 if ( m_xEmbeddedObject
.is() )
1742 int nState
= m_xEmbeddedObject
->getCurrentState();
1743 if ( ( nState
== EmbedStates::LOADED
) && i_ForceCreate
)
1745 m_xEmbeddedObject
->changeState( EmbedStates::RUNNING
);
1746 nState
= m_xEmbeddedObject
->getCurrentState();
1747 OSL_ENSURE( nState
== EmbedStates::RUNNING
, "ODocumentDefinition::impl_getComponent_throw: could not switch to RUNNING!" );
1750 if ( nState
== EmbedStates::ACTIVE
|| nState
== EmbedStates::RUNNING
)
1752 if ( m_xEmbeddedObject
.is() )
1754 xComp
= m_xEmbeddedObject
->getComponent();
1755 OSL_ENSURE(xComp
.is(),"No valid component");
1762 Reference
< util::XCloseable
> ODocumentDefinition::getComponent()
1764 ::osl::MutexGuard
aGuard( m_aMutex
);
1765 return impl_getComponent_throw();
1770 Reference
< XDatabaseDocumentUI
> lcl_getDatabaseDocumentUI( ODatabaseModelImpl
const & _rModelImpl
)
1772 Reference
< XDatabaseDocumentUI
> xUI
;
1774 Reference
< XModel
> xModel( _rModelImpl
.getModel_noCreate() );
1776 xUI
.set( xModel
->getCurrentController(), UNO_QUERY
);
1781 Reference
< XComponent
> ODocumentDefinition::impl_openUI_nolck_throw( bool _bForEditing
)
1783 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
1784 if ( !m_pImpl
|| !m_pImpl
->m_pDataSource
)
1785 throw DisposedException();
1787 Reference
< XComponent
> xComponent
;
1790 Reference
< XDatabaseDocumentUI
> xUI( lcl_getDatabaseDocumentUI( *m_pImpl
->m_pDataSource
) );
1793 // no XDatabaseDocumentUI -> just execute the respective command
1794 m_bOpenInDesign
= _bForEditing
;
1795 xComponent
= Reference
<XComponent
>(onCommandOpenSomething(Any(), true, nullptr), UNO_QUERY
);
1796 OSL_ENSURE( xComponent
.is(), "ODocumentDefinition::impl_openUI_nolck_throw: opening the thingie failed." );
1801 OUString
sName( impl_getHierarchicalName( false ) );
1802 sal_Int32 nObjectType
= m_bForm
? DatabaseObject::FORM
: DatabaseObject::REPORT
;
1805 xComponent
= xUI
->loadComponent(
1806 nObjectType
, sName
, _bForEditing
1809 catch( const RuntimeException
& ) { throw; }
1810 catch( const Exception
& )
1812 throw WrappedTargetException(
1813 OUString(), *this, ::cppu::getCaughtException() );
1819 void ODocumentDefinition::impl_store_throw()
1821 Reference
<XEmbedPersist
> xPersist( m_xEmbeddedObject
, UNO_QUERY
);
1822 if ( xPersist
.is() )
1824 xPersist
->storeOwn();
1825 notifyDataSourceModified();
1829 bool ODocumentDefinition::impl_close_throw()
1831 bool bSuccess
= prepareClose();
1832 if ( bSuccess
&& m_xEmbeddedObject
.is() )
1834 m_xEmbeddedObject
->changeState( EmbedStates::LOADED
);
1835 bSuccess
= m_xEmbeddedObject
->getCurrentState() == EmbedStates::LOADED
;
1840 Reference
< XComponent
> SAL_CALL
ODocumentDefinition::open( )
1842 return impl_openUI_nolck_throw( false );
1845 Reference
< XComponent
> SAL_CALL
ODocumentDefinition::openDesign( )
1847 return impl_openUI_nolck_throw( true );
1850 void SAL_CALL
ODocumentDefinition::store( )
1852 ::osl::MutexGuard
aGuard( m_aMutex
);
1857 catch( const RuntimeException
& ) { throw; }
1858 catch( const Exception
& )
1860 throw WrappedTargetException(
1861 OUString(), *this, ::cppu::getCaughtException() );
1865 sal_Bool SAL_CALL
ODocumentDefinition::close( )
1867 ::osl::MutexGuard
aGuard( m_aMutex
);
1869 bool bSuccess
= false;
1872 bSuccess
= impl_close_throw();
1874 catch( const RuntimeException
& ) { throw; }
1875 catch( const Exception
& )
1877 throw WrappedTargetException(
1878 OUString(), *this, ::cppu::getCaughtException() );
1883 OUString SAL_CALL
ODocumentDefinition::getHierarchicalName()
1885 ::osl::MutexGuard
aGuard( m_aMutex
);
1886 return impl_getHierarchicalName( false );
1889 OUString SAL_CALL
ODocumentDefinition::composeHierarchicalName( const OUString
& i_rRelativeName
)
1891 return getHierarchicalName() + "/" + i_rRelativeName
;
1894 void SAL_CALL
ODocumentDefinition::rename( const OUString
& _rNewName
)
1898 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
1899 if ( _rNewName
== m_pImpl
->m_aProps
.aTitle
)
1902 // document definitions are organized in a hierarchical way, so reject names
1903 // which contain a /, as this is reserved for hierarchy level separation
1904 if ( _rNewName
.indexOf( '/' ) != -1 )
1905 m_aErrorHelper
.raiseException( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES
, *this );
1907 NameChangeNotifier
aNameChangeAndNotify( *this, _rNewName
, aGuard
);
1908 m_pImpl
->m_aProps
.aTitle
= _rNewName
;
1910 if ( m_xEmbeddedObject
.is() && m_xEmbeddedObject
->getCurrentState() == EmbedStates::ACTIVE
)
1911 updateDocumentTitle();
1913 catch(const PropertyVetoException
&)
1915 throw ElementExistException(_rNewName
,*this);
1919 Reference
< XStorage
> ODocumentDefinition::getContainerStorage() const
1921 return m_pImpl
->m_pDataSource
1922 ? m_pImpl
->m_pDataSource
->getStorage( m_bForm
? ODatabaseModelImpl::ObjectType::Form
: ODatabaseModelImpl::ObjectType::Report
)
1923 : Reference
< XStorage
>();
1926 bool ODocumentDefinition::isModified()
1928 osl::ClearableGuard
< osl::Mutex
> aGuard(m_aMutex
);
1930 if ( m_xEmbeddedObject
.is() )
1932 Reference
<XModifiable
> xModel(getComponent(),UNO_QUERY
);
1933 bRet
= xModel
.is() && xModel
->isModified();
1938 bool ODocumentDefinition::prepareClose()
1940 if ( !m_xEmbeddedObject
.is() )
1945 // suspend the controller. Embedded objects are not allowed to raise
1946 // own UI at their own discretion, instead, this has always to be triggered
1947 // by the embedding component. Thus, we do the suspend call here.
1950 Reference
< util::XCloseable
> xComponent( impl_getComponent_throw( false ) );
1951 if ( !xComponent
.is() )
1954 Reference
< XModel
> xModel( xComponent
, UNO_QUERY
);
1955 Reference
< XController
> xController
;
1957 xController
= xModel
->getCurrentController();
1959 OSL_ENSURE( xController
.is() || ( m_xEmbeddedObject
->getCurrentState() < EmbedStates::ACTIVE
),
1960 "ODocumentDefinition::prepareClose: no controller!" );
1961 if ( !xController
.is() )
1962 // document has not yet been activated, i.e. has no UI, yet
1965 if (!xController
->suspend(true))
1966 // controller vetoed the closing
1971 Reference
< XFrame
> xFrame( xController
->getFrame() );
1972 Reference
<XTopWindow
> xTopWindow
;
1975 xTopWindow
= Reference
<XTopWindow
>(xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
1976 xTopWindow
->toFront();
1978 if (!save(true, xTopWindow
))
1980 // revert suspension
1981 xController
->suspend(false);
1982 // saving failed or was cancelled
1987 catch( const Exception
& )
1989 DBG_UNHANDLED_EXCEPTION("dbaccess");
1995 void ODocumentDefinition::fillReportData( const Reference
< XComponentContext
>& _rContext
,
1996 const Reference
< util::XCloseable
>& _rxComponent
,
1997 const Reference
< XConnection
>& _rxActiveConnection
)
1999 uno::Sequence
<uno::Any
> aArgs(comphelper::InitAnyPropertySequence(
2001 {"TextDocument", uno::Any(_rxComponent
)},
2002 {"ActiveConnection", uno::Any(_rxActiveConnection
)}
2006 Reference
< XJobExecutor
> xExecutable(
2007 _rContext
->getServiceManager()->createInstanceWithArgumentsAndContext(u
"com.sun.star.wizards.report.CallReportWizard"_ustr
, aArgs
, _rContext
), UNO_QUERY_THROW
);
2008 xExecutable
->trigger( u
"fill"_ustr
);
2010 catch( const Exception
& )
2012 DBG_UNHANDLED_EXCEPTION("dbaccess");
2016 void ODocumentDefinition::updateDocumentTitle()
2018 OUString sName
= m_pImpl
->m_aProps
.aTitle
;
2019 if ( m_pImpl
->m_pDataSource
)
2021 if ( sName
.isEmpty() )
2024 sName
= DBA_RES( RID_STR_FORM
);
2026 sName
= DBA_RES( RID_STR_REPORT
);
2027 rtl::Reference
< ODatabaseDocument
> xUntitledProvider(m_pImpl
->m_pDataSource
->getModel_noCreate() );
2028 if ( xUntitledProvider
.is() )
2029 sName
+= OUString::number( xUntitledProvider
->leaseNumber(getComponent()) );
2032 rtl::Reference
< ODatabaseDocument
> xDatabaseDocumentModel(m_pImpl
->m_pDataSource
->getModel_noCreate());
2033 if ( xDatabaseDocumentModel
.is() )
2034 sName
= xDatabaseDocumentModel
->getTitle() + " : " + sName
;
2036 Reference
< XTitle
> xTitle(getComponent(),UNO_QUERY
);
2038 xTitle
->setTitle(sName
);
2041 void SAL_CALL
ODocumentDefinition::queryClosing( const lang::EventObject
&, sal_Bool
)
2046 throw util::CloseVetoException();
2048 catch(const lang::WrappedTargetException
&)
2050 throw util::CloseVetoException();
2054 void SAL_CALL
ODocumentDefinition::notifyClosing( const lang::EventObject
& /*Source*/ )
2058 void SAL_CALL
ODocumentDefinition::disposing( const lang::EventObject
& /*Source*/ )
2062 void ODocumentDefinition::firePropertyChange( sal_Int32 i_nHandle
, const Any
& i_rNewValue
, const Any
& i_rOldValue
,
2063 bool i_bVetoable
, const NotifierAccess
& )
2065 fire( &i_nHandle
, &i_rNewValue
, &i_rOldValue
, 1, i_bVetoable
);
2068 // NameChangeNotifier
2069 NameChangeNotifier::NameChangeNotifier( ODocumentDefinition
& i_rDocumentDefinition
, const OUString
& i_rNewName
,
2070 ::osl::ResettableMutexGuard
& i_rClearForNotify
)
2071 :m_rDocumentDefinition( i_rDocumentDefinition
)
2072 ,m_aOldValue( Any( i_rDocumentDefinition
.getCurrentName() ) )
2073 ,m_aNewValue( Any( i_rNewName
) )
2074 ,m_rClearForNotify( i_rClearForNotify
)
2076 impl_fireEvent_throw( true );
2079 NameChangeNotifier::~NameChangeNotifier()
2081 impl_fireEvent_throw( false );
2084 void NameChangeNotifier::impl_fireEvent_throw( const bool i_bVetoable
)
2086 m_rClearForNotify
.clear();
2087 m_rDocumentDefinition
.firePropertyChange(
2088 PROPERTY_ID_NAME
, m_aNewValue
, m_aOldValue
, i_bVetoable
, ODocumentDefinition::NotifierAccess() );
2089 m_rClearForNotify
.reset();
2092 } // namespace dbaccess
2094 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */