| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sw.hxx" |
| |
| #include <vos/ref.hxx> |
| #include <cppuhelper/weakref.hxx> |
| #include <vcl/window.hxx> |
| #include <svx/svdmodel.hxx> |
| #include <svx/unomod.hxx> |
| #include <tools/debug.hxx> |
| #include <map> |
| #include <list> |
| #include <vector> |
| #include <accmap.hxx> |
| #include <acccontext.hxx> |
| #include <accdoc.hxx> |
| #include <accpreview.hxx> |
| #include <accpage.hxx> |
| #include <accpara.hxx> |
| #include <accheaderfooter.hxx> |
| #include <accfootnote.hxx> |
| #include <acctextframe.hxx> |
| #include <accgraphic.hxx> |
| #include <accembedded.hxx> |
| #include <acccell.hxx> |
| #include <acctable.hxx> |
| #include <fesh.hxx> |
| #include <rootfrm.hxx> |
| #include <txtfrm.hxx> |
| #include <hffrm.hxx> |
| #include <ftnfrm.hxx> |
| #include <cellfrm.hxx> |
| #include <tabfrm.hxx> |
| #include <pagefrm.hxx> |
| #include <flyfrm.hxx> |
| #include <ndtyp.hxx> |
| #include <IDocumentDrawModelAccess.hxx> |
| #include <svx/ShapeTypeHandler.hxx> |
| #include <vcl/svapp.hxx> |
| #include <svx/ShapeTypeHandler.hxx> |
| #include <svx/SvxShapeTypes.hxx> |
| #include <svx/svdpage.hxx> |
| #include <com/sun/star/accessibility/AccessibleRelationType.hpp> |
| #include <com/sun/star/accessibility/AccessibleEventId.hpp> |
| #include <com/sun/star/accessibility/AccessibleStateType.hpp> |
| #include <com/sun/star/accessibility/AccessibleRole.hpp> |
| #include <cppuhelper/implbase1.hxx> |
| #include <pagepreviewlayout.hxx> |
| #include <dcontact.hxx> |
| #include <svx/unoapi.hxx> |
| #include <svx/svdmark.hxx> |
| #include <doc.hxx> |
| #include <pam.hxx> |
| #include <ndtxt.hxx> |
| #include <dflyobj.hxx> |
| #include <prevwpage.hxx> |
| #include <switerator.hxx> |
| #include <drawdoc.hxx> |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::accessibility; |
| using ::rtl::OUString; |
| using namespace ::sw::access; |
| |
| struct SwFrmFunc |
| { |
| sal_Bool operator()( const SwFrm * p1, |
| const SwFrm * p2) const |
| { |
| return p1 < p2; |
| } |
| }; |
| |
| typedef ::std::map < const SwFrm *, uno::WeakReference < XAccessible >, SwFrmFunc > _SwAccessibleContextMap_Impl; |
| |
| class SwAccessibleContextMap_Impl: public _SwAccessibleContextMap_Impl |
| { |
| public: |
| |
| #ifdef DBG_UTIL |
| sal_Bool mbLocked; |
| #endif |
| |
| SwAccessibleContextMap_Impl() |
| #ifdef DBG_UTIL |
| : mbLocked( sal_False ) |
| #endif |
| {} |
| |
| }; |
| |
| //------------------------------------------------------------------------------ |
| class SwDrawModellListener_Impl : public SfxListener, |
| public ::cppu::WeakImplHelper1< document::XEventBroadcaster > |
| { |
| mutable ::osl::Mutex maListenerMutex; |
| ::cppu::OInterfaceContainerHelper maEventListeners; |
| SdrModel *mpDrawModel; |
| protected: |
| virtual ~SwDrawModellListener_Impl(); |
| public: |
| |
| SwDrawModellListener_Impl( SdrModel *pDrawModel ); |
| |
| |
| virtual void SAL_CALL addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException); |
| virtual void SAL_CALL removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException); |
| |
| virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); |
| void Dispose(); |
| }; |
| |
| SwDrawModellListener_Impl::SwDrawModellListener_Impl( SdrModel *pDrawModel ) : |
| maEventListeners( maListenerMutex ), |
| mpDrawModel( pDrawModel ) |
| { |
| StartListening( *mpDrawModel ); |
| } |
| |
| SwDrawModellListener_Impl::~SwDrawModellListener_Impl() |
| { |
| EndListening( *mpDrawModel ); |
| } |
| |
| void SAL_CALL SwDrawModellListener_Impl::addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException) |
| { |
| maEventListeners.addInterface( xListener ); |
| } |
| |
| void SAL_CALL SwDrawModellListener_Impl::removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException) |
| { |
| maEventListeners.removeInterface( xListener ); |
| } |
| |
| void SwDrawModellListener_Impl::Notify( SfxBroadcaster& /*rBC*/, |
| const SfxHint& rHint ) |
| { |
| // do not broadcast notifications for writer fly frames, because there |
| // are no shapes that need to know about them. |
| // OD 01.07.2003 #110554# - correct condition in order not to broadcast |
| // notifications for writer fly frames. |
| // OD 01.07.2003 #110554# - do not broadcast notifications for plane |
| // <SdrObject>objects |
| const SdrHint *pSdrHint = PTR_CAST( SdrHint, &rHint ); |
| if ( !pSdrHint || |
| ( pSdrHint->GetObject() && |
| ( pSdrHint->GetObject()->ISA(SwFlyDrawObj) || |
| pSdrHint->GetObject()->ISA(SwVirtFlyDrawObj) || |
| IS_TYPE(SdrObject,pSdrHint->GetObject()) ) ) ) |
| { |
| return; |
| } |
| |
| ASSERT( mpDrawModel, "draw model listener is disposed" ); |
| if( !mpDrawModel ) |
| return; |
| |
| document::EventObject aEvent; |
| if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) ) |
| return; |
| |
| ::cppu::OInterfaceIteratorHelper aIter( maEventListeners ); |
| while( aIter.hasMoreElements() ) |
| { |
| uno::Reference < document::XEventListener > xListener( aIter.next(), |
| uno::UNO_QUERY ); |
| try |
| { |
| xListener->notifyEvent( aEvent ); |
| } |
| catch( uno::RuntimeException const & r ) |
| { |
| (void)r; |
| #if OSL_DEBUG_LEVEL > 1 |
| ByteString aError( "Runtime exception caught while notifying shape.:\n" ); |
| aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); |
| DBG_ERROR( aError.GetBuffer() ); |
| #endif |
| } |
| } |
| } |
| |
| void SwDrawModellListener_Impl::Dispose() |
| { |
| mpDrawModel = 0; |
| } |
| |
| //------------------------------------------------------------------------------ |
| struct SwShapeFunc |
| { |
| sal_Bool operator()( const SdrObject * p1, |
| const SdrObject * p2) const |
| { |
| return p1 < p2; |
| } |
| }; |
| typedef ::std::map < const SdrObject *, uno::WeakReference < XAccessible >, SwShapeFunc > _SwAccessibleShapeMap_Impl; |
| typedef ::std::pair < const SdrObject *, ::vos::ORef < ::accessibility::AccessibleShape > > SwAccessibleObjShape_Impl; |
| |
| class SwAccessibleShapeMap_Impl: public _SwAccessibleShapeMap_Impl |
| |
| { |
| ::accessibility::AccessibleShapeTreeInfo maInfo; |
| |
| public: |
| |
| #ifdef DBG_UTIL |
| sal_Bool mbLocked; |
| #endif |
| SwAccessibleShapeMap_Impl( SwAccessibleMap *pMap ) |
| #ifdef DBG_UTIL |
| : mbLocked( sal_False ) |
| #endif |
| { |
| maInfo.SetSdrView( pMap->GetShell()->GetDrawView() ); |
| maInfo.SetWindow( pMap->GetShell()->GetWin() ); |
| maInfo.SetViewForwarder( pMap ); |
| // --> OD 2005-08-08 #i52858# - method name changed |
| uno::Reference < document::XEventBroadcaster > xModelBroadcaster = |
| new SwDrawModellListener_Impl( |
| pMap->GetShell()->getIDocumentDrawModelAccess()->GetOrCreateDrawModel() ); |
| // <-- |
| maInfo.SetControllerBroadcaster( xModelBroadcaster ); |
| } |
| |
| ~SwAccessibleShapeMap_Impl(); |
| |
| const ::accessibility::AccessibleShapeTreeInfo& GetInfo() const { return maInfo; } |
| |
| SwAccessibleObjShape_Impl *Copy( size_t& rSize, |
| const SwFEShell *pFESh = 0, |
| SwAccessibleObjShape_Impl **pSelShape = 0 ) const; |
| }; |
| |
| SwAccessibleShapeMap_Impl::~SwAccessibleShapeMap_Impl() |
| { |
| uno::Reference < document::XEventBroadcaster > xBrd( maInfo.GetControllerBroadcaster() ); |
| if( xBrd.is() ) |
| static_cast < SwDrawModellListener_Impl * >( xBrd.get() )->Dispose(); |
| } |
| |
| SwAccessibleObjShape_Impl |
| *SwAccessibleShapeMap_Impl::Copy( |
| size_t& rSize, const SwFEShell *pFESh, |
| SwAccessibleObjShape_Impl **pSelStart ) const |
| { |
| SwAccessibleObjShape_Impl *pShapes = 0; |
| SwAccessibleObjShape_Impl *pSelShape = 0; |
| |
| sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0; |
| rSize = size(); |
| |
| if( rSize > 0 ) |
| { |
| pShapes = |
| new SwAccessibleObjShape_Impl[rSize]; |
| |
| const_iterator aIter = begin(); |
| const_iterator aEndIter = end(); |
| |
| SwAccessibleObjShape_Impl *pShape = pShapes; |
| pSelShape = &(pShapes[rSize]); |
| while( aIter != aEndIter ) |
| { |
| const SdrObject *pObj = (*aIter).first; |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| if( nSelShapes && pFESh &&pFESh->IsObjSelected( *pObj ) ) |
| { |
| // selected objects are inserted from the back |
| --pSelShape; |
| pSelShape->first = pObj; |
| pSelShape->second = |
| static_cast < ::accessibility::AccessibleShape* >( |
| xAcc.get() ); |
| --nSelShapes; |
| } |
| else |
| { |
| pShape->first = pObj; |
| pShape->second = |
| static_cast < ::accessibility::AccessibleShape* >( |
| xAcc.get() ); |
| ++pShape; |
| } |
| ++aIter; |
| } |
| ASSERT( pSelShape == pShape, "copying shapes went wrong!" ); |
| } |
| |
| if( pSelStart ) |
| *pSelStart = pSelShape; |
| |
| return pShapes; |
| } |
| |
| //------------------------------------------------------------------------------ |
| struct SwAccessibleEvent_Impl |
| { |
| public: |
| enum EventType { CARET_OR_STATES, |
| INVALID_CONTENT, |
| POS_CHANGED, |
| CHILD_POS_CHANGED, |
| SHAPE_SELECTION, |
| DISPOSE, |
| INVALID_ATTR }; |
| |
| private: |
| SwRect maOldBox; // the old bounds for CHILD_POS_CHANGED |
| // and POS_CHANGED |
| uno::WeakReference < XAccessible > mxAcc; // The object that fires the event |
| SwAccessibleChild maFrmOrObj; // the child for CHILD_POS_CHANGED and |
| // the same as xAcc for any other |
| // event type |
| EventType meType; // The event type |
| // --> OD 2005-12-12 #i27301# - use new type definition for <mnStates> |
| tAccessibleStates mnStates; // check states or update caret pos |
| // <-- |
| |
| SwAccessibleEvent_Impl& operator==( const SwAccessibleEvent_Impl& ); |
| |
| public: |
| const SwFrm* mpParentFrm; // The object that fires the event |
| sal_Bool IsNoXaccParentFrm() const |
| { |
| return CHILD_POS_CHANGED == meType && mpParentFrm != 0; |
| } |
| uno::WeakReference < XAccessible > GetxAcc() const { return mxAcc;} |
| public: |
| SwAccessibleEvent_Impl( EventType eT, |
| SwAccessibleContext *pA, |
| const SwAccessibleChild& rFrmOrObj ) |
| : mxAcc( pA ), |
| maFrmOrObj( rFrmOrObj ), |
| meType( eT ), |
| mnStates( 0 ), |
| mpParentFrm( 0 ) |
| {} |
| |
| SwAccessibleEvent_Impl( EventType eT, |
| const SwAccessibleChild& rFrmOrObj ) |
| : maFrmOrObj( rFrmOrObj ), |
| meType( eT ), |
| mnStates( 0 ), |
| mpParentFrm( 0 ) |
| { |
| ASSERT( SwAccessibleEvent_Impl::DISPOSE == meType, |
| "wrong event constructor, DISPOSE only" ); |
| } |
| |
| SwAccessibleEvent_Impl( EventType eT ) |
| : meType( eT ), |
| mnStates( 0 ), |
| mpParentFrm( 0 ) |
| { |
| ASSERT( SwAccessibleEvent_Impl::SHAPE_SELECTION == meType, |
| "wrong event constructor, SHAPE_SELECTION only" ); |
| } |
| |
| SwAccessibleEvent_Impl( EventType eT, |
| SwAccessibleContext *pA, |
| const SwAccessibleChild& rFrmOrObj, |
| const SwRect& rR ) |
| : maOldBox( rR ), |
| mxAcc( pA ), |
| maFrmOrObj( rFrmOrObj ), |
| meType( eT ), |
| mnStates( 0 ), |
| mpParentFrm( 0 ) |
| { |
| ASSERT( SwAccessibleEvent_Impl::CHILD_POS_CHANGED == meType || |
| SwAccessibleEvent_Impl::POS_CHANGED == meType, |
| "wrong event constructor, (CHILD_)POS_CHANGED only" ); |
| } |
| |
| // --> OD 2005-12-12 #i27301# - use new type definition for parameter <_nStates> |
| SwAccessibleEvent_Impl( EventType eT, |
| SwAccessibleContext *pA, |
| const SwAccessibleChild& rFrmOrObj, |
| const tAccessibleStates _nStates ) |
| : mxAcc( pA ), |
| maFrmOrObj( rFrmOrObj ), |
| meType( eT ), |
| mnStates( _nStates ), |
| mpParentFrm( 0 ) |
| { |
| ASSERT( SwAccessibleEvent_Impl::CARET_OR_STATES == meType, |
| "wrong event constructor, CARET_OR_STATES only" ); |
| } |
| |
| SwAccessibleEvent_Impl( EventType eT, |
| const SwFrm *pParentFrm, |
| const SwAccessibleChild& rFrmOrObj, |
| const SwRect& rR ) : |
| maOldBox( rR ), |
| maFrmOrObj( rFrmOrObj ), |
| meType( eT ), |
| mnStates( 0 ), |
| mpParentFrm( pParentFrm ) |
| { |
| OSL_ENSURE( SwAccessibleEvent_Impl::CHILD_POS_CHANGED == meType, |
| "wrong event constructor, CHILD_POS_CHANGED only" ); |
| } |
| // <SetType(..)> only used in method <SwAccessibleMap::AppendEvent(..)> |
| inline void SetType( EventType eT ) |
| { |
| meType = eT; |
| } |
| inline EventType GetType() const |
| { |
| return meType; |
| } |
| |
| inline ::vos::ORef < SwAccessibleContext > GetContext() const |
| { |
| uno::Reference < XAccessible > xTmp( mxAcc ); |
| ::vos::ORef < SwAccessibleContext > xAccImpl( |
| static_cast<SwAccessibleContext*>( xTmp.get() ) ); |
| |
| return xAccImpl; |
| } |
| |
| inline const SwRect& GetOldBox() const |
| { |
| return maOldBox; |
| } |
| // <SetOldBox(..)> only used in method <SwAccessibleMap::AppendEvent(..)> |
| inline void SetOldBox( const SwRect& rOldBox ) |
| { |
| maOldBox = rOldBox; |
| } |
| |
| inline const SwAccessibleChild& GetFrmOrObj() const |
| { |
| return maFrmOrObj; |
| } |
| |
| // <SetStates(..)> only used in method <SwAccessibleMap::AppendEvent(..)> |
| // --> OD 2005-12-12 #i27301# - use new type definition for parameter <_nStates> |
| inline void SetStates( tAccessibleStates _nStates ) |
| { |
| mnStates |= _nStates; |
| } |
| // <-- |
| |
| inline sal_Bool IsUpdateCursorPos() const |
| { |
| return (mnStates & ACC_STATE_CARET) != 0; |
| } |
| inline sal_Bool IsInvalidateStates() const |
| { |
| return (mnStates & ACC_STATE_MASK) != 0; |
| } |
| inline sal_Bool IsInvalidateRelation() const |
| { |
| return (mnStates & ACC_STATE_RELATION_MASK) != 0; |
| } |
| // --> OD 2005-12-12 #i27301# - new event TEXT_SELECTION_CHANGED |
| inline sal_Bool IsInvalidateTextSelection() const |
| { |
| return ( mnStates & ACC_STATE_TEXT_SELECTION_CHANGED ) != 0; |
| } |
| // <-- |
| // --> OD 2009-01-07 #i88069# - new event TEXT_ATTRIBUTE_CHANGED |
| inline sal_Bool IsInvalidateTextAttrs() const |
| { |
| return ( mnStates & ACC_STATE_TEXT_ATTRIBUTE_CHANGED ) != 0; |
| } |
| // <-- |
| // --> OD 2005-12-12 #i27301# - use new type definition <tAccessibleStates> |
| // for return value |
| inline tAccessibleStates GetStates() const |
| { |
| return mnStates & ACC_STATE_MASK; |
| } |
| // <-- |
| // --> OD 2005-12-12 #i27301# - use new type definition <tAccessibleStates> |
| // for return value |
| inline tAccessibleStates GetAllStates() const |
| { |
| return mnStates; |
| } |
| // <-- |
| }; |
| |
| //------------------------------------------------------------------------------ |
| typedef ::std::list < SwAccessibleEvent_Impl > _SwAccessibleEventList_Impl; |
| |
| class SwAccessibleEventList_Impl: public _SwAccessibleEventList_Impl |
| { |
| sal_Bool mbFiring; |
| |
| public: |
| |
| SwAccessibleEventList_Impl() |
| : mbFiring( sal_False ) |
| {} |
| |
| inline void SetFiring() |
| { |
| mbFiring = sal_True; |
| } |
| inline sal_Bool IsFiring() const |
| { |
| return mbFiring; |
| } |
| struct XAccisNULL |
| { |
| bool operator()(const SwAccessibleEvent_Impl& e) |
| { |
| return e.IsNoXaccParentFrm(); |
| } |
| }; |
| void MoveInvalidXAccToEnd(); |
| }; |
| |
| void SwAccessibleEventList_Impl::MoveInvalidXAccToEnd() |
| { |
| int nSize = size(); |
| if (nSize < 2 ) |
| { |
| return; |
| } |
| SwAccessibleEventList_Impl lstEvent; |
| iterator li = begin(); |
| for ( ;li != end();) |
| { |
| SwAccessibleEvent_Impl e = *li; |
| if (e.IsNoXaccParentFrm()) |
| { |
| iterator liNext = li; |
| ++liNext; |
| erase(li); |
| li = liNext; |
| lstEvent.insert(lstEvent.end(),e); |
| } |
| else |
| ++li; |
| } |
| OSL_ENSURE(size() + lstEvent.size() == nSize ,""); |
| insert(end(),lstEvent.begin(),lstEvent.end()); |
| OSL_ENSURE(size() == nSize ,""); |
| } |
| //------------------------------------------------------------------------------ |
| // The shape list is filled if an accessible shape is destroyed. It |
| // simply keeps a reference to the accessible shape's XShape. These |
| // references are destroyed within the EndAction when firing events, |
| // There are twp reason for this. First of all, a new accessible shape |
| // for the XShape might be created soon. It's then cheaper if the XShape |
| // still exists. The other reason are situations where an accessible shape |
| // is destroyed within an SwFrmFmt::Modify. In this case, destryoing |
| // the XShape at the same time (indirectly by destroying the accessible |
| // shape) leads to an assert, because a client of the Modify is destroyed |
| // within a Modify call. |
| |
| typedef ::std::list < uno::Reference < drawing::XShape > > _SwShapeList_Impl; |
| |
| class SwShapeList_Impl: public _SwShapeList_Impl |
| { |
| public: |
| |
| SwShapeList_Impl() {} |
| }; |
| |
| |
| //------------------------------------------------------------------------------ |
| struct SwAccessibleChildFunc |
| { |
| sal_Bool operator()( const SwAccessibleChild& r1, |
| const SwAccessibleChild& r2 ) const |
| { |
| const void *p1 = r1.GetSwFrm() |
| ? static_cast < const void * >( r1.GetSwFrm()) |
| : ( r1.GetDrawObject() |
| ? static_cast < const void * >( r1.GetDrawObject() ) |
| : static_cast < const void * >( r1.GetWindow() ) ); |
| const void *p2 = r2.GetSwFrm() |
| ? static_cast < const void * >( r2.GetSwFrm()) |
| : ( r2.GetDrawObject() |
| ? static_cast < const void * >( r2.GetDrawObject() ) |
| : static_cast < const void * >( r2.GetWindow() ) ); |
| return p1 < p2; |
| } |
| }; |
| typedef ::std::map < SwAccessibleChild, SwAccessibleEventList_Impl::iterator, |
| SwAccessibleChildFunc > _SwAccessibleEventMap_Impl; |
| |
| class SwAccessibleEventMap_Impl: public _SwAccessibleEventMap_Impl |
| { |
| }; |
| |
| //------------------------------------------------------------------------------ |
| // --> OD 2005-12-13 #i27301# - map containing the accessible paragraph, which |
| // have a selection. Needed to keep this information to submit corresponding |
| // TEXT_SELECTION_CHANGED events. |
| struct SwAccessibleParaSelection |
| { |
| xub_StrLen nStartOfSelection; |
| xub_StrLen nEndOfSelection; |
| |
| SwAccessibleParaSelection( const xub_StrLen _nStartOfSelection, |
| const xub_StrLen _nEndOfSelection ) |
| : nStartOfSelection( _nStartOfSelection ), |
| nEndOfSelection( _nEndOfSelection ) |
| {} |
| }; |
| |
| struct SwXAccWeakRefComp |
| { |
| sal_Bool operator()( const uno::WeakReference<XAccessible>& _rXAccWeakRef1, |
| const uno::WeakReference<XAccessible>& _rXAccWeakRef2 ) const |
| { |
| return _rXAccWeakRef1.get() < _rXAccWeakRef2.get(); |
| } |
| }; |
| |
| typedef ::std::map< uno::WeakReference < XAccessible >, |
| SwAccessibleParaSelection, |
| SwXAccWeakRefComp > _SwAccessibleSelectedParas_Impl; |
| |
| class SwAccessibleSelectedParas_Impl: public _SwAccessibleSelectedParas_Impl |
| {}; |
| // <-- |
| |
| // helper class that stores preview data |
| class SwAccPreviewData |
| { |
| typedef std::vector<Rectangle> Rectangles; |
| Rectangles maPreviewRects; |
| Rectangles maLogicRects; |
| |
| SwRect maVisArea; |
| Fraction maScale; |
| |
| const SwPageFrm *mpSelPage; |
| |
| /** adjust logic page retangle to its visible part |
| |
| OD 17.01.2003 #103492# |
| |
| @author OD |
| |
| @param _iorLogicPgSwRect |
| input/output parameter - reference to the logic page rectangle, which |
| has to be adjusted. |
| |
| @param _rPrevwPgSwRect |
| input parameter - constant reference to the corresponding preview page |
| rectangle; needed to determine the visible part of the logic page rectangle. |
| |
| @param _rPrevwWinSize |
| input parameter - constant reference to the preview window size in TWIP; |
| needed to determine the visible part of the logic page rectangle |
| */ |
| void AdjustLogicPgRectToVisibleArea( SwRect& _iorLogicPgSwRect, |
| const SwRect& _rPrevwPgSwRect, |
| const Size& _rPrevwWinSize ); |
| |
| public: |
| SwAccPreviewData(); |
| ~SwAccPreviewData(); |
| |
| // OD 14.01.2003 #103492# - complete re-factoring of method due to new |
| // page/print preview functionality. |
| void Update( const SwAccessibleMap& rAccMap, |
| const std::vector<PrevwPage*>& _rPrevwPages, |
| const Fraction& _rScale, |
| const SwPageFrm* _pSelectedPageFrm, |
| const Size& _rPrevwWinSize ); |
| |
| // OD 14.01.2003 #103492# - complete re-factoring of method due to new |
| // page/print preview functionality. |
| void InvalidateSelection( const SwPageFrm* _pSelectedPageFrm ); |
| |
| const SwRect& GetVisArea() const; |
| |
| MapMode GetMapModeForPreview( ) const; |
| |
| /** Adjust the MapMode so that the preview page appears at the |
| * proper position. rPoint identifies the page for which the |
| * MapMode should be adjusted. If bFromPreview is true, rPoint is |
| * a preview coordinate; else it's a document coordinate. */ |
| // OD 17.01.2003 #103492# - delete unused 3rd parameter. |
| void AdjustMapMode( MapMode& rMapMode, |
| const Point& rPoint ) const; |
| |
| inline const SwPageFrm *GetSelPage() const { return mpSelPage; } |
| |
| void DisposePage(const SwPageFrm *pPageFrm ); |
| }; |
| |
| SwAccPreviewData::SwAccPreviewData() : |
| mpSelPage( 0 ) |
| { |
| } |
| |
| SwAccPreviewData::~SwAccPreviewData() |
| { |
| } |
| |
| // OD 13.01.2003 #103492# - complete re-factoring of method due to new page/print |
| // preview functionality. |
| void SwAccPreviewData::Update( const SwAccessibleMap& rAccMap, |
| const std::vector<PrevwPage*>& _rPrevwPages, |
| const Fraction& _rScale, |
| const SwPageFrm* _pSelectedPageFrm, |
| const Size& _rPrevwWinSize ) |
| { |
| // store preview scaling, maximal preview page size and selected page |
| maScale = _rScale; |
| mpSelPage = _pSelectedPageFrm; |
| |
| // prepare loop on preview pages |
| maPreviewRects.clear(); |
| maLogicRects.clear(); |
| SwAccessibleChild aPage; |
| maVisArea.Clear(); |
| |
| // loop on preview pages to calculate <maPreviewRects>, <maLogicRects> and |
| // <maVisArea> |
| for ( std::vector<PrevwPage*>::const_iterator aPageIter = _rPrevwPages.begin(); |
| aPageIter != _rPrevwPages.end(); |
| ++aPageIter ) |
| { |
| aPage = (*aPageIter)->pPage; |
| |
| // add preview page rectangle to <maPreviewRects> |
| Rectangle aPrevwPgRect( (*aPageIter)->aPrevwWinPos, (*aPageIter)->aPageSize ); |
| maPreviewRects.push_back( aPrevwPgRect ); |
| |
| // add logic page rectangle to <maLogicRects> |
| SwRect aLogicPgSwRect( aPage.GetBox( rAccMap ) ); |
| Rectangle aLogicPgRect( aLogicPgSwRect.SVRect() ); |
| maLogicRects.push_back( aLogicPgRect ); |
| // union visible area with visible part of logic page rectangle |
| if ( (*aPageIter)->bVisible ) |
| { |
| if ( !(*aPageIter)->pPage->IsEmptyPage() ) |
| { |
| AdjustLogicPgRectToVisibleArea( aLogicPgSwRect, |
| SwRect( aPrevwPgRect ), |
| _rPrevwWinSize ); |
| } |
| if ( maVisArea.IsEmpty() ) |
| maVisArea = aLogicPgSwRect; |
| else |
| maVisArea.Union( aLogicPgSwRect ); |
| } |
| } |
| } |
| |
| // OD 16.01.2003 #103492# - complete re-factoring of method due to new page/print |
| // preview functionality. |
| void SwAccPreviewData::InvalidateSelection( const SwPageFrm* _pSelectedPageFrm ) |
| { |
| mpSelPage = _pSelectedPageFrm; |
| ASSERT( mpSelPage, "selected page not found" ); |
| } |
| |
| struct ContainsPredicate |
| { |
| const Point& mrPoint; |
| ContainsPredicate( const Point& rPoint ) : mrPoint(rPoint) {} |
| bool operator() ( const Rectangle& rRect ) const |
| { |
| return rRect.IsInside( mrPoint ) ? true : false; |
| } |
| }; |
| |
| const SwRect& SwAccPreviewData::GetVisArea() const |
| { |
| return maVisArea; |
| } |
| |
| void SwAccPreviewData::AdjustMapMode( MapMode& rMapMode, |
| const Point& rPoint ) const |
| { |
| // adjust scale |
| rMapMode.SetScaleX( maScale ); |
| rMapMode.SetScaleY( maScale ); |
| |
| // find proper rectangle |
| Rectangles::const_iterator aBegin = maLogicRects.begin(); |
| Rectangles::const_iterator aEnd = maLogicRects.end(); |
| Rectangles::const_iterator aFound = ::std::find_if( aBegin, aEnd, |
| ContainsPredicate( rPoint ) ); |
| |
| if( aFound != aEnd ) |
| { |
| // found! set new origin |
| Point aPoint = (maPreviewRects.begin() + (aFound - aBegin))->TopLeft(); |
| aPoint -= (maLogicRects.begin() + (aFound-aBegin))->TopLeft(); |
| rMapMode.SetOrigin( aPoint ); |
| } |
| // else: don't adjust MapMode |
| } |
| |
| void SwAccPreviewData::DisposePage(const SwPageFrm *pPageFrm ) |
| { |
| if( mpSelPage == pPageFrm ) |
| mpSelPage = 0; |
| } |
| |
| /** adjust logic page retangle to its visible part |
| |
| OD 17.01.2003 #103492# |
| |
| @author OD |
| */ |
| void SwAccPreviewData::AdjustLogicPgRectToVisibleArea( |
| SwRect& _iorLogicPgSwRect, |
| const SwRect& _rPrevwPgSwRect, |
| const Size& _rPrevwWinSize ) |
| { |
| // determine preview window rectangle |
| const SwRect aPrevwWinSwRect( Point( 0, 0 ), _rPrevwWinSize ); |
| // calculate visible preview page rectangle |
| SwRect aVisPrevwPgSwRect( _rPrevwPgSwRect ); |
| aVisPrevwPgSwRect.Intersection( aPrevwWinSwRect ); |
| // adjust logic page rectangle |
| SwTwips nTmpDiff; |
| // left |
| nTmpDiff = aVisPrevwPgSwRect.Left() - _rPrevwPgSwRect.Left(); |
| if ( nTmpDiff > 0 ) |
| _iorLogicPgSwRect.Left( _iorLogicPgSwRect.Left() + nTmpDiff ); |
| // top |
| nTmpDiff = aVisPrevwPgSwRect.Top() - _rPrevwPgSwRect.Top(); |
| if ( nTmpDiff > 0 ) |
| _iorLogicPgSwRect.Top( _iorLogicPgSwRect.Top() + nTmpDiff ); |
| // right |
| nTmpDiff = _rPrevwPgSwRect.Right() - aVisPrevwPgSwRect.Right(); |
| if ( nTmpDiff > 0 ) |
| _iorLogicPgSwRect.Right( _iorLogicPgSwRect.Right() - nTmpDiff ); |
| // bottom |
| nTmpDiff = _rPrevwPgSwRect.Bottom() - aVisPrevwPgSwRect.Bottom(); |
| if ( nTmpDiff > 0 ) |
| _iorLogicPgSwRect.Bottom( _iorLogicPgSwRect.Bottom() - nTmpDiff ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| static sal_Bool AreInSameTable( const uno::Reference< XAccessible >& rAcc, |
| const SwFrm *pFrm ) |
| { |
| sal_Bool bRet = sal_False; |
| |
| if( pFrm && pFrm->IsCellFrm() && rAcc.is() ) |
| { |
| // Is it in the same table? We check that |
| // by comparing the last table frame in the |
| // follow chain, because that's cheaper than |
| // searching the first one. |
| SwAccessibleContext *pAccImpl = |
| static_cast< SwAccessibleContext *>( rAcc.get() ); |
| if( pAccImpl->GetFrm()->IsCellFrm() ) |
| { |
| const SwTabFrm *pTabFrm1 = pAccImpl->GetFrm()->FindTabFrm(); |
| while( pTabFrm1->GetFollow() ) |
| pTabFrm1 = pTabFrm1->GetFollow(); |
| |
| const SwTabFrm *pTabFrm2 = pFrm->FindTabFrm(); |
| while( pTabFrm2->GetFollow() ) |
| pTabFrm2 = pTabFrm2->GetFollow(); |
| |
| bRet = (pTabFrm1 == pTabFrm2); |
| } |
| } |
| |
| return bRet; |
| } |
| |
| void SwAccessibleMap::FireEvent( const SwAccessibleEvent_Impl& rEvent ) |
| { |
| ::vos::ORef < SwAccessibleContext > xAccImpl( rEvent.GetContext() ); |
| if (!xAccImpl.isValid() && rEvent.mpParentFrm != 0 ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( rEvent.mpParentFrm ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| if (xAcc.is()) |
| { |
| uno::Reference < XAccessibleContext > xContext(xAcc,uno::UNO_QUERY); |
| if (xContext.is() && xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) |
| { |
| xAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() ); |
| } |
| } |
| } |
| } |
| if( SwAccessibleEvent_Impl::SHAPE_SELECTION == rEvent.GetType() ) |
| { |
| DoInvalidateShapeSelection(); |
| } |
| else if( xAccImpl.isValid() && xAccImpl->GetFrm() ) |
| { |
| // --> OD 2009-01-07 #i88069# |
| if ( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE && |
| rEvent.IsInvalidateTextAttrs() ) |
| { |
| xAccImpl->InvalidateAttr(); |
| } |
| // <-- |
| switch( rEvent.GetType() ) |
| { |
| case SwAccessibleEvent_Impl::INVALID_CONTENT: |
| xAccImpl->InvalidateContent(); |
| break; |
| case SwAccessibleEvent_Impl::POS_CHANGED: |
| xAccImpl->InvalidatePosOrSize( rEvent.GetOldBox() ); |
| break; |
| case SwAccessibleEvent_Impl::CHILD_POS_CHANGED: |
| xAccImpl->InvalidateChildPosOrSize( rEvent.GetFrmOrObj(), |
| rEvent.GetOldBox() ); |
| break; |
| case SwAccessibleEvent_Impl::DISPOSE: |
| ASSERT( xAccImpl.isValid(), |
| "dispose event has been stored" ); |
| break; |
| // --> OD 2009-01-06 #i88069# |
| case SwAccessibleEvent_Impl::INVALID_ATTR: |
| // nothing to do here - handled above |
| break; |
| // <-- |
| default: |
| break; |
| } |
| if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() ) |
| { |
| if( rEvent.IsUpdateCursorPos() ) |
| xAccImpl->InvalidateCursorPos(); |
| if( rEvent.IsInvalidateStates() ) |
| xAccImpl->InvalidateStates( rEvent.GetStates() ); |
| if( rEvent.IsInvalidateRelation() ) |
| { |
| // --> OD 2005-12-01 #i27138# |
| // both events CONTENT_FLOWS_FROM_RELATION_CHANGED and |
| // CONTENT_FLOWS_TO_RELATION_CHANGED are possible |
| if ( rEvent.GetAllStates() & ACC_STATE_RELATION_FROM ) |
| { |
| xAccImpl->InvalidateRelation( |
| AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED ); |
| } |
| if ( rEvent.GetAllStates() & ACC_STATE_RELATION_TO ) |
| { |
| xAccImpl->InvalidateRelation( |
| AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED ); |
| } |
| // <-- |
| } |
| // --> OD 2005-12-12 #i27301# - submit event TEXT_SELECTION_CHANGED |
| if ( rEvent.IsInvalidateTextSelection() ) |
| { |
| xAccImpl->InvalidateTextSelection(); |
| } |
| // <-- |
| } |
| } |
| } |
| |
| void SwAccessibleMap::AppendEvent( const SwAccessibleEvent_Impl& rEvent ) |
| { |
| vos::OGuard aGuard( maEventMutex ); |
| |
| if( !mpEvents ) |
| mpEvents = new SwAccessibleEventList_Impl; |
| if( !mpEventMap ) |
| mpEventMap = new SwAccessibleEventMap_Impl; |
| |
| if( mpEvents->IsFiring() ) |
| { |
| // While events are fired new ones are generated. They have to be fired |
| // now. This does not work for DISPOSE events! |
| ASSERT( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE, |
| "dispose event while firing events" ); |
| FireEvent( rEvent ); |
| } |
| else |
| { |
| |
| SwAccessibleEventMap_Impl::iterator aIter = |
| mpEventMap->find( rEvent.GetFrmOrObj() ); |
| if( aIter != mpEventMap->end() ) |
| { |
| SwAccessibleEvent_Impl aEvent( *(*aIter).second ); |
| ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE, |
| "dispose events should not be stored" ); |
| sal_Bool bAppendEvent = sal_True; |
| switch( rEvent.GetType() ) |
| { |
| case SwAccessibleEvent_Impl::CARET_OR_STATES: |
| // A CARET_OR_STATES event is added to any other |
| // event only. It is broadcasted after any other event, so the |
| // event should be put to the back. |
| ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED, |
| "invalid event combination" ); |
| aEvent.SetStates( rEvent.GetAllStates() ); |
| break; |
| case SwAccessibleEvent_Impl::INVALID_CONTENT: |
| // An INVALID_CONTENT event overwrites a CARET_OR_STATES |
| // event (but keeps its flags) and it is contained in a |
| // POS_CHANGED event. |
| // Therefor, the event's type has to be adapted and the event |
| // has to be put at the end. |
| ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED, |
| "invalid event combination" ); |
| if( aEvent.GetType() == SwAccessibleEvent_Impl::CARET_OR_STATES ) |
| aEvent.SetType( SwAccessibleEvent_Impl::INVALID_CONTENT ); |
| break; |
| case SwAccessibleEvent_Impl::POS_CHANGED: |
| // A pos changed event overwrites CARET_STATES (keeping its |
| // flags) as well as INVALID_CONTENT. The old box position |
| // has to be stored however if the old event is not a |
| // POS_CHANGED itself. |
| ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED, |
| "invalid event combination" ); |
| if( aEvent.GetType() != SwAccessibleEvent_Impl::POS_CHANGED ) |
| aEvent.SetOldBox( rEvent.GetOldBox() ); |
| aEvent.SetType( SwAccessibleEvent_Impl::POS_CHANGED ); |
| break; |
| case SwAccessibleEvent_Impl::CHILD_POS_CHANGED: |
| // CHILD_POS_CHANGED events can only follow CHILD_POS_CHANGED |
| // events. The only action that needs to be done again is |
| // to put the old event to the back. The new one cannot be used, |
| // because we are interested in the old frame bounds. |
| ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::CHILD_POS_CHANGED, |
| "invalid event combination" ); |
| break; |
| case SwAccessibleEvent_Impl::SHAPE_SELECTION: |
| ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::SHAPE_SELECTION, |
| "invalid event combination" ); |
| break; |
| case SwAccessibleEvent_Impl::DISPOSE: |
| // DISPOSE events overwrite all others. They are not stored |
| // but executed immediately to avoid broadcasting of |
| // defunctional objects. So what needs to be done here is to |
| // remove all events for the frame in question. |
| bAppendEvent = sal_False; |
| break; |
| // --> OD 2009-01-06 #i88069# |
| case SwAccessibleEvent_Impl::INVALID_ATTR: |
| ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR, |
| "invalid event combination" ); |
| break; |
| // <-- |
| } |
| if( bAppendEvent ) |
| { |
| mpEvents->erase( (*aIter).second ); |
| (*aIter).second = mpEvents->insert( mpEvents->end(), aEvent ); |
| } |
| else |
| { |
| mpEvents->erase( (*aIter).second ); |
| mpEventMap->erase( aIter ); |
| } |
| } |
| else if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() ) |
| { |
| SwAccessibleEventMap_Impl::value_type aEntry( rEvent.GetFrmOrObj(), |
| mpEvents->insert( mpEvents->end(), rEvent ) ); |
| mpEventMap->insert( aEntry ); |
| } |
| } |
| } |
| |
| void SwAccessibleMap::InvalidateCursorPosition( |
| const uno::Reference< XAccessible >& rAcc ) |
| { |
| SwAccessibleContext *pAccImpl = |
| static_cast< SwAccessibleContext *>( rAcc.get() ); |
| ASSERT( pAccImpl, "no caret context" ); |
| ASSERT( pAccImpl->GetFrm(), "caret context is disposed" ); |
| if( GetShell()->ActionPend() ) |
| { |
| SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES, |
| pAccImpl, |
| SwAccessibleChild(pAccImpl->GetFrm()), |
| ACC_STATE_CARET ); |
| AppendEvent( aEvent ); |
| } |
| else |
| { |
| FireEvents(); |
| // While firing events the current frame might have |
| // been disposed because it moved out of the vis area. |
| // Setting the cursor for such frames is useless and even |
| // causes asserts. |
| if( pAccImpl->GetFrm() ) |
| pAccImpl->InvalidateCursorPos(); |
| } |
| } |
| |
| void SwAccessibleMap::InvalidateShapeSelection() |
| { |
| if( GetShell()->ActionPend() ) |
| { |
| SwAccessibleEvent_Impl aEvent( |
| SwAccessibleEvent_Impl::SHAPE_SELECTION ); |
| AppendEvent( aEvent ); |
| } |
| else |
| { |
| FireEvents(); |
| DoInvalidateShapeSelection(); |
| } |
| } |
| //This method should implement the following functions: |
| //1.find the shape objects and set the selected state. |
| //2.find the Swframe objects and set the selected state. |
| //3.find the paragraph objects and set the selected state. |
| void SwAccessibleMap::InvalidateShapeInParaSelection() |
| { |
| SwAccessibleObjShape_Impl *pShapes = 0; |
| SwAccessibleObjShape_Impl *pSelShape = 0; |
| size_t nShapes = 0; |
| |
| const ViewShell *pVSh = GetShell(); |
| const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ? |
| static_cast< const SwFEShell * >( pVSh ) : 0; |
| SwPaM* pCrsr = pFESh ? pFESh->GetCrsr( sal_False /* ??? */ ) : NULL; |
| //sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0; |
| |
| { |
| vos::OGuard aGuard( maMutex ); |
| if( mpShapeMap ) |
| pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape ); |
| } |
| |
| sal_Bool bIsSelAll =IsDocumentSelAll(); |
| |
| if( mpShapeMap ) |
| { |
| //Checked for shapes. |
| _SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin(); |
| _SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end(); |
| ::vos::ORef< SwAccessibleContext > xParentAccImpl; |
| |
| if( bIsSelAll) |
| { |
| while( aIter != aEndIter ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| if( xAcc.is() ) |
| (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->SetState( AccessibleStateType::SELECTED ); |
| |
| ++aIter; |
| } |
| } |
| else |
| { |
| while( aIter != aEndIter ) |
| { |
| sal_Bool bChanged = sal_False; |
| sal_Bool bMarked = sal_False; |
| SwAccessibleChild pFrm( (*aIter).first ); |
| |
| const SwFrmFmt *pFrmFmt = (*aIter).first ? ::FindFrmFmt( (*aIter).first ) : 0; |
| if( !pFrmFmt ) { ++aIter; continue; } |
| const SwFmtAnchor& pAnchor = pFrmFmt->GetAnchor(); |
| const SwPosition *pPos = pAnchor.GetCntntAnchor(); |
| |
| if(pAnchor.GetAnchorId() == FLY_AT_PAGE) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| if(xAcc.is()) |
| (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED ); |
| |
| ++aIter; continue; |
| } |
| |
| if( !pPos ) { ++aIter; continue; } |
| if( pPos->nNode.GetNode().GetTxtNode() ) |
| { |
| int pIndex = pPos->nContent.GetIndex(); |
| SwPaM* pTmpCrsr = pCrsr; |
| if( pTmpCrsr != NULL ) |
| { |
| const SwTxtNode* pNode = pPos->nNode.GetNode().GetTxtNode(); |
| sal_uLong nHere = pNode->GetIndex(); |
| |
| do |
| { |
| // ignore, if no mark |
| if( pTmpCrsr->HasMark() ) |
| { |
| bMarked = sal_True; |
| // check whether nHere is 'inside' pCrsr |
| SwPosition* pStart = pTmpCrsr->Start(); |
| sal_uLong nStartIndex = pStart->nNode.GetIndex(); |
| SwPosition* pEnd = pTmpCrsr->End(); |
| sal_uLong nEndIndex = pEnd->nNode.GetIndex(); |
| if( ( nHere >= nStartIndex ) && (nHere <= nEndIndex) ) |
| { |
| if( pAnchor.GetAnchorId() == FLY_AS_CHAR ) |
| { |
| if( ( (nHere == nStartIndex) && (pIndex >= pStart->nContent.GetIndex()) || (nHere > nStartIndex) ) |
| &&( (nHere == nEndIndex) && (pIndex < pEnd->nContent.GetIndex()) || (nHere < nEndIndex) ) ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| if( xAcc.is() ) |
| bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->SetState( AccessibleStateType::SELECTED ); |
| } |
| else |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| if( xAcc.is() ) |
| bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED ); |
| } |
| } |
| else if( pAnchor.GetAnchorId() == FLY_AT_PARA ) |
| { |
| if( ((nHere > nStartIndex) || pStart->nContent.GetIndex() ==0 ) |
| && (nHere < nEndIndex ) ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| if( xAcc.is() ) |
| bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->SetState( AccessibleStateType::SELECTED ); |
| } |
| else |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| if(xAcc.is()) |
| bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED ); |
| } |
| } |
| } |
| } |
| // next PaM in ring |
| pTmpCrsr = static_cast<SwPaM*>( pTmpCrsr->GetNext() ); |
| } |
| while( pTmpCrsr != pCrsr ); |
| } |
| if( !bMarked ) |
| { |
| SwAccessibleObjShape_Impl *pShape = pShapes; |
| size_t nNumShapes = nShapes; |
| while( nNumShapes ) |
| { |
| if( pShape < pSelShape && (pShape->first==(*aIter).first) ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| if(xAcc.is()) |
| bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED ); |
| } |
| --nNumShapes; |
| ++pShape; |
| } |
| } |
| } |
| ++aIter; |
| }//while( aIter != aEndIter ) |
| }//else |
| } |
| |
| //Checked for FlyFrm |
| SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin(); |
| while( aIter != mpFrmMap->end() ) |
| { |
| const SwFrm *pFrm = (*aIter).first; |
| if(pFrm->IsFlyFrm()) |
| { |
| sal_Bool bFrmChanged = sal_False; |
| uno::Reference < XAccessible > xAcc = (*aIter).second; |
| |
| if(xAcc.is()) |
| { |
| SwAccessibleFrameBase *pAccFrame = (static_cast< SwAccessibleFrameBase * >(xAcc.get())); |
| bFrmChanged = pAccFrame->SetSelectedState( sal_True ); |
| if (bFrmChanged) |
| { |
| const SwFlyFrm *pFlyFrm = static_cast< const SwFlyFrm * >( pFrm ); |
| const SwFrmFmt *pFrmFmt = pFlyFrm->GetFmt(); |
| if (pFrmFmt) |
| { |
| const SwFmtAnchor& pAnchor = pFrmFmt->GetAnchor(); |
| if( pAnchor.GetAnchorId() == FLY_AS_CHAR ) |
| { |
| uno::Reference< XAccessible > xAccParent = pAccFrame->getAccessibleParent(); |
| if (xAccParent.is()) |
| { |
| uno::Reference< XAccessibleContext > xAccContext = xAccParent->getAccessibleContext(); |
| if(xAccContext.is() && xAccContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) |
| { |
| SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xAccContext.get()); |
| if(pAccFrame->IsSeletedInDoc()) |
| { |
| m_setParaAdd.insert(pAccPara); |
| } |
| else if(m_setParaAdd.count(pAccPara) == 0) |
| { |
| m_setParaRemove.insert(pAccPara); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| ++aIter; |
| } |
| typedef std::vector< SwAccessibleContext* > VEC_PARA; |
| VEC_PARA vecAdd; |
| VEC_PARA vecRemove; |
| //Checked for Paras. |
| SwPaM* pTmpCrsr = pCrsr; |
| sal_Bool bMarkChanged = sal_False; |
| SwAccessibleContextMap_Impl mapTemp; |
| if( pTmpCrsr != NULL ) |
| { |
| do |
| { |
| if( pTmpCrsr->HasMark() ) |
| { |
| SwNodeIndex nStartIndex( pTmpCrsr->Start()->nNode ); |
| SwNodeIndex nEndIndex( pTmpCrsr->End()->nNode ); |
| while(nStartIndex <= nEndIndex) |
| { |
| SwFrm *pFrm = NULL; |
| if(nStartIndex.GetNode().IsCntntNode()) |
| { |
| SwCntntNode* pCNd = (SwCntntNode*)&(nStartIndex.GetNode()); |
| SwClientIter aClientIter( *pCNd ); |
| pFrm = (SwFrm*)aClientIter.First( TYPE(SwFrm)); |
| } |
| else if( nStartIndex.GetNode().IsTableNode() ) |
| { |
| SwTableNode * pTable= (SwTableNode *)&(nStartIndex.GetNode()); |
| SwFrmFmt* pFmt = const_cast<SwFrmFmt*>(pTable->GetTable().GetFrmFmt()); |
| SwClientIter aClientIter( *pFmt ); |
| pFrm = (SwFrm*)aClientIter.First( TYPE(SwFrm)); |
| } |
| |
| if( pFrm && mpFrmMap) |
| { |
| aIter = mpFrmMap->find( pFrm ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| uno::Reference < XAccessible > xAcc = (*aIter).second; |
| sal_Bool isChanged = sal_False; |
| if( xAcc.is() ) |
| { |
| isChanged = (static_cast< SwAccessibleContext * >(xAcc.get()))->SetSelectedState( sal_True ); |
| } |
| if(!isChanged) |
| { |
| SwAccessibleContextMap_Impl::iterator aEraseIter = mpSeletedFrmMap->find( pFrm ); |
| if(aEraseIter != mpSeletedFrmMap->end()) |
| mpSeletedFrmMap->erase(aEraseIter); |
| } |
| else |
| { |
| bMarkChanged = sal_True; |
| vecAdd.push_back(static_cast< SwAccessibleContext * >(xAcc.get())); |
| } |
| |
| mapTemp.insert( SwAccessibleContextMap_Impl::value_type( pFrm, xAcc ) ); |
| } |
| } |
| nStartIndex++; |
| } |
| } |
| pTmpCrsr = static_cast<SwPaM*>( pTmpCrsr->GetNext() ); |
| } |
| while( pTmpCrsr != pCrsr ); |
| } |
| if( !mpSeletedFrmMap ) |
| mpSeletedFrmMap = new SwAccessibleContextMap_Impl; |
| if( !mpSeletedFrmMap->empty() ) |
| { |
| aIter = mpSeletedFrmMap->begin(); |
| while( aIter != mpSeletedFrmMap->end() ) |
| { |
| uno::Reference < XAccessible > xAcc = (*aIter).second; |
| if(xAcc.is()) |
| (static_cast< SwAccessibleContext * >(xAcc.get()))->SetSelectedState( sal_False ); |
| ++aIter; |
| vecRemove.push_back(static_cast< SwAccessibleContext * >(xAcc.get())); |
| } |
| bMarkChanged = sal_True; |
| mpSeletedFrmMap->clear(); |
| } |
| |
| if( !mapTemp.empty() ) |
| { |
| aIter = mapTemp.begin(); |
| while( aIter != mapTemp.end() ) |
| { |
| mpSeletedFrmMap->insert( SwAccessibleContextMap_Impl::value_type( (*aIter).first, (*aIter).second ) ); |
| ++aIter; |
| } |
| mapTemp.clear(); |
| } |
| if( bMarkChanged && mpFrmMap) |
| { |
| VEC_PARA::iterator vi = vecAdd.begin(); |
| for (; vi != vecAdd.end() ; ++vi) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; |
| SwAccessibleContext* pAccPara = *vi; |
| if (pAccPara) |
| { |
| pAccPara->FireAccessibleEvent( aEvent ); |
| } |
| } |
| vi = vecRemove.begin(); |
| for (; vi != vecRemove.end() ; ++vi) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; |
| SwAccessibleContext* pAccPara = *vi; |
| if (pAccPara) |
| { |
| pAccPara->FireAccessibleEvent( aEvent ); |
| } |
| } |
| } |
| } |
| |
| //Marge with DoInvalidateShapeFocus |
| void SwAccessibleMap::DoInvalidateShapeSelection(sal_Bool bInvalidateFocusMode /*=sal_False*/) |
| { |
| SwAccessibleObjShape_Impl *pShapes = 0; |
| SwAccessibleObjShape_Impl *pSelShape = 0; |
| size_t nShapes = 0; |
| |
| const ViewShell *pVSh = GetShell(); |
| const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ? |
| static_cast< const SwFEShell * >( pVSh ) : 0; |
| sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0; |
| |
| |
| //when InvalidateFocus Call this function ,and the current selected shape count is not 1 , |
| //return |
| if (bInvalidateFocusMode && nSelShapes != 1) |
| { |
| return; |
| } |
| { |
| vos::OGuard aGuard( maMutex ); |
| if( mpShapeMap ) |
| pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape ); |
| } |
| |
| if( pShapes ) |
| { |
| typedef std::vector< ::vos::ORef < ::accessibility::AccessibleShape > > VEC_SHAPE; |
| VEC_SHAPE vecxShapeAdd; |
| VEC_SHAPE vecxShapeRemove; |
| int nCountSelectedShape=0; |
| |
| Window *pWin = GetShell()->GetWin(); |
| sal_Bool bFocused = pWin && pWin->HasFocus(); |
| SwAccessibleObjShape_Impl *pShape = pShapes; |
| int nShapeCount = nShapes; |
| while( nShapeCount ) |
| { |
| //if( pShape->second.isValid() ) |
| if (pShape->second.isValid() && IsInSameLevel(pShape->first, pFESh)) |
| { |
| if( pShape < pSelShape ) |
| { |
| if(pShape->second->ResetState( AccessibleStateType::SELECTED )) |
| { |
| vecxShapeRemove.push_back(pShape->second); |
| } |
| pShape->second->ResetState( AccessibleStateType::FOCUSED ); |
| } |
| } |
| --nShapeCount; |
| ++pShape; |
| } |
| |
| VEC_SHAPE::iterator vi =vecxShapeRemove.begin(); |
| for (; vi != vecxShapeRemove.end(); ++vi) |
| { |
| ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr()); |
| if (pAccShape) |
| { |
| pAccShape->CommitChange(AccessibleEventId::SELECTION_CHANGED_REMOVE, uno::Any(), uno::Any()); |
| } |
| } |
| |
| pShape = pShapes; |
| while( nShapes ) |
| { |
| //if( pShape->second.isValid() ) |
| if (pShape->second.isValid() && IsInSameLevel(pShape->first, pFESh)) |
| { |
| // IA2 - why? |
| // sal_Bool bChanged; |
| if( pShape >= pSelShape ) |
| { |
| // IA2: first fire focus event |
| // bChanged = pShape->second->SetState( AccessibleStateType::SELECTED ); |
| |
| //first fire focus event |
| if( bFocused && 1 == nSelShapes ) |
| pShape->second->SetState( AccessibleStateType::FOCUSED ); |
| else |
| pShape->second->ResetState( AccessibleStateType::FOCUSED ); |
| |
| if(pShape->second->SetState( AccessibleStateType::SELECTED )) |
| { |
| vecxShapeAdd.push_back(pShape->second); |
| } |
| ++nCountSelectedShape; |
| } |
| /* MT: This still was in DEV300m80, but was removed in IA2 CWS. |
| Someone needs to check what should happen here, see original diff CWS oo31ia2 vs. OOO310M11 |
| else |
| { |
| bChanged = |
| pShape->second->ResetState( AccessibleStateType::SELECTED ); |
| pShape->second->ResetState( AccessibleStateType::FOCUSED ); |
| } |
| if( bChanged ) |
| { |
| const SwFrm* pParent = SwAccessibleFrame::GetParent( |
| SwAccessibleChild( pShape->first ), |
| GetShell()->IsPreView() ); |
| aParents.push_back( pParent ); |
| } |
| */ |
| } |
| |
| --nShapes; |
| ++pShape; |
| } |
| |
| const unsigned int SELECTION_WITH_NUM = 10; |
| if (vecxShapeAdd.size() > SELECTION_WITH_NUM ) |
| { |
| uno::Reference< XAccessible > xDoc = GetDocumentView( ); |
| SwAccessibleContext * pCont = static_cast<SwAccessibleContext *>(xDoc.get()); |
| if (pCont) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; |
| pCont->FireAccessibleEvent(aEvent); |
| } |
| } |
| else |
| { |
| short nEventID = AccessibleEventId::SELECTION_CHANGED_ADD; |
| if (nCountSelectedShape <= 1 && vecxShapeAdd.size() == 1 ) |
| { |
| nEventID = AccessibleEventId::SELECTION_CHANGED; |
| } |
| vi = vecxShapeAdd.begin(); |
| for (; vi != vecxShapeAdd.end(); ++vi) |
| { |
| ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr()); |
| if (pAccShape) |
| { |
| pAccShape->CommitChange(nEventID, uno::Any(), uno::Any()); |
| } |
| } |
| } |
| |
| vi = vecxShapeAdd.begin(); |
| for (; vi != vecxShapeAdd.end(); ++vi) |
| { |
| ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr()); |
| if (pAccShape) |
| { |
| SdrObject *pObj = GetSdrObjectFromXShape(pAccShape->GetXShape()); |
| SwFrmFmt *pFrmFmt = pObj ? FindFrmFmt( pObj ) : NULL; |
| if (pFrmFmt) |
| { |
| const SwFmtAnchor& pAnchor = pFrmFmt->GetAnchor(); |
| if( pAnchor.GetAnchorId() == FLY_AS_CHAR ) |
| { |
| uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent(); |
| if (xPara.is()) |
| { |
| uno::Reference< XAccessibleContext > xParaContext = xPara->getAccessibleContext(); |
| if (xParaContext.is() && xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) |
| { |
| SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xPara.get()); |
| if (pAccPara) |
| { |
| m_setParaAdd.insert(pAccPara); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| vi = vecxShapeRemove.begin(); |
| for (; vi != vecxShapeRemove.end(); ++vi) |
| { |
| ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr()); |
| if (pAccShape) |
| { |
| uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent(); |
| uno::Reference< XAccessibleContext > xParaContext = xPara->getAccessibleContext(); |
| if (xParaContext.is() && xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) |
| { |
| SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xPara.get()); |
| if (m_setParaAdd.count(pAccPara) == 0 ) |
| { |
| m_setParaRemove.insert(pAccPara); |
| } |
| } |
| } |
| } |
| delete[] pShapes; |
| } |
| } |
| |
| //Marge with DoInvalidateShapeSelection |
| /* |
| void SwAccessibleMap::DoInvalidateShapeFocus() |
| { |
| const ViewShell *pVSh = GetShell(); |
| const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ? |
| static_cast< const SwFEShell * >( pVSh ) : 0; |
| sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0; |
| |
| if( nSelShapes != 1 ) |
| return; |
| |
| SwAccessibleObjShape_Impl *pShapes = 0; |
| SwAccessibleObjShape_Impl *pSelShape = 0; |
| size_t nShapes = 0; |
| |
| |
| { |
| vos::OGuard aGuard( maMutex ); |
| if( mpShapeMap ) |
| pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape ); |
| } |
| |
| if( pShapes ) |
| { |
| Window *pWin = GetShell()->GetWin(); |
| sal_Bool bFocused = pWin && pWin->HasFocus(); |
| SwAccessibleObjShape_Impl *pShape = pShapes; |
| while( nShapes ) |
| { |
| if( pShape->second.isValid() ) |
| { |
| if( bFocused && pShape >= pSelShape ) |
| pShape->second->SetState( AccessibleStateType::FOCUSED ); |
| else |
| pShape->second->ResetState( AccessibleStateType::FOCUSED ); |
| } |
| |
| --nShapes; |
| ++pShape; |
| } |
| |
| delete[] pShapes; |
| } |
| } |
| */ |
| |
| SwAccessibleMap::SwAccessibleMap( ViewShell *pSh ) : |
| mpFrmMap( 0 ), |
| mpShapeMap( 0 ), |
| mpShapes( 0 ), |
| mpEvents( 0 ), |
| mpEventMap( 0 ), |
| // --> OD 2005-12-13 #i27301# |
| mpSelectedParas( 0 ), |
| // <-- |
| mpVSh( pSh ), |
| mpPreview( 0 ), |
| mnPara( 1 ), |
| mnFootnote( 1 ), |
| mnEndnote( 1 ), |
| mbShapeSelected( sal_False ), |
| mpSeletedFrmMap(NULL) |
| { |
| pSh->GetLayout()->AddAccessibleShell(); |
| } |
| |
| SwAccessibleMap::~SwAccessibleMap() |
| { |
| uno::Reference < XAccessible > xAcc; |
| { |
| vos::OGuard aGuard( maMutex ); |
| if( mpFrmMap ) |
| { |
| const SwRootFrm *pRootFrm = GetShell()->GetLayout(); |
| SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm ); |
| if( aIter != mpFrmMap->end() ) |
| xAcc = (*aIter).second; |
| if( !xAcc.is() ) |
| xAcc = new SwAccessibleDocument( this ); |
| } |
| } |
| |
| if(xAcc.is()) |
| { |
| SwAccessibleDocument *pAcc = |
| static_cast< SwAccessibleDocument * >( xAcc.get() ); |
| pAcc->Dispose( sal_True ); |
| } |
| if( mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin(); |
| while( aIter != mpFrmMap->end() ) |
| { |
| uno::Reference < XAccessible > xTmp = (*aIter).second; |
| if( xTmp.is() ) |
| { |
| SwAccessibleContext *pTmp = static_cast< SwAccessibleContext * >( xTmp.get() ); |
| pTmp->SetMap(NULL); |
| } |
| ++aIter; |
| } |
| } |
| { |
| vos::OGuard aGuard( maMutex ); |
| #ifdef DBG_UTIL |
| ASSERT( !mpFrmMap || mpFrmMap->empty(), |
| "Frame map should be empty after disposing the root frame" ); |
| if( mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin(); |
| while( aIter != mpFrmMap->end() ) |
| { |
| uno::Reference < XAccessible > xTmp = (*aIter).second; |
| if( xTmp.is() ) |
| { |
| SwAccessibleContext *pTmp = |
| static_cast< SwAccessibleContext * >( xTmp.get() ); |
| (void) pTmp; |
| } |
| ++aIter; |
| } |
| } |
| ASSERT( !mpShapeMap || mpShapeMap->empty(), |
| "Object map should be empty after disposing the root frame" ); |
| if( mpShapeMap ) |
| { |
| SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->begin(); |
| while( aIter != mpShapeMap->end() ) |
| { |
| uno::Reference < XAccessible > xTmp = (*aIter).second; |
| if( xTmp.is() ) |
| { |
| ::accessibility::AccessibleShape *pTmp = |
| static_cast< ::accessibility::AccessibleShape* >( xTmp.get() ); |
| (void) pTmp; |
| } |
| ++aIter; |
| } |
| } |
| #endif |
| delete mpFrmMap; |
| mpFrmMap = 0; |
| delete mpShapeMap; |
| mpShapeMap = 0; |
| delete mpShapes; |
| mpShapes = 0; |
| // --> OD 2005-12-13 #i27301# |
| delete mpSelectedParas; |
| mpSelectedParas = 0; |
| // <-- |
| } |
| |
| delete mpPreview; |
| mpPreview = NULL; |
| |
| { |
| vos::OGuard aGuard( maEventMutex ); |
| #ifdef DBG_UTIL |
| ASSERT( !(mpEvents || mpEventMap), "pending events" ); |
| if( mpEvents ) |
| { |
| SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin(); |
| while( aIter != mpEvents->end() ) |
| { |
| ++aIter; |
| } |
| } |
| if( mpEventMap ) |
| { |
| SwAccessibleEventMap_Impl::iterator aIter = mpEventMap->begin(); |
| while( aIter != mpEventMap->end() ) |
| { |
| ++aIter; |
| } |
| } |
| #endif |
| delete mpEventMap; |
| mpEventMap = 0; |
| delete mpEvents; |
| mpEvents = 0; |
| } |
| mpVSh->GetLayout()->RemoveAccessibleShell(); |
| delete mpSeletedFrmMap; |
| } |
| |
| uno::Reference< XAccessible > SwAccessibleMap::_GetDocumentView( |
| sal_Bool bPagePreview ) |
| { |
| uno::Reference < XAccessible > xAcc; |
| sal_Bool bSetVisArea = sal_False; |
| |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( !mpFrmMap ) |
| { |
| mpFrmMap = new SwAccessibleContextMap_Impl; |
| #ifdef DBG_UTIL |
| mpFrmMap->mbLocked = sal_False; |
| #endif |
| } |
| |
| #ifdef DBG_UTIL |
| ASSERT( !mpFrmMap->mbLocked, "Map is locked" ); |
| mpFrmMap->mbLocked = sal_True; |
| #endif |
| |
| const SwRootFrm *pRootFrm = GetShell()->GetLayout(); |
| SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm ); |
| if( aIter != mpFrmMap->end() ) |
| xAcc = (*aIter).second; |
| if( xAcc.is() ) |
| { |
| bSetVisArea = sal_True; // Set VisArea when map mutex is not |
| // locked |
| } |
| else |
| { |
| if( bPagePreview ) |
| xAcc = new SwAccessiblePreview( this ); |
| else |
| xAcc = new SwAccessibleDocument( this ); |
| |
| if( aIter != mpFrmMap->end() ) |
| { |
| (*aIter).second = xAcc; |
| } |
| else |
| { |
| SwAccessibleContextMap_Impl::value_type aEntry( pRootFrm, xAcc ); |
| mpFrmMap->insert( aEntry ); |
| } |
| } |
| |
| #ifdef DBG_UTIL |
| mpFrmMap->mbLocked = sal_False; |
| #endif |
| } |
| |
| if( bSetVisArea ) |
| { |
| SwAccessibleDocumentBase *pAcc = |
| static_cast< SwAccessibleDocumentBase * >( xAcc.get() ); |
| pAcc->SetVisArea(); |
| } |
| |
| return xAcc; |
| } |
| |
| uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView( ) |
| { |
| return _GetDocumentView( sal_False ); |
| } |
| |
| // OD 14.01.2003 #103492# - complete re-factoring of method due to new page/print |
| // preview functionality. |
| uno::Reference<XAccessible> SwAccessibleMap::GetDocumentPreview( |
| const std::vector<PrevwPage*>& _rPrevwPages, |
| const Fraction& _rScale, |
| const SwPageFrm* _pSelectedPageFrm, |
| const Size& _rPrevwWinSize ) |
| { |
| // create & update preview data object |
| if( mpPreview == NULL ) |
| mpPreview = new SwAccPreviewData(); |
| mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize ); |
| |
| uno::Reference<XAccessible> xAcc = _GetDocumentView( sal_True ); |
| return xAcc; |
| } |
| |
| uno::Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrm *pFrm, |
| sal_Bool bCreate ) |
| { |
| uno::Reference < XAccessible > xAcc; |
| uno::Reference < XAccessible > xOldCursorAcc; |
| sal_Bool bOldShapeSelected = sal_False; |
| |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( !mpFrmMap && bCreate ) |
| mpFrmMap = new SwAccessibleContextMap_Impl; |
| if( mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pFrm ); |
| if( aIter != mpFrmMap->end() ) |
| xAcc = (*aIter).second; |
| |
| if( !xAcc.is() && bCreate ) |
| { |
| SwAccessibleContext *pAcc = 0; |
| switch( pFrm->GetType() ) |
| { |
| case FRM_TXT: |
| mnPara++; |
| pAcc = new SwAccessibleParagraph( *this, |
| static_cast< const SwTxtFrm& >( *pFrm ) ); |
| break; |
| case FRM_HEADER: |
| pAcc = new SwAccessibleHeaderFooter( this, |
| static_cast< const SwHeaderFrm *>( pFrm ) ); |
| break; |
| case FRM_FOOTER: |
| pAcc = new SwAccessibleHeaderFooter( this, |
| static_cast< const SwFooterFrm *>( pFrm ) ); |
| break; |
| case FRM_FTN: |
| { |
| const SwFtnFrm *pFtnFrm = |
| static_cast < const SwFtnFrm * >( pFrm ); |
| sal_Bool bIsEndnote = |
| SwAccessibleFootnote::IsEndnote( pFtnFrm ); |
| pAcc = new SwAccessibleFootnote( this, bIsEndnote, |
| /*(bIsEndnote ? mnEndnote++ : mnFootnote++),*/ |
| pFtnFrm ); |
| } |
| break; |
| case FRM_FLY: |
| { |
| const SwFlyFrm *pFlyFrm = |
| static_cast < const SwFlyFrm * >( pFrm ); |
| switch( SwAccessibleFrameBase::GetNodeType( pFlyFrm ) ) |
| { |
| case ND_GRFNODE: |
| pAcc = new SwAccessibleGraphic( this, pFlyFrm ); |
| break; |
| case ND_OLENODE: |
| pAcc = new SwAccessibleEmbeddedObject( this, pFlyFrm ); |
| break; |
| default: |
| pAcc = new SwAccessibleTextFrame( this, pFlyFrm ); |
| break; |
| } |
| } |
| break; |
| case FRM_CELL: |
| pAcc = new SwAccessibleCell( this, |
| static_cast< const SwCellFrm *>( pFrm ) ); |
| break; |
| case FRM_TAB: |
| pAcc = new SwAccessibleTable( this, |
| static_cast< const SwTabFrm *>( pFrm ) ); |
| break; |
| case FRM_PAGE: |
| DBG_ASSERT( GetShell()->IsPreView(), |
| "accessible page frames only in PagePreview" ); |
| pAcc = new SwAccessiblePage( this, pFrm ); |
| break; |
| } |
| xAcc = pAcc; |
| |
| ASSERT( xAcc.is(), "unknown frame type" ); |
| if( xAcc.is() ) |
| { |
| if( aIter != mpFrmMap->end() ) |
| { |
| (*aIter).second = xAcc; |
| } |
| else |
| { |
| SwAccessibleContextMap_Impl::value_type aEntry( pFrm, xAcc ); |
| mpFrmMap->insert( aEntry ); |
| } |
| |
| if( pAcc->HasCursor() && |
| !AreInSameTable( mxCursorContext, pFrm ) ) |
| { |
| // If the new context has the focus, and if we know |
| // another context that had the focus, then the focus |
| // just moves from the old context to the new one. We |
| // have to send a focus event and a caret event for |
| // the old context then. We have to to that know, |
| // because after we have left this method, anyone might |
| // call getStates for the new context and will get a |
| // focused state then. Sending the focus changes event |
| // after that seems to be strange. However, we cannot |
| // send a focus event fo the new context now, because |
| // no one except us knows it. In any case, we remember |
| // the new context as the one that has the focus |
| // currently. |
| |
| xOldCursorAcc = mxCursorContext; |
| mxCursorContext = xAcc; |
| |
| bOldShapeSelected = mbShapeSelected; |
| mbShapeSelected = sal_False; |
| } |
| } |
| } |
| } |
| } |
| |
| // Invalidate focus for old object when map is not locked |
| if( xOldCursorAcc.is() ) |
| InvalidateCursorPosition( xOldCursorAcc ); |
| if( bOldShapeSelected ) |
| InvalidateShapeSelection(); |
| |
| return xAcc; |
| } |
| |
| ::vos::ORef < SwAccessibleContext > SwAccessibleMap::GetContextImpl( |
| const SwFrm *pFrm, |
| sal_Bool bCreate ) |
| { |
| uno::Reference < XAccessible > xAcc( GetContext( pFrm, bCreate ) ); |
| |
| ::vos::ORef < SwAccessibleContext > xAccImpl( |
| static_cast< SwAccessibleContext * >( xAcc.get() ) ); |
| |
| return xAccImpl; |
| } |
| |
| uno::Reference< XAccessible> SwAccessibleMap::GetContext( |
| const SdrObject *pObj, |
| SwAccessibleContext *pParentImpl, |
| sal_Bool bCreate ) |
| { |
| uno::Reference < XAccessible > xAcc; |
| uno::Reference < XAccessible > xOldCursorAcc; |
| |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( !mpShapeMap && bCreate ) |
| mpShapeMap = new SwAccessibleShapeMap_Impl( this ); |
| if( mpShapeMap ) |
| { |
| SwAccessibleShapeMap_Impl::iterator aIter = |
| mpShapeMap->find( pObj ); |
| if( aIter != mpShapeMap->end() ) |
| xAcc = (*aIter).second; |
| |
| if( !xAcc.is() && bCreate ) |
| { |
| ::accessibility::AccessibleShape *pAcc = 0; |
| uno::Reference < drawing::XShape > xShape( |
| const_cast< SdrObject * >( pObj )->getUnoShape(), |
| uno::UNO_QUERY ); |
| if( xShape.is() ) |
| { |
| ::accessibility::ShapeTypeHandler& rShapeTypeHandler = |
| ::accessibility::ShapeTypeHandler::Instance(); |
| uno::Reference < XAccessible > xParent( pParentImpl ); |
| ::accessibility::AccessibleShapeInfo aShapeInfo( |
| xShape, xParent, this ); |
| |
| pAcc = rShapeTypeHandler.CreateAccessibleObject( |
| aShapeInfo, mpShapeMap->GetInfo() ); |
| } |
| xAcc = pAcc; |
| |
| ASSERT( xAcc.is(), "unknown shape type" ); |
| if( xAcc.is() ) |
| { |
| pAcc->Init(); |
| if( aIter != mpShapeMap->end() ) |
| { |
| (*aIter).second = xAcc; |
| } |
| else |
| { |
| SwAccessibleShapeMap_Impl::value_type aEntry( pObj, |
| xAcc ); |
| mpShapeMap->insert( aEntry ); |
| } |
| // TODO: focus!!! |
| } |
| if (xAcc.is()) |
| AddGroupContext(pObj, xAcc); |
| } |
| } |
| } |
| |
| // Invalidate focus for old object when map is not locked |
| if( xOldCursorAcc.is() ) |
| InvalidateCursorPosition( xOldCursorAcc ); |
| |
| return xAcc; |
| } |
| sal_Bool SwAccessibleMap::IsInSameLevel(const SdrObject* pObj, const SwFEShell* pFESh) |
| { |
| if (pFESh) |
| return pFESh->IsObjSameLevelWithMarked(pObj); |
| return sal_False; |
| } |
| void SwAccessibleMap::AddShapeContext(const SdrObject *pObj, uno::Reference < XAccessible > xAccShape) |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( mpShapeMap ) |
| { |
| SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAccShape ); |
| mpShapeMap->insert( aEntry ); |
| } |
| |
| } |
| |
| //Added by yanjun for sym2_6407 |
| void SwAccessibleMap::RemoveGroupContext(const SdrObject *pParentObj, ::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xAccParent) |
| { |
| vos::OGuard aGuard( maMutex ); |
| if (mpShapeMap && pParentObj && pParentObj->IsGroupObject() && xAccParent.is()) |
| { |
| uno::Reference < XAccessibleContext > xContext = xAccParent->getAccessibleContext(); |
| if (xContext.is()) |
| { |
| for (sal_Int32 i = 0; i < xContext->getAccessibleChildCount(); ++i) |
| { |
| uno::Reference < XAccessible > xChild = xContext->getAccessibleChild(i); |
| if (xChild.is()) |
| { |
| uno::Reference < XAccessibleContext > xChildContext = xChild->getAccessibleContext(); |
| if (xChildContext.is()) |
| { |
| if (xChildContext->getAccessibleRole() == AccessibleRole::SHAPE) |
| { |
| ::accessibility::AccessibleShape* pAccShape = static_cast < ::accessibility::AccessibleShape* >( xChild.get()); |
| uno::Reference < drawing::XShape > xShape = pAccShape->GetXShape(); |
| if (xShape.is()) |
| { |
| SdrObject* pObj = GetSdrObjectFromXShape(xShape); |
| if (pObj) |
| RemoveContext(pObj); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| //End |
| |
| |
| void SwAccessibleMap::AddGroupContext(const SdrObject *pParentObj, uno::Reference < XAccessible > xAccParent) |
| { |
| vos::OGuard aGuard( maMutex ); |
| if( mpShapeMap ) |
| { |
| //here get all the sub list. |
| if (pParentObj->IsGroupObject()) |
| { |
| if (xAccParent.is()) |
| { |
| uno::Reference < XAccessibleContext > xContext = xAccParent->getAccessibleContext(); |
| if (xContext.is()) |
| { |
| sal_Int32 nChildren = xContext->getAccessibleChildCount(); |
| for(sal_Int32 i = 0; i<nChildren; i++) |
| { |
| uno::Reference < XAccessible > xChild = xContext->getAccessibleChild(i); |
| if (xChild.is()) |
| { |
| uno::Reference < XAccessibleContext > xChildContext = xChild->getAccessibleContext(); |
| if (xChildContext.is()) |
| { |
| short nRole = xChildContext->getAccessibleRole(); |
| if (nRole == AccessibleRole::SHAPE) |
| { |
| ::accessibility::AccessibleShape* pAccShape = static_cast < ::accessibility::AccessibleShape* >( xChild.get()); |
| uno::Reference < drawing::XShape > xShape = pAccShape->GetXShape(); |
| if (xShape.is()) |
| { |
| SdrObject* pObj = GetSdrObjectFromXShape(xShape); |
| AddShapeContext(pObj, xChild); |
| AddGroupContext(pObj,xChild); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| ::vos::ORef < ::accessibility::AccessibleShape > SwAccessibleMap::GetContextImpl( |
| const SdrObject *pObj, |
| SwAccessibleContext *pParentImpl, |
| sal_Bool bCreate ) |
| { |
| uno::Reference < XAccessible > xAcc( GetContext( pObj, pParentImpl, bCreate ) ); |
| |
| ::vos::ORef < ::accessibility::AccessibleShape > xAccImpl( |
| static_cast< ::accessibility::AccessibleShape* >( xAcc.get() ) ); |
| |
| return xAccImpl; |
| } |
| |
| |
| void SwAccessibleMap::RemoveContext( const SwFrm *pFrm ) |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( pFrm ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| mpFrmMap->erase( aIter ); |
| |
| // Remove reference to old caret object. Though mxCursorContext |
| // is a weak reference and cleared automatically, clearing it |
| // directly makes sure to not keep a defunctional object. |
| uno::Reference < XAccessible > xOldAcc( mxCursorContext ); |
| if( xOldAcc.is() ) |
| { |
| SwAccessibleContext *pOldAccImpl = |
| static_cast< SwAccessibleContext *>( xOldAcc.get() ); |
| ASSERT( pOldAccImpl->GetFrm(), "old caret context is disposed" ); |
| if( pOldAccImpl->GetFrm() == pFrm ) |
| { |
| xOldAcc.clear(); // get an empty ref |
| mxCursorContext = xOldAcc; |
| } |
| } |
| |
| if( mpFrmMap->empty() ) |
| { |
| delete mpFrmMap; |
| mpFrmMap = 0; |
| } |
| } |
| } |
| } |
| |
| void SwAccessibleMap::RemoveContext( const SdrObject *pObj ) |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( mpShapeMap ) |
| { |
| SwAccessibleShapeMap_Impl::iterator aIter = |
| mpShapeMap->find( pObj ); |
| if( aIter != mpShapeMap->end() ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| mpShapeMap->erase( aIter ); |
| RemoveGroupContext(pObj, xAcc); |
| // The shape selection flag is not cleared, but one might do |
| // so but has to make sure that the removed context is the one |
| // that is selected. |
| |
| if( mpShapeMap && mpShapeMap->empty() ) |
| { |
| delete mpShapeMap; |
| mpShapeMap = 0; |
| } |
| } |
| } |
| } |
| |
| |
| void SwAccessibleMap::Dispose( const SwFrm *pFrm, |
| const SdrObject *pObj, |
| Window* pWindow, |
| sal_Bool bRecursive ) |
| { |
| SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow ); |
| |
| // Indeed, the following assert checks the frame's accessible flag, |
| // because that's the one that is evaluated in the layout. The frame |
| // might not be accessible anyway. That's the case for cell frames that |
| // contain further cells. |
| ASSERT( !aFrmOrObj.GetSwFrm() || aFrmOrObj.GetSwFrm()->IsAccessibleFrm(), |
| "non accessible frame should be disposed" ); |
| |
| if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) |
| { |
| ::vos::ORef< SwAccessibleContext > xAccImpl; |
| ::vos::ORef< SwAccessibleContext > xParentAccImpl; |
| ::vos::ORef< ::accessibility::AccessibleShape > xShapeAccImpl; |
| // get accessible context for frame |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| // First of all look for an accessible context for a frame |
| if( aFrmOrObj.GetSwFrm() && mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( aFrmOrObj.GetSwFrm() ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| xAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| } |
| } |
| if( !xAccImpl.isValid() && mpFrmMap ) |
| { |
| // If there is none, look if the parent is accessible. |
| const SwFrm *pParent = |
| SwAccessibleFrame::GetParent( aFrmOrObj, |
| GetShell()->IsPreView()); |
| |
| if( pParent ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( pParent ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| xParentAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| } |
| } |
| } |
| if( !xParentAccImpl.isValid() && !aFrmOrObj.GetSwFrm() && |
| mpShapeMap ) |
| { |
| SwAccessibleShapeMap_Impl::iterator aIter = |
| mpShapeMap->find( aFrmOrObj.GetDrawObject() ); |
| if( aIter != mpShapeMap->end() ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| xShapeAccImpl = |
| static_cast< ::accessibility::AccessibleShape *>( xAcc.get() ); |
| } |
| } |
| if( pObj && GetShell()->ActionPend() && |
| (xParentAccImpl.isValid() || xShapeAccImpl.isValid()) ) |
| { |
| // Keep a reference to the XShape to avoid that it |
| // is deleted with a SwFrmFmt::Modify. |
| uno::Reference < drawing::XShape > xShape( |
| const_cast< SdrObject * >( pObj )->getUnoShape(), |
| uno::UNO_QUERY ); |
| if( xShape.is() ) |
| { |
| if( !mpShapes ) |
| mpShapes = new SwShapeList_Impl; |
| mpShapes->push_back( xShape ); |
| } |
| } |
| } |
| |
| // remove events stored for the frame |
| { |
| vos::OGuard aGuard( maEventMutex ); |
| if( mpEvents ) |
| { |
| SwAccessibleEventMap_Impl::iterator aIter = |
| mpEventMap->find( aFrmOrObj ); |
| if( aIter != mpEventMap->end() ) |
| { |
| SwAccessibleEvent_Impl aEvent( |
| SwAccessibleEvent_Impl::DISPOSE, aFrmOrObj ); |
| AppendEvent( aEvent ); |
| } |
| } |
| } |
| |
| // If the frame is accessible and there is a context for it, dispose |
| // the frame. If the frame is no context for it but disposing should |
| // take place recursive, the frame's children have to be disposed |
| // anyway, so we have to create the context then. |
| if( xAccImpl.isValid() ) |
| { |
| xAccImpl->Dispose( bRecursive ); |
| } |
| else if( xParentAccImpl.isValid() ) |
| { |
| // If the frame is a cell frame, the table must be notified. |
| // If we are in an action, a table model change event will |
| // be broadcasted at the end of the action to give the table |
| // a chance to generate a single table change event. |
| |
| xParentAccImpl->DisposeChild( aFrmOrObj, bRecursive ); |
| } |
| else if( xShapeAccImpl.isValid() ) |
| { |
| RemoveContext( aFrmOrObj.GetDrawObject() ); |
| xShapeAccImpl->dispose(); |
| } |
| |
| if( mpPreview && pFrm && pFrm->IsPageFrm() ) |
| mpPreview->DisposePage( static_cast< const SwPageFrm *>( pFrm ) ); |
| } |
| } |
| |
| void SwAccessibleMap::InvalidatePosOrSize( const SwFrm *pFrm, |
| const SdrObject *pObj, |
| Window* pWindow, |
| const SwRect& rOldBox ) |
| { |
| SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow ); |
| if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) |
| { |
| ::vos::ORef< SwAccessibleContext > xAccImpl; |
| ::vos::ORef< SwAccessibleContext > xParentAccImpl; |
| const SwFrm *pParent =NULL; |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( mpFrmMap ) |
| { |
| if( aFrmOrObj.GetSwFrm() ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( aFrmOrObj.GetSwFrm() ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| // If there is an accesible object already it is |
| // notified directly. |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| xAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| } |
| } |
| if( !xAccImpl.isValid() ) |
| { |
| // Otherwise we look if the parent is accessible. |
| // If not, there is nothing to do. |
| pParent = SwAccessibleFrame::GetParent( aFrmOrObj, |
| GetShell()->IsPreView()); |
| |
| if( pParent ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( pParent ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| xParentAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| } |
| } |
| } |
| } |
| } |
| |
| if( xAccImpl.isValid() ) |
| { |
| if( GetShell()->ActionPend() ) |
| { |
| SwAccessibleEvent_Impl aEvent( |
| SwAccessibleEvent_Impl::POS_CHANGED, xAccImpl.getBodyPtr(), |
| aFrmOrObj, rOldBox ); |
| AppendEvent( aEvent ); |
| } |
| else |
| { |
| FireEvents(); |
| xAccImpl->InvalidatePosOrSize( rOldBox ); |
| } |
| } |
| else if( xParentAccImpl.isValid() ) |
| { |
| if( GetShell()->ActionPend() ) |
| { |
| SwAccessibleEvent_Impl aEvent( |
| SwAccessibleEvent_Impl::CHILD_POS_CHANGED, |
| xParentAccImpl.getBodyPtr(), aFrmOrObj, rOldBox ); |
| AppendEvent( aEvent ); |
| } |
| else |
| { |
| FireEvents(); |
| xParentAccImpl->InvalidateChildPosOrSize( aFrmOrObj, |
| rOldBox ); |
| } |
| } |
| else if(pParent) |
| { |
| /* |
| For child graphic and it's parent paragraph,if split 2 graphic to 2 paragraph, |
| will delete one graphic swfrm and new create 1 graphic swfrm , |
| then the new paragraph and the new graphic SwFrm will add . |
| but when add graphic SwFrm ,the accessible of the new Paragraph is not created yet. |
| so the new graphic accessible 'parent is NULL, |
| so run here: save the parent's SwFrm not the accessible object parent, |
| */ |
| sal_Bool bIsValidFrm = sal_False; |
| sal_Bool bIsTxtParent = sal_False; |
| if (aFrmOrObj.GetSwFrm()) |
| { |
| int nType = pFrm->GetType(); |
| if ( FRM_FLY == nType ) |
| { |
| bIsValidFrm =sal_True; |
| } |
| } |
| else if(pObj) |
| { |
| int nType = pParent->GetType(); |
| if (FRM_TXT == nType) |
| { |
| bIsTxtParent =sal_True; |
| } |
| } |
| // sal_Bool bIsVisibleChildrenOnly =aFrmOrObj.IsVisibleChildrenOnly() ; |
| // sal_Bool bIsBoundAsChar =aFrmOrObj.IsBoundAsChar() ;//bIsVisibleChildrenOnly && bIsBoundAsChar && |
| if((bIsValidFrm || bIsTxtParent) ) |
| { |
| if( GetShell()->ActionPend() ) |
| { |
| SwAccessibleEvent_Impl aEvent( |
| SwAccessibleEvent_Impl::CHILD_POS_CHANGED, |
| pParent, aFrmOrObj, rOldBox ); |
| AppendEvent( aEvent ); |
| } |
| else |
| { |
| OSL_ENSURE(false,""); |
| } |
| } |
| } |
| } |
| } |
| |
| void SwAccessibleMap::InvalidateContent( const SwFrm *pFrm ) |
| { |
| SwAccessibleChild aFrmOrObj( pFrm ); |
| if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) |
| { |
| uno::Reference < XAccessible > xAcc; |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( aFrmOrObj.GetSwFrm() ); |
| if( aIter != mpFrmMap->end() ) |
| xAcc = (*aIter).second; |
| } |
| } |
| |
| if( xAcc.is() ) |
| { |
| SwAccessibleContext *pAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| if( GetShell()->ActionPend() ) |
| { |
| SwAccessibleEvent_Impl aEvent( |
| SwAccessibleEvent_Impl::INVALID_CONTENT, pAccImpl, |
| aFrmOrObj ); |
| AppendEvent( aEvent ); |
| } |
| else |
| { |
| FireEvents(); |
| pAccImpl->InvalidateContent(); |
| } |
| } |
| } |
| } |
| |
| // --> OD 2009-01-06 #i88069# |
| void SwAccessibleMap::InvalidateAttr( const SwTxtFrm& rTxtFrm ) |
| { |
| SwAccessibleChild aFrmOrObj( &rTxtFrm ); |
| if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) |
| { |
| uno::Reference < XAccessible > xAcc; |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( aFrmOrObj.GetSwFrm() ); |
| if( aIter != mpFrmMap->end() ) |
| xAcc = (*aIter).second; |
| } |
| } |
| |
| if( xAcc.is() ) |
| { |
| SwAccessibleContext *pAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| if( GetShell()->ActionPend() ) |
| { |
| SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::INVALID_ATTR, |
| pAccImpl, aFrmOrObj ); |
| aEvent.SetStates( ACC_STATE_TEXT_ATTRIBUTE_CHANGED ); |
| AppendEvent( aEvent ); |
| } |
| else |
| { |
| FireEvents(); |
| pAccImpl->InvalidateAttr(); |
| } |
| } |
| } |
| } |
| // <-- |
| |
| void SwAccessibleMap::InvalidateCursorPosition( const SwFrm *pFrm ) |
| { |
| SwAccessibleChild aFrmOrObj( pFrm ); |
| sal_Bool bShapeSelected = sal_False; |
| const ViewShell *pVSh = GetShell(); |
| if( pVSh->ISA( SwCrsrShell ) ) |
| { |
| const SwCrsrShell *pCSh = static_cast< const SwCrsrShell * >( pVSh ); |
| if( pCSh->IsTableMode() ) |
| { |
| while( aFrmOrObj.GetSwFrm() && !aFrmOrObj.GetSwFrm()->IsCellFrm() ) |
| aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper(); |
| } |
| else if( pVSh->ISA( SwFEShell ) ) |
| { |
| sal_uInt16 nObjCount; |
| const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh ); |
| const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm(); |
| if( pFlyFrm ) |
| { |
| ASSERT( !pFrm || pFrm->FindFlyFrm() == pFlyFrm, |
| "cursor is not contained in fly frame" ); |
| aFrmOrObj = pFlyFrm; |
| } |
| else if( (nObjCount = pFESh->IsObjSelected()) > 0 ) |
| { |
| bShapeSelected = sal_True; |
| aFrmOrObj = static_cast<const SwFrm *>( 0 ); |
| } |
| } |
| } |
| |
| ASSERT( bShapeSelected || aFrmOrObj.IsAccessible(GetShell()->IsPreView()), |
| "frame is not accessible" ); |
| |
| uno::Reference < XAccessible > xOldAcc; |
| uno::Reference < XAccessible > xAcc; |
| sal_Bool bOldShapeSelected = sal_False; |
| |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| xOldAcc = mxCursorContext; |
| mxCursorContext = xAcc; // clear reference |
| |
| bOldShapeSelected = mbShapeSelected; |
| mbShapeSelected = bShapeSelected; |
| |
| if( aFrmOrObj.GetSwFrm() && mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( aFrmOrObj.GetSwFrm() ); |
| if( aIter != mpFrmMap->end() ) |
| xAcc = (*aIter).second; |
| else |
| { |
| SwRect rcEmpty; |
| const SwTabFrm* pTabFrm = aFrmOrObj.GetSwFrm()->FindTabFrm(); |
| if (pTabFrm) |
| { |
| InvalidatePosOrSize(pTabFrm,0,0,rcEmpty); |
| } |
| else |
| { |
| InvalidatePosOrSize(aFrmOrObj.GetSwFrm(),0,0,rcEmpty); |
| } |
| |
| |
| aIter = |
| mpFrmMap->find( aFrmOrObj.GetSwFrm() ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| xAcc = (*aIter).second; |
| } |
| } |
| |
| // For cells, some extra thoughts are necessary, |
| // because invalidating the cursor for one cell |
| // invalidates the cursor for all cells of the same |
| // table. For this reason, we don't want to |
| // invalidate the cursor for the old cursor object |
| // and the new one if they are within the same table, |
| // because this would result in doing the work twice. |
| // Moreover, we have to make sure to invalidate the |
| // cursor even if the current cell has no accessible object. |
| // If the old cursor objects exists and is in the same |
| // table, its the best choice, because using it avoids |
| // an unnessarary cursor invalidation cycle when creating |
| // a new object for the current cell. |
| if( aFrmOrObj.GetSwFrm()->IsCellFrm() ) |
| { |
| if( xOldAcc.is() && |
| AreInSameTable( xOldAcc, aFrmOrObj.GetSwFrm() ) ) |
| { |
| if( xAcc.is() ) |
| xOldAcc = xAcc; // avoid extra invalidation |
| else |
| xAcc = xOldAcc; // make sure ate least one |
| } |
| if( !xAcc.is() ) |
| xAcc = GetContext( aFrmOrObj.GetSwFrm(), sal_True ); |
| } |
| } |
| else if (bShapeSelected) |
| { |
| const SwFEShell *pFESh = pVSh ? static_cast< const SwFEShell * >( pVSh ) : NULL ; |
| if(pFESh) |
| { |
| const SdrMarkList *pMarkList = pFESh->GetMarkList(); |
| if (pMarkList != NULL && pMarkList->GetMarkCount() == 1) |
| { |
| SdrObject *pObj = pMarkList->GetMark( 0 )->GetMarkedSdrObj(); |
| ::vos::ORef < ::accessibility::AccessibleShape > pAccShapeImpl = GetContextImpl(pObj,NULL,sal_False); |
| if (!pAccShapeImpl.isValid()) |
| { |
| while (pObj && pObj->GetUpGroup()) |
| { |
| pObj = pObj->GetUpGroup(); |
| } |
| if (pObj != NULL) |
| { |
| const SwFrm *pParent = SwAccessibleFrame::GetParent( SwAccessibleChild(pObj), GetShell()->IsPreView() ); |
| if( pParent ) |
| { |
| ::vos::ORef< SwAccessibleContext > xParentAccImpl = GetContextImpl(pParent,sal_False); |
| if (!xParentAccImpl.isValid()) |
| { |
| const SwTabFrm* pTabFrm = pParent->FindTabFrm(); |
| if (pTabFrm) |
| { |
| //The Table should not add in acc.because the "pParent" is not add to acc . |
| uno::Reference< XAccessible> xAccParentTab = GetContext(pTabFrm,sal_True);//Should Create. |
| |
| const SwFrm *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pTabFrm), GetShell()->IsPreView() ); |
| if (pParentRoot) |
| { |
| ::vos::ORef< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,sal_False); |
| if(xParentAccImplRoot.isValid()) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::CHILD; |
| aEvent.NewValue <<= xAccParentTab; |
| xParentAccImplRoot->FireAccessibleEvent( aEvent ); |
| } |
| } |
| |
| //Get "pParent" acc again. |
| xParentAccImpl = GetContextImpl(pParent,sal_False); |
| } |
| else |
| { |
| //directly create this acc para . |
| xParentAccImpl = GetContextImpl(pParent,sal_True);//Should Create. |
| |
| const SwFrm *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pParent), GetShell()->IsPreView() ); |
| |
| ::vos::ORef< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,sal_False); |
| if(xParentAccImplRoot.isValid()) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::CHILD; |
| aEvent.NewValue <<= uno::Reference< XAccessible>(xParentAccImpl.getBodyPtr()); |
| xParentAccImplRoot->FireAccessibleEvent( aEvent ); |
| } |
| } |
| } |
| if (xParentAccImpl.isValid()) |
| { |
| uno::Reference< XAccessible> xAccShape = |
| GetContext(pObj,xParentAccImpl.getBodyPtr(),sal_True); |
| |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::CHILD; |
| aEvent.NewValue <<= xAccShape; |
| xParentAccImpl->FireAccessibleEvent( aEvent ); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| m_setParaAdd.clear(); |
| m_setParaRemove.clear(); |
| if( xOldAcc.is() && xOldAcc != xAcc ) |
| InvalidateCursorPosition( xOldAcc ); |
| if( bOldShapeSelected || bShapeSelected ) |
| InvalidateShapeSelection(); |
| if( xAcc.is() ) |
| InvalidateCursorPosition( xAcc ); |
| |
| InvalidateShapeInParaSelection(); |
| |
| SET_PARA::iterator si = m_setParaRemove.begin(); |
| for (; si != m_setParaRemove.end() ; ++si) |
| { |
| SwAccessibleParagraph* pAccPara = *si; |
| if(pAccPara && pAccPara->getSelectedAccessibleChildCount() == 0 && pAccPara->getSelectedText().getLength() == 0) |
| { |
| if(pAccPara->SetSelectedState(sal_False)) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; |
| pAccPara->FireAccessibleEvent( aEvent ); |
| } |
| } |
| } |
| si = m_setParaAdd.begin(); |
| for (; si != m_setParaAdd.end() ; ++si) |
| { |
| SwAccessibleParagraph* pAccPara = *si; |
| if(pAccPara && pAccPara->SetSelectedState(sal_True)) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; |
| pAccPara->FireAccessibleEvent( aEvent ); |
| } |
| } |
| } |
| |
| //Notify the page change event to bridge. |
| void SwAccessibleMap::FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage) |
| { |
| uno::Reference<XAccessible> xAcc = GetDocumentView( ); |
| if ( xAcc.is() ) |
| { |
| SwAccessibleDocumentBase *pAcc = |
| static_cast< SwAccessibleDocumentBase * >( xAcc.get() ); |
| if (pAcc) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::PAGE_CHANGED; |
| aEvent.OldValue <<= nOldPage; |
| aEvent.NewValue <<= nNewPage; |
| pAcc->FireAccessibleEvent( aEvent ); |
| } |
| } |
| } |
| |
| void SwAccessibleMap::FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection) |
| { |
| uno::Reference<XAccessible> xAcc = GetDocumentView( ); |
| if ( xAcc.is() ) |
| { |
| SwAccessibleDocumentBase *pAcc = |
| static_cast< SwAccessibleDocumentBase * >( xAcc.get() ); |
| if (pAcc) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::SECTION_CHANGED; |
| aEvent.OldValue <<= nOldSection; |
| aEvent.NewValue <<= nNewSection; |
| pAcc->FireAccessibleEvent( aEvent ); |
| |
| } |
| } |
| } |
| void SwAccessibleMap::FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn) |
| { |
| uno::Reference<XAccessible> xAcc = GetDocumentView( ); |
| if ( xAcc.is() ) |
| { |
| SwAccessibleDocumentBase *pAcc = |
| static_cast< SwAccessibleDocumentBase * >( xAcc.get() ); |
| if (pAcc) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::COLUMN_CHANGED; |
| aEvent.OldValue <<= nOldColumn; |
| aEvent.NewValue <<= nNewColumn; |
| pAcc->FireAccessibleEvent( aEvent ); |
| |
| } |
| } |
| } |
| |
| void SwAccessibleMap::InvalidateFocus() |
| { |
| if(GetShell()->IsPreView()) |
| { |
| uno::Reference<XAccessible> xAcc = _GetDocumentView( sal_True ); |
| if (xAcc.get()) |
| { |
| SwAccessiblePreview *pAccPreview = static_cast<SwAccessiblePreview *>(xAcc.get()); |
| if (pAccPreview) |
| { |
| pAccPreview->InvalidateFocus(); |
| return ; |
| } |
| } |
| } |
| uno::Reference < XAccessible > xAcc; |
| sal_Bool bShapeSelected; |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| xAcc = mxCursorContext; |
| bShapeSelected = mbShapeSelected; |
| } |
| |
| if( xAcc.is() ) |
| { |
| SwAccessibleContext *pAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| pAccImpl->InvalidateFocus(); |
| } |
| else |
| { |
| DoInvalidateShapeSelection(sal_True); |
| } |
| } |
| |
| void SwAccessibleMap::SetCursorContext( |
| const ::vos::ORef < SwAccessibleContext >& rCursorContext ) |
| { |
| vos::OGuard aGuard( maMutex ); |
| uno::Reference < XAccessible > xAcc( rCursorContext.getBodyPtr() ); |
| mxCursorContext = xAcc; |
| } |
| |
| // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates> |
| void SwAccessibleMap::InvalidateStates( tAccessibleStates _nStates, |
| const SwFrm* _pFrm ) |
| { |
| // Start with the frame or the first upper that is accessible |
| SwAccessibleChild aFrmOrObj( _pFrm ); |
| while( aFrmOrObj.GetSwFrm() && |
| !aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) |
| aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper(); |
| if( !aFrmOrObj.GetSwFrm() ) |
| aFrmOrObj = GetShell()->GetLayout(); |
| |
| uno::Reference< XAccessible > xAcc( GetContext( aFrmOrObj.GetSwFrm(), sal_True ) ); |
| SwAccessibleContext *pAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| if( GetShell()->ActionPend() ) |
| { |
| SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES, |
| pAccImpl, |
| SwAccessibleChild(pAccImpl->GetFrm()), |
| _nStates ); |
| AppendEvent( aEvent ); |
| } |
| else |
| { |
| FireEvents(); |
| pAccImpl->InvalidateStates( _nStates ); |
| } |
| } |
| // <-- |
| |
| void SwAccessibleMap::_InvalidateRelationSet( const SwFrm* pFrm, |
| sal_Bool bFrom ) |
| { |
| // first, see if this frame is accessible, and if so, get the respective |
| SwAccessibleChild aFrmOrObj( pFrm ); |
| if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) |
| { |
| uno::Reference < XAccessible > xAcc; |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( aFrmOrObj.GetSwFrm() ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| xAcc = (*aIter).second; |
| } |
| } |
| } |
| |
| // deliver event directly, or queue event |
| if( xAcc.is() ) |
| { |
| SwAccessibleContext *pAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| if( GetShell()->ActionPend() ) |
| { |
| SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES, |
| pAccImpl, SwAccessibleChild(pFrm), |
| ( bFrom |
| ? ACC_STATE_RELATION_FROM |
| : ACC_STATE_RELATION_TO ) ); |
| AppendEvent( aEvent ); |
| } |
| else |
| { |
| FireEvents(); |
| pAccImpl->InvalidateRelation( bFrom |
| ? AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED |
| : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED ); |
| } |
| } |
| } |
| } |
| |
| void SwAccessibleMap::InvalidateRelationSet( const SwFrm* pMaster, |
| const SwFrm* pFollow ) |
| { |
| _InvalidateRelationSet( pMaster, sal_False ); |
| _InvalidateRelationSet( pFollow, sal_True ); |
| } |
| |
| /** invalidation CONTENT_FLOW_FROM/_TO relation of a paragraph |
| |
| OD 2005-12-01 #i27138# |
| |
| @author OD |
| */ |
| void SwAccessibleMap::InvalidateParaFlowRelation( const SwTxtFrm& _rTxtFrm, |
| const bool _bFrom ) |
| { |
| _InvalidateRelationSet( &_rTxtFrm, _bFrom ); |
| } |
| |
| /** invalidation of text selection of a paragraph |
| |
| OD 2005-12-12 #i27301# |
| |
| @author OD |
| */ |
| void SwAccessibleMap::InvalidateParaTextSelection( const SwTxtFrm& _rTxtFrm ) |
| { |
| // first, see if this frame is accessible, and if so, get the respective |
| SwAccessibleChild aFrmOrObj( &_rTxtFrm ); |
| if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) |
| { |
| uno::Reference < XAccessible > xAcc; |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( aFrmOrObj.GetSwFrm() ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| xAcc = (*aIter).second; |
| } |
| } |
| } |
| |
| // deliver event directly, or queue event |
| if( xAcc.is() ) |
| { |
| SwAccessibleContext *pAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| if( GetShell()->ActionPend() ) |
| { |
| SwAccessibleEvent_Impl aEvent( |
| SwAccessibleEvent_Impl::CARET_OR_STATES, |
| pAccImpl, |
| SwAccessibleChild( &_rTxtFrm ), |
| ACC_STATE_TEXT_SELECTION_CHANGED ); |
| AppendEvent( aEvent ); |
| } |
| else |
| { |
| FireEvents(); |
| pAccImpl->InvalidateTextSelection(); |
| } |
| } |
| } |
| } |
| |
| sal_Int32 SwAccessibleMap::GetChildIndex( const SwFrm& rParentFrm, |
| Window& rChild ) const |
| { |
| sal_Int32 nIndex( -1 ); |
| |
| SwAccessibleChild aFrmOrObj( &rParentFrm ); |
| if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) |
| { |
| uno::Reference < XAccessible > xAcc; |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( aFrmOrObj.GetSwFrm() ); |
| if( aIter != mpFrmMap->end() ) |
| { |
| xAcc = (*aIter).second; |
| } |
| } |
| } |
| |
| if( xAcc.is() ) |
| { |
| SwAccessibleContext *pAccImpl = |
| static_cast< SwAccessibleContext *>( xAcc.get() ); |
| |
| nIndex = pAccImpl->GetChildIndex( const_cast<SwAccessibleMap&>(*this), |
| SwAccessibleChild( &rChild ) ); |
| } |
| } |
| |
| return nIndex; |
| } |
| |
| |
| // OD 15.01.2003 #103492# - complete re-factoring of method due to new page/print |
| // preview functionality. |
| void SwAccessibleMap::UpdatePreview( const std::vector<PrevwPage*>& _rPrevwPages, |
| const Fraction& _rScale, |
| const SwPageFrm* _pSelectedPageFrm, |
| const Size& _rPrevwWinSize ) |
| { |
| DBG_ASSERT( GetShell()->IsPreView(), "no preview?" ); |
| DBG_ASSERT( mpPreview != NULL, "no preview data?" ); |
| |
| // OD 15.01.2003 #103492# - adjustments for changed method signature |
| mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize ); |
| |
| // propagate change of VisArea through the document's |
| // accessibility tree; this will also send appropriate scroll |
| // events |
| SwAccessibleContext* pDoc = |
| GetContextImpl( GetShell()->GetLayout() ).getBodyPtr(); |
| static_cast<SwAccessibleDocumentBase*>( pDoc )->SetVisArea(); |
| |
| uno::Reference < XAccessible > xOldAcc; |
| uno::Reference < XAccessible > xAcc; |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| xOldAcc = mxCursorContext; |
| |
| const SwPageFrm *pSelPage = mpPreview->GetSelPage(); |
| if( pSelPage && mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( pSelPage ); |
| if( aIter != mpFrmMap->end() ) |
| xAcc = (*aIter).second; |
| } |
| } |
| |
| if( xOldAcc.is() && xOldAcc != xAcc ) |
| InvalidateCursorPosition( xOldAcc ); |
| if( xAcc.is() ) |
| InvalidateCursorPosition( xAcc ); |
| } |
| |
| void SwAccessibleMap::InvalidatePreViewSelection( sal_uInt16 nSelPage ) |
| { |
| DBG_ASSERT( GetShell()->IsPreView(), "no preview?" ); |
| DBG_ASSERT( mpPreview != NULL, "no preview data?" ); |
| |
| // OD 16.01.2003 #103492# - changed metthod call due to method signature change. |
| mpPreview->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage ) ); |
| |
| uno::Reference < XAccessible > xOldAcc; |
| uno::Reference < XAccessible > xAcc; |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| xOldAcc = mxCursorContext; |
| |
| const SwPageFrm *pSelPage = mpPreview->GetSelPage(); |
| if( pSelPage && mpFrmMap ) |
| { |
| SwAccessibleContextMap_Impl::iterator aIter = |
| mpFrmMap->find( pSelPage ); |
| if( aIter != mpFrmMap->end() ) |
| xAcc = (*aIter).second; |
| } |
| } |
| |
| if( xOldAcc.is() && xOldAcc != xAcc ) |
| InvalidateCursorPosition( xOldAcc ); |
| if( xAcc.is() ) |
| InvalidateCursorPosition( xAcc ); |
| } |
| |
| |
| sal_Bool SwAccessibleMap::IsPageSelected( const SwPageFrm *pPageFrm ) const |
| { |
| return mpPreview && mpPreview->GetSelPage() == pPageFrm; |
| } |
| |
| |
| void SwAccessibleMap::FireEvents() |
| { |
| { |
| vos::OGuard aGuard( maEventMutex ); |
| if( mpEvents ) |
| { |
| mpEvents->SetFiring(); |
| mpEvents->MoveInvalidXAccToEnd(); |
| SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin(); |
| while( aIter != mpEvents->end() ) |
| { |
| FireEvent( *aIter ); |
| ++aIter; |
| } |
| |
| delete mpEventMap; |
| mpEventMap = 0; |
| |
| delete mpEvents; |
| mpEvents = 0; |
| } |
| } |
| { |
| vos::OGuard aGuard( maMutex ); |
| if( mpShapes ) |
| { |
| delete mpShapes; |
| mpShapes = 0; |
| } |
| } |
| |
| } |
| |
| sal_Bool SwAccessibleMap::IsValid() const |
| { |
| return sal_True; |
| } |
| |
| Rectangle SwAccessibleMap::GetVisibleArea() const |
| { |
| MapMode aSrc( MAP_TWIP ); |
| MapMode aDest( MAP_100TH_MM ); |
| return OutputDevice::LogicToLogic( GetVisArea().SVRect(), aSrc, aDest ); |
| } |
| |
| // Convert a MM100 value realtive to the document root into a pixel value |
| // realtive to the screen! |
| Point SwAccessibleMap::LogicToPixel( const Point& rPoint ) const |
| { |
| MapMode aSrc( MAP_100TH_MM ); |
| MapMode aDest( MAP_TWIP ); |
| |
| Point aPoint = rPoint; |
| |
| aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest ); |
| Window *pWin = GetShell()->GetWin(); |
| if( pWin ) |
| { |
| // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion |
| MapMode aMapMode; |
| GetMapMode( aPoint, aMapMode ); |
| aPoint = pWin->LogicToPixel( aPoint, aMapMode ); |
| aPoint = pWin->OutputToAbsoluteScreenPixel( aPoint ); |
| } |
| |
| return aPoint; |
| } |
| |
| Size SwAccessibleMap::LogicToPixel( const Size& rSize ) const |
| { |
| MapMode aSrc( MAP_100TH_MM ); |
| MapMode aDest( MAP_TWIP ); |
| Size aSize( OutputDevice::LogicToLogic( rSize, aSrc, aDest ) ); |
| if( GetShell()->GetWin() ) |
| { |
| // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion |
| MapMode aMapMode; |
| GetMapMode( Point(0,0), aMapMode ); |
| aSize = GetShell()->GetWin()->LogicToPixel( aSize, aMapMode ); |
| } |
| |
| return aSize; |
| } |
| |
| Point SwAccessibleMap::PixelToLogic( const Point& rPoint ) const |
| { |
| Point aPoint; |
| Window *pWin = GetShell()->GetWin(); |
| if( pWin ) |
| { |
| aPoint = pWin->ScreenToOutputPixel( rPoint ); |
| // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion |
| MapMode aMapMode; |
| GetMapMode( aPoint, aMapMode ); |
| aPoint = pWin->PixelToLogic( aPoint, aMapMode ); |
| MapMode aSrc( MAP_TWIP ); |
| MapMode aDest( MAP_100TH_MM ); |
| aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest ); |
| } |
| |
| return aPoint; |
| } |
| |
| Size SwAccessibleMap::PixelToLogic( const Size& rSize ) const |
| { |
| Size aSize; |
| if( GetShell()->GetWin() ) |
| { |
| // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion |
| MapMode aMapMode; |
| GetMapMode( Point(0,0), aMapMode ); |
| aSize = GetShell()->GetWin()->PixelToLogic( rSize, aMapMode ); |
| MapMode aSrc( MAP_TWIP ); |
| MapMode aDest( MAP_100TH_MM ); |
| aSize = OutputDevice::LogicToLogic( aSize, aSrc, aDest ); |
| } |
| |
| return aSize; |
| } |
| |
| sal_Bool SwAccessibleMap::ReplaceChild ( |
| ::accessibility::AccessibleShape* pCurrentChild, |
| const uno::Reference< drawing::XShape >& _rxShape, |
| const long /*_nIndex*/, |
| const ::accessibility::AccessibleShapeTreeInfo& /*_rShapeTreeInfo*/ |
| ) throw (uno::RuntimeException) |
| { |
| const SdrObject *pObj = 0; |
| { |
| vos::OGuard aGuard( maMutex ); |
| if( mpShapeMap ) |
| { |
| SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin(); |
| SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end(); |
| while( aIter != aEndIter && !pObj ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| ::accessibility::AccessibleShape *pAccShape = |
| static_cast < ::accessibility::AccessibleShape* >( xAcc.get() ); |
| if( pAccShape == pCurrentChild ) |
| { |
| pObj = (*aIter).first; |
| } |
| ++aIter; |
| } |
| } |
| } |
| if( !pObj ) |
| return sal_False; |
| |
| uno::Reference < drawing::XShape > xShape( _rxShape ); //keep reference to shape, because |
| // we might be the only one that |
| // hold it. |
| // Also get keep parent. |
| uno::Reference < XAccessible > xParent( pCurrentChild->getAccessibleParent() ); |
| pCurrentChild = 0; // well be realease by dispose |
| Dispose( 0, pObj, 0 ); |
| |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| if( !mpShapeMap ) |
| mpShapeMap = new SwAccessibleShapeMap_Impl( this ); |
| |
| // create the new child |
| ::accessibility::ShapeTypeHandler& rShapeTypeHandler = |
| ::accessibility::ShapeTypeHandler::Instance(); |
| ::accessibility::AccessibleShapeInfo aShapeInfo( |
| xShape, xParent, this ); |
| ::accessibility::AccessibleShape* pReplacement = |
| rShapeTypeHandler.CreateAccessibleObject ( |
| aShapeInfo, mpShapeMap->GetInfo() ); |
| |
| uno::Reference < XAccessible > xAcc( pReplacement ); |
| if( xAcc.is() ) |
| { |
| pReplacement->Init(); |
| |
| SwAccessibleShapeMap_Impl::iterator aIter = |
| mpShapeMap->find( pObj ); |
| if( aIter != mpShapeMap->end() ) |
| { |
| (*aIter).second = xAcc; |
| } |
| else |
| { |
| SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAcc ); |
| mpShapeMap->insert( aEntry ); |
| } |
| } |
| } |
| |
| SwRect aEmptyRect; |
| InvalidatePosOrSize( 0, pObj, 0, aEmptyRect ); |
| |
| return sal_True; |
| } |
| |
| //Get the accessible control shape from the model object, here model object is with XPropertySet type |
| ::accessibility::AccessibleControlShape * SwAccessibleMap::GetAccControlShapeFromModel(::com::sun::star::beans::XPropertySet* pSet) throw (::com::sun::star::uno::RuntimeException) |
| { |
| if( mpShapeMap ) |
| { |
| SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin(); |
| SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end(); |
| while( aIter != aEndIter) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).second ); |
| ::accessibility::AccessibleShape *pAccShape = |
| static_cast < ::accessibility::AccessibleShape* >( xAcc.get() ); |
| if(pAccShape && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape->GetXShape()) == ::accessibility::DRAWING_CONTROL) |
| { |
| ::accessibility::AccessibleControlShape *pCtlAccShape = static_cast < ::accessibility::AccessibleControlShape* >(pAccShape); |
| if (pCtlAccShape && pCtlAccShape->GetControlModel() == pSet) |
| return pCtlAccShape; |
| } |
| ++aIter; |
| } |
| } |
| return NULL; |
| } |
| |
| ::com::sun::star::uno::Reference< XAccessible > |
| SwAccessibleMap::GetAccessibleCaption (const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| SdrObject* captionedObject = GetSdrObjectFromXShape(xShape); |
| |
| SwDrawContact *pContact = (SwDrawContact*)GetUserCall( captionedObject ); |
| ASSERT( RES_DRAWFRMFMT == pContact->GetFmt()->Which(), |
| "fail" ); |
| if( !pContact ) |
| return 0; |
| |
| SwDrawFrmFmt *pCaptionedFmt = (SwDrawFrmFmt *)pContact->GetFmt(); |
| if( !pCaptionedFmt ) |
| return 0; |
| |
| SwFlyFrm* pFrm = NULL; |
| if (pCaptionedFmt->HasCaption()) |
| { |
| const SwFrmFmt *pCaptionFrmFmt = pCaptionedFmt->GetCaptionFmt(); |
| SwClientIter aIter (*(SwModify*)pCaptionFrmFmt); |
| pFrm = (SwFlyFrm*)aIter.First( TYPE ( SwFlyFrm )); |
| } |
| if (!pFrm) |
| return 0; |
| //SwFrmFmt* pFrm = pCaptionedFmt->GetCaptionFmt(); |
| uno::Reference < XAccessible > xAcc( GetContext((SwFrm*)pFrm,sal_True) ); |
| //Reference < XAccessibleShape > xAccShape( xAcc, UNO_QUERY ); |
| |
| uno::Reference< XAccessibleContext > xAccContext = xAcc->getAccessibleContext(); |
| if( xAccContext.is() ) |
| { //get the parent of caption frame, which is paragaph |
| uno::Reference< XAccessible > xAccParent = xAccContext->getAccessibleParent(); |
| if(xAccParent.is()) |
| { |
| //get the great parent of caption frame which is text frame. |
| uno::Reference< XAccessibleContext > xAccParentContext = xAccParent->getAccessibleContext(); |
| uno::Reference< XAccessible > xAccGreatParent = xAccParentContext->getAccessibleParent(); |
| if(xAccGreatParent.is()) |
| { |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::CHILD; |
| aEvent.NewValue <<= xAccParent; |
| ( static_cast< SwAccessibleContext * >(xAccGreatParent.get()) )->FireAccessibleEvent( aEvent ); |
| |
| } |
| |
| AccessibleEventObject aEvent; |
| aEvent.EventId = AccessibleEventId::CHILD; |
| aEvent.NewValue <<= xAcc; |
| ( static_cast< SwAccessibleContext * >(xAccParent.get()) )->FireAccessibleEvent( aEvent ); |
| } |
| } |
| |
| if(xAcc.get()) |
| return xAcc; |
| else |
| return NULL; |
| |
| } |
| Point SwAccessibleMap::PixelToCore( const Point& rPoint ) const |
| { |
| Point aPoint; |
| if( GetShell()->GetWin() ) |
| { |
| // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)> |
| MapMode aMapMode; |
| GetMapMode( rPoint, aMapMode ); |
| aPoint = GetShell()->GetWin()->PixelToLogic( rPoint, aMapMode ); |
| } |
| return aPoint; |
| } |
| |
| static inline long lcl_CorrectCoarseValue(long aCoarseValue, long aFineValue, |
| long aRefValue, bool bToLower) |
| { |
| long aResult = aCoarseValue; |
| |
| if (bToLower) |
| { |
| if (aFineValue < aRefValue) |
| aResult -= 1; |
| } |
| else |
| { |
| if (aFineValue > aRefValue) |
| aResult += 1; |
| } |
| |
| return aResult; |
| } |
| |
| static inline void lcl_CorrectRectangle(Rectangle & rRect, |
| const Rectangle & rSource, |
| const Rectangle & rInGrid) |
| { |
| rRect.nLeft = lcl_CorrectCoarseValue(rRect.nLeft, rSource.nLeft, |
| rInGrid.nLeft, false); |
| rRect.nTop = lcl_CorrectCoarseValue(rRect.nTop, rSource.nTop, |
| rInGrid.nTop, false); |
| rRect.nRight = lcl_CorrectCoarseValue(rRect.nRight, rSource.nRight, |
| rInGrid.nRight, true); |
| rRect.nBottom = lcl_CorrectCoarseValue(rRect.nBottom, rSource.nBottom, |
| rInGrid.nBottom, true); |
| } |
| |
| Rectangle SwAccessibleMap::CoreToPixel( const Rectangle& rRect ) const |
| { |
| Rectangle aRect; |
| if( GetShell()->GetWin() ) |
| { |
| // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)> |
| MapMode aMapMode; |
| GetMapMode( rRect.TopLeft(), aMapMode ); |
| aRect = GetShell()->GetWin()->LogicToPixel( rRect, aMapMode ); |
| |
| Rectangle aTmpRect = GetShell()->GetWin()->PixelToLogic( aRect, aMapMode ); |
| lcl_CorrectRectangle(aRect, rRect, aTmpRect); |
| } |
| |
| return aRect; |
| } |
| |
| /** get mapping mode for LogicToPixel and PixelToLogic conversions |
| |
| OD 15.01.2003 #103492# |
| Replacement method <PreviewAdjust(..)> by new method <GetMapMode>. |
| Method returns mapping mode of current output device and adjusts it, |
| if the shell is in page/print preview. |
| Necessary, because <PreviewAdjust(..)> changes mapping mode at current |
| output device for mapping logic document positions to page preview window |
| positions and vice versa and doesn't take care to recover its changes. |
| |
| @author OD |
| */ |
| void SwAccessibleMap::GetMapMode( const Point& _rPoint, |
| MapMode& _orMapMode ) const |
| { |
| MapMode aMapMode = GetShell()->GetWin()->GetMapMode(); |
| if( GetShell()->IsPreView() ) |
| { |
| DBG_ASSERT( mpPreview != NULL, "need preview data" ); |
| |
| mpPreview->AdjustMapMode( aMapMode, _rPoint ); |
| } |
| _orMapMode = aMapMode; |
| } |
| |
| /** get size of a dedicated preview page |
| |
| OD 15.01.2003 #103492# |
| |
| @author OD |
| */ |
| Size SwAccessibleMap::GetPreViewPageSize( sal_uInt16 _nPrevwPageNum ) const |
| { |
| DBG_ASSERT( mpVSh->IsPreView(), "no page preview accessible." ); |
| DBG_ASSERT( mpVSh->IsPreView() && ( mpPreview != NULL ), |
| "missing accessible preview data at page preview" ); |
| if ( mpVSh->IsPreView() && ( mpPreview != NULL ) ) |
| { |
| return mpVSh->PagePreviewLayout()->GetPrevwPageSizeByPageNum( _nPrevwPageNum ); |
| } |
| else |
| { |
| return Size( 0, 0 ); |
| } |
| } |
| |
| /** method to build up a new data structure of the accessible pararaphs, |
| which have a selection |
| |
| OD 2005-12-13 #i27301# |
| Important note: method has to used inside a mutual exclusive section |
| |
| @author OD |
| */ |
| SwAccessibleSelectedParas_Impl* SwAccessibleMap::_BuildSelectedParas() |
| { |
| // no accessible contexts, no selection |
| if ( !mpFrmMap ) |
| { |
| return 0L; |
| } |
| |
| // get cursor as an instance of its base class <SwPaM> |
| SwPaM* pCrsr( 0L ); |
| { |
| SwCrsrShell* pCrsrShell = dynamic_cast<SwCrsrShell*>(GetShell()); |
| if ( pCrsrShell ) |
| { |
| SwFEShell* pFEShell = dynamic_cast<SwFEShell*>(pCrsrShell); |
| if ( !pFEShell || |
| ( !pFEShell->IsFrmSelected() && |
| pFEShell->IsObjSelected() == 0 ) ) |
| { |
| // get cursor without updating an existing table cursor. |
| pCrsr = pCrsrShell->GetCrsr( sal_False ); |
| } |
| } |
| } |
| // no cursor, no selection |
| if ( !pCrsr ) |
| { |
| return 0L; |
| } |
| |
| SwAccessibleSelectedParas_Impl* pRetSelectedParas( 0L ); |
| |
| // loop on all cursors |
| SwPaM* pRingStart = pCrsr; |
| do { |
| |
| // for a selection the cursor has to have a mark. |
| // for savety reasons assure that point and mark are in text nodes |
| if ( pCrsr->HasMark() && |
| pCrsr->GetPoint()->nNode.GetNode().IsTxtNode() && |
| pCrsr->GetMark()->nNode.GetNode().IsTxtNode() ) |
| { |
| SwPosition* pStartPos = pCrsr->Start(); |
| SwPosition* pEndPos = pCrsr->End(); |
| // loop on all text nodes inside the selection |
| SwNodeIndex aIdx( pStartPos->nNode ); |
| for ( ; aIdx.GetIndex() <= pEndPos->nNode.GetIndex(); ++aIdx ) |
| { |
| SwTxtNode* pTxtNode( aIdx.GetNode().GetTxtNode() ); |
| if ( pTxtNode ) |
| { |
| // loop on all text frames registered at the text node. |
| SwIterator<SwTxtFrm,SwTxtNode> aIter( *pTxtNode ); |
| for( SwTxtFrm* pTxtFrm = aIter.First(); pTxtFrm; pTxtFrm = aIter.Next() ) |
| { |
| uno::WeakReference < XAccessible > xWeakAcc; |
| SwAccessibleContextMap_Impl::iterator aMapIter = |
| mpFrmMap->find( pTxtFrm ); |
| if( aMapIter != mpFrmMap->end() ) |
| { |
| xWeakAcc = (*aMapIter).second; |
| SwAccessibleParaSelection aDataEntry( |
| pTxtNode == &(pStartPos->nNode.GetNode()) |
| ? pStartPos->nContent.GetIndex() |
| : 0, |
| pTxtNode == &(pEndPos->nNode.GetNode()) |
| ? pEndPos->nContent.GetIndex() |
| : STRING_LEN ); |
| SwAccessibleSelectedParas_Impl::value_type |
| aEntry( xWeakAcc, aDataEntry ); |
| if ( !pRetSelectedParas ) |
| { |
| pRetSelectedParas = |
| new SwAccessibleSelectedParas_Impl; |
| } |
| pRetSelectedParas->insert( aEntry ); |
| } |
| } |
| } |
| } |
| } |
| |
| // prepare next turn: get next cursor in ring |
| pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() ); |
| } while ( pCrsr != pRingStart ); |
| |
| return pRetSelectedParas; |
| } |
| |
| /** invalidation of text selection of all paragraphs |
| |
| OD 2005-12-13 #i27301# |
| |
| @author OD |
| */ |
| void SwAccessibleMap::InvalidateTextSelectionOfAllParas() |
| { |
| vos::OGuard aGuard( maMutex ); |
| |
| // keep previously known selected paragraphs |
| SwAccessibleSelectedParas_Impl* pPrevSelectedParas( mpSelectedParas ); |
| |
| // determine currently selected paragraphs |
| mpSelectedParas = _BuildSelectedParas(); |
| |
| // compare currently selected paragraphs with the previously selected |
| // paragraphs and submit corresponding TEXT_SELECTION_CHANGED events. |
| // first, search for new and changed selections. |
| // on the run remove selections from previously known ones, if they are |
| // also in the current ones. |
| if ( mpSelectedParas ) |
| { |
| SwAccessibleSelectedParas_Impl::iterator aIter = mpSelectedParas->begin(); |
| for ( ; aIter != mpSelectedParas->end(); ++aIter ) |
| { |
| bool bSubmitEvent( false ); |
| if ( !pPrevSelectedParas ) |
| { |
| // new selection |
| bSubmitEvent = true; |
| } |
| else |
| { |
| SwAccessibleSelectedParas_Impl::iterator aPrevSelected = |
| pPrevSelectedParas->find( (*aIter).first ); |
| if ( aPrevSelected != pPrevSelectedParas->end() ) |
| { |
| // check, if selection has changed |
| if ( (*aIter).second.nStartOfSelection != |
| (*aPrevSelected).second.nStartOfSelection || |
| (*aIter).second.nEndOfSelection != |
| (*aPrevSelected).second.nEndOfSelection ) |
| { |
| // changed selection |
| bSubmitEvent = true; |
| } |
| pPrevSelectedParas->erase( aPrevSelected ); |
| } |
| else |
| { |
| // new selection |
| bSubmitEvent = true; |
| } |
| } |
| |
| if ( bSubmitEvent ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).first ); |
| if ( xAcc.is() ) |
| { |
| ::vos::ORef < SwAccessibleContext > xAccImpl( |
| static_cast<SwAccessibleContext*>( xAcc.get() ) ); |
| if ( xAccImpl.isValid() && xAccImpl->GetFrm() ) |
| { |
| const SwTxtFrm* pTxtFrm( |
| dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) ); |
| ASSERT( pTxtFrm, |
| "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" ); |
| if ( pTxtFrm ) |
| { |
| InvalidateParaTextSelection( *pTxtFrm ); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // second, handle previous selections - after the first step the data |
| // structure of the previously known only contains the 'old' selections |
| if ( pPrevSelectedParas ) |
| { |
| SwAccessibleSelectedParas_Impl::iterator aIter = pPrevSelectedParas->begin(); |
| for ( ; aIter != pPrevSelectedParas->end(); ++aIter ) |
| { |
| uno::Reference < XAccessible > xAcc( (*aIter).first ); |
| if ( xAcc.is() ) |
| { |
| ::vos::ORef < SwAccessibleContext > xAccImpl( |
| static_cast<SwAccessibleContext*>( xAcc.get() ) ); |
| if ( xAccImpl.isValid() && xAccImpl->GetFrm() ) |
| { |
| const SwTxtFrm* pTxtFrm( |
| dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) ); |
| ASSERT( pTxtFrm, |
| "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" ); |
| if ( pTxtFrm ) |
| { |
| InvalidateParaTextSelection( *pTxtFrm ); |
| } |
| } |
| } |
| } |
| |
| delete pPrevSelectedParas; |
| } |
| } |
| |
| const SwRect& SwAccessibleMap::GetVisArea() const |
| { |
| DBG_ASSERT( !GetShell()->IsPreView() || (mpPreview != NULL), |
| "preview without preview data?" ); |
| |
| return GetShell()->IsPreView() |
| ? mpPreview->GetVisArea() |
| : GetShell()->VisArea(); |
| } |
| |
| sal_Bool SwAccessibleMap::IsDocumentSelAll() |
| { |
| return GetShell()->GetDoc()->IsPrepareSelAll(); |
| } |
| |