1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sw.hxx"
24
25 #include <vos/ref.hxx>
26 #include <cppuhelper/weakref.hxx>
27 #include <vcl/window.hxx>
28 #include <svx/svdmodel.hxx>
29 #include <svx/unomod.hxx>
30 #include <tools/debug.hxx>
31 #include <map>
32 #include <list>
33 #include <vector>
34 #include <accmap.hxx>
35 #include <acccontext.hxx>
36 #include <accdoc.hxx>
37 #include <accpreview.hxx>
38 #include <accpage.hxx>
39 #include <accpara.hxx>
40 #include <accheaderfooter.hxx>
41 #include <accfootnote.hxx>
42 #include <acctextframe.hxx>
43 #include <accgraphic.hxx>
44 #include <accembedded.hxx>
45 #include <acccell.hxx>
46 #include <acctable.hxx>
47 #include <fesh.hxx>
48 #include <rootfrm.hxx>
49 #include <txtfrm.hxx>
50 #include <hffrm.hxx>
51 #include <ftnfrm.hxx>
52 #include <cellfrm.hxx>
53 #include <tabfrm.hxx>
54 #include <pagefrm.hxx>
55 #include <flyfrm.hxx>
56 #include <ndtyp.hxx>
57 #include <IDocumentDrawModelAccess.hxx>
58 #include <svx/ShapeTypeHandler.hxx>
59 #include <vcl/svapp.hxx>
60 #include <svx/ShapeTypeHandler.hxx>
61 #include <svx/SvxShapeTypes.hxx>
62 #include <svx/svdpage.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 <com/sun/star/accessibility/AccessibleRole.hpp>
67 #include <cppuhelper/implbase1.hxx>
68 #include <pagepreviewlayout.hxx>
69 #include <dcontact.hxx>
70 #include <svx/unoapi.hxx>
71 #include <svx/svdmark.hxx>
72 #include <doc.hxx>
73 #include <pam.hxx>
74 #include <ndtxt.hxx>
75 #include <dflyobj.hxx>
76 #include <prevwpage.hxx>
77 #include <switerator.hxx>
78 #include <drawdoc.hxx>
79
80 using namespace ::com::sun::star;
81 using namespace ::com::sun::star::accessibility;
82 using ::rtl::OUString;
83 using namespace ::sw::access;
84
85 struct SwFrmFunc
86 {
operator ()SwFrmFunc87 sal_Bool operator()( const SwFrm * p1,
88 const SwFrm * p2) const
89 {
90 return p1 < p2;
91 }
92 };
93
94 typedef ::std::map < const SwFrm *, uno::WeakReference < XAccessible >, SwFrmFunc > _SwAccessibleContextMap_Impl;
95
96 class SwAccessibleContextMap_Impl: public _SwAccessibleContextMap_Impl
97 {
98 public:
99
100 #ifdef DBG_UTIL
101 sal_Bool mbLocked;
102 #endif
103
SwAccessibleContextMap_Impl()104 SwAccessibleContextMap_Impl()
105 #ifdef DBG_UTIL
106 : mbLocked( sal_False )
107 #endif
108 {}
109
110 };
111
112 //------------------------------------------------------------------------------
113 class SwDrawModellListener_Impl : public SfxListener,
114 public ::cppu::WeakImplHelper1< document::XEventBroadcaster >
115 {
116 mutable ::osl::Mutex maListenerMutex;
117 ::cppu::OInterfaceContainerHelper maEventListeners;
118 SdrModel *mpDrawModel;
119 protected:
120 virtual ~SwDrawModellListener_Impl();
121 public:
122
123 SwDrawModellListener_Impl( SdrModel *pDrawModel );
124
125
126 virtual void SAL_CALL addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException);
127 virtual void SAL_CALL removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException);
128
129 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
130 void Dispose();
131 };
132
SwDrawModellListener_Impl(SdrModel * pDrawModel)133 SwDrawModellListener_Impl::SwDrawModellListener_Impl( SdrModel *pDrawModel ) :
134 maEventListeners( maListenerMutex ),
135 mpDrawModel( pDrawModel )
136 {
137 StartListening( *mpDrawModel );
138 }
139
~SwDrawModellListener_Impl()140 SwDrawModellListener_Impl::~SwDrawModellListener_Impl()
141 {
142 EndListening( *mpDrawModel );
143 }
144
addEventListener(const uno::Reference<document::XEventListener> & xListener)145 void SAL_CALL SwDrawModellListener_Impl::addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException)
146 {
147 maEventListeners.addInterface( xListener );
148 }
149
removeEventListener(const uno::Reference<document::XEventListener> & xListener)150 void SAL_CALL SwDrawModellListener_Impl::removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException)
151 {
152 maEventListeners.removeInterface( xListener );
153 }
154
Notify(SfxBroadcaster &,const SfxHint & rHint)155 void SwDrawModellListener_Impl::Notify( SfxBroadcaster& /*rBC*/,
156 const SfxHint& rHint )
157 {
158 // do not broadcast notifications for writer fly frames, because there
159 // are no shapes that need to know about them.
160 // OD 01.07.2003 #110554# - correct condition in order not to broadcast
161 // notifications for writer fly frames.
162 // OD 01.07.2003 #110554# - do not broadcast notifications for plane
163 // <SdrObject>objects
164 const SdrHint *pSdrHint = PTR_CAST( SdrHint, &rHint );
165 if ( !pSdrHint ||
166 ( pSdrHint->GetObject() &&
167 ( pSdrHint->GetObject()->ISA(SwFlyDrawObj) ||
168 pSdrHint->GetObject()->ISA(SwVirtFlyDrawObj) ||
169 IS_TYPE(SdrObject,pSdrHint->GetObject()) ) ) )
170 {
171 return;
172 }
173
174 ASSERT( mpDrawModel, "draw model listener is disposed" );
175 if( !mpDrawModel )
176 return;
177
178 document::EventObject aEvent;
179 if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) )
180 return;
181
182 ::cppu::OInterfaceIteratorHelper aIter( maEventListeners );
183 while( aIter.hasMoreElements() )
184 {
185 uno::Reference < document::XEventListener > xListener( aIter.next(),
186 uno::UNO_QUERY );
187 try
188 {
189 xListener->notifyEvent( aEvent );
190 }
191 catch( uno::RuntimeException const & r )
192 {
193 (void)r;
194 #if OSL_DEBUG_LEVEL > 1
195 ByteString aError( "Runtime exception caught while notifying shape.:\n" );
196 aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
197 DBG_ERROR( aError.GetBuffer() );
198 #endif
199 }
200 }
201 }
202
Dispose()203 void SwDrawModellListener_Impl::Dispose()
204 {
205 mpDrawModel = 0;
206 }
207
208 //------------------------------------------------------------------------------
209 struct SwShapeFunc
210 {
operator ()SwShapeFunc211 sal_Bool operator()( const SdrObject * p1,
212 const SdrObject * p2) const
213 {
214 return p1 < p2;
215 }
216 };
217 typedef ::std::map < const SdrObject *, uno::WeakReference < XAccessible >, SwShapeFunc > _SwAccessibleShapeMap_Impl;
218 typedef ::std::pair < const SdrObject *, ::vos::ORef < ::accessibility::AccessibleShape > > SwAccessibleObjShape_Impl;
219
220 class SwAccessibleShapeMap_Impl: public _SwAccessibleShapeMap_Impl
221
222 {
223 ::accessibility::AccessibleShapeTreeInfo maInfo;
224
225 public:
226
227 #ifdef DBG_UTIL
228 sal_Bool mbLocked;
229 #endif
SwAccessibleShapeMap_Impl(SwAccessibleMap * pMap)230 SwAccessibleShapeMap_Impl( SwAccessibleMap *pMap )
231 #ifdef DBG_UTIL
232 : mbLocked( sal_False )
233 #endif
234 {
235 maInfo.SetSdrView( pMap->GetShell()->GetDrawView() );
236 maInfo.SetWindow( pMap->GetShell()->GetWin() );
237 maInfo.SetViewForwarder( pMap );
238 // --> OD 2005-08-08 #i52858# - method name changed
239 uno::Reference < document::XEventBroadcaster > xModelBroadcaster =
240 new SwDrawModellListener_Impl(
241 pMap->GetShell()->getIDocumentDrawModelAccess()->GetOrCreateDrawModel() );
242 // <--
243 maInfo.SetControllerBroadcaster( xModelBroadcaster );
244 }
245
246 ~SwAccessibleShapeMap_Impl();
247
GetInfo() const248 const ::accessibility::AccessibleShapeTreeInfo& GetInfo() const { return maInfo; }
249
250 SwAccessibleObjShape_Impl *Copy( size_t& rSize,
251 const SwFEShell *pFESh = 0,
252 SwAccessibleObjShape_Impl **pSelShape = 0 ) const;
253 };
254
~SwAccessibleShapeMap_Impl()255 SwAccessibleShapeMap_Impl::~SwAccessibleShapeMap_Impl()
256 {
257 uno::Reference < document::XEventBroadcaster > xBrd( maInfo.GetControllerBroadcaster() );
258 if( xBrd.is() )
259 static_cast < SwDrawModellListener_Impl * >( xBrd.get() )->Dispose();
260 }
261
262 SwAccessibleObjShape_Impl
Copy(size_t & rSize,const SwFEShell * pFESh,SwAccessibleObjShape_Impl ** pSelStart) const263 *SwAccessibleShapeMap_Impl::Copy(
264 size_t& rSize, const SwFEShell *pFESh,
265 SwAccessibleObjShape_Impl **pSelStart ) const
266 {
267 SwAccessibleObjShape_Impl *pShapes = 0;
268 SwAccessibleObjShape_Impl *pSelShape = 0;
269
270 sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
271 rSize = size();
272
273 if( rSize > 0 )
274 {
275 pShapes =
276 new SwAccessibleObjShape_Impl[rSize];
277
278 const_iterator aIter = begin();
279 const_iterator aEndIter = end();
280
281 SwAccessibleObjShape_Impl *pShape = pShapes;
282 pSelShape = &(pShapes[rSize]);
283 while( aIter != aEndIter )
284 {
285 const SdrObject *pObj = (*aIter).first;
286 uno::Reference < XAccessible > xAcc( (*aIter).second );
287 if( nSelShapes && pFESh &&pFESh->IsObjSelected( *pObj ) )
288 {
289 // selected objects are inserted from the back
290 --pSelShape;
291 pSelShape->first = pObj;
292 pSelShape->second =
293 static_cast < ::accessibility::AccessibleShape* >(
294 xAcc.get() );
295 --nSelShapes;
296 }
297 else
298 {
299 pShape->first = pObj;
300 pShape->second =
301 static_cast < ::accessibility::AccessibleShape* >(
302 xAcc.get() );
303 ++pShape;
304 }
305 ++aIter;
306 }
307 ASSERT( pSelShape == pShape, "copying shapes went wrong!" );
308 }
309
310 if( pSelStart )
311 *pSelStart = pSelShape;
312
313 return pShapes;
314 }
315
316 //------------------------------------------------------------------------------
317 struct SwAccessibleEvent_Impl
318 {
319 public:
320 enum EventType { CARET_OR_STATES,
321 INVALID_CONTENT,
322 POS_CHANGED,
323 CHILD_POS_CHANGED,
324 SHAPE_SELECTION,
325 DISPOSE,
326 INVALID_ATTR };
327
328 private:
329 SwRect maOldBox; // the old bounds for CHILD_POS_CHANGED
330 // and POS_CHANGED
331 uno::WeakReference < XAccessible > mxAcc; // The object that fires the event
332 SwAccessibleChild maFrmOrObj; // the child for CHILD_POS_CHANGED and
333 // the same as xAcc for any other
334 // event type
335 EventType meType; // The event type
336 // --> OD 2005-12-12 #i27301# - use new type definition for <mnStates>
337 tAccessibleStates mnStates; // check states or update caret pos
338 // <--
339
340 SwAccessibleEvent_Impl& operator==( const SwAccessibleEvent_Impl& );
341
342 public:
343 const SwFrm* mpParentFrm; // The object that fires the event
IsNoXaccParentFrmSwAccessibleEvent_Impl344 sal_Bool IsNoXaccParentFrm() const
345 {
346 return CHILD_POS_CHANGED == meType && mpParentFrm != 0;
347 }
GetxAccSwAccessibleEvent_Impl348 uno::WeakReference < XAccessible > GetxAcc() const { return mxAcc;}
349 public:
SwAccessibleEvent_ImplSwAccessibleEvent_Impl350 SwAccessibleEvent_Impl( EventType eT,
351 SwAccessibleContext *pA,
352 const SwAccessibleChild& rFrmOrObj )
353 : mxAcc( pA ),
354 maFrmOrObj( rFrmOrObj ),
355 meType( eT ),
356 mnStates( 0 ),
357 mpParentFrm( 0 )
358 {}
359
SwAccessibleEvent_ImplSwAccessibleEvent_Impl360 SwAccessibleEvent_Impl( EventType eT,
361 const SwAccessibleChild& rFrmOrObj )
362 : maFrmOrObj( rFrmOrObj ),
363 meType( eT ),
364 mnStates( 0 ),
365 mpParentFrm( 0 )
366 {
367 ASSERT( SwAccessibleEvent_Impl::DISPOSE == meType,
368 "wrong event constructor, DISPOSE only" );
369 }
370
SwAccessibleEvent_ImplSwAccessibleEvent_Impl371 SwAccessibleEvent_Impl( EventType eT )
372 : meType( eT ),
373 mnStates( 0 ),
374 mpParentFrm( 0 )
375 {
376 ASSERT( SwAccessibleEvent_Impl::SHAPE_SELECTION == meType,
377 "wrong event constructor, SHAPE_SELECTION only" );
378 }
379
SwAccessibleEvent_ImplSwAccessibleEvent_Impl380 SwAccessibleEvent_Impl( EventType eT,
381 SwAccessibleContext *pA,
382 const SwAccessibleChild& rFrmOrObj,
383 const SwRect& rR )
384 : maOldBox( rR ),
385 mxAcc( pA ),
386 maFrmOrObj( rFrmOrObj ),
387 meType( eT ),
388 mnStates( 0 ),
389 mpParentFrm( 0 )
390 {
391 ASSERT( SwAccessibleEvent_Impl::CHILD_POS_CHANGED == meType ||
392 SwAccessibleEvent_Impl::POS_CHANGED == meType,
393 "wrong event constructor, (CHILD_)POS_CHANGED only" );
394 }
395
396 // --> OD 2005-12-12 #i27301# - use new type definition for parameter <_nStates>
SwAccessibleEvent_ImplSwAccessibleEvent_Impl397 SwAccessibleEvent_Impl( EventType eT,
398 SwAccessibleContext *pA,
399 const SwAccessibleChild& rFrmOrObj,
400 const tAccessibleStates _nStates )
401 : mxAcc( pA ),
402 maFrmOrObj( rFrmOrObj ),
403 meType( eT ),
404 mnStates( _nStates ),
405 mpParentFrm( 0 )
406 {
407 ASSERT( SwAccessibleEvent_Impl::CARET_OR_STATES == meType,
408 "wrong event constructor, CARET_OR_STATES only" );
409 }
410
SwAccessibleEvent_ImplSwAccessibleEvent_Impl411 SwAccessibleEvent_Impl( EventType eT,
412 const SwFrm *pParentFrm,
413 const SwAccessibleChild& rFrmOrObj,
414 const SwRect& rR ) :
415 maOldBox( rR ),
416 maFrmOrObj( rFrmOrObj ),
417 meType( eT ),
418 mnStates( 0 ),
419 mpParentFrm( pParentFrm )
420 {
421 OSL_ENSURE( SwAccessibleEvent_Impl::CHILD_POS_CHANGED == meType,
422 "wrong event constructor, CHILD_POS_CHANGED only" );
423 }
424 // <SetType(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
SetTypeSwAccessibleEvent_Impl425 inline void SetType( EventType eT )
426 {
427 meType = eT;
428 }
GetTypeSwAccessibleEvent_Impl429 inline EventType GetType() const
430 {
431 return meType;
432 }
433
GetContextSwAccessibleEvent_Impl434 inline ::vos::ORef < SwAccessibleContext > GetContext() const
435 {
436 uno::Reference < XAccessible > xTmp( mxAcc );
437 ::vos::ORef < SwAccessibleContext > xAccImpl(
438 static_cast<SwAccessibleContext*>( xTmp.get() ) );
439
440 return xAccImpl;
441 }
442
GetOldBoxSwAccessibleEvent_Impl443 inline const SwRect& GetOldBox() const
444 {
445 return maOldBox;
446 }
447 // <SetOldBox(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
SetOldBoxSwAccessibleEvent_Impl448 inline void SetOldBox( const SwRect& rOldBox )
449 {
450 maOldBox = rOldBox;
451 }
452
GetFrmOrObjSwAccessibleEvent_Impl453 inline const SwAccessibleChild& GetFrmOrObj() const
454 {
455 return maFrmOrObj;
456 }
457
458 // <SetStates(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
459 // --> OD 2005-12-12 #i27301# - use new type definition for parameter <_nStates>
SetStatesSwAccessibleEvent_Impl460 inline void SetStates( tAccessibleStates _nStates )
461 {
462 mnStates |= _nStates;
463 }
464 // <--
465
IsUpdateCursorPosSwAccessibleEvent_Impl466 inline sal_Bool IsUpdateCursorPos() const
467 {
468 return (mnStates & ACC_STATE_CARET) != 0;
469 }
IsInvalidateStatesSwAccessibleEvent_Impl470 inline sal_Bool IsInvalidateStates() const
471 {
472 return (mnStates & ACC_STATE_MASK) != 0;
473 }
IsInvalidateRelationSwAccessibleEvent_Impl474 inline sal_Bool IsInvalidateRelation() const
475 {
476 return (mnStates & ACC_STATE_RELATION_MASK) != 0;
477 }
478 // --> OD 2005-12-12 #i27301# - new event TEXT_SELECTION_CHANGED
IsInvalidateTextSelectionSwAccessibleEvent_Impl479 inline sal_Bool IsInvalidateTextSelection() const
480 {
481 return ( mnStates & ACC_STATE_TEXT_SELECTION_CHANGED ) != 0;
482 }
483 // <--
484 // --> OD 2009-01-07 #i88069# - new event TEXT_ATTRIBUTE_CHANGED
IsInvalidateTextAttrsSwAccessibleEvent_Impl485 inline sal_Bool IsInvalidateTextAttrs() const
486 {
487 return ( mnStates & ACC_STATE_TEXT_ATTRIBUTE_CHANGED ) != 0;
488 }
489 // <--
490 // --> OD 2005-12-12 #i27301# - use new type definition <tAccessibleStates>
491 // for return value
GetStatesSwAccessibleEvent_Impl492 inline tAccessibleStates GetStates() const
493 {
494 return mnStates & ACC_STATE_MASK;
495 }
496 // <--
497 // --> OD 2005-12-12 #i27301# - use new type definition <tAccessibleStates>
498 // for return value
GetAllStatesSwAccessibleEvent_Impl499 inline tAccessibleStates GetAllStates() const
500 {
501 return mnStates;
502 }
503 // <--
504 };
505
506 //------------------------------------------------------------------------------
507 typedef ::std::list < SwAccessibleEvent_Impl > _SwAccessibleEventList_Impl;
508
509 class SwAccessibleEventList_Impl: public _SwAccessibleEventList_Impl
510 {
511 sal_Bool mbFiring;
512
513 public:
514
SwAccessibleEventList_Impl()515 SwAccessibleEventList_Impl()
516 : mbFiring( sal_False )
517 {}
518
SetFiring()519 inline void SetFiring()
520 {
521 mbFiring = sal_True;
522 }
IsFiring() const523 inline sal_Bool IsFiring() const
524 {
525 return mbFiring;
526 }
527 struct XAccisNULL
528 {
operator ()SwAccessibleEventList_Impl::XAccisNULL529 bool operator()(const SwAccessibleEvent_Impl& e)
530 {
531 return e.IsNoXaccParentFrm();
532 }
533 };
534 void MoveInvalidXAccToEnd();
535 };
536
MoveInvalidXAccToEnd()537 void SwAccessibleEventList_Impl::MoveInvalidXAccToEnd()
538 {
539 int nSize = size();
540 if (nSize < 2 )
541 {
542 return;
543 }
544 SwAccessibleEventList_Impl lstEvent;
545 iterator li = begin();
546 for ( ;li != end();)
547 {
548 SwAccessibleEvent_Impl e = *li;
549 if (e.IsNoXaccParentFrm())
550 {
551 iterator liNext = li;
552 ++liNext;
553 erase(li);
554 li = liNext;
555 lstEvent.insert(lstEvent.end(),e);
556 }
557 else
558 ++li;
559 }
560 OSL_ENSURE(size() + lstEvent.size() == nSize ,"");
561 insert(end(),lstEvent.begin(),lstEvent.end());
562 OSL_ENSURE(size() == nSize ,"");
563 }
564 //------------------------------------------------------------------------------
565 // The shape list is filled if an accessible shape is destroyed. It
566 // simply keeps a reference to the accessible shape's XShape. These
567 // references are destroyed within the EndAction when firing events,
568 // There are twp reason for this. First of all, a new accessible shape
569 // for the XShape might be created soon. It's then cheaper if the XShape
570 // still exists. The other reason are situations where an accessible shape
571 // is destroyed within an SwFrmFmt::Modify. In this case, destryoing
572 // the XShape at the same time (indirectly by destroying the accessible
573 // shape) leads to an assert, because a client of the Modify is destroyed
574 // within a Modify call.
575
576 typedef ::std::list < uno::Reference < drawing::XShape > > _SwShapeList_Impl;
577
578 class SwShapeList_Impl: public _SwShapeList_Impl
579 {
580 public:
581
SwShapeList_Impl()582 SwShapeList_Impl() {}
583 };
584
585
586 //------------------------------------------------------------------------------
587 struct SwAccessibleChildFunc
588 {
operator ()SwAccessibleChildFunc589 sal_Bool operator()( const SwAccessibleChild& r1,
590 const SwAccessibleChild& r2 ) const
591 {
592 const void *p1 = r1.GetSwFrm()
593 ? static_cast < const void * >( r1.GetSwFrm())
594 : ( r1.GetDrawObject()
595 ? static_cast < const void * >( r1.GetDrawObject() )
596 : static_cast < const void * >( r1.GetWindow() ) );
597 const void *p2 = r2.GetSwFrm()
598 ? static_cast < const void * >( r2.GetSwFrm())
599 : ( r2.GetDrawObject()
600 ? static_cast < const void * >( r2.GetDrawObject() )
601 : static_cast < const void * >( r2.GetWindow() ) );
602 return p1 < p2;
603 }
604 };
605 typedef ::std::map < SwAccessibleChild, SwAccessibleEventList_Impl::iterator,
606 SwAccessibleChildFunc > _SwAccessibleEventMap_Impl;
607
608 class SwAccessibleEventMap_Impl: public _SwAccessibleEventMap_Impl
609 {
610 };
611
612 //------------------------------------------------------------------------------
613 // --> OD 2005-12-13 #i27301# - map containing the accessible paragraph, which
614 // have a selection. Needed to keep this information to submit corresponding
615 // TEXT_SELECTION_CHANGED events.
616 struct SwAccessibleParaSelection
617 {
618 xub_StrLen nStartOfSelection;
619 xub_StrLen nEndOfSelection;
620
SwAccessibleParaSelectionSwAccessibleParaSelection621 SwAccessibleParaSelection( const xub_StrLen _nStartOfSelection,
622 const xub_StrLen _nEndOfSelection )
623 : nStartOfSelection( _nStartOfSelection ),
624 nEndOfSelection( _nEndOfSelection )
625 {}
626 };
627
628 struct SwXAccWeakRefComp
629 {
operator ()SwXAccWeakRefComp630 sal_Bool operator()( const uno::WeakReference<XAccessible>& _rXAccWeakRef1,
631 const uno::WeakReference<XAccessible>& _rXAccWeakRef2 ) const
632 {
633 return _rXAccWeakRef1.get() < _rXAccWeakRef2.get();
634 }
635 };
636
637 typedef ::std::map< uno::WeakReference < XAccessible >,
638 SwAccessibleParaSelection,
639 SwXAccWeakRefComp > _SwAccessibleSelectedParas_Impl;
640
641 class SwAccessibleSelectedParas_Impl: public _SwAccessibleSelectedParas_Impl
642 {};
643 // <--
644
645 // helper class that stores preview data
646 class SwAccPreviewData
647 {
648 typedef std::vector<Rectangle> Rectangles;
649 Rectangles maPreviewRects;
650 Rectangles maLogicRects;
651
652 SwRect maVisArea;
653 Fraction maScale;
654
655 const SwPageFrm *mpSelPage;
656
657 /** adjust logic page retangle to its visible part
658
659 OD 17.01.2003 #103492#
660
661 @author OD
662
663 @param _iorLogicPgSwRect
664 input/output parameter - reference to the logic page rectangle, which
665 has to be adjusted.
666
667 @param _rPrevwPgSwRect
668 input parameter - constant reference to the corresponding preview page
669 rectangle; needed to determine the visible part of the logic page rectangle.
670
671 @param _rPrevwWinSize
672 input parameter - constant reference to the preview window size in TWIP;
673 needed to determine the visible part of the logic page rectangle
674 */
675 void AdjustLogicPgRectToVisibleArea( SwRect& _iorLogicPgSwRect,
676 const SwRect& _rPrevwPgSwRect,
677 const Size& _rPrevwWinSize );
678
679 public:
680 SwAccPreviewData();
681 ~SwAccPreviewData();
682
683 // OD 14.01.2003 #103492# - complete re-factoring of method due to new
684 // page/print preview functionality.
685 void Update( const SwAccessibleMap& rAccMap,
686 const std::vector<PrevwPage*>& _rPrevwPages,
687 const Fraction& _rScale,
688 const SwPageFrm* _pSelectedPageFrm,
689 const Size& _rPrevwWinSize );
690
691 // OD 14.01.2003 #103492# - complete re-factoring of method due to new
692 // page/print preview functionality.
693 void InvalidateSelection( const SwPageFrm* _pSelectedPageFrm );
694
695 const SwRect& GetVisArea() const;
696
697 MapMode GetMapModeForPreview( ) const;
698
699 /** Adjust the MapMode so that the preview page appears at the
700 * proper position. rPoint identifies the page for which the
701 * MapMode should be adjusted. If bFromPreview is true, rPoint is
702 * a preview coordinate; else it's a document coordinate. */
703 // OD 17.01.2003 #103492# - delete unused 3rd parameter.
704 void AdjustMapMode( MapMode& rMapMode,
705 const Point& rPoint ) const;
706
GetSelPage() const707 inline const SwPageFrm *GetSelPage() const { return mpSelPage; }
708
709 void DisposePage(const SwPageFrm *pPageFrm );
710 };
711
SwAccPreviewData()712 SwAccPreviewData::SwAccPreviewData() :
713 mpSelPage( 0 )
714 {
715 }
716
~SwAccPreviewData()717 SwAccPreviewData::~SwAccPreviewData()
718 {
719 }
720
721 // OD 13.01.2003 #103492# - complete re-factoring of method due to new page/print
722 // preview functionality.
Update(const SwAccessibleMap & rAccMap,const std::vector<PrevwPage * > & _rPrevwPages,const Fraction & _rScale,const SwPageFrm * _pSelectedPageFrm,const Size & _rPrevwWinSize)723 void SwAccPreviewData::Update( const SwAccessibleMap& rAccMap,
724 const std::vector<PrevwPage*>& _rPrevwPages,
725 const Fraction& _rScale,
726 const SwPageFrm* _pSelectedPageFrm,
727 const Size& _rPrevwWinSize )
728 {
729 // store preview scaling, maximal preview page size and selected page
730 maScale = _rScale;
731 mpSelPage = _pSelectedPageFrm;
732
733 // prepare loop on preview pages
734 maPreviewRects.clear();
735 maLogicRects.clear();
736 SwAccessibleChild aPage;
737 maVisArea.Clear();
738
739 // loop on preview pages to calculate <maPreviewRects>, <maLogicRects> and
740 // <maVisArea>
741 for ( std::vector<PrevwPage*>::const_iterator aPageIter = _rPrevwPages.begin();
742 aPageIter != _rPrevwPages.end();
743 ++aPageIter )
744 {
745 aPage = (*aPageIter)->pPage;
746
747 // add preview page rectangle to <maPreviewRects>
748 Rectangle aPrevwPgRect( (*aPageIter)->aPrevwWinPos, (*aPageIter)->aPageSize );
749 maPreviewRects.push_back( aPrevwPgRect );
750
751 // add logic page rectangle to <maLogicRects>
752 SwRect aLogicPgSwRect( aPage.GetBox( rAccMap ) );
753 Rectangle aLogicPgRect( aLogicPgSwRect.SVRect() );
754 maLogicRects.push_back( aLogicPgRect );
755 // union visible area with visible part of logic page rectangle
756 if ( (*aPageIter)->bVisible )
757 {
758 if ( !(*aPageIter)->pPage->IsEmptyPage() )
759 {
760 AdjustLogicPgRectToVisibleArea( aLogicPgSwRect,
761 SwRect( aPrevwPgRect ),
762 _rPrevwWinSize );
763 }
764 if ( maVisArea.IsEmpty() )
765 maVisArea = aLogicPgSwRect;
766 else
767 maVisArea.Union( aLogicPgSwRect );
768 }
769 }
770 }
771
772 // OD 16.01.2003 #103492# - complete re-factoring of method due to new page/print
773 // preview functionality.
InvalidateSelection(const SwPageFrm * _pSelectedPageFrm)774 void SwAccPreviewData::InvalidateSelection( const SwPageFrm* _pSelectedPageFrm )
775 {
776 mpSelPage = _pSelectedPageFrm;
777 ASSERT( mpSelPage, "selected page not found" );
778 }
779
780 struct ContainsPredicate
781 {
782 const Point& mrPoint;
ContainsPredicateContainsPredicate783 ContainsPredicate( const Point& rPoint ) : mrPoint(rPoint) {}
operator ()ContainsPredicate784 bool operator() ( const Rectangle& rRect ) const
785 {
786 return rRect.IsInside( mrPoint ) ? true : false;
787 }
788 };
789
GetVisArea() const790 const SwRect& SwAccPreviewData::GetVisArea() const
791 {
792 return maVisArea;
793 }
794
AdjustMapMode(MapMode & rMapMode,const Point & rPoint) const795 void SwAccPreviewData::AdjustMapMode( MapMode& rMapMode,
796 const Point& rPoint ) const
797 {
798 // adjust scale
799 rMapMode.SetScaleX( maScale );
800 rMapMode.SetScaleY( maScale );
801
802 // find proper rectangle
803 Rectangles::const_iterator aBegin = maLogicRects.begin();
804 Rectangles::const_iterator aEnd = maLogicRects.end();
805 Rectangles::const_iterator aFound = ::std::find_if( aBegin, aEnd,
806 ContainsPredicate( rPoint ) );
807
808 if( aFound != aEnd )
809 {
810 // found! set new origin
811 Point aPoint = (maPreviewRects.begin() + (aFound - aBegin))->TopLeft();
812 aPoint -= (maLogicRects.begin() + (aFound-aBegin))->TopLeft();
813 rMapMode.SetOrigin( aPoint );
814 }
815 // else: don't adjust MapMode
816 }
817
DisposePage(const SwPageFrm * pPageFrm)818 void SwAccPreviewData::DisposePage(const SwPageFrm *pPageFrm )
819 {
820 if( mpSelPage == pPageFrm )
821 mpSelPage = 0;
822 }
823
824 /** adjust logic page retangle to its visible part
825
826 OD 17.01.2003 #103492#
827
828 @author OD
829 */
AdjustLogicPgRectToVisibleArea(SwRect & _iorLogicPgSwRect,const SwRect & _rPrevwPgSwRect,const Size & _rPrevwWinSize)830 void SwAccPreviewData::AdjustLogicPgRectToVisibleArea(
831 SwRect& _iorLogicPgSwRect,
832 const SwRect& _rPrevwPgSwRect,
833 const Size& _rPrevwWinSize )
834 {
835 // determine preview window rectangle
836 const SwRect aPrevwWinSwRect( Point( 0, 0 ), _rPrevwWinSize );
837 // calculate visible preview page rectangle
838 SwRect aVisPrevwPgSwRect( _rPrevwPgSwRect );
839 aVisPrevwPgSwRect.Intersection( aPrevwWinSwRect );
840 // adjust logic page rectangle
841 SwTwips nTmpDiff;
842 // left
843 nTmpDiff = aVisPrevwPgSwRect.Left() - _rPrevwPgSwRect.Left();
844 if ( nTmpDiff > 0 )
845 _iorLogicPgSwRect.Left( _iorLogicPgSwRect.Left() + nTmpDiff );
846 // top
847 nTmpDiff = aVisPrevwPgSwRect.Top() - _rPrevwPgSwRect.Top();
848 if ( nTmpDiff > 0 )
849 _iorLogicPgSwRect.Top( _iorLogicPgSwRect.Top() + nTmpDiff );
850 // right
851 nTmpDiff = _rPrevwPgSwRect.Right() - aVisPrevwPgSwRect.Right();
852 if ( nTmpDiff > 0 )
853 _iorLogicPgSwRect.Right( _iorLogicPgSwRect.Right() - nTmpDiff );
854 // bottom
855 nTmpDiff = _rPrevwPgSwRect.Bottom() - aVisPrevwPgSwRect.Bottom();
856 if ( nTmpDiff > 0 )
857 _iorLogicPgSwRect.Bottom( _iorLogicPgSwRect.Bottom() - nTmpDiff );
858 }
859
860 //------------------------------------------------------------------------------
AreInSameTable(const uno::Reference<XAccessible> & rAcc,const SwFrm * pFrm)861 static sal_Bool AreInSameTable( const uno::Reference< XAccessible >& rAcc,
862 const SwFrm *pFrm )
863 {
864 sal_Bool bRet = sal_False;
865
866 if( pFrm && pFrm->IsCellFrm() && rAcc.is() )
867 {
868 // Is it in the same table? We check that
869 // by comparing the last table frame in the
870 // follow chain, because that's cheaper than
871 // searching the first one.
872 SwAccessibleContext *pAccImpl =
873 static_cast< SwAccessibleContext *>( rAcc.get() );
874 if( pAccImpl->GetFrm()->IsCellFrm() )
875 {
876 const SwTabFrm *pTabFrm1 = pAccImpl->GetFrm()->FindTabFrm();
877 while( pTabFrm1->GetFollow() )
878 pTabFrm1 = pTabFrm1->GetFollow();
879
880 const SwTabFrm *pTabFrm2 = pFrm->FindTabFrm();
881 while( pTabFrm2->GetFollow() )
882 pTabFrm2 = pTabFrm2->GetFollow();
883
884 bRet = (pTabFrm1 == pTabFrm2);
885 }
886 }
887
888 return bRet;
889 }
890
FireEvent(const SwAccessibleEvent_Impl & rEvent)891 void SwAccessibleMap::FireEvent( const SwAccessibleEvent_Impl& rEvent )
892 {
893 ::vos::ORef < SwAccessibleContext > xAccImpl( rEvent.GetContext() );
894 if (!xAccImpl.isValid() && rEvent.mpParentFrm != 0 )
895 {
896 SwAccessibleContextMap_Impl::iterator aIter =
897 mpFrmMap->find( rEvent.mpParentFrm );
898 if( aIter != mpFrmMap->end() )
899 {
900 uno::Reference < XAccessible > xAcc( (*aIter).second );
901 if (xAcc.is())
902 {
903 uno::Reference < XAccessibleContext > xContext(xAcc,uno::UNO_QUERY);
904 if (xContext.is() && xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
905 {
906 xAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() );
907 }
908 }
909 }
910 }
911 if( SwAccessibleEvent_Impl::SHAPE_SELECTION == rEvent.GetType() )
912 {
913 DoInvalidateShapeSelection();
914 }
915 else if( xAccImpl.isValid() && xAccImpl->GetFrm() )
916 {
917 // --> OD 2009-01-07 #i88069#
918 if ( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE &&
919 rEvent.IsInvalidateTextAttrs() )
920 {
921 xAccImpl->InvalidateAttr();
922 }
923 // <--
924 switch( rEvent.GetType() )
925 {
926 case SwAccessibleEvent_Impl::INVALID_CONTENT:
927 xAccImpl->InvalidateContent();
928 break;
929 case SwAccessibleEvent_Impl::POS_CHANGED:
930 xAccImpl->InvalidatePosOrSize( rEvent.GetOldBox() );
931 break;
932 case SwAccessibleEvent_Impl::CHILD_POS_CHANGED:
933 xAccImpl->InvalidateChildPosOrSize( rEvent.GetFrmOrObj(),
934 rEvent.GetOldBox() );
935 break;
936 case SwAccessibleEvent_Impl::DISPOSE:
937 ASSERT( xAccImpl.isValid(),
938 "dispose event has been stored" );
939 break;
940 // --> OD 2009-01-06 #i88069#
941 case SwAccessibleEvent_Impl::INVALID_ATTR:
942 // nothing to do here - handled above
943 break;
944 // <--
945 default:
946 break;
947 }
948 if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
949 {
950 if( rEvent.IsUpdateCursorPos() )
951 xAccImpl->InvalidateCursorPos();
952 if( rEvent.IsInvalidateStates() )
953 xAccImpl->InvalidateStates( rEvent.GetStates() );
954 if( rEvent.IsInvalidateRelation() )
955 {
956 // --> OD 2005-12-01 #i27138#
957 // both events CONTENT_FLOWS_FROM_RELATION_CHANGED and
958 // CONTENT_FLOWS_TO_RELATION_CHANGED are possible
959 if ( rEvent.GetAllStates() & ACC_STATE_RELATION_FROM )
960 {
961 xAccImpl->InvalidateRelation(
962 AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED );
963 }
964 if ( rEvent.GetAllStates() & ACC_STATE_RELATION_TO )
965 {
966 xAccImpl->InvalidateRelation(
967 AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
968 }
969 // <--
970 }
971 // --> OD 2005-12-12 #i27301# - submit event TEXT_SELECTION_CHANGED
972 if ( rEvent.IsInvalidateTextSelection() )
973 {
974 xAccImpl->InvalidateTextSelection();
975 }
976 // <--
977 }
978 }
979 }
980
AppendEvent(const SwAccessibleEvent_Impl & rEvent)981 void SwAccessibleMap::AppendEvent( const SwAccessibleEvent_Impl& rEvent )
982 {
983 vos::OGuard aGuard( maEventMutex );
984
985 if( !mpEvents )
986 mpEvents = new SwAccessibleEventList_Impl;
987 if( !mpEventMap )
988 mpEventMap = new SwAccessibleEventMap_Impl;
989
990 if( mpEvents->IsFiring() )
991 {
992 // While events are fired new ones are generated. They have to be fired
993 // now. This does not work for DISPOSE events!
994 ASSERT( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
995 "dispose event while firing events" );
996 FireEvent( rEvent );
997 }
998 else
999 {
1000
1001 SwAccessibleEventMap_Impl::iterator aIter =
1002 mpEventMap->find( rEvent.GetFrmOrObj() );
1003 if( aIter != mpEventMap->end() )
1004 {
1005 SwAccessibleEvent_Impl aEvent( *(*aIter).second );
1006 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
1007 "dispose events should not be stored" );
1008 sal_Bool bAppendEvent = sal_True;
1009 switch( rEvent.GetType() )
1010 {
1011 case SwAccessibleEvent_Impl::CARET_OR_STATES:
1012 // A CARET_OR_STATES event is added to any other
1013 // event only. It is broadcasted after any other event, so the
1014 // event should be put to the back.
1015 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
1016 "invalid event combination" );
1017 aEvent.SetStates( rEvent.GetAllStates() );
1018 break;
1019 case SwAccessibleEvent_Impl::INVALID_CONTENT:
1020 // An INVALID_CONTENT event overwrites a CARET_OR_STATES
1021 // event (but keeps its flags) and it is contained in a
1022 // POS_CHANGED event.
1023 // Therefor, the event's type has to be adapted and the event
1024 // has to be put at the end.
1025 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
1026 "invalid event combination" );
1027 if( aEvent.GetType() == SwAccessibleEvent_Impl::CARET_OR_STATES )
1028 aEvent.SetType( SwAccessibleEvent_Impl::INVALID_CONTENT );
1029 break;
1030 case SwAccessibleEvent_Impl::POS_CHANGED:
1031 // A pos changed event overwrites CARET_STATES (keeping its
1032 // flags) as well as INVALID_CONTENT. The old box position
1033 // has to be stored however if the old event is not a
1034 // POS_CHANGED itself.
1035 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
1036 "invalid event combination" );
1037 if( aEvent.GetType() != SwAccessibleEvent_Impl::POS_CHANGED )
1038 aEvent.SetOldBox( rEvent.GetOldBox() );
1039 aEvent.SetType( SwAccessibleEvent_Impl::POS_CHANGED );
1040 break;
1041 case SwAccessibleEvent_Impl::CHILD_POS_CHANGED:
1042 // CHILD_POS_CHANGED events can only follow CHILD_POS_CHANGED
1043 // events. The only action that needs to be done again is
1044 // to put the old event to the back. The new one cannot be used,
1045 // because we are interested in the old frame bounds.
1046 ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
1047 "invalid event combination" );
1048 break;
1049 case SwAccessibleEvent_Impl::SHAPE_SELECTION:
1050 ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::SHAPE_SELECTION,
1051 "invalid event combination" );
1052 break;
1053 case SwAccessibleEvent_Impl::DISPOSE:
1054 // DISPOSE events overwrite all others. They are not stored
1055 // but executed immediately to avoid broadcasting of
1056 // defunctional objects. So what needs to be done here is to
1057 // remove all events for the frame in question.
1058 bAppendEvent = sal_False;
1059 break;
1060 // --> OD 2009-01-06 #i88069#
1061 case SwAccessibleEvent_Impl::INVALID_ATTR:
1062 ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR,
1063 "invalid event combination" );
1064 break;
1065 // <--
1066 }
1067 if( bAppendEvent )
1068 {
1069 mpEvents->erase( (*aIter).second );
1070 (*aIter).second = mpEvents->insert( mpEvents->end(), aEvent );
1071 }
1072 else
1073 {
1074 mpEvents->erase( (*aIter).second );
1075 mpEventMap->erase( aIter );
1076 }
1077 }
1078 else if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
1079 {
1080 SwAccessibleEventMap_Impl::value_type aEntry( rEvent.GetFrmOrObj(),
1081 mpEvents->insert( mpEvents->end(), rEvent ) );
1082 mpEventMap->insert( aEntry );
1083 }
1084 }
1085 }
1086
InvalidateCursorPosition(const uno::Reference<XAccessible> & rAcc)1087 void SwAccessibleMap::InvalidateCursorPosition(
1088 const uno::Reference< XAccessible >& rAcc )
1089 {
1090 SwAccessibleContext *pAccImpl =
1091 static_cast< SwAccessibleContext *>( rAcc.get() );
1092 ASSERT( pAccImpl, "no caret context" );
1093 ASSERT( pAccImpl->GetFrm(), "caret context is disposed" );
1094 if( GetShell()->ActionPend() )
1095 {
1096 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
1097 pAccImpl,
1098 SwAccessibleChild(pAccImpl->GetFrm()),
1099 ACC_STATE_CARET );
1100 AppendEvent( aEvent );
1101 }
1102 else
1103 {
1104 FireEvents();
1105 // While firing events the current frame might have
1106 // been disposed because it moved out of the vis area.
1107 // Setting the cursor for such frames is useless and even
1108 // causes asserts.
1109 if( pAccImpl->GetFrm() )
1110 pAccImpl->InvalidateCursorPos();
1111 }
1112 }
1113
InvalidateShapeSelection()1114 void SwAccessibleMap::InvalidateShapeSelection()
1115 {
1116 if( GetShell()->ActionPend() )
1117 {
1118 SwAccessibleEvent_Impl aEvent(
1119 SwAccessibleEvent_Impl::SHAPE_SELECTION );
1120 AppendEvent( aEvent );
1121 }
1122 else
1123 {
1124 FireEvents();
1125 DoInvalidateShapeSelection();
1126 }
1127 }
1128 //This method should implement the following functions:
1129 //1.find the shape objects and set the selected state.
1130 //2.find the Swframe objects and set the selected state.
1131 //3.find the paragraph objects and set the selected state.
InvalidateShapeInParaSelection()1132 void SwAccessibleMap::InvalidateShapeInParaSelection()
1133 {
1134 SwAccessibleObjShape_Impl *pShapes = 0;
1135 SwAccessibleObjShape_Impl *pSelShape = 0;
1136 size_t nShapes = 0;
1137
1138 const ViewShell *pVSh = GetShell();
1139 const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ?
1140 static_cast< const SwFEShell * >( pVSh ) : 0;
1141 SwPaM* pCrsr = pFESh ? pFESh->GetCrsr( sal_False /* ??? */ ) : NULL;
1142 //sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1143
1144 {
1145 vos::OGuard aGuard( maMutex );
1146 if( mpShapeMap )
1147 pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1148 }
1149
1150 sal_Bool bIsSelAll =IsDocumentSelAll();
1151
1152 if( mpShapeMap )
1153 {
1154 //Checked for shapes.
1155 _SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin();
1156 _SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end();
1157 ::vos::ORef< SwAccessibleContext > xParentAccImpl;
1158
1159 if( bIsSelAll)
1160 {
1161 while( aIter != aEndIter )
1162 {
1163 uno::Reference < XAccessible > xAcc( (*aIter).second );
1164 if( xAcc.is() )
1165 (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->SetState( AccessibleStateType::SELECTED );
1166
1167 ++aIter;
1168 }
1169 }
1170 else
1171 {
1172 while( aIter != aEndIter )
1173 {
1174 sal_Bool bChanged = sal_False;
1175 sal_Bool bMarked = sal_False;
1176 SwAccessibleChild pFrm( (*aIter).first );
1177
1178 const SwFrmFmt *pFrmFmt = (*aIter).first ? ::FindFrmFmt( (*aIter).first ) : 0;
1179 if( !pFrmFmt ) { ++aIter; continue; }
1180 const SwFmtAnchor& pAnchor = pFrmFmt->GetAnchor();
1181 const SwPosition *pPos = pAnchor.GetCntntAnchor();
1182
1183 if(pAnchor.GetAnchorId() == FLY_AT_PAGE)
1184 {
1185 uno::Reference < XAccessible > xAcc( (*aIter).second );
1186 if(xAcc.is())
1187 (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED );
1188
1189 ++aIter; continue;
1190 }
1191
1192 if( !pPos ) { ++aIter; continue; }
1193 if( pPos->nNode.GetNode().GetTxtNode() )
1194 {
1195 int pIndex = pPos->nContent.GetIndex();
1196 SwPaM* pTmpCrsr = pCrsr;
1197 if( pTmpCrsr != NULL )
1198 {
1199 const SwTxtNode* pNode = pPos->nNode.GetNode().GetTxtNode();
1200 sal_uLong nHere = pNode->GetIndex();
1201
1202 do
1203 {
1204 // ignore, if no mark
1205 if( pTmpCrsr->HasMark() )
1206 {
1207 bMarked = sal_True;
1208 // check whether nHere is 'inside' pCrsr
1209 SwPosition* pStart = pTmpCrsr->Start();
1210 sal_uLong nStartIndex = pStart->nNode.GetIndex();
1211 SwPosition* pEnd = pTmpCrsr->End();
1212 sal_uLong nEndIndex = pEnd->nNode.GetIndex();
1213 if( ( nHere >= nStartIndex ) && (nHere <= nEndIndex) )
1214 {
1215 if( pAnchor.GetAnchorId() == FLY_AS_CHAR )
1216 {
1217 if( ( (nHere == nStartIndex) && (pIndex >= pStart->nContent.GetIndex()) || (nHere > nStartIndex) )
1218 &&( (nHere == nEndIndex) && (pIndex < pEnd->nContent.GetIndex()) || (nHere < nEndIndex) ) )
1219 {
1220 uno::Reference < XAccessible > xAcc( (*aIter).second );
1221 if( xAcc.is() )
1222 bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->SetState( AccessibleStateType::SELECTED );
1223 }
1224 else
1225 {
1226 uno::Reference < XAccessible > xAcc( (*aIter).second );
1227 if( xAcc.is() )
1228 bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED );
1229 }
1230 }
1231 else if( pAnchor.GetAnchorId() == FLY_AT_PARA )
1232 {
1233 if( ((nHere > nStartIndex) || pStart->nContent.GetIndex() ==0 )
1234 && (nHere < nEndIndex ) )
1235 {
1236 uno::Reference < XAccessible > xAcc( (*aIter).second );
1237 if( xAcc.is() )
1238 bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->SetState( AccessibleStateType::SELECTED );
1239 }
1240 else
1241 {
1242 uno::Reference < XAccessible > xAcc( (*aIter).second );
1243 if(xAcc.is())
1244 bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED );
1245 }
1246 }
1247 }
1248 }
1249 // next PaM in ring
1250 pTmpCrsr = static_cast<SwPaM*>( pTmpCrsr->GetNext() );
1251 }
1252 while( pTmpCrsr != pCrsr );
1253 }
1254 if( !bMarked )
1255 {
1256 SwAccessibleObjShape_Impl *pShape = pShapes;
1257 size_t nNumShapes = nShapes;
1258 while( nNumShapes )
1259 {
1260 if( pShape < pSelShape && (pShape->first==(*aIter).first) )
1261 {
1262 uno::Reference < XAccessible > xAcc( (*aIter).second );
1263 if(xAcc.is())
1264 bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED );
1265 }
1266 --nNumShapes;
1267 ++pShape;
1268 }
1269 }
1270 }
1271 ++aIter;
1272 }//while( aIter != aEndIter )
1273 }//else
1274 }
1275
1276 //Checked for FlyFrm
1277 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin();
1278 while( aIter != mpFrmMap->end() )
1279 {
1280 const SwFrm *pFrm = (*aIter).first;
1281 if(pFrm->IsFlyFrm())
1282 {
1283 sal_Bool bFrmChanged = sal_False;
1284 uno::Reference < XAccessible > xAcc = (*aIter).second;
1285
1286 if(xAcc.is())
1287 {
1288 SwAccessibleFrameBase *pAccFrame = (static_cast< SwAccessibleFrameBase * >(xAcc.get()));
1289 bFrmChanged = pAccFrame->SetSelectedState( sal_True );
1290 if (bFrmChanged)
1291 {
1292 const SwFlyFrm *pFlyFrm = static_cast< const SwFlyFrm * >( pFrm );
1293 const SwFrmFmt *pFrmFmt = pFlyFrm->GetFmt();
1294 if (pFrmFmt)
1295 {
1296 const SwFmtAnchor& pAnchor = pFrmFmt->GetAnchor();
1297 if( pAnchor.GetAnchorId() == FLY_AS_CHAR )
1298 {
1299 uno::Reference< XAccessible > xAccParent = pAccFrame->getAccessibleParent();
1300 if (xAccParent.is())
1301 {
1302 uno::Reference< XAccessibleContext > xAccContext = xAccParent->getAccessibleContext();
1303 if(xAccContext.is() && xAccContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1304 {
1305 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xAccContext.get());
1306 if(pAccFrame->IsSeletedInDoc())
1307 {
1308 m_setParaAdd.insert(pAccPara);
1309 }
1310 else if(m_setParaAdd.count(pAccPara) == 0)
1311 {
1312 m_setParaRemove.insert(pAccPara);
1313 }
1314 }
1315 }
1316 }
1317 }
1318 }
1319 }
1320 }
1321 ++aIter;
1322 }
1323 typedef std::vector< SwAccessibleContext* > VEC_PARA;
1324 VEC_PARA vecAdd;
1325 VEC_PARA vecRemove;
1326 //Checked for Paras.
1327 SwPaM* pTmpCrsr = pCrsr;
1328 sal_Bool bMarkChanged = sal_False;
1329 SwAccessibleContextMap_Impl mapTemp;
1330 if( pTmpCrsr != NULL )
1331 {
1332 do
1333 {
1334 if( pTmpCrsr->HasMark() )
1335 {
1336 SwNodeIndex nStartIndex( pTmpCrsr->Start()->nNode );
1337 SwNodeIndex nEndIndex( pTmpCrsr->End()->nNode );
1338 while(nStartIndex <= nEndIndex)
1339 {
1340 SwFrm *pFrm = NULL;
1341 if(nStartIndex.GetNode().IsCntntNode())
1342 {
1343 SwCntntNode* pCNd = (SwCntntNode*)&(nStartIndex.GetNode());
1344 SwClientIter aClientIter( *pCNd );
1345 pFrm = (SwFrm*)aClientIter.First( TYPE(SwFrm));
1346 }
1347 else if( nStartIndex.GetNode().IsTableNode() )
1348 {
1349 SwTableNode * pTable= (SwTableNode *)&(nStartIndex.GetNode());
1350 SwFrmFmt* pFmt = const_cast<SwFrmFmt*>(pTable->GetTable().GetFrmFmt());
1351 SwClientIter aClientIter( *pFmt );
1352 pFrm = (SwFrm*)aClientIter.First( TYPE(SwFrm));
1353 }
1354
1355 if( pFrm && mpFrmMap)
1356 {
1357 aIter = mpFrmMap->find( pFrm );
1358 if( aIter != mpFrmMap->end() )
1359 {
1360 uno::Reference < XAccessible > xAcc = (*aIter).second;
1361 sal_Bool isChanged = sal_False;
1362 if( xAcc.is() )
1363 {
1364 isChanged = (static_cast< SwAccessibleContext * >(xAcc.get()))->SetSelectedState( sal_True );
1365 }
1366 if(!isChanged)
1367 {
1368 SwAccessibleContextMap_Impl::iterator aEraseIter = mpSeletedFrmMap->find( pFrm );
1369 if(aEraseIter != mpSeletedFrmMap->end())
1370 mpSeletedFrmMap->erase(aEraseIter);
1371 }
1372 else
1373 {
1374 bMarkChanged = sal_True;
1375 vecAdd.push_back(static_cast< SwAccessibleContext * >(xAcc.get()));
1376 }
1377
1378 mapTemp.insert( SwAccessibleContextMap_Impl::value_type( pFrm, xAcc ) );
1379 }
1380 }
1381 nStartIndex++;
1382 }
1383 }
1384 pTmpCrsr = static_cast<SwPaM*>( pTmpCrsr->GetNext() );
1385 }
1386 while( pTmpCrsr != pCrsr );
1387 }
1388 if( !mpSeletedFrmMap )
1389 mpSeletedFrmMap = new SwAccessibleContextMap_Impl;
1390 if( !mpSeletedFrmMap->empty() )
1391 {
1392 aIter = mpSeletedFrmMap->begin();
1393 while( aIter != mpSeletedFrmMap->end() )
1394 {
1395 uno::Reference < XAccessible > xAcc = (*aIter).second;
1396 if(xAcc.is())
1397 (static_cast< SwAccessibleContext * >(xAcc.get()))->SetSelectedState( sal_False );
1398 ++aIter;
1399 vecRemove.push_back(static_cast< SwAccessibleContext * >(xAcc.get()));
1400 }
1401 bMarkChanged = sal_True;
1402 mpSeletedFrmMap->clear();
1403 }
1404
1405 if( !mapTemp.empty() )
1406 {
1407 aIter = mapTemp.begin();
1408 while( aIter != mapTemp.end() )
1409 {
1410 mpSeletedFrmMap->insert( SwAccessibleContextMap_Impl::value_type( (*aIter).first, (*aIter).second ) );
1411 ++aIter;
1412 }
1413 mapTemp.clear();
1414 }
1415 if( bMarkChanged && mpFrmMap)
1416 {
1417 VEC_PARA::iterator vi = vecAdd.begin();
1418 for (; vi != vecAdd.end() ; ++vi)
1419 {
1420 AccessibleEventObject aEvent;
1421 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1422 SwAccessibleContext* pAccPara = *vi;
1423 if (pAccPara)
1424 {
1425 pAccPara->FireAccessibleEvent( aEvent );
1426 }
1427 }
1428 vi = vecRemove.begin();
1429 for (; vi != vecRemove.end() ; ++vi)
1430 {
1431 AccessibleEventObject aEvent;
1432 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
1433 SwAccessibleContext* pAccPara = *vi;
1434 if (pAccPara)
1435 {
1436 pAccPara->FireAccessibleEvent( aEvent );
1437 }
1438 }
1439 }
1440 }
1441
1442 //Marge with DoInvalidateShapeFocus
DoInvalidateShapeSelection(sal_Bool bInvalidateFocusMode)1443 void SwAccessibleMap::DoInvalidateShapeSelection(sal_Bool bInvalidateFocusMode /*=sal_False*/)
1444 {
1445 SwAccessibleObjShape_Impl *pShapes = 0;
1446 SwAccessibleObjShape_Impl *pSelShape = 0;
1447 size_t nShapes = 0;
1448
1449 const ViewShell *pVSh = GetShell();
1450 const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ?
1451 static_cast< const SwFEShell * >( pVSh ) : 0;
1452 sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1453
1454
1455 //when InvalidateFocus Call this function ,and the current selected shape count is not 1 ,
1456 //return
1457 if (bInvalidateFocusMode && nSelShapes != 1)
1458 {
1459 return;
1460 }
1461 {
1462 vos::OGuard aGuard( maMutex );
1463 if( mpShapeMap )
1464 pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1465 }
1466
1467 if( pShapes )
1468 {
1469 typedef std::vector< ::vos::ORef < ::accessibility::AccessibleShape > > VEC_SHAPE;
1470 VEC_SHAPE vecxShapeAdd;
1471 VEC_SHAPE vecxShapeRemove;
1472 int nCountSelectedShape=0;
1473
1474 Window *pWin = GetShell()->GetWin();
1475 sal_Bool bFocused = pWin && pWin->HasFocus();
1476 SwAccessibleObjShape_Impl *pShape = pShapes;
1477 int nShapeCount = nShapes;
1478 while( nShapeCount )
1479 {
1480 //if( pShape->second.isValid() )
1481 if (pShape->second.isValid() && IsInSameLevel(pShape->first, pFESh))
1482 {
1483 if( pShape < pSelShape )
1484 {
1485 if(pShape->second->ResetState( AccessibleStateType::SELECTED ))
1486 {
1487 vecxShapeRemove.push_back(pShape->second);
1488 }
1489 pShape->second->ResetState( AccessibleStateType::FOCUSED );
1490 }
1491 }
1492 --nShapeCount;
1493 ++pShape;
1494 }
1495
1496 VEC_SHAPE::iterator vi =vecxShapeRemove.begin();
1497 for (; vi != vecxShapeRemove.end(); ++vi)
1498 {
1499 ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr());
1500 if (pAccShape)
1501 {
1502 pAccShape->CommitChange(AccessibleEventId::SELECTION_CHANGED_REMOVE, uno::Any(), uno::Any());
1503 }
1504 }
1505
1506 pShape = pShapes;
1507 while( nShapes )
1508 {
1509 //if( pShape->second.isValid() )
1510 if (pShape->second.isValid() && IsInSameLevel(pShape->first, pFESh))
1511 {
1512 // IA2 - why?
1513 // sal_Bool bChanged;
1514 if( pShape >= pSelShape )
1515 {
1516 // IA2: first fire focus event
1517 // bChanged = pShape->second->SetState( AccessibleStateType::SELECTED );
1518
1519 //first fire focus event
1520 if( bFocused && 1 == nSelShapes )
1521 pShape->second->SetState( AccessibleStateType::FOCUSED );
1522 else
1523 pShape->second->ResetState( AccessibleStateType::FOCUSED );
1524
1525 if(pShape->second->SetState( AccessibleStateType::SELECTED ))
1526 {
1527 vecxShapeAdd.push_back(pShape->second);
1528 }
1529 ++nCountSelectedShape;
1530 }
1531 /* MT: This still was in DEV300m80, but was removed in IA2 CWS.
1532 Someone needs to check what should happen here, see original diff CWS oo31ia2 vs. OOO310M11
1533 else
1534 {
1535 bChanged =
1536 pShape->second->ResetState( AccessibleStateType::SELECTED );
1537 pShape->second->ResetState( AccessibleStateType::FOCUSED );
1538 }
1539 if( bChanged )
1540 {
1541 const SwFrm* pParent = SwAccessibleFrame::GetParent(
1542 SwAccessibleChild( pShape->first ),
1543 GetShell()->IsPreView() );
1544 aParents.push_back( pParent );
1545 }
1546 */
1547 }
1548
1549 --nShapes;
1550 ++pShape;
1551 }
1552
1553 const unsigned int SELECTION_WITH_NUM = 10;
1554 if (vecxShapeAdd.size() > SELECTION_WITH_NUM )
1555 {
1556 uno::Reference< XAccessible > xDoc = GetDocumentView( );
1557 SwAccessibleContext * pCont = static_cast<SwAccessibleContext *>(xDoc.get());
1558 if (pCont)
1559 {
1560 AccessibleEventObject aEvent;
1561 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN;
1562 pCont->FireAccessibleEvent(aEvent);
1563 }
1564 }
1565 else
1566 {
1567 short nEventID = AccessibleEventId::SELECTION_CHANGED_ADD;
1568 if (nCountSelectedShape <= 1 && vecxShapeAdd.size() == 1 )
1569 {
1570 nEventID = AccessibleEventId::SELECTION_CHANGED;
1571 }
1572 vi = vecxShapeAdd.begin();
1573 for (; vi != vecxShapeAdd.end(); ++vi)
1574 {
1575 ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr());
1576 if (pAccShape)
1577 {
1578 pAccShape->CommitChange(nEventID, uno::Any(), uno::Any());
1579 }
1580 }
1581 }
1582
1583 vi = vecxShapeAdd.begin();
1584 for (; vi != vecxShapeAdd.end(); ++vi)
1585 {
1586 ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr());
1587 if (pAccShape)
1588 {
1589 SdrObject *pObj = GetSdrObjectFromXShape(pAccShape->GetXShape());
1590 SwFrmFmt *pFrmFmt = pObj ? FindFrmFmt( pObj ) : NULL;
1591 if (pFrmFmt)
1592 {
1593 const SwFmtAnchor& pAnchor = pFrmFmt->GetAnchor();
1594 if( pAnchor.GetAnchorId() == FLY_AS_CHAR )
1595 {
1596 uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent();
1597 if (xPara.is())
1598 {
1599 uno::Reference< XAccessibleContext > xParaContext = xPara->getAccessibleContext();
1600 if (xParaContext.is() && xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1601 {
1602 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xPara.get());
1603 if (pAccPara)
1604 {
1605 m_setParaAdd.insert(pAccPara);
1606 }
1607 }
1608 }
1609 }
1610 }
1611 }
1612 }
1613 vi = vecxShapeRemove.begin();
1614 for (; vi != vecxShapeRemove.end(); ++vi)
1615 {
1616 ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr());
1617 if (pAccShape)
1618 {
1619 uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent();
1620 uno::Reference< XAccessibleContext > xParaContext = xPara->getAccessibleContext();
1621 if (xParaContext.is() && xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1622 {
1623 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xPara.get());
1624 if (m_setParaAdd.count(pAccPara) == 0 )
1625 {
1626 m_setParaRemove.insert(pAccPara);
1627 }
1628 }
1629 }
1630 }
1631 delete[] pShapes;
1632 }
1633 }
1634
1635 //Marge with DoInvalidateShapeSelection
1636 /*
1637 void SwAccessibleMap::DoInvalidateShapeFocus()
1638 {
1639 const ViewShell *pVSh = GetShell();
1640 const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ?
1641 static_cast< const SwFEShell * >( pVSh ) : 0;
1642 sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1643
1644 if( nSelShapes != 1 )
1645 return;
1646
1647 SwAccessibleObjShape_Impl *pShapes = 0;
1648 SwAccessibleObjShape_Impl *pSelShape = 0;
1649 size_t nShapes = 0;
1650
1651
1652 {
1653 vos::OGuard aGuard( maMutex );
1654 if( mpShapeMap )
1655 pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1656 }
1657
1658 if( pShapes )
1659 {
1660 Window *pWin = GetShell()->GetWin();
1661 sal_Bool bFocused = pWin && pWin->HasFocus();
1662 SwAccessibleObjShape_Impl *pShape = pShapes;
1663 while( nShapes )
1664 {
1665 if( pShape->second.isValid() )
1666 {
1667 if( bFocused && pShape >= pSelShape )
1668 pShape->second->SetState( AccessibleStateType::FOCUSED );
1669 else
1670 pShape->second->ResetState( AccessibleStateType::FOCUSED );
1671 }
1672
1673 --nShapes;
1674 ++pShape;
1675 }
1676
1677 delete[] pShapes;
1678 }
1679 }
1680 */
1681
SwAccessibleMap(ViewShell * pSh)1682 SwAccessibleMap::SwAccessibleMap( ViewShell *pSh ) :
1683 mpFrmMap( 0 ),
1684 mpShapeMap( 0 ),
1685 mpShapes( 0 ),
1686 mpEvents( 0 ),
1687 mpEventMap( 0 ),
1688 // --> OD 2005-12-13 #i27301#
1689 mpSelectedParas( 0 ),
1690 // <--
1691 mpVSh( pSh ),
1692 mpPreview( 0 ),
1693 mnPara( 1 ),
1694 mnFootnote( 1 ),
1695 mnEndnote( 1 ),
1696 mbShapeSelected( sal_False ),
1697 mpSeletedFrmMap(NULL)
1698 {
1699 pSh->GetLayout()->AddAccessibleShell();
1700 }
1701
~SwAccessibleMap()1702 SwAccessibleMap::~SwAccessibleMap()
1703 {
1704 uno::Reference < XAccessible > xAcc;
1705 {
1706 vos::OGuard aGuard( maMutex );
1707 if( mpFrmMap )
1708 {
1709 const SwRootFrm *pRootFrm = GetShell()->GetLayout();
1710 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm );
1711 if( aIter != mpFrmMap->end() )
1712 xAcc = (*aIter).second;
1713 if( !xAcc.is() )
1714 xAcc = new SwAccessibleDocument( this );
1715 }
1716 }
1717
1718 if(xAcc.is())
1719 {
1720 SwAccessibleDocument *pAcc =
1721 static_cast< SwAccessibleDocument * >( xAcc.get() );
1722 pAcc->Dispose( sal_True );
1723 }
1724 if( mpFrmMap )
1725 {
1726 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin();
1727 while( aIter != mpFrmMap->end() )
1728 {
1729 uno::Reference < XAccessible > xTmp = (*aIter).second;
1730 if( xTmp.is() )
1731 {
1732 SwAccessibleContext *pTmp = static_cast< SwAccessibleContext * >( xTmp.get() );
1733 pTmp->SetMap(NULL);
1734 }
1735 ++aIter;
1736 }
1737 }
1738 {
1739 vos::OGuard aGuard( maMutex );
1740 #ifdef DBG_UTIL
1741 ASSERT( !mpFrmMap || mpFrmMap->empty(),
1742 "Frame map should be empty after disposing the root frame" );
1743 if( mpFrmMap )
1744 {
1745 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin();
1746 while( aIter != mpFrmMap->end() )
1747 {
1748 uno::Reference < XAccessible > xTmp = (*aIter).second;
1749 if( xTmp.is() )
1750 {
1751 SwAccessibleContext *pTmp =
1752 static_cast< SwAccessibleContext * >( xTmp.get() );
1753 (void) pTmp;
1754 }
1755 ++aIter;
1756 }
1757 }
1758 ASSERT( !mpShapeMap || mpShapeMap->empty(),
1759 "Object map should be empty after disposing the root frame" );
1760 if( mpShapeMap )
1761 {
1762 SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->begin();
1763 while( aIter != mpShapeMap->end() )
1764 {
1765 uno::Reference < XAccessible > xTmp = (*aIter).second;
1766 if( xTmp.is() )
1767 {
1768 ::accessibility::AccessibleShape *pTmp =
1769 static_cast< ::accessibility::AccessibleShape* >( xTmp.get() );
1770 (void) pTmp;
1771 }
1772 ++aIter;
1773 }
1774 }
1775 #endif
1776 delete mpFrmMap;
1777 mpFrmMap = 0;
1778 delete mpShapeMap;
1779 mpShapeMap = 0;
1780 delete mpShapes;
1781 mpShapes = 0;
1782 // --> OD 2005-12-13 #i27301#
1783 delete mpSelectedParas;
1784 mpSelectedParas = 0;
1785 // <--
1786 }
1787
1788 delete mpPreview;
1789 mpPreview = NULL;
1790
1791 {
1792 vos::OGuard aGuard( maEventMutex );
1793 #ifdef DBG_UTIL
1794 ASSERT( !(mpEvents || mpEventMap), "pending events" );
1795 if( mpEvents )
1796 {
1797 SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin();
1798 while( aIter != mpEvents->end() )
1799 {
1800 ++aIter;
1801 }
1802 }
1803 if( mpEventMap )
1804 {
1805 SwAccessibleEventMap_Impl::iterator aIter = mpEventMap->begin();
1806 while( aIter != mpEventMap->end() )
1807 {
1808 ++aIter;
1809 }
1810 }
1811 #endif
1812 delete mpEventMap;
1813 mpEventMap = 0;
1814 delete mpEvents;
1815 mpEvents = 0;
1816 }
1817 mpVSh->GetLayout()->RemoveAccessibleShell();
1818 delete mpSeletedFrmMap;
1819 }
1820
_GetDocumentView(sal_Bool bPagePreview)1821 uno::Reference< XAccessible > SwAccessibleMap::_GetDocumentView(
1822 sal_Bool bPagePreview )
1823 {
1824 uno::Reference < XAccessible > xAcc;
1825 sal_Bool bSetVisArea = sal_False;
1826
1827 {
1828 vos::OGuard aGuard( maMutex );
1829
1830 if( !mpFrmMap )
1831 {
1832 mpFrmMap = new SwAccessibleContextMap_Impl;
1833 #ifdef DBG_UTIL
1834 mpFrmMap->mbLocked = sal_False;
1835 #endif
1836 }
1837
1838 #ifdef DBG_UTIL
1839 ASSERT( !mpFrmMap->mbLocked, "Map is locked" );
1840 mpFrmMap->mbLocked = sal_True;
1841 #endif
1842
1843 const SwRootFrm *pRootFrm = GetShell()->GetLayout();
1844 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm );
1845 if( aIter != mpFrmMap->end() )
1846 xAcc = (*aIter).second;
1847 if( xAcc.is() )
1848 {
1849 bSetVisArea = sal_True; // Set VisArea when map mutex is not
1850 // locked
1851 }
1852 else
1853 {
1854 if( bPagePreview )
1855 xAcc = new SwAccessiblePreview( this );
1856 else
1857 xAcc = new SwAccessibleDocument( this );
1858
1859 if( aIter != mpFrmMap->end() )
1860 {
1861 (*aIter).second = xAcc;
1862 }
1863 else
1864 {
1865 SwAccessibleContextMap_Impl::value_type aEntry( pRootFrm, xAcc );
1866 mpFrmMap->insert( aEntry );
1867 }
1868 }
1869
1870 #ifdef DBG_UTIL
1871 mpFrmMap->mbLocked = sal_False;
1872 #endif
1873 }
1874
1875 if( bSetVisArea )
1876 {
1877 SwAccessibleDocumentBase *pAcc =
1878 static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
1879 pAcc->SetVisArea();
1880 }
1881
1882 return xAcc;
1883 }
1884
GetDocumentView()1885 uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView( )
1886 {
1887 return _GetDocumentView( sal_False );
1888 }
1889
1890 // OD 14.01.2003 #103492# - complete re-factoring of method due to new page/print
1891 // preview functionality.
GetDocumentPreview(const std::vector<PrevwPage * > & _rPrevwPages,const Fraction & _rScale,const SwPageFrm * _pSelectedPageFrm,const Size & _rPrevwWinSize)1892 uno::Reference<XAccessible> SwAccessibleMap::GetDocumentPreview(
1893 const std::vector<PrevwPage*>& _rPrevwPages,
1894 const Fraction& _rScale,
1895 const SwPageFrm* _pSelectedPageFrm,
1896 const Size& _rPrevwWinSize )
1897 {
1898 // create & update preview data object
1899 if( mpPreview == NULL )
1900 mpPreview = new SwAccPreviewData();
1901 mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize );
1902
1903 uno::Reference<XAccessible> xAcc = _GetDocumentView( sal_True );
1904 return xAcc;
1905 }
1906
GetContext(const SwFrm * pFrm,sal_Bool bCreate)1907 uno::Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrm *pFrm,
1908 sal_Bool bCreate )
1909 {
1910 uno::Reference < XAccessible > xAcc;
1911 uno::Reference < XAccessible > xOldCursorAcc;
1912 sal_Bool bOldShapeSelected = sal_False;
1913
1914 {
1915 vos::OGuard aGuard( maMutex );
1916
1917 if( !mpFrmMap && bCreate )
1918 mpFrmMap = new SwAccessibleContextMap_Impl;
1919 if( mpFrmMap )
1920 {
1921 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pFrm );
1922 if( aIter != mpFrmMap->end() )
1923 xAcc = (*aIter).second;
1924
1925 if( !xAcc.is() && bCreate )
1926 {
1927 SwAccessibleContext *pAcc = 0;
1928 switch( pFrm->GetType() )
1929 {
1930 case FRM_TXT:
1931 mnPara++;
1932 pAcc = new SwAccessibleParagraph( *this,
1933 static_cast< const SwTxtFrm& >( *pFrm ) );
1934 break;
1935 case FRM_HEADER:
1936 pAcc = new SwAccessibleHeaderFooter( this,
1937 static_cast< const SwHeaderFrm *>( pFrm ) );
1938 break;
1939 case FRM_FOOTER:
1940 pAcc = new SwAccessibleHeaderFooter( this,
1941 static_cast< const SwFooterFrm *>( pFrm ) );
1942 break;
1943 case FRM_FTN:
1944 {
1945 const SwFtnFrm *pFtnFrm =
1946 static_cast < const SwFtnFrm * >( pFrm );
1947 sal_Bool bIsEndnote =
1948 SwAccessibleFootnote::IsEndnote( pFtnFrm );
1949 pAcc = new SwAccessibleFootnote( this, bIsEndnote,
1950 /*(bIsEndnote ? mnEndnote++ : mnFootnote++),*/
1951 pFtnFrm );
1952 }
1953 break;
1954 case FRM_FLY:
1955 {
1956 const SwFlyFrm *pFlyFrm =
1957 static_cast < const SwFlyFrm * >( pFrm );
1958 switch( SwAccessibleFrameBase::GetNodeType( pFlyFrm ) )
1959 {
1960 case ND_GRFNODE:
1961 pAcc = new SwAccessibleGraphic( this, pFlyFrm );
1962 break;
1963 case ND_OLENODE:
1964 pAcc = new SwAccessibleEmbeddedObject( this, pFlyFrm );
1965 break;
1966 default:
1967 pAcc = new SwAccessibleTextFrame( this, pFlyFrm );
1968 break;
1969 }
1970 }
1971 break;
1972 case FRM_CELL:
1973 pAcc = new SwAccessibleCell( this,
1974 static_cast< const SwCellFrm *>( pFrm ) );
1975 break;
1976 case FRM_TAB:
1977 pAcc = new SwAccessibleTable( this,
1978 static_cast< const SwTabFrm *>( pFrm ) );
1979 break;
1980 case FRM_PAGE:
1981 DBG_ASSERT( GetShell()->IsPreView(),
1982 "accessible page frames only in PagePreview" );
1983 pAcc = new SwAccessiblePage( this, pFrm );
1984 break;
1985 }
1986 xAcc = pAcc;
1987
1988 ASSERT( xAcc.is(), "unknown frame type" );
1989 if( xAcc.is() )
1990 {
1991 if( aIter != mpFrmMap->end() )
1992 {
1993 (*aIter).second = xAcc;
1994 }
1995 else
1996 {
1997 SwAccessibleContextMap_Impl::value_type aEntry( pFrm, xAcc );
1998 mpFrmMap->insert( aEntry );
1999 }
2000
2001 if( pAcc->HasCursor() &&
2002 !AreInSameTable( mxCursorContext, pFrm ) )
2003 {
2004 // If the new context has the focus, and if we know
2005 // another context that had the focus, then the focus
2006 // just moves from the old context to the new one. We
2007 // have to send a focus event and a caret event for
2008 // the old context then. We have to to that know,
2009 // because after we have left this method, anyone might
2010 // call getStates for the new context and will get a
2011 // focused state then. Sending the focus changes event
2012 // after that seems to be strange. However, we cannot
2013 // send a focus event fo the new context now, because
2014 // no one except us knows it. In any case, we remember
2015 // the new context as the one that has the focus
2016 // currently.
2017
2018 xOldCursorAcc = mxCursorContext;
2019 mxCursorContext = xAcc;
2020
2021 bOldShapeSelected = mbShapeSelected;
2022 mbShapeSelected = sal_False;
2023 }
2024 }
2025 }
2026 }
2027 }
2028
2029 // Invalidate focus for old object when map is not locked
2030 if( xOldCursorAcc.is() )
2031 InvalidateCursorPosition( xOldCursorAcc );
2032 if( bOldShapeSelected )
2033 InvalidateShapeSelection();
2034
2035 return xAcc;
2036 }
2037
GetContextImpl(const SwFrm * pFrm,sal_Bool bCreate)2038 ::vos::ORef < SwAccessibleContext > SwAccessibleMap::GetContextImpl(
2039 const SwFrm *pFrm,
2040 sal_Bool bCreate )
2041 {
2042 uno::Reference < XAccessible > xAcc( GetContext( pFrm, bCreate ) );
2043
2044 ::vos::ORef < SwAccessibleContext > xAccImpl(
2045 static_cast< SwAccessibleContext * >( xAcc.get() ) );
2046
2047 return xAccImpl;
2048 }
2049
GetContext(const SdrObject * pObj,SwAccessibleContext * pParentImpl,sal_Bool bCreate)2050 uno::Reference< XAccessible> SwAccessibleMap::GetContext(
2051 const SdrObject *pObj,
2052 SwAccessibleContext *pParentImpl,
2053 sal_Bool bCreate )
2054 {
2055 uno::Reference < XAccessible > xAcc;
2056 uno::Reference < XAccessible > xOldCursorAcc;
2057
2058 {
2059 vos::OGuard aGuard( maMutex );
2060
2061 if( !mpShapeMap && bCreate )
2062 mpShapeMap = new SwAccessibleShapeMap_Impl( this );
2063 if( mpShapeMap )
2064 {
2065 SwAccessibleShapeMap_Impl::iterator aIter =
2066 mpShapeMap->find( pObj );
2067 if( aIter != mpShapeMap->end() )
2068 xAcc = (*aIter).second;
2069
2070 if( !xAcc.is() && bCreate )
2071 {
2072 ::accessibility::AccessibleShape *pAcc = 0;
2073 uno::Reference < drawing::XShape > xShape(
2074 const_cast< SdrObject * >( pObj )->getUnoShape(),
2075 uno::UNO_QUERY );
2076 if( xShape.is() )
2077 {
2078 ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
2079 ::accessibility::ShapeTypeHandler::Instance();
2080 uno::Reference < XAccessible > xParent( pParentImpl );
2081 ::accessibility::AccessibleShapeInfo aShapeInfo(
2082 xShape, xParent, this );
2083
2084 pAcc = rShapeTypeHandler.CreateAccessibleObject(
2085 aShapeInfo, mpShapeMap->GetInfo() );
2086 }
2087 xAcc = pAcc;
2088
2089 ASSERT( xAcc.is(), "unknown shape type" );
2090 if( xAcc.is() )
2091 {
2092 pAcc->Init();
2093 if( aIter != mpShapeMap->end() )
2094 {
2095 (*aIter).second = xAcc;
2096 }
2097 else
2098 {
2099 SwAccessibleShapeMap_Impl::value_type aEntry( pObj,
2100 xAcc );
2101 mpShapeMap->insert( aEntry );
2102 }
2103 // TODO: focus!!!
2104 }
2105 if (xAcc.is())
2106 AddGroupContext(pObj, xAcc);
2107 }
2108 }
2109 }
2110
2111 // Invalidate focus for old object when map is not locked
2112 if( xOldCursorAcc.is() )
2113 InvalidateCursorPosition( xOldCursorAcc );
2114
2115 return xAcc;
2116 }
IsInSameLevel(const SdrObject * pObj,const SwFEShell * pFESh)2117 sal_Bool SwAccessibleMap::IsInSameLevel(const SdrObject* pObj, const SwFEShell* pFESh)
2118 {
2119 if (pFESh)
2120 return pFESh->IsObjSameLevelWithMarked(pObj);
2121 return sal_False;
2122 }
AddShapeContext(const SdrObject * pObj,uno::Reference<XAccessible> xAccShape)2123 void SwAccessibleMap::AddShapeContext(const SdrObject *pObj, uno::Reference < XAccessible > xAccShape)
2124 {
2125 vos::OGuard aGuard( maMutex );
2126
2127 if( mpShapeMap )
2128 {
2129 SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAccShape );
2130 mpShapeMap->insert( aEntry );
2131 }
2132
2133 }
2134
2135 //Added by yanjun for sym2_6407
RemoveGroupContext(const SdrObject * pParentObj,::com::sun::star::uno::Reference<::com::sun::star::accessibility::XAccessible> xAccParent)2136 void SwAccessibleMap::RemoveGroupContext(const SdrObject *pParentObj, ::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xAccParent)
2137 {
2138 vos::OGuard aGuard( maMutex );
2139 if (mpShapeMap && pParentObj && pParentObj->IsGroupObject() && xAccParent.is())
2140 {
2141 uno::Reference < XAccessibleContext > xContext = xAccParent->getAccessibleContext();
2142 if (xContext.is())
2143 {
2144 for (sal_Int32 i = 0; i < xContext->getAccessibleChildCount(); ++i)
2145 {
2146 uno::Reference < XAccessible > xChild = xContext->getAccessibleChild(i);
2147 if (xChild.is())
2148 {
2149 uno::Reference < XAccessibleContext > xChildContext = xChild->getAccessibleContext();
2150 if (xChildContext.is())
2151 {
2152 if (xChildContext->getAccessibleRole() == AccessibleRole::SHAPE)
2153 {
2154 ::accessibility::AccessibleShape* pAccShape = static_cast < ::accessibility::AccessibleShape* >( xChild.get());
2155 uno::Reference < drawing::XShape > xShape = pAccShape->GetXShape();
2156 if (xShape.is())
2157 {
2158 SdrObject* pObj = GetSdrObjectFromXShape(xShape);
2159 if (pObj)
2160 RemoveContext(pObj);
2161 }
2162 }
2163 }
2164 }
2165 }
2166 }
2167 }
2168 }
2169 //End
2170
2171
AddGroupContext(const SdrObject * pParentObj,uno::Reference<XAccessible> xAccParent)2172 void SwAccessibleMap::AddGroupContext(const SdrObject *pParentObj, uno::Reference < XAccessible > xAccParent)
2173 {
2174 vos::OGuard aGuard( maMutex );
2175 if( mpShapeMap )
2176 {
2177 //here get all the sub list.
2178 if (pParentObj->IsGroupObject())
2179 {
2180 if (xAccParent.is())
2181 {
2182 uno::Reference < XAccessibleContext > xContext = xAccParent->getAccessibleContext();
2183 if (xContext.is())
2184 {
2185 sal_Int32 nChildren = xContext->getAccessibleChildCount();
2186 for(sal_Int32 i = 0; i<nChildren; i++)
2187 {
2188 uno::Reference < XAccessible > xChild = xContext->getAccessibleChild(i);
2189 if (xChild.is())
2190 {
2191 uno::Reference < XAccessibleContext > xChildContext = xChild->getAccessibleContext();
2192 if (xChildContext.is())
2193 {
2194 short nRole = xChildContext->getAccessibleRole();
2195 if (nRole == AccessibleRole::SHAPE)
2196 {
2197 ::accessibility::AccessibleShape* pAccShape = static_cast < ::accessibility::AccessibleShape* >( xChild.get());
2198 uno::Reference < drawing::XShape > xShape = pAccShape->GetXShape();
2199 if (xShape.is())
2200 {
2201 SdrObject* pObj = GetSdrObjectFromXShape(xShape);
2202 AddShapeContext(pObj, xChild);
2203 AddGroupContext(pObj,xChild);
2204 }
2205 }
2206 }
2207 }
2208 }
2209 }
2210 }
2211 }
2212 }
2213 }
2214
GetContextImpl(const SdrObject * pObj,SwAccessibleContext * pParentImpl,sal_Bool bCreate)2215 ::vos::ORef < ::accessibility::AccessibleShape > SwAccessibleMap::GetContextImpl(
2216 const SdrObject *pObj,
2217 SwAccessibleContext *pParentImpl,
2218 sal_Bool bCreate )
2219 {
2220 uno::Reference < XAccessible > xAcc( GetContext( pObj, pParentImpl, bCreate ) );
2221
2222 ::vos::ORef < ::accessibility::AccessibleShape > xAccImpl(
2223 static_cast< ::accessibility::AccessibleShape* >( xAcc.get() ) );
2224
2225 return xAccImpl;
2226 }
2227
2228
RemoveContext(const SwFrm * pFrm)2229 void SwAccessibleMap::RemoveContext( const SwFrm *pFrm )
2230 {
2231 vos::OGuard aGuard( maMutex );
2232
2233 if( mpFrmMap )
2234 {
2235 SwAccessibleContextMap_Impl::iterator aIter =
2236 mpFrmMap->find( pFrm );
2237 if( aIter != mpFrmMap->end() )
2238 {
2239 mpFrmMap->erase( aIter );
2240
2241 // Remove reference to old caret object. Though mxCursorContext
2242 // is a weak reference and cleared automatically, clearing it
2243 // directly makes sure to not keep a defunctional object.
2244 uno::Reference < XAccessible > xOldAcc( mxCursorContext );
2245 if( xOldAcc.is() )
2246 {
2247 SwAccessibleContext *pOldAccImpl =
2248 static_cast< SwAccessibleContext *>( xOldAcc.get() );
2249 ASSERT( pOldAccImpl->GetFrm(), "old caret context is disposed" );
2250 if( pOldAccImpl->GetFrm() == pFrm )
2251 {
2252 xOldAcc.clear(); // get an empty ref
2253 mxCursorContext = xOldAcc;
2254 }
2255 }
2256
2257 if( mpFrmMap->empty() )
2258 {
2259 delete mpFrmMap;
2260 mpFrmMap = 0;
2261 }
2262 }
2263 }
2264 }
2265
RemoveContext(const SdrObject * pObj)2266 void SwAccessibleMap::RemoveContext( const SdrObject *pObj )
2267 {
2268 vos::OGuard aGuard( maMutex );
2269
2270 if( mpShapeMap )
2271 {
2272 SwAccessibleShapeMap_Impl::iterator aIter =
2273 mpShapeMap->find( pObj );
2274 if( aIter != mpShapeMap->end() )
2275 {
2276 uno::Reference < XAccessible > xAcc( (*aIter).second );
2277 mpShapeMap->erase( aIter );
2278 RemoveGroupContext(pObj, xAcc);
2279 // The shape selection flag is not cleared, but one might do
2280 // so but has to make sure that the removed context is the one
2281 // that is selected.
2282
2283 if( mpShapeMap && mpShapeMap->empty() )
2284 {
2285 delete mpShapeMap;
2286 mpShapeMap = 0;
2287 }
2288 }
2289 }
2290 }
2291
2292
Dispose(const SwFrm * pFrm,const SdrObject * pObj,Window * pWindow,sal_Bool bRecursive)2293 void SwAccessibleMap::Dispose( const SwFrm *pFrm,
2294 const SdrObject *pObj,
2295 Window* pWindow,
2296 sal_Bool bRecursive )
2297 {
2298 SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow );
2299
2300 // Indeed, the following assert checks the frame's accessible flag,
2301 // because that's the one that is evaluated in the layout. The frame
2302 // might not be accessible anyway. That's the case for cell frames that
2303 // contain further cells.
2304 ASSERT( !aFrmOrObj.GetSwFrm() || aFrmOrObj.GetSwFrm()->IsAccessibleFrm(),
2305 "non accessible frame should be disposed" );
2306
2307 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2308 {
2309 ::vos::ORef< SwAccessibleContext > xAccImpl;
2310 ::vos::ORef< SwAccessibleContext > xParentAccImpl;
2311 ::vos::ORef< ::accessibility::AccessibleShape > xShapeAccImpl;
2312 // get accessible context for frame
2313 {
2314 vos::OGuard aGuard( maMutex );
2315
2316 // First of all look for an accessible context for a frame
2317 if( aFrmOrObj.GetSwFrm() && mpFrmMap )
2318 {
2319 SwAccessibleContextMap_Impl::iterator aIter =
2320 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2321 if( aIter != mpFrmMap->end() )
2322 {
2323 uno::Reference < XAccessible > xAcc( (*aIter).second );
2324 xAccImpl =
2325 static_cast< SwAccessibleContext *>( xAcc.get() );
2326 }
2327 }
2328 if( !xAccImpl.isValid() && mpFrmMap )
2329 {
2330 // If there is none, look if the parent is accessible.
2331 const SwFrm *pParent =
2332 SwAccessibleFrame::GetParent( aFrmOrObj,
2333 GetShell()->IsPreView());
2334
2335 if( pParent )
2336 {
2337 SwAccessibleContextMap_Impl::iterator aIter =
2338 mpFrmMap->find( pParent );
2339 if( aIter != mpFrmMap->end() )
2340 {
2341 uno::Reference < XAccessible > xAcc( (*aIter).second );
2342 xParentAccImpl =
2343 static_cast< SwAccessibleContext *>( xAcc.get() );
2344 }
2345 }
2346 }
2347 if( !xParentAccImpl.isValid() && !aFrmOrObj.GetSwFrm() &&
2348 mpShapeMap )
2349 {
2350 SwAccessibleShapeMap_Impl::iterator aIter =
2351 mpShapeMap->find( aFrmOrObj.GetDrawObject() );
2352 if( aIter != mpShapeMap->end() )
2353 {
2354 uno::Reference < XAccessible > xAcc( (*aIter).second );
2355 xShapeAccImpl =
2356 static_cast< ::accessibility::AccessibleShape *>( xAcc.get() );
2357 }
2358 }
2359 if( pObj && GetShell()->ActionPend() &&
2360 (xParentAccImpl.isValid() || xShapeAccImpl.isValid()) )
2361 {
2362 // Keep a reference to the XShape to avoid that it
2363 // is deleted with a SwFrmFmt::Modify.
2364 uno::Reference < drawing::XShape > xShape(
2365 const_cast< SdrObject * >( pObj )->getUnoShape(),
2366 uno::UNO_QUERY );
2367 if( xShape.is() )
2368 {
2369 if( !mpShapes )
2370 mpShapes = new SwShapeList_Impl;
2371 mpShapes->push_back( xShape );
2372 }
2373 }
2374 }
2375
2376 // remove events stored for the frame
2377 {
2378 vos::OGuard aGuard( maEventMutex );
2379 if( mpEvents )
2380 {
2381 SwAccessibleEventMap_Impl::iterator aIter =
2382 mpEventMap->find( aFrmOrObj );
2383 if( aIter != mpEventMap->end() )
2384 {
2385 SwAccessibleEvent_Impl aEvent(
2386 SwAccessibleEvent_Impl::DISPOSE, aFrmOrObj );
2387 AppendEvent( aEvent );
2388 }
2389 }
2390 }
2391
2392 // If the frame is accessible and there is a context for it, dispose
2393 // the frame. If the frame is no context for it but disposing should
2394 // take place recursive, the frame's children have to be disposed
2395 // anyway, so we have to create the context then.
2396 if( xAccImpl.isValid() )
2397 {
2398 xAccImpl->Dispose( bRecursive );
2399 }
2400 else if( xParentAccImpl.isValid() )
2401 {
2402 // If the frame is a cell frame, the table must be notified.
2403 // If we are in an action, a table model change event will
2404 // be broadcasted at the end of the action to give the table
2405 // a chance to generate a single table change event.
2406
2407 xParentAccImpl->DisposeChild( aFrmOrObj, bRecursive );
2408 }
2409 else if( xShapeAccImpl.isValid() )
2410 {
2411 RemoveContext( aFrmOrObj.GetDrawObject() );
2412 xShapeAccImpl->dispose();
2413 }
2414
2415 if( mpPreview && pFrm && pFrm->IsPageFrm() )
2416 mpPreview->DisposePage( static_cast< const SwPageFrm *>( pFrm ) );
2417 }
2418 }
2419
InvalidatePosOrSize(const SwFrm * pFrm,const SdrObject * pObj,Window * pWindow,const SwRect & rOldBox)2420 void SwAccessibleMap::InvalidatePosOrSize( const SwFrm *pFrm,
2421 const SdrObject *pObj,
2422 Window* pWindow,
2423 const SwRect& rOldBox )
2424 {
2425 SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow );
2426 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2427 {
2428 ::vos::ORef< SwAccessibleContext > xAccImpl;
2429 ::vos::ORef< SwAccessibleContext > xParentAccImpl;
2430 const SwFrm *pParent =NULL;
2431 {
2432 vos::OGuard aGuard( maMutex );
2433
2434 if( mpFrmMap )
2435 {
2436 if( aFrmOrObj.GetSwFrm() )
2437 {
2438 SwAccessibleContextMap_Impl::iterator aIter =
2439 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2440 if( aIter != mpFrmMap->end() )
2441 {
2442 // If there is an accesible object already it is
2443 // notified directly.
2444 uno::Reference < XAccessible > xAcc( (*aIter).second );
2445 xAccImpl =
2446 static_cast< SwAccessibleContext *>( xAcc.get() );
2447 }
2448 }
2449 if( !xAccImpl.isValid() )
2450 {
2451 // Otherwise we look if the parent is accessible.
2452 // If not, there is nothing to do.
2453 pParent = SwAccessibleFrame::GetParent( aFrmOrObj,
2454 GetShell()->IsPreView());
2455
2456 if( pParent )
2457 {
2458 SwAccessibleContextMap_Impl::iterator aIter =
2459 mpFrmMap->find( pParent );
2460 if( aIter != mpFrmMap->end() )
2461 {
2462 uno::Reference < XAccessible > xAcc( (*aIter).second );
2463 xParentAccImpl =
2464 static_cast< SwAccessibleContext *>( xAcc.get() );
2465 }
2466 }
2467 }
2468 }
2469 }
2470
2471 if( xAccImpl.isValid() )
2472 {
2473 if( GetShell()->ActionPend() )
2474 {
2475 SwAccessibleEvent_Impl aEvent(
2476 SwAccessibleEvent_Impl::POS_CHANGED, xAccImpl.getBodyPtr(),
2477 aFrmOrObj, rOldBox );
2478 AppendEvent( aEvent );
2479 }
2480 else
2481 {
2482 FireEvents();
2483 xAccImpl->InvalidatePosOrSize( rOldBox );
2484 }
2485 }
2486 else if( xParentAccImpl.isValid() )
2487 {
2488 if( GetShell()->ActionPend() )
2489 {
2490 SwAccessibleEvent_Impl aEvent(
2491 SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
2492 xParentAccImpl.getBodyPtr(), aFrmOrObj, rOldBox );
2493 AppendEvent( aEvent );
2494 }
2495 else
2496 {
2497 FireEvents();
2498 xParentAccImpl->InvalidateChildPosOrSize( aFrmOrObj,
2499 rOldBox );
2500 }
2501 }
2502 else if(pParent)
2503 {
2504 /*
2505 For child graphic and it's parent paragraph,if split 2 graphic to 2 paragraph,
2506 will delete one graphic swfrm and new create 1 graphic swfrm ,
2507 then the new paragraph and the new graphic SwFrm will add .
2508 but when add graphic SwFrm ,the accessible of the new Paragraph is not created yet.
2509 so the new graphic accessible 'parent is NULL,
2510 so run here: save the parent's SwFrm not the accessible object parent,
2511 */
2512 sal_Bool bIsValidFrm = sal_False;
2513 sal_Bool bIsTxtParent = sal_False;
2514 if (aFrmOrObj.GetSwFrm())
2515 {
2516 int nType = pFrm->GetType();
2517 if ( FRM_FLY == nType )
2518 {
2519 bIsValidFrm =sal_True;
2520 }
2521 }
2522 else if(pObj)
2523 {
2524 int nType = pParent->GetType();
2525 if (FRM_TXT == nType)
2526 {
2527 bIsTxtParent =sal_True;
2528 }
2529 }
2530 // sal_Bool bIsVisibleChildrenOnly =aFrmOrObj.IsVisibleChildrenOnly() ;
2531 // sal_Bool bIsBoundAsChar =aFrmOrObj.IsBoundAsChar() ;//bIsVisibleChildrenOnly && bIsBoundAsChar &&
2532 if((bIsValidFrm || bIsTxtParent) )
2533 {
2534 if( GetShell()->ActionPend() )
2535 {
2536 SwAccessibleEvent_Impl aEvent(
2537 SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
2538 pParent, aFrmOrObj, rOldBox );
2539 AppendEvent( aEvent );
2540 }
2541 else
2542 {
2543 OSL_ENSURE(false,"");
2544 }
2545 }
2546 }
2547 }
2548 }
2549
InvalidateContent(const SwFrm * pFrm)2550 void SwAccessibleMap::InvalidateContent( const SwFrm *pFrm )
2551 {
2552 SwAccessibleChild aFrmOrObj( pFrm );
2553 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2554 {
2555 uno::Reference < XAccessible > xAcc;
2556 {
2557 vos::OGuard aGuard( maMutex );
2558
2559 if( mpFrmMap )
2560 {
2561 SwAccessibleContextMap_Impl::iterator aIter =
2562 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2563 if( aIter != mpFrmMap->end() )
2564 xAcc = (*aIter).second;
2565 }
2566 }
2567
2568 if( xAcc.is() )
2569 {
2570 SwAccessibleContext *pAccImpl =
2571 static_cast< SwAccessibleContext *>( xAcc.get() );
2572 if( GetShell()->ActionPend() )
2573 {
2574 SwAccessibleEvent_Impl aEvent(
2575 SwAccessibleEvent_Impl::INVALID_CONTENT, pAccImpl,
2576 aFrmOrObj );
2577 AppendEvent( aEvent );
2578 }
2579 else
2580 {
2581 FireEvents();
2582 pAccImpl->InvalidateContent();
2583 }
2584 }
2585 }
2586 }
2587
2588 // --> OD 2009-01-06 #i88069#
InvalidateAttr(const SwTxtFrm & rTxtFrm)2589 void SwAccessibleMap::InvalidateAttr( const SwTxtFrm& rTxtFrm )
2590 {
2591 SwAccessibleChild aFrmOrObj( &rTxtFrm );
2592 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2593 {
2594 uno::Reference < XAccessible > xAcc;
2595 {
2596 vos::OGuard aGuard( maMutex );
2597
2598 if( mpFrmMap )
2599 {
2600 SwAccessibleContextMap_Impl::iterator aIter =
2601 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2602 if( aIter != mpFrmMap->end() )
2603 xAcc = (*aIter).second;
2604 }
2605 }
2606
2607 if( xAcc.is() )
2608 {
2609 SwAccessibleContext *pAccImpl =
2610 static_cast< SwAccessibleContext *>( xAcc.get() );
2611 if( GetShell()->ActionPend() )
2612 {
2613 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::INVALID_ATTR,
2614 pAccImpl, aFrmOrObj );
2615 aEvent.SetStates( ACC_STATE_TEXT_ATTRIBUTE_CHANGED );
2616 AppendEvent( aEvent );
2617 }
2618 else
2619 {
2620 FireEvents();
2621 pAccImpl->InvalidateAttr();
2622 }
2623 }
2624 }
2625 }
2626 // <--
2627
InvalidateCursorPosition(const SwFrm * pFrm)2628 void SwAccessibleMap::InvalidateCursorPosition( const SwFrm *pFrm )
2629 {
2630 SwAccessibleChild aFrmOrObj( pFrm );
2631 sal_Bool bShapeSelected = sal_False;
2632 const ViewShell *pVSh = GetShell();
2633 if( pVSh->ISA( SwCrsrShell ) )
2634 {
2635 const SwCrsrShell *pCSh = static_cast< const SwCrsrShell * >( pVSh );
2636 if( pCSh->IsTableMode() )
2637 {
2638 while( aFrmOrObj.GetSwFrm() && !aFrmOrObj.GetSwFrm()->IsCellFrm() )
2639 aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper();
2640 }
2641 else if( pVSh->ISA( SwFEShell ) )
2642 {
2643 sal_uInt16 nObjCount;
2644 const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh );
2645 const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm();
2646 if( pFlyFrm )
2647 {
2648 ASSERT( !pFrm || pFrm->FindFlyFrm() == pFlyFrm,
2649 "cursor is not contained in fly frame" );
2650 aFrmOrObj = pFlyFrm;
2651 }
2652 else if( (nObjCount = pFESh->IsObjSelected()) > 0 )
2653 {
2654 bShapeSelected = sal_True;
2655 aFrmOrObj = static_cast<const SwFrm *>( 0 );
2656 }
2657 }
2658 }
2659
2660 ASSERT( bShapeSelected || aFrmOrObj.IsAccessible(GetShell()->IsPreView()),
2661 "frame is not accessible" );
2662
2663 uno::Reference < XAccessible > xOldAcc;
2664 uno::Reference < XAccessible > xAcc;
2665 sal_Bool bOldShapeSelected = sal_False;
2666
2667 {
2668 vos::OGuard aGuard( maMutex );
2669
2670 xOldAcc = mxCursorContext;
2671 mxCursorContext = xAcc; // clear reference
2672
2673 bOldShapeSelected = mbShapeSelected;
2674 mbShapeSelected = bShapeSelected;
2675
2676 if( aFrmOrObj.GetSwFrm() && mpFrmMap )
2677 {
2678 SwAccessibleContextMap_Impl::iterator aIter =
2679 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2680 if( aIter != mpFrmMap->end() )
2681 xAcc = (*aIter).second;
2682 else
2683 {
2684 SwRect rcEmpty;
2685 const SwTabFrm* pTabFrm = aFrmOrObj.GetSwFrm()->FindTabFrm();
2686 if (pTabFrm)
2687 {
2688 InvalidatePosOrSize(pTabFrm,0,0,rcEmpty);
2689 }
2690 else
2691 {
2692 InvalidatePosOrSize(aFrmOrObj.GetSwFrm(),0,0,rcEmpty);
2693 }
2694
2695
2696 aIter =
2697 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2698 if( aIter != mpFrmMap->end() )
2699 {
2700 xAcc = (*aIter).second;
2701 }
2702 }
2703
2704 // For cells, some extra thoughts are necessary,
2705 // because invalidating the cursor for one cell
2706 // invalidates the cursor for all cells of the same
2707 // table. For this reason, we don't want to
2708 // invalidate the cursor for the old cursor object
2709 // and the new one if they are within the same table,
2710 // because this would result in doing the work twice.
2711 // Moreover, we have to make sure to invalidate the
2712 // cursor even if the current cell has no accessible object.
2713 // If the old cursor objects exists and is in the same
2714 // table, its the best choice, because using it avoids
2715 // an unnessarary cursor invalidation cycle when creating
2716 // a new object for the current cell.
2717 if( aFrmOrObj.GetSwFrm()->IsCellFrm() )
2718 {
2719 if( xOldAcc.is() &&
2720 AreInSameTable( xOldAcc, aFrmOrObj.GetSwFrm() ) )
2721 {
2722 if( xAcc.is() )
2723 xOldAcc = xAcc; // avoid extra invalidation
2724 else
2725 xAcc = xOldAcc; // make sure ate least one
2726 }
2727 if( !xAcc.is() )
2728 xAcc = GetContext( aFrmOrObj.GetSwFrm(), sal_True );
2729 }
2730 }
2731 else if (bShapeSelected)
2732 {
2733 const SwFEShell *pFESh = pVSh ? static_cast< const SwFEShell * >( pVSh ) : NULL ;
2734 if(pFESh)
2735 {
2736 const SdrMarkList *pMarkList = pFESh->GetMarkList();
2737 if (pMarkList != NULL && pMarkList->GetMarkCount() == 1)
2738 {
2739 SdrObject *pObj = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
2740 ::vos::ORef < ::accessibility::AccessibleShape > pAccShapeImpl = GetContextImpl(pObj,NULL,sal_False);
2741 if (!pAccShapeImpl.isValid())
2742 {
2743 while (pObj && pObj->GetUpGroup())
2744 {
2745 pObj = pObj->GetUpGroup();
2746 }
2747 if (pObj != NULL)
2748 {
2749 const SwFrm *pParent = SwAccessibleFrame::GetParent( SwAccessibleChild(pObj), GetShell()->IsPreView() );
2750 if( pParent )
2751 {
2752 ::vos::ORef< SwAccessibleContext > xParentAccImpl = GetContextImpl(pParent,sal_False);
2753 if (!xParentAccImpl.isValid())
2754 {
2755 const SwTabFrm* pTabFrm = pParent->FindTabFrm();
2756 if (pTabFrm)
2757 {
2758 //The Table should not add in acc.because the "pParent" is not add to acc .
2759 uno::Reference< XAccessible> xAccParentTab = GetContext(pTabFrm,sal_True);//Should Create.
2760
2761 const SwFrm *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pTabFrm), GetShell()->IsPreView() );
2762 if (pParentRoot)
2763 {
2764 ::vos::ORef< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,sal_False);
2765 if(xParentAccImplRoot.isValid())
2766 {
2767 AccessibleEventObject aEvent;
2768 aEvent.EventId = AccessibleEventId::CHILD;
2769 aEvent.NewValue <<= xAccParentTab;
2770 xParentAccImplRoot->FireAccessibleEvent( aEvent );
2771 }
2772 }
2773
2774 //Get "pParent" acc again.
2775 xParentAccImpl = GetContextImpl(pParent,sal_False);
2776 }
2777 else
2778 {
2779 //directly create this acc para .
2780 xParentAccImpl = GetContextImpl(pParent,sal_True);//Should Create.
2781
2782 const SwFrm *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pParent), GetShell()->IsPreView() );
2783
2784 ::vos::ORef< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,sal_False);
2785 if(xParentAccImplRoot.isValid())
2786 {
2787 AccessibleEventObject aEvent;
2788 aEvent.EventId = AccessibleEventId::CHILD;
2789 aEvent.NewValue <<= uno::Reference< XAccessible>(xParentAccImpl.getBodyPtr());
2790 xParentAccImplRoot->FireAccessibleEvent( aEvent );
2791 }
2792 }
2793 }
2794 if (xParentAccImpl.isValid())
2795 {
2796 uno::Reference< XAccessible> xAccShape =
2797 GetContext(pObj,xParentAccImpl.getBodyPtr(),sal_True);
2798
2799 AccessibleEventObject aEvent;
2800 aEvent.EventId = AccessibleEventId::CHILD;
2801 aEvent.NewValue <<= xAccShape;
2802 xParentAccImpl->FireAccessibleEvent( aEvent );
2803 }
2804 }
2805 }
2806 }
2807 }
2808 }
2809 }
2810 }
2811
2812 m_setParaAdd.clear();
2813 m_setParaRemove.clear();
2814 if( xOldAcc.is() && xOldAcc != xAcc )
2815 InvalidateCursorPosition( xOldAcc );
2816 if( bOldShapeSelected || bShapeSelected )
2817 InvalidateShapeSelection();
2818 if( xAcc.is() )
2819 InvalidateCursorPosition( xAcc );
2820
2821 InvalidateShapeInParaSelection();
2822
2823 SET_PARA::iterator si = m_setParaRemove.begin();
2824 for (; si != m_setParaRemove.end() ; ++si)
2825 {
2826 SwAccessibleParagraph* pAccPara = *si;
2827 if(pAccPara && pAccPara->getSelectedAccessibleChildCount() == 0 && pAccPara->getSelectedText().getLength() == 0)
2828 {
2829 if(pAccPara->SetSelectedState(sal_False))
2830 {
2831 AccessibleEventObject aEvent;
2832 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
2833 pAccPara->FireAccessibleEvent( aEvent );
2834 }
2835 }
2836 }
2837 si = m_setParaAdd.begin();
2838 for (; si != m_setParaAdd.end() ; ++si)
2839 {
2840 SwAccessibleParagraph* pAccPara = *si;
2841 if(pAccPara && pAccPara->SetSelectedState(sal_True))
2842 {
2843 AccessibleEventObject aEvent;
2844 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
2845 pAccPara->FireAccessibleEvent( aEvent );
2846 }
2847 }
2848 }
2849
2850 //Notify the page change event to bridge.
FirePageChangeEvent(sal_uInt16 nOldPage,sal_uInt16 nNewPage)2851 void SwAccessibleMap::FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage)
2852 {
2853 uno::Reference<XAccessible> xAcc = GetDocumentView( );
2854 if ( xAcc.is() )
2855 {
2856 SwAccessibleDocumentBase *pAcc =
2857 static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
2858 if (pAcc)
2859 {
2860 AccessibleEventObject aEvent;
2861 aEvent.EventId = AccessibleEventId::PAGE_CHANGED;
2862 aEvent.OldValue <<= nOldPage;
2863 aEvent.NewValue <<= nNewPage;
2864 pAcc->FireAccessibleEvent( aEvent );
2865 }
2866 }
2867 }
2868
FireSectionChangeEvent(sal_uInt16 nOldSection,sal_uInt16 nNewSection)2869 void SwAccessibleMap::FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection)
2870 {
2871 uno::Reference<XAccessible> xAcc = GetDocumentView( );
2872 if ( xAcc.is() )
2873 {
2874 SwAccessibleDocumentBase *pAcc =
2875 static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
2876 if (pAcc)
2877 {
2878 AccessibleEventObject aEvent;
2879 aEvent.EventId = AccessibleEventId::SECTION_CHANGED;
2880 aEvent.OldValue <<= nOldSection;
2881 aEvent.NewValue <<= nNewSection;
2882 pAcc->FireAccessibleEvent( aEvent );
2883
2884 }
2885 }
2886 }
FireColumnChangeEvent(sal_uInt16 nOldColumn,sal_uInt16 nNewColumn)2887 void SwAccessibleMap::FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn)
2888 {
2889 uno::Reference<XAccessible> xAcc = GetDocumentView( );
2890 if ( xAcc.is() )
2891 {
2892 SwAccessibleDocumentBase *pAcc =
2893 static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
2894 if (pAcc)
2895 {
2896 AccessibleEventObject aEvent;
2897 aEvent.EventId = AccessibleEventId::COLUMN_CHANGED;
2898 aEvent.OldValue <<= nOldColumn;
2899 aEvent.NewValue <<= nNewColumn;
2900 pAcc->FireAccessibleEvent( aEvent );
2901
2902 }
2903 }
2904 }
2905
InvalidateFocus()2906 void SwAccessibleMap::InvalidateFocus()
2907 {
2908 if(GetShell()->IsPreView())
2909 {
2910 uno::Reference<XAccessible> xAcc = _GetDocumentView( sal_True );
2911 if (xAcc.get())
2912 {
2913 SwAccessiblePreview *pAccPreview = static_cast<SwAccessiblePreview *>(xAcc.get());
2914 if (pAccPreview)
2915 {
2916 pAccPreview->InvalidateFocus();
2917 return ;
2918 }
2919 }
2920 }
2921 uno::Reference < XAccessible > xAcc;
2922 sal_Bool bShapeSelected;
2923 {
2924 vos::OGuard aGuard( maMutex );
2925
2926 xAcc = mxCursorContext;
2927 bShapeSelected = mbShapeSelected;
2928 }
2929
2930 if( xAcc.is() )
2931 {
2932 SwAccessibleContext *pAccImpl =
2933 static_cast< SwAccessibleContext *>( xAcc.get() );
2934 pAccImpl->InvalidateFocus();
2935 }
2936 else
2937 {
2938 DoInvalidateShapeSelection(sal_True);
2939 }
2940 }
2941
SetCursorContext(const::vos::ORef<SwAccessibleContext> & rCursorContext)2942 void SwAccessibleMap::SetCursorContext(
2943 const ::vos::ORef < SwAccessibleContext >& rCursorContext )
2944 {
2945 vos::OGuard aGuard( maMutex );
2946 uno::Reference < XAccessible > xAcc( rCursorContext.getBodyPtr() );
2947 mxCursorContext = xAcc;
2948 }
2949
2950 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates>
InvalidateStates(tAccessibleStates _nStates,const SwFrm * _pFrm)2951 void SwAccessibleMap::InvalidateStates( tAccessibleStates _nStates,
2952 const SwFrm* _pFrm )
2953 {
2954 // Start with the frame or the first upper that is accessible
2955 SwAccessibleChild aFrmOrObj( _pFrm );
2956 while( aFrmOrObj.GetSwFrm() &&
2957 !aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2958 aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper();
2959 if( !aFrmOrObj.GetSwFrm() )
2960 aFrmOrObj = GetShell()->GetLayout();
2961
2962 uno::Reference< XAccessible > xAcc( GetContext( aFrmOrObj.GetSwFrm(), sal_True ) );
2963 SwAccessibleContext *pAccImpl =
2964 static_cast< SwAccessibleContext *>( xAcc.get() );
2965 if( GetShell()->ActionPend() )
2966 {
2967 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
2968 pAccImpl,
2969 SwAccessibleChild(pAccImpl->GetFrm()),
2970 _nStates );
2971 AppendEvent( aEvent );
2972 }
2973 else
2974 {
2975 FireEvents();
2976 pAccImpl->InvalidateStates( _nStates );
2977 }
2978 }
2979 // <--
2980
_InvalidateRelationSet(const SwFrm * pFrm,sal_Bool bFrom)2981 void SwAccessibleMap::_InvalidateRelationSet( const SwFrm* pFrm,
2982 sal_Bool bFrom )
2983 {
2984 // first, see if this frame is accessible, and if so, get the respective
2985 SwAccessibleChild aFrmOrObj( pFrm );
2986 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2987 {
2988 uno::Reference < XAccessible > xAcc;
2989 {
2990 vos::OGuard aGuard( maMutex );
2991
2992 if( mpFrmMap )
2993 {
2994 SwAccessibleContextMap_Impl::iterator aIter =
2995 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2996 if( aIter != mpFrmMap->end() )
2997 {
2998 xAcc = (*aIter).second;
2999 }
3000 }
3001 }
3002
3003 // deliver event directly, or queue event
3004 if( xAcc.is() )
3005 {
3006 SwAccessibleContext *pAccImpl =
3007 static_cast< SwAccessibleContext *>( xAcc.get() );
3008 if( GetShell()->ActionPend() )
3009 {
3010 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
3011 pAccImpl, SwAccessibleChild(pFrm),
3012 ( bFrom
3013 ? ACC_STATE_RELATION_FROM
3014 : ACC_STATE_RELATION_TO ) );
3015 AppendEvent( aEvent );
3016 }
3017 else
3018 {
3019 FireEvents();
3020 pAccImpl->InvalidateRelation( bFrom
3021 ? AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
3022 : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
3023 }
3024 }
3025 }
3026 }
3027
InvalidateRelationSet(const SwFrm * pMaster,const SwFrm * pFollow)3028 void SwAccessibleMap::InvalidateRelationSet( const SwFrm* pMaster,
3029 const SwFrm* pFollow )
3030 {
3031 _InvalidateRelationSet( pMaster, sal_False );
3032 _InvalidateRelationSet( pFollow, sal_True );
3033 }
3034
3035 /** invalidation CONTENT_FLOW_FROM/_TO relation of a paragraph
3036
3037 OD 2005-12-01 #i27138#
3038
3039 @author OD
3040 */
InvalidateParaFlowRelation(const SwTxtFrm & _rTxtFrm,const bool _bFrom)3041 void SwAccessibleMap::InvalidateParaFlowRelation( const SwTxtFrm& _rTxtFrm,
3042 const bool _bFrom )
3043 {
3044 _InvalidateRelationSet( &_rTxtFrm, _bFrom );
3045 }
3046
3047 /** invalidation of text selection of a paragraph
3048
3049 OD 2005-12-12 #i27301#
3050
3051 @author OD
3052 */
InvalidateParaTextSelection(const SwTxtFrm & _rTxtFrm)3053 void SwAccessibleMap::InvalidateParaTextSelection( const SwTxtFrm& _rTxtFrm )
3054 {
3055 // first, see if this frame is accessible, and if so, get the respective
3056 SwAccessibleChild aFrmOrObj( &_rTxtFrm );
3057 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
3058 {
3059 uno::Reference < XAccessible > xAcc;
3060 {
3061 vos::OGuard aGuard( maMutex );
3062
3063 if( mpFrmMap )
3064 {
3065 SwAccessibleContextMap_Impl::iterator aIter =
3066 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
3067 if( aIter != mpFrmMap->end() )
3068 {
3069 xAcc = (*aIter).second;
3070 }
3071 }
3072 }
3073
3074 // deliver event directly, or queue event
3075 if( xAcc.is() )
3076 {
3077 SwAccessibleContext *pAccImpl =
3078 static_cast< SwAccessibleContext *>( xAcc.get() );
3079 if( GetShell()->ActionPend() )
3080 {
3081 SwAccessibleEvent_Impl aEvent(
3082 SwAccessibleEvent_Impl::CARET_OR_STATES,
3083 pAccImpl,
3084 SwAccessibleChild( &_rTxtFrm ),
3085 ACC_STATE_TEXT_SELECTION_CHANGED );
3086 AppendEvent( aEvent );
3087 }
3088 else
3089 {
3090 FireEvents();
3091 pAccImpl->InvalidateTextSelection();
3092 }
3093 }
3094 }
3095 }
3096
GetChildIndex(const SwFrm & rParentFrm,Window & rChild) const3097 sal_Int32 SwAccessibleMap::GetChildIndex( const SwFrm& rParentFrm,
3098 Window& rChild ) const
3099 {
3100 sal_Int32 nIndex( -1 );
3101
3102 SwAccessibleChild aFrmOrObj( &rParentFrm );
3103 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
3104 {
3105 uno::Reference < XAccessible > xAcc;
3106 {
3107 vos::OGuard aGuard( maMutex );
3108
3109 if( mpFrmMap )
3110 {
3111 SwAccessibleContextMap_Impl::iterator aIter =
3112 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
3113 if( aIter != mpFrmMap->end() )
3114 {
3115 xAcc = (*aIter).second;
3116 }
3117 }
3118 }
3119
3120 if( xAcc.is() )
3121 {
3122 SwAccessibleContext *pAccImpl =
3123 static_cast< SwAccessibleContext *>( xAcc.get() );
3124
3125 nIndex = pAccImpl->GetChildIndex( const_cast<SwAccessibleMap&>(*this),
3126 SwAccessibleChild( &rChild ) );
3127 }
3128 }
3129
3130 return nIndex;
3131 }
3132
3133
3134 // OD 15.01.2003 #103492# - complete re-factoring of method due to new page/print
3135 // preview functionality.
UpdatePreview(const std::vector<PrevwPage * > & _rPrevwPages,const Fraction & _rScale,const SwPageFrm * _pSelectedPageFrm,const Size & _rPrevwWinSize)3136 void SwAccessibleMap::UpdatePreview( const std::vector<PrevwPage*>& _rPrevwPages,
3137 const Fraction& _rScale,
3138 const SwPageFrm* _pSelectedPageFrm,
3139 const Size& _rPrevwWinSize )
3140 {
3141 DBG_ASSERT( GetShell()->IsPreView(), "no preview?" );
3142 DBG_ASSERT( mpPreview != NULL, "no preview data?" );
3143
3144 // OD 15.01.2003 #103492# - adjustments for changed method signature
3145 mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize );
3146
3147 // propagate change of VisArea through the document's
3148 // accessibility tree; this will also send appropriate scroll
3149 // events
3150 SwAccessibleContext* pDoc =
3151 GetContextImpl( GetShell()->GetLayout() ).getBodyPtr();
3152 static_cast<SwAccessibleDocumentBase*>( pDoc )->SetVisArea();
3153
3154 uno::Reference < XAccessible > xOldAcc;
3155 uno::Reference < XAccessible > xAcc;
3156 {
3157 vos::OGuard aGuard( maMutex );
3158
3159 xOldAcc = mxCursorContext;
3160
3161 const SwPageFrm *pSelPage = mpPreview->GetSelPage();
3162 if( pSelPage && mpFrmMap )
3163 {
3164 SwAccessibleContextMap_Impl::iterator aIter =
3165 mpFrmMap->find( pSelPage );
3166 if( aIter != mpFrmMap->end() )
3167 xAcc = (*aIter).second;
3168 }
3169 }
3170
3171 if( xOldAcc.is() && xOldAcc != xAcc )
3172 InvalidateCursorPosition( xOldAcc );
3173 if( xAcc.is() )
3174 InvalidateCursorPosition( xAcc );
3175 }
3176
InvalidatePreViewSelection(sal_uInt16 nSelPage)3177 void SwAccessibleMap::InvalidatePreViewSelection( sal_uInt16 nSelPage )
3178 {
3179 DBG_ASSERT( GetShell()->IsPreView(), "no preview?" );
3180 DBG_ASSERT( mpPreview != NULL, "no preview data?" );
3181
3182 // OD 16.01.2003 #103492# - changed metthod call due to method signature change.
3183 mpPreview->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage ) );
3184
3185 uno::Reference < XAccessible > xOldAcc;
3186 uno::Reference < XAccessible > xAcc;
3187 {
3188 vos::OGuard aGuard( maMutex );
3189
3190 xOldAcc = mxCursorContext;
3191
3192 const SwPageFrm *pSelPage = mpPreview->GetSelPage();
3193 if( pSelPage && mpFrmMap )
3194 {
3195 SwAccessibleContextMap_Impl::iterator aIter =
3196 mpFrmMap->find( pSelPage );
3197 if( aIter != mpFrmMap->end() )
3198 xAcc = (*aIter).second;
3199 }
3200 }
3201
3202 if( xOldAcc.is() && xOldAcc != xAcc )
3203 InvalidateCursorPosition( xOldAcc );
3204 if( xAcc.is() )
3205 InvalidateCursorPosition( xAcc );
3206 }
3207
3208
IsPageSelected(const SwPageFrm * pPageFrm) const3209 sal_Bool SwAccessibleMap::IsPageSelected( const SwPageFrm *pPageFrm ) const
3210 {
3211 return mpPreview && mpPreview->GetSelPage() == pPageFrm;
3212 }
3213
3214
FireEvents()3215 void SwAccessibleMap::FireEvents()
3216 {
3217 {
3218 vos::OGuard aGuard( maEventMutex );
3219 if( mpEvents )
3220 {
3221 mpEvents->SetFiring();
3222 mpEvents->MoveInvalidXAccToEnd();
3223 SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin();
3224 while( aIter != mpEvents->end() )
3225 {
3226 FireEvent( *aIter );
3227 ++aIter;
3228 }
3229
3230 delete mpEventMap;
3231 mpEventMap = 0;
3232
3233 delete mpEvents;
3234 mpEvents = 0;
3235 }
3236 }
3237 {
3238 vos::OGuard aGuard( maMutex );
3239 if( mpShapes )
3240 {
3241 delete mpShapes;
3242 mpShapes = 0;
3243 }
3244 }
3245
3246 }
3247
IsValid() const3248 sal_Bool SwAccessibleMap::IsValid() const
3249 {
3250 return sal_True;
3251 }
3252
GetVisibleArea() const3253 Rectangle SwAccessibleMap::GetVisibleArea() const
3254 {
3255 MapMode aSrc( MAP_TWIP );
3256 MapMode aDest( MAP_100TH_MM );
3257 return OutputDevice::LogicToLogic( GetVisArea().SVRect(), aSrc, aDest );
3258 }
3259
3260 // Convert a MM100 value realtive to the document root into a pixel value
3261 // realtive to the screen!
LogicToPixel(const Point & rPoint) const3262 Point SwAccessibleMap::LogicToPixel( const Point& rPoint ) const
3263 {
3264 MapMode aSrc( MAP_100TH_MM );
3265 MapMode aDest( MAP_TWIP );
3266
3267 Point aPoint = rPoint;
3268
3269 aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest );
3270 Window *pWin = GetShell()->GetWin();
3271 if( pWin )
3272 {
3273 // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion
3274 MapMode aMapMode;
3275 GetMapMode( aPoint, aMapMode );
3276 aPoint = pWin->LogicToPixel( aPoint, aMapMode );
3277 aPoint = pWin->OutputToAbsoluteScreenPixel( aPoint );
3278 }
3279
3280 return aPoint;
3281 }
3282
LogicToPixel(const Size & rSize) const3283 Size SwAccessibleMap::LogicToPixel( const Size& rSize ) const
3284 {
3285 MapMode aSrc( MAP_100TH_MM );
3286 MapMode aDest( MAP_TWIP );
3287 Size aSize( OutputDevice::LogicToLogic( rSize, aSrc, aDest ) );
3288 if( GetShell()->GetWin() )
3289 {
3290 // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion
3291 MapMode aMapMode;
3292 GetMapMode( Point(0,0), aMapMode );
3293 aSize = GetShell()->GetWin()->LogicToPixel( aSize, aMapMode );
3294 }
3295
3296 return aSize;
3297 }
3298
PixelToLogic(const Point & rPoint) const3299 Point SwAccessibleMap::PixelToLogic( const Point& rPoint ) const
3300 {
3301 Point aPoint;
3302 Window *pWin = GetShell()->GetWin();
3303 if( pWin )
3304 {
3305 aPoint = pWin->ScreenToOutputPixel( rPoint );
3306 // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion
3307 MapMode aMapMode;
3308 GetMapMode( aPoint, aMapMode );
3309 aPoint = pWin->PixelToLogic( aPoint, aMapMode );
3310 MapMode aSrc( MAP_TWIP );
3311 MapMode aDest( MAP_100TH_MM );
3312 aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest );
3313 }
3314
3315 return aPoint;
3316 }
3317
PixelToLogic(const Size & rSize) const3318 Size SwAccessibleMap::PixelToLogic( const Size& rSize ) const
3319 {
3320 Size aSize;
3321 if( GetShell()->GetWin() )
3322 {
3323 // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion
3324 MapMode aMapMode;
3325 GetMapMode( Point(0,0), aMapMode );
3326 aSize = GetShell()->GetWin()->PixelToLogic( rSize, aMapMode );
3327 MapMode aSrc( MAP_TWIP );
3328 MapMode aDest( MAP_100TH_MM );
3329 aSize = OutputDevice::LogicToLogic( aSize, aSrc, aDest );
3330 }
3331
3332 return aSize;
3333 }
3334
ReplaceChild(::accessibility::AccessibleShape * pCurrentChild,const uno::Reference<drawing::XShape> & _rxShape,const long,const::accessibility::AccessibleShapeTreeInfo &)3335 sal_Bool SwAccessibleMap::ReplaceChild (
3336 ::accessibility::AccessibleShape* pCurrentChild,
3337 const uno::Reference< drawing::XShape >& _rxShape,
3338 const long /*_nIndex*/,
3339 const ::accessibility::AccessibleShapeTreeInfo& /*_rShapeTreeInfo*/
3340 ) throw (uno::RuntimeException)
3341 {
3342 const SdrObject *pObj = 0;
3343 {
3344 vos::OGuard aGuard( maMutex );
3345 if( mpShapeMap )
3346 {
3347 SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin();
3348 SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end();
3349 while( aIter != aEndIter && !pObj )
3350 {
3351 uno::Reference < XAccessible > xAcc( (*aIter).second );
3352 ::accessibility::AccessibleShape *pAccShape =
3353 static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
3354 if( pAccShape == pCurrentChild )
3355 {
3356 pObj = (*aIter).first;
3357 }
3358 ++aIter;
3359 }
3360 }
3361 }
3362 if( !pObj )
3363 return sal_False;
3364
3365 uno::Reference < drawing::XShape > xShape( _rxShape ); //keep reference to shape, because
3366 // we might be the only one that
3367 // hold it.
3368 // Also get keep parent.
3369 uno::Reference < XAccessible > xParent( pCurrentChild->getAccessibleParent() );
3370 pCurrentChild = 0; // well be realease by dispose
3371 Dispose( 0, pObj, 0 );
3372
3373 {
3374 vos::OGuard aGuard( maMutex );
3375
3376 if( !mpShapeMap )
3377 mpShapeMap = new SwAccessibleShapeMap_Impl( this );
3378
3379 // create the new child
3380 ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
3381 ::accessibility::ShapeTypeHandler::Instance();
3382 ::accessibility::AccessibleShapeInfo aShapeInfo(
3383 xShape, xParent, this );
3384 ::accessibility::AccessibleShape* pReplacement =
3385 rShapeTypeHandler.CreateAccessibleObject (
3386 aShapeInfo, mpShapeMap->GetInfo() );
3387
3388 uno::Reference < XAccessible > xAcc( pReplacement );
3389 if( xAcc.is() )
3390 {
3391 pReplacement->Init();
3392
3393 SwAccessibleShapeMap_Impl::iterator aIter =
3394 mpShapeMap->find( pObj );
3395 if( aIter != mpShapeMap->end() )
3396 {
3397 (*aIter).second = xAcc;
3398 }
3399 else
3400 {
3401 SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAcc );
3402 mpShapeMap->insert( aEntry );
3403 }
3404 }
3405 }
3406
3407 SwRect aEmptyRect;
3408 InvalidatePosOrSize( 0, pObj, 0, aEmptyRect );
3409
3410 return sal_True;
3411 }
3412
3413 //Get the accessible control shape from the model object, here model object is with XPropertySet type
GetAccControlShapeFromModel(::com::sun::star::beans::XPropertySet * pSet)3414 ::accessibility::AccessibleControlShape * SwAccessibleMap::GetAccControlShapeFromModel(::com::sun::star::beans::XPropertySet* pSet) throw (::com::sun::star::uno::RuntimeException)
3415 {
3416 if( mpShapeMap )
3417 {
3418 SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin();
3419 SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end();
3420 while( aIter != aEndIter)
3421 {
3422 uno::Reference < XAccessible > xAcc( (*aIter).second );
3423 ::accessibility::AccessibleShape *pAccShape =
3424 static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
3425 if(pAccShape && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape->GetXShape()) == ::accessibility::DRAWING_CONTROL)
3426 {
3427 ::accessibility::AccessibleControlShape *pCtlAccShape = static_cast < ::accessibility::AccessibleControlShape* >(pAccShape);
3428 if (pCtlAccShape && pCtlAccShape->GetControlModel() == pSet)
3429 return pCtlAccShape;
3430 }
3431 ++aIter;
3432 }
3433 }
3434 return NULL;
3435 }
3436
3437 ::com::sun::star::uno::Reference< XAccessible >
GetAccessibleCaption(const::com::sun::star::uno::Reference<::com::sun::star::drawing::XShape> & xShape)3438 SwAccessibleMap::GetAccessibleCaption (const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape)
3439 throw (::com::sun::star::uno::RuntimeException)
3440 {
3441 SdrObject* captionedObject = GetSdrObjectFromXShape(xShape);
3442
3443 SwDrawContact *pContact = (SwDrawContact*)GetUserCall( captionedObject );
3444 ASSERT( RES_DRAWFRMFMT == pContact->GetFmt()->Which(),
3445 "fail" );
3446 if( !pContact )
3447 return 0;
3448
3449 SwDrawFrmFmt *pCaptionedFmt = (SwDrawFrmFmt *)pContact->GetFmt();
3450 if( !pCaptionedFmt )
3451 return 0;
3452
3453 SwFlyFrm* pFrm = NULL;
3454 if (pCaptionedFmt->HasCaption())
3455 {
3456 const SwFrmFmt *pCaptionFrmFmt = pCaptionedFmt->GetCaptionFmt();
3457 SwClientIter aIter (*(SwModify*)pCaptionFrmFmt);
3458 pFrm = (SwFlyFrm*)aIter.First( TYPE ( SwFlyFrm ));
3459 }
3460 if (!pFrm)
3461 return 0;
3462 //SwFrmFmt* pFrm = pCaptionedFmt->GetCaptionFmt();
3463 uno::Reference < XAccessible > xAcc( GetContext((SwFrm*)pFrm,sal_True) );
3464 //Reference < XAccessibleShape > xAccShape( xAcc, UNO_QUERY );
3465
3466 uno::Reference< XAccessibleContext > xAccContext = xAcc->getAccessibleContext();
3467 if( xAccContext.is() )
3468 { //get the parent of caption frame, which is paragaph
3469 uno::Reference< XAccessible > xAccParent = xAccContext->getAccessibleParent();
3470 if(xAccParent.is())
3471 {
3472 //get the great parent of caption frame which is text frame.
3473 uno::Reference< XAccessibleContext > xAccParentContext = xAccParent->getAccessibleContext();
3474 uno::Reference< XAccessible > xAccGreatParent = xAccParentContext->getAccessibleParent();
3475 if(xAccGreatParent.is())
3476 {
3477 AccessibleEventObject aEvent;
3478 aEvent.EventId = AccessibleEventId::CHILD;
3479 aEvent.NewValue <<= xAccParent;
3480 ( static_cast< SwAccessibleContext * >(xAccGreatParent.get()) )->FireAccessibleEvent( aEvent );
3481
3482 }
3483
3484 AccessibleEventObject aEvent;
3485 aEvent.EventId = AccessibleEventId::CHILD;
3486 aEvent.NewValue <<= xAcc;
3487 ( static_cast< SwAccessibleContext * >(xAccParent.get()) )->FireAccessibleEvent( aEvent );
3488 }
3489 }
3490
3491 if(xAcc.get())
3492 return xAcc;
3493 else
3494 return NULL;
3495
3496 }
PixelToCore(const Point & rPoint) const3497 Point SwAccessibleMap::PixelToCore( const Point& rPoint ) const
3498 {
3499 Point aPoint;
3500 if( GetShell()->GetWin() )
3501 {
3502 // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)>
3503 MapMode aMapMode;
3504 GetMapMode( rPoint, aMapMode );
3505 aPoint = GetShell()->GetWin()->PixelToLogic( rPoint, aMapMode );
3506 }
3507 return aPoint;
3508 }
3509
lcl_CorrectCoarseValue(long aCoarseValue,long aFineValue,long aRefValue,bool bToLower)3510 static inline long lcl_CorrectCoarseValue(long aCoarseValue, long aFineValue,
3511 long aRefValue, bool bToLower)
3512 {
3513 long aResult = aCoarseValue;
3514
3515 if (bToLower)
3516 {
3517 if (aFineValue < aRefValue)
3518 aResult -= 1;
3519 }
3520 else
3521 {
3522 if (aFineValue > aRefValue)
3523 aResult += 1;
3524 }
3525
3526 return aResult;
3527 }
3528
lcl_CorrectRectangle(Rectangle & rRect,const Rectangle & rSource,const Rectangle & rInGrid)3529 static inline void lcl_CorrectRectangle(Rectangle & rRect,
3530 const Rectangle & rSource,
3531 const Rectangle & rInGrid)
3532 {
3533 rRect.nLeft = lcl_CorrectCoarseValue(rRect.nLeft, rSource.nLeft,
3534 rInGrid.nLeft, false);
3535 rRect.nTop = lcl_CorrectCoarseValue(rRect.nTop, rSource.nTop,
3536 rInGrid.nTop, false);
3537 rRect.nRight = lcl_CorrectCoarseValue(rRect.nRight, rSource.nRight,
3538 rInGrid.nRight, true);
3539 rRect.nBottom = lcl_CorrectCoarseValue(rRect.nBottom, rSource.nBottom,
3540 rInGrid.nBottom, true);
3541 }
3542
CoreToPixel(const Rectangle & rRect) const3543 Rectangle SwAccessibleMap::CoreToPixel( const Rectangle& rRect ) const
3544 {
3545 Rectangle aRect;
3546 if( GetShell()->GetWin() )
3547 {
3548 // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)>
3549 MapMode aMapMode;
3550 GetMapMode( rRect.TopLeft(), aMapMode );
3551 aRect = GetShell()->GetWin()->LogicToPixel( rRect, aMapMode );
3552
3553 Rectangle aTmpRect = GetShell()->GetWin()->PixelToLogic( aRect, aMapMode );
3554 lcl_CorrectRectangle(aRect, rRect, aTmpRect);
3555 }
3556
3557 return aRect;
3558 }
3559
3560 /** get mapping mode for LogicToPixel and PixelToLogic conversions
3561
3562 OD 15.01.2003 #103492#
3563 Replacement method <PreviewAdjust(..)> by new method <GetMapMode>.
3564 Method returns mapping mode of current output device and adjusts it,
3565 if the shell is in page/print preview.
3566 Necessary, because <PreviewAdjust(..)> changes mapping mode at current
3567 output device for mapping logic document positions to page preview window
3568 positions and vice versa and doesn't take care to recover its changes.
3569
3570 @author OD
3571 */
GetMapMode(const Point & _rPoint,MapMode & _orMapMode) const3572 void SwAccessibleMap::GetMapMode( const Point& _rPoint,
3573 MapMode& _orMapMode ) const
3574 {
3575 MapMode aMapMode = GetShell()->GetWin()->GetMapMode();
3576 if( GetShell()->IsPreView() )
3577 {
3578 DBG_ASSERT( mpPreview != NULL, "need preview data" );
3579
3580 mpPreview->AdjustMapMode( aMapMode, _rPoint );
3581 }
3582 _orMapMode = aMapMode;
3583 }
3584
3585 /** get size of a dedicated preview page
3586
3587 OD 15.01.2003 #103492#
3588
3589 @author OD
3590 */
GetPreViewPageSize(sal_uInt16 _nPrevwPageNum) const3591 Size SwAccessibleMap::GetPreViewPageSize( sal_uInt16 _nPrevwPageNum ) const
3592 {
3593 DBG_ASSERT( mpVSh->IsPreView(), "no page preview accessible." );
3594 DBG_ASSERT( mpVSh->IsPreView() && ( mpPreview != NULL ),
3595 "missing accessible preview data at page preview" );
3596 if ( mpVSh->IsPreView() && ( mpPreview != NULL ) )
3597 {
3598 return mpVSh->PagePreviewLayout()->GetPrevwPageSizeByPageNum( _nPrevwPageNum );
3599 }
3600 else
3601 {
3602 return Size( 0, 0 );
3603 }
3604 }
3605
3606 /** method to build up a new data structure of the accessible pararaphs,
3607 which have a selection
3608
3609 OD 2005-12-13 #i27301#
3610 Important note: method has to used inside a mutual exclusive section
3611
3612 @author OD
3613 */
_BuildSelectedParas()3614 SwAccessibleSelectedParas_Impl* SwAccessibleMap::_BuildSelectedParas()
3615 {
3616 // no accessible contexts, no selection
3617 if ( !mpFrmMap )
3618 {
3619 return 0L;
3620 }
3621
3622 // get cursor as an instance of its base class <SwPaM>
3623 SwPaM* pCrsr( 0L );
3624 {
3625 SwCrsrShell* pCrsrShell = dynamic_cast<SwCrsrShell*>(GetShell());
3626 if ( pCrsrShell )
3627 {
3628 SwFEShell* pFEShell = dynamic_cast<SwFEShell*>(pCrsrShell);
3629 if ( !pFEShell ||
3630 ( !pFEShell->IsFrmSelected() &&
3631 pFEShell->IsObjSelected() == 0 ) )
3632 {
3633 // get cursor without updating an existing table cursor.
3634 pCrsr = pCrsrShell->GetCrsr( sal_False );
3635 }
3636 }
3637 }
3638 // no cursor, no selection
3639 if ( !pCrsr )
3640 {
3641 return 0L;
3642 }
3643
3644 SwAccessibleSelectedParas_Impl* pRetSelectedParas( 0L );
3645
3646 // loop on all cursors
3647 SwPaM* pRingStart = pCrsr;
3648 do {
3649
3650 // for a selection the cursor has to have a mark.
3651 // for savety reasons assure that point and mark are in text nodes
3652 if ( pCrsr->HasMark() &&
3653 pCrsr->GetPoint()->nNode.GetNode().IsTxtNode() &&
3654 pCrsr->GetMark()->nNode.GetNode().IsTxtNode() )
3655 {
3656 SwPosition* pStartPos = pCrsr->Start();
3657 SwPosition* pEndPos = pCrsr->End();
3658 // loop on all text nodes inside the selection
3659 SwNodeIndex aIdx( pStartPos->nNode );
3660 for ( ; aIdx.GetIndex() <= pEndPos->nNode.GetIndex(); ++aIdx )
3661 {
3662 SwTxtNode* pTxtNode( aIdx.GetNode().GetTxtNode() );
3663 if ( pTxtNode )
3664 {
3665 // loop on all text frames registered at the text node.
3666 SwIterator<SwTxtFrm,SwTxtNode> aIter( *pTxtNode );
3667 for( SwTxtFrm* pTxtFrm = aIter.First(); pTxtFrm; pTxtFrm = aIter.Next() )
3668 {
3669 uno::WeakReference < XAccessible > xWeakAcc;
3670 SwAccessibleContextMap_Impl::iterator aMapIter =
3671 mpFrmMap->find( pTxtFrm );
3672 if( aMapIter != mpFrmMap->end() )
3673 {
3674 xWeakAcc = (*aMapIter).second;
3675 SwAccessibleParaSelection aDataEntry(
3676 pTxtNode == &(pStartPos->nNode.GetNode())
3677 ? pStartPos->nContent.GetIndex()
3678 : 0,
3679 pTxtNode == &(pEndPos->nNode.GetNode())
3680 ? pEndPos->nContent.GetIndex()
3681 : STRING_LEN );
3682 SwAccessibleSelectedParas_Impl::value_type
3683 aEntry( xWeakAcc, aDataEntry );
3684 if ( !pRetSelectedParas )
3685 {
3686 pRetSelectedParas =
3687 new SwAccessibleSelectedParas_Impl;
3688 }
3689 pRetSelectedParas->insert( aEntry );
3690 }
3691 }
3692 }
3693 }
3694 }
3695
3696 // prepare next turn: get next cursor in ring
3697 pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
3698 } while ( pCrsr != pRingStart );
3699
3700 return pRetSelectedParas;
3701 }
3702
3703 /** invalidation of text selection of all paragraphs
3704
3705 OD 2005-12-13 #i27301#
3706
3707 @author OD
3708 */
InvalidateTextSelectionOfAllParas()3709 void SwAccessibleMap::InvalidateTextSelectionOfAllParas()
3710 {
3711 vos::OGuard aGuard( maMutex );
3712
3713 // keep previously known selected paragraphs
3714 SwAccessibleSelectedParas_Impl* pPrevSelectedParas( mpSelectedParas );
3715
3716 // determine currently selected paragraphs
3717 mpSelectedParas = _BuildSelectedParas();
3718
3719 // compare currently selected paragraphs with the previously selected
3720 // paragraphs and submit corresponding TEXT_SELECTION_CHANGED events.
3721 // first, search for new and changed selections.
3722 // on the run remove selections from previously known ones, if they are
3723 // also in the current ones.
3724 if ( mpSelectedParas )
3725 {
3726 SwAccessibleSelectedParas_Impl::iterator aIter = mpSelectedParas->begin();
3727 for ( ; aIter != mpSelectedParas->end(); ++aIter )
3728 {
3729 bool bSubmitEvent( false );
3730 if ( !pPrevSelectedParas )
3731 {
3732 // new selection
3733 bSubmitEvent = true;
3734 }
3735 else
3736 {
3737 SwAccessibleSelectedParas_Impl::iterator aPrevSelected =
3738 pPrevSelectedParas->find( (*aIter).first );
3739 if ( aPrevSelected != pPrevSelectedParas->end() )
3740 {
3741 // check, if selection has changed
3742 if ( (*aIter).second.nStartOfSelection !=
3743 (*aPrevSelected).second.nStartOfSelection ||
3744 (*aIter).second.nEndOfSelection !=
3745 (*aPrevSelected).second.nEndOfSelection )
3746 {
3747 // changed selection
3748 bSubmitEvent = true;
3749 }
3750 pPrevSelectedParas->erase( aPrevSelected );
3751 }
3752 else
3753 {
3754 // new selection
3755 bSubmitEvent = true;
3756 }
3757 }
3758
3759 if ( bSubmitEvent )
3760 {
3761 uno::Reference < XAccessible > xAcc( (*aIter).first );
3762 if ( xAcc.is() )
3763 {
3764 ::vos::ORef < SwAccessibleContext > xAccImpl(
3765 static_cast<SwAccessibleContext*>( xAcc.get() ) );
3766 if ( xAccImpl.isValid() && xAccImpl->GetFrm() )
3767 {
3768 const SwTxtFrm* pTxtFrm(
3769 dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) );
3770 ASSERT( pTxtFrm,
3771 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
3772 if ( pTxtFrm )
3773 {
3774 InvalidateParaTextSelection( *pTxtFrm );
3775 }
3776 }
3777 }
3778 }
3779 }
3780 }
3781
3782 // second, handle previous selections - after the first step the data
3783 // structure of the previously known only contains the 'old' selections
3784 if ( pPrevSelectedParas )
3785 {
3786 SwAccessibleSelectedParas_Impl::iterator aIter = pPrevSelectedParas->begin();
3787 for ( ; aIter != pPrevSelectedParas->end(); ++aIter )
3788 {
3789 uno::Reference < XAccessible > xAcc( (*aIter).first );
3790 if ( xAcc.is() )
3791 {
3792 ::vos::ORef < SwAccessibleContext > xAccImpl(
3793 static_cast<SwAccessibleContext*>( xAcc.get() ) );
3794 if ( xAccImpl.isValid() && xAccImpl->GetFrm() )
3795 {
3796 const SwTxtFrm* pTxtFrm(
3797 dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) );
3798 ASSERT( pTxtFrm,
3799 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
3800 if ( pTxtFrm )
3801 {
3802 InvalidateParaTextSelection( *pTxtFrm );
3803 }
3804 }
3805 }
3806 }
3807
3808 delete pPrevSelectedParas;
3809 }
3810 }
3811
GetVisArea() const3812 const SwRect& SwAccessibleMap::GetVisArea() const
3813 {
3814 DBG_ASSERT( !GetShell()->IsPreView() || (mpPreview != NULL),
3815 "preview without preview data?" );
3816
3817 return GetShell()->IsPreView()
3818 ? mpPreview->GetVisArea()
3819 : GetShell()->VisArea();
3820 }
3821
IsDocumentSelAll()3822 sal_Bool SwAccessibleMap::IsDocumentSelAll()
3823 {
3824 return GetShell()->GetDoc()->IsPrepareSelAll();
3825 }
3826
3827