summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/core/access/acccontext.cxx31
-rw-r--r--sw/source/core/access/acccontext.hxx14
-rw-r--r--sw/source/core/access/accmap.cxx293
-rw-r--r--sw/source/core/access/accpara.cxx334
-rw-r--r--sw/source/core/access/accpara.hxx28
5 files changed, 517 insertions, 183 deletions
diff --git a/sw/source/core/access/acccontext.cxx b/sw/source/core/access/acccontext.cxx
index c7c7bc5223..fe4e48425f 100644
--- a/sw/source/core/access/acccontext.cxx
+++ b/sw/source/core/access/acccontext.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: acccontext.cxx,v $
*
- * $Revision: 1.9 $
+ * $Revision: 1.10 $
*
- * last change: $Author: mib $ $Date: 2002-02-27 09:32:33 $
+ * last change: $Author: mib $ $Date: 2002-03-08 13:26:29 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -144,12 +144,12 @@ using namespace ::com::sun::star::uno;
using namespace ::drafts::com::sun::star::accessibility;
using namespace ::rtl;
-void SwAccessibleContext::_Moved()
+void SwAccessibleContext::FireVisibleDataEvent()
{
AccessibleEventObject aEvent;
aEvent.EventId = AccessibleEventId::ACCESSIBLE_VISIBLE_DATA_EVENT;
- AccessibleEvent( aEvent );
+ FireAccessibleEvent( aEvent );
DBG_MSG( "AccessibleVisibleData" )
}
@@ -176,7 +176,7 @@ sal_Bool SwAccessibleContext::ChildScrolledIn( const SwFrm *pFrm )
Reference < XAccessible > xChild( xChildImpl.getBodyPtr() );
aEvent.NewValue <<= xChild;
- AccessibleEvent( aEvent );
+ FireAccessibleEvent( aEvent );
DBG_MSG_PARAM( "AccessibleChild (added)", xChildImpl.getBodyPtr() )
xWeakChild = xChild;
@@ -256,7 +256,7 @@ sal_Bool SwAccessibleContext::ChildScrolled( const SwFrm *pFrm )
// the update event for the parent has been send.
xChildImpl->SetVisArea( GetVisArea() );
- xChildImpl->_Moved();
+ xChildImpl->FireVisibleDataEvent();
bUpdateChildren = sal_False;
}
}
@@ -305,7 +305,7 @@ void SwAccessibleContext::Dispose( sal_Bool bRecursive )
AccessibleEventObject aEvent;
aEvent.EventId = AccessibleEventId::ACCESSIBLE_CHILD_EVENT;
aEvent.OldValue <<= xThis;
- pAcc->AccessibleEvent( aEvent );
+ pAcc->FireAccessibleEvent( aEvent );
DBG_MSG_THIS_PARAM( "AccessibleChild (removed)", pAcc, this )
}
@@ -329,7 +329,9 @@ void SwAccessibleContext::PosChanged()
if( IsShowing() )
{
// The frame stays visible -> broadcast event
- _Moved();
+ FireVisibleDataEvent();
+
+ _InvalidateContent( sal_True );
}
else
{
@@ -364,8 +366,13 @@ void SwAccessibleContext::ChildPosChanged( const SwFrm *pFrm,
}
}
+void SwAccessibleContext::InvalidateContent()
+{
+ _InvalidateContent( sal_False );
+}
-void SwAccessibleContext::AccessibleEvent( AccessibleEventObject& rEvent )
+
+void SwAccessibleContext::FireAccessibleEvent( AccessibleEventObject& rEvent )
{
Reference < XAccessibleContext > xThis( this );
rEvent.Source = xThis;
@@ -414,6 +421,12 @@ void SwAccessibleContext::SetStates(
}
}
+void SwAccessibleContext::_InvalidateContent( sal_Bool )
+{
+}
+
+
+
OUString SwAccessibleContext::GetResource( sal_uInt16 nResId,
const OUString *pArg1,
const OUString *pArg2 ) const
diff --git a/sw/source/core/access/acccontext.hxx b/sw/source/core/access/acccontext.hxx
index 0439da6169..45b938a97a 100644
--- a/sw/source/core/access/acccontext.hxx
+++ b/sw/source/core/access/acccontext.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: acccontext.hxx,v $
*
- * $Revision: 1.8 $
+ * $Revision: 1.9 $
*
- * last change: $Author: mib $ $Date: 2002-02-27 09:32:33 $
+ * last change: $Author: mib $ $Date: 2002-03-08 13:26:29 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -144,7 +144,7 @@ protected:
virtual sal_Bool DisposeChild( const SwFrm *pFrm,
sal_Bool bRecursive );
- void AccessibleEvent( ::drafts::com::sun::star::accessibility::AccessibleEventObject& rEvent );
+ void FireAccessibleEvent( ::drafts::com::sun::star::accessibility::AccessibleEventObject& rEvent );
::rtl::OUString GetResource( sal_uInt16 nResId,
const ::rtl::OUString *pArg1 = 0,
@@ -155,8 +155,10 @@ protected:
// SHOWING(0/1), OPAQUE(0/1) and VISIBLE(1).
virtual void SetStates( ::utl::AccessibleStateSetHelper& rStateSet );
+ virtual void _InvalidateContent( sal_Bool bVisibleDataFired );
+
// broadcast visual data event
- void _Moved();
+ void FireVisibleDataEvent();
Window *GetWindow();
SwAccessibleMap *GetMap() { return pMap; }
@@ -337,6 +339,10 @@ public:
// The object has been moved by the layout
void ChildPosChanged( const SwFrm *pFrm, const SwRect& rFrm );
+ // The content may have changed (but it hasn't tohave changed)
+ virtual void InvalidateContent();
+
+
const ::rtl::OUString& GetName() const { return sName; }
};
diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx
index e8b5fb20aa..a4a8813c65 100644
--- a/sw/source/core/access/accmap.cxx
+++ b/sw/source/core/access/accmap.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: accmap.cxx,v $
*
- * $Revision: 1.6 $
+ * $Revision: 1.7 $
*
- * last change: $Author: mib $ $Date: 2002-03-06 08:14:51 $
+ * last change: $Author: mib $ $Date: 2002-03-08 13:26:29 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -72,9 +72,8 @@
#include <cppuhelper/weakref.hxx>
#endif
-#ifndef __SGI_STL_MAP
#include <map>
-#endif
+#include <list>
#ifndef _ACCMAP_HXX
#include <accmap.hxx>
#endif
@@ -125,14 +124,67 @@ struct SwFrmFunc
}
};
-typedef ::std::map < const SwFrm *, WeakReference < XAccessible >, SwFrmFunc > _SwAccessibleMap_Impl;
+typedef ::std::map < const SwFrm *, WeakReference < XAccessible >, SwFrmFunc > _SwAccessibleContextMap_Impl;
+
+class SwAccessibleContextMap_Impl: public _SwAccessibleContextMap_Impl
+{
+};
-class SwAccessibleMap_Impl: public _SwAccessibleMap_Impl
+struct SwAccessibleEvent_Impl
{
+public:
+ enum EventType { INVALID_CONTENT, POS_CHANGED, CHILD_POS_CHANGED, DISPOSE };
+
+private:
+ EventType eType; // The event type
+ WeakReference < XAccessible > xAcc; // The object that fires the event
+ SwRect aOldFrm; // the old bounds for CHILD_POS_CHANGED
+ const SwFrm *pFrm; // the child for CHILD_POS_CHANGED and
+ // the same as xAcc for any other
+ // event type
+
+public:
+ SwAccessibleEvent_Impl( EventType eT, SwAccessibleContext *pA ) :
+ eType( eT ), xAcc( pA ), pFrm( pA->GetFrm() ) {}
+ SwAccessibleEvent_Impl( EventType eT, const SwFrm *pF ) :
+ eType( eT ), pFrm( pF ) {}
+ SwAccessibleEvent_Impl( EventType eT, SwAccessibleContext *pA,
+ const SwFrm *pF, const SwRect& rR ) :
+ eType( eT ), xAcc( pA ), pFrm( pF ), aOldFrm( rR ) {}
+
+ inline EventType GetType() const { return eType; }
+ inline ::vos::ORef < SwAccessibleContext > GetContext() const;
+ inline const SwRect& GetOldFrm() const { return aOldFrm; }
+ inline const SwFrm *GetFrm() const { return pFrm; }
};
+inline ::vos::ORef < SwAccessibleContext >
+ SwAccessibleEvent_Impl::GetContext() const
+{
+ Reference < XAccessible > xTmp( xAcc );
+ ::vos::ORef < SwAccessibleContext > xAccImpl(
+ static_cast< SwAccessibleContext * >( xTmp.get() ) );
+
+ return xAccImpl;
+}
+
+typedef ::std::list < SwAccessibleEvent_Impl > _SwAccessibleEventList_Impl;
+
+class SwAccessibleEventList_Impl: public _SwAccessibleEventList_Impl
+{
+};
+
+typedef ::std::map < const SwFrm *, SwAccessibleEventList_Impl::iterator, SwFrmFunc > _SwAccessibleEventMap_Impl;
+
+class SwAccessibleEventMap_Impl: public _SwAccessibleEventMap_Impl
+{
+};
+
+
SwAccessibleMap::SwAccessibleMap( ViewShell *pSh ) :
pMap( 0 ),
+ pEvents( 0 ),
+ pEventMap( 0 ),
pVSh( pSh ),
nPara( 1 ),
nFootnote( 1 ),
@@ -147,7 +199,7 @@ SwAccessibleMap::~SwAccessibleMap()
{
Reference < XAccessible > xAcc;
const SwRootFrm *pRootFrm = GetShell()->GetDoc()->GetRootFrm();
- SwAccessibleMap_Impl::iterator aIter = pMap->find( pRootFrm );
+ SwAccessibleContextMap_Impl::iterator aIter = pMap->find( pRootFrm );
if( aIter != pMap->end() )
xAcc = (*aIter).second;
if( !xAcc.is() )
@@ -155,9 +207,92 @@ SwAccessibleMap::~SwAccessibleMap()
SwAccessibleDocument *pAcc =
static_cast< SwAccessibleDocument * >( xAcc.get() );
pAcc->Dispose( sal_True );
+
+ ASSERT( !pMap || pMap->empty(),
+ "Map should be empty after disposing the root frame" );
}
delete pMap;
+
+ ASSERT( !(pEvents || pEventMap), "pending events" );
+ delete pEventMap;
+ delete pEvents;
+}
+
+void SwAccessibleMap::AppendEvent( const SwAccessibleEvent_Impl& rEvent )
+{
+ vos::OGuard aGuard( aEventMutex );
+
+ if( !pEvents )
+ pEvents = new SwAccessibleEventList_Impl;
+ if( !pEventMap )
+ pEventMap = new SwAccessibleEventMap_Impl;
+
+ SwAccessibleEventMap_Impl::iterator aIter =
+ pEventMap->find( rEvent.GetFrm() );
+ if( aIter != pEventMap->end() )
+ {
+ SwAccessibleEvent_Impl aEvent( *(*aIter).second );
+ sal_Bool bAppendEvent = sal_True;
+ switch( rEvent.GetType() )
+ {
+ case SwAccessibleEvent_Impl::INVALID_CONTENT:
+ // All events include a INVALID_CONTENT, so the only action that
+ // needs to be done is to put the event to the back. That's done
+ // automatically.
+ ASSERT( aEvent.GetType()!=SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
+ "invalid event combination" );
+ ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
+ "dispose events should not be stored" );
+ break;
+ case SwAccessibleEvent_Impl::POS_CHANGED:
+ // If the the old event is not a DISPOSE event, the new event
+ // includes the old one.
+ ASSERT( aEvent.GetType()!=SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
+ "invalid event combination" );
+ ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
+ "dispose events should not be stored" );
+ if( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE )
+ aEvent = rEvent;
+ 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::DISPOSE:
+ // DISPOSE events overwrite all others. They are not stored
+ // but executed immidiatly to avoid broadcasting of defuntional
+ // objects. So what needs to be done here is to remove all
+ // events for the frame in question.
+ ASSERT( aEvent.GetType()!=SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
+ "invalid event combination" );
+ ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
+ "dispose events should not be stored" );
+ bAppendEvent = sal_False;
+ break;
+ }
+ if( bAppendEvent )
+ {
+ pEvents->erase( (*aIter).second );
+ (*aIter).second = pEvents->insert( pEvents->end(), aEvent );
+ }
+ else
+ {
+ pEvents->erase( (*aIter).second );
+ pEventMap->erase( aIter );
+ }
+ }
+ else if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
+ {
+ SwAccessibleEventMap_Impl::value_type aEntry( rEvent.GetFrm(),
+ pEvents->insert( pEvents->end(), rEvent ) );
+ pEventMap->insert( aEntry );
+ }
+
}
Reference< XAccessible > SwAccessibleMap::GetDocumentView()
@@ -167,9 +302,9 @@ Reference< XAccessible > SwAccessibleMap::GetDocumentView()
Reference < XAccessible > xAcc;
if( !pMap )
- pMap = new SwAccessibleMap_Impl;
+ pMap = new SwAccessibleContextMap_Impl;
const SwRootFrm *pRootFrm = GetShell()->GetDoc()->GetRootFrm();
- SwAccessibleMap_Impl::iterator aIter = pMap->find( pRootFrm );
+ SwAccessibleContextMap_Impl::iterator aIter = pMap->find( pRootFrm );
if( aIter != pMap->end() )
xAcc = (*aIter).second;
if( xAcc.is() )
@@ -187,7 +322,7 @@ Reference< XAccessible > SwAccessibleMap::GetDocumentView()
}
else
{
- SwAccessibleMap_Impl::value_type aEntry( pRootFrm, xAcc );
+ SwAccessibleContextMap_Impl::value_type aEntry( pRootFrm, xAcc );
pMap->insert( aEntry );
}
}
@@ -203,10 +338,10 @@ Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrm *pFrm,
Reference < XAccessible > xAcc;
if( !pMap && bCreate )
- pMap = new SwAccessibleMap_Impl;
+ pMap = new SwAccessibleContextMap_Impl;
if( pMap )
{
- SwAccessibleMap_Impl::iterator aIter = pMap->find( pFrm );
+ SwAccessibleContextMap_Impl::iterator aIter = pMap->find( pFrm );
if( aIter != pMap->end() )
xAcc = (*aIter).second;
@@ -248,7 +383,7 @@ Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrm *pFrm,
}
else
{
- SwAccessibleMap_Impl::value_type aEntry( pFrm, xAcc );
+ SwAccessibleContextMap_Impl::value_type aEntry( pFrm, xAcc );
pMap->insert( aEntry );
}
}
@@ -276,7 +411,8 @@ void SwAccessibleMap::RemoveContext( SwAccessibleContext *pAcc )
if( pMap )
{
- SwAccessibleMap_Impl::iterator aIter = pMap->find( pAcc->GetFrm() );
+ SwAccessibleContextMap_Impl::iterator aIter =
+ pMap->find( pAcc->GetFrm() );
if( aIter != pMap->end() )
{
pMap->erase( aIter );
@@ -297,12 +433,28 @@ void SwAccessibleMap::DisposeFrm( const SwFrm *pFrm )
if( pMap )
{
- SwAccessibleMap_Impl::iterator aIter = pMap->find( pFrm );
+ SwAccessibleContextMap_Impl::iterator aIter = pMap->find( pFrm );
if( aIter != pMap->end() )
{
Reference < XAccessible > xAcc = (*aIter).second;
if( xAcc.is() )
- static_cast< SwAccessibleContext *>( xAcc.get())->Dispose();
+ {
+ SwAccessibleContext *pAccImpl =
+ static_cast< SwAccessibleContext *>( xAcc.get() );
+ pAccImpl->Dispose();
+ }
+ }
+ }
+ if( pEvents )
+ {
+ vos::OGuard aGuard( aEventMutex );
+ SwAccessibleEventMap_Impl::iterator aIter =
+ pEventMap->find( pFrm );
+ if( aIter != pEventMap->end() )
+ {
+ SwAccessibleEvent_Impl aEvent(
+ SwAccessibleEvent_Impl::DISPOSE, pFrm );
+ AppendEvent( aEvent );
}
}
}
@@ -316,13 +468,27 @@ void SwAccessibleMap::MoveFrm( const SwFrm *pFrm, const SwRect& rOldFrm )
if( pMap )
{
- SwAccessibleMap_Impl::iterator aIter = pMap->find( pFrm );
+ SwAccessibleContextMap_Impl::iterator aIter = pMap->find( pFrm );
if( aIter != pMap->end() )
{
// If there is an accesible object already it is
// notified directly.
Reference < XAccessible > xAcc = (*aIter).second;
- static_cast< SwAccessibleContext * >(xAcc.get())->PosChanged();
+ if( xAcc.is() )
+ {
+ SwAccessibleContext *pAccImpl =
+ static_cast< SwAccessibleContext *>( xAcc.get() );
+ if( GetShell()->ActionPend() )
+ {
+ SwAccessibleEvent_Impl aEvent(
+ SwAccessibleEvent_Impl::POS_CHANGED, pAccImpl );
+ AppendEvent( aEvent );
+ }
+ else
+ {
+ pAccImpl->PosChanged();
+ }
+ }
}
else
{
@@ -338,11 +504,98 @@ void SwAccessibleMap::MoveFrm( const SwFrm *pFrm, const SwRect& rOldFrm )
if( aIter != pMap->end() )
{
Reference < XAccessible > xAcc = (*aIter).second;
- static_cast<SwAccessibleContext *>(xAcc.get())
- ->ChildPosChanged( pFrm, rOldFrm );
+ if( xAcc.is() )
+ {
+ SwAccessibleContext *pAccImpl =
+ static_cast< SwAccessibleContext *>(xAcc.get());
+ if( GetShell()->ActionPend() )
+ {
+ SwAccessibleEvent_Impl aEvent(
+ SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
+ pAccImpl, pFrm, rOldFrm );
+ AppendEvent( aEvent );
+ }
+ else
+ {
+ pAccImpl->ChildPosChanged( pFrm, rOldFrm );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void SwAccessibleMap::InvalidateFrmContent( const SwFrm *pFrm )
+{
+ if( pFrm->IsAccessibleFrm() )
+ {
+ vos::OGuard aGuard( aMutex );
+
+ if( pMap )
+ {
+ SwAccessibleContextMap_Impl::iterator aIter = pMap->find( pFrm );
+ if( aIter != pMap->end() )
+ {
+ Reference < XAccessible > xAcc = (*aIter).second;
+ if( xAcc.is() )
+ {
+ SwAccessibleContext *pAccImpl =
+ static_cast< SwAccessibleContext *>( xAcc.get() );
+ if( GetShell()->ActionPend() )
+ {
+ SwAccessibleEvent_Impl aEvent(
+ SwAccessibleEvent_Impl::INVALID_CONTENT, pAccImpl );
+ AppendEvent( aEvent );
+ }
+ else
+ {
+ pAccImpl->InvalidateContent();
}
}
}
}
}
}
+
+void SwAccessibleMap::FireEvents()
+{
+ vos::OGuard aGuard( aEventMutex );
+ if( pEvents )
+ {
+ SwAccessibleEventList_Impl::iterator aIter = pEvents->begin();
+ while( aIter != pEvents->end() )
+ {
+ ::vos::ORef < SwAccessibleContext > xAccImpl( (*aIter).GetContext() );
+ if( xAccImpl.isValid() )
+ {
+ switch( (*aIter).GetType() )
+ {
+ case SwAccessibleEvent_Impl::INVALID_CONTENT:
+ xAccImpl->InvalidateContent();
+ break;
+ case SwAccessibleEvent_Impl::POS_CHANGED:
+ xAccImpl->PosChanged();
+ break;
+ case SwAccessibleEvent_Impl::CHILD_POS_CHANGED:
+ xAccImpl->ChildPosChanged( (*aIter).GetFrm(),
+ (*aIter).GetOldFrm() );
+ break;
+ case SwAccessibleEvent_Impl::DISPOSE:
+ ASSERT( xAccImpl.isValid(),
+ "dispose event has been stored" );
+ break;
+ }
+ }
+
+ aIter++;
+ }
+ }
+
+ delete pEventMap;
+ pEventMap = 0;
+
+ delete pEvents;
+ pEvents = 0;
+}
diff --git a/sw/source/core/access/accpara.cxx b/sw/source/core/access/accpara.cxx
index 30d7be8722..da6a6aa967 100644
--- a/sw/source/core/access/accpara.cxx
+++ b/sw/source/core/access/accpara.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: accpara.cxx,v $
*
- * $Revision: 1.13 $
+ * $Revision: 1.14 $
*
- * last change: $Author: dvo $ $Date: 2002-03-04 12:43:32 $
+ * last change: $Author: mib $ $Date: 2002-03-08 13:26:29 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -109,6 +109,9 @@
#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLETEXTTYPE_HPP_
#include <drafts/com/sun/star/accessibility/AccessibleTextType.hpp>
#endif
+#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTID_HPP_
+#include <drafts/com/sun/star/accessibility/AccessibleEventId.hpp>
+#endif
#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX_
#include <unotools/accessiblestatesethelper.hxx>
@@ -152,6 +155,145 @@ using ::com::sun::star::beans::PropertyValue;
const sal_Char sServiceName[] = "com.sun.star.text.AccessibleParagraphView";
const sal_Char sImplementationName[] = "SwAccessibleParagraph";
const xub_StrLen MAX_DESC_TEXT_LEN = 40;
+const SwTxtNode* SwAccessibleParagraph::GetTxtNode() const
+{
+ const SwFrm* pFrm = GetFrm();
+ DBG_ASSERT( pFrm->IsTxtFrm(), "The text frame has mutated!" );
+
+ const SwTxtNode* pNode = static_cast<const SwTxtFrm*>(pFrm)->GetTxtNode();
+ DBG_ASSERT( pNode != NULL, "A text frame without a text node." );
+
+ return pNode;
+}
+
+OUString SwAccessibleParagraph::GetString()
+{
+ return GetPortionData().GetAccessibleString();
+}
+
+OUString SwAccessibleParagraph::GetDescription()
+{
+ const OUString& rText = GetString();
+
+ // the description contains the first sentence up to
+ // MAX_DESC_TEXT_LEN characters (including the next full word)
+ Boundary aBound;
+ if( rText.getLength() > 0 )
+ {
+ GetSentenceBoundary( aBound, rText, 0 );
+ if( aBound.endPos > MAX_DESC_TEXT_LEN )
+ {
+ GetWordBoundary( aBound, rText, MAX_DESC_TEXT_LEN );
+ aBound.startPos = 0;
+ }
+ }
+ else
+ GetEmptyBoundary( aBound );
+ OUString sArg1( rText.copy( aBound.startPos, aBound.endPos ) );
+
+ sal_Int16 nResId;
+ if( IsHeading() )
+ {
+ nResId = STR_ACCESS_HEADING_DESC;
+ }
+ else
+ {
+ nResId = STR_ACCESS_PARAGRAPH_DESC;
+ }
+
+ return GetResource( nResId, &sArg1 );
+}
+
+sal_Bool SwAccessibleParagraph::GetSelection(
+ sal_Int32& nStart, sal_Int32& nEnd)
+{
+ sal_Bool bRet = sal_False;
+ nStart = -1;
+ nEnd = -1;
+
+ // get the selection, and test whether it affects our text node
+ SwPaM* pCrsr = GetCrsr();
+ if( pCrsr != NULL )
+ {
+ // get SwPosition for my node
+ const SwTxtNode* pNode = GetTxtNode();
+ ULONG nHere = pNode->GetIndex();
+
+ // iterate over ring
+ SwPaM* pRingStart = pCrsr;
+ do
+ {
+ // ignore, if no mark
+ if( pCrsr->HasMark() )
+ {
+ // check whether nHere is 'inside' pCrsr
+ SwPosition* pStart = pCrsr->Start();
+ SwPosition* pEnd = pCrsr->End();
+ if( ( nHere >= pStart->nNode.GetIndex() ) &&
+ ( nHere <= pEnd->nNode.GetIndex() ) )
+ {
+ // Yup, we are selected!
+ bRet = sal_True;
+ nStart = static_cast<sal_Int32>(
+ ( nHere > pStart->nNode.GetIndex() ) ? 0
+ : pStart->nContent.GetIndex() );
+ nEnd = static_cast<sal_Int32>(
+ ( nHere < pEnd->nNode.GetIndex() ) ? pNode->Len()
+ : pEnd->nContent.GetIndex() );
+ }
+ // else: this PaM doesn't point to this paragraph
+ }
+ // else: this PaM is collapsed and doesn't select anything
+
+ // next PaM in ring
+ pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
+ }
+ while( !bRet && (pCrsr != pRingStart) );
+ }
+ // else: nocursor -> no selection
+
+ return bRet;
+}
+
+SwPaM* SwAccessibleParagraph::GetCrsr()
+{
+ // get the cursor shell; if we don't have any, we don't have a
+ // cursor/selection either
+ SwPaM* pCrsr = NULL;
+ SwCrsrShell* pCrsrShell = SwAccessibleParagraph::GetCrsrShell();
+ if( pCrsrShell != NULL )
+ {
+ // get the selection, and test whether it affects our text node
+ pCrsr = pCrsrShell->GetCrsr( FALSE /* ??? */ );
+ }
+
+ return pCrsr;
+}
+
+SwCrsrShell* SwAccessibleParagraph::GetCrsrShell()
+{
+ // first, get the view shell
+ DBG_ASSERT( GetMap() != NULL, "no map?" );
+ ViewShell* pViewShell = GetMap()->GetShell();
+ DBG_ASSERT( pViewShell != NULL,
+ "No view shell? Then what are you looking at?" );
+
+ SwCrsrShell* pCrsrShell = NULL;
+
+ // see if our view shell is a cursor shell
+ if( pViewShell->ISA( SwCrsrShell ) )
+ {
+ pCrsrShell = static_cast<SwCrsrShell*>( pViewShell );
+ }
+
+ return pCrsrShell;
+}
+
+sal_Bool SwAccessibleParagraph::IsHeading() const
+{
+ const SwTxtNode *pTxtNd = GetTxtNode();
+ return (pTxtNd->GetOutlineNum() && !pTxtNd->GetNum());
+}
void SwAccessibleParagraph::SetStates(
::utl::AccessibleStateSetHelper& rStateSet )
@@ -167,6 +309,48 @@ void SwAccessibleParagraph::SetStates(
// TODO: SELECTED
}
+void SwAccessibleParagraph::_InvalidateContent( sal_Bool bVisibleDataFired )
+{
+ OUString sOldText( GetString() );
+
+ ClearPortionData();
+
+ const OUString& rText = GetString();
+
+ if( rText != sOldText )
+ {
+ // The text is changed
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACCESSIBLE_TEXT_EVENT;
+
+ FireAccessibleEvent( aEvent );
+ }
+ else if( !bVisibleDataFired )
+ {
+ FireVisibleDataEvent();
+ }
+
+ sal_Bool bIsNowHeading = IsHeading();
+ if( bIsNowHeading != bIsHeading || rText != sOldText )
+ {
+ bIsHeading = bIsNowHeading;
+
+ OUString sNewDesc( GetDescription() );
+ if( sNewDesc != sDesc )
+ {
+ // The text is changed
+ AccessibleEventObject aEvent;
+ aEvent.EventId = AccessibleEventId::ACCESSIBLE_DESCRIPTION_EVENT;
+ aEvent.OldValue <<= sDesc;
+ aEvent.NewValue <<= sNewDesc;
+ sDesc = sNewDesc;
+
+ FireAccessibleEvent( aEvent );
+ }
+ }
+}
+
+
SwAccessibleParagraph::SwAccessibleParagraph(
SwAccessibleMap *pMap,
sal_Int32 nPara,
@@ -176,10 +360,9 @@ SwAccessibleParagraph::SwAccessibleParagraph(
{
vos::OGuard aGuard(Application::GetSolarMutex());
- const SwTxtNode *pTxtNd = pTxtFrm->GetTxtNode();
- sal_uInt16 nResId = (pTxtNd->GetOutlineNum() && !pTxtNd->GetNum())
- ? STR_ACCESS_HEADING_NAME
- : STR_ACCESS_PARAGRAPH_NAME;
+ bIsHeading = IsHeading();
+ sal_uInt16 nResId = bIsHeading ? STR_ACCESS_HEADING_NAME
+ : STR_ACCESS_PARAGRAPH_NAME;
OUString sArg( OUString::valueOf( nPara ) );
SetName( GetResource( nResId, &sArg ) );
}
@@ -309,24 +492,6 @@ void SwAccessibleParagraph::GetTextBoundary(
}
}
-
-const SwTxtNode* SwAccessibleParagraph::GetTxtNode()
-{
- const SwFrm* pFrm = GetFrm();
- DBG_ASSERT( pFrm->IsTxtFrm(), "The text frame has mutated!" );
-
- const SwTxtNode* pNode = static_cast<const SwTxtFrm*>(pFrm)->GetTxtNode();
- DBG_ASSERT( pNode != NULL, "A text frame without a text node." );
-
- return pNode;
-}
-
-OUString SwAccessibleParagraph::GetString()
-{
- return GetPortionData().GetAccessibleString();
-}
-
-
OUString SAL_CALL SwAccessibleParagraph::getAccessibleDescription (void)
throw (::com::sun::star::uno::RuntimeException)
{
@@ -334,36 +499,10 @@ OUString SAL_CALL SwAccessibleParagraph::getAccessibleDescription (void)
CHECK_FOR_DEFUNC( XAccessibleContext );
- const OUString& rText = GetString();
+ if( !sDesc.getLength() )
+ sDesc = GetDescription();
- // the description contains the first sentence up to
- // MAX_DESC_TEXT_LEN characters (including the next full word)
- Boundary aBound;
- if( rText.getLength() > 0 )
- {
- GetSentenceBoundary( aBound, rText, 0 );
- if( aBound.endPos > MAX_DESC_TEXT_LEN )
- {
- GetWordBoundary( aBound, rText, MAX_DESC_TEXT_LEN );
- aBound.startPos = 0;
- }
- }
- else
- GetEmptyBoundary( aBound );
- OUString sArg1( rText.copy( aBound.startPos, aBound.endPos ) );
-
- sal_uInt16 nResId;
- const SwTxtNode* pTxtNd = GetTxtNode();
- if( pTxtNd->GetOutlineNum() && !pTxtNd->GetNum() )
- {
- nResId = STR_ACCESS_HEADING_DESC;
- }
- else
- {
- nResId = STR_ACCESS_PARAGRAPH_DESC;
- }
-
- return GetResource( nResId, &sArg1 );
+ return sDesc;
}
Locale SAL_CALL SwAccessibleParagraph::getLocale (void)
@@ -821,92 +960,3 @@ sal_Bool SwAccessibleParagraph::setText( const OUString& sText )
return replaceText(0, GetString().getLength(), sText);
}
-
-
-
-
-
-SwCrsrShell* SwAccessibleParagraph::GetCrsrShell()
-{
- // first, get the view shell
- DBG_ASSERT( GetMap() != NULL, "no map?" );
- ViewShell* pViewShell = GetMap()->GetShell();
- DBG_ASSERT( pViewShell != NULL,
- "No view shell? Then what are you looking at?" );
-
- SwCrsrShell* pCrsrShell = NULL;
-
- // see if our view shell is a cursor shell
- if( pViewShell->ISA( SwCrsrShell ) )
- {
- pCrsrShell = static_cast<SwCrsrShell*>( pViewShell );
- }
-
- return pCrsrShell;
-}
-
-SwPaM* SwAccessibleParagraph::GetCrsr()
-{
- // get the cursor shell; if we don't have any, we don't have a
- // cursor/selection either
- SwPaM* pCrsr = NULL;
- SwCrsrShell* pCrsrShell = SwAccessibleParagraph::GetCrsrShell();
- if( pCrsrShell != NULL )
- {
- // get the selection, and test whether it affects our text node
- pCrsr = pCrsrShell->GetCrsr( FALSE /* ??? */ );
- }
-
- return pCrsr;
-}
-
-sal_Bool SwAccessibleParagraph::GetSelection(
- sal_Int32& nStart, sal_Int32& nEnd)
-{
- sal_Bool bRet = sal_False;
- nStart = -1;
- nEnd = -1;
-
- // get the selection, and test whether it affects our text node
- SwPaM* pCrsr = GetCrsr();
- if( pCrsr != NULL )
- {
- // get SwPosition for my node
- const SwTxtNode* pNode = GetTxtNode();
- ULONG nHere = pNode->GetIndex();
-
- // iterate over ring
- SwPaM* pRingStart = pCrsr;
- do
- {
- // ignore, if no mark
- if( pCrsr->HasMark() )
- {
- // check whether nHere is 'inside' pCrsr
- SwPosition* pStart = pCrsr->Start();
- SwPosition* pEnd = pCrsr->End();
- if( ( nHere >= pStart->nNode.GetIndex() ) &&
- ( nHere <= pEnd->nNode.GetIndex() ) )
- {
- // Yup, we are selected!
- bRet = sal_True;
- nStart = static_cast<sal_Int32>(
- ( nHere > pStart->nNode.GetIndex() ) ? 0
- : pStart->nContent.GetIndex() );
- nEnd = static_cast<sal_Int32>(
- ( nHere < pEnd->nNode.GetIndex() ) ? pNode->Len()
- : pEnd->nContent.GetIndex() );
- }
- // else: this PaM doesn't point to this paragraph
- }
- // else: this PaM is collapsed and doesn't select anything
-
- // next PaM in ring
- pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
- }
- while( !bRet && (pCrsr != pRingStart) );
- }
- // else: nocursor -> no selection
-
- return bRet;
-}
diff --git a/sw/source/core/access/accpara.hxx b/sw/source/core/access/accpara.hxx
index d939c4b7d4..27010fa624 100644
--- a/sw/source/core/access/accpara.hxx
+++ b/sw/source/core/access/accpara.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: accpara.hxx,v $
*
- * $Revision: 1.8 $
+ * $Revision: 1.9 $
*
- * last change: $Author: dvo $ $Date: 2002-03-01 16:07:57 $
+ * last change: $Author: mib $ $Date: 2002-03-08 13:26:29 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -87,6 +87,8 @@ namespace com { namespace sun { namespace star {
class SwAccessibleParagraph : public SwAccessibleContext,
public drafts::com::sun::star::accessibility::XAccessibleEditableText
{
+ ::rtl::OUString sDesc;
+
/// data for this paragraph's text portions; this contains the
/// mapping from the core 'model string' to the accessible text
/// string.
@@ -94,17 +96,16 @@ class SwAccessibleParagraph : public SwAccessibleContext,
/// Get/Clear/Has/UpdatePortionData() methods
SwAccessiblePortionData* pPortionData;
+ sal_Bool bIsHeading;
- // Set states for getAccessibleStateSet.
- // This drived class additinaly sets MULTILINE(1), SELECTABLE(1) and
- // SELECTED(0/1)
- virtual void SetStates( ::utl::AccessibleStateSetHelper& rStateSet );
/// get the SwTxtNode (requires frame; check before)
- const SwTxtNode* GetTxtNode();
+ const SwTxtNode* GetTxtNode() const;
/// get the (accessible) text string (requires frame; check before)
- rtl::OUString GetString();
+ ::rtl::OUString GetString();
+
+ ::rtl::OUString GetDescription();
/// determine whether the current selection. Fill the values with
/// -1 if there is no selection in the this paragraph
@@ -112,6 +113,17 @@ class SwAccessibleParagraph : public SwAccessibleContext,
SwPaM* GetCrsr(); /// helper for GetSelection and getCaretPosition
SwCrsrShell* GetCrsrShell(); /// helper for GetCrsr and setSelection
+ sal_Bool IsHeading() const;
+
+protected:
+
+ // Set states for getAccessibleStateSet.
+ // This drived class additinaly sets MULTILINE(1), SELECTABLE(1) and
+ // SELECTED(0/1)
+ virtual void SetStates( ::utl::AccessibleStateSetHelper& rStateSet );
+
+ virtual void _InvalidateContent( sal_Bool bVisibleDataFired );
+
public:
SwAccessibleParagraph( SwAccessibleMap *pMap, sal_Int32 nPara,