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