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