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