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