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 <ModelImpl.hxx>
22 #include <stringconstants.hxx>
23 #include <sdbcoretools.hxx>
24 #include <tools/diagnose_ex.h>
25 #include <osl/diagnose.h>
26 #include <comphelper/sequence.hxx>
27 #include <comphelper/namedvaluecollection.hxx>
28 #include <comphelper/classids.hxx>
29 #include <comphelper/propertysequence.hxx>
30 #include <comphelper/types.hxx>
31 #include <com/sun/star/frame/XUntitledNumbers.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/report/XReportDefinition.hpp>
41 #include <com/sun/star/report/XReportEngine.hpp>
42 #include <com/sun/star/ucb/OpenMode.hpp>
43 #include <com/sun/star/embed/WrongStateException.hpp>
44 #include <com/sun/star/embed/EmbeddedObjectCreator.hpp>
45 #include <com/sun/star/embed/Aspects.hpp>
46 #include <com/sun/star/embed/OOoEmbeddedObjectFactory.hpp>
47 #include <ucbhelper/cancelcommandexecution.hxx>
48 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
49 #include <com/sun/star/embed/ElementModes.hpp>
50 #include <com/sun/star/embed/XEmbedPersist.hpp>
51 #include <com/sun/star/embed/EmbedStates.hpp>
52 #include <com/sun/star/embed/EntryInitModes.hpp>
53 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
54 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
55 #include <com/sun/star/util/CloseVetoException.hpp>
56 #include <com/sun/star/frame/XModule.hpp>
57 #include <com/sun/star/datatransfer/DataFlavor.hpp>
58 #include <com/sun/star/datatransfer/XTransferable.hpp>
59 #include <com/sun/star/container/XNameContainer.hpp>
60 #include <com/sun/star/embed/XCommonEmbedPersist.hpp>
61 #include "intercept.hxx"
62 #include <com/sun/star/sdb/ErrorCondition.hpp>
63 #include <com/sun/star/sdb/XInteractionDocumentSave.hpp>
64 #include <com/sun/star/task/InteractionHandler.hpp>
65 #include <com/sun/star/sdb/DocumentSaveRequest.hpp>
66 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
67 #include <com/sun/star/document/MacroExecMode.hpp>
68 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
69 #include <com/sun/star/form/XFormsSupplier.hpp>
70 #include <com/sun/star/form/XForm.hpp>
71 #include <comphelper/interaction.hxx>
72 #include <connectivity/dbtools.hxx>
73 #include <vcl/svapp.hxx>
74 #include <osl/mutex.hxx>
75 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
76 #include <core_resource.hxx>
77 #include <strings.hrc>
78 #include <com/sun/star/task/XInteractionApprove.hpp>
79 #include <com/sun/star/task/XInteractionDisapprove.hpp>
80 #include <com/sun/star/frame/XLayoutManager.hpp>
81 #include <cppuhelper/compbase.hxx>
82 #include <cppuhelper/exc_hlp.hxx>
83 #include <cppuhelper/implbase.hxx>
84 #include <comphelper/mimeconfighelper.hxx>
85 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
86 #include <com/sun/star/io/WrongFormatException.hpp>
87 #include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp>
88 #include <com/sun/star/sdb/application/DatabaseObject.hpp>
89 #include <com/sun/star/util/XModifiable2.hpp>
91 using namespace ::com::sun::star
;
96 using namespace beans
;
99 using namespace embed
;
100 using namespace frame
;
101 using namespace document
;
102 using namespace sdbc
;
105 using namespace container
;
106 using namespace datatransfer
;
107 using namespace task
;
108 using namespace form
;
109 using namespace drawing
;
110 using namespace ::osl
;
111 using namespace ::comphelper
;
112 using namespace ::cppu
;
114 using sdb::application::XDatabaseDocumentUI
;
115 namespace DatabaseObject
= sdb::application::DatabaseObject
;
117 #define DEFAULT_WIDTH 10000
118 #define DEFAULT_HEIGHT 7500
123 typedef ::std::optional
< bool > optional_bool
;
128 OUString
lcl_determineContentType_nothrow( const Reference
< XStorage
>& _rxContainerStorage
,
129 const OUString
& _rEntityName
)
131 OUString sContentType
;
134 ::utl::SharedUNOComponent
< XPropertySet
> xStorageProps(
135 _rxContainerStorage
->openStorageElement( _rEntityName
, ElementModes::READ
), UNO_QUERY_THROW
);
136 OSL_VERIFY( xStorageProps
->getPropertyValue( INFO_MEDIATYPE
) >>= sContentType
);
138 catch( const Exception
& )
140 DBG_UNHANDLED_EXCEPTION("dbaccess");
146 // OEmbedObjectHolder
147 typedef ::cppu::WeakComponentImplHelper
< embed::XStateChangeListener
> TEmbedObjectHolder
;
151 class OEmbedObjectHolder
: public ::cppu::BaseMutex
152 ,public TEmbedObjectHolder
154 Reference
< XEmbeddedObject
> m_xBroadCaster
;
155 ODocumentDefinition
* m_pDefinition
;
156 bool m_bInStateChange
;
158 virtual void SAL_CALL
disposing() override
;
160 OEmbedObjectHolder(const Reference
< XEmbeddedObject
>& _xBroadCaster
,ODocumentDefinition
* _pDefinition
)
161 : TEmbedObjectHolder(m_aMutex
)
162 ,m_xBroadCaster(_xBroadCaster
)
163 ,m_pDefinition(_pDefinition
)
164 ,m_bInStateChange(false)
166 osl_atomic_increment( &m_refCount
);
168 if ( m_xBroadCaster
.is() )
169 m_xBroadCaster
->addStateChangeListener(this);
171 osl_atomic_decrement( &m_refCount
);
174 virtual void SAL_CALL
changingState( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) override
;
175 virtual void SAL_CALL
stateChanged( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) override
;
176 virtual void SAL_CALL
disposing( const lang::EventObject
& Source
) override
;
181 void SAL_CALL
OEmbedObjectHolder::disposing()
183 if ( m_xBroadCaster
.is() )
184 m_xBroadCaster
->removeStateChangeListener(this);
185 m_xBroadCaster
= nullptr;
186 m_pDefinition
= nullptr;
189 void SAL_CALL
OEmbedObjectHolder::changingState( const lang::EventObject
& /*aEvent*/, ::sal_Int32
/*nOldState*/, ::sal_Int32
/*nNewState*/ )
193 void SAL_CALL
OEmbedObjectHolder::stateChanged( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
)
195 if ( !m_bInStateChange
&& nNewState
== EmbedStates::RUNNING
&& nOldState
== EmbedStates::ACTIVE
&& m_pDefinition
)
197 m_bInStateChange
= true;
198 Reference
<XInterface
> xHoldAlive(static_cast< ::cppu::OWeakObject
* >(m_pDefinition
),UNO_QUERY
);
200 Reference
<XEmbeddedObject
> xEmbeddedObject(aEvent
.Source
,UNO_QUERY
);
201 if ( xEmbeddedObject
.is() )
202 xEmbeddedObject
->changeState(EmbedStates::LOADED
);
204 m_bInStateChange
= false;
208 void SAL_CALL
OEmbedObjectHolder::disposing( const lang::EventObject
& /*Source*/ )
210 m_xBroadCaster
= nullptr;
213 // OEmbeddedClientHelper
214 class OEmbeddedClientHelper
: public ::cppu::WeakImplHelper
<XEmbeddedClient
>
217 virtual void SAL_CALL
saveObject( ) override
220 // XComponentSupplier
221 virtual Reference
< util::XCloseable
> SAL_CALL
getComponent( ) override
223 return Reference
< css::util::XCloseable
>();
227 virtual void SAL_CALL
visibilityChanged( sal_Bool
/*bVisible*/ ) override
238 explicit LockModifiable( const Reference
< XInterface
>& i_rModifiable
)
239 :m_xModifiable( i_rModifiable
, UNO_QUERY
)
241 OSL_ENSURE( m_xModifiable
.is(), "LockModifiable::LockModifiable: invalid component!" );
242 if ( m_xModifiable
.is() )
244 if ( !m_xModifiable
->isSetModifiedEnabled() )
246 // somebody already locked that, no need to lock it, again, and no need to unlock it later
247 m_xModifiable
.clear();
251 m_xModifiable
->disableSetModified();
258 if ( m_xModifiable
.is() )
259 m_xModifiable
->enableSetModified();
263 Reference
< XModifiable2
> m_xModifiable
;
269 typedef ::cppu::WeakImplHelper
< css::lang::XEventListener
270 > LifetimeCoupler_Base
;
274 /** helper class which couples the lifetime of a component to the lifetime
277 Instances of this class are constructed with two components. The first is
278 simply held by reference, and thus kept alive. The second one is observed
279 for <code>disposing</code> calls - if they occur, i.e. if the component dies,
280 the reference to the first component is cleared.
282 This way, you can ensure that a certain component is kept alive as long
283 as a second component is not disposed.
285 class LifetimeCoupler
: public LifetimeCoupler_Base
288 Reference
< XInterface
> m_xClient
;
291 static void couple( const Reference
< XInterface
>& _rxClient
, const Reference
< XComponent
>& _rxActor
)
293 new LifetimeCoupler( _rxClient
, _rxActor
);
297 LifetimeCoupler( const Reference
< XInterface
>& _rxClient
, const Reference
< XComponent
>& _rxActor
)
298 :m_xClient( _rxClient
)
300 OSL_ENSURE( _rxActor
.is(), "LifetimeCoupler::LifetimeCoupler: this will crash!" );
301 osl_atomic_increment( &m_refCount
);
303 _rxActor
->addEventListener( this );
305 osl_atomic_decrement( &m_refCount
);
306 OSL_ENSURE( m_refCount
, "LifetimeCoupler::LifetimeCoupler: the actor is not holding us by hard ref - this won't work!" );
309 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) override
;
315 void SAL_CALL
LifetimeCoupler::disposing( const css::lang::EventObject
& /*Source*/ )
322 // ODocumentSaveContinuation
323 class ODocumentSaveContinuation
: public OInteraction
< XInteractionDocumentSave
>
326 Reference
<XContent
> m_xParentContainer
;
329 ODocumentSaveContinuation() { }
331 const Reference
<XContent
>& getContent() const { return m_xParentContainer
; }
332 const OUString
& getName() const { return m_sName
; }
334 // XInteractionDocumentSave
335 virtual void SAL_CALL
setName( const OUString
& _sName
,const Reference
<XContent
>& _xParent
) override
;
340 void SAL_CALL
ODocumentSaveContinuation::setName( const OUString
& _sName
,const Reference
<XContent
>& _xParent
)
343 m_xParentContainer
= _xParent
;
346 OUString
ODocumentDefinition::GetDocumentServiceFromMediaType( const Reference
< XStorage
>& _rxContainerStorage
,
347 const OUString
& _rEntityName
, const Reference
< XComponentContext
>& _rContext
,
348 Sequence
< sal_Int8
>& _rClassId
)
350 return GetDocumentServiceFromMediaType(
351 lcl_determineContentType_nothrow( _rxContainerStorage
, _rEntityName
),
352 _rContext
, _rClassId
);
355 OUString
ODocumentDefinition::GetDocumentServiceFromMediaType( const OUString
& _rMediaType
,
356 const Reference
< XComponentContext
>& _rContext
, Sequence
< sal_Int8
>& _rClassId
)
361 ::comphelper::MimeConfigurationHelper
aConfigHelper( _rContext
);
362 sResult
= aConfigHelper
.GetDocServiceNameFromMediaType( _rMediaType
);
363 _rClassId
= comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation(aConfigHelper
.GetExplicitlyRegisteredObjClassID( _rMediaType
));
364 if ( !_rClassId
.hasElements() && !sResult
.isEmpty() )
366 Reference
< XNameAccess
> xObjConfig
= aConfigHelper
.GetObjConfiguration();
367 if ( xObjConfig
.is() )
369 const Sequence
< OUString
> aClassIDs
= xObjConfig
->getElementNames();
370 for ( OUString
const & classId
: aClassIDs
)
372 Reference
< XNameAccess
> xObjectProps
;
373 OUString aEntryDocName
;
375 if ( ( xObjConfig
->getByName( classId
) >>= xObjectProps
) && xObjectProps
.is()
376 && ( xObjectProps
->getByName("ObjectDocumentServiceName") >>= aEntryDocName
)
377 && aEntryDocName
== sResult
)
379 _rClassId
= comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation(classId
);
385 #if OSL_DEBUG_LEVEL > 0
386 // alternative, shorter approach
387 const Sequence
< NamedValue
> aProps( aConfigHelper
.GetObjectPropsByMediaType( _rMediaType
) );
388 const ::comphelper::NamedValueCollection
aMediaTypeProps( aProps
);
389 const OUString sAlternativeResult
= aMediaTypeProps
.getOrDefault( "ObjectDocumentServiceName", OUString() );
390 OSL_ENSURE( sAlternativeResult
== sResult
, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (1)!" );
391 const Sequence
< sal_Int8
> aAlternativeClassID
= aMediaTypeProps
.getOrDefault( "ClassID", Sequence
< sal_Int8
>() );
392 OSL_ENSURE( aAlternativeClassID
== _rClassId
, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (2)!" );
395 catch ( const Exception
& )
397 DBG_UNHANDLED_EXCEPTION("dbaccess");
402 // ODocumentDefinition
404 ODocumentDefinition::ODocumentDefinition( const Reference
< XInterface
>& _rxContainer
, const Reference
< XComponentContext
>& _xORB
,
405 const TContentPtr
& _pImpl
, bool _bForm
)
406 :OContentHelper(_xORB
,_rxContainer
,_pImpl
)
407 ,OPropertyStateContainer(OContentHelper::rBHelper
)
409 ,m_bOpenInDesign(false)
411 ,m_bRemoveListener(false)
413 registerProperties();
416 void ODocumentDefinition::initialLoad( const Sequence
< sal_Int8
>& i_rClassID
, const Sequence
< PropertyValue
>& i_rCreationArgs
,
417 const Reference
< XConnection
>& i_rConnection
)
419 OSL_ENSURE( i_rClassID
.hasElements(), "ODocumentDefinition::initialLoad: illegal class ID!" );
420 if ( !i_rClassID
.hasElements() )
423 loadEmbeddedObject( i_rConnection
, i_rClassID
, i_rCreationArgs
, false, false );
426 ODocumentDefinition::~ODocumentDefinition()
428 if ( !OContentHelper::rBHelper
.bInDispose
&& !OContentHelper::rBHelper
.bDisposed
)
434 if ( m_pInterceptor
.is() )
436 m_pInterceptor
->dispose();
437 m_pInterceptor
.clear();
441 void ODocumentDefinition::closeObject()
443 ::osl::MutexGuard
aGuard(m_aMutex
);
444 if ( m_xEmbeddedObject
.is() )
448 m_xEmbeddedObject
->close(true);
450 catch(const Exception
&)
453 m_xEmbeddedObject
= nullptr;
454 m_pClientHelper
.clear();
458 void SAL_CALL
ODocumentDefinition::disposing()
460 OContentHelper::disposing();
461 ::osl::MutexGuard
aGuard(m_aMutex
);
463 ::comphelper::disposeComponent(m_xListener
);
464 if ( m_bRemoveListener
)
466 Reference
<util::XCloseable
> xCloseable(m_pImpl
->m_pDataSource
->getModel_noCreate(),UNO_QUERY
);
467 if ( xCloseable
.is() )
468 xCloseable
->removeCloseListener(this);
472 css::uno::Sequence
<sal_Int8
> ODocumentDefinition::getImplementationId()
474 return css::uno::Sequence
<sal_Int8
>();
477 IMPLEMENT_GETTYPES3(ODocumentDefinition
,OContentHelper
,OPropertyStateContainer
,ODocumentDefinition_Base
);
478 IMPLEMENT_FORWARD_XINTERFACE3( ODocumentDefinition
,OContentHelper
,OPropertyStateContainer
,ODocumentDefinition_Base
)
480 void ODocumentDefinition::registerProperties()
482 #define REGISTER_PROPERTY( name, location ) \
483 registerProperty( PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::READONLY, &location, cppu::UnoType<decltype(location)>::get() );
485 #define REGISTER_PROPERTY_BV( name, location ) \
486 registerProperty( PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::CONSTRAINED | PropertyAttribute::BOUND | PropertyAttribute::READONLY, &location, cppu::UnoType<decltype(location)>::get() );
488 REGISTER_PROPERTY_BV( NAME
, m_pImpl
->m_aProps
.aTitle
);
489 REGISTER_PROPERTY ( AS_TEMPLATE
, m_pImpl
->m_aProps
.bAsTemplate
);
490 REGISTER_PROPERTY ( PERSISTENT_NAME
, m_pImpl
->m_aProps
.sPersistentName
);
491 REGISTER_PROPERTY ( IS_FORM
, m_bForm
);
494 void SAL_CALL
ODocumentDefinition::getFastPropertyValue( Any
& o_rValue
, sal_Int32 i_nHandle
) const
496 if ( i_nHandle
== PROPERTY_ID_PERSISTENT_PATH
)
498 OUString sPersistentPath
;
499 if ( !m_pImpl
->m_aProps
.sPersistentName
.isEmpty() )
501 OUStringBuffer aBuffer
;
502 aBuffer
.append( ODatabaseModelImpl::getObjectContainerStorageName( m_bForm
? ODatabaseModelImpl::E_FORM
: ODatabaseModelImpl::E_REPORT
) );
503 aBuffer
.append( '/' );
504 aBuffer
.append( m_pImpl
->m_aProps
.sPersistentName
);
505 sPersistentPath
= aBuffer
.makeStringAndClear();
507 o_rValue
<<= sPersistentPath
;
511 OPropertyStateContainer::getFastPropertyValue( o_rValue
, i_nHandle
);
514 Reference
< XPropertySetInfo
> SAL_CALL
ODocumentDefinition::getPropertySetInfo( )
516 Reference
<XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
520 IPropertyArrayHelper
& ODocumentDefinition::getInfoHelper()
522 return *getArrayHelper();
525 IPropertyArrayHelper
* ODocumentDefinition::createArrayHelper( ) const
527 // properties maintained by our base class (see registerProperties)
528 Sequence
< Property
> aProps
;
529 describeProperties( aProps
);
531 // properties not maintained by our base class
532 Sequence
< Property
> aManualProps( 1 );
533 aManualProps
[0].Name
= PROPERTY_PERSISTENT_PATH
;
534 aManualProps
[0].Handle
= PROPERTY_ID_PERSISTENT_PATH
;
535 aManualProps
[0].Type
= ::cppu::UnoType
<OUString
>::get();
536 aManualProps
[0].Attributes
= PropertyAttribute::READONLY
;
538 return new OPropertyArrayHelper( ::comphelper::concatSequences( aProps
, aManualProps
) );
547 explicit OExecuteImpl(bool& _rbSet
) : m_rbSet(_rbSet
){ m_rbSet
=true; }
548 ~OExecuteImpl(){ m_rbSet
= false; }
551 bool lcl_extractOpenMode( const Any
& _rValue
, sal_Int32
& _out_rMode
)
553 OpenCommandArgument aOpenCommand
;
554 if ( _rValue
>>= aOpenCommand
)
555 _out_rMode
= aOpenCommand
.Mode
;
558 OpenCommandArgument2 aOpenCommand2
;
559 if ( _rValue
>>= aOpenCommand2
)
560 _out_rMode
= aOpenCommand2
.Mode
;
568 void ODocumentDefinition::impl_removeFrameFromDesktop_throw( const Reference
<XComponentContext
> & _rxContext
, const Reference
< XFrame
>& _rxFrame
)
570 Reference
< XDesktop2
> xDesktop
= Desktop::create( _rxContext
);
571 Reference
< XFrames
> xFrames( xDesktop
->getFrames(), UNO_SET_THROW
);
572 xFrames
->remove( _rxFrame
);
575 void ODocumentDefinition::impl_onActivateEmbeddedObject_nothrow( const bool i_bReactivated
)
579 Reference
< XModel
> xModel( getComponent(), UNO_QUERY
);
580 Reference
< XController
> xController( xModel
.is() ? xModel
->getCurrentController() : Reference
< XController
>() );
581 if ( !xController
.is() )
584 if ( !m_xListener
.is() )
585 // it's the first time the embedded object has been activated
586 // create an OEmbedObjectHolder
587 m_xListener
= new OEmbedObjectHolder( m_xEmbeddedObject
, this );
589 // raise the window to top (especially necessary if this is not the first activation)
590 Reference
< XFrame
> xFrame( xController
->getFrame(), UNO_SET_THROW
);
591 Reference
< XTopWindow
> xTopWindow( xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
592 xTopWindow
->toFront();
594 // remove the frame from the desktop's frame collection because we need full control of it.
595 impl_removeFrameFromDesktop_throw( m_aContext
, xFrame
);
597 // ensure that we ourself are kept alive as long as the embedded object's frame is
599 LifetimeCoupler::couple( *this, xFrame
.get() );
601 // init the edit view
602 if ( m_bForm
&& m_bOpenInDesign
&& !i_bReactivated
)
603 impl_initFormEditView( xController
);
605 catch( const RuntimeException
& )
607 DBG_UNHANDLED_EXCEPTION("dbaccess");
613 // PreserveVisualAreaSize
614 /** stack-guard for preserving the size of the VisArea of an XModel
616 class PreserveVisualAreaSize
619 Reference
< XVisualObject
> m_xVisObject
;
620 awt::Size m_aOriginalSize
;
623 explicit PreserveVisualAreaSize( const Reference
< XModel
>& _rxModel
)
624 :m_xVisObject( _rxModel
, UNO_QUERY
)
626 if ( m_xVisObject
.is() )
630 m_aOriginalSize
= m_xVisObject
->getVisualAreaSize( Aspects::MSOLE_CONTENT
);
632 catch ( const Exception
& )
634 TOOLS_WARN_EXCEPTION( "dbaccess", "PreserveVisualAreaSize::PreserveVisualAreaSize" );
639 ~PreserveVisualAreaSize()
641 if ( m_xVisObject
.is() && m_aOriginalSize
.Width
&& m_aOriginalSize
.Height
)
645 m_xVisObject
->setVisualAreaSize( Aspects::MSOLE_CONTENT
, m_aOriginalSize
);
647 catch ( const Exception
& )
649 TOOLS_WARN_EXCEPTION( "dbaccess", "PreserveVisualAreaSize::~PreserveVisualAreaSize" );
656 /** helper class for stack-usage which during its lifetime locks a layout manager
658 class LayoutManagerLock
661 Reference
< XLayoutManager
> m_xLayoutManager
;
664 explicit LayoutManagerLock( const Reference
< XController
>& _rxController
)
666 OSL_ENSURE( _rxController
.is(), "LayoutManagerLock::LayoutManagerLock: this will crash!" );
667 Reference
< XFrame
> xFrame( _rxController
->getFrame() );
670 Reference
< XPropertySet
> xPropSet( xFrame
, UNO_QUERY_THROW
);
671 m_xLayoutManager
.set(
672 xPropSet
->getPropertyValue( "LayoutManager" ),
674 m_xLayoutManager
->lock();
677 catch( const Exception
& )
679 TOOLS_WARN_EXCEPTION( "dbaccess", "LayoutManagerLock::LayoutManagerLock" );
687 // unlock the layout manager
688 if ( m_xLayoutManager
.is() )
689 m_xLayoutManager
->unlock();
691 catch( const Exception
& )
693 TOOLS_WARN_EXCEPTION( "dbaccess", "LayoutManagerLock::~LayoutManagerLock" );
699 void ODocumentDefinition::impl_initFormEditView( const Reference
< XController
>& _rxController
)
703 Reference
< XViewSettingsSupplier
> xSettingsSupplier( _rxController
, UNO_QUERY_THROW
);
704 Reference
< XPropertySet
> xViewSettings( xSettingsSupplier
->getViewSettings(), UNO_SET_THROW
);
706 // the below code could indirectly tamper with the "modified" flag of the model, temporarily disable this
707 LockModifiable
aLockModify( _rxController
->getModel() );
709 // The visual area size can be changed by the setting of the following properties
710 // so it should be restored later
711 PreserveVisualAreaSize
aPreserveVisAreaSize( _rxController
->getModel() );
713 // Layout manager should not layout while the size is still not restored
714 // so it will stay locked for this time
715 LayoutManagerLock
aLockLayout( _rxController
);
717 // setting of the visual properties
718 xViewSettings
->setPropertyValue("ShowRulers",makeAny(true));
719 xViewSettings
->setPropertyValue("ShowVertRuler",makeAny(true));
720 xViewSettings
->setPropertyValue("ShowHoriRuler",makeAny(true));
721 xViewSettings
->setPropertyValue("IsRasterVisible",makeAny(true));
722 xViewSettings
->setPropertyValue("IsSnapToRaster",makeAny(true));
723 xViewSettings
->setPropertyValue("ShowOnlineLayout",makeAny(true));
724 xViewSettings
->setPropertyValue("RasterSubdivisionX",makeAny(sal_Int32(5)));
725 xViewSettings
->setPropertyValue("RasterSubdivisionY",makeAny(sal_Int32(5)));
727 catch( const Exception
& )
729 DBG_UNHANDLED_EXCEPTION("dbaccess");
733 void ODocumentDefinition::impl_showOrHideComponent_throw( const bool i_bShow
)
735 const sal_Int32 nCurrentState
= m_xEmbeddedObject
.is() ? m_xEmbeddedObject
->getCurrentState() : EmbedStates::LOADED
;
736 switch ( nCurrentState
)
739 case EmbedStates::LOADED
:
740 throw embed::WrongStateException( OUString(), *this );
742 case EmbedStates::RUNNING
:
744 // fine, a running (and not yet active) object is never visible
747 LockModifiable
aLockModify( impl_getComponent_throw() );
748 m_xEmbeddedObject
->changeState( EmbedStates::ACTIVE
);
749 impl_onActivateEmbeddedObject_nothrow( false );
753 case EmbedStates::ACTIVE
:
755 Reference
< XModel
> xEmbeddedDoc( impl_getComponent_throw(), UNO_QUERY_THROW
);
756 Reference
< XController
> xEmbeddedController( xEmbeddedDoc
->getCurrentController(), UNO_SET_THROW
);
757 Reference
< XFrame
> xEmbeddedFrame( xEmbeddedController
->getFrame(), UNO_SET_THROW
);
758 Reference
< XWindow
> xEmbeddedWindow( xEmbeddedFrame
->getContainerWindow(), UNO_SET_THROW
);
759 xEmbeddedWindow
->setVisible( i_bShow
);
765 Any
ODocumentDefinition::onCommandOpenSomething( const Any
& _rOpenArgument
, const bool _bActivate
,
766 const Reference
< XCommandEnvironment
>& _rxEnvironment
)
768 OExecuteImpl
aExecuteGuard( m_bInExecute
);
770 Reference
< XConnection
> xConnection
;
771 sal_Int32 nOpenMode
= OpenMode::DOCUMENT
;
773 ::comphelper::NamedValueCollection aDocumentArgs
;
775 // for the document, default to the interaction handler as used for loading the DB doc
776 // This might be overwritten below, when examining _rOpenArgument.
777 const ::comphelper::NamedValueCollection
& aDBDocArgs( m_pImpl
->m_pDataSource
->getMediaDescriptor() );
778 Reference
< XInteractionHandler
> xHandler( aDBDocArgs
.getOrDefault( "InteractionHandler", Reference
< XInteractionHandler
>() ) );
780 aDocumentArgs
.put( "InteractionHandler", xHandler
);
782 ::std::optional
< sal_Int16
> aDocumentMacroMode
;
784 if ( !lcl_extractOpenMode( _rOpenArgument
, nOpenMode
) )
786 Sequence
< PropertyValue
> aArguments
;
787 if ( _rOpenArgument
>>= aArguments
)
789 const PropertyValue
* pIter
= aArguments
.getConstArray();
790 const PropertyValue
* pEnd
= pIter
+ aArguments
.getLength();
791 for ( ;pIter
!= pEnd
; ++pIter
)
793 if ( pIter
->Name
== PROPERTY_ACTIVE_CONNECTION
)
795 xConnection
.set( pIter
->Value
, UNO_QUERY
);
799 if ( lcl_extractOpenMode( pIter
->Value
, nOpenMode
) )
802 if ( pIter
->Name
== "MacroExecutionMode" )
804 sal_Int16
nMacroExecMode( !aDocumentMacroMode
? MacroExecMode::USE_CONFIG
: *aDocumentMacroMode
);
805 OSL_VERIFY( pIter
->Value
>>= nMacroExecMode
);
806 aDocumentMacroMode
= nMacroExecMode
;
810 // unknown argument -> pass to the loaded document
811 aDocumentArgs
.put( pIter
->Name
, pIter
->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::eNoMacros
)
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( "MacroExecutionMode", *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 makeAny( 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( "Hidden", false );
896 aDocumentArgs
.remove( "Hidden" );
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( "com.sun.star.sdb.FormDesign" );
911 else if ( !xReportDefinition
.is() )
912 xModule
->setIdentifier( "com.sun.star.text.TextDocument" );
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("com.sun.star.comp.report.OReportEngineJFree", m_aContext
), UNO_QUERY_THROW
);
924 xReportEngine
->setReportDefinition(xReportDefinition
);
925 xReportEngine
->setActiveConnection(m_xLastKnownConnection
);
927 return makeAny( xReportEngine
->createDocumentModel() );
928 return makeAny( 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
.get() );
943 if ( !m_bForm
&& m_pImpl
->m_aProps
.bAsTemplate
&& !m_bOpenInDesign
)
944 ODocumentDefinition::fillReportData( m_aContext
, getComponent(), xConnection
);
946 return makeAny( 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 makeAny( 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 makeAny( 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 makeAny( 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
, makeAny( 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 makeAny( 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
,aMediaDesc(1);
1172 aMediaDesc
[0].Name
= PROPERTY_URL
;
1173 aMediaDesc
[0].Value
<<= _sURL
;
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 OInteractionRequest
* pRequest
= new OInteractionRequest(makeAny(aRequest
));
1228 Reference
< XInteractionRequest
> xRequest(pRequest
);
1230 // two continuations allowed: OK and Cancel
1231 ODocumentSaveContinuation
* pDocuSave
= nullptr;
1233 if ( m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1235 pDocuSave
= new ODocumentSaveContinuation
;
1236 pRequest
->addContinuation(pDocuSave
);
1240 OInteraction
< XInteractionApprove
>* pApprove
= new OInteraction
< XInteractionApprove
>;
1241 pRequest
->addContinuation(pApprove
);
1244 OInteraction
< XInteractionDisapprove
>* pDisApprove
= new OInteraction
< XInteractionDisapprove
>;
1245 pRequest
->addContinuation(pDisApprove
);
1247 OInteractionAbort
* pAbort
= new OInteractionAbort
;
1248 pRequest
->addContinuation(pAbort
);
1250 Reference
<XWindow
> xDialogParent(rDialogParent
, UNO_QUERY
);
1252 // create the handler, let it handle the request
1253 Reference
<XInteractionHandler2
> xHandler(InteractionHandler::createWithParent(m_aContext
, xDialogParent
));
1254 xHandler
->handle(xRequest
);
1256 if ( pAbort
->wasSelected() )
1258 if ( pDisApprove
->wasSelected() )
1260 if ( pDocuSave
&& pDocuSave
->wasSelected() )
1262 Reference
<XNameContainer
> xNC( pDocuSave
->getContent(), UNO_QUERY_THROW
);
1264 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
1265 NameChangeNotifier
aNameChangeAndNotify( *this, pDocuSave
->getName(), aGuard
);
1266 m_pImpl
->m_aProps
.aTitle
= pDocuSave
->getName();
1268 Reference
< XContent
> xContent
= this;
1269 xNC
->insertByName(pDocuSave
->getName(),makeAny(xContent
));
1271 updateDocumentTitle();
1275 ::osl::MutexGuard
aGuard(m_aMutex
);
1276 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1277 if ( xPersist
.is() )
1279 xPersist
->storeOwn();
1280 notifyDataSourceModified();
1283 catch(const Exception
&)
1285 OSL_FAIL("ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1290 void ODocumentDefinition::saveAs()
1292 // default handling: instantiate an interaction handler and let it handle the parameter request
1293 if ( !m_bOpenInDesign
)
1297 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1298 if ( m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1301 save(false, css::uno::Reference
<css::awt::XTopWindow
>()); // (sal_False) : we don't want an approve dialog
1307 ::SolarMutexGuard aSolarGuard
;
1310 DocumentSaveRequest aRequest
;
1311 aRequest
.Name
= m_pImpl
->m_aProps
.aTitle
;
1313 aRequest
.Content
.set(m_xParentContainer
,UNO_QUERY
);
1314 OInteractionRequest
* pRequest
= new OInteractionRequest(makeAny(aRequest
));
1315 Reference
< XInteractionRequest
> xRequest(pRequest
);
1317 // two continuations allowed: OK and Cancel
1318 ODocumentSaveContinuation
* pDocuSave
= new ODocumentSaveContinuation
;
1319 pRequest
->addContinuation(pDocuSave
);
1320 OInteraction
< XInteractionDisapprove
>* pDisApprove
= new OInteraction
< XInteractionDisapprove
>;
1321 pRequest
->addContinuation(pDisApprove
);
1322 OInteractionAbort
* pAbort
= new OInteractionAbort
;
1323 pRequest
->addContinuation(pAbort
);
1325 // create the handler, let it handle the request
1326 Reference
< XInteractionHandler2
> xHandler( InteractionHandler::createWithParent(m_aContext
, nullptr) );
1327 xHandler
->handle(xRequest
);
1329 if ( pAbort
->wasSelected() )
1331 if ( pDisApprove
->wasSelected() )
1333 if ( pDocuSave
->wasSelected() )
1335 ::osl::MutexGuard
aGuard(m_aMutex
);
1336 Reference
<XNameContainer
> xNC(pDocuSave
->getContent(),UNO_QUERY
);
1339 if ( m_pImpl
->m_aProps
.aTitle
!= pDocuSave
->getName() )
1343 Reference
< XStorage
> xStorage
= getContainerStorage();
1345 OUString sPersistentName
= ::dbtools::createUniqueName(xStorage
,"Obj");
1346 xStorage
->copyElementTo(m_pImpl
->m_aProps
.sPersistentName
,xStorage
,sPersistentName
);
1348 OUString sOldName
= m_pImpl
->m_aProps
.aTitle
;
1349 rename(pDocuSave
->getName());
1350 updateDocumentTitle();
1352 uno::Sequence
<uno::Any
> aArguments(comphelper::InitAnyPropertySequence(
1354 {PROPERTY_NAME
, uno::Any(sOldName
)}, // set as folder
1355 {PROPERTY_PERSISTENT_NAME
, uno::Any(sPersistentName
)},
1356 {PROPERTY_AS_TEMPLATE
, uno::Any(m_pImpl
->m_aProps
.bAsTemplate
)},
1358 Reference
< XMultiServiceFactory
> xORB( m_xParentContainer
, UNO_QUERY_THROW
);
1359 Reference
< XInterface
> xComponent( xORB
->createInstanceWithArguments( SERVICE_SDB_DOCUMENTDEFINITION
, aArguments
) );
1360 Reference
< XNameContainer
> xNameContainer( m_xParentContainer
, UNO_QUERY_THROW
);
1361 xNameContainer
->insertByName( sOldName
, makeAny( xComponent
) );
1363 catch(const Exception
&)
1365 DBG_UNHANDLED_EXCEPTION("dbaccess");
1368 Reference
<XEmbedPersist
> xPersist(m_xEmbeddedObject
,UNO_QUERY
);
1369 if ( xPersist
.is() )
1371 xPersist
->storeOwn();
1372 notifyDataSourceModified();
1377 catch(const Exception
&)
1379 OSL_FAIL("ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!");
1385 void lcl_putLoadArgs( ::comphelper::NamedValueCollection
& _io_rArgs
, const optional_bool
& _bSuppressMacros
, const optional_bool
& _bReadOnly
)
1387 if ( !!_bSuppressMacros
)
1389 if ( *_bSuppressMacros
)
1391 // if we're to suppress macros, do exactly this
1392 _io_rArgs
.put( "MacroExecutionMode", MacroExecMode::NEVER_EXECUTE
);
1396 // otherwise, put the setting only if not already present
1397 if ( !_io_rArgs
.has( "MacroExecutionMode" ) )
1399 _io_rArgs
.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG
);
1405 _io_rArgs
.put( "ReadOnly", *_bReadOnly
);
1411 Reference
< XFrame
> lcl_getDatabaseDocumentFrame( ODatabaseModelImpl
const & _rImpl
)
1413 Reference
< XModel
> xDatabaseDocumentModel( _rImpl
.getModel_noCreate() );
1415 Reference
< XController
> xDatabaseDocumentController
;
1416 if ( xDatabaseDocumentModel
.is() )
1417 xDatabaseDocumentController
= xDatabaseDocumentModel
->getCurrentController();
1419 Reference
< XFrame
> xFrame
;
1420 if ( xDatabaseDocumentController
.is() )
1421 xFrame
= xDatabaseDocumentController
->getFrame();
1427 bool ODocumentDefinition::objectSupportsEmbeddedScripts() const
1429 bool bAllowDocumentMacros
= !m_pImpl
->m_pDataSource
1430 || ( m_pImpl
->m_pDataSource
->determineEmbeddedMacros() == ODatabaseModelImpl::eSubDocumentMacros
);
1432 // if *any* of the objects of the database document already has macros, we
1433 // continue to allow it to have them, until the user does a migration.
1434 // If there are no macros, we don't allow them to be created.
1436 return bAllowDocumentMacros
;
1439 OUString
ODocumentDefinition::determineContentType() const
1441 return lcl_determineContentType_nothrow( getContainerStorage(), m_pImpl
->m_aProps
.sPersistentName
);
1444 void ODocumentDefinition::separateOpenCommandArguments( const Sequence
< PropertyValue
>& i_rOpenCommandArguments
,
1445 ::comphelper::NamedValueCollection
& o_rDocumentLoadArgs
, ::comphelper::NamedValueCollection
& o_rEmbeddedObjectDescriptor
)
1447 ::comphelper::NamedValueCollection
aOpenCommandArguments( i_rOpenCommandArguments
);
1449 const char* const pObjectDescriptorArgs
[] =
1453 for (const char* pObjectDescriptorArg
: pObjectDescriptorArgs
)
1455 if ( aOpenCommandArguments
.has( pObjectDescriptorArg
) )
1457 o_rEmbeddedObjectDescriptor
.put( pObjectDescriptorArg
, aOpenCommandArguments
.get( pObjectDescriptorArg
) );
1458 aOpenCommandArguments
.remove( pObjectDescriptorArg
);
1462 o_rDocumentLoadArgs
.merge( aOpenCommandArguments
, false );
1465 Sequence
< PropertyValue
> ODocumentDefinition::fillLoadArgs( const Reference
< XConnection
>& _xConnection
, const bool _bSuppressMacros
, const bool _bReadOnly
,
1466 const Sequence
< PropertyValue
>& i_rOpenCommandArguments
, Sequence
< PropertyValue
>& _out_rEmbeddedObjectDescriptor
)
1468 // (re-)create interceptor, and put it into the descriptor of the embedded object
1469 if ( m_pInterceptor
.is() )
1471 m_pInterceptor
->dispose();
1472 m_pInterceptor
.clear();
1475 m_pInterceptor
= new OInterceptor( this );
1476 Reference
<XDispatchProviderInterceptor
> xInterceptor
= m_pInterceptor
.get();
1478 ::comphelper::NamedValueCollection aEmbeddedDescriptor
;
1479 aEmbeddedDescriptor
.put( "OutplaceDispatchInterceptor", xInterceptor
);
1481 ::comphelper::NamedValueCollection aMediaDesc
;
1482 separateOpenCommandArguments( i_rOpenCommandArguments
, aMediaDesc
, aEmbeddedDescriptor
);
1484 // create the OutplaceFrameProperties, and put them into the descriptor of the embedded object
1485 ::comphelper::NamedValueCollection OutplaceFrameProperties
;
1486 OutplaceFrameProperties
.put( "TopWindow", true );
1487 OutplaceFrameProperties
.put( "SupportPersistentWindowState", true );
1489 Reference
< XFrame
> xParentFrame
;
1490 if ( m_pImpl
->m_pDataSource
)
1491 xParentFrame
= lcl_getDatabaseDocumentFrame( *m_pImpl
->m_pDataSource
);
1492 if ( !xParentFrame
.is() )
1493 { // i87957 we need a parent frame
1494 Reference
< XDesktop2
> xDesktop
= Desktop::create( m_aContext
);
1495 xParentFrame
.set( xDesktop
, UNO_QUERY_THROW
);
1496 Reference
<util::XCloseable
> xCloseable(m_pImpl
->m_pDataSource
->getModel_noCreate(),UNO_QUERY
);
1497 if ( xCloseable
.is() )
1499 xCloseable
->addCloseListener(this);
1500 m_bRemoveListener
= true;
1503 OSL_ENSURE( xParentFrame
.is(), "ODocumentDefinition::fillLoadArgs: no parent frame!" );
1504 if ( xParentFrame
.is() )
1505 OutplaceFrameProperties
.put( "ParentFrame", xParentFrame
);
1507 aEmbeddedDescriptor
.put( "OutplaceFrameProperties", OutplaceFrameProperties
.getNamedValues() );
1509 // tell the embedded object to have (or not have) script support
1510 aEmbeddedDescriptor
.put( "EmbeddedScriptSupport", objectSupportsEmbeddedScripts() );
1512 // tell the embedded object to not participate in the document recovery game - the DB doc will handle it
1513 aEmbeddedDescriptor
.put( "DocumentRecoverySupport", false );
1515 // pass the descriptor of the embedded object to the caller
1516 aEmbeddedDescriptor
>>= _out_rEmbeddedObjectDescriptor
;
1518 // create the ComponentData, and put it into the document's media descriptor
1520 ::comphelper::NamedValueCollection aComponentData
;
1521 aComponentData
.put( "ActiveConnection", _xConnection
);
1522 aComponentData
.put( "ApplyFormDesignMode", !_bReadOnly
);
1523 aMediaDesc
.put( "ComponentData", aComponentData
.getPropertyValues() );
1526 if ( !m_pImpl
->m_aProps
.aTitle
.isEmpty() )
1527 aMediaDesc
.put( "DocumentTitle", m_pImpl
->m_aProps
.aTitle
);
1529 aMediaDesc
.put( "DocumentBaseURL", m_pImpl
->m_pDataSource
->getURL() );
1531 // put the common load arguments into the document's media descriptor
1532 lcl_putLoadArgs( aMediaDesc
, optional_bool( _bSuppressMacros
), optional_bool( _bReadOnly
) );
1534 return aMediaDesc
.getPropertyValues();
1537 void ODocumentDefinition::loadEmbeddedObject( const Reference
< XConnection
>& i_rConnection
, const Sequence
< sal_Int8
>& _aClassID
,
1538 const Sequence
< PropertyValue
>& i_rOpenCommandArguments
, const bool _bSuppressMacros
, const bool _bReadOnly
)
1540 if ( !m_xEmbeddedObject
.is() )
1542 Reference
< XStorage
> xStorage
= getContainerStorage();
1543 if ( xStorage
.is() )
1545 Reference
< XEmbeddedObjectCreator
> xEmbedFactory
= OOoEmbeddedObjectFactory::create(m_aContext
);
1546 OUString sDocumentService
;
1547 bool bSetSize
= false;
1548 sal_Int32 nEntryConnectionMode
= EntryInitModes::DEFAULT_INIT
;
1549 Sequence
< sal_Int8
> aClassID
= _aClassID
;
1550 if ( aClassID
.hasElements() )
1552 nEntryConnectionMode
= EntryInitModes::TRUNCATE_INIT
;
1557 sDocumentService
= GetDocumentServiceFromMediaType( getContentType(), m_aContext
, aClassID
);
1558 // check if we are not a form and
1559 // the org.libreoffice.report.pentaho.SOReportJobFactory is not present.
1560 if ( !m_bForm
&& sDocumentService
!= "com.sun.star.text.TextDocument")
1562 // we seem to be a "new style" report, check if report extension is present.
1563 Reference
< XContentEnumerationAccess
> xEnumAccess( m_aContext
->getServiceManager(), UNO_QUERY
);
1564 const OUString sReportEngineServiceName
= ::dbtools::getDefaultReportEngineServiceName(m_aContext
);
1565 Reference
< XEnumeration
> xEnumDrivers
= xEnumAccess
->createContentEnumeration(sReportEngineServiceName
);
1566 if ( !xEnumDrivers
.is() || !xEnumDrivers
->hasMoreElements() )
1568 css::io::WrongFormatException aWFE
;
1569 aWFE
.Message
= DBA_RES( RID_STR_MISSING_EXTENSION
);
1573 if ( !aClassID
.hasElements() )
1576 aClassID
= MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID
);
1579 aClassID
= MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90
);
1584 OSL_ENSURE( aClassID
.hasElements(),"No Class ID" );
1586 Sequence
< PropertyValue
> aEmbeddedObjectDescriptor
;
1587 Sequence
< PropertyValue
> aLoadArgs( fillLoadArgs(
1588 i_rConnection
, _bSuppressMacros
, _bReadOnly
, i_rOpenCommandArguments
, aEmbeddedObjectDescriptor
) );
1590 m_xEmbeddedObject
.set(xEmbedFactory
->createInstanceUserInit(aClassID
1593 ,m_pImpl
->m_aProps
.sPersistentName
1594 ,nEntryConnectionMode
1596 ,aEmbeddedObjectDescriptor
1598 if ( m_xEmbeddedObject
.is() )
1600 if ( !m_pClientHelper
.is() )
1602 m_pClientHelper
= new OEmbeddedClientHelper
;
1604 Reference
<XEmbeddedClient
> xClient
= m_pClientHelper
.get();
1605 m_xEmbeddedObject
->setClientSite(xClient
);
1606 m_xEmbeddedObject
->changeState(EmbedStates::RUNNING
);
1609 LockModifiable
aLockModify( impl_getComponent_throw( false ) );
1611 awt::Size
aSize( DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
1612 m_xEmbeddedObject
->setVisualAreaSize(Aspects::MSOLE_CONTENT
,aSize
);
1619 sal_Int32 nCurrentState
= m_xEmbeddedObject
->getCurrentState();
1620 if ( nCurrentState
== EmbedStates::LOADED
)
1622 if ( !m_pClientHelper
.is() )
1624 m_pClientHelper
= new OEmbeddedClientHelper
;
1626 Reference
<XEmbeddedClient
> xClient
= m_pClientHelper
.get();
1627 m_xEmbeddedObject
->setClientSite(xClient
);
1629 Sequence
< PropertyValue
> aEmbeddedObjectDescriptor
;
1630 Sequence
< PropertyValue
> aLoadArgs( fillLoadArgs(
1631 i_rConnection
, _bSuppressMacros
, _bReadOnly
, i_rOpenCommandArguments
, aEmbeddedObjectDescriptor
) );
1633 Reference
<XCommonEmbedPersist
> xCommon(m_xEmbeddedObject
,UNO_QUERY
);
1634 OSL_ENSURE(xCommon
.is(),"unsupported interface!");
1636 xCommon
->reload( aLoadArgs
, aEmbeddedObjectDescriptor
);
1637 m_xEmbeddedObject
->changeState(EmbedStates::RUNNING
);
1641 OSL_ENSURE( ( nCurrentState
== EmbedStates::RUNNING
) || ( nCurrentState
== EmbedStates::ACTIVE
),
1642 "ODocumentDefinition::loadEmbeddedObject: unexpected state!" );
1644 // if the document was already loaded (which means the embedded object is in state RUNNING or ACTIVE),
1645 // then just re-set some model parameters
1648 // ensure the media descriptor doesn't contain any values which are intended for the
1649 // EmbeddedObjectDescriptor only
1650 ::comphelper::NamedValueCollection aEmbeddedObjectDescriptor
;
1651 ::comphelper::NamedValueCollection aNewMediaDesc
;
1652 separateOpenCommandArguments( i_rOpenCommandArguments
, aNewMediaDesc
, aEmbeddedObjectDescriptor
);
1654 // merge the new media descriptor into the existing media descriptor
1655 const Reference
< XModel
> xModel( getComponent(), UNO_QUERY_THROW
);
1656 const Sequence
< PropertyValue
> aArgs
= xModel
->getArgs();
1657 ::comphelper::NamedValueCollection
aExistentMediaDesc( aArgs
);
1658 aExistentMediaDesc
.merge( aNewMediaDesc
, false );
1660 lcl_putLoadArgs( aExistentMediaDesc
, optional_bool(), optional_bool() );
1661 // don't put _bSuppressMacros and _bReadOnly here - if the document was already
1662 // loaded, we should not tamper with its settings.
1663 // #i88977# #i86872#
1665 xModel
->attachResource( xModel
->getURL(), aExistentMediaDesc
.getPropertyValues() );
1667 catch( const Exception
& )
1669 DBG_UNHANDLED_EXCEPTION("dbaccess");
1674 // set the OfficeDatabaseDocument instance as parent of the embedded document
1676 Reference
< XChild
> xDepdendDocAsChild( getComponent(), UNO_QUERY
);
1677 if ( xDepdendDocAsChild
.is() )
1681 if ( !xDepdendDocAsChild
->getParent().is() )
1682 { // first encounter
1683 xDepdendDocAsChild
->setParent( getDataSource( m_xParentContainer
) );
1686 catch( const Exception
& )
1688 DBG_UNHANDLED_EXCEPTION("dbaccess");
1692 if ( i_rConnection
.is() )
1693 m_xLastKnownConnection
= i_rConnection
;
1696 void ODocumentDefinition::onCommandPreview(Any
& _rImage
)
1698 loadEmbeddedObjectForPreview();
1699 if ( !m_xEmbeddedObject
.is() )
1704 Reference
<XTransferable
> xTransfer(getComponent(),UNO_QUERY
);
1705 if ( xTransfer
.is() )
1708 aFlavor
.MimeType
= "image/png";
1709 aFlavor
.HumanPresentableName
= "Portable Network Graphics";
1710 aFlavor
.DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
1712 _rImage
= xTransfer
->getTransferData( aFlavor
);
1715 catch( const Exception
& )
1720 void ODocumentDefinition::getPropertyDefaultByHandle( sal_Int32
/*_nHandle*/, Any
& _rDefault
) const
1725 void ODocumentDefinition::onCommandGetDocumentProperties( Any
& _rProps
)
1727 loadEmbeddedObjectForPreview();
1728 if ( !m_xEmbeddedObject
.is() )
1733 Reference
<XDocumentPropertiesSupplier
> xDocSup(
1734 getComponent(), UNO_QUERY
);
1736 _rProps
<<= xDocSup
->getDocumentProperties();
1738 catch( const Exception
& )
1740 DBG_UNHANDLED_EXCEPTION("dbaccess");
1744 Reference
< util::XCloseable
> ODocumentDefinition::impl_getComponent_throw( const bool i_ForceCreate
)
1746 OSL_ENSURE(m_xEmbeddedObject
.is(),"Illegal call for embeddedObject");
1747 Reference
< util::XCloseable
> xComp
;
1748 if ( m_xEmbeddedObject
.is() )
1750 int nState
= m_xEmbeddedObject
->getCurrentState();
1751 if ( ( nState
== EmbedStates::LOADED
) && i_ForceCreate
)
1753 m_xEmbeddedObject
->changeState( EmbedStates::RUNNING
);
1754 nState
= m_xEmbeddedObject
->getCurrentState();
1755 OSL_ENSURE( nState
== EmbedStates::RUNNING
, "ODocumentDefinition::impl_getComponent_throw: could not switch to RUNNING!" );
1758 if ( nState
== EmbedStates::ACTIVE
|| nState
== EmbedStates::RUNNING
)
1760 if ( m_xEmbeddedObject
.is() )
1762 xComp
= m_xEmbeddedObject
->getComponent();
1763 OSL_ENSURE(xComp
.is(),"No valid component");
1770 Reference
< util::XCloseable
> ODocumentDefinition::getComponent()
1772 ::osl::MutexGuard
aGuard( m_aMutex
);
1773 return impl_getComponent_throw();
1778 Reference
< XDatabaseDocumentUI
> lcl_getDatabaseDocumentUI( ODatabaseModelImpl
const & _rModelImpl
)
1780 Reference
< XDatabaseDocumentUI
> xUI
;
1782 Reference
< XModel
> xModel( _rModelImpl
.getModel_noCreate() );
1784 xUI
.set( xModel
->getCurrentController(), UNO_QUERY
);
1789 Reference
< XComponent
> ODocumentDefinition::impl_openUI_nolck_throw( bool _bForEditing
)
1791 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
1792 if ( !m_pImpl
|| !m_pImpl
->m_pDataSource
)
1793 throw DisposedException();
1795 Reference
< XComponent
> xComponent
;
1798 Reference
< XDatabaseDocumentUI
> xUI( lcl_getDatabaseDocumentUI( *m_pImpl
->m_pDataSource
) );
1801 // no XDatabaseDocumentUI -> just execute the respective command
1802 m_bOpenInDesign
= _bForEditing
;
1803 xComponent
= Reference
<XComponent
>(onCommandOpenSomething(Any(), true, nullptr), UNO_QUERY
);
1804 OSL_ENSURE( xComponent
.is(), "ODocumentDefinition::impl_openUI_nolck_throw: opening the thingie failed." );
1809 OUString
sName( impl_getHierarchicalName( false ) );
1810 sal_Int32 nObjectType
= m_bForm
? DatabaseObject::FORM
: DatabaseObject::REPORT
;
1813 xComponent
= xUI
->loadComponent(
1814 nObjectType
, sName
, _bForEditing
1817 catch( const RuntimeException
& ) { throw; }
1818 catch( const Exception
& )
1820 throw WrappedTargetException(
1821 OUString(), *this, ::cppu::getCaughtException() );
1827 void ODocumentDefinition::impl_store_throw()
1829 Reference
<XEmbedPersist
> xPersist( m_xEmbeddedObject
, UNO_QUERY
);
1830 if ( xPersist
.is() )
1832 xPersist
->storeOwn();
1833 notifyDataSourceModified();
1837 bool ODocumentDefinition::impl_close_throw()
1839 bool bSuccess
= prepareClose();
1840 if ( bSuccess
&& m_xEmbeddedObject
.is() )
1842 m_xEmbeddedObject
->changeState( EmbedStates::LOADED
);
1843 bSuccess
= m_xEmbeddedObject
->getCurrentState() == EmbedStates::LOADED
;
1848 Reference
< XComponent
> SAL_CALL
ODocumentDefinition::open( )
1850 return impl_openUI_nolck_throw( false );
1853 Reference
< XComponent
> SAL_CALL
ODocumentDefinition::openDesign( )
1855 return impl_openUI_nolck_throw( true );
1858 void SAL_CALL
ODocumentDefinition::store( )
1860 ::osl::MutexGuard
aGuard( m_aMutex
);
1865 catch( const RuntimeException
& ) { throw; }
1866 catch( const Exception
& )
1868 throw WrappedTargetException(
1869 OUString(), *this, ::cppu::getCaughtException() );
1873 sal_Bool SAL_CALL
ODocumentDefinition::close( )
1875 ::osl::MutexGuard
aGuard( m_aMutex
);
1877 bool bSuccess
= false;
1880 bSuccess
= impl_close_throw();
1882 catch( const RuntimeException
& ) { throw; }
1883 catch( const Exception
& )
1885 throw WrappedTargetException(
1886 OUString(), *this, ::cppu::getCaughtException() );
1891 OUString SAL_CALL
ODocumentDefinition::getHierarchicalName()
1893 ::osl::MutexGuard
aGuard( m_aMutex
);
1894 return impl_getHierarchicalName( false );
1897 OUString SAL_CALL
ODocumentDefinition::composeHierarchicalName( const OUString
& i_rRelativeName
)
1899 OUStringBuffer aBuffer
;
1900 aBuffer
.append( getHierarchicalName() );
1901 aBuffer
.append( '/' );
1902 aBuffer
.append( i_rRelativeName
);
1903 return aBuffer
.makeStringAndClear();
1906 void SAL_CALL
ODocumentDefinition::rename( const OUString
& _rNewName
)
1910 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
1911 if ( _rNewName
== m_pImpl
->m_aProps
.aTitle
)
1914 // document definitions are organized in a hierarchical way, so reject names
1915 // which contain a /, as this is reserved for hierarchy level separation
1916 if ( _rNewName
.indexOf( '/' ) != -1 )
1917 m_aErrorHelper
.raiseException( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES
, *this );
1919 NameChangeNotifier
aNameChangeAndNotify( *this, _rNewName
, aGuard
);
1920 m_pImpl
->m_aProps
.aTitle
= _rNewName
;
1922 if ( m_xEmbeddedObject
.is() && m_xEmbeddedObject
->getCurrentState() == EmbedStates::ACTIVE
)
1923 updateDocumentTitle();
1925 catch(const PropertyVetoException
&)
1927 throw ElementExistException(_rNewName
,*this);
1931 Reference
< XStorage
> ODocumentDefinition::getContainerStorage() const
1933 return m_pImpl
->m_pDataSource
1934 ? m_pImpl
->m_pDataSource
->getStorage( m_bForm
? ODatabaseModelImpl::E_FORM
: ODatabaseModelImpl::E_REPORT
)
1935 : Reference
< XStorage
>();
1938 bool ODocumentDefinition::isModified()
1940 osl::ClearableGuard
< osl::Mutex
> aGuard(m_aMutex
);
1942 if ( m_xEmbeddedObject
.is() )
1944 Reference
<XModifiable
> xModel(getComponent(),UNO_QUERY
);
1945 bRet
= xModel
.is() && xModel
->isModified();
1950 bool ODocumentDefinition::prepareClose()
1952 if ( !m_xEmbeddedObject
.is() )
1957 // suspend the controller. Embedded objects are not allowed to raise
1958 // own UI at their own discretion, instead, this has always to be triggered
1959 // by the embedding component. Thus, we do the suspend call here.
1962 Reference
< util::XCloseable
> xComponent( impl_getComponent_throw( false ) );
1963 if ( !xComponent
.is() )
1966 Reference
< XModel
> xModel( xComponent
, UNO_QUERY
);
1967 Reference
< XController
> xController
;
1969 xController
= xModel
->getCurrentController();
1971 OSL_ENSURE( xController
.is() || ( m_xEmbeddedObject
->getCurrentState() < EmbedStates::ACTIVE
),
1972 "ODocumentDefinition::prepareClose: no controller!" );
1973 if ( !xController
.is() )
1974 // document has not yet been activated, i.e. has no UI, yet
1977 if (!xController
->suspend(true))
1978 // controller vetoed the closing
1983 Reference
< XFrame
> xFrame( xController
->getFrame() );
1984 Reference
<XTopWindow
> xTopWindow
;
1987 xTopWindow
= Reference
<XTopWindow
>(xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
1988 xTopWindow
->toFront();
1990 if (!save(true, xTopWindow
))
1992 // revert suspension
1993 xController
->suspend(false);
1994 // saving failed or was cancelled
1999 catch( const Exception
& )
2001 DBG_UNHANDLED_EXCEPTION("dbaccess");
2007 void ODocumentDefinition::fillReportData( const Reference
< XComponentContext
>& _rContext
,
2008 const Reference
< util::XCloseable
>& _rxComponent
,
2009 const Reference
< XConnection
>& _rxActiveConnection
)
2011 uno::Sequence
<uno::Any
> aArgs(comphelper::InitAnyPropertySequence(
2013 {"TextDocument", uno::Any(_rxComponent
)},
2014 {"ActiveConnection", uno::Any(_rxActiveConnection
)}
2018 Reference
< XJobExecutor
> xExecutable(
2019 _rContext
->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.wizards.report.CallReportWizard", aArgs
, _rContext
), UNO_QUERY_THROW
);
2020 xExecutable
->trigger( "fill" );
2022 catch( const Exception
& )
2024 DBG_UNHANDLED_EXCEPTION("dbaccess");
2028 void ODocumentDefinition::updateDocumentTitle()
2030 OUString sName
= m_pImpl
->m_aProps
.aTitle
;
2031 if ( m_pImpl
->m_pDataSource
)
2033 if ( sName
.isEmpty() )
2036 sName
= DBA_RES( RID_STR_FORM
);
2038 sName
= DBA_RES( RID_STR_REPORT
);
2039 Reference
< XUntitledNumbers
> xUntitledProvider(m_pImpl
->m_pDataSource
->getModel_noCreate(), UNO_QUERY
);
2040 if ( xUntitledProvider
.is() )
2041 sName
+= OUString::number( xUntitledProvider
->leaseNumber(getComponent()) );
2044 Reference
< XTitle
> xDatabaseDocumentModel(m_pImpl
->m_pDataSource
->getModel_noCreate(),uno::UNO_QUERY
);
2045 if ( xDatabaseDocumentModel
.is() )
2046 sName
= xDatabaseDocumentModel
->getTitle() + " : " + sName
;
2048 Reference
< XTitle
> xTitle(getComponent(),UNO_QUERY
);
2050 xTitle
->setTitle(sName
);
2053 void SAL_CALL
ODocumentDefinition::queryClosing( const lang::EventObject
&, sal_Bool
)
2058 throw util::CloseVetoException();
2060 catch(const lang::WrappedTargetException
&)
2062 throw util::CloseVetoException();
2066 void SAL_CALL
ODocumentDefinition::notifyClosing( const lang::EventObject
& /*Source*/ )
2070 void SAL_CALL
ODocumentDefinition::disposing( const lang::EventObject
& /*Source*/ )
2074 void ODocumentDefinition::firePropertyChange( sal_Int32 i_nHandle
, const Any
& i_rNewValue
, const Any
& i_rOldValue
,
2075 bool i_bVetoable
, const NotifierAccess
& )
2077 fire( &i_nHandle
, &i_rNewValue
, &i_rOldValue
, 1, i_bVetoable
);
2080 // NameChangeNotifier
2081 NameChangeNotifier::NameChangeNotifier( ODocumentDefinition
& i_rDocumentDefinition
, const OUString
& i_rNewName
,
2082 ::osl::ResettableMutexGuard
& i_rClearForNotify
)
2083 :m_rDocumentDefinition( i_rDocumentDefinition
)
2084 ,m_aOldValue( makeAny( i_rDocumentDefinition
.getCurrentName() ) )
2085 ,m_aNewValue( makeAny( i_rNewName
) )
2086 ,m_rClearForNotify( i_rClearForNotify
)
2088 impl_fireEvent_throw( true );
2091 NameChangeNotifier::~NameChangeNotifier()
2093 impl_fireEvent_throw( false );
2096 void NameChangeNotifier::impl_fireEvent_throw( const bool i_bVetoable
)
2098 m_rClearForNotify
.clear();
2099 m_rDocumentDefinition
.firePropertyChange(
2100 PROPERTY_ID_NAME
, m_aNewValue
, m_aOldValue
, i_bVetoable
, ODocumentDefinition::NotifierAccess() );
2101 m_rClearForNotify
.reset();
2104 } // namespace dbaccess
2106 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */