1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB
27 	#ifndef _STRING_HXX
28 	#include <tools/string.hxx>
29 	#endif
30 
31 	#ifndef _STREAM_HXX
32 	#include <tools/stream.hxx>
33 	#endif
34 #endif // #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB
35 #include <tools/debug.hxx>
36 #include <vcl/window.hxx>
37 #include <errhdl.hxx>
38 #include <swtypes.hxx>
39 
40 #include <com/sun/star/accessibility/XAccessible.hpp>
41 #include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
42 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
43 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
44 #include <vos/mutex.hxx>
45 #include <vcl/svapp.hxx>
46 #include <unotools/accessiblestatesethelper.hxx>
47 #include <unotools/accessiblerelationsethelper.hxx>
48 #include <viewsh.hxx>
49 #include <crsrsh.hxx>
50 #include <fesh.hxx>
51 #include <txtfrm.hxx>
52 #include <ndtxt.hxx>
53 #include <pagefrm.hxx>
54 #include <flyfrm.hxx>
55 #include <dflyobj.hxx>
56 #include <pam.hxx>
57 #include <viewimp.hxx>
58 #include <accmap.hxx>
59 #include <accfrmobjslist.hxx>
60 #include <acccontext.hxx>
61 #include <svx/AccessibleShape.hxx>
62 #include <comphelper/accessibleeventnotifier.hxx>
63 #ifndef _ACCPARA_HXX
64 #include "accpara.hxx"
65 #endif
66 #include <PostItMgr.hxx>
67 
68 using namespace sw::access;
69 
70 #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB
71 #define DBG_MSG( _msg ) \
72 	lcl_SwAccessibleContext_DbgMsg( this, _msg, 0, sal_False );
73 #define DBG_MSG_CD( _msg ) \
74 	lcl_SwAccessibleContext_DbgMsg( this, _msg, 0, sal_True );
75 #define DBG_MSG_PARAM( _msg, _param ) \
76 	lcl_SwAccessibleContext_DbgMsg( this, _msg, _param, sal_False );
77 #define DBG_MSG_THIS_PARAM( _msg, _this, _param ) \
78 	lcl_SwAccessibleContext_DbgMsg( _this, _msg, _param, sal_False );
79 
80 void lcl_SwAccessibleContext_DbgMsg( SwAccessibleContext *pThisAcc,
81 									 const char *pMsg,
82 								     SwAccessibleContext *pChildAcc,
83 								  	 sal_Bool bConstrDestr );
84 #else
85 #define DBG_MSG( _msg )
86 #define DBG_MSG_PARAM( _msg, _param )
87 #define DBG_MSG_THIS_PARAM( _msg, _this, _param )
88 #define DBG_MSG_CD( _msg )
89 #endif
90 
91 using namespace ::com::sun::star;
92 using namespace ::com::sun::star::accessibility;
93 using ::rtl::OUString;
94 
InitStates()95 void SwAccessibleContext::InitStates()
96 {
97     bIsShowingState = GetMap() ? IsShowing( *(GetMap()) ) : sal_False;
98 
99 	ViewShell *pVSh = GetMap()->GetShell();
100     bIsEditableState = pVSh && IsEditable( pVSh );
101 	bIsOpaqueState = pVSh && IsOpaque( pVSh );
102 	bIsDefuncState = sal_False;
103 }
104 
SetParent(SwAccessibleContext * pParent)105 void SwAccessibleContext::SetParent( SwAccessibleContext *pParent )
106 {
107 	vos::OGuard aGuard( aMutex );
108 
109 	uno::Reference < XAccessible > xParent( pParent );
110 	xWeakParent = xParent;
111 }
112 
GetWeakParent() const113 uno::Reference< XAccessible > SwAccessibleContext::GetWeakParent() const
114 {
115 	vos::OGuard aGuard( aMutex );
116 
117 	uno::Reference< XAccessible > xParent( xWeakParent );
118 	return xParent;
119 }
120 
GetWindow()121 Window *SwAccessibleContext::GetWindow()
122 {
123 	Window *pWin = 0;
124 
125 	if( GetMap() )
126 	{
127 		const ViewShell *pVSh = GetMap()->GetShell();
128 		ASSERT( pVSh, "no view shell" );
129 		if( pVSh )
130 			pWin = pVSh->GetWin();
131 
132 		ASSERT( pWin, "no window" );
133 	}
134 
135 	return pWin;
136 }
137 
138 // get ViewShell from accessibility map, and cast to cursor shell
GetCrsrShell()139 SwCrsrShell* SwAccessibleContext::GetCrsrShell()
140 {
141     SwCrsrShell* pCrsrShell;
142     ViewShell* pViewShell = GetMap() ? GetMap()->GetShell() : 0;
143 	ASSERT( pViewShell, "no view shell" );
144     if( pViewShell && pViewShell->ISA( SwCrsrShell ) )
145         pCrsrShell = static_cast<SwCrsrShell*>( pViewShell );
146     else
147         pCrsrShell = NULL;
148 
149     return pCrsrShell;
150 }
151 
GetCrsrShell() const152 const SwCrsrShell* SwAccessibleContext::GetCrsrShell() const
153 {
154     // just like non-const GetCrsrShell
155     const SwCrsrShell* pCrsrShell;
156     const ViewShell* pViewShell = GetMap() ? GetMap()->GetShell() : 0;
157 	ASSERT( pViewShell, "no view shell" );
158     if( pViewShell && pViewShell->ISA( SwCrsrShell ) )
159         pCrsrShell = static_cast<const SwCrsrShell*>( pViewShell );
160     else
161         pCrsrShell = NULL;
162 
163     return pCrsrShell;
164 }
165 
166 
167 enum Action { NONE, SCROLLED, SCROLLED_WITHIN,
168 						  SCROLLED_IN, SCROLLED_OUT };
169 
ChildrenScrolled(const SwFrm * pFrm,const SwRect & rOldVisArea)170 void SwAccessibleContext::ChildrenScrolled( const SwFrm *pFrm,
171                                             const SwRect& rOldVisArea )
172 {
173 	const SwRect& rNewVisArea = GetVisArea();
174     const bool bVisibleChildrenOnly = SwAccessibleChild( pFrm ).IsVisibleChildrenOnly();
175 
176     const SwAccessibleChildSList aList( *pFrm, *(GetMap()) );
177     SwAccessibleChildSList::const_iterator aIter( aList.begin() );
178 	while( aIter != aList.end() )
179 	{
180         const SwAccessibleChild& rLower = *aIter;
181         const SwRect aBox( rLower.GetBox( *(GetMap()) ) );
182 		if( rLower.IsAccessible( GetShell()->IsPreView() ) )
183 		{
184 			Action eAction = NONE;
185 			if( aBox.IsOver( rNewVisArea ) )
186 			{
187 				if( aBox.IsOver( rOldVisArea ) )
188 				{
189 					eAction = SCROLLED_WITHIN;
190 				}
191 				else
192 				{
193                     if ( bVisibleChildrenOnly &&
194                          !rLower.AlwaysIncludeAsChild() )
195                     {
196 						eAction = SCROLLED_IN;
197                     }
198 					else
199                     {
200 						eAction = SCROLLED;
201                     }
202 				}
203 			}
204 			else if( aBox.IsOver( rOldVisArea ) )
205 			{
206                 if ( bVisibleChildrenOnly &&
207                      !rLower.AlwaysIncludeAsChild() )
208                 {
209 					eAction = SCROLLED_OUT;
210                 }
211 				else
212                 {
213 					eAction = SCROLLED;
214                 }
215 			}
216             else if( !bVisibleChildrenOnly ||
217                      rLower.AlwaysIncludeAsChild() )
218 			{
219 				// This wouldn't be required if the SwAccessibleFrame,
220 				// wouldn't know about the vis area.
221 				eAction = SCROLLED;
222 			}
223 			if( NONE != eAction )
224 			{
225                 if ( rLower.GetSwFrm() )
226 				{
227                     ASSERT( !rLower.AlwaysIncludeAsChild(),
228                             "<SwAccessibleContext::ChildrenScrolled(..)> - always included child not considered!" );
229                     const SwFrm* pLower( rLower.GetSwFrm() );
230 					::vos::ORef< SwAccessibleContext > xAccImpl =
231 						//O is: GetMap()->GetContextImpl( pLower, SCROLLED_OUT == eAction ||
232 						//						SCROLLED_IN == eAction );
233 						GetMap()->GetContextImpl( pLower, sal_True );
234 					if( xAccImpl.isValid() )
235 					{
236 						switch( eAction )
237 						{
238 						case SCROLLED:
239 							xAccImpl->Scrolled( rOldVisArea );
240 							break;
241 						case SCROLLED_WITHIN:
242 							xAccImpl->ScrolledWithin( rOldVisArea );
243 							break;
244 						case SCROLLED_IN:
245 							xAccImpl->ScrolledIn();
246 							break;
247 						case SCROLLED_OUT:
248 							xAccImpl->ScrolledOut( rOldVisArea );
249 							break;
250 						case NONE:
251 							break;
252 						}
253 					}
254 					else
255 					{
256 						ChildrenScrolled( pLower, rOldVisArea );
257 					}
258 				}
259                 else if ( rLower.GetDrawObject() )
260 				{
261                     ASSERT( !rLower.AlwaysIncludeAsChild(),
262                             "<SwAccessibleContext::ChildrenScrolled(..)> - always included child not considered!" );
263 					::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
264 						//O is:	GetMap()->GetContextImpl( rLower.GetSdrObject(),
265 						//						  this,
266 						//						  SCROLLED_OUT == eAction ||
267 						//						  SCROLLED_IN == eAction );
268                         GetMap()->GetContextImpl( rLower.GetDrawObject(),
269 												  this,
270 												  sal_True );
271 					if( xAccImpl.isValid() )
272 					{
273 						switch( eAction )
274 						{
275 						case SCROLLED:
276 						case SCROLLED_WITHIN:
277 							xAccImpl->ViewForwarderChanged(
278 								::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA,
279 								GetMap() );
280 							break;
281 						case SCROLLED_IN:
282                             ScrolledInShape( rLower.GetDrawObject(),
283 											 xAccImpl.getBodyPtr() );
284 							break;
285 						case SCROLLED_OUT:
286 							{
287 								xAccImpl->ViewForwarderChanged(
288 									::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA,
289 									GetMap() );
290 								//Remove
291 								//DisposeShape( rLower.GetDrawObject(),
292 								//			  xAccImpl.getBodyPtr() );
293 							}
294 							break;
295 						case NONE:
296 							break;
297 						}
298 					}
299 				}
300                 else if ( rLower.GetWindow() )
301                 {
302                     // nothing to do - as such children are always included as children.
303                     ASSERT( rLower.AlwaysIncludeAsChild(),
304                             "<SwAccessibleContext::ChildrenScrolled(..)> - not always included child not considered!" );
305                 }
306 			}
307 		}
308         else if ( rLower.GetSwFrm() &&
309                   ( !bVisibleChildrenOnly ||
310                     aBox.IsOver( rOldVisArea ) ||
311                     aBox.IsOver( rNewVisArea ) ) )
312 		{
313 			// There are no unaccessible SdrObjects that need to be notified
314             ChildrenScrolled( rLower.GetSwFrm(), rOldVisArea );
315 		}
316 		++aIter;
317 	}
318 }
319 
Scrolled(const SwRect & rOldVisArea)320 void SwAccessibleContext::Scrolled( const SwRect& rOldVisArea )
321 {
322 	SetVisArea( GetMap()->GetVisArea() );
323 
324 	ChildrenScrolled( GetFrm(), rOldVisArea );
325 
326 	sal_Bool bIsOldShowingState;
327     sal_Bool bIsNewShowingState = IsShowing( *(GetMap()) );
328 	{
329 		vos::OGuard aGuard( aMutex );
330 		bIsOldShowingState = bIsShowingState;
331 		bIsShowingState = bIsNewShowingState;
332 	}
333 
334 	if( bIsOldShowingState != bIsNewShowingState )
335 		FireStateChangedEvent( AccessibleStateType::SHOWING,
336 							   bIsNewShowingState  );
337 }
338 
ScrolledWithin(const SwRect & rOldVisArea)339 void SwAccessibleContext::ScrolledWithin( const SwRect& rOldVisArea )
340 {
341 	SetVisArea( GetMap()->GetVisArea() );
342 
343 	ChildrenScrolled( GetFrm(), rOldVisArea );
344 
345 	FireVisibleDataEvent();
346 }
347 
ScrolledIn()348 void SwAccessibleContext::ScrolledIn()
349 {
350 	// This accessible should be freshly created, because it
351 	// was not visisble before. Therefor, its vis area must already
352 	// reflect the scrolling.
353 	ASSERT( GetVisArea() == GetMap()->GetVisArea(),
354 			"Vis area of child is wrong. Did it exist already?" );
355 
356 	// Send child event at parent. That's all we have to do here.
357     const SwFrm* pParent = GetParent();
358 	::vos::ORef< SwAccessibleContext > xParentImpl(
359 		 GetMap()->GetContextImpl( pParent, sal_False ) );
360 	uno::Reference < XAccessibleContext > xThis( this );
361 	if( xParentImpl.isValid() )
362 	{
363 		SetParent( xParentImpl.getBodyPtr() );
364 
365 		AccessibleEventObject aEvent;
366 		aEvent.EventId = AccessibleEventId::CHILD;
367 		aEvent.NewValue <<= xThis;
368 
369 		xParentImpl->FireAccessibleEvent( aEvent );
370 		DBG_MSG_PARAM( "AccessibleChild (added)", xChildImpl.getBodyPtr() );
371 
372 		if( HasCursor() )
373 		{
374 			Window *pWin = GetWindow();
375 			if( pWin && pWin->HasFocus() )
376 			{
377 				FireStateChangedEvent( AccessibleStateType::FOCUSED, sal_True );
378 			}
379 		}
380 
381 	}
382 }
383 
ScrolledOut(const SwRect & rOldVisArea)384 void SwAccessibleContext::ScrolledOut( const SwRect& rOldVisArea )
385 {
386 	SetVisArea( GetMap()->GetVisArea() );
387 
388 	// First of all, update the children. That's required to dispose
389 	// all children that are existing only if they are visible. They
390 	// are not disposed by the recusive Dispose call that follows later on,
391 	// because this call will only dispose children that are in the
392 	// new vis area. The children we want to dispode however are in the
393 	// old vis area all.
394 	ChildrenScrolled( GetFrm(), rOldVisArea );
395 
396 	// Broadcast a state changed event for the showing state.
397 	// It might be that the child is freshly created just to send
398 	// the child event. In this case no listener will exist.
399 	FireStateChangedEvent( AccessibleStateType::SHOWING, sal_False );
400 
401 	//Remove Dispose When scrolledout
402 	// We now dispose the frame
403 	//	Dispose( sal_True );
404 }
405 
406 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates>
InvalidateChildrenStates(const SwFrm * _pFrm,tAccessibleStates _nStates)407 void SwAccessibleContext::InvalidateChildrenStates( const SwFrm* _pFrm,
408                                                     tAccessibleStates _nStates )
409 {
410     const SwAccessibleChildSList aVisList( GetVisArea(), *_pFrm, *(GetMap()) );
411 
412     SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
413 	while( aIter != aVisList.end() )
414 	{
415         const SwAccessibleChild& rLower = *aIter;
416         const SwFrm* pLower = rLower.GetSwFrm();
417 		if( pLower )
418 		{
419 			::vos::ORef< SwAccessibleContext > xAccImpl;
420 			if( rLower.IsAccessible( GetShell()->IsPreView() ) )
421 				xAccImpl = GetMap()->GetContextImpl( pLower, sal_False );
422 			if( xAccImpl.isValid() )
423                 xAccImpl->InvalidateStates( _nStates );
424 			else
425                 InvalidateChildrenStates( pLower, _nStates );
426 		}
427         else if ( rLower.GetDrawObject() )
428 		{
429 			// TODO: SdrObjects
430 		}
431         else if ( rLower.GetWindow() )
432         {
433             // nothing to do ?
434         }
435 
436 		++aIter;
437 	}
438 }
439 // <--
440 
DisposeChildren(const SwFrm * pFrm,sal_Bool bRecursive)441 void SwAccessibleContext::DisposeChildren( const SwFrm *pFrm,
442 									   sal_Bool bRecursive )
443 {
444     const SwAccessibleChildSList aVisList( GetVisArea(), *pFrm, *(GetMap()) );
445     SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
446 	while( aIter != aVisList.end() )
447 	{
448         const SwAccessibleChild& rLower = *aIter;
449         const SwFrm* pLower = rLower.GetSwFrm();
450 		if( pLower )
451 		{
452 			::vos::ORef< SwAccessibleContext > xAccImpl;
453 			if( rLower.IsAccessible( GetShell()->IsPreView() ) )
454 				xAccImpl = GetMap()->GetContextImpl( pLower, sal_False );
455 			if( xAccImpl.isValid() )
456 				xAccImpl->Dispose( bRecursive );
457 			else if( bRecursive )
458 				DisposeChildren( pLower, bRecursive );
459 		}
460         else if ( rLower.GetDrawObject() )
461 		{
462 			::vos::ORef< ::accessibility::AccessibleShape > xAccImpl(
463                     GetMap()->GetContextImpl( rLower.GetDrawObject(),
464 										  this, sal_False )  );
465 			if( xAccImpl.isValid() )
466                 DisposeShape( rLower.GetDrawObject(), xAccImpl.getBodyPtr() );
467 		}
468         else if ( rLower.GetWindow() )
469         {
470             DisposeChild( rLower, sal_False );
471         }
472 		++aIter;
473 	}
474 }
475 
_InvalidateContent(sal_Bool)476 void SwAccessibleContext::_InvalidateContent( sal_Bool )
477 {
478 }
479 
_InvalidateCursorPos()480 void SwAccessibleContext::_InvalidateCursorPos()
481 {
482 }
483 
_InvalidateFocus()484 void SwAccessibleContext::_InvalidateFocus()
485 {
486 }
487 
FireAccessibleEvent(AccessibleEventObject & rEvent)488 void SwAccessibleContext::FireAccessibleEvent( AccessibleEventObject& rEvent )
489 {
490 	ASSERT( GetFrm(), "fire event for diposed frame?" );
491 	if( !GetFrm() )
492 		return;
493 
494 	if( !rEvent.Source.is() )
495 	{
496 		uno::Reference < XAccessibleContext > xThis( this );
497 		rEvent.Source = xThis;
498 	}
499 
500 	if (nClientId)
501 		comphelper::AccessibleEventNotifier::addEvent( nClientId, rEvent );
502 }
503 
FireVisibleDataEvent()504 void SwAccessibleContext::FireVisibleDataEvent()
505 {
506 	AccessibleEventObject aEvent;
507 	aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
508 
509 	FireAccessibleEvent( aEvent );
510 	DBG_MSG( "AccessibleVisibleData" )
511 }
512 
FireStateChangedEvent(sal_Int16 nState,sal_Bool bNewState)513 void SwAccessibleContext::FireStateChangedEvent( sal_Int16 nState,
514 												 sal_Bool bNewState )
515 {
516 	AccessibleEventObject aEvent;
517 
518 	aEvent.EventId = AccessibleEventId::STATE_CHANGED;
519 	if( bNewState )
520 		aEvent.NewValue <<= nState;
521 	else
522 		aEvent.OldValue <<= nState;
523 
524 	FireAccessibleEvent( aEvent );
525 	DBG_MSG( "StateChanged" )
526 }
527 
GetStates(::utl::AccessibleStateSetHelper & rStateSet)528 void SwAccessibleContext::GetStates(
529 		::utl::AccessibleStateSetHelper& rStateSet )
530 {
531 	vos::OGuard aGuard(Application::GetSolarMutex());
532 
533 	// SHOWING
534 	if( bIsShowingState )
535 		rStateSet.AddState( AccessibleStateType::SHOWING );
536 
537 	// EDITABLE
538 	if( bIsEditableState )
539 	//Solution:Set editable state to graphic and other object when the document is editable
540 	{
541 		rStateSet.AddState( AccessibleStateType::EDITABLE );
542 		rStateSet.AddState( AccessibleStateType::RESIZABLE );
543 		rStateSet.AddState( AccessibleStateType::MOVEABLE );
544 	}
545 	// ENABLED
546 	rStateSet.AddState( AccessibleStateType::ENABLED );
547 
548 	// OPAQUE
549 	if( bIsOpaqueState )
550 		rStateSet.AddState( AccessibleStateType::OPAQUE );
551 
552 	// VISIBLE
553 	rStateSet.AddState( AccessibleStateType::VISIBLE );
554 
555 	if( bIsDefuncState )
556 		rStateSet.AddState( AccessibleStateType::DEFUNC );
557 }
558 
IsEditableState()559 sal_Bool SwAccessibleContext::IsEditableState()
560 {
561 	sal_Bool bRet;
562 	{
563 		vos::OGuard aGuard( aMutex );
564 		bRet = bIsEditableState;
565 	}
566 
567 	return bRet;
568 }
569 
SwAccessibleContext(SwAccessibleMap * pM,sal_Int16 nR,const SwFrm * pF)570 SwAccessibleContext::SwAccessibleContext( SwAccessibleMap *pM,
571 										  sal_Int16 nR,
572                                           const SwFrm *pF )
573     : SwAccessibleFrame( pM->GetVisArea().SVRect(), pF,
574                          pM->GetShell()->IsPreView() )
575     , pMap( pM )
576     , nClientId(0)
577     , nRole( nR )
578     , bDisposing( sal_False )
579     , bRegisteredAtAccessibleMap( true )
580     //Solution:Initialize the begin document load and IfAsynLoad to true
581     , bBeginDocumentLoad( sal_True )
582 	, isIfAsynLoad( sal_True )
583 	, bIsSeletedInDoc( sal_False)
584 {
585 	InitStates();
586 	DBG_MSG_CD( "constructed" )
587 }
588 
~SwAccessibleContext()589 SwAccessibleContext::~SwAccessibleContext()
590 {
591 	if(Application::GetUnoWrapper())
592 		vos::OGuard aGuard(Application::GetSolarMutex());
593 
594 	DBG_MSG_CD( "destructed" )
595     RemoveFrmFromAccessibleMap();
596 }
597 
598 uno::Reference< XAccessibleContext > SAL_CALL
getAccessibleContext(void)599 	SwAccessibleContext::getAccessibleContext( void )
600         throw (uno::RuntimeException)
601 {
602 	uno::Reference < XAccessibleContext > xRet( this );
603 	return xRet;
604 }
605 
getAccessibleChildCount(void)606 sal_Int32 SAL_CALL SwAccessibleContext::getAccessibleChildCount( void )
607         throw (uno::RuntimeException)
608 {
609 	vos::OGuard aGuard(Application::GetSolarMutex());
610 
611 	CHECK_FOR_DEFUNC( XAccessibleContext )
612 	//Solution:Notify the frame is a document
613 	if( nRole == AccessibleRole::DOCUMENT )
614 		bIsAccDocUse = sal_True;
615 
616     return bDisposing ? 0 : GetChildCount( *(GetMap()) );
617 }
618 
619 uno::Reference< XAccessible> SAL_CALL
getAccessibleChild(sal_Int32 nIndex)620 	SwAccessibleContext::getAccessibleChild( sal_Int32 nIndex )
621         throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
622 {
623 	vos::OGuard aGuard(Application::GetSolarMutex());
624 
625 	CHECK_FOR_DEFUNC( XAccessibleContext )
626 
627 	//Solution:Notify the frame is a document
628 	if( nRole == AccessibleRole::DOCUMENT )
629 		bIsAccDocUse = sal_True;
630 
631     const SwAccessibleChild aChild( GetChild( *(GetMap()), nIndex ) );
632 	if( !aChild.IsValid() )
633 	{
634 		uno::Reference < XAccessibleContext > xThis( this );
635 		lang::IndexOutOfBoundsException aExcept(
636 				OUString( RTL_CONSTASCII_USTRINGPARAM("index out of bounds") ),
637 				xThis );
638 		throw aExcept;
639 	}
640 
641 	uno::Reference< XAccessible > xChild;
642 	if( aChild.GetSwFrm() )
643 	{
644 		::vos::ORef < SwAccessibleContext > xChildImpl(
645 				GetMap()->GetContextImpl( aChild.GetSwFrm(), !bDisposing )  );
646 		//Solution:Send out accessible event when begin load.
647 		if( bBeginDocumentLoad && nRole == AccessibleRole::DOCUMENT )
648 		{
649 
650 			FireStateChangedEvent( AccessibleStateType::FOCUSABLE,sal_True );
651 			FireStateChangedEvent( AccessibleStateType::BUSY,sal_True );
652 			if( !isIfAsynLoad )
653 			{
654 				FireStateChangedEvent( AccessibleStateType::FOCUSED,sal_True );
655 				// IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent
656 				// FireStateChangedEvent( AccessibleStateType::OFFSCREEN,sal_True );
657 				FireStateChangedEvent( AccessibleStateType::SHOWING,sal_True );
658 			    FireStateChangedEvent( AccessibleStateType::BUSY,sal_False );
659 				// MT: OFFSCREEN again?
660 			    // FireStateChangedEvent( AccessibleStateType::OFFSCREEN,sal_False );
661 			}
662 			bBeginDocumentLoad = sal_False;
663 		}
664 		if( xChildImpl.isValid() )
665 		{
666 			xChildImpl->SetParent( this );
667 			xChild = xChildImpl.getBodyPtr();
668 		}
669 	}
670     else if ( aChild.GetDrawObject() )
671 	{
672 		::vos::ORef < ::accessibility::AccessibleShape > xChildImpl(
673                 GetMap()->GetContextImpl( aChild.GetDrawObject(),
674 										  this, !bDisposing )  );
675 		if( xChildImpl.isValid() )
676 			xChild = xChildImpl.getBodyPtr();
677 	}
678     else if ( aChild.GetWindow() )
679     {
680         xChild = aChild.GetWindow()->GetAccessible();
681     }
682 
683 	return xChild;
684 }
685 
getAccessibleParent(void)686 uno::Reference< XAccessible> SAL_CALL SwAccessibleContext::getAccessibleParent (void)
687         throw (uno::RuntimeException)
688 {
689 	vos::OGuard aGuard(Application::GetSolarMutex());
690 
691 	CHECK_FOR_DEFUNC( XAccessibleContext )
692 
693 	const SwFrm *pUpper = GetParent();
694 	ASSERT( pUpper != 0 || bDisposing, "no upper found" );
695 
696 	uno::Reference< XAccessible > xAcc;
697 	if( pUpper )
698 		xAcc = GetMap()->GetContext( pUpper, !bDisposing );
699 
700 	ASSERT( xAcc.is() || bDisposing, "no parent found" );
701 
702 	// Remember the parent as weak ref.
703 	{
704         vos::OGuard aWeakParentGuard( aMutex );
705 		xWeakParent = xAcc;
706 	}
707 
708 	return xAcc;
709 }
710 
getAccessibleIndexInParent(void)711 sal_Int32 SAL_CALL SwAccessibleContext::getAccessibleIndexInParent (void)
712         throw (uno::RuntimeException)
713 {
714 	vos::OGuard aGuard(Application::GetSolarMutex());
715 
716 	CHECK_FOR_DEFUNC( XAccessibleContext )
717 
718 	const SwFrm *pUpper = GetParent();
719 	ASSERT( pUpper != 0 || bDisposing, "no upper found" );
720 
721 	sal_Int32 nIndex = -1;
722 	if( pUpper )
723 	{
724 		::vos::ORef < SwAccessibleContext > xAccImpl(
725 			GetMap()->GetContextImpl( pUpper, !bDisposing )  );
726 		ASSERT( xAccImpl.isValid() || bDisposing, "no parent found" );
727 		if( xAccImpl.isValid() )
728             nIndex = xAccImpl->GetChildIndex( *(GetMap()), SwAccessibleChild(GetFrm()) );
729 	}
730 
731 	return nIndex;
732 }
733 
getAccessibleRole(void)734 sal_Int16 SAL_CALL SwAccessibleContext::getAccessibleRole (void)
735         throw (uno::RuntimeException)
736 {
737 	return nRole;
738 }
739 
getAccessibleDescription(void)740 OUString SAL_CALL SwAccessibleContext::getAccessibleDescription (void)
741         throw (uno::RuntimeException)
742 {
743 	ASSERT( !this, "description needs to be overloaded" );
744 	THROW_RUNTIME_EXCEPTION( XAccessibleContext, "internal error (method must be overloaded)" );
745 }
746 
getAccessibleName(void)747 OUString SAL_CALL SwAccessibleContext::getAccessibleName (void)
748         throw (uno::RuntimeException)
749 {
750 	return sName;
751 }
752 
753 uno::Reference< XAccessibleRelationSet> SAL_CALL
getAccessibleRelationSet(void)754 	SwAccessibleContext::getAccessibleRelationSet (void)
755         throw (uno::RuntimeException)
756 {
757 	// by default there are no relations
758 	uno::Reference< XAccessibleRelationSet> xRet( new utl::AccessibleRelationSetHelper() );
759 	return xRet;
760 }
761 
762 uno::Reference<XAccessibleStateSet> SAL_CALL
getAccessibleStateSet(void)763 	SwAccessibleContext::getAccessibleStateSet (void)
764         throw (uno::RuntimeException)
765 {
766 	vos::OGuard aGuard(Application::GetSolarMutex());
767 
768 	CHECK_FOR_DEFUNC( XAccessibleContext )
769 
770 	::utl::AccessibleStateSetHelper *pStateSet =
771 		new ::utl::AccessibleStateSetHelper;
772 
773 	if( bIsSeletedInDoc )
774 		pStateSet->AddState( AccessibleStateType::SELECTED );
775 
776 	uno::Reference<XAccessibleStateSet> xStateSet( pStateSet );
777 	GetStates( *pStateSet );
778 
779 	return xStateSet;
780 }
781 
getLocale(void)782 lang::Locale SAL_CALL SwAccessibleContext::getLocale (void)
783 		throw (IllegalAccessibleComponentStateException, uno::RuntimeException)
784 {
785 	vos::OGuard aGuard(Application::GetSolarMutex());
786 
787 	lang::Locale aLoc( Application::GetSettings().GetLocale() );
788 	return aLoc;
789 }
790 
addEventListener(const uno::Reference<XAccessibleEventListener> & xListener)791 void SAL_CALL SwAccessibleContext::addEventListener(
792 			const uno::Reference< XAccessibleEventListener >& xListener )
793 		throw (uno::RuntimeException)
794 {
795 	DBG_MSG( "accessible event listener added" )
796 
797 	if (xListener.is())
798     {
799     	vos::OGuard aGuard(Application::GetSolarMutex());
800 		if (!nClientId)
801             nClientId = comphelper::AccessibleEventNotifier::registerClient( );
802 		comphelper::AccessibleEventNotifier::addEventListener( nClientId, xListener );
803     }
804 }
805 
removeEventListener(const uno::Reference<XAccessibleEventListener> & xListener)806 void SAL_CALL SwAccessibleContext::removeEventListener(
807 			const uno::Reference< XAccessibleEventListener >& xListener )
808 		throw (uno::RuntimeException)
809 {
810 	DBG_MSG( "accessible event listener removed" )
811 
812 	if (xListener.is())
813 	{
814     	vos::OGuard aGuard(Application::GetSolarMutex());
815 		sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( nClientId, xListener );
816 		if ( !nListenerCount )
817 		{
818 			// no listeners anymore
819 			// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
820 			// and at least to us not firing any events anymore, in case somebody calls
821 			// NotifyAccessibleEvent, again
822 			comphelper::AccessibleEventNotifier::revokeClient( nClientId );
823 			nClientId = 0;
824 		}
825 	}
826 }
827 
lcl_PointInRectangle(const awt::Point & aPoint,const awt::Rectangle & aRect)828 static sal_Bool lcl_PointInRectangle(const awt::Point & aPoint,
829                                      const awt::Rectangle & aRect)
830 {
831     long nDiffX = aPoint.X - aRect.X;
832     long nDiffY = aPoint.Y - aRect.Y;
833 
834     return
835         nDiffX >= 0 && nDiffX < aRect.Width && nDiffY >= 0 &&
836         nDiffY < aRect.Height;
837 
838 }
839 
containsPoint(const awt::Point & aPoint)840 sal_Bool SAL_CALL SwAccessibleContext::containsPoint(
841 			const awt::Point& aPoint )
842 		throw (uno::RuntimeException)
843 {
844     awt::Rectangle aPixBounds = getBoundsImpl(sal_True);
845     aPixBounds.X = 0;
846     aPixBounds.Y = 0;
847 
848     return lcl_PointInRectangle(aPoint, aPixBounds);
849 }
850 
getAccessibleAtPoint(const awt::Point & aPoint)851 uno::Reference< XAccessible > SAL_CALL SwAccessibleContext::getAccessibleAtPoint(
852 				const awt::Point& aPoint )
853 		throw (uno::RuntimeException)
854 {
855 	vos::OGuard aGuard(Application::GetSolarMutex());
856 
857 	CHECK_FOR_DEFUNC( XAccessibleComponent )
858 
859 	uno::Reference< XAccessible > xAcc;
860 
861 	Window *pWin = GetWindow();
862 	CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
863 
864 	Point aPixPoint( aPoint.X, aPoint.Y ); // px rel to parent
865 	if( !GetFrm()->IsRootFrm() )
866 	{
867         SwRect aLogBounds( GetBounds( *(GetMap()), GetFrm() ) ); // twip rel to doc root
868 		Point aPixPos( GetMap()->CoreToPixel( aLogBounds.SVRect() ).TopLeft() );
869 		aPixPoint.X() += aPixPos.X();
870 		aPixPoint.Y() += aPixPos.Y();
871 	}
872 
873     const SwAccessibleChild aChild( GetChildAtPixel( aPixPoint, *(GetMap()) ) );
874 	if( aChild.GetSwFrm() )
875 	{
876 		xAcc = GetMap()->GetContext( aChild.GetSwFrm() );
877 	}
878     else if( aChild.GetDrawObject() )
879 	{
880         xAcc = GetMap()->GetContext( aChild.GetDrawObject(), this );
881 	}
882     else if ( aChild.GetWindow() )
883     {
884         xAcc = aChild.GetWindow()->GetAccessible();
885     }
886 
887 	return xAcc;
888 }
889 
890 
891 /**
892    Get bounding box.
893 
894    There are two modes.
895 
896    - realative
897 
898      Return bounding box relative to parent if parent is no root
899      frame. Otherwise return the absolute bounding box.
900 
901    - absolute
902 
903      Return the absolute bounding box.
904 
905    @param bRelative
906    true: Use relative mode.
907    false: Use absolute mode.
908 */
getBoundsImpl(sal_Bool bRelative)909 awt::Rectangle SAL_CALL SwAccessibleContext::getBoundsImpl(sal_Bool bRelative)
910 		throw (uno::RuntimeException)
911 {
912 	vos::OGuard aGuard(Application::GetSolarMutex());
913 
914 	CHECK_FOR_DEFUNC( XAccessibleComponent )
915 
916 	const SwFrm *pParent = GetParent();
917 	ASSERT( pParent, "no Parent found" );
918 	Window *pWin = GetWindow();
919 
920 	CHECK_FOR_WINDOW( XAccessibleComponent, pWin && pParent )
921 
922     SwRect aLogBounds( GetBounds( *(GetMap()), GetFrm() ) ); // twip rel to doc root
923 	Rectangle aPixBounds( 0, 0, 0, 0 );
924 	if( GetFrm()->IsPageFrm() &&
925 		static_cast < const SwPageFrm * >( GetFrm() )->IsEmptyPage() )
926 	{
927 		ASSERT( GetShell()->IsPreView(), "empty page accessible?" );
928 		if( GetShell()->IsPreView() )
929         {
930             // OD 15.01.2003 #103492# - adjust method call <GetMap()->GetPreViewPageSize()>
931             sal_uInt16 nPageNum =
932                 static_cast < const SwPageFrm * >( GetFrm() )->GetPhyPageNum();
933             aLogBounds.SSize( GetMap()->GetPreViewPageSize( nPageNum ) );
934         }
935 	}
936 	if( !aLogBounds.IsEmpty() )
937 	{
938 		aPixBounds = GetMap()->CoreToPixel( aLogBounds.SVRect() );
939 		if( !pParent->IsRootFrm() && bRelative)
940 		{
941             SwRect aParentLogBounds( GetBounds( *(GetMap()), pParent ) ); // twip rel to doc root
942 			Point aParentPixPos( GetMap()->CoreToPixel( aParentLogBounds.SVRect() ).TopLeft() );
943 			aPixBounds.Move( -aParentPixPos.X(), -aParentPixPos.Y() );
944 		}
945 	}
946 
947 	awt::Rectangle aBox( aPixBounds.Left(), aPixBounds.Top(),
948 						 aPixBounds.GetWidth(), aPixBounds.GetHeight() );
949 
950 	return aBox;
951 }
952 
953 
getBounds()954 awt::Rectangle SAL_CALL SwAccessibleContext::getBounds()
955 		throw (uno::RuntimeException)
956 {
957     return getBoundsImpl(sal_True);
958 }
959 
getLocation()960 awt::Point SAL_CALL SwAccessibleContext::getLocation()
961     throw (uno::RuntimeException)
962 {
963     awt::Rectangle aRect = getBoundsImpl(sal_True);
964     awt::Point aPoint(aRect.X, aRect.Y);
965 
966     return aPoint;
967 }
968 
969 
970 
getLocationOnScreen()971 awt::Point SAL_CALL SwAccessibleContext::getLocationOnScreen()
972 		throw (uno::RuntimeException)
973 {
974     awt::Rectangle aRect = getBoundsImpl(sal_False);
975 
976     Point aPixPos(aRect.X, aRect.Y);
977 
978     /* getBoundsImpl already checked that GetWindow returns valid pointer. */
979     aPixPos = GetWindow()->OutputToAbsoluteScreenPixel(aPixPos);
980     awt::Point aPoint(aPixPos.X(), aPixPos.Y());
981 
982     return aPoint;
983 }
984 
985 
getSize()986 awt::Size SAL_CALL SwAccessibleContext::getSize()
987 		throw (uno::RuntimeException)
988 {
989     awt::Rectangle aRect = getBoundsImpl(sal_False);
990 	awt::Size aSize( aRect.Width, aRect.Height );
991 
992 	return aSize;
993 }
994 
grabFocus()995 void SAL_CALL SwAccessibleContext::grabFocus()
996 		throw (uno::RuntimeException)
997 {
998 	vos::OGuard aGuard(Application::GetSolarMutex());
999 
1000 	CHECK_FOR_DEFUNC( XAccessibleContext );
1001 
1002 	if( GetFrm()->IsFlyFrm() )
1003 	{
1004 		const SdrObject *pObj =
1005 			static_cast < const SwFlyFrm * >( GetFrm() )->GetVirtDrawObj();
1006 		if( pObj )
1007 			Select( const_cast < SdrObject * >( pObj ), sal_False );
1008 	}
1009 	else
1010 	{
1011 		const SwCntntFrm *pCFrm = 0;
1012 		if( GetFrm()->IsCntntFrm() )
1013 			pCFrm = static_cast< const SwCntntFrm * >( GetFrm() );
1014 		else if( GetFrm()->IsLayoutFrm() )
1015 			pCFrm = static_cast< const SwLayoutFrm * >( GetFrm() )->ContainsCntnt();
1016 
1017 		if( pCFrm && pCFrm->IsTxtFrm() )
1018 		{
1019 			const SwTxtFrm *pTxtFrm = static_cast< const SwTxtFrm * >( pCFrm );
1020 			const SwTxtNode *pTxtNd = pTxtFrm->GetTxtNode();
1021 			if( pTxtNd )
1022 			{
1023 				// create pam for selection
1024 				SwIndex aIndex( const_cast< SwTxtNode * >( pTxtNd ),
1025 								pTxtFrm->GetOfst() );
1026 				SwPosition aStartPos( *pTxtNd, aIndex );
1027 				SwPaM aPaM( aStartPos );
1028 
1029 				// set PaM at cursor shell
1030 				Select( aPaM );
1031 			}
1032 		}
1033 	}
1034 }
1035 
1036 
getAccessibleKeyBinding()1037 uno::Any SAL_CALL SwAccessibleContext::getAccessibleKeyBinding()
1038 		throw (uno::RuntimeException)
1039 {
1040 	// There are no key bindings
1041 	return uno::Any();
1042 }
1043 
getForeground()1044 sal_Int32 SAL_CALL SwAccessibleContext::getForeground()
1045 		throw (uno::RuntimeException)
1046 {
1047 	return COL_BLACK;
1048 }
1049 
getBackground()1050 sal_Int32 SAL_CALL SwAccessibleContext::getBackground()
1051 		throw (uno::RuntimeException)
1052 {
1053 	return COL_WHITE;
1054 }
1055 
1056 
getImplementationName()1057 OUString SAL_CALL SwAccessibleContext::getImplementationName()
1058         throw( uno::RuntimeException )
1059 {
1060 	ASSERT( !this, "implementation name needs to be overloaded" );
1061 
1062 	THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "implementation name needs to be overloaded" )
1063 }
1064 
1065 sal_Bool SAL_CALL
supportsService(const::rtl::OUString &)1066     SwAccessibleContext::supportsService (const ::rtl::OUString& )
1067         throw (uno::RuntimeException)
1068 {
1069 	ASSERT( !this, "supports service needs to be overloaded" );
1070 	THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "supports service needs to be overloaded" )
1071 }
1072 
getSupportedServiceNames()1073 uno::Sequence< OUString > SAL_CALL SwAccessibleContext::getSupportedServiceNames()
1074 		throw( uno::RuntimeException )
1075 {
1076 	ASSERT( !this, "supported services names needs to be overloaded" );
1077 	THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "supported services needs to be overloaded" )
1078 }
1079 
DisposeShape(const SdrObject * pObj,::accessibility::AccessibleShape * pAccImpl)1080 void SwAccessibleContext::DisposeShape( const SdrObject *pObj,
1081 								::accessibility::AccessibleShape *pAccImpl )
1082 {
1083 	::vos::ORef< ::accessibility::AccessibleShape > xAccImpl( pAccImpl );
1084 	if( !xAccImpl.isValid() )
1085 		xAccImpl = GetMap()->GetContextImpl( pObj, this, sal_True );
1086 
1087 	AccessibleEventObject aEvent;
1088 	aEvent.EventId = AccessibleEventId::CHILD;
1089 	uno::Reference< XAccessible > xAcc( xAccImpl.getBodyPtr() );
1090 	aEvent.OldValue <<= xAcc;
1091 	FireAccessibleEvent( aEvent );
1092 
1093 	GetMap()->RemoveContext( pObj );
1094 	xAccImpl->dispose();
1095 }
1096 
ScrolledInShape(const SdrObject *,::accessibility::AccessibleShape * pAccImpl)1097 void SwAccessibleContext::ScrolledInShape( const SdrObject* ,
1098 								::accessibility::AccessibleShape *pAccImpl )
1099 {
1100 	if(NULL == pAccImpl)
1101 	{
1102 		return ;
1103 	}
1104 	AccessibleEventObject aEvent;
1105 	aEvent.EventId = AccessibleEventId::CHILD;
1106 	uno::Reference< XAccessible > xAcc( pAccImpl );
1107 	aEvent.NewValue <<= xAcc;
1108 	FireAccessibleEvent( aEvent );
1109 
1110 	if( pAccImpl->GetState( AccessibleStateType::FOCUSED ) )
1111 	{
1112 		Window *pWin = GetWindow();
1113 		if( pWin && pWin->HasFocus() )
1114 		{
1115             AccessibleEventObject aStateChangedEvent;
1116             aStateChangedEvent.EventId = AccessibleEventId::STATE_CHANGED;
1117             aStateChangedEvent.NewValue <<= AccessibleStateType::FOCUSED;
1118             aStateChangedEvent.Source = xAcc;
1119 
1120             FireAccessibleEvent( aStateChangedEvent );
1121 		}
1122 	}
1123 }
1124 
Dispose(sal_Bool bRecursive)1125 void SwAccessibleContext::Dispose( sal_Bool bRecursive )
1126 {
1127 	vos::OGuard aGuard(Application::GetSolarMutex());
1128 
1129 	ASSERT( GetFrm() && GetMap(), "already disposed" );
1130 	ASSERT( GetMap()->GetVisArea() == GetVisArea(),
1131 				"invalid vis area for dispose" );
1132 
1133 	bDisposing = sal_True;
1134 
1135 	// dispose children
1136 	if( bRecursive )
1137 		DisposeChildren( GetFrm(), bRecursive );
1138 
1139 	// get parent
1140 	uno::Reference< XAccessible > xParent( GetWeakParent() );
1141 	uno::Reference < XAccessibleContext > xThis( this );
1142 
1143 	// send child event at parent
1144 	if( xParent.is() )
1145 	{
1146 		SwAccessibleContext *pAcc = (SwAccessibleContext *)xParent.get();
1147 
1148 		AccessibleEventObject aEvent;
1149 		aEvent.EventId = AccessibleEventId::CHILD;
1150 		aEvent.OldValue <<= xThis;
1151 		pAcc->FireAccessibleEvent( aEvent );
1152 		DBG_MSG_THIS_PARAM( "AccessibleChild (removed)", pAcc, this )
1153 	}
1154 
1155 	// set defunc state (its not required to broadcast a state changed
1156 	// event if the object is diposed afterwards)
1157 	{
1158         vos::OGuard aDefuncStateGuard( aMutex );
1159 		bIsDefuncState = sal_True;
1160 	}
1161 
1162 	// broadcast dispose event
1163 	if ( nClientId )
1164 	{
1165         comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
1166 		nClientId =  0;
1167 		DBG_MSG_CD( "dispose" )
1168 	}
1169 
1170     RemoveFrmFromAccessibleMap();
1171 	ClearFrm();
1172 	pMap = 0;
1173 
1174 	bDisposing = sal_False;
1175 }
1176 
DisposeChild(const SwAccessibleChild & rChildFrmOrObj,sal_Bool bRecursive)1177 void SwAccessibleContext::DisposeChild( const SwAccessibleChild& rChildFrmOrObj,
1178 										sal_Bool bRecursive )
1179 {
1180 	vos::OGuard aGuard(Application::GetSolarMutex());
1181 
1182     if ( IsShowing( *(GetMap()), rChildFrmOrObj ) ||
1183          rChildFrmOrObj.AlwaysIncludeAsChild() ||
1184          !SwAccessibleChild( GetFrm() ).IsVisibleChildrenOnly() )
1185 	{
1186 		// If the object could have existed before, than there is nothing to do,
1187 		// because no wrapper exists now and therefor no one is interested to
1188 		// get notified of the movement.
1189 		if( rChildFrmOrObj.GetSwFrm() )
1190 		{
1191 			::vos::ORef< SwAccessibleContext > xAccImpl =
1192 					GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(),
1193 											  sal_True );
1194 			xAccImpl->Dispose( bRecursive );
1195 		}
1196         else if ( rChildFrmOrObj.GetDrawObject() )
1197 		{
1198 			::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
1199                     GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(),
1200 											  this, sal_True );
1201             DisposeShape( rChildFrmOrObj.GetDrawObject(),
1202 						  xAccImpl.getBodyPtr() );
1203 		}
1204         else if ( rChildFrmOrObj.GetWindow() )
1205         {
1206             AccessibleEventObject aEvent;
1207             aEvent.EventId = AccessibleEventId::CHILD;
1208             uno::Reference< XAccessible > xAcc =
1209                                     rChildFrmOrObj.GetWindow()->GetAccessible();
1210             aEvent.OldValue <<= xAcc;
1211             FireAccessibleEvent( aEvent );
1212         }
1213 	}
1214 	else if( bRecursive && rChildFrmOrObj.GetSwFrm() )
1215 		DisposeChildren( rChildFrmOrObj.GetSwFrm(), bRecursive );
1216 }
1217 
InvalidatePosOrSize(const SwRect &)1218 void SwAccessibleContext::InvalidatePosOrSize( const SwRect& )
1219 {
1220 	vos::OGuard aGuard(Application::GetSolarMutex());
1221 
1222 	ASSERT( GetFrm() && !GetFrm()->Frm().IsEmpty(), "context should have a size" );
1223 
1224 	sal_Bool bIsOldShowingState;
1225     sal_Bool bIsNewShowingState = IsShowing( *(GetMap()) );
1226 	{
1227         vos::OGuard aShowingStateGuard( aMutex );
1228 		bIsOldShowingState = bIsShowingState;
1229 		bIsShowingState = bIsNewShowingState;
1230 	}
1231 
1232 	if( bIsOldShowingState != bIsNewShowingState )
1233 	{
1234 		FireStateChangedEvent( AccessibleStateType::SHOWING,
1235 							   bIsNewShowingState  );
1236 	}
1237 	else if( bIsNewShowingState )
1238 	{
1239 		// The frame stays visible -> broadcast event
1240 		FireVisibleDataEvent();
1241 	}
1242 
1243     if( !bIsNewShowingState &&
1244         SwAccessibleChild( GetParent() ).IsVisibleChildrenOnly() )
1245 	{
1246 		// The frame is now invisible -> dispose it
1247 		//Remove
1248 		//Dispose( sal_True );
1249 	}
1250 	else
1251 	{
1252 		_InvalidateContent( sal_True );
1253 	}
1254 }
1255 
InvalidateChildPosOrSize(const SwAccessibleChild & rChildFrmOrObj,const SwRect & rOldFrm)1256 void SwAccessibleContext::InvalidateChildPosOrSize(
1257                     const SwAccessibleChild& rChildFrmOrObj,
1258 					const SwRect& rOldFrm )
1259 {
1260 	vos::OGuard aGuard(Application::GetSolarMutex());
1261 
1262 	ASSERT( !rChildFrmOrObj.GetSwFrm() ||
1263 			!rChildFrmOrObj.GetSwFrm()->Frm().IsEmpty(),
1264 			"child context should have a size" );
1265 
1266     if ( rChildFrmOrObj.AlwaysIncludeAsChild() )
1267     {
1268         // nothing to do;
1269         return;
1270     }
1271 
1272     const bool bVisibleChildrenOnly = SwAccessibleChild( GetFrm() ).IsVisibleChildrenOnly();
1273     const bool bNew = rOldFrm.IsEmpty() ||
1274                      ( rOldFrm.Left() == 0 && rOldFrm.Top() == 0 );
1275     if( IsShowing( *(GetMap()), rChildFrmOrObj ) )
1276 	{
1277 		// If the object could have existed before, than there is nothing to do,
1278 		// because no wrapper exists now and therefor no one is interested to
1279 		// get notified of the movement.
1280         if( bNew || (bVisibleChildrenOnly && !IsShowing( rOldFrm )) )
1281 		{
1282 			if( rChildFrmOrObj.GetSwFrm() )
1283 			{
1284 				// The frame becomes visible. A child event must be send.
1285 				::vos::ORef< SwAccessibleContext > xAccImpl =
1286 					GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(),
1287 											  sal_True );
1288 				xAccImpl->ScrolledIn();
1289 			}
1290             else if ( rChildFrmOrObj.GetDrawObject() )
1291 			{
1292 				::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
1293                         GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(),
1294 												  this, sal_True );
1295                 // --> OD 2004-11-29 #i37790#
1296                 if ( xAccImpl.isValid() )
1297                 {
1298                     ScrolledInShape( rChildFrmOrObj.GetDrawObject(),
1299                                      xAccImpl.getBodyPtr() );
1300                 }
1301                 else
1302                 {
1303                     ASSERT( false ,
1304                             "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - no accessible shape found." );
1305                 }
1306                 // <--
1307 			}
1308             else if ( rChildFrmOrObj.GetWindow() )
1309             {
1310                 AccessibleEventObject aEvent;
1311                 aEvent.EventId = AccessibleEventId::CHILD;
1312                 aEvent.NewValue <<= (rChildFrmOrObj.GetWindow()->GetAccessible());
1313                 FireAccessibleEvent( aEvent );
1314             }
1315 		}
1316 	}
1317 	else
1318 	{
1319 		// If the frame was visible before, than a child event for the parent
1320 		// needs to be send. However, there is no wrapper existing, and so
1321 		// no notifications for grandchildren are required. If the are
1322 		// grandgrandchildren, they would be notified by the layout.
1323         if( bVisibleChildrenOnly &&
1324 			!bNew && IsShowing( rOldFrm ) )
1325 		{
1326 			if( rChildFrmOrObj.GetSwFrm() )
1327 			{
1328 				::vos::ORef< SwAccessibleContext > xAccImpl =
1329 					GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(),
1330 											  sal_True );
1331 				xAccImpl->SetParent( this );
1332 				xAccImpl->Dispose( sal_True );
1333 			}
1334             else if ( rChildFrmOrObj.GetDrawObject() )
1335 			{
1336 				::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
1337                         GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(),
1338 												  this, sal_True );
1339                 DisposeShape( rChildFrmOrObj.GetDrawObject(),
1340 						  xAccImpl.getBodyPtr() );
1341 			}
1342             else if ( rChildFrmOrObj.GetWindow() )
1343             {
1344                 ASSERT( false,
1345                         "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - not expected to handle dispose of child of type <Window>." );
1346             }
1347 		}
1348 	}
1349 }
1350 
InvalidateContent()1351 void SwAccessibleContext::InvalidateContent()
1352 {
1353 	vos::OGuard aGuard(Application::GetSolarMutex());
1354 
1355 	_InvalidateContent( sal_False );
1356 }
1357 
InvalidateCursorPos()1358 void SwAccessibleContext::InvalidateCursorPos()
1359 {
1360 	vos::OGuard aGuard(Application::GetSolarMutex());
1361 
1362 	_InvalidateCursorPos();
1363 }
1364 
InvalidateFocus()1365 void SwAccessibleContext::InvalidateFocus()
1366 {
1367 	vos::OGuard aGuard(Application::GetSolarMutex());
1368 
1369 	_InvalidateFocus();
1370 }
1371 
1372 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates>
InvalidateStates(tAccessibleStates _nStates)1373 void SwAccessibleContext::InvalidateStates( tAccessibleStates _nStates )
1374 {
1375 	if( GetMap() )
1376 	{
1377 		ViewShell *pVSh = GetMap()->GetShell();
1378 		if( pVSh )
1379 		{
1380             if( (_nStates & ACC_STATE_EDITABLE) != 0 )
1381 			{
1382 				sal_Bool bIsOldEditableState;
1383 				sal_Bool bIsNewEditableState = IsEditable( pVSh );
1384 				{
1385 					vos::OGuard aGuard( aMutex );
1386 					bIsOldEditableState = bIsEditableState;
1387 					bIsEditableState = bIsNewEditableState;
1388 				}
1389 
1390 				if( bIsOldEditableState != bIsNewEditableState )
1391 					FireStateChangedEvent( AccessibleStateType::EDITABLE,
1392 										   bIsNewEditableState  );
1393 			}
1394             if( (_nStates & ACC_STATE_OPAQUE) != 0 )
1395 			{
1396 				sal_Bool bIsOldOpaqueState;
1397 				sal_Bool bIsNewOpaqueState = IsOpaque( pVSh );
1398 				{
1399 					vos::OGuard aGuard( aMutex );
1400 					bIsOldOpaqueState = bIsOpaqueState;
1401 					bIsOpaqueState = bIsNewOpaqueState;
1402 				}
1403 
1404 				if( bIsOldOpaqueState != bIsNewOpaqueState )
1405 					FireStateChangedEvent( AccessibleStateType::OPAQUE,
1406 										   bIsNewOpaqueState  );
1407 			}
1408 		}
1409 
1410         InvalidateChildrenStates( GetFrm(), _nStates );
1411 	}
1412 }
1413 // <--
1414 
InvalidateRelation(sal_uInt16 nType)1415 void SwAccessibleContext::InvalidateRelation( sal_uInt16 nType )
1416 {
1417 	AccessibleEventObject aEvent;
1418 	aEvent.EventId = nType;
1419 
1420     FireAccessibleEvent( aEvent );
1421 }
1422 
1423 /** text selection has changed
1424 
1425     OD 2005-12-14 #i27301#
1426 
1427     @author OD
1428 */
InvalidateTextSelection()1429 void SwAccessibleContext::InvalidateTextSelection()
1430 {
1431     AccessibleEventObject aEvent;
1432     aEvent.EventId = AccessibleEventId::TEXT_SELECTION_CHANGED;
1433 
1434     FireAccessibleEvent( aEvent );
1435 }
1436 
1437 /** attributes has changed
1438 
1439     OD 2009-01-06 #i88069#
1440 
1441     @author OD
1442 */
InvalidateAttr()1443 void SwAccessibleContext::InvalidateAttr()
1444 {
1445     AccessibleEventObject aEvent;
1446     aEvent.EventId = AccessibleEventId::TEXT_ATTRIBUTE_CHANGED;
1447 
1448     FireAccessibleEvent( aEvent );
1449 }
1450 
HasCursor()1451 sal_Bool SwAccessibleContext::HasCursor()
1452 {
1453 	return sal_False;
1454 }
1455 
Select(SwPaM * pPaM,SdrObject * pObj,sal_Bool bAdd)1456 sal_Bool SwAccessibleContext::Select( SwPaM *pPaM, SdrObject *pObj,
1457 									  sal_Bool bAdd )
1458 {
1459     SwCrsrShell* pCrsrShell = GetCrsrShell();
1460 	if( !pCrsrShell )
1461 		return sal_False;
1462 
1463     SwFEShell* pFEShell = pCrsrShell->ISA( SwFEShell )
1464 								? static_cast<SwFEShell*>( pCrsrShell )
1465 								: 0;
1466 	// Get rid of activated OLE object
1467 	if( pFEShell )
1468 		pFEShell->FinishOLEObj();
1469 
1470 	sal_Bool bRet = sal_False;
1471 	if( pObj )
1472 	{
1473 		if( pFEShell )
1474 		{
1475 			Point aDummy;
1476 			sal_uInt8 nFlags = bAdd ? SW_ADD_SELECT : 0;
1477 			pFEShell->SelectObj( aDummy, nFlags, pObj );
1478 			bRet = sal_True;
1479 		}
1480 	}
1481 	else if( pPaM )
1482 	{
1483 		// Get rid of frame selection. If there is one, make text cursor
1484 		// visible again.
1485 		sal_Bool bCallShowCrsr = sal_False;
1486 		if( pFEShell && (pFEShell->IsFrmSelected() ||
1487 						 pFEShell->IsObjSelected()) )
1488 		{
1489 			Point aPt( LONG_MIN, LONG_MIN );
1490 			pFEShell->SelectObj( aPt, 0 );
1491 			bCallShowCrsr = sal_True;
1492 		}
1493         pCrsrShell->KillPams();
1494         pCrsrShell->SetSelection( *pPaM );
1495 		if( bCallShowCrsr )
1496 			pCrsrShell->ShowCrsr();
1497 		bRet = sal_True;
1498 	}
1499 
1500 	return bRet;
1501 }
1502 
GetResource(sal_uInt16 nResId,const OUString * pArg1,const OUString * pArg2)1503 OUString SwAccessibleContext::GetResource( sal_uInt16 nResId,
1504 										   const OUString *pArg1,
1505 										   const OUString *pArg2 )
1506 {
1507 	String sStr;
1508 	{
1509 		vos::OGuard aGuard(Application::GetSolarMutex());
1510 
1511 		sStr = SW_RES( nResId );
1512 	}
1513 
1514 	if( pArg1 )
1515 	{
1516 		sStr.SearchAndReplace( String::CreateFromAscii(
1517 									RTL_CONSTASCII_STRINGPARAM( "$(ARG1)" )),
1518 							   String( *pArg1 ) );
1519 	}
1520 	if( pArg2 )
1521 	{
1522 		sStr.SearchAndReplace( String::CreateFromAscii(
1523 									RTL_CONSTASCII_STRINGPARAM( "$(ARG2)" )),
1524 							   String( *pArg2 ) );
1525 	}
1526 
1527 	return OUString( sStr );
1528 }
1529 
RemoveFrmFromAccessibleMap()1530 void SwAccessibleContext::RemoveFrmFromAccessibleMap()
1531 {
1532     if( bRegisteredAtAccessibleMap && GetFrm() && GetMap() )
1533         GetMap()->RemoveContext( GetFrm() );
1534 }
1535 
HasAdditionalAccessibleChildren()1536 bool SwAccessibleContext::HasAdditionalAccessibleChildren()
1537 {
1538     bool bRet( false );
1539 
1540     if ( GetFrm()->IsTxtFrm() )
1541     {
1542         SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1543         if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1544         {
1545             bRet = pPostItMgr->HasFrmConnectedSidebarWins( *(GetFrm()) );
1546         }
1547     }
1548 
1549     return bRet;
1550 }
1551 /** get additional accessible child by index
1552 
1553     OD 2010-01-27 #i88070#
1554 
1555     @author OD
1556 */
GetAdditionalAccessibleChild(const sal_Int32 nIndex)1557 Window* SwAccessibleContext::GetAdditionalAccessibleChild( const sal_Int32 nIndex )
1558 {
1559     Window* pAdditionalAccessibleChild( 0 );
1560 
1561     if ( GetFrm()->IsTxtFrm() )
1562     {
1563         SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1564         if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1565         {
1566             pAdditionalAccessibleChild =
1567                     pPostItMgr->GetSidebarWinForFrmByIndex( *(GetFrm()), nIndex );
1568         }
1569     }
1570 
1571     return pAdditionalAccessibleChild;
1572 }
1573 
1574 /** get all additional accessible children
1575 
1576     OD 2010-01-27 #i88070#
1577 
1578     @author OD
1579 */
GetAdditionalAccessibleChildren(std::vector<Window * > * pChildren)1580 void SwAccessibleContext::GetAdditionalAccessibleChildren( std::vector< Window* >* pChildren )
1581 {
1582     if ( GetFrm()->IsTxtFrm() )
1583     {
1584         SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1585         if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1586         {
1587             pPostItMgr->GetAllSidebarWinForFrm( *(GetFrm()), pChildren );
1588         }
1589     }
1590 }
1591 
1592 #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB
lcl_SwAccessibleContext_DbgMsg(SwAccessibleContext * pThisAcc,const char * pMsg,SwAccessibleContext * pChildAcc,sal_Bool bConstrDestr)1593 void lcl_SwAccessibleContext_DbgMsg( SwAccessibleContext *pThisAcc,
1594 									 const char *pMsg,
1595 								     SwAccessibleContext *pChildAcc,
1596 								  	 sal_Bool bConstrDestr )
1597 {
1598 	static SvFileStream aStrm( String::CreateFromAscii("j:\\acc.log"),
1599 					STREAM_WRITE|STREAM_TRUNC|STREAM_SHARE_DENYNONE	);
1600 	ByteString aName( String(pThisAcc->GetName()),
1601 					  RTL_TEXTENCODING_ISO_8859_1 );
1602 	if( aName.Len() )
1603 	{
1604 		aStrm << aName.GetBuffer()
1605 			  << ": ";
1606 	}
1607 	aStrm << pMsg;
1608 	if( pChildAcc )
1609 	{
1610 		ByteString aChild( String(pChildAcc->GetName()),
1611 						   RTL_TEXTENCODING_ISO_8859_1 );
1612 		aStrm << ": "
1613 		      << aChild.GetBuffer();
1614 	}
1615 	aStrm << "\r\n    (";
1616 
1617 	if( !bConstrDestr )
1618 	{
1619 		ByteString aDesc( String(pThisAcc->getAccessibleDescription()),
1620 						   RTL_TEXTENCODING_ISO_8859_1 );
1621 		aStrm << aDesc.GetBuffer()
1622 			  << ", ";
1623 	}
1624 
1625 	Rectangle aVisArea( pThisAcc->GetVisArea() );
1626 	aStrm << "VA: "
1627 		  << ByteString::CreateFromInt32( aVisArea.Left() ).GetBuffer()
1628 		  << ","
1629 		  << ByteString::CreateFromInt32( aVisArea.Top() ).GetBuffer()
1630 		  << ","
1631 		  << ByteString::CreateFromInt32( aVisArea.GetWidth() ).GetBuffer()
1632 		  << ","
1633 		  << ByteString::CreateFromInt32( aVisArea.GetHeight() ).GetBuffer();
1634 
1635 	if( pThisAcc->GetFrm() )
1636 	{
1637 		Rectangle aBounds( pThisAcc->GetBounds( pThisAcc->GetFrm() ) );
1638 		aStrm << ", BB: "
1639 			  << ByteString::CreateFromInt32( aBounds.Left() ).GetBuffer()
1640 			  << ","
1641 			  << ByteString::CreateFromInt32( aBounds.Top() ).GetBuffer()
1642 			  << ","
1643 			  << ByteString::CreateFromInt32( aBounds.GetWidth() ).GetBuffer()
1644 			  << ","
1645 			  << ByteString::CreateFromInt32( aBounds.GetHeight() ).GetBuffer()
1646 			  << ")\r\n";
1647 	}
1648 
1649 	aStrm.Flush();
1650 }
1651 #endif
SetSelectedState(sal_Bool bSeleted)1652 sal_Bool SwAccessibleContext::SetSelectedState(sal_Bool bSeleted)
1653 {
1654 	if(bIsSeletedInDoc != bSeleted)
1655 	{
1656 		bIsSeletedInDoc = bSeleted;
1657 		FireStateChangedEvent( AccessibleStateType::SELECTED, bSeleted );
1658 		return sal_True;
1659 	}
1660 	return sal_False;
1661 };
1662