Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <com/sun/star/embed/EmbedStates.hpp>
21 : #include <com/sun/star/embed/EmbedVerbs.hpp>
22 : #include <com/sun/star/embed/EmbedUpdateModes.hpp>
23 : #include <com/sun/star/embed/XEmbeddedClient.hpp>
24 : #include <com/sun/star/embed/XInplaceClient.hpp>
25 : #include <com/sun/star/embed/XWindowSupplier.hpp>
26 : #include <com/sun/star/embed/StateChangeInProgressException.hpp>
27 : #include <com/sun/star/embed/Aspects.hpp>
28 :
29 : #include <com/sun/star/awt/XWindowPeer.hpp>
30 : #include <com/sun/star/util/XCloseBroadcaster.hpp>
31 : #include <com/sun/star/util/XCloseable.hpp>
32 : #include <com/sun/star/util/XModifiable.hpp>
33 : #include <com/sun/star/frame/XFrame.hpp>
34 : #include <com/sun/star/frame/XComponentLoader.hpp>
35 : #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
36 : #include <com/sun/star/frame/ModuleManager.hpp>
37 : #include <com/sun/star/lang/DisposedException.hpp>
38 :
39 : #include <com/sun/star/embed/EmbedMisc.hpp>
40 : #include <comphelper/processfactory.hxx>
41 :
42 : #include <rtl/logfile.hxx>
43 : #include <vcl/svapp.hxx>
44 :
45 : #include <targetstatecontrol.hxx>
46 :
47 : #include "commonembobj.hxx"
48 : #include "intercept.hxx"
49 :
50 :
51 : using namespace ::com::sun::star;
52 :
53 0 : awt::Rectangle GetRectangleInterception( const awt::Rectangle& aRect1, const awt::Rectangle& aRect2 )
54 : {
55 0 : awt::Rectangle aResult;
56 :
57 : OSL_ENSURE( aRect1.Width >= 0 && aRect2.Width >= 0 && aRect1.Height >= 0 && aRect2.Height >= 0,
58 : "Offset must not be less then zero!" );
59 :
60 0 : aResult.X = aRect1.X > aRect2.X ? aRect1.X : aRect2.X;
61 0 : aResult.Y = aRect1.Y > aRect2.Y ? aRect1.Y : aRect2.Y;
62 :
63 0 : sal_Int32 nRight1 = aRect1.X + aRect1.Width;
64 0 : sal_Int32 nBottom1 = aRect1.Y + aRect1.Height;
65 0 : sal_Int32 nRight2 = aRect2.X + aRect2.Width;
66 0 : sal_Int32 nBottom2 = aRect2.Y + aRect2.Height;
67 0 : aResult.Width = ( nRight1 < nRight2 ? nRight1 : nRight2 ) - aResult.X;
68 0 : aResult.Height = ( nBottom1 < nBottom2 ? nBottom1 : nBottom2 ) - aResult.Y;
69 :
70 0 : return aResult;
71 : }
72 :
73 : //----------------------------------------------
74 0 : sal_Int32 OCommonEmbeddedObject::ConvertVerbToState_Impl( sal_Int32 nVerb )
75 : {
76 0 : for ( sal_Int32 nInd = 0; nInd < m_aVerbTable.getLength(); nInd++ )
77 0 : if ( m_aVerbTable[nInd][0] == nVerb )
78 0 : return m_aVerbTable[nInd][1];
79 :
80 0 : throw lang::IllegalArgumentException(); // TODO: unexpected verb provided
81 : }
82 :
83 : //----------------------------------------------
84 0 : void OCommonEmbeddedObject::Deactivate()
85 : {
86 0 : uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
87 :
88 : // no need to lock for the initialization
89 0 : uno::Reference< embed::XEmbeddedClient > xClientSite = m_xClientSite;
90 0 : if ( !xClientSite.is() )
91 0 : throw embed::WrongStateException(); //TODO: client site is not set!
92 :
93 : // store document if it is modified
94 0 : if ( xModif.is() && xModif->isModified() )
95 : {
96 : try {
97 0 : xClientSite->saveObject();
98 : }
99 0 : catch( const embed::ObjectSaveVetoException& )
100 : {
101 : }
102 0 : catch( const uno::Exception& e )
103 : {
104 : throw embed::StorageWrappedTargetException(
105 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The client could not store the object!" )),
106 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
107 0 : uno::makeAny( e ) );
108 : }
109 : }
110 :
111 0 : m_pDocHolder->CloseFrame();
112 :
113 0 : xClientSite->visibilityChanged( sal_False );
114 0 : }
115 :
116 : //----------------------------------------------
117 289 : void OCommonEmbeddedObject::StateChangeNotification_Impl( sal_Bool bBeforeChange, sal_Int32 nOldState, sal_Int32 nNewState ,::osl::ResettableMutexGuard& rGuard )
118 : {
119 289 : if ( m_pInterfaceContainer )
120 : {
121 : ::cppu::OInterfaceContainerHelper* pContainer = m_pInterfaceContainer->getContainer(
122 289 : ::getCppuType( ( const uno::Reference< embed::XStateChangeListener >*) NULL ) );
123 289 : if ( pContainer != NULL )
124 : {
125 289 : lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );
126 289 : ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
127 :
128 : // should be locked after the method is finished successfully
129 289 : rGuard.clear();
130 :
131 708 : while (pIterator.hasMoreElements())
132 : {
133 : try
134 : {
135 130 : if ( bBeforeChange )
136 68 : ((embed::XStateChangeListener*)pIterator.next())->changingState( aSource, nOldState, nNewState );
137 : else
138 62 : ((embed::XStateChangeListener*)pIterator.next())->stateChanged( aSource, nOldState, nNewState );
139 : }
140 0 : catch( const uno::Exception& )
141 : {
142 : // even if the listener complains ignore it for now
143 : }
144 :
145 130 : if ( m_bDisposed )
146 289 : return;
147 : }
148 :
149 289 : rGuard.reset();
150 : }
151 : }
152 : }
153 :
154 : //----------------------------------------------
155 146 : void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
156 : {
157 : // TODO: may be needs interaction handler to detect wherether the object state
158 : // can be changed even after errors
159 :
160 146 : if ( m_nObjectState == embed::EmbedStates::LOADED )
161 : {
162 3 : if ( nNextState == embed::EmbedStates::RUNNING )
163 : {
164 : // after the object reaches the running state the cloned size is not necessary any more
165 3 : m_bHasClonedSize = sal_False;
166 :
167 3 : if ( m_bIsLink )
168 : {
169 0 : m_pDocHolder->SetComponent( LoadLink_Impl(), m_bReadOnly );
170 : }
171 : else
172 : {
173 3 : uno::Reference < embed::XEmbedPersist > xPersist( static_cast < embed::XClassifiedObject* > (this), uno::UNO_QUERY );
174 3 : if ( xPersist.is() )
175 : {
176 : // in case embedded object is in loaded state the contents must
177 : // be stored in the related storage and the storage
178 : // must be created already
179 3 : if ( !m_xObjectStorage.is() )
180 0 : throw io::IOException(); //TODO: access denied
181 :
182 3 : m_pDocHolder->SetComponent( LoadDocumentFromStorage_Impl(), m_bReadOnly );
183 : }
184 : else
185 : {
186 : // objects without persistence will be initialized internally
187 0 : uno::Sequence < uno::Any > aArgs(1);
188 0 : aArgs[0] <<= uno::Reference < embed::XEmbeddedObject >( this );
189 : uno::Reference< util::XCloseable > xDocument(
190 0 : m_xFactory->createInstanceWithArguments( GetDocumentServiceName(), aArgs ), uno::UNO_QUERY );
191 :
192 0 : uno::Reference < container::XChild > xChild( xDocument, uno::UNO_QUERY );
193 0 : if ( xChild.is() )
194 0 : xChild->setParent( m_xParent );
195 :
196 0 : m_pDocHolder->SetComponent( xDocument, m_bReadOnly );
197 3 : }
198 : }
199 :
200 0 : if ( !m_pDocHolder->GetComponent().is() )
201 0 : throw embed::UnreachableStateException(); //TODO: can't open document
202 :
203 0 : m_nObjectState = nNextState;
204 : }
205 : else
206 : {
207 : OSL_FAIL( "Unacceptable state switch!\n" );
208 0 : throw uno::RuntimeException(); // TODO
209 : }
210 : }
211 143 : else if ( m_nObjectState == embed::EmbedStates::RUNNING )
212 : {
213 143 : if ( nNextState == embed::EmbedStates::LOADED )
214 : {
215 143 : m_nClonedMapUnit = m_pDocHolder->GetMapUnit( embed::Aspects::MSOLE_CONTENT );
216 143 : m_bHasClonedSize = m_pDocHolder->GetExtent( embed::Aspects::MSOLE_CONTENT, &m_aClonedSize );
217 :
218 : // actually frame should not exist at this point
219 143 : m_pDocHolder->CloseDocument( sal_False, sal_False );
220 :
221 143 : m_nObjectState = nNextState;
222 : }
223 : else
224 : {
225 0 : if ( nNextState == embed::EmbedStates::INPLACE_ACTIVE )
226 : {
227 0 : if ( !m_xClientSite.is() )
228 : throw embed::WrongStateException(
229 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "client site not set, yet" ) ),
230 : *this
231 0 : );
232 :
233 0 : uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
234 0 : if ( xInplaceClient.is() && xInplaceClient->canInplaceActivate() )
235 : {
236 0 : xInplaceClient->activatingInplace();
237 :
238 0 : uno::Reference< embed::XWindowSupplier > xClientWindowSupplier( xInplaceClient, uno::UNO_QUERY );
239 0 : if ( !xClientWindowSupplier.is() )
240 0 : throw uno::RuntimeException(); // TODO: the inplace client implementation must support XWinSupp
241 :
242 0 : m_xClientWindow = xClientWindowSupplier->getWindow();
243 0 : m_aOwnRectangle = xInplaceClient->getPlacement();
244 0 : m_aClipRectangle = xInplaceClient->getClipRectangle();
245 0 : awt::Rectangle aRectangleToShow = GetRectangleInterception( m_aOwnRectangle, m_aClipRectangle );
246 :
247 : // create own window based on the client window
248 : // place and resize the window according to the rectangles
249 0 : uno::Reference< awt::XWindowPeer > xClientWindowPeer( m_xClientWindow, uno::UNO_QUERY );
250 0 : if ( !xClientWindowPeer.is() )
251 0 : throw uno::RuntimeException(); // TODO: the container window must support the interface
252 :
253 : // dispatch provider may not be provided
254 0 : uno::Reference< frame::XDispatchProvider > xContainerDP = xInplaceClient->getInplaceDispatchProvider();
255 0 : sal_Bool bOk = m_pDocHolder->ShowInplace( xClientWindowPeer, aRectangleToShow, xContainerDP );
256 0 : m_nObjectState = nNextState;
257 0 : if ( !bOk )
258 : {
259 0 : SwitchStateTo_Impl( embed::EmbedStates::RUNNING );
260 0 : throw embed::WrongStateException(); //TODO: can't activate inplace
261 0 : }
262 : }
263 : else
264 0 : throw embed::WrongStateException(); //TODO: can't activate inplace
265 : }
266 0 : else if ( nNextState == embed::EmbedStates::ACTIVE )
267 : {
268 0 : if ( !m_xClientSite.is() )
269 0 : throw embed::WrongStateException(); //TODO: client site is not set!
270 :
271 : // create frame and load document in the frame
272 0 : m_pDocHolder->Show();
273 :
274 0 : m_xClientSite->visibilityChanged( sal_True );
275 0 : m_nObjectState = nNextState;
276 : }
277 : else
278 : {
279 : OSL_FAIL( "Unacceptable state switch!\n" );
280 0 : throw uno::RuntimeException(); // TODO
281 : }
282 : }
283 : }
284 0 : else if ( m_nObjectState == embed::EmbedStates::INPLACE_ACTIVE )
285 : {
286 0 : if ( nNextState == embed::EmbedStates::RUNNING )
287 : {
288 0 : uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
289 0 : if ( !xInplaceClient.is() )
290 0 : throw uno::RuntimeException();
291 :
292 0 : m_xClientSite->visibilityChanged( sal_True );
293 :
294 0 : xInplaceClient->deactivatedInplace();
295 0 : Deactivate();
296 0 : m_nObjectState = nNextState;
297 : }
298 0 : else if ( nNextState == embed::EmbedStates::UI_ACTIVE )
299 : {
300 0 : if ( !(m_nMiscStatus & embed::EmbedMisc::MS_EMBED_NOUIACTIVATE) )
301 : {
302 0 : uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY_THROW );
303 : // TODO:
304 : uno::Reference< ::com::sun::star::frame::XLayoutManager > xContainerLM =
305 0 : xInplaceClient->getLayoutManager();
306 0 : if ( xContainerLM.is() )
307 : {
308 : // dispatch provider may not be provided
309 0 : uno::Reference< frame::XDispatchProvider > xContainerDP = xInplaceClient->getInplaceDispatchProvider();
310 :
311 : // get the container module name
312 0 : ::rtl::OUString aModuleName;
313 : try
314 : {
315 0 : uno::Reference< embed::XComponentSupplier > xCompSupl( m_xClientSite, uno::UNO_QUERY_THROW );
316 0 : uno::Reference< uno::XInterface > xContDoc( xCompSupl->getComponent(), uno::UNO_QUERY_THROW );
317 :
318 0 : uno::Reference< frame::XModuleManager2 > xManager( frame::ModuleManager::create(comphelper::getComponentContext(m_xFactory)) );
319 :
320 0 : aModuleName = xManager->identify( xContDoc );
321 : }
322 0 : catch( const uno::Exception& )
323 : {}
324 :
325 : // if currently another object is UIactive it will be deactivated; usually this will activate the LM of
326 : // the container. Locking the LM will prevent flicker.
327 0 : xContainerLM->lock();
328 0 : xInplaceClient->activatingUI();
329 0 : sal_Bool bOk = m_pDocHolder->ShowUI( xContainerLM, xContainerDP, aModuleName );
330 0 : xContainerLM->unlock();
331 :
332 0 : if ( bOk )
333 : {
334 0 : m_nObjectState = nNextState;
335 0 : m_pDocHolder->ResizeHatchWindow();
336 : }
337 : else
338 : {
339 0 : xInplaceClient->deactivatedUI();
340 0 : throw embed::WrongStateException(); //TODO: can't activate UI
341 0 : }
342 : }
343 : else
344 0 : throw embed::WrongStateException(); //TODO: can't activate UI
345 : }
346 : }
347 : else
348 : {
349 : OSL_FAIL( "Unacceptable state switch!\n" );
350 0 : throw uno::RuntimeException(); // TODO
351 : }
352 : }
353 0 : else if ( m_nObjectState == embed::EmbedStates::ACTIVE )
354 : {
355 0 : if ( nNextState == embed::EmbedStates::RUNNING )
356 : {
357 0 : Deactivate();
358 0 : m_nObjectState = nNextState;
359 : }
360 : else
361 : {
362 : OSL_FAIL( "Unacceptable state switch!\n" );
363 0 : throw uno::RuntimeException(); // TODO
364 : }
365 : }
366 0 : else if ( m_nObjectState == embed::EmbedStates::UI_ACTIVE )
367 : {
368 0 : if ( nNextState == embed::EmbedStates::INPLACE_ACTIVE )
369 : {
370 0 : uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY_THROW );
371 : uno::Reference< ::com::sun::star::frame::XLayoutManager > xContainerLM =
372 0 : xInplaceClient->getLayoutManager();
373 :
374 0 : sal_Bool bOk = sal_False;
375 0 : if ( xContainerLM.is() )
376 0 : bOk = m_pDocHolder->HideUI( xContainerLM );
377 :
378 0 : if ( bOk )
379 : {
380 0 : m_nObjectState = nNextState;
381 0 : m_pDocHolder->ResizeHatchWindow();
382 0 : xInplaceClient->deactivatedUI();
383 : }
384 : else
385 0 : throw embed::WrongStateException(); //TODO: can't activate UI
386 : }
387 : }
388 : else
389 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object is in unacceptable state!\n" )),
390 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
391 143 : }
392 :
393 : //----------------------------------------------
394 146 : uno::Sequence< sal_Int32 > OCommonEmbeddedObject::GetIntermediateStatesSequence_Impl( sal_Int32 nNewState )
395 : {
396 146 : sal_Int32 nCurInd = 0;
397 289 : for ( nCurInd = 0; nCurInd < m_aAcceptedStates.getLength(); nCurInd++ )
398 289 : if ( m_aAcceptedStates[nCurInd] == m_nObjectState )
399 146 : break;
400 :
401 146 : if ( nCurInd == m_aAcceptedStates.getLength() )
402 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object is in unacceptable state!\n" )),
403 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
404 :
405 146 : sal_Int32 nDestInd = 0;
406 149 : for ( nDestInd = 0; nDestInd < m_aAcceptedStates.getLength(); nDestInd++ )
407 149 : if ( m_aAcceptedStates[nDestInd] == nNewState )
408 146 : break;
409 :
410 146 : if ( nDestInd == m_aAcceptedStates.getLength() )
411 : throw embed::UnreachableStateException(
412 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The state either not reachable, or the object allows the state only as an intermediate one!\n" )),
413 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
414 : m_nObjectState,
415 0 : nNewState );
416 :
417 146 : return m_pIntermediateStatesSeqs[nCurInd][nDestInd];
418 : }
419 :
420 : //----------------------------------------------
421 149 : void SAL_CALL OCommonEmbeddedObject::changeState( sal_Int32 nNewState )
422 : throw ( embed::UnreachableStateException,
423 : embed::WrongStateException,
424 : uno::Exception,
425 : uno::RuntimeException )
426 : {
427 : RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::changeState" );
428 :
429 149 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ), uno::UNO_QUERY);
430 : {
431 149 : ::osl::ResettableMutexGuard aGuard( m_aMutex );
432 149 : if ( m_bDisposed )
433 0 : throw lang::DisposedException(); // TODO
434 :
435 149 : if ( m_nObjectState == -1 )
436 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
437 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
438 :
439 149 : sal_Int32 nOldState = m_nObjectState;
440 :
441 149 : if ( m_nTargetState != -1 )
442 : {
443 : // means that the object is currently trying to reach the target state
444 : throw embed::StateChangeInProgressException( ::rtl::OUString(),
445 : uno::Reference< uno::XInterface >(),
446 0 : m_nTargetState );
447 : }
448 : else
449 : {
450 149 : TargetStateControl_Impl aControl( m_nTargetState, nNewState );
451 :
452 : // in case the object is already in requested state
453 149 : if ( m_nObjectState == nNewState )
454 : {
455 : // if active object is activated again, bring it's window to top
456 3 : if ( m_nObjectState == embed::EmbedStates::ACTIVE )
457 0 : m_pDocHolder->Show();
458 :
459 146 : return;
460 : }
461 :
462 : // retrieve sequence of states that should be passed to reach desired state
463 146 : uno::Sequence< sal_Int32 > aIntermediateStates = GetIntermediateStatesSequence_Impl( nNewState );
464 :
465 : // notify listeners that the object is going to change the state
466 146 : StateChangeNotification_Impl( sal_True, nOldState, nNewState,aGuard );
467 :
468 : try {
469 146 : for ( sal_Int32 nInd = 0; nInd < aIntermediateStates.getLength(); nInd++ )
470 0 : SwitchStateTo_Impl( aIntermediateStates[nInd] );
471 :
472 146 : SwitchStateTo_Impl( nNewState );
473 : }
474 3 : catch( const uno::Exception& )
475 : {
476 3 : if ( nOldState != m_nObjectState )
477 : // notify listeners that the object has changed the state
478 0 : StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState, aGuard );
479 :
480 3 : throw;
481 146 : }
482 : }
483 :
484 : // notify listeners that the object has changed the state
485 143 : StateChangeNotification_Impl( sal_False, nOldState, nNewState, aGuard );
486 :
487 : // let the object window be shown
488 143 : if ( nNewState == embed::EmbedStates::UI_ACTIVE || nNewState == embed::EmbedStates::INPLACE_ACTIVE )
489 0 : PostEvent_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnVisAreaChanged" ) ) );
490 : }
491 : }
492 :
493 : //----------------------------------------------
494 0 : uno::Sequence< sal_Int32 > SAL_CALL OCommonEmbeddedObject::getReachableStates()
495 : throw ( embed::WrongStateException,
496 : uno::RuntimeException )
497 : {
498 0 : if ( m_bDisposed )
499 0 : throw lang::DisposedException(); // TODO
500 :
501 0 : if ( m_nObjectState == -1 )
502 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
503 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
504 :
505 0 : return m_aAcceptedStates;
506 : }
507 :
508 : //----------------------------------------------
509 4259 : sal_Int32 SAL_CALL OCommonEmbeddedObject::getCurrentState()
510 : throw ( embed::WrongStateException,
511 : uno::RuntimeException )
512 : {
513 4259 : if ( m_bDisposed )
514 0 : throw lang::DisposedException(); // TODO
515 :
516 4259 : if ( m_nObjectState == -1 )
517 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
518 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
519 :
520 4259 : return m_nObjectState;
521 : }
522 :
523 : //----------------------------------------------
524 0 : void SAL_CALL OCommonEmbeddedObject::doVerb( sal_Int32 nVerbID )
525 : throw ( lang::IllegalArgumentException,
526 : embed::WrongStateException,
527 : embed::UnreachableStateException,
528 : uno::Exception,
529 : uno::RuntimeException )
530 : {
531 : RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::doVerb" );
532 :
533 0 : SolarMutexGuard aSolarGuard;
534 : //TODO: a gross hack to avoid deadlocks when this is called from the
535 : // outside and OCommonEmbeddedObject::changeState, with m_aMutex locked,
536 : // calls into framework code that tries to lock the solar mutex, while
537 : // another thread (through Window::ImplCallPaint, say) calls
538 : // OCommonEmbeddedObject::getComponent with the solar mutex locked and
539 : // then tries to lock m_aMutex (see fdo#56818); the alternative would be
540 : // to get locking done right in this class, but that looks like a
541 : // daunting task
542 :
543 0 : ::osl::ResettableMutexGuard aGuard( m_aMutex );
544 0 : if ( m_bDisposed )
545 0 : throw lang::DisposedException(); // TODO
546 :
547 0 : if ( m_nObjectState == -1 )
548 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
549 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
550 :
551 : // for internal documents this call is just a duplicate of changeState
552 0 : sal_Int32 nNewState = -1;
553 : try
554 : {
555 0 : nNewState = ConvertVerbToState_Impl( nVerbID );
556 : }
557 0 : catch( const uno::Exception& )
558 : {}
559 :
560 0 : if ( nNewState == -1 )
561 : {
562 : // TODO/LATER: Save Copy as... verb ( -8 ) is implemented by container
563 : // TODO/LATER: check if the verb is a supported one and if it is produce related operation
564 : }
565 : else
566 : {
567 0 : aGuard.clear();
568 0 : changeState( nNewState );
569 0 : }
570 0 : }
571 :
572 : //----------------------------------------------
573 0 : uno::Sequence< embed::VerbDescriptor > SAL_CALL OCommonEmbeddedObject::getSupportedVerbs()
574 : throw ( embed::WrongStateException,
575 : uno::RuntimeException )
576 : {
577 0 : if ( m_bDisposed )
578 0 : throw lang::DisposedException(); // TODO
579 :
580 0 : if ( m_nObjectState == -1 )
581 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
582 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
583 :
584 0 : return m_aObjectVerbs;
585 : }
586 :
587 : //----------------------------------------------
588 44 : void SAL_CALL OCommonEmbeddedObject::setClientSite(
589 : const uno::Reference< embed::XEmbeddedClient >& xClient )
590 : throw ( embed::WrongStateException,
591 : uno::RuntimeException )
592 : {
593 44 : ::osl::MutexGuard aGuard( m_aMutex );
594 44 : if ( m_bDisposed )
595 0 : throw lang::DisposedException(); // TODO
596 :
597 44 : if ( m_xClientSite != xClient)
598 : {
599 0 : if ( m_nObjectState != embed::EmbedStates::LOADED && m_nObjectState != embed::EmbedStates::RUNNING )
600 : throw embed::WrongStateException(
601 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The client site can not be set currently!\n" )),
602 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
603 :
604 0 : m_xClientSite = xClient;
605 44 : }
606 44 : }
607 :
608 : //----------------------------------------------
609 40 : uno::Reference< embed::XEmbeddedClient > SAL_CALL OCommonEmbeddedObject::getClientSite()
610 : throw ( embed::WrongStateException,
611 : uno::RuntimeException )
612 : {
613 40 : if ( m_bDisposed )
614 0 : throw lang::DisposedException(); // TODO
615 :
616 40 : if ( m_nObjectState == -1 )
617 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
618 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
619 :
620 40 : return m_xClientSite;
621 : }
622 :
623 : //----------------------------------------------
624 0 : void SAL_CALL OCommonEmbeddedObject::update()
625 : throw ( embed::WrongStateException,
626 : uno::Exception,
627 : uno::RuntimeException )
628 : {
629 0 : ::osl::MutexGuard aGuard( m_aMutex );
630 0 : if ( m_bDisposed )
631 0 : throw lang::DisposedException(); // TODO
632 :
633 0 : if ( m_nObjectState == -1 )
634 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
635 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
636 :
637 0 : PostEvent_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnVisAreaChanged" ) ) );
638 0 : }
639 :
640 : //----------------------------------------------
641 0 : void SAL_CALL OCommonEmbeddedObject::setUpdateMode( sal_Int32 nMode )
642 : throw ( embed::WrongStateException,
643 : uno::RuntimeException )
644 : {
645 0 : ::osl::MutexGuard aGuard( m_aMutex );
646 0 : if ( m_bDisposed )
647 0 : throw lang::DisposedException(); // TODO
648 :
649 0 : if ( m_nObjectState == -1 )
650 : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object has no persistence!\n" )),
651 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
652 :
653 : OSL_ENSURE( nMode == embed::EmbedUpdateModes::ALWAYS_UPDATE
654 : || nMode == embed::EmbedUpdateModes::EXPLICIT_UPDATE,
655 : "Unknown update mode!\n" );
656 0 : m_nUpdateMode = nMode;
657 0 : }
658 :
659 : //----------------------------------------------
660 497 : sal_Int64 SAL_CALL OCommonEmbeddedObject::getStatus( sal_Int64 )
661 : throw ( embed::WrongStateException,
662 : uno::RuntimeException )
663 : {
664 497 : if ( m_bDisposed )
665 0 : throw lang::DisposedException(); // TODO
666 :
667 497 : return m_nMiscStatus;
668 : }
669 :
670 : //----------------------------------------------
671 0 : void SAL_CALL OCommonEmbeddedObject::setContainerName( const ::rtl::OUString& sName )
672 : throw ( uno::RuntimeException )
673 : {
674 0 : ::osl::MutexGuard aGuard( m_aMutex );
675 0 : if ( m_bDisposed )
676 0 : throw lang::DisposedException(); // TODO
677 :
678 0 : m_aContainerName = sName;
679 0 : }
680 :
681 617 : com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL OCommonEmbeddedObject::getParent() throw (::com::sun::star::uno::RuntimeException)
682 : {
683 617 : return m_xParent;
684 : }
685 :
686 331 : void SAL_CALL OCommonEmbeddedObject::setParent( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface >& xParent ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException)
687 : {
688 331 : m_xParent = xParent;
689 331 : if ( m_nObjectState != -1 && m_nObjectState != embed::EmbedStates::LOADED )
690 : {
691 327 : uno::Reference < container::XChild > xChild( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
692 327 : if ( xChild.is() )
693 327 : xChild->setParent( xParent );
694 : }
695 331 : }
696 :
697 : // XDefaultSizeTransmitter
698 0 : void SAL_CALL OCommonEmbeddedObject::setDefaultSize( const ::com::sun::star::awt::Size& rSize_100TH_MM ) throw (::com::sun::star::uno::RuntimeException)
699 : {
700 : //#i103460# charts do not necessaryly have an own size within ODF files, in this case they need to use the size settings from the surrounding frame, which is made available with this method
701 0 : m_aDefaultSizeForChart_In_100TH_MM = rSize_100TH_MM;
702 0 : }
703 :
704 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|