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
SwAccessibleDocumentBase(SwAccessibleMap * _pMap)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
~SwAccessibleDocumentBase()96 SwAccessibleDocumentBase::~SwAccessibleDocumentBase()
97 {
98 }
99
SetVisArea()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
AddChild(Window * pWin,sal_Bool bFireEvent)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
RemoveChild(Window * pWin)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
getAccessibleChildCount(void)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
getAccessibleChild(sal_Int32 nIndex)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
getAccessibleParent(void)184 uno::Reference< XAccessible> SAL_CALL SwAccessibleDocumentBase::getAccessibleParent (void)
185 {
186 return mxParent;
187 }
188
getAccessibleIndexInParent(void)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
getAccessibleDescription(void)212 OUString SAL_CALL SwAccessibleDocumentBase::getAccessibleDescription (void)
213 {
214 return GetResource( STR_ACCESS_DOC_DESC );
215 }
216
getAccessibleName(void)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
getBounds()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
getLocation()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
getLocationOnScreen()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
getSize()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
containsPoint(const awt::Point & aPoint)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
getAccessibleAtPoint(const awt::Point & aPoint)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
GetStates(::utl::AccessibleStateSetHelper & rStateSet)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
SwAccessibleDocument(SwAccessibleMap * pInitMap)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
~SwAccessibleDocument()385 SwAccessibleDocument::~SwAccessibleDocument()
386 {
387 Window *pWin = GetMap() ? GetMap()->GetShell()->GetWin() : 0;
388 if( pWin )
389 pWin->RemoveChildEventListener( LINK( this, SwAccessibleDocument, WindowChildEventListener ));
390 }
391
Dispose(sal_Bool bRecursive)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
IMPL_LINK(SwAccessibleDocument,WindowChildEventListener,VclSimpleEvent *,pEvent)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
getImplementationName()444 OUString SAL_CALL SwAccessibleDocument::getImplementationName()
445 {
446 return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationName));
447 }
448
supportsService(const::rtl::OUString & sTestServiceName)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
getSupportedServiceNames()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
queryInterface(const uno::Type & rType)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 ====================================================
getTypes()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
getImplementationId()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
selectAccessibleChild(sal_Int32 nChildIndex)531 void SwAccessibleDocument::selectAccessibleChild(
532 sal_Int32 nChildIndex )
533 {
534 maSelectionHelper.selectAccessibleChild(nChildIndex);
535 }
536
isAccessibleChildSelected(sal_Int32 nChildIndex)537 sal_Bool SwAccessibleDocument::isAccessibleChildSelected(
538 sal_Int32 nChildIndex )
539 {
540 return maSelectionHelper.isAccessibleChildSelected(nChildIndex);
541 }
542
clearAccessibleSelection()543 void SwAccessibleDocument::clearAccessibleSelection( )
544 {
545 maSelectionHelper.clearAccessibleSelection();
546 }
547
selectAllAccessibleChildren()548 void SwAccessibleDocument::selectAllAccessibleChildren( )
549 {
550 maSelectionHelper.selectAllAccessibleChildren();
551 }
552
getSelectedAccessibleChildCount()553 sal_Int32 SwAccessibleDocument::getSelectedAccessibleChildCount( )
554 {
555 return maSelectionHelper.getSelectedAccessibleChildCount();
556 }
557
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)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.
deselectAccessibleChild(sal_Int32 nChildIndex)565 void SwAccessibleDocument::deselectAccessibleChild(
566 sal_Int32 nChildIndex )
567 {
568 maSelectionHelper.deselectAccessibleChild( nChildIndex );
569 }
570 //Solution:Implement XEventListener interfaces
notifyEvent(const::com::sun::star::document::EventObject & Event)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
disposing(const::com::sun::star::lang::EventObject &)596 void SAL_CALL SwAccessibleDocument::disposing( const ::com::sun::star::lang::EventObject& )
597 {
598 }
599
getExtendedAttributes()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
getBackground()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 >
get_AccFlowTo(const::com::sun::star::uno::Any & rAny,sal_Int32 nType)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