diff options
author | Michael Stahl <mst@openoffice.org> | 2010-03-09 13:27:18 +0100 |
---|---|---|
committer | Michael Stahl <mst@openoffice.org> | 2010-03-09 13:27:18 +0100 |
commit | 310be1160a7205e11967b8cc5a0ad1669343538d (patch) | |
tree | 0e5829e54f257208d2bc88119411fceb018f492d | |
parent | 6ca446db78cc9724a343eef3ab4c8fc9068c735c (diff) |
odfmetadata4: #i107672#: SwX{Reference,DocumentIndex}Mark attach to right fmt:
replace SwTxtNode::GetTxtAttr() with methods:
GetTxtAttrAt() handles only those hints where only 1 can be at same position.
GetTxtAttrsAt() handles all hints and returns a vector.
refactor SwXDocumentIndexMark to create InsertTOXMark() method.
-rw-r--r-- | sw/inc/ndtxt.hxx | 28 | ||||
-rwxr-xr-x | sw/qa/complex/writer/TextPortionEnumerationTest.java | 32 | ||||
-rw-r--r-- | sw/source/core/crsr/crstrvl.cxx | 37 | ||||
-rw-r--r-- | sw/source/core/crsr/trvlfnfl.cxx | 8 | ||||
-rw-r--r-- | sw/source/core/doc/docfmt.cxx | 14 | ||||
-rw-r--r-- | sw/source/core/edit/edattr.cxx | 8 | ||||
-rw-r--r-- | sw/source/core/frmedt/fecopy.cxx | 5 | ||||
-rw-r--r-- | sw/source/core/text/EnhancedPDFExportHelper.cxx | 11 | ||||
-rw-r--r-- | sw/source/core/text/inftxt.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 102 | ||||
-rw-r--r-- | sw/source/core/undo/unattr.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/unocore/unocrsrhelper.cxx | 34 | ||||
-rw-r--r-- | sw/source/core/unocore/unoidx.cxx | 141 | ||||
-rw-r--r-- | sw/source/core/unocore/unoobj2.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/unocore/unorefmk.cxx | 52 | ||||
-rw-r--r-- | sw/source/filter/ww1/fltshell.cxx | 4 |
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; |