xref: /trunk/main/sw/source/core/access/accdoc.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
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     // Sym2_3241----, added by Steve Yin
898     vos::OGuard aGuard(Application::GetSolarMutex());
899     return SW_MOD()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
900     // ----Sym2_3241
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