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