Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <rtl/ref.hxx>
30 : : #include <rtl/strbuf.hxx>
31 : : #include <cppuhelper/weakref.hxx>
32 : : #include <vcl/window.hxx>
33 : : #include <svx/svdmodel.hxx>
34 : : #include <svx/unomod.hxx>
35 : : #include <map>
36 : : #include <list>
37 : : #include <accmap.hxx>
38 : : #include <acccontext.hxx>
39 : : #include <accdoc.hxx>
40 : : #include <accpreview.hxx>
41 : : #include <accpage.hxx>
42 : : #include <accpara.hxx>
43 : : #include <accheaderfooter.hxx>
44 : : #include <accfootnote.hxx>
45 : : #include <acctextframe.hxx>
46 : : #include <accgraphic.hxx>
47 : : #include <accembedded.hxx>
48 : : #include <acccell.hxx>
49 : : #include <acctable.hxx>
50 : : #include <fesh.hxx>
51 : : #include <rootfrm.hxx>
52 : : #include <txtfrm.hxx>
53 : : #include <hffrm.hxx>
54 : : #include <ftnfrm.hxx>
55 : : #include <cellfrm.hxx>
56 : : #include <tabfrm.hxx>
57 : : #include <pagefrm.hxx>
58 : : #include <flyfrm.hxx>
59 : : #include <ndtyp.hxx>
60 : : #include <IDocumentDrawModelAccess.hxx>
61 : : #include <svx/ShapeTypeHandler.hxx>
62 : : #include <vcl/svapp.hxx>
63 : : #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
64 : : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
65 : : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
66 : : #include <cppuhelper/implbase1.hxx>
67 : : #include <pagepreviewlayout.hxx>
68 : : #include <pam.hxx>
69 : : #include <ndtxt.hxx>
70 : : #include <dflyobj.hxx>
71 : : #include <prevwpage.hxx>
72 : : #include <switerator.hxx>
73 : :
74 : : using namespace ::com::sun::star;
75 : : using namespace ::com::sun::star::accessibility;
76 : : using ::rtl::OUString;
77 : : using namespace ::sw::access;
78 : :
79 : : struct SwFrmFunc
80 : : {
81 : 3198 : sal_Bool operator()( const SwFrm * p1,
82 : : const SwFrm * p2) const
83 : : {
84 : 3198 : return p1 < p2;
85 : : }
86 : : };
87 : :
88 : : typedef ::std::map < const SwFrm *, uno::WeakReference < XAccessible >, SwFrmFunc > _SwAccessibleContextMap_Impl;
89 : :
90 : 24 : class SwAccessibleContextMap_Impl: public _SwAccessibleContextMap_Impl
91 : : {
92 : : public:
93 : :
94 : : #if OSL_DEBUG_LEVEL > 0
95 : : sal_Bool mbLocked;
96 : : #endif
97 : :
98 : 24 : SwAccessibleContextMap_Impl()
99 : : #if OSL_DEBUG_LEVEL > 0
100 : : : mbLocked( sal_False )
101 : : #endif
102 : 24 : {}
103 : :
104 : : };
105 : :
106 : : //------------------------------------------------------------------------------
107 : : class SwDrawModellListener_Impl : public SfxListener,
108 : : public ::cppu::WeakImplHelper1< document::XEventBroadcaster >
109 : : {
110 : : mutable ::osl::Mutex maListenerMutex;
111 : : ::cppu::OInterfaceContainerHelper maEventListeners;
112 : : SdrModel *mpDrawModel;
113 : : protected:
114 : : virtual ~SwDrawModellListener_Impl();
115 : : public:
116 : :
117 : : SwDrawModellListener_Impl( SdrModel *pDrawModel );
118 : :
119 : :
120 : : virtual void SAL_CALL addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException);
121 : : virtual void SAL_CALL removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException);
122 : :
123 : : virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
124 : : void Dispose();
125 : : };
126 : :
127 : 0 : SwDrawModellListener_Impl::SwDrawModellListener_Impl( SdrModel *pDrawModel ) :
128 : : maEventListeners( maListenerMutex ),
129 [ # # ][ # # ]: 0 : mpDrawModel( pDrawModel )
[ # # ]
130 : : {
131 [ # # ]: 0 : StartListening( *mpDrawModel );
132 : 0 : }
133 : :
134 [ # # ][ # # ]: 0 : SwDrawModellListener_Impl::~SwDrawModellListener_Impl()
[ # # ]
135 : : {
136 [ # # ]: 0 : EndListening( *mpDrawModel );
137 [ # # ]: 0 : }
138 : :
139 : 0 : void SAL_CALL SwDrawModellListener_Impl::addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException)
140 : : {
141 : 0 : maEventListeners.addInterface( xListener );
142 : 0 : }
143 : :
144 : 0 : void SAL_CALL SwDrawModellListener_Impl::removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException)
145 : : {
146 : 0 : maEventListeners.removeInterface( xListener );
147 : 0 : }
148 : :
149 : 0 : void SwDrawModellListener_Impl::Notify( SfxBroadcaster& /*rBC*/,
150 : : const SfxHint& rHint )
151 : : {
152 : : // do not broadcast notifications for writer fly frames, because there
153 : : // are no shapes that need to know about them.
154 [ # # ][ # # ]: 0 : const SdrHint *pSdrHint = PTR_CAST( SdrHint, &rHint );
[ # # ][ # # ]
155 [ # # ][ # # ]: 0 : if ( !pSdrHint ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
156 [ # # ]: 0 : ( pSdrHint->GetObject() &&
157 [ # # ][ # # ]: 0 : ( pSdrHint->GetObject()->ISA(SwFlyDrawObj) ||
[ # # ]
158 [ # # ][ # # ]: 0 : pSdrHint->GetObject()->ISA(SwVirtFlyDrawObj) ||
[ # # ]
159 [ # # ][ # # ]: 0 : IS_TYPE(SdrObject,pSdrHint->GetObject()) ) ) )
[ # # ][ # # ]
160 : : {
161 : : return;
162 : : }
163 : :
164 : : OSL_ENSURE( mpDrawModel, "draw model listener is disposed" );
165 [ # # ]: 0 : if( !mpDrawModel )
166 : : return;
167 : :
168 [ # # ]: 0 : document::EventObject aEvent;
169 [ # # ][ # # ]: 0 : if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) )
170 : : return;
171 : :
172 [ # # ]: 0 : ::cppu::OInterfaceIteratorHelper aIter( maEventListeners );
173 [ # # ]: 0 : while( aIter.hasMoreElements() )
174 : : {
175 : : uno::Reference < document::XEventListener > xListener( aIter.next(),
176 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
177 : : try
178 : : {
179 [ # # ][ # # ]: 0 : xListener->notifyEvent( aEvent );
180 : : }
181 [ # # ]: 0 : catch( uno::RuntimeException const & r )
182 : : {
183 : : (void)r;
184 : : #if OSL_DEBUG_LEVEL > 0
185 : : rtl::OStringBuffer aError(RTL_CONSTASCII_STRINGPARAM("Runtime exception caught while notifying shape.:\n"));
186 : : aError.append(rtl::OUStringToOString(r.Message, RTL_TEXTENCODING_ASCII_US));
187 : : OSL_FAIL( aError.getStr() );
188 : : #endif
189 : : }
190 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
191 : : }
192 : :
193 : 0 : void SwDrawModellListener_Impl::Dispose()
194 : : {
195 : 0 : mpDrawModel = 0;
196 : 0 : }
197 : :
198 : : //------------------------------------------------------------------------------
199 : : struct SwShapeFunc
200 : : {
201 : 0 : sal_Bool operator()( const SdrObject * p1,
202 : : const SdrObject * p2) const
203 : : {
204 : 0 : return p1 < p2;
205 : : }
206 : : };
207 : : typedef ::std::map < const SdrObject *, uno::WeakReference < XAccessible >, SwShapeFunc > _SwAccessibleShapeMap_Impl;
208 : : typedef ::std::pair < const SdrObject *, ::rtl::Reference < ::accessibility::AccessibleShape > > SwAccessibleObjShape_Impl;
209 : :
210 : : class SwAccessibleShapeMap_Impl: public _SwAccessibleShapeMap_Impl
211 : :
212 : : {
213 : : ::accessibility::AccessibleShapeTreeInfo maInfo;
214 : :
215 : : public:
216 : :
217 : : #if OSL_DEBUG_LEVEL > 0
218 : : sal_Bool mbLocked;
219 : : #endif
220 : 0 : SwAccessibleShapeMap_Impl( SwAccessibleMap *pMap )
221 : : #if OSL_DEBUG_LEVEL > 0
222 : : : mbLocked( sal_False )
223 : : #endif
224 [ # # ]: 0 : {
225 [ # # ][ # # ]: 0 : maInfo.SetSdrView( pMap->GetShell()->GetDrawView() );
226 [ # # ]: 0 : maInfo.SetWindow( pMap->GetShell()->GetWin() );
227 [ # # ]: 0 : maInfo.SetViewForwarder( pMap );
228 : : uno::Reference < document::XEventBroadcaster > xModelBroadcaster =
229 : : new SwDrawModellListener_Impl(
230 [ # # ][ # # ]: 0 : pMap->GetShell()->getIDocumentDrawModelAccess()->GetOrCreateDrawModel() );
[ # # ][ # # ]
[ # # ]
231 [ # # ]: 0 : maInfo.SetControllerBroadcaster( xModelBroadcaster );
232 : 0 : }
233 : :
234 : : ~SwAccessibleShapeMap_Impl();
235 : :
236 : 0 : const ::accessibility::AccessibleShapeTreeInfo& GetInfo() const { return maInfo; }
237 : :
238 : : SwAccessibleObjShape_Impl *Copy( size_t& rSize,
239 : : const SwFEShell *pFESh = 0,
240 : : SwAccessibleObjShape_Impl **pSelShape = 0 ) const;
241 : : };
242 : :
243 [ # # ]: 0 : SwAccessibleShapeMap_Impl::~SwAccessibleShapeMap_Impl()
244 : : {
245 [ # # ]: 0 : uno::Reference < document::XEventBroadcaster > xBrd( maInfo.GetControllerBroadcaster() );
246 [ # # ]: 0 : if( xBrd.is() )
247 [ # # ][ # # ]: 0 : static_cast < SwDrawModellListener_Impl * >( xBrd.get() )->Dispose();
248 : 0 : }
249 : :
250 : : SwAccessibleObjShape_Impl
251 : 0 : *SwAccessibleShapeMap_Impl::Copy(
252 : : size_t& rSize, const SwFEShell *pFESh,
253 : : SwAccessibleObjShape_Impl **pSelStart ) const
254 : : {
255 : 0 : SwAccessibleObjShape_Impl *pShapes = 0;
256 : 0 : SwAccessibleObjShape_Impl *pSelShape = 0;
257 : :
258 [ # # ]: 0 : sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
259 : 0 : rSize = size();
260 : :
261 [ # # ]: 0 : if( rSize > 0 )
262 : : {
263 : : pShapes =
264 [ # # ][ # # ]: 0 : new SwAccessibleObjShape_Impl[rSize];
[ # # # #
# # ]
265 : :
266 : 0 : const_iterator aIter = begin();
267 : 0 : const_iterator aEndIter = end();
268 : :
269 : 0 : SwAccessibleObjShape_Impl *pShape = pShapes;
270 : 0 : pSelShape = &(pShapes[rSize]);
271 [ # # ]: 0 : while( aIter != aEndIter )
272 : : {
273 : 0 : const SdrObject *pObj = (*aIter).first;
274 [ # # ]: 0 : uno::Reference < XAccessible > xAcc( (*aIter).second );
275 [ # # ][ # # ]: 0 : if( nSelShapes && pFESh->IsObjSelected( *pObj ) )
[ # # ][ # # ]
276 : : {
277 : : // selected objects are inserted from the back
278 : 0 : --pSelShape;
279 : 0 : pSelShape->first = pObj;
280 : : pSelShape->second =
281 : : static_cast < ::accessibility::AccessibleShape* >(
282 [ # # ][ # # ]: 0 : xAcc.get() );
[ # # ]
283 : 0 : --nSelShapes;
284 : : }
285 : : else
286 : : {
287 : 0 : pShape->first = pObj;
288 : : pShape->second =
289 : : static_cast < ::accessibility::AccessibleShape* >(
290 [ # # ][ # # ]: 0 : xAcc.get() );
[ # # ]
291 : 0 : ++pShape;
292 : : }
293 : 0 : ++aIter;
294 : 0 : }
295 : : OSL_ENSURE( pSelShape == pShape, "copying shapes went wrong!" );
296 : : }
297 : :
298 [ # # ]: 0 : if( pSelStart )
299 : 0 : *pSelStart = pSelShape;
300 : :
301 : 0 : return pShapes;
302 : : }
303 : :
304 : : //------------------------------------------------------------------------------
305 [ + - ]: 219 : struct SwAccessibleEvent_Impl
306 : : {
307 : : public:
308 : : enum EventType { CARET_OR_STATES,
309 : : INVALID_CONTENT,
310 : : POS_CHANGED,
311 : : CHILD_POS_CHANGED,
312 : : SHAPE_SELECTION,
313 : : DISPOSE,
314 : : INVALID_ATTR };
315 : :
316 : : private:
317 : : SwRect maOldBox; // the old bounds for CHILD_POS_CHANGED
318 : : // and POS_CHANGED
319 : : uno::WeakReference < XAccessible > mxAcc; // The object that fires the event
320 : : SwAccessibleChild maFrmOrObj; // the child for CHILD_POS_CHANGED and
321 : : // the same as xAcc for any other
322 : : // event type
323 : : EventType meType; // The event type
324 : : tAccessibleStates mnStates; // check states or update caret pos
325 : :
326 : : SwAccessibleEvent_Impl& operator==( const SwAccessibleEvent_Impl& );
327 : :
328 : : public:
329 : 0 : SwAccessibleEvent_Impl( EventType eT,
330 : : SwAccessibleContext *pA,
331 : : const SwAccessibleChild& rFrmOrObj )
332 : : : mxAcc( pA ),
333 : : maFrmOrObj( rFrmOrObj ),
334 : : meType( eT ),
335 [ # # ][ # # ]: 0 : mnStates( 0 )
[ # # ]
336 : 0 : {}
337 : :
338 : 0 : SwAccessibleEvent_Impl( EventType eT,
339 : : const SwAccessibleChild& rFrmOrObj )
340 : : : maFrmOrObj( rFrmOrObj ),
341 : : meType( eT ),
342 [ # # ]: 0 : mnStates( 0 )
343 : : {
344 : : OSL_ENSURE( SwAccessibleEvent_Impl::DISPOSE == meType,
345 : : "wrong event constructor, DISPOSE only" );
346 : 0 : }
347 : :
348 : 0 : SwAccessibleEvent_Impl( EventType eT )
349 : : : meType( eT ),
350 [ # # ]: 0 : mnStates( 0 )
351 : : {
352 : : OSL_ENSURE( SwAccessibleEvent_Impl::SHAPE_SELECTION == meType,
353 : : "wrong event constructor, SHAPE_SELECTION only" );
354 : 0 : }
355 : :
356 : 73 : SwAccessibleEvent_Impl( EventType eT,
357 : : SwAccessibleContext *pA,
358 : : const SwAccessibleChild& rFrmOrObj,
359 : : const SwRect& rR )
360 : : : maOldBox( rR ),
361 : : mxAcc( pA ),
362 : : maFrmOrObj( rFrmOrObj ),
363 : : meType( eT ),
364 [ + - ][ + - ]: 73 : mnStates( 0 )
[ + - ]
365 : : {
366 : : OSL_ENSURE( SwAccessibleEvent_Impl::CHILD_POS_CHANGED == meType ||
367 : : SwAccessibleEvent_Impl::POS_CHANGED == meType,
368 : : "wrong event constructor, (CHILD_)POS_CHANGED only" );
369 : 73 : }
370 : :
371 : 0 : SwAccessibleEvent_Impl( EventType eT,
372 : : SwAccessibleContext *pA,
373 : : const SwAccessibleChild& rFrmOrObj,
374 : : const tAccessibleStates _nStates )
375 : : : mxAcc( pA ),
376 : : maFrmOrObj( rFrmOrObj ),
377 : : meType( eT ),
378 [ # # ][ # # ]: 0 : mnStates( _nStates )
[ # # ]
379 : : {
380 : : OSL_ENSURE( SwAccessibleEvent_Impl::CARET_OR_STATES == meType,
381 : : "wrong event constructor, CARET_OR_STATES only" );
382 : 0 : }
383 : :
384 : : // <SetType(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
385 : 0 : inline void SetType( EventType eT )
386 : : {
387 : 0 : meType = eT;
388 : 0 : }
389 : 365 : inline EventType GetType() const
390 : : {
391 : 365 : return meType;
392 : : }
393 : :
394 : 73 : inline ::rtl::Reference < SwAccessibleContext > GetContext() const
395 : : {
396 [ + - ]: 73 : uno::Reference < XAccessible > xTmp( mxAcc );
397 : : ::rtl::Reference < SwAccessibleContext > xAccImpl(
398 [ + - ][ + - ]: 73 : static_cast<SwAccessibleContext*>( xTmp.get() ) );
399 : :
400 : 73 : return xAccImpl;
401 : : }
402 : :
403 : 73 : inline const SwRect& GetOldBox() const
404 : : {
405 : 73 : return maOldBox;
406 : : }
407 : : // <SetOldBox(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
408 : 0 : inline void SetOldBox( const SwRect& rOldBox )
409 : : {
410 : 0 : maOldBox = rOldBox;
411 : 0 : }
412 : :
413 : 163 : inline const SwAccessibleChild& GetFrmOrObj() const
414 : : {
415 : 163 : return maFrmOrObj;
416 : : }
417 : :
418 : : // <SetStates(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
419 : 0 : inline void SetStates( tAccessibleStates _nStates )
420 : : {
421 : 0 : mnStates |= _nStates;
422 : 0 : }
423 : :
424 : 73 : inline sal_Bool IsUpdateCursorPos() const
425 : : {
426 : 73 : return (mnStates & ACC_STATE_CARET) != 0;
427 : : }
428 : 73 : inline sal_Bool IsInvalidateStates() const
429 : : {
430 : 73 : return (mnStates & ACC_STATE_MASK) != 0;
431 : : }
432 : 73 : inline sal_Bool IsInvalidateRelation() const
433 : : {
434 : 73 : return (mnStates & ACC_STATE_RELATION_MASK) != 0;
435 : : }
436 : 73 : inline sal_Bool IsInvalidateTextSelection() const
437 : : {
438 : 73 : return ( mnStates & ACC_STATE_TEXT_SELECTION_CHANGED ) != 0;
439 : : }
440 : :
441 : 73 : inline sal_Bool IsInvalidateTextAttrs() const
442 : : {
443 : 73 : return ( mnStates & ACC_STATE_TEXT_ATTRIBUTE_CHANGED ) != 0;
444 : : }
445 : :
446 : 0 : inline tAccessibleStates GetStates() const
447 : : {
448 : 0 : return mnStates & ACC_STATE_MASK;
449 : : }
450 : :
451 : 0 : inline tAccessibleStates GetAllStates() const
452 : : {
453 : 0 : return mnStates;
454 : : }
455 : :
456 : : };
457 : :
458 : : //------------------------------------------------------------------------------
459 : : typedef ::std::list < SwAccessibleEvent_Impl > _SwAccessibleEventList_Impl;
460 : :
461 : 29 : class SwAccessibleEventList_Impl: public _SwAccessibleEventList_Impl
462 : : {
463 : : sal_Bool mbFiring;
464 : :
465 : : public:
466 : :
467 : 29 : SwAccessibleEventList_Impl()
468 : 29 : : mbFiring( sal_False )
469 : 29 : {}
470 : :
471 : 29 : inline void SetFiring()
472 : : {
473 : 29 : mbFiring = sal_True;
474 : 29 : }
475 : 73 : inline sal_Bool IsFiring() const
476 : : {
477 : 73 : return mbFiring;
478 : : }
479 : : };
480 : :
481 : : //------------------------------------------------------------------------------
482 : : // The shape list is filled if an accessible shape is destroyed. It
483 : : // simply keeps a reference to the accessible shape's XShape. These
484 : : // references are destroyed within the EndAction when firing events,
485 : : // There are twp reason for this. First of all, a new accessible shape
486 : : // for the XShape might be created soon. It's then cheaper if the XShape
487 : : // still exists. The other reason are situations where an accessible shape
488 : : // is destroyed within an SwFrmFmt::Modify. In this case, destryoing
489 : : // the XShape at the same time (indirectly by destroying the accessible
490 : : // shape) leads to an assert, because a client of the Modify is destroyed
491 : : // within a Modify call.
492 : :
493 : : typedef ::std::list < uno::Reference < drawing::XShape > > _SwShapeList_Impl;
494 : :
495 : 0 : class SwShapeList_Impl: public _SwShapeList_Impl
496 : : {
497 : : public:
498 : :
499 : 0 : SwShapeList_Impl() {}
500 : : };
501 : :
502 : :
503 : : //------------------------------------------------------------------------------
504 : : struct SwAccessibleChildFunc
505 : : {
506 : 216 : sal_Bool operator()( const SwAccessibleChild& r1,
507 : : const SwAccessibleChild& r2 ) const
508 : : {
509 : 216 : const void *p1 = r1.GetSwFrm()
510 : : ? static_cast < const void * >( r1.GetSwFrm())
511 : 0 : : ( r1.GetDrawObject()
512 : : ? static_cast < const void * >( r1.GetDrawObject() )
513 [ # # ][ + - ]: 216 : : static_cast < const void * >( r1.GetWindow() ) );
514 : 216 : const void *p2 = r2.GetSwFrm()
515 : : ? static_cast < const void * >( r2.GetSwFrm())
516 : 0 : : ( r2.GetDrawObject()
517 : : ? static_cast < const void * >( r2.GetDrawObject() )
518 [ # # ][ + - ]: 216 : : static_cast < const void * >( r2.GetWindow() ) );
519 : 216 : return p1 < p2;
520 : : }
521 : : };
522 : : typedef ::std::map < SwAccessibleChild, SwAccessibleEventList_Impl::iterator,
523 : : SwAccessibleChildFunc > _SwAccessibleEventMap_Impl;
524 : :
525 : 58 : class SwAccessibleEventMap_Impl: public _SwAccessibleEventMap_Impl
526 : : {
527 : : };
528 : :
529 : : //------------------------------------------------------------------------------
530 : :
531 : : struct SwAccessibleParaSelection
532 : : {
533 : : xub_StrLen nStartOfSelection;
534 : : xub_StrLen nEndOfSelection;
535 : :
536 : 0 : SwAccessibleParaSelection( const xub_StrLen _nStartOfSelection,
537 : : const xub_StrLen _nEndOfSelection )
538 : : : nStartOfSelection( _nStartOfSelection ),
539 : 0 : nEndOfSelection( _nEndOfSelection )
540 : 0 : {}
541 : : };
542 : :
543 : : struct SwXAccWeakRefComp
544 : : {
545 : 0 : sal_Bool operator()( const uno::WeakReference<XAccessible>& _rXAccWeakRef1,
546 : : const uno::WeakReference<XAccessible>& _rXAccWeakRef2 ) const
547 : : {
548 [ # # ][ # # ]: 0 : return _rXAccWeakRef1.get() < _rXAccWeakRef2.get();
549 : : }
550 : : };
551 : :
552 : : typedef ::std::map< uno::WeakReference < XAccessible >,
553 : : SwAccessibleParaSelection,
554 : : SwXAccWeakRefComp > _SwAccessibleSelectedParas_Impl;
555 : :
556 : 0 : class SwAccessibleSelectedParas_Impl: public _SwAccessibleSelectedParas_Impl
557 : : {};
558 : :
559 : : // helper class that stores preview data
560 : : class SwAccPreviewData
561 : : {
562 : : typedef std::vector<Rectangle> Rectangles;
563 : : Rectangles maPreviewRects;
564 : : Rectangles maLogicRects;
565 : :
566 : : SwRect maVisArea;
567 : : Fraction maScale;
568 : :
569 : : const SwPageFrm *mpSelPage;
570 : :
571 : : /** adjust logic page retangle to its visible part
572 : :
573 : : @param _iorLogicPgSwRect
574 : : input/output parameter - reference to the logic page rectangle, which
575 : : has to be adjusted.
576 : :
577 : : @param _rPrevwPgSwRect
578 : : input parameter - constant reference to the corresponding preview page
579 : : rectangle; needed to determine the visible part of the logic page rectangle.
580 : :
581 : : @param _rPrevwWinSize
582 : : input paramter - constant reference to the preview window size in TWIP;
583 : : needed to determine the visible part of the logic page rectangle
584 : : */
585 : : void AdjustLogicPgRectToVisibleArea( SwRect& _iorLogicPgSwRect,
586 : : const SwRect& _rPrevwPgSwRect,
587 : : const Size& _rPrevwWinSize );
588 : :
589 : : public:
590 : : SwAccPreviewData();
591 : : ~SwAccPreviewData();
592 : :
593 : : void Update( const SwAccessibleMap& rAccMap,
594 : : const std::vector<PrevwPage*>& _rPrevwPages,
595 : : const Fraction& _rScale,
596 : : const SwPageFrm* _pSelectedPageFrm,
597 : : const Size& _rPrevwWinSize );
598 : :
599 : : void InvalidateSelection( const SwPageFrm* _pSelectedPageFrm );
600 : :
601 : : const SwRect& GetVisArea() const;
602 : :
603 : : MapMode GetMapModeForPreview( ) const;
604 : :
605 : : /** Adjust the MapMode so that the preview page appears at the
606 : : * proper position. rPoint identifies the page for which the
607 : : * MapMode should be adjusted. If bFromPreview is true, rPoint is
608 : : * a preview coordinate; else it's a document coordinate. */
609 : : void AdjustMapMode( MapMode& rMapMode,
610 : : const Point& rPoint ) const;
611 : :
612 : 0 : inline const SwPageFrm *GetSelPage() const { return mpSelPage; }
613 : :
614 : : void DisposePage(const SwPageFrm *pPageFrm );
615 : : };
616 : :
617 : 0 : SwAccPreviewData::SwAccPreviewData() :
618 [ # # ]: 0 : mpSelPage( 0 )
619 : : {
620 : 0 : }
621 : :
622 : 0 : SwAccPreviewData::~SwAccPreviewData()
623 : : {
624 : 0 : }
625 : :
626 : 0 : void SwAccPreviewData::Update( const SwAccessibleMap& rAccMap,
627 : : const std::vector<PrevwPage*>& _rPrevwPages,
628 : : const Fraction& _rScale,
629 : : const SwPageFrm* _pSelectedPageFrm,
630 : : const Size& _rPrevwWinSize )
631 : : {
632 : : // store preview scaling, maximal preview page size and selected page
633 [ # # ]: 0 : maScale = _rScale;
634 : 0 : mpSelPage = _pSelectedPageFrm;
635 : :
636 : : // prepare loop on preview pages
637 : 0 : maPreviewRects.clear();
638 : 0 : maLogicRects.clear();
639 [ # # ]: 0 : SwAccessibleChild aPage;
640 : 0 : maVisArea.Clear();
641 : :
642 : : // loop on preview pages to calculate <maPreviewRects>, <maLogicRects> and
643 : : // <maVisArea>
644 [ # # ][ # # ]: 0 : for ( std::vector<PrevwPage*>::const_iterator aPageIter = _rPrevwPages.begin();
645 : 0 : aPageIter != _rPrevwPages.end();
646 : : ++aPageIter )
647 : : {
648 [ # # ]: 0 : aPage = (*aPageIter)->pPage;
649 : :
650 : : // add preview page rectangle to <maPreviewRects>
651 [ # # ]: 0 : Rectangle aPrevwPgRect( (*aPageIter)->aPrevwWinPos, (*aPageIter)->aPageSize );
652 [ # # ]: 0 : maPreviewRects.push_back( aPrevwPgRect );
653 : :
654 : : // add logic page rectangle to <maLogicRects>
655 [ # # ]: 0 : SwRect aLogicPgSwRect( aPage.GetBox( rAccMap ) );
656 [ # # ]: 0 : Rectangle aLogicPgRect( aLogicPgSwRect.SVRect() );
657 [ # # ]: 0 : maLogicRects.push_back( aLogicPgRect );
658 : : // union visible area with visible part of logic page rectangle
659 [ # # ]: 0 : if ( (*aPageIter)->bVisible )
660 : : {
661 [ # # ]: 0 : if ( !(*aPageIter)->pPage->IsEmptyPage() )
662 : : {
663 : : AdjustLogicPgRectToVisibleArea( aLogicPgSwRect,
664 : : SwRect( aPrevwPgRect ),
665 [ # # ][ # # ]: 0 : _rPrevwWinSize );
666 : : }
667 [ # # ]: 0 : if ( maVisArea.IsEmpty() )
668 : 0 : maVisArea = aLogicPgSwRect;
669 : : else
670 [ # # ]: 0 : maVisArea.Union( aLogicPgSwRect );
671 : : }
672 : : }
673 : 0 : }
674 : :
675 : 0 : void SwAccPreviewData::InvalidateSelection( const SwPageFrm* _pSelectedPageFrm )
676 : : {
677 : 0 : mpSelPage = _pSelectedPageFrm;
678 : : OSL_ENSURE( mpSelPage, "selected page not found" );
679 : 0 : }
680 : :
681 : : struct ContainsPredicate
682 : : {
683 : : const Point& mrPoint;
684 : 0 : ContainsPredicate( const Point& rPoint ) : mrPoint(rPoint) {}
685 : 0 : bool operator() ( const Rectangle& rRect ) const
686 : : {
687 : 0 : return rRect.IsInside( mrPoint ) ? true : false;
688 : : }
689 : : };
690 : :
691 : 0 : const SwRect& SwAccPreviewData::GetVisArea() const
692 : : {
693 : 0 : return maVisArea;
694 : : }
695 : :
696 : 0 : void SwAccPreviewData::AdjustMapMode( MapMode& rMapMode,
697 : : const Point& rPoint ) const
698 : : {
699 : : // adjust scale
700 [ # # ]: 0 : rMapMode.SetScaleX( maScale );
701 [ # # ]: 0 : rMapMode.SetScaleY( maScale );
702 : :
703 : : // find proper rectangle
704 : 0 : Rectangles::const_iterator aBegin = maLogicRects.begin();
705 : 0 : Rectangles::const_iterator aEnd = maLogicRects.end();
706 : : Rectangles::const_iterator aFound = ::std::find_if( aBegin, aEnd,
707 [ # # ]: 0 : ContainsPredicate( rPoint ) );
708 : :
709 [ # # ][ # # ]: 0 : if( aFound != aEnd )
710 : : {
711 : : // found! set new origin
712 [ # # ][ # # ]: 0 : Point aPoint = (maPreviewRects.begin() + (aFound - aBegin))->TopLeft();
[ # # ]
713 [ # # ][ # # ]: 0 : aPoint -= (maLogicRects.begin() + (aFound-aBegin))->TopLeft();
[ # # ]
714 [ # # ]: 0 : rMapMode.SetOrigin( aPoint );
715 : : }
716 : : // else: don't adjust MapMode
717 : 0 : }
718 : :
719 : 0 : void SwAccPreviewData::DisposePage(const SwPageFrm *pPageFrm )
720 : : {
721 [ # # ]: 0 : if( mpSelPage == pPageFrm )
722 : 0 : mpSelPage = 0;
723 : 0 : }
724 : :
725 : : // adjust logic page retangle to its visible part
726 : 0 : void SwAccPreviewData::AdjustLogicPgRectToVisibleArea(
727 : : SwRect& _iorLogicPgSwRect,
728 : : const SwRect& _rPrevwPgSwRect,
729 : : const Size& _rPrevwWinSize )
730 : : {
731 : : // determine preview window rectangle
732 : 0 : const SwRect aPrevwWinSwRect( Point( 0, 0 ), _rPrevwWinSize );
733 : : // calculate visible preview page rectangle
734 : 0 : SwRect aVisPrevwPgSwRect( _rPrevwPgSwRect );
735 [ # # ]: 0 : aVisPrevwPgSwRect.Intersection( aPrevwWinSwRect );
736 : : // adjust logic page rectangle
737 : : SwTwips nTmpDiff;
738 : : // left
739 : 0 : nTmpDiff = aVisPrevwPgSwRect.Left() - _rPrevwPgSwRect.Left();
740 [ # # ]: 0 : if ( nTmpDiff > 0 )
741 : 0 : _iorLogicPgSwRect.Left( _iorLogicPgSwRect.Left() + nTmpDiff );
742 : : // top
743 : 0 : nTmpDiff = aVisPrevwPgSwRect.Top() - _rPrevwPgSwRect.Top();
744 [ # # ]: 0 : if ( nTmpDiff > 0 )
745 : 0 : _iorLogicPgSwRect.Top( _iorLogicPgSwRect.Top() + nTmpDiff );
746 : : // right
747 : 0 : nTmpDiff = _rPrevwPgSwRect.Right() - aVisPrevwPgSwRect.Right();
748 [ # # ]: 0 : if ( nTmpDiff > 0 )
749 : 0 : _iorLogicPgSwRect.Right( _iorLogicPgSwRect.Right() - nTmpDiff );
750 : : // bottom
751 : 0 : nTmpDiff = _rPrevwPgSwRect.Bottom() - aVisPrevwPgSwRect.Bottom();
752 [ # # ]: 0 : if ( nTmpDiff > 0 )
753 : 0 : _iorLogicPgSwRect.Bottom( _iorLogicPgSwRect.Bottom() - nTmpDiff );
754 : 0 : }
755 : :
756 : : //------------------------------------------------------------------------------
757 : 29 : static sal_Bool AreInSameTable( const uno::Reference< XAccessible >& rAcc,
758 : : const SwFrm *pFrm )
759 : : {
760 : 29 : sal_Bool bRet = sal_False;
761 : :
762 [ + - ][ + + ]: 29 : if( pFrm && pFrm->IsCellFrm() && rAcc.is() )
[ + + ][ + + ]
763 : : {
764 : : // Is it in the same table? We check that
765 : : // by comparing the last table frame in the
766 : : // follow chain, because that's cheaper than
767 : : // searching the first one.
768 : : SwAccessibleContext *pAccImpl =
769 [ + - ]: 2 : static_cast< SwAccessibleContext *>( rAcc.get() );
770 [ + - ]: 2 : if( pAccImpl->GetFrm()->IsCellFrm() )
771 : : {
772 : 2 : const SwTabFrm *pTabFrm1 = pAccImpl->GetFrm()->FindTabFrm();
773 [ - + ]: 2 : while( pTabFrm1->GetFollow() )
774 : 0 : pTabFrm1 = pTabFrm1->GetFollow();
775 : :
776 : 2 : const SwTabFrm *pTabFrm2 = pFrm->FindTabFrm();
777 [ - + ]: 2 : while( pTabFrm2->GetFollow() )
778 : 0 : pTabFrm2 = pTabFrm2->GetFollow();
779 : :
780 : 2 : bRet = (pTabFrm1 == pTabFrm2);
781 : : }
782 : : }
783 : :
784 : 29 : return bRet;
785 : : }
786 : :
787 : 73 : void SwAccessibleMap::FireEvent( const SwAccessibleEvent_Impl& rEvent )
788 : : {
789 [ + - ]: 73 : ::rtl::Reference < SwAccessibleContext > xAccImpl( rEvent.GetContext() );
790 [ - + ]: 73 : if( SwAccessibleEvent_Impl::SHAPE_SELECTION == rEvent.GetType() )
791 : : {
792 [ # # ]: 0 : DoInvalidateShapeSelection();
793 : : }
794 [ + - ][ + - ]: 73 : else if( xAccImpl.is() && xAccImpl->GetFrm() )
[ + - ]
795 : : {
796 [ + - - + ]: 146 : if ( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE &&
[ - + ]
797 : 73 : rEvent.IsInvalidateTextAttrs() )
798 : : {
799 [ # # ]: 0 : xAccImpl->InvalidateAttr();
800 : : }
801 [ - + + - : 73 : switch( rEvent.GetType() )
- - ]
802 : : {
803 : : case SwAccessibleEvent_Impl::INVALID_CONTENT:
804 [ # # ]: 0 : xAccImpl->InvalidateContent();
805 : 0 : break;
806 : : case SwAccessibleEvent_Impl::POS_CHANGED:
807 [ + - ]: 56 : xAccImpl->InvalidatePosOrSize( rEvent.GetOldBox() );
808 : 56 : break;
809 : : case SwAccessibleEvent_Impl::CHILD_POS_CHANGED:
810 : 34 : xAccImpl->InvalidateChildPosOrSize( rEvent.GetFrmOrObj(),
811 [ + - ]: 34 : rEvent.GetOldBox() );
812 : 17 : break;
813 : : case SwAccessibleEvent_Impl::DISPOSE:
814 : : OSL_ENSURE( xAccImpl.is(),
815 : : "dispose event has been stored" );
816 : 0 : break;
817 : : case SwAccessibleEvent_Impl::INVALID_ATTR:
818 : : // nothing to do here - handled above
819 : 0 : break;
820 : : default:
821 : 0 : break;
822 : : }
823 [ + - ]: 73 : if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
824 : : {
825 [ - + ]: 73 : if( rEvent.IsUpdateCursorPos() )
826 [ # # ]: 0 : xAccImpl->InvalidateCursorPos();
827 [ - + ]: 73 : if( rEvent.IsInvalidateStates() )
828 [ # # ]: 0 : xAccImpl->InvalidateStates( rEvent.GetStates() );
829 [ - + ]: 73 : if( rEvent.IsInvalidateRelation() )
830 : : {
831 : : // both events CONTENT_FLOWS_FROM_RELATION_CHANGED and
832 : : // CONTENT_FLOWS_TO_RELATION_CHANGED are possible
833 [ # # ]: 0 : if ( rEvent.GetAllStates() & ACC_STATE_RELATION_FROM )
834 : : {
835 : : xAccImpl->InvalidateRelation(
836 [ # # ]: 0 : AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED );
837 : : }
838 [ # # ]: 0 : if ( rEvent.GetAllStates() & ACC_STATE_RELATION_TO )
839 : : {
840 : : xAccImpl->InvalidateRelation(
841 [ # # ]: 0 : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
842 : : }
843 : : }
844 : :
845 [ - + ]: 73 : if ( rEvent.IsInvalidateTextSelection() )
846 : : {
847 [ # # ]: 0 : xAccImpl->InvalidateTextSelection();
848 : : }
849 : : }
850 : 73 : }
851 : 73 : }
852 : :
853 : 73 : void SwAccessibleMap::AppendEvent( const SwAccessibleEvent_Impl& rEvent )
854 : : {
855 [ + - ]: 73 : osl::MutexGuard aGuard( maEventMutex );
856 : :
857 [ + + ]: 73 : if( !mpEvents )
858 [ + - ][ + - ]: 29 : mpEvents = new SwAccessibleEventList_Impl;
859 [ + + ]: 73 : if( !mpEventMap )
860 [ + - ][ + - ]: 29 : mpEventMap = new SwAccessibleEventMap_Impl;
861 : :
862 [ - + ]: 73 : if( mpEvents->IsFiring() )
863 : : {
864 : : // While events are fired new ones are generated. They have to be fired
865 : : // now. This does not work for DISPOSE events!
866 : : OSL_ENSURE( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
867 : : "dispose event while firing events" );
868 [ # # ]: 0 : FireEvent( rEvent );
869 : : }
870 : : else
871 : : {
872 : :
873 : : SwAccessibleEventMap_Impl::iterator aIter =
874 [ + - ]: 73 : mpEventMap->find( rEvent.GetFrmOrObj() );
875 [ - + ]: 73 : if( aIter != mpEventMap->end() )
876 : : {
877 [ # # ]: 0 : SwAccessibleEvent_Impl aEvent( *(*aIter).second );
878 : : OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
879 : : "dispose events should not be stored" );
880 : 0 : sal_Bool bAppendEvent = sal_True;
881 [ # # # # : 0 : switch( rEvent.GetType() )
# # # # ]
882 : : {
883 : : case SwAccessibleEvent_Impl::CARET_OR_STATES:
884 : : // A CARET_OR_STATES event is added to any other
885 : : // event only. It is broadcasted after any other event, so the
886 : : // event should be put to the back.
887 : : OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
888 : : "invalid event combination" );
889 : 0 : aEvent.SetStates( rEvent.GetAllStates() );
890 : 0 : break;
891 : : case SwAccessibleEvent_Impl::INVALID_CONTENT:
892 : : // An INVALID_CONTENT event overwrites a CARET_OR_STATES
893 : : // event (but keeps its flags) and it is contained in a
894 : : // POS_CHANGED event.
895 : : // Therefor, the event's type has to be adapted and the event
896 : : // has to be put at the end.
897 : : OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
898 : : "invalid event combination" );
899 [ # # ]: 0 : if( aEvent.GetType() == SwAccessibleEvent_Impl::CARET_OR_STATES )
900 : 0 : aEvent.SetType( SwAccessibleEvent_Impl::INVALID_CONTENT );
901 : 0 : break;
902 : : case SwAccessibleEvent_Impl::POS_CHANGED:
903 : : // A pos changed event overwrites CARET_STATES (keeping its
904 : : // flags) as well as INVALID_CONTENT. The old box position
905 : : // has to be stored however if the old event is not a
906 : : // POS_CHANGED itself.
907 : : OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
908 : : "invalid event combination" );
909 [ # # ]: 0 : if( aEvent.GetType() != SwAccessibleEvent_Impl::POS_CHANGED )
910 : 0 : aEvent.SetOldBox( rEvent.GetOldBox() );
911 : 0 : aEvent.SetType( SwAccessibleEvent_Impl::POS_CHANGED );
912 : 0 : break;
913 : : case SwAccessibleEvent_Impl::CHILD_POS_CHANGED:
914 : : // CHILD_POS_CHANGED events can only follow CHILD_POS_CHANGED
915 : : // events. The only action that needs to be done again is
916 : : // to put the old event to the back. The new one cannot be used,
917 : : // because we are interested in the old frame bounds.
918 : : OSL_ENSURE( aEvent.GetType() == SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
919 : : "invalid event combination" );
920 : 0 : break;
921 : : case SwAccessibleEvent_Impl::SHAPE_SELECTION:
922 : : OSL_ENSURE( aEvent.GetType() == SwAccessibleEvent_Impl::SHAPE_SELECTION,
923 : : "invalid event combination" );
924 : 0 : break;
925 : : case SwAccessibleEvent_Impl::DISPOSE:
926 : : // DISPOSE events overwrite all others. They are not stored
927 : : // but executed immediatly to avoid broadcasting of
928 : : // defunctional objects. So what needs to be done here is to
929 : : // remove all events for the frame in question.
930 : 0 : bAppendEvent = sal_False;
931 : 0 : break;
932 : : case SwAccessibleEvent_Impl::INVALID_ATTR:
933 : : OSL_ENSURE( aEvent.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR,
934 : : "invalid event combination" );
935 : 0 : break;
936 : : }
937 [ # # ]: 0 : if( bAppendEvent )
938 : : {
939 [ # # ]: 0 : mpEvents->erase( (*aIter).second );
940 [ # # ]: 0 : (*aIter).second = mpEvents->insert( mpEvents->end(), aEvent );
941 : : }
942 : : else
943 : : {
944 [ # # ]: 0 : mpEvents->erase( (*aIter).second );
945 [ # # ]: 0 : mpEventMap->erase( aIter );
946 [ # # ]: 0 : }
947 : : }
948 [ + - ]: 73 : else if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
949 : : {
950 : 73 : SwAccessibleEventMap_Impl::value_type aEntry( rEvent.GetFrmOrObj(),
951 [ + - + - ]: 146 : mpEvents->insert( mpEvents->end(), rEvent ) );
952 [ + - ]: 73 : mpEventMap->insert( aEntry );
953 : : }
954 [ + - ]: 73 : }
955 : 73 : }
956 : :
957 : 124 : void SwAccessibleMap::InvalidateCursorPosition(
958 : : const uno::Reference< XAccessible >& rAcc )
959 : : {
960 : : SwAccessibleContext *pAccImpl =
961 [ + - ]: 124 : static_cast< SwAccessibleContext *>( rAcc.get() );
962 : : OSL_ENSURE( pAccImpl, "no caret context" );
963 : : OSL_ENSURE( pAccImpl->GetFrm(), "caret context is disposed" );
964 [ - + ]: 124 : if( GetShell()->ActionPend() )
965 : : {
966 : : SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
967 : : pAccImpl,
968 : : SwAccessibleChild(pAccImpl->GetFrm()),
969 [ # # ][ # # ]: 0 : ACC_STATE_CARET );
970 [ # # ][ # # ]: 0 : AppendEvent( aEvent );
971 : : }
972 : : else
973 : : {
974 : 124 : FireEvents();
975 : : // While firing events the current frame might have
976 : : // been disposed because it moved out of the vis area.
977 : : // Setting the cursor for such frames is useless and even
978 : : // causes asserts.
979 [ + - ]: 124 : if( pAccImpl->GetFrm() )
980 : 124 : pAccImpl->InvalidateCursorPos();
981 : : }
982 : 124 : }
983 : :
984 : 0 : void SwAccessibleMap::InvalidateShapeSelection()
985 : : {
986 [ # # ]: 0 : if( GetShell()->ActionPend() )
987 : : {
988 : : SwAccessibleEvent_Impl aEvent(
989 [ # # ]: 0 : SwAccessibleEvent_Impl::SHAPE_SELECTION );
990 [ # # ][ # # ]: 0 : AppendEvent( aEvent );
991 : : }
992 : : else
993 : : {
994 : 0 : FireEvents();
995 : 0 : DoInvalidateShapeSelection();
996 : : }
997 : 0 : }
998 : :
999 : 0 : void SwAccessibleMap::DoInvalidateShapeSelection()
1000 : : {
1001 : 0 : SwAccessibleObjShape_Impl *pShapes = 0;
1002 : 0 : SwAccessibleObjShape_Impl *pSelShape = 0;
1003 : 0 : size_t nShapes = 0;
1004 : :
1005 : 0 : const ViewShell *pVSh = GetShell();
1006 [ # # ][ # # ]: 0 : const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ?
1007 [ # # ]: 0 : static_cast< const SwFEShell * >( pVSh ) : 0;
1008 [ # # ][ # # ]: 0 : sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1009 : :
1010 : : {
1011 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
1012 [ # # ]: 0 : if( mpShapeMap )
1013 [ # # ][ # # ]: 0 : pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1014 : : }
1015 : :
1016 [ # # ]: 0 : if( pShapes )
1017 : : {
1018 [ # # ]: 0 : ::std::list< const SwFrm * > aParents;
1019 : 0 : Window *pWin = GetShell()->GetWin();
1020 [ # # ][ # # ]: 0 : sal_Bool bFocused = pWin && pWin->HasFocus();
[ # # ]
1021 : 0 : SwAccessibleObjShape_Impl *pShape = pShapes;
1022 [ # # ]: 0 : while( nShapes )
1023 : : {
1024 [ # # ]: 0 : if( pShape->second.is() )
1025 : : {
1026 : : sal_Bool bChanged;
1027 [ # # ]: 0 : if( pShape >= pSelShape )
1028 : : {
1029 : : bChanged =
1030 [ # # ]: 0 : pShape->second->SetState( AccessibleStateType::SELECTED );
1031 [ # # ][ # # ]: 0 : if( bFocused && 1 == nSelShapes )
1032 [ # # ]: 0 : pShape->second->SetState( AccessibleStateType::FOCUSED );
1033 : : else
1034 [ # # ]: 0 : pShape->second->ResetState( AccessibleStateType::FOCUSED );
1035 : : }
1036 : : else
1037 : : {
1038 : : bChanged =
1039 [ # # ]: 0 : pShape->second->ResetState( AccessibleStateType::SELECTED );
1040 [ # # ]: 0 : pShape->second->ResetState( AccessibleStateType::FOCUSED );
1041 : : }
1042 [ # # ]: 0 : if( bChanged )
1043 : : {
1044 : : const SwFrm* pParent = SwAccessibleFrame::GetParent(
1045 : : SwAccessibleChild( pShape->first ),
1046 [ # # ][ # # ]: 0 : GetShell()->IsPreView() );
1047 [ # # ]: 0 : aParents.push_back( pParent );
1048 : : }
1049 : : }
1050 : :
1051 : 0 : --nShapes;
1052 : 0 : ++pShape;
1053 : : }
1054 [ # # ]: 0 : if( aParents.size() > 0 )
1055 : : {
1056 : 0 : ::std::list< const SwFrm * >::const_iterator aIter = aParents.begin();
1057 : 0 : ::std::list< const SwFrm * >::const_iterator aEndIter = aParents.end();
1058 [ # # ]: 0 : while( aIter != aEndIter )
1059 : : {
1060 : 0 : ::rtl::Reference< SwAccessibleContext > xParentAccImpl;
1061 : : {
1062 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
1063 [ # # ]: 0 : if( mpFrmMap )
1064 : : {
1065 : : SwAccessibleContextMap_Impl::const_iterator aMapIter =
1066 [ # # ]: 0 : mpFrmMap->find( *aIter );
1067 [ # # ]: 0 : if( aMapIter != mpFrmMap->end() )
1068 : : {
1069 [ # # ]: 0 : uno::Reference < XAccessible > xAcc( (*aMapIter).second );
1070 : : xParentAccImpl =
1071 [ # # ][ # # ]: 0 : static_cast< SwAccessibleContext *>( xAcc.get() );
[ # # ]
1072 : : }
1073 [ # # ]: 0 : }
1074 : : }
1075 [ # # ]: 0 : if( xParentAccImpl.is() )
1076 : : {
1077 [ # # ]: 0 : AccessibleEventObject aEvent;
1078 : 0 : aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1079 [ # # ][ # # ]: 0 : xParentAccImpl->FireAccessibleEvent( aEvent );
1080 : : }
1081 : :
1082 : 0 : ++aIter;
1083 : 0 : }
1084 : : }
1085 : :
1086 [ # # ][ # # ]: 0 : delete[] pShapes;
[ # # ]
1087 : : }
1088 : 0 : }
1089 : :
1090 : 0 : void SwAccessibleMap::DoInvalidateShapeFocus()
1091 : : {
1092 : 0 : const ViewShell *pVSh = GetShell();
1093 [ # # ][ # # ]: 0 : const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ?
1094 [ # # ]: 0 : static_cast< const SwFEShell * >( pVSh ) : 0;
1095 [ # # ][ # # ]: 0 : sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1096 : :
1097 [ # # ]: 0 : if( nSelShapes != 1 )
1098 : 0 : return;
1099 : :
1100 : 0 : SwAccessibleObjShape_Impl *pShapes = 0;
1101 : 0 : SwAccessibleObjShape_Impl *pSelShape = 0;
1102 : 0 : size_t nShapes = 0;
1103 : :
1104 : :
1105 : : {
1106 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
1107 [ # # ]: 0 : if( mpShapeMap )
1108 [ # # ][ # # ]: 0 : pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1109 : : }
1110 : :
1111 [ # # ]: 0 : if( pShapes )
1112 : : {
1113 : 0 : Window *pWin = GetShell()->GetWin();
1114 [ # # ][ # # ]: 0 : sal_Bool bFocused = pWin && pWin->HasFocus();
[ # # ]
1115 : 0 : SwAccessibleObjShape_Impl *pShape = pShapes;
1116 [ # # ]: 0 : while( nShapes )
1117 : : {
1118 [ # # ]: 0 : if( pShape->second.is() )
1119 : : {
1120 [ # # ][ # # ]: 0 : if( bFocused && pShape >= pSelShape )
1121 [ # # ]: 0 : pShape->second->SetState( AccessibleStateType::FOCUSED );
1122 : : else
1123 [ # # ]: 0 : pShape->second->ResetState( AccessibleStateType::FOCUSED );
1124 : : }
1125 : :
1126 : 0 : --nShapes;
1127 : 0 : ++pShape;
1128 : : }
1129 : :
1130 [ # # ][ # # ]: 0 : delete[] pShapes;
[ # # ]
1131 : : }
1132 : : }
1133 : :
1134 : :
1135 : 24 : SwAccessibleMap::SwAccessibleMap( ViewShell *pSh ) :
1136 : : mpFrmMap( 0 ),
1137 : : mpShapeMap( 0 ),
1138 : : mpShapes( 0 ),
1139 : : mpEvents( 0 ),
1140 : : mpEventMap( 0 ),
1141 : : mpSelectedParas( 0 ),
1142 : : mpVSh( pSh ),
1143 : : mpPreview( 0 ),
1144 : : mnPara( 1 ),
1145 : : mnFootnote( 1 ),
1146 : : mnEndnote( 1 ),
1147 [ + - ][ + - ]: 24 : mbShapeSelected( sal_False )
[ + - ]
1148 : : {
1149 [ + - ]: 24 : pSh->GetLayout()->AddAccessibleShell();
1150 : 24 : }
1151 : :
1152 [ + - ][ + - ]: 24 : SwAccessibleMap::~SwAccessibleMap()
[ + - ]
1153 : : {
1154 : 24 : uno::Reference < XAccessible > xAcc;
1155 : : {
1156 [ + - ]: 24 : osl::MutexGuard aGuard( maMutex );
1157 [ + - ]: 24 : if( mpFrmMap )
1158 : : {
1159 [ + - ]: 24 : const SwRootFrm *pRootFrm = GetShell()->GetLayout();
1160 [ + - ]: 24 : SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm );
1161 [ + - ]: 24 : if( aIter != mpFrmMap->end() )
1162 [ + - ][ + - ]: 24 : xAcc = (*aIter).second;
1163 [ - + ]: 24 : if( !xAcc.is() )
1164 [ # # ][ # # ]: 24 : xAcc = new SwAccessibleDocument( this );
[ # # ]
1165 [ + - ]: 24 : }
1166 : : }
1167 : :
1168 : : SwAccessibleDocument *pAcc =
1169 [ + - ][ + - ]: 24 : static_cast< SwAccessibleDocument * >( xAcc.get() );
1170 [ + - ]: 24 : pAcc->Dispose( sal_True );
1171 : :
1172 : : {
1173 [ + - ]: 24 : osl::MutexGuard aGuard( maMutex );
1174 : : #if OSL_DEBUG_LEVEL > 0
1175 : : OSL_ENSURE( !mpFrmMap || mpFrmMap->empty(),
1176 : : "Frame map should be empty after disposing the root frame" );
1177 : : if( mpFrmMap )
1178 : : {
1179 : : SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin();
1180 : : while( aIter != mpFrmMap->end() )
1181 : : {
1182 : : uno::Reference < XAccessible > xTmp = (*aIter).second;
1183 : : if( xTmp.is() )
1184 : : {
1185 : : SwAccessibleContext *pTmp =
1186 : : static_cast< SwAccessibleContext * >( xTmp.get() );
1187 : : (void) pTmp;
1188 : : }
1189 : : ++aIter;
1190 : : }
1191 : : }
1192 : : OSL_ENSURE( !mpShapeMap || mpShapeMap->empty(),
1193 : : "Object map should be empty after disposing the root frame" );
1194 : : if( mpShapeMap )
1195 : : {
1196 : : SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->begin();
1197 : : while( aIter != mpShapeMap->end() )
1198 : : {
1199 : : uno::Reference < XAccessible > xTmp = (*aIter).second;
1200 : : if( xTmp.is() )
1201 : : {
1202 : : ::accessibility::AccessibleShape *pTmp =
1203 : : static_cast< ::accessibility::AccessibleShape* >( xTmp.get() );
1204 : : (void) pTmp;
1205 : : }
1206 : : ++aIter;
1207 : : }
1208 : : }
1209 : : #endif
1210 [ - + ]: 24 : delete mpFrmMap;
1211 : 24 : mpFrmMap = 0;
1212 [ - + ][ # # ]: 24 : delete mpShapeMap;
1213 : 24 : mpShapeMap = 0;
1214 [ - + ]: 24 : delete mpShapes;
1215 : 24 : mpShapes = 0;
1216 [ - + ]: 24 : delete mpSelectedParas;
1217 [ + - ]: 24 : mpSelectedParas = 0;
1218 : : }
1219 : :
1220 [ - + ]: 24 : delete mpPreview;
1221 : 24 : mpPreview = NULL;
1222 : :
1223 : : {
1224 [ + - ]: 24 : osl::MutexGuard aGuard( maEventMutex );
1225 : : #if OSL_DEBUG_LEVEL > 0
1226 : : OSL_ENSURE( !(mpEvents || mpEventMap), "pending events" );
1227 : : if( mpEvents )
1228 : : {
1229 : : SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin();
1230 : : while( aIter != mpEvents->end() )
1231 : : {
1232 : : ++aIter;
1233 : : }
1234 : : }
1235 : : if( mpEventMap )
1236 : : {
1237 : : SwAccessibleEventMap_Impl::iterator aIter = mpEventMap->begin();
1238 : : while( aIter != mpEventMap->end() )
1239 : : {
1240 : : ++aIter;
1241 : : }
1242 : : }
1243 : : #endif
1244 [ - + ]: 24 : delete mpEventMap;
1245 : 24 : mpEventMap = 0;
1246 [ - + ]: 24 : delete mpEvents;
1247 [ + - ]: 24 : mpEvents = 0;
1248 : : }
1249 [ + - ]: 24 : mpVSh->GetLayout()->RemoveAccessibleShell();
1250 [ - + ]: 48 : }
1251 : :
1252 : 62 : uno::Reference< XAccessible > SwAccessibleMap::_GetDocumentView(
1253 : : sal_Bool bPagePreview )
1254 : : {
1255 : 62 : uno::Reference < XAccessible > xAcc;
1256 : 62 : sal_Bool bSetVisArea = sal_False;
1257 : :
1258 : : {
1259 [ + - ]: 62 : osl::MutexGuard aGuard( maMutex );
1260 : :
1261 [ + + ]: 62 : if( !mpFrmMap )
1262 : : {
1263 [ + - ][ + - ]: 24 : mpFrmMap = new SwAccessibleContextMap_Impl;
1264 : : #if OSL_DEBUG_LEVEL > 0
1265 : : mpFrmMap->mbLocked = sal_False;
1266 : : #endif
1267 : : }
1268 : :
1269 : : #if OSL_DEBUG_LEVEL > 0
1270 : : OSL_ENSURE( !mpFrmMap->mbLocked, "Map is locked" );
1271 : : mpFrmMap->mbLocked = sal_True;
1272 : : #endif
1273 : :
1274 [ + - ]: 62 : const SwRootFrm *pRootFrm = GetShell()->GetLayout();
1275 [ + - ]: 62 : SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm );
1276 [ + + ]: 62 : if( aIter != mpFrmMap->end() )
1277 [ + - ][ + - ]: 38 : xAcc = (*aIter).second;
1278 [ + + ]: 62 : if( xAcc.is() )
1279 : : {
1280 : 38 : bSetVisArea = sal_True; // Set VisArea when map mutex is not
1281 : : // locked
1282 : : }
1283 : : else
1284 : : {
1285 [ - + ]: 24 : if( bPagePreview )
1286 [ # # ][ # # ]: 0 : xAcc = new SwAccessiblePreview( this );
[ # # ]
1287 : : else
1288 [ + - ][ + - ]: 24 : xAcc = new SwAccessibleDocument( this );
[ + - ]
1289 : :
1290 [ - + ]: 24 : if( aIter != mpFrmMap->end() )
1291 : : {
1292 [ # # ]: 0 : (*aIter).second = xAcc;
1293 : : }
1294 : : else
1295 : : {
1296 [ + - ]: 24 : SwAccessibleContextMap_Impl::value_type aEntry( pRootFrm, xAcc );
1297 [ + - ][ + - ]: 24 : mpFrmMap->insert( aEntry );
1298 : : }
1299 [ + - ]: 62 : }
1300 : :
1301 : : #if OSL_DEBUG_LEVEL > 0
1302 : : mpFrmMap->mbLocked = sal_False;
1303 : : #endif
1304 : : }
1305 : :
1306 [ + + ]: 62 : if( bSetVisArea )
1307 : : {
1308 : : SwAccessibleDocumentBase *pAcc =
1309 [ + - ][ + - ]: 38 : static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
1310 [ + - ]: 38 : pAcc->SetVisArea();
1311 : : }
1312 : :
1313 : 62 : return xAcc;
1314 : : }
1315 : :
1316 : 62 : uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView( )
1317 : : {
1318 : 62 : return _GetDocumentView( sal_False );
1319 : : }
1320 : :
1321 : 0 : uno::Reference<XAccessible> SwAccessibleMap::GetDocumentPreview(
1322 : : const std::vector<PrevwPage*>& _rPrevwPages,
1323 : : const Fraction& _rScale,
1324 : : const SwPageFrm* _pSelectedPageFrm,
1325 : : const Size& _rPrevwWinSize )
1326 : : {
1327 : : // create & update preview data object
1328 [ # # ]: 0 : if( mpPreview == NULL )
1329 [ # # ]: 0 : mpPreview = new SwAccPreviewData();
1330 : 0 : mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize );
1331 : :
1332 : 0 : uno::Reference<XAccessible> xAcc = _GetDocumentView( sal_True );
1333 : 0 : return xAcc;
1334 : : }
1335 : :
1336 : 656 : uno::Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrm *pFrm,
1337 : : sal_Bool bCreate )
1338 : : {
1339 : 656 : uno::Reference < XAccessible > xAcc;
1340 : 656 : uno::Reference < XAccessible > xOldCursorAcc;
1341 : 656 : sal_Bool bOldShapeSelected = sal_False;
1342 : :
1343 : : {
1344 [ + - ]: 656 : osl::MutexGuard aGuard( maMutex );
1345 : :
1346 [ - + ][ # # ]: 656 : if( !mpFrmMap && bCreate )
1347 [ # # ][ # # ]: 0 : mpFrmMap = new SwAccessibleContextMap_Impl;
1348 [ + - ]: 656 : if( mpFrmMap )
1349 : : {
1350 [ + - ]: 656 : SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pFrm );
1351 [ + + ]: 656 : if( aIter != mpFrmMap->end() )
1352 [ + - ][ + - ]: 421 : xAcc = (*aIter).second;
1353 : :
1354 [ + + ][ + + ]: 656 : if( !xAcc.is() && bCreate )
[ + + ]
1355 : : {
1356 : 55 : SwAccessibleContext *pAcc = 0;
1357 [ + - - + : 55 : switch( pFrm->GetType() )
+ + + -
- ]
1358 : : {
1359 : : case FRM_TXT:
1360 : 33 : mnPara++;
1361 : : pAcc = new SwAccessibleParagraph( *this,
1362 [ + - ][ + - ]: 33 : static_cast< const SwTxtFrm& >( *pFrm ) );
1363 : 33 : break;
1364 : : case FRM_HEADER:
1365 : : pAcc = new SwAccessibleHeaderFooter( this,
1366 [ # # ]: 0 : static_cast< const SwHeaderFrm *>( pFrm ) );
1367 : 0 : break;
1368 : : case FRM_FOOTER:
1369 : : pAcc = new SwAccessibleHeaderFooter( this,
1370 [ # # ]: 0 : static_cast< const SwFooterFrm *>( pFrm ) );
1371 : 0 : break;
1372 : : case FRM_FTN:
1373 : : {
1374 : : const SwFtnFrm *pFtnFrm =
1375 : 2 : static_cast < const SwFtnFrm * >( pFrm );
1376 : : sal_Bool bIsEndnote =
1377 [ + - ]: 2 : SwAccessibleFootnote::IsEndnote( pFtnFrm );
1378 : : pAcc = new SwAccessibleFootnote( this, bIsEndnote,
1379 : : (bIsEndnote ? mnEndnote++ : mnFootnote++),
1380 [ + - ][ + - ]: 2 : pFtnFrm );
1381 : : }
1382 : 2 : break;
1383 : : case FRM_FLY:
1384 : : {
1385 : : const SwFlyFrm *pFlyFrm =
1386 : 2 : static_cast < const SwFlyFrm * >( pFrm );
1387 [ + - ]: 2 : switch( SwAccessibleFrameBase::GetNodeType( pFlyFrm ) )
[ + - - ]
1388 : : {
1389 : : case ND_GRFNODE:
1390 [ + - ]: 2 : pAcc = new SwAccessibleGraphic( this, pFlyFrm );
1391 : 2 : break;
1392 : : case ND_OLENODE:
1393 [ # # ]: 0 : pAcc = new SwAccessibleEmbeddedObject( this, pFlyFrm );
1394 : 0 : break;
1395 : : default:
1396 [ # # ]: 0 : pAcc = new SwAccessibleTextFrame( this, pFlyFrm );
1397 : 0 : break;
1398 : : }
1399 : : }
1400 : 2 : break;
1401 : : case FRM_CELL:
1402 : : pAcc = new SwAccessibleCell( this,
1403 [ + - ]: 14 : static_cast< const SwCellFrm *>( pFrm ) );
1404 : 14 : break;
1405 : : case FRM_TAB:
1406 : : pAcc = new SwAccessibleTable( this,
1407 [ + - ]: 4 : static_cast< const SwTabFrm *>( pFrm ) );
1408 : 4 : break;
1409 : : case FRM_PAGE:
1410 : : OSL_ENSURE( GetShell()->IsPreView(),
1411 : : "accessible page frames only in PagePreview" );
1412 [ # # ]: 0 : pAcc = new SwAccessiblePage( this, pFrm );
1413 : 0 : break;
1414 : : }
1415 [ + - ][ + - ]: 55 : xAcc = pAcc;
1416 : :
1417 : : OSL_ENSURE( xAcc.is(), "unknown frame type" );
1418 [ + - ]: 55 : if( xAcc.is() )
1419 : : {
1420 [ - + ]: 55 : if( aIter != mpFrmMap->end() )
1421 : : {
1422 [ # # ]: 0 : (*aIter).second = xAcc;
1423 : : }
1424 : : else
1425 : : {
1426 [ + - ]: 55 : SwAccessibleContextMap_Impl::value_type aEntry( pFrm, xAcc );
1427 [ + - ][ + - ]: 55 : mpFrmMap->insert( aEntry );
1428 : : }
1429 : :
1430 [ + - ][ + + ]: 137 : if( pAcc->HasCursor() &&
[ + - ][ + + ]
1431 [ + - ][ + - ]: 82 : !AreInSameTable( mxCursorContext, pFrm ) )
[ + + ][ # # ]
1432 : : {
1433 : : // If the new context has the focus, and if we know
1434 : : // another context that had the focus, then the focus
1435 : : // just moves from the old context to the new one. We
1436 : : // have to send a focus event and a caret event for
1437 : : // the old context then. We have to to that know,
1438 : : // because after we have left this method, anyone might
1439 : : // call getStates for the new context and will get a
1440 : : // focused state then. Sending the focus changes event
1441 : : // after that seems to be strange. However, we cannot
1442 : : // send a focus event fo the new context now, because
1443 : : // noone except us knows it. In any case, we remeber
1444 : : // the new context as the one that has the focus
1445 : : // currently.
1446 : :
1447 [ + - ][ + - ]: 27 : xOldCursorAcc = mxCursorContext;
1448 [ + - ]: 27 : mxCursorContext = xAcc;
1449 : :
1450 : 27 : bOldShapeSelected = mbShapeSelected;
1451 : 656 : mbShapeSelected = sal_False;
1452 : : }
1453 : : }
1454 : : }
1455 [ + - ]: 656 : }
1456 : : }
1457 : :
1458 : : // Invalidate focus for old object when map is not locked
1459 [ - + ]: 656 : if( xOldCursorAcc.is() )
1460 [ # # ]: 0 : InvalidateCursorPosition( xOldCursorAcc );
1461 [ - + ]: 656 : if( bOldShapeSelected )
1462 [ # # ]: 0 : InvalidateShapeSelection();
1463 : :
1464 : 656 : return xAcc;
1465 : : }
1466 : :
1467 : 564 : ::rtl::Reference < SwAccessibleContext > SwAccessibleMap::GetContextImpl(
1468 : : const SwFrm *pFrm,
1469 : : sal_Bool bCreate )
1470 : : {
1471 [ + - ]: 564 : uno::Reference < XAccessible > xAcc( GetContext( pFrm, bCreate ) );
1472 : :
1473 : : ::rtl::Reference < SwAccessibleContext > xAccImpl(
1474 [ + - ][ + + ]: 564 : static_cast< SwAccessibleContext * >( xAcc.get() ) );
1475 : :
1476 : 564 : return xAccImpl;
1477 : : }
1478 : :
1479 : 0 : uno::Reference< XAccessible> SwAccessibleMap::GetContext(
1480 : : const SdrObject *pObj,
1481 : : SwAccessibleContext *pParentImpl,
1482 : : sal_Bool bCreate )
1483 : : {
1484 : 0 : uno::Reference < XAccessible > xAcc;
1485 : 0 : uno::Reference < XAccessible > xOldCursorAcc;
1486 : :
1487 : : {
1488 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
1489 : :
1490 [ # # ][ # # ]: 0 : if( !mpShapeMap && bCreate )
1491 [ # # ][ # # ]: 0 : mpShapeMap = new SwAccessibleShapeMap_Impl( this );
1492 [ # # ]: 0 : if( mpShapeMap )
1493 : : {
1494 : : SwAccessibleShapeMap_Impl::iterator aIter =
1495 [ # # ]: 0 : mpShapeMap->find( pObj );
1496 [ # # ]: 0 : if( aIter != mpShapeMap->end() )
1497 [ # # ][ # # ]: 0 : xAcc = (*aIter).second;
1498 : :
1499 [ # # ][ # # ]: 0 : if( !xAcc.is() && bCreate )
[ # # ]
1500 : : {
1501 : 0 : ::accessibility::AccessibleShape *pAcc = 0;
1502 : : uno::Reference < drawing::XShape > xShape(
1503 : 0 : const_cast< SdrObject * >( pObj )->getUnoShape(),
1504 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
1505 [ # # ]: 0 : if( xShape.is() )
1506 : : {
1507 : : ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
1508 [ # # ]: 0 : ::accessibility::ShapeTypeHandler::Instance();
1509 [ # # ][ # # ]: 0 : uno::Reference < XAccessible > xParent( pParentImpl );
1510 : : ::accessibility::AccessibleShapeInfo aShapeInfo(
1511 [ # # ]: 0 : xShape, xParent, this );
1512 : :
1513 : : pAcc = rShapeTypeHandler.CreateAccessibleObject(
1514 [ # # ][ # # ]: 0 : aShapeInfo, mpShapeMap->GetInfo() );
1515 : : }
1516 [ # # ][ # # ]: 0 : xAcc = pAcc;
1517 : :
1518 : : OSL_ENSURE( xAcc.is(), "unknown shape type" );
1519 [ # # ]: 0 : if( xAcc.is() )
1520 : : {
1521 [ # # ]: 0 : pAcc->Init();
1522 [ # # ]: 0 : if( aIter != mpShapeMap->end() )
1523 : : {
1524 [ # # ]: 0 : (*aIter).second = xAcc;
1525 : : }
1526 : : else
1527 : : {
1528 : : SwAccessibleShapeMap_Impl::value_type aEntry( pObj,
1529 [ # # ]: 0 : xAcc );
1530 [ # # ][ # # ]: 0 : mpShapeMap->insert( aEntry );
1531 : : }
1532 : : // TODO: focus!!!
1533 : 0 : }
1534 : : }
1535 [ # # ]: 0 : }
1536 : : }
1537 : :
1538 : : // Invalidate focus for old object when map is not locked
1539 [ # # ]: 0 : if( xOldCursorAcc.is() )
1540 [ # # ]: 0 : InvalidateCursorPosition( xOldCursorAcc );
1541 : :
1542 : 0 : return xAcc;
1543 : : }
1544 : :
1545 : 0 : ::rtl::Reference < ::accessibility::AccessibleShape > SwAccessibleMap::GetContextImpl(
1546 : : const SdrObject *pObj,
1547 : : SwAccessibleContext *pParentImpl,
1548 : : sal_Bool bCreate )
1549 : : {
1550 [ # # ]: 0 : uno::Reference < XAccessible > xAcc( GetContext( pObj, pParentImpl, bCreate ) );
1551 : :
1552 : : ::rtl::Reference < ::accessibility::AccessibleShape > xAccImpl(
1553 [ # # ][ # # ]: 0 : static_cast< ::accessibility::AccessibleShape* >( xAcc.get() ) );
1554 : :
1555 : 0 : return xAccImpl;
1556 : : }
1557 : :
1558 : :
1559 : 79 : void SwAccessibleMap::RemoveContext( const SwFrm *pFrm )
1560 : : {
1561 [ + - ]: 79 : osl::MutexGuard aGuard( maMutex );
1562 : :
1563 [ + - ]: 79 : if( mpFrmMap )
1564 : : {
1565 : : SwAccessibleContextMap_Impl::iterator aIter =
1566 [ + - ]: 79 : mpFrmMap->find( pFrm );
1567 [ + - ]: 79 : if( aIter != mpFrmMap->end() )
1568 : : {
1569 [ + - ]: 79 : mpFrmMap->erase( aIter );
1570 : :
1571 : : // Remove reference to old caret object. Though mxCursorContext
1572 : : // is a weak reference and cleared automatically, clearing it
1573 : : // directly makes sure to not keep a defunctional object.
1574 [ + - ]: 79 : uno::Reference < XAccessible > xOldAcc( mxCursorContext );
1575 [ + + ]: 79 : if( xOldAcc.is() )
1576 : : {
1577 : : SwAccessibleContext *pOldAccImpl =
1578 [ + - ][ + - ]: 20 : static_cast< SwAccessibleContext *>( xOldAcc.get() );
1579 : : OSL_ENSURE( pOldAccImpl->GetFrm(), "old caret context is disposed" );
1580 [ + + ]: 20 : if( pOldAccImpl->GetFrm() == pFrm )
1581 : : {
1582 : 18 : xOldAcc.clear(); // get an empty ref
1583 [ + - ]: 18 : mxCursorContext = xOldAcc;
1584 : : }
1585 : : }
1586 : :
1587 [ + + ]: 79 : if( mpFrmMap->empty() )
1588 : : {
1589 [ + - ]: 24 : delete mpFrmMap;
1590 : 24 : mpFrmMap = 0;
1591 : 79 : }
1592 : : }
1593 [ + - ]: 79 : }
1594 : 79 : }
1595 : :
1596 : 0 : void SwAccessibleMap::RemoveContext( const SdrObject *pObj )
1597 : : {
1598 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
1599 : :
1600 [ # # ]: 0 : if( mpShapeMap )
1601 : : {
1602 : : SwAccessibleShapeMap_Impl::iterator aIter =
1603 [ # # ]: 0 : mpShapeMap->find( pObj );
1604 [ # # ]: 0 : if( aIter != mpShapeMap->end() )
1605 : : {
1606 [ # # ]: 0 : mpShapeMap->erase( aIter );
1607 : :
1608 : : // The shape selection flag is not cleared, but one might do
1609 : : // so but has to make sure that the removed context is the one
1610 : : // that is selected.
1611 : :
1612 [ # # ]: 0 : if( mpShapeMap->empty() )
1613 : : {
1614 [ # # ][ # # ]: 0 : delete mpShapeMap;
1615 : 0 : mpShapeMap = 0;
1616 : : }
1617 : : }
1618 [ # # ]: 0 : }
1619 : 0 : }
1620 : :
1621 : :
1622 : 0 : void SwAccessibleMap::Dispose( const SwFrm *pFrm,
1623 : : const SdrObject *pObj,
1624 : : Window* pWindow,
1625 : : sal_Bool bRecursive )
1626 : : {
1627 [ # # ]: 0 : SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow );
1628 : :
1629 : : // Indeed, the following assert checks the frame's accessible flag,
1630 : : // because that's the one that is evaluated in the layout. The frame
1631 : : // might not be accessible anyway. That's the case for cell frames that
1632 : : // contain further cells.
1633 : : OSL_ENSURE( !aFrmOrObj.GetSwFrm() || aFrmOrObj.GetSwFrm()->IsAccessibleFrm(),
1634 : : "non accessible frame should be disposed" );
1635 : :
1636 [ # # ][ # # ]: 0 : if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
1637 : : {
1638 : 0 : ::rtl::Reference< SwAccessibleContext > xAccImpl;
1639 : 0 : ::rtl::Reference< SwAccessibleContext > xParentAccImpl;
1640 : 0 : ::rtl::Reference< ::accessibility::AccessibleShape > xShapeAccImpl;
1641 : : // get accessible context for frame
1642 : : {
1643 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
1644 : :
1645 : : // First of all look for an accessible context for a frame
1646 [ # # ][ # # ]: 0 : if( aFrmOrObj.GetSwFrm() && mpFrmMap )
[ # # ][ # # ]
1647 : : {
1648 : : SwAccessibleContextMap_Impl::iterator aIter =
1649 [ # # ][ # # ]: 0 : mpFrmMap->find( aFrmOrObj.GetSwFrm() );
1650 [ # # ]: 0 : if( aIter != mpFrmMap->end() )
1651 : : {
1652 [ # # ]: 0 : uno::Reference < XAccessible > xAcc( (*aIter).second );
1653 : : xAccImpl =
1654 [ # # ][ # # ]: 0 : static_cast< SwAccessibleContext *>( xAcc.get() );
[ # # ]
1655 : : }
1656 : : }
1657 [ # # ][ # # ]: 0 : if( !xAccImpl.is() && mpFrmMap )
[ # # ]
1658 : : {
1659 : : // If there is none, look if the parent is accessible.
1660 : : const SwFrm *pParent =
1661 : : SwAccessibleFrame::GetParent( aFrmOrObj,
1662 [ # # ]: 0 : GetShell()->IsPreView());
1663 : :
1664 [ # # ]: 0 : if( pParent )
1665 : : {
1666 : : SwAccessibleContextMap_Impl::iterator aIter =
1667 [ # # ]: 0 : mpFrmMap->find( pParent );
1668 [ # # ]: 0 : if( aIter != mpFrmMap->end() )
1669 : : {
1670 [ # # ]: 0 : uno::Reference < XAccessible > xAcc( (*aIter).second );
1671 : : xParentAccImpl =
1672 [ # # ][ # # ]: 0 : static_cast< SwAccessibleContext *>( xAcc.get() );
[ # # ]
1673 : : }
1674 : : }
1675 : : }
1676 [ # # ][ # # ]: 0 : if( !xParentAccImpl.is() && !aFrmOrObj.GetSwFrm() &&
[ # # ][ # # ]
[ # # ]
1677 : : mpShapeMap )
1678 : : {
1679 : : SwAccessibleShapeMap_Impl::iterator aIter =
1680 [ # # ][ # # ]: 0 : mpShapeMap->find( aFrmOrObj.GetDrawObject() );
1681 [ # # ]: 0 : if( aIter != mpShapeMap->end() )
1682 : : {
1683 [ # # ]: 0 : uno::Reference < XAccessible > xAcc( (*aIter).second );
1684 : : xShapeAccImpl =
1685 [ # # ][ # # ]: 0 : static_cast< ::accessibility::AccessibleShape *>( xAcc.get() );
[ # # ]
1686 : : }
1687 : : }
1688 [ # # ][ # # : 0 : if( pObj && GetShell()->ActionPend() &&
# # # # ]
[ # # ]
1689 : 0 : (xParentAccImpl.is() || xShapeAccImpl.is()) )
1690 : : {
1691 : : // Keep a reference to the XShape to avoid that it
1692 : : // is deleted with a SwFrmFmt::Modify.
1693 : : uno::Reference < drawing::XShape > xShape(
1694 : 0 : const_cast< SdrObject * >( pObj )->getUnoShape(),
1695 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
1696 [ # # ]: 0 : if( xShape.is() )
1697 : : {
1698 [ # # ]: 0 : if( !mpShapes )
1699 [ # # ][ # # ]: 0 : mpShapes = new SwShapeList_Impl;
1700 [ # # ]: 0 : mpShapes->push_back( xShape );
1701 : 0 : }
1702 [ # # ]: 0 : }
1703 : : }
1704 : :
1705 : : // remove events stored for the frame
1706 : : {
1707 [ # # ]: 0 : osl::MutexGuard aGuard( maEventMutex );
1708 [ # # ]: 0 : if( mpEvents )
1709 : : {
1710 : : SwAccessibleEventMap_Impl::iterator aIter =
1711 [ # # ]: 0 : mpEventMap->find( aFrmOrObj );
1712 [ # # ]: 0 : if( aIter != mpEventMap->end() )
1713 : : {
1714 : : SwAccessibleEvent_Impl aEvent(
1715 [ # # ]: 0 : SwAccessibleEvent_Impl::DISPOSE, aFrmOrObj );
1716 [ # # ][ # # ]: 0 : AppendEvent( aEvent );
1717 : : }
1718 [ # # ]: 0 : }
1719 : : }
1720 : :
1721 : : // If the frame is accessible and there is a context for it, dispose
1722 : : // the frame. If the frame is no context for it but disposing should
1723 : : // take place recursive, the frame's children have to be disposed
1724 : : // anyway, so we have to create the context then.
1725 [ # # ]: 0 : if( xAccImpl.is() )
1726 : : {
1727 [ # # ]: 0 : xAccImpl->Dispose( bRecursive );
1728 : : }
1729 [ # # ]: 0 : else if( xParentAccImpl.is() )
1730 : : {
1731 : : // If the frame is a cell frame, the table must be notified.
1732 : : // If we are in an action, a table model change event will
1733 : : // be broadcasted at the end of the action to give the table
1734 : : // a chance to generate a single table change event.
1735 : :
1736 [ # # ]: 0 : xParentAccImpl->DisposeChild( aFrmOrObj, bRecursive );
1737 : : }
1738 [ # # ]: 0 : else if( xShapeAccImpl.is() )
1739 : : {
1740 [ # # ][ # # ]: 0 : RemoveContext( aFrmOrObj.GetDrawObject() );
1741 [ # # ]: 0 : xShapeAccImpl->dispose();
1742 : : }
1743 : :
1744 [ # # ][ # # ]: 0 : if( mpPreview && pFrm && pFrm->IsPageFrm() )
[ # # ][ # # ]
1745 : 0 : mpPreview->DisposePage( static_cast< const SwPageFrm *>( pFrm ) );
1746 : : }
1747 : 0 : }
1748 : :
1749 : 117 : void SwAccessibleMap::InvalidatePosOrSize( const SwFrm *pFrm,
1750 : : const SdrObject *pObj,
1751 : : Window* pWindow,
1752 : : const SwRect& rOldBox )
1753 : : {
1754 [ + - ]: 117 : SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow );
1755 [ + - ][ + + ]: 117 : if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
1756 : : {
1757 : 73 : ::rtl::Reference< SwAccessibleContext > xAccImpl;
1758 : 73 : ::rtl::Reference< SwAccessibleContext > xParentAccImpl;
1759 : : {
1760 [ + - ]: 73 : osl::MutexGuard aGuard( maMutex );
1761 : :
1762 [ + - ]: 73 : if( mpFrmMap )
1763 : : {
1764 [ + - ][ + - ]: 73 : if( aFrmOrObj.GetSwFrm() )
1765 : : {
1766 : : SwAccessibleContextMap_Impl::iterator aIter =
1767 [ + - ][ + - ]: 73 : mpFrmMap->find( aFrmOrObj.GetSwFrm() );
1768 [ + + ]: 73 : if( aIter != mpFrmMap->end() )
1769 : : {
1770 : : // If there is an accesible object already it is
1771 : : // notified directly.
1772 [ + - ]: 56 : uno::Reference < XAccessible > xAcc( (*aIter).second );
1773 : : xAccImpl =
1774 [ + - ][ + - ]: 73 : static_cast< SwAccessibleContext *>( xAcc.get() );
[ + - ]
1775 : : }
1776 : : }
1777 [ + + ]: 73 : if( !xAccImpl.is() )
1778 : : {
1779 : : // Otherwise we look if the parent is accessible.
1780 : : // If not, there is nothing to do.
1781 : : const SwFrm *pParent =
1782 : : SwAccessibleFrame::GetParent( aFrmOrObj,
1783 [ + - ]: 17 : GetShell()->IsPreView());
1784 : :
1785 [ + - ]: 17 : if( pParent )
1786 : : {
1787 : : SwAccessibleContextMap_Impl::iterator aIter =
1788 [ + - ]: 17 : mpFrmMap->find( pParent );
1789 [ + - ]: 17 : if( aIter != mpFrmMap->end() )
1790 : : {
1791 [ + - ]: 17 : uno::Reference < XAccessible > xAcc( (*aIter).second );
1792 : : xParentAccImpl =
1793 [ + - ][ + - ]: 17 : static_cast< SwAccessibleContext *>( xAcc.get() );
[ + - ]
1794 : : }
1795 : : }
1796 : : }
1797 [ + - ]: 73 : }
1798 : : }
1799 : :
1800 [ + + ]: 73 : if( xAccImpl.is() )
1801 : : {
1802 [ + - ]: 56 : if( GetShell()->ActionPend() )
1803 : : {
1804 : : SwAccessibleEvent_Impl aEvent(
1805 : : SwAccessibleEvent_Impl::POS_CHANGED, xAccImpl.get(),
1806 [ + - ]: 56 : aFrmOrObj, rOldBox );
1807 [ + - ][ + - ]: 56 : AppendEvent( aEvent );
1808 : : }
1809 : : else
1810 : : {
1811 [ # # ]: 0 : FireEvents();
1812 [ # # ]: 0 : xAccImpl->InvalidatePosOrSize( rOldBox );
1813 : : }
1814 : : }
1815 [ + - ]: 17 : else if( xParentAccImpl.is() )
1816 : : {
1817 [ + - ]: 17 : if( GetShell()->ActionPend() )
1818 : : {
1819 : : SwAccessibleEvent_Impl aEvent(
1820 : : SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
1821 [ + - ]: 17 : xParentAccImpl.get(), aFrmOrObj, rOldBox );
1822 [ + - ][ + - ]: 17 : AppendEvent( aEvent );
1823 : : }
1824 : : else
1825 : : {
1826 [ # # ]: 0 : FireEvents();
1827 : 0 : xParentAccImpl->InvalidateChildPosOrSize( aFrmOrObj,
1828 [ # # ]: 0 : rOldBox );
1829 : : }
1830 : 73 : }
1831 : : }
1832 : 117 : }
1833 : :
1834 : 0 : void SwAccessibleMap::InvalidateContent( const SwFrm *pFrm )
1835 : : {
1836 [ # # ]: 0 : SwAccessibleChild aFrmOrObj( pFrm );
1837 [ # # ][ # # ]: 0 : if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
1838 : : {
1839 : 0 : uno::Reference < XAccessible > xAcc;
1840 : : {
1841 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
1842 : :
1843 [ # # ]: 0 : if( mpFrmMap )
1844 : : {
1845 : : SwAccessibleContextMap_Impl::iterator aIter =
1846 [ # # ][ # # ]: 0 : mpFrmMap->find( aFrmOrObj.GetSwFrm() );
1847 [ # # ]: 0 : if( aIter != mpFrmMap->end() )
1848 [ # # ][ # # ]: 0 : xAcc = (*aIter).second;
1849 [ # # ]: 0 : }
1850 : : }
1851 : :
1852 [ # # ]: 0 : if( xAcc.is() )
1853 : : {
1854 : : SwAccessibleContext *pAccImpl =
1855 [ # # ][ # # ]: 0 : static_cast< SwAccessibleContext *>( xAcc.get() );
1856 [ # # ]: 0 : if( GetShell()->ActionPend() )
1857 : : {
1858 : : SwAccessibleEvent_Impl aEvent(
1859 : : SwAccessibleEvent_Impl::INVALID_CONTENT, pAccImpl,
1860 [ # # ]: 0 : aFrmOrObj );
1861 [ # # ][ # # ]: 0 : AppendEvent( aEvent );
1862 : : }
1863 : : else
1864 : : {
1865 [ # # ]: 0 : FireEvents();
1866 [ # # ]: 0 : pAccImpl->InvalidateContent();
1867 : : }
1868 : 0 : }
1869 : : }
1870 : 0 : }
1871 : :
1872 : 0 : void SwAccessibleMap::InvalidateAttr( const SwTxtFrm& rTxtFrm )
1873 : : {
1874 [ # # ]: 0 : SwAccessibleChild aFrmOrObj( &rTxtFrm );
1875 [ # # ][ # # ]: 0 : if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
1876 : : {
1877 : 0 : uno::Reference < XAccessible > xAcc;
1878 : : {
1879 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
1880 : :
1881 [ # # ]: 0 : if( mpFrmMap )
1882 : : {
1883 : : SwAccessibleContextMap_Impl::iterator aIter =
1884 [ # # ][ # # ]: 0 : mpFrmMap->find( aFrmOrObj.GetSwFrm() );
1885 [ # # ]: 0 : if( aIter != mpFrmMap->end() )
1886 [ # # ][ # # ]: 0 : xAcc = (*aIter).second;
1887 [ # # ]: 0 : }
1888 : : }
1889 : :
1890 [ # # ]: 0 : if( xAcc.is() )
1891 : : {
1892 : : SwAccessibleContext *pAccImpl =
1893 [ # # ][ # # ]: 0 : static_cast< SwAccessibleContext *>( xAcc.get() );
1894 [ # # ]: 0 : if( GetShell()->ActionPend() )
1895 : : {
1896 : : SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::INVALID_ATTR,
1897 [ # # ]: 0 : pAccImpl, aFrmOrObj );
1898 : 0 : aEvent.SetStates( ACC_STATE_TEXT_ATTRIBUTE_CHANGED );
1899 [ # # ][ # # ]: 0 : AppendEvent( aEvent );
1900 : : }
1901 : : else
1902 : : {
1903 [ # # ]: 0 : FireEvents();
1904 [ # # ]: 0 : pAccImpl->InvalidateAttr();
1905 : : }
1906 : 0 : }
1907 : : }
1908 : 0 : }
1909 : :
1910 : 142 : void SwAccessibleMap::InvalidateCursorPosition( const SwFrm *pFrm )
1911 : : {
1912 [ + - ]: 142 : SwAccessibleChild aFrmOrObj( pFrm );
1913 : 142 : sal_Bool bShapeSelected = sal_False;
1914 : 142 : const ViewShell *pVSh = GetShell();
1915 [ + - ][ + - ]: 142 : if( pVSh->ISA( SwCrsrShell ) )
[ + - ]
1916 : : {
1917 : 142 : const SwCrsrShell *pCSh = static_cast< const SwCrsrShell * >( pVSh );
1918 [ + + ]: 142 : if( pCSh->IsTableMode() )
1919 : : {
1920 [ + - ][ + - ]: 32 : while( aFrmOrObj.GetSwFrm() && !aFrmOrObj.GetSwFrm()->IsCellFrm() )
[ + - ][ + + ]
[ + + ]
1921 [ + - ][ + - ]: 16 : aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper();
1922 : : }
1923 [ + - ][ + - ]: 126 : else if( pVSh->ISA( SwFEShell ) )
[ + - ]
1924 : : {
1925 : 126 : const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh );
1926 [ + - ]: 126 : const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm();
1927 [ - + ]: 126 : if( pFlyFrm )
1928 : : {
1929 : : OSL_ENSURE( !pFrm || pFrm->FindFlyFrm() == pFlyFrm,
1930 : : "cursor is not contained in fly frame" );
1931 [ # # ]: 0 : aFrmOrObj = pFlyFrm;
1932 : : }
1933 [ + - ][ - + ]: 126 : else if( pFESh->IsObjSelected() > 0 )
1934 : : {
1935 : 0 : bShapeSelected = sal_True;
1936 [ # # ]: 0 : aFrmOrObj = static_cast<const SwFrm *>( 0 );
1937 : : }
1938 : : }
1939 : : }
1940 : :
1941 : : OSL_ENSURE( bShapeSelected || aFrmOrObj.IsAccessible(GetShell()->IsPreView()),
1942 : : "frame is not accessible" );
1943 : :
1944 : 142 : uno::Reference < XAccessible > xOldAcc;
1945 : 142 : uno::Reference < XAccessible > xAcc;
1946 : 142 : sal_Bool bOldShapeSelected = sal_False;
1947 : :
1948 : : {
1949 [ + - ]: 142 : osl::MutexGuard aGuard( maMutex );
1950 : :
1951 [ + - ][ + - ]: 142 : xOldAcc = mxCursorContext;
1952 [ + - ]: 142 : mxCursorContext = xAcc; // clear reference
1953 : :
1954 : 142 : bOldShapeSelected = mbShapeSelected;
1955 : 142 : mbShapeSelected = bShapeSelected;
1956 : :
1957 [ + - ][ + - ]: 142 : if( aFrmOrObj.GetSwFrm() && mpFrmMap )
[ + - ][ + - ]
1958 : : {
1959 : : SwAccessibleContextMap_Impl::iterator aIter =
1960 [ + - ][ + - ]: 142 : mpFrmMap->find( aFrmOrObj.GetSwFrm() );
1961 [ + + ]: 142 : if( aIter != mpFrmMap->end() )
1962 [ + - ][ + - ]: 108 : xAcc = (*aIter).second;
1963 : :
1964 : : // For cells, some extra thoughts are necessary,
1965 : : // because invalidating the cursor for one cell
1966 : : // invalidates the cursor for all cells of the same
1967 : : // table. For this reason, we don't want to
1968 : : // invalidate the cursor for the old cursor object
1969 : : // and the new one if they are within the same table,
1970 : : // because this would result in doing the work twice.
1971 : : // Moreover, we have to make sure to invalidate the
1972 : : // cursor even if the current cell has no accessible object.
1973 : : // If the old cursor objects exists and is in the same
1974 : : // table, its the best choice, because using it avoids
1975 : : // an unnessarary cursor invalidation cycle when creating
1976 : : // a new object for the current cell.
1977 [ + - ][ + + ]: 142 : if( aFrmOrObj.GetSwFrm()->IsCellFrm() )
1978 : : {
1979 [ + + ][ + - ]: 18 : if( xOldAcc.is() &&
[ + + ]
1980 [ + - ][ + - ]: 2 : AreInSameTable( xOldAcc, aFrmOrObj.GetSwFrm() ) )
1981 : : {
1982 [ + - ]: 2 : if( xAcc.is() )
1983 [ + - ]: 2 : xOldAcc = xAcc; // avoid extra invalidation
1984 : : else
1985 [ # # ]: 0 : xAcc = xOldAcc; // make sure ate least one
1986 : : }
1987 [ + + ]: 16 : if( !xAcc.is() )
1988 [ + - ][ + - ]: 142 : xAcc = GetContext( aFrmOrObj.GetSwFrm(), sal_True );
[ + - ]
1989 : : }
1990 [ + - ]: 142 : }
1991 : : }
1992 : :
1993 [ + + ][ + - ]: 142 : if( xOldAcc.is() && xOldAcc != xAcc )
[ + + ][ + + ]
1994 [ + - ]: 6 : InvalidateCursorPosition( xOldAcc );
1995 [ + - ][ - + ]: 142 : if( bOldShapeSelected || bShapeSelected )
1996 [ # # ]: 0 : InvalidateShapeSelection();
1997 [ + + ]: 142 : if( xAcc.is() )
1998 [ + - ]: 142 : InvalidateCursorPosition( xAcc );
1999 : 142 : }
2000 : :
2001 : 24 : void SwAccessibleMap::InvalidateFocus()
2002 : : {
2003 : 24 : uno::Reference < XAccessible > xAcc;
2004 : : sal_Bool bShapeSelected;
2005 : : {
2006 [ + - ]: 24 : osl::MutexGuard aGuard( maMutex );
2007 : :
2008 [ + - ][ + - ]: 24 : xAcc = mxCursorContext;
2009 [ + - ]: 24 : bShapeSelected = mbShapeSelected;
2010 : : }
2011 : :
2012 [ + + ]: 24 : if( xAcc.is() )
2013 : : {
2014 : : SwAccessibleContext *pAccImpl =
2015 [ + - ][ + - ]: 18 : static_cast< SwAccessibleContext *>( xAcc.get() );
2016 [ + - ]: 18 : pAccImpl->InvalidateFocus();
2017 : : }
2018 [ - + ]: 6 : else if( bShapeSelected )
2019 : : {
2020 [ # # ]: 0 : DoInvalidateShapeFocus();
2021 : 24 : }
2022 : 24 : }
2023 : :
2024 : 146 : void SwAccessibleMap::SetCursorContext(
2025 : : const ::rtl::Reference < SwAccessibleContext >& rCursorContext )
2026 : : {
2027 [ + - ]: 146 : osl::MutexGuard aGuard( maMutex );
2028 [ + - ][ + - ]: 146 : uno::Reference < XAccessible > xAcc( rCursorContext.get() );
2029 [ + - ][ + - ]: 146 : mxCursorContext = xAcc;
2030 : 146 : }
2031 : :
2032 : 0 : void SwAccessibleMap::InvalidateStates( tAccessibleStates _nStates,
2033 : : const SwFrm* _pFrm )
2034 : : {
2035 : : // Start with the frame or the first upper that is accessible
2036 [ # # ]: 0 : SwAccessibleChild aFrmOrObj( _pFrm );
2037 [ # # ][ # # ]: 0 : while( aFrmOrObj.GetSwFrm() &&
[ # # ][ # # ]
2038 [ # # ]: 0 : !aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2039 [ # # ][ # # ]: 0 : aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper();
2040 [ # # ][ # # ]: 0 : if( !aFrmOrObj.GetSwFrm() )
2041 [ # # ][ # # ]: 0 : aFrmOrObj = GetShell()->GetLayout();
2042 : :
2043 [ # # ][ # # ]: 0 : uno::Reference< XAccessible > xAcc( GetContext( aFrmOrObj.GetSwFrm(), sal_True ) );
2044 : : SwAccessibleContext *pAccImpl =
2045 [ # # ][ # # ]: 0 : static_cast< SwAccessibleContext *>( xAcc.get() );
2046 [ # # ]: 0 : if( GetShell()->ActionPend() )
2047 : : {
2048 : : SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
2049 : : pAccImpl,
2050 : : SwAccessibleChild(pAccImpl->GetFrm()),
2051 [ # # ][ # # ]: 0 : _nStates );
2052 [ # # ][ # # ]: 0 : AppendEvent( aEvent );
2053 : : }
2054 : : else
2055 : : {
2056 [ # # ]: 0 : FireEvents();
2057 [ # # ]: 0 : pAccImpl->InvalidateStates( _nStates );
2058 : 0 : }
2059 : 0 : }
2060 : :
2061 : 0 : void SwAccessibleMap::_InvalidateRelationSet( const SwFrm* pFrm,
2062 : : sal_Bool bFrom )
2063 : : {
2064 : : // first, see if this frame is accessible, and if so, get the respective
2065 [ # # ]: 0 : SwAccessibleChild aFrmOrObj( pFrm );
2066 [ # # ][ # # ]: 0 : if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2067 : : {
2068 : 0 : uno::Reference < XAccessible > xAcc;
2069 : : {
2070 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
2071 : :
2072 [ # # ]: 0 : if( mpFrmMap )
2073 : : {
2074 : : SwAccessibleContextMap_Impl::iterator aIter =
2075 [ # # ][ # # ]: 0 : mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2076 [ # # ]: 0 : if( aIter != mpFrmMap->end() )
2077 : : {
2078 [ # # ][ # # ]: 0 : xAcc = (*aIter).second;
2079 : : }
2080 [ # # ]: 0 : }
2081 : : }
2082 : :
2083 : : // deliver event directly, or queue event
2084 [ # # ]: 0 : if( xAcc.is() )
2085 : : {
2086 : : SwAccessibleContext *pAccImpl =
2087 [ # # ][ # # ]: 0 : static_cast< SwAccessibleContext *>( xAcc.get() );
2088 [ # # ]: 0 : if( GetShell()->ActionPend() )
2089 : : {
2090 : : SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
2091 : : pAccImpl, SwAccessibleChild(pFrm),
2092 : : ( bFrom
2093 : : ? ACC_STATE_RELATION_FROM
2094 [ # # ][ # # ]: 0 : : ACC_STATE_RELATION_TO ) );
[ # # ]
2095 [ # # ][ # # ]: 0 : AppendEvent( aEvent );
2096 : : }
2097 : : else
2098 : : {
2099 [ # # ]: 0 : FireEvents();
2100 : : pAccImpl->InvalidateRelation( bFrom
2101 : : ? AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
2102 [ # # ][ # # ]: 0 : : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
2103 : : }
2104 : 0 : }
2105 : : }
2106 : 0 : }
2107 : :
2108 : 0 : void SwAccessibleMap::InvalidateRelationSet( const SwFrm* pMaster,
2109 : : const SwFrm* pFollow )
2110 : : {
2111 : 0 : _InvalidateRelationSet( pMaster, sal_False );
2112 : 0 : _InvalidateRelationSet( pFollow, sal_True );
2113 : 0 : }
2114 : :
2115 : : // invalidation of CONTENT_FLOW_FROM/_TO relation of a paragraph
2116 : 0 : void SwAccessibleMap::InvalidateParaFlowRelation( const SwTxtFrm& _rTxtFrm,
2117 : : const bool _bFrom )
2118 : : {
2119 : 0 : _InvalidateRelationSet( &_rTxtFrm, _bFrom );
2120 : 0 : }
2121 : :
2122 : : // invalidation of text selection of a paragraph
2123 : 0 : void SwAccessibleMap::InvalidateParaTextSelection( const SwTxtFrm& _rTxtFrm )
2124 : : {
2125 : : // first, see if this frame is accessible, and if so, get the respective
2126 [ # # ]: 0 : SwAccessibleChild aFrmOrObj( &_rTxtFrm );
2127 [ # # ][ # # ]: 0 : if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2128 : : {
2129 : 0 : uno::Reference < XAccessible > xAcc;
2130 : : {
2131 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
2132 : :
2133 [ # # ]: 0 : if( mpFrmMap )
2134 : : {
2135 : : SwAccessibleContextMap_Impl::iterator aIter =
2136 [ # # ][ # # ]: 0 : mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2137 [ # # ]: 0 : if( aIter != mpFrmMap->end() )
2138 : : {
2139 [ # # ][ # # ]: 0 : xAcc = (*aIter).second;
2140 : : }
2141 [ # # ]: 0 : }
2142 : : }
2143 : :
2144 : : // deliver event directly, or queue event
2145 [ # # ]: 0 : if( xAcc.is() )
2146 : : {
2147 : : SwAccessibleContext *pAccImpl =
2148 [ # # ][ # # ]: 0 : static_cast< SwAccessibleContext *>( xAcc.get() );
2149 [ # # ]: 0 : if( GetShell()->ActionPend() )
2150 : : {
2151 : : SwAccessibleEvent_Impl aEvent(
2152 : : SwAccessibleEvent_Impl::CARET_OR_STATES,
2153 : : pAccImpl,
2154 : : SwAccessibleChild( &_rTxtFrm ),
2155 [ # # ][ # # ]: 0 : ACC_STATE_TEXT_SELECTION_CHANGED );
2156 [ # # ][ # # ]: 0 : AppendEvent( aEvent );
2157 : : }
2158 : : else
2159 : : {
2160 [ # # ]: 0 : FireEvents();
2161 [ # # ]: 0 : pAccImpl->InvalidateTextSelection();
2162 : : }
2163 : 0 : }
2164 : : }
2165 : 0 : }
2166 : :
2167 : 0 : sal_Int32 SwAccessibleMap::GetChildIndex( const SwFrm& rParentFrm,
2168 : : Window& rChild ) const
2169 : : {
2170 : 0 : sal_Int32 nIndex( -1 );
2171 : :
2172 [ # # ]: 0 : SwAccessibleChild aFrmOrObj( &rParentFrm );
2173 [ # # ][ # # ]: 0 : if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2174 : : {
2175 : 0 : uno::Reference < XAccessible > xAcc;
2176 : : {
2177 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
2178 : :
2179 [ # # ]: 0 : if( mpFrmMap )
2180 : : {
2181 : : SwAccessibleContextMap_Impl::iterator aIter =
2182 [ # # ][ # # ]: 0 : mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2183 [ # # ]: 0 : if( aIter != mpFrmMap->end() )
2184 : : {
2185 [ # # ][ # # ]: 0 : xAcc = (*aIter).second;
2186 : : }
2187 [ # # ]: 0 : }
2188 : : }
2189 : :
2190 [ # # ]: 0 : if( xAcc.is() )
2191 : : {
2192 : : SwAccessibleContext *pAccImpl =
2193 [ # # ][ # # ]: 0 : static_cast< SwAccessibleContext *>( xAcc.get() );
2194 : :
2195 : : nIndex = pAccImpl->GetChildIndex( const_cast<SwAccessibleMap&>(*this),
2196 [ # # ][ # # ]: 0 : SwAccessibleChild( &rChild ) );
2197 : 0 : }
2198 : : }
2199 : :
2200 : 0 : return nIndex;
2201 : : }
2202 : :
2203 : 0 : void SwAccessibleMap::UpdatePreview( const std::vector<PrevwPage*>& _rPrevwPages,
2204 : : const Fraction& _rScale,
2205 : : const SwPageFrm* _pSelectedPageFrm,
2206 : : const Size& _rPrevwWinSize )
2207 : : {
2208 : : OSL_ENSURE( GetShell()->IsPreView(), "no preview?" );
2209 : : OSL_ENSURE( mpPreview != NULL, "no preview data?" );
2210 : :
2211 [ # # ]: 0 : mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize );
2212 : :
2213 : : // propagate change of VisArea through the document's
2214 : : // accessibility tree; this will also send appropriate scroll
2215 : : // events
2216 : : SwAccessibleContext* pDoc =
2217 [ # # ][ # # ]: 0 : GetContextImpl( GetShell()->GetLayout() ).get();
2218 [ # # ]: 0 : static_cast<SwAccessibleDocumentBase*>( pDoc )->SetVisArea();
2219 : :
2220 : 0 : uno::Reference < XAccessible > xOldAcc;
2221 : 0 : uno::Reference < XAccessible > xAcc;
2222 : : {
2223 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
2224 : :
2225 [ # # ][ # # ]: 0 : xOldAcc = mxCursorContext;
2226 : :
2227 : 0 : const SwPageFrm *pSelPage = mpPreview->GetSelPage();
2228 [ # # ][ # # ]: 0 : if( pSelPage && mpFrmMap )
2229 : : {
2230 : : SwAccessibleContextMap_Impl::iterator aIter =
2231 [ # # ]: 0 : mpFrmMap->find( pSelPage );
2232 [ # # ]: 0 : if( aIter != mpFrmMap->end() )
2233 [ # # ][ # # ]: 0 : xAcc = (*aIter).second;
2234 [ # # ]: 0 : }
2235 : : }
2236 : :
2237 [ # # ][ # # ]: 0 : if( xOldAcc.is() && xOldAcc != xAcc )
[ # # ][ # # ]
2238 [ # # ]: 0 : InvalidateCursorPosition( xOldAcc );
2239 [ # # ]: 0 : if( xAcc.is() )
2240 [ # # ]: 0 : InvalidateCursorPosition( xAcc );
2241 : 0 : }
2242 : :
2243 : 0 : void SwAccessibleMap::InvalidatePreViewSelection( sal_uInt16 nSelPage )
2244 : : {
2245 : : OSL_ENSURE( GetShell()->IsPreView(), "no preview?" );
2246 : : OSL_ENSURE( mpPreview != NULL, "no preview data?" );
2247 : :
2248 [ # # ][ # # ]: 0 : mpPreview->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage ) );
2249 : :
2250 : 0 : uno::Reference < XAccessible > xOldAcc;
2251 : 0 : uno::Reference < XAccessible > xAcc;
2252 : : {
2253 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
2254 : :
2255 [ # # ][ # # ]: 0 : xOldAcc = mxCursorContext;
2256 : :
2257 : 0 : const SwPageFrm *pSelPage = mpPreview->GetSelPage();
2258 [ # # ][ # # ]: 0 : if( pSelPage && mpFrmMap )
2259 : : {
2260 : : SwAccessibleContextMap_Impl::iterator aIter =
2261 [ # # ]: 0 : mpFrmMap->find( pSelPage );
2262 [ # # ]: 0 : if( aIter != mpFrmMap->end() )
2263 [ # # ][ # # ]: 0 : xAcc = (*aIter).second;
2264 [ # # ]: 0 : }
2265 : : }
2266 : :
2267 [ # # ][ # # ]: 0 : if( xOldAcc.is() && xOldAcc != xAcc )
[ # # ][ # # ]
2268 [ # # ]: 0 : InvalidateCursorPosition( xOldAcc );
2269 [ # # ]: 0 : if( xAcc.is() )
2270 [ # # ]: 0 : InvalidateCursorPosition( xAcc );
2271 : 0 : }
2272 : :
2273 : :
2274 : 0 : sal_Bool SwAccessibleMap::IsPageSelected( const SwPageFrm *pPageFrm ) const
2275 : : {
2276 [ # # ][ # # ]: 0 : return mpPreview && mpPreview->GetSelPage() == pPageFrm;
2277 : : }
2278 : :
2279 : :
2280 : 288 : void SwAccessibleMap::FireEvents()
2281 : : {
2282 : : {
2283 [ + - ]: 288 : osl::MutexGuard aGuard( maEventMutex );
2284 [ + + ]: 288 : if( mpEvents )
2285 : : {
2286 : 29 : mpEvents->SetFiring();
2287 : 29 : SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin();
2288 [ + + ]: 102 : while( aIter != mpEvents->end() )
2289 : : {
2290 [ + - ]: 73 : FireEvent( *aIter );
2291 : 73 : ++aIter;
2292 : : }
2293 : :
2294 [ + - ]: 29 : delete mpEventMap;
2295 : 29 : mpEventMap = 0;
2296 : :
2297 [ + - ]: 29 : delete mpEvents;
2298 : 29 : mpEvents = 0;
2299 [ + - ]: 288 : }
2300 : : }
2301 : : {
2302 [ + - ]: 288 : osl::MutexGuard aGuard( maMutex );
2303 [ - + ]: 288 : if( mpShapes )
2304 : : {
2305 [ # # ]: 0 : delete mpShapes;
2306 : 0 : mpShapes = 0;
2307 [ + - ]: 288 : }
2308 : : }
2309 : :
2310 : 288 : }
2311 : :
2312 : 0 : sal_Bool SwAccessibleMap::IsValid() const
2313 : : {
2314 : 0 : return sal_True;
2315 : : }
2316 : :
2317 : 0 : Rectangle SwAccessibleMap::GetVisibleArea() const
2318 : : {
2319 [ # # ]: 0 : MapMode aSrc( MAP_TWIP );
2320 [ # # ]: 0 : MapMode aDest( MAP_100TH_MM );
2321 [ # # ][ # # ]: 0 : return OutputDevice::LogicToLogic( GetVisArea().SVRect(), aSrc, aDest );
[ # # ][ # # ]
2322 : : }
2323 : :
2324 : : // Convert a MM100 value realtive to the document root into a pixel value
2325 : : // realtive to the screen!
2326 : 0 : Point SwAccessibleMap::LogicToPixel( const Point& rPoint ) const
2327 : : {
2328 [ # # ]: 0 : MapMode aSrc( MAP_100TH_MM );
2329 [ # # ]: 0 : MapMode aDest( MAP_TWIP );
2330 : :
2331 : 0 : Point aPoint = rPoint;
2332 : :
2333 [ # # ]: 0 : aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest );
2334 : 0 : Window *pWin = GetShell()->GetWin();
2335 [ # # ]: 0 : if( pWin )
2336 : : {
2337 [ # # ]: 0 : MapMode aMapMode;
2338 [ # # ]: 0 : GetMapMode( aPoint, aMapMode );
2339 [ # # ]: 0 : aPoint = pWin->LogicToPixel( aPoint, aMapMode );
2340 [ # # ][ # # ]: 0 : aPoint = pWin->OutputToAbsoluteScreenPixel( aPoint );
2341 : : }
2342 : :
2343 [ # # ][ # # ]: 0 : return aPoint;
2344 : : }
2345 : :
2346 : 0 : Size SwAccessibleMap::LogicToPixel( const Size& rSize ) const
2347 : : {
2348 [ # # ]: 0 : MapMode aSrc( MAP_100TH_MM );
2349 [ # # ]: 0 : MapMode aDest( MAP_TWIP );
2350 [ # # ]: 0 : Size aSize( OutputDevice::LogicToLogic( rSize, aSrc, aDest ) );
2351 [ # # ]: 0 : if( GetShell()->GetWin() )
2352 : : {
2353 [ # # ]: 0 : MapMode aMapMode;
2354 [ # # ]: 0 : GetMapMode( Point(0,0), aMapMode );
2355 [ # # ][ # # ]: 0 : aSize = GetShell()->GetWin()->LogicToPixel( aSize, aMapMode );
2356 : : }
2357 : :
2358 [ # # ][ # # ]: 0 : return aSize;
2359 : : }
2360 : :
2361 : 0 : Point SwAccessibleMap::PixelToLogic( const Point& rPoint ) const
2362 : : {
2363 : 0 : Point aPoint;
2364 : 0 : Window *pWin = GetShell()->GetWin();
2365 [ # # ]: 0 : if( pWin )
2366 : : {
2367 [ # # ]: 0 : aPoint = pWin->ScreenToOutputPixel( rPoint );
2368 [ # # ]: 0 : MapMode aMapMode;
2369 [ # # ]: 0 : GetMapMode( aPoint, aMapMode );
2370 [ # # ]: 0 : aPoint = pWin->PixelToLogic( aPoint, aMapMode );
2371 [ # # ]: 0 : MapMode aSrc( MAP_TWIP );
2372 [ # # ]: 0 : MapMode aDest( MAP_100TH_MM );
2373 [ # # ][ # # ]: 0 : aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest );
[ # # ][ # # ]
2374 : : }
2375 : :
2376 : 0 : return aPoint;
2377 : : }
2378 : :
2379 : 0 : Size SwAccessibleMap::PixelToLogic( const Size& rSize ) const
2380 : : {
2381 : 0 : Size aSize;
2382 [ # # ]: 0 : if( GetShell()->GetWin() )
2383 : : {
2384 [ # # ]: 0 : MapMode aMapMode;
2385 [ # # ]: 0 : GetMapMode( Point(0,0), aMapMode );
2386 [ # # ]: 0 : aSize = GetShell()->GetWin()->PixelToLogic( rSize, aMapMode );
2387 [ # # ]: 0 : MapMode aSrc( MAP_TWIP );
2388 [ # # ]: 0 : MapMode aDest( MAP_100TH_MM );
2389 [ # # ][ # # ]: 0 : aSize = OutputDevice::LogicToLogic( aSize, aSrc, aDest );
[ # # ][ # # ]
2390 : : }
2391 : :
2392 : 0 : return aSize;
2393 : : }
2394 : :
2395 : 0 : sal_Bool SwAccessibleMap::ReplaceChild (
2396 : : ::accessibility::AccessibleShape* pCurrentChild,
2397 : : const uno::Reference< drawing::XShape >& _rxShape,
2398 : : const long /*_nIndex*/,
2399 : : const ::accessibility::AccessibleShapeTreeInfo& /*_rShapeTreeInfo*/
2400 : : ) throw (uno::RuntimeException)
2401 : : {
2402 : 0 : const SdrObject *pObj = 0;
2403 : : {
2404 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
2405 [ # # ]: 0 : if( mpShapeMap )
2406 : : {
2407 : 0 : SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin();
2408 : 0 : SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end();
2409 [ # # ][ # # ]: 0 : while( aIter != aEndIter && !pObj )
[ # # ]
2410 : : {
2411 [ # # ]: 0 : uno::Reference < XAccessible > xAcc( (*aIter).second );
2412 : : ::accessibility::AccessibleShape *pAccShape =
2413 [ # # ][ # # ]: 0 : static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
2414 [ # # ]: 0 : if( pAccShape == pCurrentChild )
2415 : : {
2416 : 0 : pObj = (*aIter).first;
2417 : : }
2418 : 0 : ++aIter;
2419 : 0 : }
2420 [ # # ]: 0 : }
2421 : : }
2422 [ # # ]: 0 : if( !pObj )
2423 : 0 : return sal_False;
2424 : :
2425 : 0 : uno::Reference < drawing::XShape > xShape( _rxShape ); //keep reference to shape, because
2426 : : // we might be the only one that
2427 : : // hold it.
2428 : : // Also get keep parent.
2429 [ # # ]: 0 : uno::Reference < XAccessible > xParent( pCurrentChild->getAccessibleParent() );
2430 : 0 : pCurrentChild = 0; // well be realease by dispose
2431 [ # # ]: 0 : Dispose( 0, pObj, 0 );
2432 : :
2433 : : {
2434 [ # # ]: 0 : osl::MutexGuard aGuard( maMutex );
2435 : :
2436 [ # # ]: 0 : if( !mpShapeMap )
2437 [ # # ][ # # ]: 0 : mpShapeMap = new SwAccessibleShapeMap_Impl( this );
2438 : :
2439 : : // create the new child
2440 : : ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
2441 [ # # ]: 0 : ::accessibility::ShapeTypeHandler::Instance();
2442 : : ::accessibility::AccessibleShapeInfo aShapeInfo(
2443 [ # # ]: 0 : xShape, xParent, this );
2444 : : ::accessibility::AccessibleShape* pReplacement =
2445 : : rShapeTypeHandler.CreateAccessibleObject (
2446 [ # # ]: 0 : aShapeInfo, mpShapeMap->GetInfo() );
2447 : :
2448 [ # # ][ # # ]: 0 : uno::Reference < XAccessible > xAcc( pReplacement );
2449 [ # # ]: 0 : if( xAcc.is() )
2450 : : {
2451 [ # # ]: 0 : pReplacement->Init();
2452 : :
2453 : : SwAccessibleShapeMap_Impl::iterator aIter =
2454 [ # # ]: 0 : mpShapeMap->find( pObj );
2455 [ # # ]: 0 : if( aIter != mpShapeMap->end() )
2456 : : {
2457 [ # # ]: 0 : (*aIter).second = xAcc;
2458 : : }
2459 : : else
2460 : : {
2461 [ # # ]: 0 : SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAcc );
2462 [ # # ][ # # ]: 0 : mpShapeMap->insert( aEntry );
2463 : : }
2464 [ # # ][ # # ]: 0 : }
2465 : : }
2466 : :
2467 : 0 : SwRect aEmptyRect;
2468 [ # # ]: 0 : InvalidatePosOrSize( 0, pObj, 0, aEmptyRect );
2469 : :
2470 : 0 : return sal_True;
2471 : : }
2472 : :
2473 : 0 : Point SwAccessibleMap::PixelToCore( const Point& rPoint ) const
2474 : : {
2475 : 0 : Point aPoint;
2476 [ # # ]: 0 : if( GetShell()->GetWin() )
2477 : : {
2478 [ # # ]: 0 : MapMode aMapMode;
2479 [ # # ]: 0 : GetMapMode( rPoint, aMapMode );
2480 [ # # ][ # # ]: 0 : aPoint = GetShell()->GetWin()->PixelToLogic( rPoint, aMapMode );
2481 : : }
2482 : 0 : return aPoint;
2483 : : }
2484 : :
2485 : 23752 : static inline long lcl_CorrectCoarseValue(long aCoarseValue, long aFineValue,
2486 : : long aRefValue, bool bToLower)
2487 : : {
2488 : 23752 : long aResult = aCoarseValue;
2489 : :
2490 [ + + ]: 23752 : if (bToLower)
2491 : : {
2492 [ + + ]: 11876 : if (aFineValue < aRefValue)
2493 : 4490 : aResult -= 1;
2494 : : }
2495 : : else
2496 : : {
2497 [ + + ]: 11876 : if (aFineValue > aRefValue)
2498 : 368 : aResult += 1;
2499 : : }
2500 : :
2501 : 23752 : return aResult;
2502 : : }
2503 : :
2504 : 5938 : static inline void lcl_CorrectRectangle(Rectangle & rRect,
2505 : : const Rectangle & rSource,
2506 : : const Rectangle & rInGrid)
2507 : : {
2508 : : rRect.nLeft = lcl_CorrectCoarseValue(rRect.nLeft, rSource.nLeft,
2509 : 5938 : rInGrid.nLeft, false);
2510 : : rRect.nTop = lcl_CorrectCoarseValue(rRect.nTop, rSource.nTop,
2511 : 5938 : rInGrid.nTop, false);
2512 : : rRect.nRight = lcl_CorrectCoarseValue(rRect.nRight, rSource.nRight,
2513 : 5938 : rInGrid.nRight, true);
2514 : : rRect.nBottom = lcl_CorrectCoarseValue(rRect.nBottom, rSource.nBottom,
2515 : 5938 : rInGrid.nBottom, true);
2516 : 5938 : }
2517 : :
2518 : 5938 : Rectangle SwAccessibleMap::CoreToPixel( const Rectangle& rRect ) const
2519 : : {
2520 : 5938 : Rectangle aRect;
2521 [ + - ]: 5938 : if( GetShell()->GetWin() )
2522 : : {
2523 [ + - ]: 5938 : MapMode aMapMode;
2524 [ + - ]: 5938 : GetMapMode( rRect.TopLeft(), aMapMode );
2525 [ + - ]: 5938 : aRect = GetShell()->GetWin()->LogicToPixel( rRect, aMapMode );
2526 : :
2527 [ + - ]: 5938 : Rectangle aTmpRect = GetShell()->GetWin()->PixelToLogic( aRect, aMapMode );
2528 [ + - ]: 5938 : lcl_CorrectRectangle(aRect, rRect, aTmpRect);
2529 : : }
2530 : :
2531 : 5938 : return aRect;
2532 : : }
2533 : :
2534 : : /** get mapping mode for LogicToPixel and PixelToLogic conversions
2535 : :
2536 : : Method returns mapping mode of current output device and adjusts it,
2537 : : if the shell is in page/print preview.
2538 : : Necessary, because <PreviewAdjust(..)> changes mapping mode at current
2539 : : output device for mapping logic document positions to page preview window
2540 : : positions and vice versa and doesn't take care to recover its changes.
2541 : : */
2542 : 5938 : void SwAccessibleMap::GetMapMode( const Point& _rPoint,
2543 : : MapMode& _orMapMode ) const
2544 : : {
2545 [ + - ]: 5938 : MapMode aMapMode = GetShell()->GetWin()->GetMapMode();
2546 [ - + ]: 5938 : if( GetShell()->IsPreView() )
2547 : : {
2548 : : OSL_ENSURE( mpPreview != NULL, "need preview data" );
2549 : :
2550 [ # # ]: 0 : mpPreview->AdjustMapMode( aMapMode, _rPoint );
2551 : : }
2552 [ + - ][ + - ]: 5938 : _orMapMode = aMapMode;
2553 : 5938 : }
2554 : :
2555 : 0 : Size SwAccessibleMap::GetPreViewPageSize( sal_uInt16 _nPrevwPageNum ) const
2556 : : {
2557 : : OSL_ENSURE( mpVSh->IsPreView(), "no page preview accessible." );
2558 : : OSL_ENSURE( mpVSh->IsPreView() && ( mpPreview != NULL ),
2559 : : "missing accessible preview data at page preview" );
2560 [ # # ][ # # ]: 0 : if ( mpVSh->IsPreView() && ( mpPreview != NULL ) )
[ # # ]
2561 : : {
2562 : 0 : return mpVSh->PagePreviewLayout()->GetPrevwPageSizeByPageNum( _nPrevwPageNum );
2563 : : }
2564 : : else
2565 : : {
2566 : 0 : return Size( 0, 0 );
2567 : : }
2568 : : }
2569 : :
2570 : : /** method to build up a new data structure of the accessible pararaphs,
2571 : : which have a selection
2572 : : Important note: method has to used inside a mutual exclusive section
2573 : : */
2574 : 142 : SwAccessibleSelectedParas_Impl* SwAccessibleMap::_BuildSelectedParas()
2575 : : {
2576 : : // no accessible contexts, no selection
2577 [ - + ]: 142 : if ( !mpFrmMap )
2578 : : {
2579 : 0 : return 0L;
2580 : : }
2581 : :
2582 : : // get cursor as an instance of its base class <SwPaM>
2583 : 142 : SwPaM* pCrsr( 0L );
2584 : : {
2585 [ - + ]: 142 : SwCrsrShell* pCrsrShell = dynamic_cast<SwCrsrShell*>(GetShell());
2586 [ + - ]: 142 : if ( pCrsrShell )
2587 : : {
2588 [ - + ]: 142 : SwFEShell* pFEShell = dynamic_cast<SwFEShell*>(pCrsrShell);
2589 [ + - + - : 426 : if ( !pFEShell ||
+ - ][ + - ]
2590 : 142 : ( !pFEShell->IsFrmSelected() &&
2591 : 142 : pFEShell->IsObjSelected() == 0 ) )
2592 : : {
2593 : : // get cursor without updating an existing table cursor.
2594 : 142 : pCrsr = pCrsrShell->GetCrsr( sal_False );
2595 : : }
2596 : : }
2597 : : }
2598 : : // no cursor, no selection
2599 [ - + ]: 142 : if ( !pCrsr )
2600 : : {
2601 : 0 : return 0L;
2602 : : }
2603 : :
2604 : 142 : SwAccessibleSelectedParas_Impl* pRetSelectedParas( 0L );
2605 : :
2606 : : // loop on all cursors
2607 : 142 : SwPaM* pRingStart = pCrsr;
2608 [ + + ]: 172 : do {
2609 : :
2610 : : // for a selection the cursor has to have a mark.
2611 : : // for savety reasons assure that point and mark are in text nodes
2612 [ + + + - : 264 : if ( pCrsr->HasMark() &&
+ - ][ + + ]
2613 : 46 : pCrsr->GetPoint()->nNode.GetNode().IsTxtNode() &&
2614 : 46 : pCrsr->GetMark()->nNode.GetNode().IsTxtNode() )
2615 : : {
2616 [ + - ]: 46 : SwPosition* pStartPos = pCrsr->Start();
2617 [ + - ]: 46 : SwPosition* pEndPos = pCrsr->End();
2618 : : // loop on all text nodes inside the selection
2619 [ + - ]: 46 : SwNodeIndex aIdx( pStartPos->nNode );
2620 [ + - ][ + + ]: 92 : for ( ; aIdx.GetIndex() <= pEndPos->nNode.GetIndex(); ++aIdx )
2621 : : {
2622 : 46 : SwTxtNode* pTxtNode( aIdx.GetNode().GetTxtNode() );
2623 [ + - ]: 46 : if ( pTxtNode )
2624 : : {
2625 : : // loop on all text frames registered at the text node.
2626 [ + - ]: 46 : SwIterator<SwTxtFrm,SwTxtNode> aIter( *pTxtNode );
2627 [ + - ][ + - ]: 92 : for( SwTxtFrm* pTxtFrm = aIter.First(); pTxtFrm; pTxtFrm = aIter.Next() )
[ + + ]
2628 : : {
2629 [ + - ]: 46 : uno::WeakReference < XAccessible > xWeakAcc;
2630 : : SwAccessibleContextMap_Impl::iterator aMapIter =
2631 [ + - ]: 46 : mpFrmMap->find( pTxtFrm );
2632 [ - + ]: 46 : if( aMapIter != mpFrmMap->end() )
2633 : : {
2634 [ # # ]: 0 : xWeakAcc = (*aMapIter).second;
2635 : : SwAccessibleParaSelection aDataEntry(
2636 : 0 : pTxtNode == &(pStartPos->nNode.GetNode())
2637 : 0 : ? pStartPos->nContent.GetIndex()
2638 : : : 0,
2639 : 0 : pTxtNode == &(pEndPos->nNode.GetNode())
2640 : 0 : ? pEndPos->nContent.GetIndex()
2641 [ # # ][ # # ]: 0 : : STRING_LEN );
[ # # ][ # # ]
2642 : : SwAccessibleSelectedParas_Impl::value_type
2643 [ # # ]: 0 : aEntry( xWeakAcc, aDataEntry );
2644 [ # # ]: 0 : if ( !pRetSelectedParas )
2645 : : {
2646 : : pRetSelectedParas =
2647 [ # # ][ # # ]: 0 : new SwAccessibleSelectedParas_Impl;
2648 : : }
2649 [ # # ][ # # ]: 0 : pRetSelectedParas->insert( aEntry );
2650 : : }
2651 [ + - ][ + - ]: 92 : }
2652 : : }
2653 [ + - ]: 46 : }
2654 : : }
2655 : :
2656 : : // prepare next turn: get next cursor in ring
2657 : 172 : pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
2658 : : } while ( pCrsr != pRingStart );
2659 : :
2660 : 142 : return pRetSelectedParas;
2661 : : }
2662 : :
2663 : 142 : void SwAccessibleMap::InvalidateTextSelectionOfAllParas()
2664 : : {
2665 [ + - ]: 142 : osl::MutexGuard aGuard( maMutex );
2666 : :
2667 : : // keep previously known selected paragraphs
2668 : 142 : SwAccessibleSelectedParas_Impl* pPrevSelectedParas( mpSelectedParas );
2669 : :
2670 : : // determine currently selected paragraphs
2671 [ + - ]: 142 : mpSelectedParas = _BuildSelectedParas();
2672 : :
2673 : : // compare currently selected paragraphs with the previously selected
2674 : : // paragraphs and submit corresponding TEXT_SELECTION_CHANGED events.
2675 : : // first, search for new and changed selections.
2676 : : // on the run remove selections from previously known ones, if they are
2677 : : // also in the current ones.
2678 [ - + ]: 142 : if ( mpSelectedParas )
2679 : : {
2680 : 0 : SwAccessibleSelectedParas_Impl::iterator aIter = mpSelectedParas->begin();
2681 [ # # ]: 0 : for ( ; aIter != mpSelectedParas->end(); ++aIter )
2682 : : {
2683 : 0 : bool bSubmitEvent( false );
2684 [ # # ]: 0 : if ( !pPrevSelectedParas )
2685 : : {
2686 : : // new selection
2687 : 0 : bSubmitEvent = true;
2688 : : }
2689 : : else
2690 : : {
2691 : : SwAccessibleSelectedParas_Impl::iterator aPrevSelected =
2692 [ # # ]: 0 : pPrevSelectedParas->find( (*aIter).first );
2693 [ # # ]: 0 : if ( aPrevSelected != pPrevSelectedParas->end() )
2694 : : {
2695 : : // check, if selection has changed
2696 [ # # # # ]: 0 : if ( (*aIter).second.nStartOfSelection !=
[ # # ]
2697 : 0 : (*aPrevSelected).second.nStartOfSelection ||
2698 : 0 : (*aIter).second.nEndOfSelection !=
2699 : 0 : (*aPrevSelected).second.nEndOfSelection )
2700 : : {
2701 : : // changed selection
2702 : 0 : bSubmitEvent = true;
2703 : : }
2704 [ # # ]: 0 : pPrevSelectedParas->erase( aPrevSelected );
2705 : : }
2706 : : else
2707 : : {
2708 : : // new selection
2709 : 0 : bSubmitEvent = true;
2710 : : }
2711 : : }
2712 : :
2713 [ # # ]: 0 : if ( bSubmitEvent )
2714 : : {
2715 [ # # ]: 0 : uno::Reference < XAccessible > xAcc( (*aIter).first );
2716 [ # # ]: 0 : if ( xAcc.is() )
2717 : : {
2718 : : ::rtl::Reference < SwAccessibleContext > xAccImpl(
2719 [ # # ][ # # ]: 0 : static_cast<SwAccessibleContext*>( xAcc.get() ) );
2720 [ # # ][ # # ]: 0 : if ( xAccImpl.is() && xAccImpl->GetFrm() )
[ # # ]
2721 : : {
2722 : : const SwTxtFrm* pTxtFrm(
2723 [ # # ]: 0 : dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) );
2724 : : OSL_ENSURE( pTxtFrm,
2725 : : "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
2726 [ # # ]: 0 : if ( pTxtFrm )
2727 : : {
2728 [ # # ]: 0 : InvalidateParaTextSelection( *pTxtFrm );
2729 : : }
2730 : 0 : }
2731 : 0 : }
2732 : : }
2733 : : }
2734 : : }
2735 : :
2736 : : // second, handle previous selections - after the first step the data
2737 : : // structure of the previously known only contains the 'old' selections
2738 [ - + ]: 142 : if ( pPrevSelectedParas )
2739 : : {
2740 : 0 : SwAccessibleSelectedParas_Impl::iterator aIter = pPrevSelectedParas->begin();
2741 [ # # ]: 0 : for ( ; aIter != pPrevSelectedParas->end(); ++aIter )
2742 : : {
2743 [ # # ]: 0 : uno::Reference < XAccessible > xAcc( (*aIter).first );
2744 [ # # ]: 0 : if ( xAcc.is() )
2745 : : {
2746 : : ::rtl::Reference < SwAccessibleContext > xAccImpl(
2747 [ # # ][ # # ]: 0 : static_cast<SwAccessibleContext*>( xAcc.get() ) );
2748 [ # # ][ # # ]: 0 : if ( xAccImpl.is() && xAccImpl->GetFrm() )
[ # # ]
2749 : : {
2750 : : const SwTxtFrm* pTxtFrm(
2751 [ # # ]: 0 : dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) );
2752 : : OSL_ENSURE( pTxtFrm,
2753 : : "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
2754 [ # # ]: 0 : if ( pTxtFrm )
2755 : : {
2756 [ # # ]: 0 : InvalidateParaTextSelection( *pTxtFrm );
2757 : : }
2758 : 0 : }
2759 : : }
2760 : 0 : }
2761 : :
2762 [ # # ]: 0 : delete pPrevSelectedParas;
2763 [ + - ]: 142 : }
2764 : 142 : }
2765 : :
2766 : 269 : const SwRect& SwAccessibleMap::GetVisArea() const
2767 : : {
2768 : : OSL_ENSURE( !GetShell()->IsPreView() || (mpPreview != NULL),
2769 : : "preview without preview data?" );
2770 : :
2771 : 269 : return GetShell()->IsPreView()
2772 : 0 : ? mpPreview->GetVisArea()
2773 [ - + ]: 269 : : GetShell()->VisArea();
2774 : : }
2775 : :
2776 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|