Kaydet (Commit) 0b8965b7 authored tarafından Michael Stahl's avatar Michael Stahl

sw_redlinehide_3: SwAccessibleHyperlink listen at SwFormatINetFormat

There is an annoying problem here: how does a SwAccessibleHyperlink
check whether its corresponding model hint still exists or not?

The existing check via the hint-position appears not ideal, and with the
MergedPara the obvious extension is to add a SwTextNode pointer (or
node index?) which would make it even less ideal...

Instead, do as a lot of classes in unocore do, and register as a
listener on the pool item.

There is another aspect there in how the SwAccessibleHyperTextData
map gets disposed quite eagerly when anything changes, but the
SwAccessibleHyperlink can live longer than this map.

Change-Id: I7d0780cf28794b4ef68cff5d640190694f67530e
üst 9933690d
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <svl/poolitem.hxx> #include <svl/poolitem.hxx>
#include "swdllapi.h" #include "swdllapi.h"
#include <memory> #include <memory>
#include "calbck.hxx"
class SvxMacro; class SvxMacro;
class SvxMacroTableDtor; class SvxMacroTableDtor;
...@@ -31,7 +32,9 @@ enum class SvMacroItemId : sal_uInt16; ...@@ -31,7 +32,9 @@ enum class SvMacroItemId : sal_uInt16;
// ATT_INETFMT // ATT_INETFMT
class SW_DLLPUBLIC SwFormatINetFormat: public SfxPoolItem class SW_DLLPUBLIC SwFormatINetFormat
: public SfxPoolItem
, public sw::BroadcasterMixin
{ {
friend class SwTextINetFormat; friend class SwTextINetFormat;
......
...@@ -33,31 +33,37 @@ using namespace ::com::sun::star; ...@@ -33,31 +33,37 @@ using namespace ::com::sun::star;
using namespace ::com::sun::star::accessibility; using namespace ::com::sun::star::accessibility;
using ::com::sun::star::lang::IndexOutOfBoundsException; using ::com::sun::star::lang::IndexOutOfBoundsException;
SwAccessibleHyperlink::SwAccessibleHyperlink( size_t nHPos, SwAccessibleHyperlink::SwAccessibleHyperlink(SwTextAttr & rTextAttr,
SwAccessibleParagraph *p, sal_Int32 nStt, sal_Int32 nEnd ) : SwAccessibleParagraph & rAccPara,
m_nHintPosition( nHPos ), sal_Int32 const nStt, sal_Int32 const nEnd)
m_xParagraph( p ), : m_pHyperlink(const_cast<SwFormatINetFormat*>(&rTextAttr.GetINetFormat()))
m_nStartIndex( nStt ), , m_xParagraph(&rAccPara)
m_nEndIndex( nEnd ) , m_nStartIndex( nStt )
, m_nEndIndex( nEnd )
{ {
StartListening(m_pHyperlink->GetNotifier());
} }
const SwTextAttr *SwAccessibleHyperlink::GetTextAttr() const SwAccessibleHyperlink::~SwAccessibleHyperlink()
{ {
const SwTextAttr *pTextAttr = nullptr; Invalidate(); // with SolarMutex!
if( m_xParagraph.is() && m_xParagraph->GetMap() ) }
{
const SwTextNode *pTextNd = m_xParagraph->GetTextNode(); // when the pool item dies, invalidate! this is the only reason for Listener...
const SwpHints *pHints = pTextNd->GetpSwpHints(); void SwAccessibleHyperlink::Notify(SfxHint const& rHint)
if( pHints && m_nHintPosition < pHints->Count() ) {
if (rHint.GetId() == SfxHintId::Dying)
{ {
const SwTextAttr *pHt = pHints->Get(m_nHintPosition); Invalidate();
if( RES_TXTATR_INETFMT == pHt->Which() )
pTextAttr = pHt;
}
} }
}
return pTextAttr; // both the parent SwAccessibleParagraph and the pool-item must be valid
const SwFormatINetFormat *SwAccessibleHyperlink::GetTextAttr() const
{
return (m_xParagraph.is() && m_xParagraph->GetMap())
? m_pHyperlink
: nullptr;
} }
// XAccessibleAction // XAccessibleAction
...@@ -74,29 +80,23 @@ sal_Bool SAL_CALL SwAccessibleHyperlink::doAccessibleAction( sal_Int32 nIndex ) ...@@ -74,29 +80,23 @@ sal_Bool SAL_CALL SwAccessibleHyperlink::doAccessibleAction( sal_Int32 nIndex )
if(nIndex != 0) if(nIndex != 0)
throw lang::IndexOutOfBoundsException(); throw lang::IndexOutOfBoundsException();
const SwTextAttr *pTextAttr = GetTextAttr(); SwFormatINetFormat const*const pINetFormat = GetTextAttr();
if( pTextAttr ) if (pINetFormat && !pINetFormat->GetValue().isEmpty())
{
const SwFormatINetFormat& rINetFormat = pTextAttr->GetINetFormat();
if( !rINetFormat.GetValue().isEmpty() )
{ {
SwViewShell *pVSh = m_xParagraph->GetShell(); SwViewShell *pVSh = m_xParagraph->GetShell();
if( pVSh ) if (pVSh)
{ {
LoadURL(*pVSh, rINetFormat.GetValue(), LoadUrlFlags::NONE, LoadURL(*pVSh, pINetFormat->GetValue(), LoadUrlFlags::NONE,
rINetFormat.GetTargetFrame()); pINetFormat->GetTargetFrame());
OSL_ENSURE( pTextAttr == rINetFormat.GetTextINetFormat(), const SwTextINetFormat *const pTextAttr = pINetFormat->GetTextINetFormat();
"lost my txt attr" ); if (pTextAttr)
const SwTextINetFormat* pTextAttr2 = rINetFormat.GetTextINetFormat();
if( pTextAttr2 )
{ {
const_cast<SwTextINetFormat*>(pTextAttr2)->SetVisited(true); const_cast<SwTextINetFormat*>(pTextAttr)->SetVisited(true);
const_cast<SwTextINetFormat*>(pTextAttr2)->SetVisitedValid(true); const_cast<SwTextINetFormat*>(pTextAttr)->SetVisitedValid(true);
} }
bRet = true; bRet = true;
} }
} }
}
return bRet; return bRet;
} }
...@@ -107,11 +107,10 @@ OUString SAL_CALL SwAccessibleHyperlink::getAccessibleActionDescription( ...@@ -107,11 +107,10 @@ OUString SAL_CALL SwAccessibleHyperlink::getAccessibleActionDescription(
if(nIndex != 0) if(nIndex != 0)
throw lang::IndexOutOfBoundsException(); throw lang::IndexOutOfBoundsException();
const SwTextAttr *pTextAttr = GetTextAttr(); SolarMutexGuard g;
if( pTextAttr ) if (SwFormatINetFormat const*const pINetFormat = GetTextAttr())
{ {
const SwFormatINetFormat& rINetFormat = pTextAttr->GetINetFormat(); return pINetFormat->GetValue();
return rINetFormat.GetValue();
} }
return OUString(); return OUString();
...@@ -161,12 +160,10 @@ uno::Any SAL_CALL SwAccessibleHyperlink::getAccessibleActionObject( ...@@ -161,12 +160,10 @@ uno::Any SAL_CALL SwAccessibleHyperlink::getAccessibleActionObject(
if(nIndex != 0) if(nIndex != 0)
throw lang::IndexOutOfBoundsException(); throw lang::IndexOutOfBoundsException();
const SwTextAttr *pTextAttr = GetTextAttr();
OUString retText; OUString retText;
if( pTextAttr ) if (SwFormatINetFormat const*const pINetFormat = GetTextAttr())
{ {
const SwFormatINetFormat& rINetFormat = pTextAttr->GetINetFormat(); retText = pINetFormat->GetValue();
retText = rINetFormat.GetValue();
} }
uno::Any aRet; uno::Any aRet;
aRet <<= retText; aRet <<= retText;
...@@ -188,12 +185,9 @@ sal_Bool SAL_CALL SwAccessibleHyperlink::isValid( ) ...@@ -188,12 +185,9 @@ sal_Bool SAL_CALL SwAccessibleHyperlink::isValid( )
SolarMutexGuard aGuard; SolarMutexGuard aGuard;
if (m_xParagraph.is()) if (m_xParagraph.is())
{ {
const SwTextAttr *pTextAttr = GetTextAttr(); if (SwFormatINetFormat const*const pINetFormat = GetTextAttr())
OUString sText;
if( pTextAttr )
{ {
const SwFormatINetFormat& rINetFormat = pTextAttr->GetINetFormat(); OUString const sText(pINetFormat->GetValue());
sText = rINetFormat.GetValue();
OUString sToken = "#"; OUString sToken = "#";
sal_Int32 nPos = sText.indexOf(sToken); sal_Int32 nPos = sText.indexOf(sToken);
if (nPos==0)//document link if (nPos==0)//document link
...@@ -240,6 +234,8 @@ void SwAccessibleHyperlink::Invalidate() ...@@ -240,6 +234,8 @@ void SwAccessibleHyperlink::Invalidate()
{ {
SolarMutexGuard aGuard; SolarMutexGuard aGuard;
m_xParagraph = nullptr; m_xParagraph = nullptr;
m_pHyperlink = nullptr;
EndListeningAll();
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -23,29 +23,34 @@ ...@@ -23,29 +23,34 @@
#include <com/sun/star/accessibility/XAccessibleHyperlink.hpp> #include <com/sun/star/accessibility/XAccessibleHyperlink.hpp>
#include <rtl/ref.hxx> #include <rtl/ref.hxx>
#include <cppuhelper/implbase.hxx> #include <cppuhelper/implbase.hxx>
#include <svl/listener.hxx>
#include <fmtinfmt.hxx> #include <fmtinfmt.hxx>
class SwAccessibleParagraph; class SwAccessibleParagraph;
class SwTextAttr; class SwTextAttr;
class SwAccessibleHyperlink : class SwAccessibleHyperlink
public ::cppu::WeakImplHelper< : public ::cppu::WeakImplHelper<css::accessibility::XAccessibleHyperlink>
css::accessibility::XAccessibleHyperlink > , public SvtListener
{ {
friend class SwAccessibleParagraph; friend class SwAccessibleParagraph;
friend class SwAccessibleHyperTextData; friend class SwAccessibleHyperTextData;
size_t const m_nHintPosition; SwFormatINetFormat * m_pHyperlink;
::rtl::Reference< SwAccessibleParagraph > m_xParagraph; ::rtl::Reference< SwAccessibleParagraph > m_xParagraph;
sal_Int32 const m_nStartIndex; sal_Int32 const m_nStartIndex;
sal_Int32 const m_nEndIndex; sal_Int32 const m_nEndIndex;
SwAccessibleHyperlink( size_t nHintPos, SwAccessibleHyperlink(SwTextAttr &,
SwAccessibleParagraph *p, SwAccessibleParagraph &,
sal_Int32 nStt, sal_Int32 nEnd ); sal_Int32 nStt, sal_Int32 nEnd );
virtual ~SwAccessibleHyperlink() override;
const SwTextAttr *GetTextAttr() const; const SwFormatINetFormat* GetTextAttr() const;
void Invalidate(); void Invalidate();
virtual void Notify(SfxHint const& rHint) override;
public: public:
// XAccessibleAction // XAccessibleAction
virtual sal_Int32 SAL_CALL getAccessibleActionCount() override; virtual sal_Int32 SAL_CALL getAccessibleActionCount() override;
......
...@@ -3064,8 +3064,8 @@ uno::Reference< XAccessibleHyperlink > SAL_CALL ...@@ -3064,8 +3064,8 @@ uno::Reference< XAccessibleHyperlink > SAL_CALL
max( aHIter.startIdx(), pHt->GetStart() ) ); max( aHIter.startIdx(), pHt->GetStart() ) );
const sal_Int32 nTmpHEnd= GetPortionData().GetAccessiblePosition( const sal_Int32 nTmpHEnd= GetPortionData().GetAccessiblePosition(
min( aHIter.endIdx(), *pHt->GetAnyEnd() ) ); min( aHIter.endIdx(), *pHt->GetAnyEnd() ) );
xRet = new SwAccessibleHyperlink( aHIter.getCurrHintPos(), xRet = new SwAccessibleHyperlink(*pHt,
this, nTmpHStt, nTmpHEnd ); *this, nTmpHStt, nTmpHEnd );
} }
if( aIter != m_pHyperTextData->end() ) if( aIter != m_pHyperTextData->end() )
{ {
......
...@@ -178,6 +178,7 @@ SwFormatINetFormat::SwFormatINetFormat( const OUString& rURL, const OUString& rT ...@@ -178,6 +178,7 @@ SwFormatINetFormat::SwFormatINetFormat( const OUString& rURL, const OUString& rT
SwFormatINetFormat::SwFormatINetFormat( const SwFormatINetFormat& rAttr ) SwFormatINetFormat::SwFormatINetFormat( const SwFormatINetFormat& rAttr )
: SfxPoolItem( RES_TXTATR_INETFMT ) : SfxPoolItem( RES_TXTATR_INETFMT )
, sw::BroadcasterMixin()
, msURL( rAttr.GetValue() ) , msURL( rAttr.GetValue() )
, msTargetFrame( rAttr.msTargetFrame ) , msTargetFrame( rAttr.msTargetFrame )
, msINetFormatName( rAttr.msINetFormatName ) , msINetFormatName( rAttr.msINetFormatName )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment