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