xref: /aoo42x/main/sw/source/core/access/accdoc.cxx (revision 0deba7fb)
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 #include <vcl/window.hxx>
27 #include <rootfrm.hxx>
28 
29 
30 #include <com/sun/star/accessibility/AccessibleRole.hpp>
31 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
32 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
33 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
34 #include <unotools/accessiblestatesethelper.hxx>
35 #include <tools/link.hxx>
36 #include <sfx2/viewsh.hxx>
37 #include <vos/mutex.hxx>
38 #include <vcl/svapp.hxx>
39 #include <viewsh.hxx>
40 #include <doc.hxx>
41 #include <accmap.hxx>
42 #include <accdoc.hxx>
43 #ifndef _ACCESS_HRC
44 #include "access.hrc"
45 #endif
46 #include <pagefrm.hxx>
47 
48 //IAccessibility2 Implementation 2009-----
49 #include <editeng/brshitem.hxx>
50 #include <swatrset.hxx>
51 #include <frmatr.hxx>
52 #include "unostyle.hxx"
53 #include "viewsh.hxx"
54 #include "docsh.hxx"
55 #include <crsrsh.hxx>
56 #include "fesh.hxx"
57 #include <fmtclds.hxx>
58 #include <flyfrm.hxx>
59 #include <colfrm.hxx>
60 #include <txtfrm.hxx>
61 #include <sectfrm.hxx>
62 #include <section.hxx>
63 #include <svx/unoapi.hxx>
64 #include <swmodule.hxx>
65 #include <svtools/colorcfg.hxx>
66 //for note accessibility
67 //#include "postit.hxx"
68 //#include "PostItMgr.hxx"
69 
70 #include <fmtanchr.hxx>
71 #include <viewimp.hxx>
72 #include <dview.hxx>
73 #include <dcontact.hxx>
74 #include <svx/svdmark.hxx>
75 //-----IAccessibility2 Implementation 2009
76 const sal_Char sServiceName[] = "com.sun.star.text.AccessibleTextDocumentView";
77 const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleDocumentView";
78 
79 
80 using namespace ::com::sun::star;
81 using namespace ::com::sun::star::accessibility;
82 using ::rtl::OUString;
83 
84 using lang::IndexOutOfBoundsException;
85 
86 
87 
88 //
89 // SwAccessibleDocumentBase: base class for SwAccessibleDocument and
90 // SwAccessiblePreview
91 //
92 
93 SwAccessibleDocumentBase::SwAccessibleDocumentBase ( SwAccessibleMap *_pMap ) :
94 	SwAccessibleContext( _pMap, AccessibleRole::DOCUMENT,
95                          _pMap->GetShell()->GetLayout() ),//swmod 071107//swmod 071225
96 	mxParent( _pMap->GetShell()->GetWin()->GetAccessibleParentWindow()->GetAccessible() ),
97     mpChildWin( 0 )
98 {
99 }
100 
101 SwAccessibleDocumentBase::~SwAccessibleDocumentBase()
102 {
103 }
104 
105 void SwAccessibleDocumentBase::SetVisArea()
106 {
107 	vos::OGuard aGuard(Application::GetSolarMutex());
108 
109 	SwRect aOldVisArea( GetVisArea() );
110 	const SwRect& rNewVisArea = GetMap()->GetVisArea();
111 	if( aOldVisArea != rNewVisArea )
112 	{
113 		SwAccessibleFrame::SetVisArea( GetMap()->GetVisArea() );
114         // --> OD 2007-12-07 #i58139#
115         // showing state of document view needs also be updated.
116         // Thus, call method <Scrolled(..)> instead of <ChildrenScrolled(..)>
117 //        ChildrenScrolled( GetFrm(), aOldVisArea );
118         Scrolled( aOldVisArea );
119         // <--
120 	}
121 }
122 
123 void SwAccessibleDocumentBase::AddChild( Window *pWin, sal_Bool bFireEvent )
124 {
125 	vos::OGuard aGuard(Application::GetSolarMutex());
126 
127     ASSERT( !mpChildWin, "only one child window is supported" );
128     if( !mpChildWin )
129 	{
130         mpChildWin = pWin;
131 
132 		if( bFireEvent )
133 		{
134 			AccessibleEventObject aEvent;
135 			aEvent.EventId = AccessibleEventId::CHILD;
136             aEvent.NewValue <<= mpChildWin->GetAccessible();
137 			FireAccessibleEvent( aEvent );
138 		}
139 	}
140 }
141 
142 void SwAccessibleDocumentBase::RemoveChild( Window *pWin )
143 {
144 	vos::OGuard aGuard(Application::GetSolarMutex());
145 
146     ASSERT( !mpChildWin || pWin == mpChildWin, "invalid child window to remove" );
147     if( mpChildWin && pWin == mpChildWin )
148 	{
149 		AccessibleEventObject aEvent;
150 		aEvent.EventId = AccessibleEventId::CHILD;
151         aEvent.OldValue <<= mpChildWin->GetAccessible();
152 		FireAccessibleEvent( aEvent );
153 
154         mpChildWin = 0;
155 	}
156 }
157 
158 sal_Int32 SAL_CALL SwAccessibleDocumentBase::getAccessibleChildCount( void )
159         throw (uno::RuntimeException)
160 {
161 	vos::OGuard aGuard(Application::GetSolarMutex());
162 
163 	// CHECK_FOR_DEFUNC is called by parent
164 
165 	sal_Int32 nChildren = SwAccessibleContext::getAccessibleChildCount();
166     if( !IsDisposing() && mpChildWin )
167 		nChildren++;
168 
169 	return nChildren;
170 }
171 
172 uno::Reference< XAccessible> SAL_CALL
173 	SwAccessibleDocumentBase::getAccessibleChild( sal_Int32 nIndex )
174         throw (uno::RuntimeException,
175                 lang::IndexOutOfBoundsException)
176 {
177 	vos::OGuard aGuard(Application::GetSolarMutex());
178 
179     if( mpChildWin  )
180 	{
181 		CHECK_FOR_DEFUNC( XAccessibleContext )
182         if ( nIndex == GetChildCount( *(GetMap()) ) )
183         {
184             return mpChildWin->GetAccessible();
185         }
186 	}
187 
188 	return SwAccessibleContext::getAccessibleChild( nIndex );
189 }
190 
191 
192 uno::Reference< XAccessible> SAL_CALL SwAccessibleDocumentBase::getAccessibleParent (void)
193         throw (uno::RuntimeException)
194 {
195     return mxParent;
196 }
197 
198 sal_Int32 SAL_CALL SwAccessibleDocumentBase::getAccessibleIndexInParent (void)
199         throw (uno::RuntimeException)
200 {
201 	vos::OGuard aGuard(Application::GetSolarMutex());
202 
203 	uno::Reference < XAccessibleContext > xAcc( mxParent->getAccessibleContext() );
204 	uno::Reference < XAccessible > xThis( this );
205 	sal_Int32 nCount = xAcc->getAccessibleChildCount();
206 
207 	for( sal_Int32 i=0; i < nCount; i++ )
208 	{
209 		//IAccessibility2 Implementation 2009-----
210 		try
211 		{
212 			if( xAcc->getAccessibleChild( i ) == xThis )
213 				return i;
214 		}
215 		catch(::com::sun::star::lang::IndexOutOfBoundsException e)
216 		{
217 			return -1L;
218 		}
219 		//-----IAccessibility2 Implementation 2009
220 	}
221 	return -1L;
222 }
223 
224 OUString SAL_CALL SwAccessibleDocumentBase::getAccessibleDescription (void)
225     throw (uno::RuntimeException)
226 {
227 	return GetResource( STR_ACCESS_DOC_DESC );
228 }
229 
230 //IAccessibility2 Implementation 2009-----
231 OUString SAL_CALL SwAccessibleDocumentBase::getAccessibleName (void)
232 		throw (::com::sun::star::uno::RuntimeException)
233 {
234 	OUString sAccName = GetResource( STR_ACCESS_DOC_WORDPROCESSING );
235 	SwDoc *pDoc = GetShell()->GetDoc();
236 	if ( pDoc )
237 	{
238 		OUString sFileName = pDoc->getDocAccTitle();
239 		if ( !sFileName.getLength() )
240 		{
241 			SwDocShell* pDocSh = pDoc->GetDocShell();
242 			if ( pDocSh )
243 			{
244 				sFileName = pDocSh->GetTitle( SFX_TITLE_APINAME );
245 			}
246 		}
247 		OUString sReadOnly;
248 		if(pDoc->getDocReadOnly())
249 		{
250 			sReadOnly = GetResource( STR_ACCESS_DOC_WORDPROCESSING_READONLY );
251 		}
252 
253 		if ( sFileName.getLength() )
254 		{
255 			sAccName = sFileName + sReadOnly + OUString(RTL_CONSTASCII_USTRINGPARAM(" - ")) + sAccName;
256 		}
257 	}
258 
259 	return sAccName;
260 }
261 //-----IAccessibility2 Implementation 2009
262 
263 awt::Rectangle SAL_CALL SwAccessibleDocumentBase::getBounds()
264 		throw (uno::RuntimeException)
265 {
266 	//IAccessibility2 Implementation 2009-----
267 	try
268 	{
269 		vos::OGuard aGuard(Application::GetSolarMutex());
270 
271 		Window *pWin = GetWindow();
272 
273 		CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
274 
275 			Rectangle aPixBounds( pWin->GetWindowExtentsRelative( pWin->GetAccessibleParentWindow() ) );
276 		awt::Rectangle aBox( aPixBounds.Left(), aPixBounds.Top(),
277 			aPixBounds.GetWidth(), aPixBounds.GetHeight() );
278 
279 		return aBox;
280 	}
281 	catch(::com::sun::star::lang::IndexOutOfBoundsException e)
282 	{
283 		return awt::Rectangle();
284 	}
285 	//-----IAccessibility2 Implementation 2009
286 }
287 
288 
289 awt::Point SAL_CALL SwAccessibleDocumentBase::getLocation()
290 		throw (uno::RuntimeException)
291 {
292 	vos::OGuard aGuard(Application::GetSolarMutex());
293 
294 	Window *pWin = GetWindow();
295 
296 	CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
297 
298 	Point aPixPos( pWin->GetWindowExtentsRelative( pWin->GetAccessibleParentWindow() ).TopLeft() );
299 	awt::Point aLoc( aPixPos.X(), aPixPos.Y() );
300 
301 	return aLoc;
302 }
303 
304 
305 ::com::sun::star::awt::Point SAL_CALL SwAccessibleDocumentBase::getLocationOnScreen()
306 		throw (uno::RuntimeException)
307 {
308 	vos::OGuard aGuard(Application::GetSolarMutex());
309 
310 	Window *pWin = GetWindow();
311 
312 	CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
313 
314 	Point aPixPos( pWin->GetWindowExtentsRelative( 0 ).TopLeft() );
315 	awt::Point aLoc( aPixPos.X(), aPixPos.Y() );
316 
317 	return aLoc;
318 }
319 
320 
321 ::com::sun::star::awt::Size SAL_CALL SwAccessibleDocumentBase::getSize()
322 		throw (uno::RuntimeException)
323 {
324 	vos::OGuard aGuard(Application::GetSolarMutex());
325 
326 	Window *pWin = GetWindow();
327 
328 	CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
329 
330 	Size aPixSize( pWin->GetWindowExtentsRelative( 0 ).GetSize() );
331 	awt::Size aSize( aPixSize.Width(), aPixSize.Height() );
332 
333 	return aSize;
334 }
335 
336 sal_Bool SAL_CALL SwAccessibleDocumentBase::containsPoint(
337 			const awt::Point& aPoint )
338 		throw (uno::RuntimeException)
339 {
340 	vos::OGuard aGuard(Application::GetSolarMutex());
341 
342 	Window *pWin = GetWindow();
343 
344 	CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
345 
346 	Rectangle aPixBounds( pWin->GetWindowExtentsRelative( 0 ) );
347     aPixBounds.Move(-aPixBounds.Left(), -aPixBounds.Top());
348 
349 	Point aPixPoint( aPoint.X, aPoint.Y );
350 	return aPixBounds.IsInside( aPixPoint );
351 }
352 
353 uno::Reference< XAccessible > SAL_CALL SwAccessibleDocumentBase::getAccessibleAtPoint(
354 				const awt::Point& aPoint )
355 		throw (uno::RuntimeException)
356 {
357 	vos::OGuard aGuard(Application::GetSolarMutex());
358 
359     if( mpChildWin  )
360 	{
361 		CHECK_FOR_DEFUNC( XAccessibleComponent )
362 
363 		Window *pWin = GetWindow();
364 		CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
365 
366 		Point aPixPoint( aPoint.X, aPoint.Y ); // px rel to window
367         if( mpChildWin->GetWindowExtentsRelative( pWin ).IsInside( aPixPoint ) )
368             return mpChildWin->GetAccessible();
369 	}
370 
371 	return SwAccessibleContext::getAccessibleAtPoint( aPoint );
372 }
373 
374 //
375 // SwAccessibeDocument
376 //
377 
378 void SwAccessibleDocument::GetStates(
379 		::utl::AccessibleStateSetHelper& rStateSet )
380 {
381 	SwAccessibleContext::GetStates( rStateSet );
382 
383 	// MULTISELECTABLE
384 	rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
385 	//IAccessibility2 Implementation 2009-----
386 	rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
387 	//-----IAccessibility2 Implementation 2009
388 }
389 
390 
391 SwAccessibleDocument::SwAccessibleDocument ( SwAccessibleMap* pInitMap ) :
392     SwAccessibleDocumentBase( pInitMap ),
393     maSelectionHelper( *this )
394 {
395 	SetName( GetResource( STR_ACCESS_DOC_NAME ) );
396     Window *pWin = pInitMap->GetShell()->GetWin();
397 	if( pWin )
398 	{
399 		pWin->AddChildEventListener( LINK( this, SwAccessibleDocument, WindowChildEventListener ));
400 		sal_uInt16 nCount =   pWin->GetChildCount();
401 		for( sal_uInt16 i=0; i < nCount; i++ )
402 		{
403             Window* pChildWin = pWin->GetChild( i );
404             if( pChildWin &&
405                 AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
406                 AddChild( pChildWin, sal_False );
407 		}
408 	}
409 }
410 
411 SwAccessibleDocument::~SwAccessibleDocument()
412 {
413 	Window *pWin = GetMap() ? GetMap()->GetShell()->GetWin() : 0;
414 	if( pWin )
415 		pWin->RemoveChildEventListener( LINK( this, SwAccessibleDocument, WindowChildEventListener ));
416 }
417 
418 void SwAccessibleDocument::Dispose( sal_Bool bRecursive )
419 {
420 	ASSERT( GetFrm() && GetMap(), "already disposed" );
421 
422 	Window *pWin = GetMap() ? GetMap()->GetShell()->GetWin() : 0;
423 	if( pWin )
424 		pWin->RemoveChildEventListener( LINK( this, SwAccessibleDocument, WindowChildEventListener ));
425 	SwAccessibleContext::Dispose( bRecursive );
426 }
427 
428 IMPL_LINK( SwAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent )
429 {
430 	DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
431 	if ( pEvent && pEvent->ISA( VclWindowEvent ) )
432 	{
433 		VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent );
434 		DBG_ASSERT( pVclEvent->GetWindow(), "Window???" );
435 		switch ( pVclEvent->GetId() )
436 		{
437         case VCLEVENT_WINDOW_SHOW:  // send create on show for direct accessible children
438 			{
439 				Window* pChildWin = static_cast< Window* >( pVclEvent->GetData() );
440 				if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
441 				{
442 					AddChild( pChildWin );
443 				}
444 			}
445 			break;
446         case VCLEVENT_WINDOW_HIDE:  // send destroy on hide for direct accessible children
447 			{
448 				Window* pChildWin = static_cast< Window* >( pVclEvent->GetData() );
449 				if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
450 				{
451 					RemoveChild( pChildWin );
452 				}
453 			}
454 			break;
455         case VCLEVENT_OBJECT_DYING:  // send destroy on hide for direct accessible children
456 			{
457 				Window* pChildWin = pVclEvent->GetWindow();
458 				if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
459 				{
460 					RemoveChild( pChildWin );
461 				}
462 			}
463 			break;
464 		}
465 	}
466 	return 0;
467 }
468 
469 
470 OUString SAL_CALL SwAccessibleDocument::getImplementationName()
471         throw( uno::RuntimeException )
472 {
473 	return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationName));
474 }
475 
476 sal_Bool SAL_CALL SwAccessibleDocument::supportsService(
477 		const ::rtl::OUString& sTestServiceName)
478 	throw (uno::RuntimeException)
479 {
480 	return sTestServiceName.equalsAsciiL( sServiceName,
481 										  sizeof(sServiceName)-1 ) ||
482 		   sTestServiceName.equalsAsciiL( sAccessibleServiceName,
483 				   						  sizeof(sAccessibleServiceName)-1 );
484 }
485 
486 uno::Sequence< OUString > SAL_CALL SwAccessibleDocument::getSupportedServiceNames()
487 		throw( uno::RuntimeException )
488 {
489 	uno::Sequence< OUString > aRet(2);
490 	OUString* pArray = aRet.getArray();
491 	pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceName) );
492 	pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleServiceName) );
493 	return aRet;
494 }
495 
496 //=====  XInterface  ======================================================
497 
498 uno::Any SwAccessibleDocument::queryInterface(
499     const uno::Type& rType )
500     throw ( uno::RuntimeException )
501 {
502     uno::Any aRet;
503     if ( rType == ::getCppuType( static_cast< uno::Reference< XAccessibleSelection > * >( 0 ) ) )
504     {
505         uno::Reference<XAccessibleSelection> aSelect = this;
506         aRet <<= aSelect;
507     }
508     //IAccessibility2 Implementation 2009-----
509     //Solution:Add XEventListener interface support.
510 	else if ( (rType == ::getCppuType((uno::Reference<com::sun::star::document::XEventListener> *)NULL)) )
511     {
512         uno::Reference<com::sun::star::document::XEventListener> aSelect = this;
513         aRet <<= aSelect;
514     }
515     else  if ( rType == ::getCppuType((uno::Reference<XAccessibleExtendedAttributes> *)NULL) )
516     {
517         uno::Reference<XAccessibleExtendedAttributes> aAttribute = this;
518         aRet <<= aAttribute;
519     }
520     else if(rType == ::getCppuType((uno::Reference<XAccessibleGetAccFlowTo> *)NULL) )
521     {
522 		uno::Reference<XAccessibleGetAccFlowTo> AccFlowTo = this;
523         aRet <<= AccFlowTo;
524     }
525     //-----IAccessibility2 Implementation 2009
526     else
527         aRet = SwAccessibleContext::queryInterface( rType );
528     return aRet;
529 }
530 
531 //====== XTypeProvider ====================================================
532 uno::Sequence< uno::Type > SAL_CALL SwAccessibleDocument::getTypes()
533     throw(uno::RuntimeException)
534 {
535 	uno::Sequence< uno::Type > aTypes( SwAccessibleDocumentBase::getTypes() );
536 
537 	sal_Int32 nIndex = aTypes.getLength();
538 	//IAccessibility2 Implementation 2009-----
539 	//Solution:Reset types memory alloc
540 	//aTypes.realloc( nIndex + 1 );
541 	aTypes.realloc( nIndex + 2 );
542 
543 	uno::Type* pTypes = aTypes.getArray();
544 	pTypes[nIndex] = ::getCppuType( static_cast< uno::Reference< XAccessibleSelection > * >( 0 ) );
545 	//Solution:Add XEventListener interface support.
546 	pTypes[nIndex + 1 ] = ::getCppuType( static_cast< uno::Reference< com::sun::star::document::XEventListener > * >( 0 ) );
547 	//-----IAccessibility2 Implementation 2009
548 	return aTypes;
549 }
550 
551 uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleDocument::getImplementationId()
552 		throw(uno::RuntimeException)
553 {
554     vos::OGuard aGuard(Application::GetSolarMutex());
555     static uno::Sequence< sal_Int8 > aId( 16 );
556     static sal_Bool bInit = sal_False;
557     if(!bInit)
558     {
559         rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
560         bInit = sal_True;
561     }
562     return aId;
563 }
564 
565 //=====  XAccessibleSelection  ============================================
566 
567 void SwAccessibleDocument::selectAccessibleChild(
568     sal_Int32 nChildIndex )
569     throw ( lang::IndexOutOfBoundsException,
570             uno::RuntimeException )
571 {
572     maSelectionHelper.selectAccessibleChild(nChildIndex);
573 }
574 
575 sal_Bool SwAccessibleDocument::isAccessibleChildSelected(
576     sal_Int32 nChildIndex )
577     throw ( lang::IndexOutOfBoundsException,
578             uno::RuntimeException )
579 {
580     return maSelectionHelper.isAccessibleChildSelected(nChildIndex);
581 }
582 
583 void SwAccessibleDocument::clearAccessibleSelection(  )
584     throw ( uno::RuntimeException )
585 {
586     maSelectionHelper.clearAccessibleSelection();
587 }
588 
589 void SwAccessibleDocument::selectAllAccessibleChildren(  )
590     throw ( uno::RuntimeException )
591 {
592     maSelectionHelper.selectAllAccessibleChildren();
593 }
594 
595 sal_Int32 SwAccessibleDocument::getSelectedAccessibleChildCount(  )
596     throw ( uno::RuntimeException )
597 {
598     return maSelectionHelper.getSelectedAccessibleChildCount();
599 }
600 
601 uno::Reference<XAccessible> SwAccessibleDocument::getSelectedAccessibleChild(
602     sal_Int32 nSelectedChildIndex )
603     throw ( lang::IndexOutOfBoundsException,
604             uno::RuntimeException)
605 {
606     return maSelectionHelper.getSelectedAccessibleChild(nSelectedChildIndex);
607 }
608 
609 // --> OD 2004-11-16 #111714# - index has to be treated as global child index.
610 void SwAccessibleDocument::deselectAccessibleChild(
611     sal_Int32 nChildIndex )
612     throw ( lang::IndexOutOfBoundsException,
613             uno::RuntimeException )
614 {
615     maSelectionHelper.deselectAccessibleChild( nChildIndex );
616 }
617 //IAccessibility2 Implementation 2009-----
618 //Solution:Implement XEventListener interfaces
619 void SAL_CALL SwAccessibleDocument::notifyEvent( const ::com::sun::star::document::EventObject& Event )
620 			throw (::com::sun::star::uno::RuntimeException)
621 {
622 	if ( Event.EventName.equalsAscii( "FirstPageShows" ) )
623 	{
624 		FireStateChangedEvent( AccessibleStateType::FOCUSED,sal_True );
625 	}
626 	else if ( Event.EventName.equalsAscii( "LoadFinished" ) )
627 	{
628 		// IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent
629 		// FireStateChangedEvent( AccessibleStateType::OFFSCREEN,sal_True );
630 		// MT: LoadFinished => Why not SHOWING == TRUE?
631 		FireStateChangedEvent( AccessibleStateType::SHOWING,sal_False );
632 	}
633 	else if ( Event.EventName.equalsAscii( "FormatFinished" ) )
634 	{
635 		FireStateChangedEvent( AccessibleStateType::BUSY,sal_False );
636 		// FireStateChangedEvent( AccessibleStateType::OFFSCREEN,sal_False );
637 		FireStateChangedEvent( AccessibleStateType::SHOWING,sal_True );
638 	}
639 	else
640 	{
641 		isIfAsynLoad = sal_False;
642 	}
643 }
644 
645 void SAL_CALL SwAccessibleDocument::disposing( const ::com::sun::star::lang::EventObject& )
646 			throw (::com::sun::star::uno::RuntimeException)
647 {
648 }
649 
650 uno::Any SAL_CALL SwAccessibleDocument::getExtendedAttributes()
651 		throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
652 {
653 	uno::Any anyAtrribute;
654 	SwDoc *pDoc = GetShell()->GetDoc();
655 
656 	if (!pDoc)
657 		return anyAtrribute;
658 	SwCrsrShell* pCrsrShell = GetCrsrShell();
659 	if( !pCrsrShell )
660 		return anyAtrribute;
661 
662     SwFEShell* pFEShell = pCrsrShell->ISA( SwFEShell )
663 								? static_cast<SwFEShell*>( pCrsrShell )
664 							: 0;
665 	rtl::OUString sAttrName;
666 	rtl::OUString sValue;
667 	sal_uInt16 nPage, nLogPage;
668 	String sDisplay;
669 
670 	if( pFEShell )
671 	{
672 		pFEShell->GetPageNumber(-1,sal_True,nPage,nLogPage,sDisplay);
673 		sAttrName = rtl::OUString::createFromAscii("page-name:");
674 
675 
676 		sValue = sAttrName + sDisplay ;
677 		sAttrName = rtl::OUString::createFromAscii(";page-number:");
678 		sValue += sAttrName;
679 		sValue += String::CreateFromInt32( nPage ) ;
680 		sAttrName = rtl::OUString::createFromAscii(";total-pages:");
681 		sValue += sAttrName;
682 		sValue += String::CreateFromInt32( pCrsrShell->GetPageCnt() ) ;
683 		sValue +=  rtl::OUString::createFromAscii(";");
684 
685 
686 		sAttrName=rtl::OUString::createFromAscii("line-number:");
687 
688 
689 
690 		SwCntntFrm* pCurrFrm = pCrsrShell->GetCurrFrm();
691 		SwPageFrm* pCurrPage=((SwFrm*)pCurrFrm)->FindPageFrm();
692 		sal_uLong nLineNum = 0;
693 		//IAccessibility2 Implementation 2009-----
694 		SwTxtFrm* pTxtFrm = NULL;
695 		SwTxtFrm* pCurrTxtFrm = NULL;
696 		pTxtFrm = static_cast< SwTxtFrm* >(static_cast< SwPageFrm* > (pCurrPage)->ContainsCntnt());
697 		if (pCurrFrm->IsInFly())//such as, graphic,chart
698 		{
699 			SwFlyFrm *pFlyFrm = pCurrFrm->FindFlyFrm();
700 			const SwFmtAnchor& rAnchor = pFlyFrm->GetFmt()->GetAnchor();
701 			RndStdIds eAnchorId = rAnchor.GetAnchorId();
702 			if(eAnchorId == FLY_AS_CHAR)
703 			{
704 				const SwFrm *pSwFrm = pFlyFrm->GetAnchorFrm();
705 				if(pSwFrm->IsTxtFrm())
706 					pCurrTxtFrm = ((SwTxtFrm*)(pSwFrm));
707 			}
708 		}
709 		else
710 			pCurrTxtFrm = static_cast< SwTxtFrm* >(pCurrFrm);
711 		//check whether the text frame where the Graph/OLE/Frame anchored is in the Header/Footer
712 		SwFrm* pFrm = pCurrTxtFrm;
713 		while ( pFrm && !pFrm->IsHeaderFrm() && !pFrm->IsFooterFrm() )
714 			pFrm = pFrm->GetUpper();
715 		if ( pFrm )
716 			pCurrTxtFrm = NULL;
717 		//check shape
718 		if(pCrsrShell->Imp()->GetDrawView())
719 		{
720 			const SdrMarkList &rMrkList = pCrsrShell->Imp()->GetDrawView()->GetMarkedObjectList();
721 			for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
722 			{
723 				SdrObject *pObj = rMrkList.GetMark(i)->GetMarkedSdrObj();
724 				SwFrmFmt* pFmt = ((SwDrawContact*)pObj->GetUserCall())->GetFmt();
725 				const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
726 				if( FLY_AS_CHAR != rAnchor.GetAnchorId() )
727 					pCurrTxtFrm = NULL;
728 			}
729 		}
730 		//calculate line number
731 		if (pCurrTxtFrm && pTxtFrm)
732 		{
733 			if (!(pCurrTxtFrm->IsInTab() || pCurrTxtFrm->IsInFtn()))
734 			{
735 				while( pTxtFrm != pCurrTxtFrm )
736 				{
737 					//check header/footer
738 					pFrm = pTxtFrm;
739 					while ( pFrm && !pFrm->IsHeaderFrm() && !pFrm->IsFooterFrm() )
740 						pFrm = pFrm->GetUpper();
741 					if ( pFrm )
742 					{
743 						pTxtFrm = static_cast< SwTxtFrm*>(pTxtFrm->GetNextCntntFrm());
744 						continue;
745 					}
746 					if (!(pTxtFrm->IsInTab() || pTxtFrm->IsInFtn() || pTxtFrm->IsInFly()))
747 						nLineNum += pTxtFrm->GetThisLines();
748 					pTxtFrm = static_cast< SwTxtFrm* >(pTxtFrm ->GetNextCntntFrm());
749 				}
750 				SwPaM* pCaret = pCrsrShell->GetCrsr();
751 				if (!pCurrTxtFrm->IsEmpty() && pCaret)
752 				{
753 					sal_uInt16 nActPos = 0;
754 					if (pCurrTxtFrm->IsTxtFrm())
755 					{
756 						const SwPosition* pPoint = NULL;
757 						if(pCurrTxtFrm->IsInFly())
758 						{
759 							SwFlyFrm *pFlyFrm = pCurrTxtFrm->FindFlyFrm();
760 							const SwFmtAnchor& rAnchor = pFlyFrm->GetFmt()->GetAnchor();
761 							pPoint= rAnchor.GetCntntAnchor();
762 						}
763 						else
764 							pPoint = pCaret->GetPoint();
765 						nActPos = pPoint->nContent.GetIndex();
766 						nLineNum += pCurrTxtFrm->GetLineCount( nActPos );
767 					}
768 					else//graphic, form, shape, etc.
769 					{
770 						SwPosition* pPoint =  pCaret->GetPoint();
771 						Point aPt = pCrsrShell->_GetCrsr()->GetPtPos();
772 						if( pCrsrShell->GetLayout()->GetCrsrOfst( pPoint, aPt/*,* &eTmpState*/ ) )
773 						{
774 							nActPos = pPoint->nContent.GetIndex();
775 							nLineNum += pCurrTxtFrm->GetLineCount( nActPos );
776 						}
777 					}
778 				}
779 				else
780 					++nLineNum;
781 			}
782 		}
783 		//-----IAccessibility2 Implementation 2009
784 
785 		sValue += sAttrName;
786 		sValue += String::CreateFromInt32( nLineNum ) ;
787 
788 		sValue +=  rtl::OUString::createFromAscii(";");
789 
790 
791 		SwFrm* pCurrCol=((SwFrm*)pCurrFrm)->FindColFrm();
792 
793 		sAttrName=rtl::OUString::createFromAscii("column-number:");
794 		sValue += sAttrName;
795 
796 		sal_uInt16 nCurrCol = 1;
797 		if(pCurrCol!=NULL)
798 		{
799 			//SwLayoutFrm* pParent = pCurrCol->GetUpper();
800 			SwFrm* pCurrPageCol=((SwFrm*)pCurrFrm)->FindColFrm();
801 			while(pCurrPageCol && pCurrPageCol->GetUpper() && pCurrPageCol->GetUpper()->IsPageFrm())
802 			{
803 				pCurrPageCol = pCurrPageCol->GetUpper();
804 			}
805 
806 			SwLayoutFrm* pParent = (SwLayoutFrm*)(pCurrPageCol->GetUpper());
807 
808 			if(pParent!=NULL)
809 			{
810 				SwFrm* pCol = pParent->Lower();
811 				while(pCol&&(pCol!=pCurrPageCol))
812 				{
813 					pCol = pCol->GetNext();
814 					nCurrCol +=1;
815 				}
816 			}
817 		}
818 		sValue += String::CreateFromInt32( nCurrCol ) ;
819 		sValue +=  rtl::OUString::createFromAscii(";");
820 
821 		sAttrName=rtl::OUString::createFromAscii("total-columns:");
822 
823 		const SwFmtCol &rFmtCol=pCurrPage->GetAttrSet()->GetCol();
824 		sal_uInt16 nColCount=rFmtCol.GetNumCols();
825 		nColCount = nColCount>0?nColCount:1;
826 		sValue += sAttrName;
827 		sValue += String::CreateFromInt32( nColCount ) ;
828 
829 		sValue +=  rtl::OUString::createFromAscii(";");
830 
831 		if(pCurrFrm!=NULL)
832 		{
833 			SwSectionFrm* pCurrSctFrm=((SwFrm*)pCurrFrm)->FindSctFrm();
834 			if(pCurrSctFrm!=NULL && pCurrSctFrm->GetSection()!=NULL )
835 			{
836 				sAttrName = rtl::OUString::createFromAscii("section-name:");
837 
838 				sValue += sAttrName;
839 				String sectionName = pCurrSctFrm->GetSection()->GetSectionName();
840 
841 				sectionName.SearchAndReplace( String::CreateFromAscii( "\\" ), String::CreateFromAscii("\\\\" ));
842 				sectionName.SearchAndReplace( String::CreateFromAscii( "=" ), String::CreateFromAscii("\\=" ) );
843 				sectionName.SearchAndReplace( String::CreateFromAscii( ";" ), String::CreateFromAscii("\\;" ) );
844 				sectionName.SearchAndReplace( String::CreateFromAscii( "," ), String::CreateFromAscii("\\," ) );
845 				sectionName.SearchAndReplace( String::CreateFromAscii( ":" ), String::CreateFromAscii("\\:" ) );
846 
847 				sValue += sectionName;
848 				//sValue += pCurrSctFrm->GetSection()->GetName();
849 
850 				sValue += rtl::OUString::createFromAscii(";");
851 
852 				//section-columns-number
853 				{
854 				sAttrName=rtl::OUString::createFromAscii("section-columns-number:");
855 
856 				nCurrCol = 1;
857 
858 				if(pCurrCol!=NULL)
859 				{
860 					SwLayoutFrm* pParent = pCurrCol->GetUpper();
861 					if(pParent!=NULL)
862 					{
863 						SwFrm* pCol = pParent->Lower();
864 						while(pCol&&(pCol!=pCurrCol))
865 						{
866 							pCol = pCol->GetNext();
867 							nCurrCol +=1;
868 						}
869 					}
870 				}
871 				sValue += sAttrName;
872 				sValue += String::CreateFromInt32( nCurrCol ) ;
873 				sValue +=  rtl::OUString::createFromAscii(";");
874 				}
875 
876 				//section-total-columns
877 				{
878 				sAttrName=rtl::OUString::createFromAscii("section-total-columns:");
879 				const SwFmtCol &rFmtSctCol=pCurrSctFrm->GetAttrSet()->GetCol();
880 				sal_uInt16 nSctColCount=rFmtSctCol.GetNumCols();
881 				nSctColCount = nSctColCount>0?nSctColCount:1;
882 				sValue += sAttrName;
883 				sValue += String::CreateFromInt32( nSctColCount ) ;
884 
885 				sValue +=  rtl::OUString::createFromAscii(";");
886 				}
887 			}
888 		}
889 		anyAtrribute <<= sValue;
890 	}
891 	return anyAtrribute;
892 }
893 
894 sal_Int32 SAL_CALL SwAccessibleDocument::getBackground()
895 		throw (::com::sun::star::uno::RuntimeException)
896 {
897 	//IAccessibility2 Implementation 2009-----
898 	vos::OGuard aGuard(Application::GetSolarMutex());
899 	return SW_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
900 	//-----IAccessibility2 Implementation 2009
901 }
902 
903 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
904 		SAL_CALL SwAccessibleDocument::get_AccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType)
905 		throw ( ::com::sun::star::uno::RuntimeException )
906 {
907 	const sal_Int32 FORSPELLCHECKFLOWTO = 1;
908 	const sal_Int32 FORFINDREPLACEFLOWTO = 2;
909 	SwAccessibleMap* pAccMap = GetMap();
910 	if ( !pAccMap )
911 	{
912 		goto Rt;
913 	}
914 
915 	if ( nType == FORSPELLCHECKFLOWTO )
916 	{
917 		uno::Reference< ::com::sun::star::drawing::XShape > xShape;
918 		rAny >>= xShape;
919 		if( xShape.is() )
920 		{
921 			SdrObject* pObj = GetSdrObjectFromXShape(xShape);
922 			if( pObj )
923 			{
924 				uno::Reference<XAccessible> xAcc = pAccMap->GetContext(pObj, this, sal_False);
925 				uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY );
926 				if ( xAccSelection.is() )
927 				{
928 					try
929 					{
930 						if ( xAccSelection->getSelectedAccessibleChildCount() )
931 						{
932 							uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 );
933 							if ( xSel.is() )
934 							{
935 								uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
936 								if ( xSelContext.is() )
937 								{
938 									//if in sw we find the selected paragraph here
939 									if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
940 									{
941 										uno::Sequence<uno::Any> aRet( 1 );
942 										aRet[0] = uno::makeAny( xSel );
943 										return aRet;
944 									}
945 								}
946 							}
947 						}
948 					}
949 					catch ( com::sun::star::lang::IndexOutOfBoundsException )
950 					{
951 						//return empty sequence
952 						goto Rt;
953 					}
954 					//end of try...catch
955 				}
956 				/*uno::Sequence< uno::Any > aRet(1);
957 				aRet[0] = uno::makeAny( xAcc );
958 				return aRet;*/
959 			}
960 		}
961 		else
962 		{
963 			uno::Reference< XAccessible > xAcc = pAccMap->GetCursorContext();
964 			SwAccessibleContext *pAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
965 			if ( pAccImpl && pAccImpl->getAccessibleRole() == AccessibleRole::PARAGRAPH )
966 			{
967 				uno::Sequence< uno::Any > aRet(1);
968 				aRet[0] = uno::makeAny( xAcc );
969 				return aRet;
970 			}
971 		}
972 	}
973 	else if ( nType == FORFINDREPLACEFLOWTO )
974 	{
975 		SwCrsrShell* pCrsrShell = GetCrsrShell();
976 		if ( pCrsrShell )
977 		{
978 			SwPaM *_pStartCrsr = pCrsrShell->GetCrsr(), *__pStartCrsr = _pStartCrsr;
979 			SwCntntNode* pPrevNode = NULL;
980 			std::vector<SwFrm*> vFrmList;
981 			do
982 			{
983 				if ( _pStartCrsr && _pStartCrsr->HasMark() )
984 				{
985 					SwCntntNode* pCntntNode = _pStartCrsr->GetCntntNode();
986 					if ( pCntntNode == pPrevNode )
987 					{
988 						continue;
989 					}
990 					SwFrm* pFrm = pCntntNode ? pCntntNode->getLayoutFrm( pCrsrShell->GetLayout() ) : NULL;
991 					if ( pFrm )
992 					{
993 						vFrmList.push_back( pFrm );
994 					}
995 
996 					pPrevNode = pCntntNode;
997 				}
998 			}
999 
1000 			while( _pStartCrsr && ( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr) );
1001 
1002 			if ( vFrmList.size() )
1003 			{
1004 				uno::Sequence< uno::Any > aRet(vFrmList.size());
1005 				std::vector<SwFrm*>::iterator aIter = vFrmList.begin();
1006 				for ( sal_Int32 nIndex = 0; aIter != vFrmList.end(); aIter++, nIndex++ )
1007 				{
1008 					uno::Reference< XAccessible > xAcc = pAccMap->GetContext(*aIter, sal_False);
1009 					if ( xAcc.is() )
1010 					{
1011 						SwAccessibleContext *pAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
1012 						if ( pAccImpl && pAccImpl->getAccessibleRole() == AccessibleRole::PARAGRAPH )
1013 						{
1014 							aRet[nIndex] = uno::makeAny( xAcc );
1015 						}
1016 					}
1017 				}
1018 
1019 				return aRet;
1020 			}
1021 		}
1022 	}
1023 
1024 Rt:
1025 	uno::Sequence< uno::Any > aEmpty;
1026 	return aEmpty;
1027 }
1028 //-----IAccessibility2 Implementation 2009
1029