summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/ndtxt.hxx28
-rwxr-xr-xsw/qa/complex/writer/TextPortionEnumerationTest.java32
-rw-r--r--sw/source/core/crsr/crstrvl.cxx37
-rw-r--r--sw/source/core/crsr/trvlfnfl.cxx8
-rw-r--r--sw/source/core/doc/docfmt.cxx14
-rw-r--r--sw/source/core/edit/edattr.cxx8
-rw-r--r--sw/source/core/frmedt/fecopy.cxx5
-rw-r--r--sw/source/core/text/EnhancedPDFExportHelper.cxx11
-rw-r--r--sw/source/core/text/inftxt.cxx4
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx102
-rw-r--r--sw/source/core/undo/unattr.cxx4
-rw-r--r--sw/source/core/unocore/unocrsrhelper.cxx34
-rw-r--r--sw/source/core/unocore/unoidx.cxx141
-rw-r--r--sw/source/core/unocore/unoobj2.cxx4
-rw-r--r--sw/source/core/unocore/unorefmk.cxx52
-rw-r--r--sw/source/filter/ww1/fltshell.cxx4
16 files changed, 310 insertions, 178 deletions
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index f1582a95ba9a..27f360586b29 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -363,14 +363,26 @@ public:
BOOL DontExpandFmt( const SwIndex& rIdx, bool bFlag = true,
BOOL bFmtToTxtAttributes = TRUE );
- // gebe das vorgegebene Attribut, welches an der TextPosition (rIdx)
- // gesetzt ist zurueck. Gibt es keines, returne 0-Pointer
- // gesetzt heisst: Start <= rIdx < End
- // FIXME: this function does not seem to be well-defined for those
- // hints of which several may cover a single position, like TOXMark,
- // or CharFmt
- SwTxtAttr *GetTxtAttr( const SwIndex& rIdx, USHORT nWhichHt,
- BOOL bExpand = FALSE ) const;
+ /** get the innermost text attribute covering position nIndex.
+ @param nWhich only attribute with this id is returned.
+ @param bExpand the predicate for matching is:
+ (bExpand) ? (Start < nIndex <= End) : (Start <= nIndex < End)
+
+ ATTENTION: this function is not well-defined for those
+ hints of which several may cover a single position, like
+ RES_TXTATR_CHARFMT, RES_TXTATR_REFMARK, RES_TXTATR_TOXMARK
+ */
+ SwTxtAttr *GetTxtAttrAt(xub_StrLen const nIndex, RES_TXTATR const nWhich,
+ bool const bExpand = false) const;
+
+ /** get the innermost text attributes covering position nIndex.
+ @param nWhich only attributes with this id are returned.
+ @param bExpand the predicate for matching is:
+ (bExpand) ? (Start < nIndex <= End) : (Start <= nIndex < End)
+ */
+ ::std::vector<SwTxtAttr *> GetTxtAttrsAt(xub_StrLen const nIndex,
+ RES_TXTATR const nWhich,
+ bool const bExpand = false) const;
/** get the text attribute at position nIndex which owns
the dummy character CH_TXTATR_* at that position, if one exists.
diff --git a/sw/qa/complex/writer/TextPortionEnumerationTest.java b/sw/qa/complex/writer/TextPortionEnumerationTest.java
index 72e9664aaab4..8d5c3cab4d8a 100755
--- a/sw/qa/complex/writer/TextPortionEnumerationTest.java
+++ b/sw/qa/complex/writer/TextPortionEnumerationTest.java
@@ -1640,12 +1640,28 @@ public class TextPortionEnumerationTest extends ComplexTestCase
public void testRefMark3() throws Exception
{
+ // BUG: #i107672# (non-deterministic; depends on pointer ordering)
String name1 = mkName("refmark");
String name2 = mkName("refmark");
+ String name3 = mkName("refmark");
+ String name4 = mkName("refmark");
+ String name5 = mkName("refmark");
+ String name6 = mkName("refmark");
+ String name7 = mkName("refmark");
TreeNode root = new TreeNode();
root.appendChild( new ReferenceMarkStartNode(name1) );
root.appendChild( new ReferenceMarkStartNode(name2) );
+ root.appendChild( new ReferenceMarkStartNode(name3) );
+ root.appendChild( new ReferenceMarkStartNode(name4) );
+ root.appendChild( new ReferenceMarkStartNode(name5) );
+ root.appendChild( new ReferenceMarkStartNode(name6) );
+ root.appendChild( new ReferenceMarkStartNode(name7) );
root.appendChild( new TextNode("abc") );
+ root.appendChild( new ReferenceMarkEndNode(name7) );
+ root.appendChild( new ReferenceMarkEndNode(name6) );
+ root.appendChild( new ReferenceMarkEndNode(name5) );
+ root.appendChild( new ReferenceMarkEndNode(name4) );
+ root.appendChild( new ReferenceMarkEndNode(name3) );
root.appendChild( new ReferenceMarkEndNode(name2) );
root.appendChild( new ReferenceMarkEndNode(name1) );
root.appendChild( new TextNode("de") );
@@ -1665,12 +1681,28 @@ public class TextPortionEnumerationTest extends ComplexTestCase
public void testToxMark3() throws Exception
{
+ // BUG: #i107672# (non-deterministic; depends on pointer ordering)
String name1 = mkName("toxmark");
String name2 = mkName("toxmark");
+ String name3 = mkName("toxmark");
+ String name4 = mkName("toxmark");
+ String name5 = mkName("toxmark");
+ String name6 = mkName("toxmark");
+ String name7 = mkName("toxmark");
TreeNode root = new TreeNode();
root.appendChild( new DocumentIndexMarkStartNode(name1) );
root.appendChild( new DocumentIndexMarkStartNode(name2) );
+ root.appendChild( new DocumentIndexMarkStartNode(name3) );
+ root.appendChild( new DocumentIndexMarkStartNode(name4) );
+ root.appendChild( new DocumentIndexMarkStartNode(name5) );
+ root.appendChild( new DocumentIndexMarkStartNode(name6) );
+ root.appendChild( new DocumentIndexMarkStartNode(name7) );
root.appendChild( new TextNode("abc") );
+ root.appendChild( new DocumentIndexMarkEndNode(name7) );
+ root.appendChild( new DocumentIndexMarkEndNode(name6) );
+ root.appendChild( new DocumentIndexMarkEndNode(name5) );
+ root.appendChild( new DocumentIndexMarkEndNode(name4) );
+ root.appendChild( new DocumentIndexMarkEndNode(name3) );
root.appendChild( new DocumentIndexMarkEndNode(name2) );
root.appendChild( new DocumentIndexMarkEndNode(name1) );
root.appendChild( new TextNode("de") );
diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx
index 56986a9cf5e7..ee9dd6a9ed94 100644
--- a/sw/source/core/crsr/crstrvl.cxx
+++ b/sw/source/core/crsr/crstrvl.cxx
@@ -710,8 +710,9 @@ BOOL SwCrsrShell::MoveFldType( const SwFieldType* pFldType, BOOL bNext,
SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode();
ASSERT( pTNd, "Wo ist mein CntntNode?" );
- SwTxtFld* pTxtFld = (SwTxtFld*)pTNd->GetTxtAttr( rPos.nContent,
- RES_TXTATR_FIELD );
+ SwTxtFld * pTxtFld = static_cast<SwTxtFld *>(
+ pTNd->GetTxtAttrForCharAt(rPos.nContent.GetIndex(),
+ RES_TXTATR_FIELD));
BOOL bDelFld = 0 == pTxtFld;
if( bDelFld )
{
@@ -1231,13 +1232,27 @@ BOOL SwCrsrShell::GetContentAtPos( const Point& rPt,
{
pTxtAttr = 0;
if( SwContentAtPos::SW_TOXMARK & rCntntAtPos.eCntntAtPos )
- pTxtAttr = pTxtNd->GetTxtAttr( aPos.nContent,
- RES_TXTATR_TOXMARK );
+ {
+ ::std::vector<SwTxtAttr *> const marks(
+ pTxtNd->GetTxtAttrsAt(
+ aPos.nContent.GetIndex(), RES_TXTATR_TOXMARK));
+ if (marks.size())
+ { // hmm... can only return 1 here
+ pTxtAttr = *marks.begin();
+ }
+ }
if( !pTxtAttr &&
SwContentAtPos::SW_REFMARK & rCntntAtPos.eCntntAtPos )
- pTxtAttr = pTxtNd->GetTxtAttr( aPos.nContent,
- RES_TXTATR_REFMARK );
+ {
+ ::std::vector<SwTxtAttr *> const marks(
+ pTxtNd->GetTxtAttrsAt(
+ aPos.nContent.GetIndex(), RES_TXTATR_REFMARK));
+ if (marks.size())
+ { // hmm... can only return 1 here
+ pTxtAttr = *marks.begin();
+ }
+ }
if( pTxtAttr )
{
@@ -1282,8 +1297,8 @@ BOOL SwCrsrShell::GetContentAtPos( const Point& rPt,
if( !bRet && SwContentAtPos::SW_INETATTR & rCntntAtPos.eCntntAtPos
&& !aTmpState.bFtnNoInfo )
{
- pTxtAttr = pTxtNd->GetTxtAttr( aPos.nContent,
- RES_TXTATR_INETFMT );
+ pTxtAttr = pTxtNd->GetTxtAttrAt(
+ aPos.nContent.GetIndex(), RES_TXTATR_INETFMT);
// nur INetAttrs mit URLs "erkennen"
if( pTxtAttr && pTxtAttr->GetINetFmt().GetValue().Len() )
{
@@ -1618,8 +1633,10 @@ BOOL SwCrsrShell::SelectTxtAttr( USHORT nWhich, BOOL bExpand,
if( !pTxtAttr )
{
SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
- pTxtAttr = pTxtNd ? pTxtNd->GetTxtAttr( rPos.nContent,
- nWhich, bExpand ) : 0;
+ pTxtAttr = (pTxtNd)
+ ? pTxtNd->GetTxtAttrAt(rPos.nContent.GetIndex(),
+ static_cast<RES_TXTATR>(nWhich), bExpand)
+ : 0;
}
if( pTxtAttr )
diff --git a/sw/source/core/crsr/trvlfnfl.cxx b/sw/source/core/crsr/trvlfnfl.cxx
index af7360d64b40..3edf3718eabe 100644
--- a/sw/source/core/crsr/trvlfnfl.cxx
+++ b/sw/source/core/crsr/trvlfnfl.cxx
@@ -62,11 +62,13 @@ BOOL SwCursor::GotoFtnTxt()
{
// springe aus dem Content zur Fussnote
BOOL bRet = FALSE;
- SwTxtAttr *pFtn;
SwTxtNode* pTxtNd = GetPoint()->nNode.GetNode().GetTxtNode();
- if( pTxtNd && 0 != (
- pFtn = pTxtNd->GetTxtAttr( GetPoint()->nContent, RES_TXTATR_FTN ) ))
+ SwTxtAttr *const pFtn( (pTxtNd)
+ ? pTxtNd->GetTxtAttrForCharAt(
+ GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN)
+ : 0);
+ if (pFtn)
{
SwCrsrSaveState aSaveState( *this );
GetPoint()->nNode = *((SwTxtFtn*)pFtn)->GetStartNode();
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index af1236b6371c..d971ac0c51fe 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -397,10 +397,9 @@ void SwDoc::ResetAttrs( const SwPaM &rRg,
// JP 22.08.96: Sonderfall: steht der Crsr in einem URL-Attribut
// dann wird dessen Bereich genommen
- const SwTxtAttr* pURLAttr;
- if( pTxtNd->HasHints() &&
- 0 != ( pURLAttr = pTxtNd->GetTxtAttr( rSt, RES_TXTATR_INETFMT ))
- && pURLAttr->GetINetFmt().GetValue().Len() )
+ SwTxtAttr const*const pURLAttr(
+ pTxtNd->GetTxtAttrAt(rSt.GetIndex(), RES_TXTATR_INETFMT));
+ if (pURLAttr && pURLAttr->GetINetFmt().GetValue().Len())
{
nMkPos = *pURLAttr->GetStart();
nPtPos = *pURLAttr->GetEnd();
@@ -902,10 +901,9 @@ lcl_InsAttr(SwDoc *const pDoc, const SwPaM &rRg, const SfxItemSet& rChgSet,
// JP 22.08.96: Sonderfall: steht der Crsr in einem URL-Attribut
// dann wird dessen Bereich genommen
- const SwTxtAttr* pURLAttr;
- if( pTxtNd->HasHints() &&
- 0 != ( pURLAttr = pTxtNd->GetTxtAttr( rSt, RES_TXTATR_INETFMT ))
- && pURLAttr->GetINetFmt().GetValue().Len() )
+ SwTxtAttr const*const pURLAttr(
+ pTxtNd->GetTxtAttrAt(rSt.GetIndex(), RES_TXTATR_INETFMT));
+ if (pURLAttr && pURLAttr->GetINetFmt().GetValue().Len())
{
nMkPos = *pURLAttr->GetStart();
nPtPos = *pURLAttr->GetEnd();
diff --git a/sw/source/core/edit/edattr.cxx b/sw/source/core/edit/edattr.cxx
index 9e1cf28f0eb1..37ba5e5ced31 100644
--- a/sw/source/core/edit/edattr.cxx
+++ b/sw/source/core/edit/edattr.cxx
@@ -31,14 +31,10 @@
#include <hintids.hxx>
-#ifndef _SVX_TSTPITEM_HXX //autogen
#include <editeng/tstpitem.hxx>
-#endif
#include <editeng/lrspitem.hxx>
#include <editeng/scripttypeitem.hxx>
-#ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
#include <com/sun/star/i18n/ScriptType.hdl>
-#endif
#include <txatbase.hxx>
#include <txtftn.hxx>
#include <fmtftn.hxx>
@@ -230,8 +226,8 @@ BOOL SwEditShell::GetCurFtn( SwFmtFtn* pFillFtn )
if( !pTxtNd )
return FALSE;
- SwTxtAttr *pFtn = pTxtNd->GetTxtAttr( pCrsr->GetPoint()->nContent,
- RES_TXTATR_FTN );
+ SwTxtAttr *const pFtn = pTxtNd->GetTxtAttrForCharAt(
+ pCrsr->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
if( pFtn && pFillFtn )
{
// Daten vom Attribut uebertragen
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index 4ba5788c137f..9fe5c9a22204 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -182,8 +182,9 @@ BOOL SwFEShell::Copy( SwDoc* pClpDoc, const String* pNewClpTxt )
// das kopierte TextAttribut wieder entfernt werden,
// sonst wird es als TextSelektion erkannt
const SwIndex& rIdx = pFlyFmt->GetAnchor().GetCntntAnchor()->nContent;
- SwTxtFlyCnt* pTxtFly = (SwTxtFlyCnt*)pTxtNd->GetTxtAttr(
- rIdx, RES_TXTATR_FLYCNT );
+ SwTxtFlyCnt *const pTxtFly = static_cast<SwTxtFlyCnt *>(
+ pTxtNd->GetTxtAttrForCharAt(
+ rIdx.GetIndex(), RES_TXTATR_FLYCNT));
if( pTxtFly )
{
((SwFmtFlyCnt&)pTxtFly->GetFlyCnt()).SetFlyFmt( 0 );
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 697e99c96299..09c13b8fb250 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -1392,14 +1392,17 @@ void SwTaggedPDFHelper::BeginInlineStructureElements()
case POR_PARA :
{
SwTxtNode* pNd = (SwTxtNode*)pFrm->GetTxtNode();
- SwIndex aIndex( pNd, rInf.GetIdx() );
- const SwTxtAttr* pInetFmtAttr = pNd->GetTxtAttr( aIndex, RES_TXTATR_INETFMT );
+ SwTxtAttr const*const pInetFmtAttr =
+ pNd->GetTxtAttrAt(rInf.GetIdx(), RES_TXTATR_INETFMT);
String sStyleName;
if ( !pInetFmtAttr )
{
- const SwTxtAttr* pCharFmtAttr = pNd->GetTxtAttr( aIndex, RES_TXTATR_CHARFMT );
- const SwCharFmt* pCharFmt = pCharFmtAttr ? pCharFmtAttr->GetCharFmt().GetCharFmt() : 0;
+ ::std::vector<SwTxtAttr *> const charAttrs(
+ pNd->GetTxtAttrsAt(rInf.GetIdx(), RES_TXTATR_CHARFMT));
+ // TODO: handle more than 1 char style?
+ const SwCharFmt* pCharFmt = (charAttrs.size())
+ ? (*charAttrs.begin())->GetCharFmt().GetCharFmt() : 0;
if ( pCharFmt )
SwStyleNameMapper::FillProgName( pCharFmt->GetName(), sStyleName, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, sal_True );
}
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 9341206dfa71..18ce262f2342 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -1312,8 +1312,8 @@ void SwTxtPaintInfo::_NotifyURL( const SwLinePortion &rPor ) const
if( aIntersect.HasArea() )
{
SwTxtNode *pNd = (SwTxtNode*)GetTxtFrm()->GetTxtNode();
- SwIndex aIndex( pNd, GetIdx() );
- SwTxtAttr *pAttr = pNd->GetTxtAttr( aIndex, RES_TXTATR_INETFMT );
+ SwTxtAttr *const pAttr =
+ pNd->GetTxtAttrAt(GetIdx(), RES_TXTATR_INETFMT);
if( pAttr )
{
const SwFmtINetFmt& rFmt = pAttr->GetINetFmt();
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 8f17e4ce0005..4f730ae95d45 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1196,60 +1196,86 @@ BOOL SwTxtNode::DontExpandFmt( const SwIndex& rIdx, bool bFlag,
return bRet;
}
-
-// gebe das vorgegebene Attribut, welches an der TextPosition (rIdx)
-// gesetzt ist, zurueck. Gibt es keines, returne 0-Pointer.
-// (gesetzt heisst, je nach bExpand ?
-// Start < rIdx <= End
-// : Start <= rIdx < End )
-
-SwTxtAttr* SwTxtNode::GetTxtAttr( const SwIndex& rIdx, USHORT nWhichHt,
- BOOL bExpand ) const
+static void
+lcl_GetTxtAttrs(
+ ::std::vector<SwTxtAttr *> *const pVector, SwTxtAttr **const ppTxtAttr,
+ SwpHints *const pSwpHints,
+ xub_StrLen const nIndex, RES_TXTATR const nWhich, bool const bExpand)
{
- const SwTxtAttr* pRet = 0;
- const SwTxtAttr* pHt = 0;
- const xub_StrLen *pEndIdx = 0;
- const xub_StrLen nIdx = rIdx.GetIndex();
- const USHORT nSize = m_pSwpHints ? m_pSwpHints->Count() : 0;
+ USHORT const nSize = (pSwpHints) ? pSwpHints->Count() : 0;
+ xub_StrLen nPreviousIndex(0); // index of last hint with nWhich
for( USHORT i = 0; i < nSize; ++i )
{
- // ist der Attribut-Anfang schon groesser als der Idx ?
- pHt = (*m_pSwpHints)[i];
- if ( nIdx < *(pHt->GetStart()) )
- break; // beenden, kein gueltiges Attribut
-
- // ist es das gewuenschte Attribut ?
- if( pHt->Which() != nWhichHt )
- continue; // nein, weiter
-
- pEndIdx = pHt->GetEnd();
- // liegt innerhalb des Bereiches ??
- if( !pEndIdx )
+ SwTxtAttr *const pHint = pSwpHints->GetTextHint(i);
+ xub_StrLen const nHintStart( *(pHint->GetStart()) );
+ if (nIndex < nHintStart)
{
- if( *pHt->GetStart() == nIdx )
- {
- pRet = pHt;
- break;
- }
+ return; // hints are sorted by start, so we are done...
}
- else if( *pHt->GetStart() <= nIdx && nIdx <= *pEndIdx )
+
+ if (pHint->Which() != nWhich)
{
+ continue;
+ }
+
+ xub_StrLen const*const pEndIdx = pHint->GetEnd();
+ ASSERT(pEndIdx || pHint->HasDummyChar(),
+ "hint with no end and no dummy char?");
// Wenn bExpand gesetzt ist, wird das Verhalten bei Eingabe
// simuliert, d.h. der Start wuede verschoben, das Ende expandiert,
- if( bExpand )
+ bool const bContained( (pEndIdx)
+ ? ((bExpand)
+ ? ((nHintStart < nIndex) && (nIndex <= *pEndIdx))
+ : ((nHintStart <= nIndex) && (nIndex < *pEndIdx)))
+ : (nHintStart == nIndex) );
+ if (bContained)
+ {
+ if (pVector)
{
- if( *pHt->GetStart() < nIdx )
- pRet = pHt;
+ if (nPreviousIndex < nHintStart)
+ {
+ pVector->clear(); // clear hints that are outside pHint
+ nPreviousIndex = nHintStart;
+ }
+ pVector->push_back(pHint);
}
else
{
- if( nIdx < *pEndIdx )
- pRet = pHt; // den am dichtesten liegenden
+ *ppTxtAttr = pHint; // and possibly overwrite outer hint
+ }
+ if (!pEndIdx)
+ {
+ break;
}
}
}
- return (SwTxtAttr*)pRet; // kein gueltiges Attribut gefunden !!
+}
+
+::std::vector<SwTxtAttr *>
+SwTxtNode::GetTxtAttrsAt(xub_StrLen const nIndex, RES_TXTATR const nWhich,
+ bool const bExpand) const
+{
+ ::std::vector<SwTxtAttr *> ret;
+ lcl_GetTxtAttrs(& ret, 0, m_pSwpHints, nIndex, nWhich, bExpand);
+ return ret;
+}
+
+SwTxtAttr *
+SwTxtNode::GetTxtAttrAt(xub_StrLen const nIndex, RES_TXTATR const nWhich,
+ bool const bExpand) const
+{
+ ASSERT( (nWhich == RES_TXTATR_META)
+ || (nWhich == RES_TXTATR_METAFIELD)
+ || (nWhich == RES_TXTATR_AUTOFMT)
+ || (nWhich == RES_TXTATR_INETFMT)
+ || (nWhich == RES_TXTATR_CJK_RUBY)
+ || (nWhich == RES_TXTATR_UNKNOWN_CONTAINER),
+ "GetTxtAttrAt() will give wrong result for this hint!");
+
+ SwTxtAttr * pRet(0);
+ lcl_GetTxtAttrs(0, & pRet, m_pSwpHints, nIndex, nWhich, bExpand);
+ return pRet;
}
/*************************************************************************
diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx
index dd44a981d1d4..e3b54c59b142 100644
--- a/sw/source/core/undo/unattr.cxx
+++ b/sw/source/core/undo/unattr.cxx
@@ -1055,8 +1055,8 @@ void SwUndoAttr::RemoveIdx( SwDoc& rDoc )
SwTxtNode* pTxtNd = rNds[ nNode ]->GetTxtNode();
if( pTxtNd )
{
- SwIndex aIdx( pTxtNd, nCntnt );
- SwTxtAttr * pTxtHt = pTxtNd->GetTxtAttr( aIdx, RES_TXTATR_FTN );
+ SwTxtAttr *const pTxtHt =
+ pTxtNd->GetTxtAttrForCharAt(nCntnt, RES_TXTATR_FTN);
if( pTxtHt )
{
// ok, dann hole mal die Werte
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
index 3a40c25aecf8..1761c64b351d 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -302,14 +302,15 @@ sal_Bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
break;
case FN_UNO_DOCUMENT_INDEX_MARK:
{
- SwTxtAttr* pTxtAttr = rPam.GetNode()->GetTxtNode()->GetTxtAttr(
- rPam.GetPoint()->nContent, RES_TXTATR_TOXMARK);
- if(pTxtAttr)
+ ::std::vector<SwTxtAttr *> const marks(
+ rPam.GetNode()->GetTxtNode()->GetTxtAttrsAt(
+ rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_TOXMARK));
+ if (marks.size())
{
if( pAny )
- {
+ { // hmm... can only return 1 here
SwTOXMark & rMark =
- static_cast<SwTOXMark&>(pTxtAttr->GetAttr());
+ static_cast<SwTOXMark &>((*marks.begin())->GetAttr());
const uno::Reference< text::XDocumentIndexMark > xRef =
SwXDocumentIndexMark::CreateXDocumentIndexMark(
*rPam.GetDoc(),
@@ -345,9 +346,10 @@ sal_Bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
const SwPosition *pPos = rPam.Start();
const SwTxtNode *pTxtNd =
rPam.GetDoc()->GetNodes()[pPos->nNode.GetIndex()]->GetTxtNode();
- SwTxtAttr* pTxtAttr =
- pTxtNd ? pTxtNd->GetTxtAttr(pPos->nContent, RES_TXTATR_FIELD)
- : 0;
+ SwTxtAttr *const pTxtAttr = (pTxtNd)
+ ? pTxtNd->GetTxtAttrForCharAt(
+ pPos->nContent.GetIndex(), RES_TXTATR_FIELD)
+ : 0;
if(pTxtAttr)
{
if( pAny )
@@ -436,8 +438,9 @@ sal_Bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
case FN_UNO_ENDNOTE:
case FN_UNO_FOOTNOTE:
{
- SwTxtAttr* pTxtAttr = rPam.GetNode()->GetTxtNode()->
- GetTxtAttr(rPam.GetPoint()->nContent, RES_TXTATR_FTN);
+ SwTxtAttr *const pTxtAttr =
+ rPam.GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
+ rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
if(pTxtAttr)
{
const SwFmtFtn& rFtn = pTxtAttr->GetFtn();
@@ -459,13 +462,14 @@ sal_Bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
break;
case FN_UNO_REFERENCE_MARK:
{
- SwTxtAttr* pTxtAttr = rPam.GetNode()->GetTxtNode()->
- GetTxtAttr(rPam.GetPoint()->nContent, RES_TXTATR_REFMARK);
- if(pTxtAttr)
+ ::std::vector<SwTxtAttr *> const marks(
+ rPam.GetNode()->GetTxtNode()->GetTxtAttrsAt(
+ rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_REFMARK));
+ if (marks.size())
{
if( pAny )
- {
- const SwFmtRefMark& rRef = pTxtAttr->GetRefMark();
+ { // hmm... can only return 1 here
+ const SwFmtRefMark& rRef = (*marks.begin())->GetRefMark();
uno::Reference< XTextContent > xRef = SwXReferenceMarks::GetObject( rPam.GetDoc(), &rRef );
pAny->setValue(&xRef, ::getCppuType((uno::Reference<XTextContent>*)0));
}
diff --git a/sw/source/core/unocore/unoidx.cxx b/sw/source/core/unocore/unoidx.cxx
index 8749e9efb80a..da8b37561525 100644
--- a/sw/source/core/unocore/unoidx.cxx
+++ b/sw/source/core/unocore/unoidx.cxx
@@ -1622,6 +1622,8 @@ public:
// SwClient
virtual void Modify(SfxPoolItem *pOld, SfxPoolItem *pNew);
+ void InsertTOXMark(SwTOXMark & rMark, SwPaM & rPam,
+ SwXTextCursor const*const pTextCursor);
};
/* -----------------------------16.10.00 11:24--------------------------------
@@ -1835,28 +1837,7 @@ throw (uno::RuntimeException)
m_pImpl->m_pDoc->DeleteTOXMark(m_pImpl->m_pTOXMark);
m_pImpl->m_pTOXMark = 0;
- SwTxtAttr* pTxtAttr = 0;
- sal_Bool bInsAtPos = aMark.IsAlternativeText();
- const SwPosition *pStt = aPam.Start(),
- *pEnd = aPam.End();
- if( bInsAtPos )
- {
- SwPaM aTmp( *pStt );
- m_pImpl->m_pDoc->InsertPoolItem( aTmp, aMark, 0 );
- pTxtAttr = pStt->nNode.GetNode().GetTxtNode()->GetTxtAttrForCharAt(
- pStt->nContent.GetIndex()-1, RES_TXTATR_TOXMARK);
- }
- else if( *pEnd != *pStt )
- {
- m_pImpl->m_pDoc->InsertPoolItem( aPam, aMark,
- nsSetAttrMode::SETATTR_DONTEXPAND );
- pTxtAttr = pStt->nNode.GetNode().GetTxtNode()->GetTxtAttr(
- pStt->nContent, RES_TXTATR_TOXMARK);
- }
- if(pTxtAttr)
- {
- m_pImpl->m_pTOXMark = &pTxtAttr->GetTOXMark();
- }
+ m_pImpl->InsertTOXMark(aMark, aPam, 0);
}
else if (m_pImpl->m_bIsDescriptor)
{
@@ -1984,17 +1965,47 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
default:
break;
}
+
+ m_pImpl->InsertTOXMark(aMark, aPam,
+ dynamic_cast<SwXTextCursor const*>(pCursor));
+
+ m_pImpl->m_pDoc = pDoc;
+ m_pImpl->m_bIsDescriptor = sal_False;
+
+ const_cast<SwTOXType*>(pTOXType)->Add(&m_pImpl->m_TypeDepend);
+}
+
+template<typename T> struct NotContainedIn
+{
+ ::std::vector<T> const& m_rVector;
+ explicit NotContainedIn(::std::vector<T> const& rVector)
+ : m_rVector(rVector) { }
+ bool operator() (T const& rT) {
+ return ::std::find(m_rVector.begin(), m_rVector.end(), rT)
+ == m_rVector.end();
+ }
+};
+
+void SwXDocumentIndexMark::Impl::InsertTOXMark(SwTOXMark & rMark, SwPaM & rPam,
+ SwXTextCursor const*const pTextCursor)
+{
+ SwDoc *const pDoc( rPam.GetDoc() );
UnoActionContext aAction(pDoc);
- const sal_Bool bMark = *aPam.GetPoint() != *aPam.GetMark();
+ bool bMark = *rPam.GetPoint() != *rPam.GetMark();
+ // n.b.: toxmarks must have either alternative text or an extent
+ if (bMark && rMark.GetAlternativeText().Len())
+ {
+ rPam.Normalize(TRUE);
+ rPam.DeleteMark();
+ bMark = false;
+ }
// Marks ohne Alternativtext ohne selektierten Text koennen nicht eingefuegt werden,
// deshalb hier ein Leerzeichen - ob das die ideale Loesung ist?
- if (!bMark && !aMark.GetAlternativeText().Len())
+ if (!bMark && !rMark.GetAlternativeText().Len())
{
- aMark.SetAlternativeText( String(' ') );
+ rMark.SetAlternativeText( String(' ') );
}
- SwXTextCursor const*const pTextCursor(
- dynamic_cast<SwXTextCursor*>(pCursor));
const bool bForceExpandHints( (!bMark && pTextCursor)
? pTextCursor->IsAtEndOfMeta() : false );
const SetAttrMode nInsertFlags = (bForceExpandHints)
@@ -2002,35 +2013,52 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
| nsSetAttrMode::SETATTR_DONTEXPAND)
: nsSetAttrMode::SETATTR_DONTEXPAND;
- pDoc->InsertPoolItem(aPam, aMark, nInsertFlags);
- if (bMark && *aPam.GetPoint() > *aPam.GetMark())
+ ::std::vector<SwTxtAttr *> oldMarks;
+ if (bMark)
+ {
+ oldMarks = rPam.GetNode()->GetTxtNode()->GetTxtAttrsAt(
+ rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_TOXMARK);
+ }
+
+ pDoc->InsertPoolItem(rPam, rMark, nInsertFlags);
+ if (bMark && *rPam.GetPoint() > *rPam.GetMark())
{
- aPam.Exchange();
+ rPam.Exchange();
}
- SwTxtAttr* pTxtAttr = 0;
+ // rMark was copied into the document pool; now retrieve real format...
+ SwTxtAttr * pTxtAttr(0);
if (bMark)
{
- pTxtAttr = aPam.GetNode()->GetTxtNode()->GetTxtAttr(
- aPam.GetPoint()->nContent, RES_TXTATR_TOXMARK );
+ // #i107672#
+ // ensure that we do not retrieve a different mark at the same position
+ ::std::vector<SwTxtAttr *> const newMarks(
+ rPam.GetNode()->GetTxtNode()->GetTxtAttrsAt(
+ rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_TOXMARK));
+ ::std::vector<SwTxtAttr *>::const_iterator const iter(
+ ::std::find_if(newMarks.begin(), newMarks.end(),
+ NotContainedIn<SwTxtAttr *>(oldMarks)));
+ OSL_ASSERT(newMarks.end() != iter);
+ if (newMarks.end() != iter)
+ {
+ pTxtAttr = *iter;
+ }
}
else
{
- pTxtAttr = aPam.GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
- aPam.GetPoint()->nContent.GetIndex()-1, RES_TXTATR_TOXMARK );
+ pTxtAttr = rPam.GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
+ rPam.GetPoint()->nContent.GetIndex()-1, RES_TXTATR_TOXMARK );
}
if (!pTxtAttr)
{
- throw uno::RuntimeException();
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "SwXDocumentIndexMark::InsertTOXMark(): cannot insert attribute")),
+ 0);
}
- m_pImpl->m_pTOXMark = &pTxtAttr->GetTOXMark();
- m_pImpl->m_pDoc = pDoc;
- m_pImpl->m_bIsDescriptor = sal_False;
-
- const_cast<SwTOXMark*>(m_pImpl->m_pTOXMark)->Add(m_pImpl.get());
- const_cast<SwTOXType*>(pTOXType)->Add(&m_pImpl->m_TypeDepend);
+ m_pTOXMark = & pTxtAttr->GetTOXMark();
+ const_cast<SwTOXMark*>(m_pTOXMark)->Add(this);
}
/*-- 14.12.98 10:25:45---------------------------------------------------
@@ -2229,33 +2257,8 @@ throw (beans::UnknownPropertyException, beans::PropertyVetoException,
pLocalDoc->DeleteTOXMark(m_pImpl->m_pTOXMark);
m_pImpl->m_pTOXMark = 0;
- sal_Bool bInsAtPos = aMark.IsAlternativeText();
- const SwPosition *pStt = aPam.Start();
- const SwPosition *pEnd = aPam.End();
-
- SwTxtAttr* pTxtAttr = 0;
- if( bInsAtPos )
- {
- SwPaM aTmp( *pStt );
- pLocalDoc->InsertPoolItem( aTmp, aMark, 0 );
- pTxtAttr = pStt->nNode.GetNode().GetTxtNode()->GetTxtAttrForCharAt(
- pStt->nContent.GetIndex()-1, RES_TXTATR_TOXMARK );
- }
- else if( *pEnd != *pStt )
- {
- pLocalDoc->InsertPoolItem( aPam, aMark,
- nsSetAttrMode::SETATTR_DONTEXPAND );
- pTxtAttr = pStt->nNode.GetNode().GetTxtNode()->GetTxtAttr(
- pStt->nContent, RES_TXTATR_TOXMARK );
- }
- m_pImpl->m_pDoc = pLocalDoc;
-
- if(pTxtAttr)
- {
- m_pImpl->m_pTOXMark = &pTxtAttr->GetTOXMark();
- const_cast<SwTOXMark*>(m_pImpl->m_pTOXMark)->Add(m_pImpl.get());
- pType->Add(&m_pImpl->m_TypeDepend);
- }
+ m_pImpl->InsertTOXMark(aMark, aPam, 0);
+ pType->Add(& m_pImpl->m_TypeDepend);
}
else if (m_pImpl->m_bIsDescriptor)
{
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
index 161afb2373bd..d9334e97c841 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -1934,8 +1934,8 @@ lcl_FillFrame(SwClient & rEnum, SwUnoCrsr& rUnoCrsr,
{
// search for objects at the cursor - anchored at/as char
SwTxtAttr const*const pTxtAttr =
- rUnoCrsr.GetNode()->GetTxtNode()->GetTxtAttr(
- rUnoCrsr.GetPoint()->nContent, RES_TXTATR_FLYCNT);
+ rUnoCrsr.GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
+ rUnoCrsr.GetPoint()->nContent.GetIndex(), RES_TXTATR_FLYCNT);
if (pTxtAttr)
{
const SwFmtFlyCnt& rFlyCnt = pTxtAttr->GetFlyCnt();
diff --git a/sw/source/core/unocore/unorefmk.cxx b/sw/source/core/unocore/unorefmk.cxx
index 1450e1bd806a..26c12ebb59fb 100644
--- a/sw/source/core/unocore/unorefmk.cxx
+++ b/sw/source/core/unocore/unorefmk.cxx
@@ -235,6 +235,17 @@ throw (uno::RuntimeException)
/* -----------------03.11.99 14:14-------------------
--------------------------------------------------*/
+template<typename T> struct NotContainedIn
+{
+ ::std::vector<T> const& m_rVector;
+ explicit NotContainedIn(::std::vector<T> const& rVector)
+ : m_rVector(rVector) { }
+ bool operator() (T const& rT) {
+ return ::std::find(m_rVector.begin(), m_rVector.end(), rT)
+ == m_rVector.end();
+ }
+};
+
void SwXReferenceMark::Impl::InsertRefMark(SwPaM& rPam,
SwXTextCursor const*const pCursor)
{
@@ -254,6 +265,13 @@ void SwXReferenceMark::Impl::InsertRefMark(SwPaM& rPam,
| nsSetAttrMode::SETATTR_DONTEXPAND)
: nsSetAttrMode::SETATTR_DONTEXPAND;
+ ::std::vector<SwTxtAttr *> oldMarks;
+ if (bMark)
+ {
+ oldMarks = rPam.GetNode()->GetTxtNode()->GetTxtAttrsAt(
+ rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_REFMARK);
+ }
+
pDoc2->InsertPoolItem( rPam, aRefMark, nInsertFlags );
if( bMark && *rPam.GetPoint() > *rPam.GetMark())
@@ -261,17 +279,38 @@ void SwXReferenceMark::Impl::InsertRefMark(SwPaM& rPam,
rPam.Exchange();
}
- SwTxtAttr *const pTxtAttr = (bMark)
- ? rPam.GetNode()->GetTxtNode()->GetTxtAttr(
- rPam.GetPoint()->nContent, RES_TXTATR_REFMARK)
- : rPam.GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
+ // aRefMark was copied into the document pool; now retrieve real format...
+ SwTxtAttr * pTxtAttr(0);
+ if (bMark)
+ {
+ // #i107672#
+ // ensure that we do not retrieve a different mark at the same position
+ ::std::vector<SwTxtAttr *> const newMarks(
+ rPam.GetNode()->GetTxtNode()->GetTxtAttrsAt(
+ rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_REFMARK));
+ ::std::vector<SwTxtAttr *>::const_iterator const iter(
+ ::std::find_if(newMarks.begin(), newMarks.end(),
+ NotContainedIn<SwTxtAttr *>(oldMarks)));
+ OSL_ASSERT(newMarks.end() != iter);
+ if (newMarks.end() != iter)
+ {
+ pTxtAttr = *iter;
+ }
+ }
+ else
+ {
+ pTxtAttr = rPam.GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
rPam.GetPoint()->nContent.GetIndex() - 1, RES_TXTATR_REFMARK);
+ }
- if(pTxtAttr)
+ if (!pTxtAttr)
{
- m_pMarkFmt = &pTxtAttr->GetRefMark();
+ throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "SwXReferenceMark::InsertRefMark(): cannot insert attribute")), 0);
}
+ m_pMarkFmt = &pTxtAttr->GetRefMark();
+
pDoc2->GetUnoCallBack()->Add(this);
}
@@ -310,7 +349,6 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
m_pImpl->InsertRefMark(aPam, dynamic_cast<SwXTextCursor*>(pCursor));
m_pImpl->m_bIsDescriptor = sal_False;
m_pImpl->m_pDoc = pDocument;
- m_pImpl->m_pDoc->GetUnoCallBack()->Add(m_pImpl.get());
}
/*-- 11.12.98 10:28:34---------------------------------------------------
diff --git a/sw/source/filter/ww1/fltshell.cxx b/sw/source/filter/ww1/fltshell.cxx
index abe41737438b..010b5d174e42 100644
--- a/sw/source/filter/ww1/fltshell.cxx
+++ b/sw/source/filter/ww1/fltshell.cxx
@@ -1934,8 +1934,8 @@ void SwFltShell::BeginFootnote()
pSavedPos = new SwPosition(*pPaM->GetPoint());
pPaM->Move(fnMoveBackward, fnGoCntnt);
SwTxtNode* pTxt = pPaM->GetNode()->GetTxtNode();
- SwTxtAttr* pFN = pTxt->GetTxtAttr(pPaM->GetPoint()->nContent,
- RES_TXTATR_FTN);
+ SwTxtAttr *const pFN = pTxt->GetTxtAttrForCharAt(
+ pPaM->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
if( !pFN ){ // Passiert z.B. bei Fussnote in Fly
ASSERT(pFN, "Probleme beim Anlegen des Fussnoten-Textes");
return;