summaryrefslogtreecommitdiff
path: root/embeddedobj/source/commonembedding/embedobj.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'embeddedobj/source/commonembedding/embedobj.cxx')
-rw-r--r--embeddedobj/source/commonembedding/embedobj.cxx145
1 files changed, 108 insertions, 37 deletions
diff --git a/embeddedobj/source/commonembedding/embedobj.cxx b/embeddedobj/source/commonembedding/embedobj.cxx
index 223f25e6302c..61e5d1f39ef4 100644
--- a/embeddedobj/source/commonembedding/embedobj.cxx
+++ b/embeddedobj/source/commonembedding/embedobj.cxx
@@ -40,6 +40,7 @@
#include <comphelper/multicontainer2.hxx>
#include <comphelper/lok.hxx>
#include <sal/log.hxx>
+#include <officecfg/Office/Common.hxx>
#include <vcl/svapp.hxx>
@@ -48,6 +49,7 @@
#include <commonembobj.hxx>
#include "embedobj.hxx"
#include <specialobject.hxx>
+#include <array>
using namespace ::com::sun::star;
@@ -71,6 +73,60 @@ awt::Rectangle GetRectangleInterception( const awt::Rectangle& aRect1, const awt
return aResult;
}
+namespace
+{
+ using IntermediateStatesMap = std::array<std::array<uno::Sequence< sal_Int32 >, NUM_SUPPORTED_STATES>, NUM_SUPPORTED_STATES>;
+ const IntermediateStatesMap & getIntermediateStatesMap()
+ {
+ static const IntermediateStatesMap map = [] () {
+ IntermediateStatesMap tmp;
+
+ // intermediate states
+ // In the following table the first index points to starting state,
+ // the second one to the target state, and the sequence referenced by
+ // first two indexes contains intermediate states, that should be
+ // passed by object to reach the target state.
+ // If the sequence is empty that means that indirect switch from start
+ // state to the target state is forbidden, only if direct switch is possible
+ // the state can be reached.
+
+ tmp[0][2] = { embed::EmbedStates::RUNNING };
+
+ tmp[0][3] = { embed::EmbedStates::RUNNING,
+ embed::EmbedStates::INPLACE_ACTIVE };
+
+ tmp[0][4] = {embed::EmbedStates::RUNNING};
+
+ tmp[1][3] = { embed::EmbedStates::INPLACE_ACTIVE };
+
+ tmp[2][0] = { embed::EmbedStates::RUNNING };
+
+ tmp[3][0] = { embed::EmbedStates::INPLACE_ACTIVE,
+ embed::EmbedStates::RUNNING };
+
+ tmp[3][1] = { embed::EmbedStates::INPLACE_ACTIVE };
+
+ tmp[4][0] = { embed::EmbedStates::RUNNING };
+
+ return tmp;
+ }();
+ return map;
+ }
+
+ // accepted states
+ const css::uno::Sequence< sal_Int32 > & getAcceptedStates()
+ {
+ static const css::uno::Sequence< sal_Int32 > states {
+ /* [0] */ embed::EmbedStates::LOADED,
+ /* [1] */ embed::EmbedStates::RUNNING,
+ /* [2] */ embed::EmbedStates::INPLACE_ACTIVE,
+ /* [3] */ embed::EmbedStates::UI_ACTIVE,
+ /* [4] */ embed::EmbedStates::ACTIVE };
+ assert(states.getLength() == NUM_SUPPORTED_STATES);
+ return states;
+ }
+
+}
sal_Int32 OCommonEmbeddedObject::ConvertVerbToState_Impl( sal_Int32 nVerb )
{
@@ -161,6 +217,37 @@ void OCommonEmbeddedObject::StateChangeNotification_Impl( bool bBeforeChange, sa
rGuard.reset();
}
+void OCommonEmbeddedObject::SetInplaceActiveState()
+{
+ if ( !m_xClientSite.is() )
+ throw embed::WrongStateException( "client site not set, yet", *this );
+
+ uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
+ if ( !xInplaceClient.is() || !xInplaceClient->canInplaceActivate() )
+ throw embed::WrongStateException(); //TODO: can't activate inplace
+ xInplaceClient->activatingInplace();
+
+ uno::Reference< embed::XWindowSupplier > xClientWindowSupplier( xInplaceClient, uno::UNO_QUERY_THROW );
+
+ m_xClientWindow = xClientWindowSupplier->getWindow();
+ m_aOwnRectangle = xInplaceClient->getPlacement();
+ m_aClipRectangle = xInplaceClient->getClipRectangle();
+ awt::Rectangle aRectangleToShow = GetRectangleInterception( m_aOwnRectangle, m_aClipRectangle );
+
+ // create own window based on the client window
+ // place and resize the window according to the rectangles
+ uno::Reference< awt::XWindowPeer > xClientWindowPeer( m_xClientWindow, uno::UNO_QUERY_THROW );
+
+ // dispatch provider may not be provided
+ uno::Reference< frame::XDispatchProvider > xContainerDP = xInplaceClient->getInplaceDispatchProvider();
+ bool bOk = m_xDocHolder->ShowInplace( xClientWindowPeer, aRectangleToShow, xContainerDP );
+ m_nObjectState = embed::EmbedStates::INPLACE_ACTIVE;
+ if ( !bOk )
+ {
+ SwitchStateTo_Impl( embed::EmbedStates::RUNNING );
+ throw embed::WrongStateException(); //TODO: can't activate inplace
+ }
+}
void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
{
@@ -234,34 +321,7 @@ void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
{
if ( nNextState == embed::EmbedStates::INPLACE_ACTIVE )
{
- if ( !m_xClientSite.is() )
- throw embed::WrongStateException( "client site not set, yet", *this );
-
- uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
- if ( !xInplaceClient.is() || !xInplaceClient->canInplaceActivate() )
- throw embed::WrongStateException(); //TODO: can't activate inplace
- xInplaceClient->activatingInplace();
-
- uno::Reference< embed::XWindowSupplier > xClientWindowSupplier( xInplaceClient, uno::UNO_QUERY_THROW );
-
- m_xClientWindow = xClientWindowSupplier->getWindow();
- m_aOwnRectangle = xInplaceClient->getPlacement();
- m_aClipRectangle = xInplaceClient->getClipRectangle();
- awt::Rectangle aRectangleToShow = GetRectangleInterception( m_aOwnRectangle, m_aClipRectangle );
-
- // create own window based on the client window
- // place and resize the window according to the rectangles
- uno::Reference< awt::XWindowPeer > xClientWindowPeer( m_xClientWindow, uno::UNO_QUERY_THROW );
-
- // dispatch provider may not be provided
- uno::Reference< frame::XDispatchProvider > xContainerDP = xInplaceClient->getInplaceDispatchProvider();
- bool bOk = m_xDocHolder->ShowInplace( xClientWindowPeer, aRectangleToShow, xContainerDP );
- m_nObjectState = nNextState;
- if ( !bOk )
- {
- SwitchStateTo_Impl( embed::EmbedStates::RUNNING );
- throw embed::WrongStateException(); //TODO: can't activate inplace
- }
+ SetInplaceActiveState();
}
else if ( nNextState == embed::EmbedStates::ACTIVE )
{
@@ -389,32 +449,36 @@ void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
uno::Sequence< sal_Int32 > const & OCommonEmbeddedObject::GetIntermediateStatesSequence_Impl( sal_Int32 nNewState )
{
sal_Int32 nCurInd = 0;
- for ( nCurInd = 0; nCurInd < m_aAcceptedStates.getLength(); nCurInd++ )
- if ( m_aAcceptedStates[nCurInd] == m_nObjectState )
+ auto & rAcceptedStates = getAcceptedStates();
+ for ( nCurInd = 0; nCurInd < rAcceptedStates.getLength(); nCurInd++ )
+ if ( rAcceptedStates[nCurInd] == m_nObjectState )
break;
- if ( nCurInd == m_aAcceptedStates.getLength() )
+ if ( nCurInd == rAcceptedStates.getLength() )
throw embed::WrongStateException( "The object is in unacceptable state!",
static_cast< ::cppu::OWeakObject* >(this) );
sal_Int32 nDestInd = 0;
- for ( nDestInd = 0; nDestInd < m_aAcceptedStates.getLength(); nDestInd++ )
- if ( m_aAcceptedStates[nDestInd] == nNewState )
+ for ( nDestInd = 0; nDestInd < rAcceptedStates.getLength(); nDestInd++ )
+ if ( rAcceptedStates[nDestInd] == nNewState )
break;
- if ( nDestInd == m_aAcceptedStates.getLength() )
+ if ( nDestInd == rAcceptedStates.getLength() )
throw embed::UnreachableStateException(
"The state either not reachable, or the object allows the state only as an intermediate one!",
static_cast< ::cppu::OWeakObject* >(this),
m_nObjectState,
nNewState );
- return m_pIntermediateStatesSeqs[nCurInd][nDestInd];
+ return getIntermediateStatesMap()[nCurInd][nDestInd];
}
void SAL_CALL OCommonEmbeddedObject::changeState( sal_Int32 nNewState )
{
+ if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get()
+ && nNewState != embed::EmbedStates::LOADED )
+ throw embed::UnreachableStateException();
::osl::ResettableMutexGuard aGuard( m_aMutex );
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
@@ -453,7 +517,7 @@ void SAL_CALL OCommonEmbeddedObject::changeState( sal_Int32 nNewState )
StateChangeNotification_Impl( true, nOldState, nNewState,aGuard );
try {
- for ( sal_Int32 state : std::as_const(aIntermediateStates) )
+ for (sal_Int32 state : aIntermediateStates)
SwitchStateTo_Impl( state );
SwitchStateTo_Impl( nNewState );
@@ -486,7 +550,7 @@ uno::Sequence< sal_Int32 > SAL_CALL OCommonEmbeddedObject::getReachableStates()
throw embed::WrongStateException( "The object has no persistence!",
static_cast< ::cppu::OWeakObject* >(this) );
- return m_aAcceptedStates;
+ return getAcceptedStates();
}
@@ -639,6 +703,13 @@ void SAL_CALL OCommonEmbeddedObject::setContainerName( const OUString& sName )
m_aContainerName = sName;
}
+void OCommonEmbeddedObject::SetOleState(bool bIsOleUpdate)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_bOleUpdate = bIsOleUpdate;
+}
+
css::uno::Reference< css::uno::XInterface > SAL_CALL OCommonEmbeddedObject::getParent()
{
return m_xParent;