diff options
Diffstat (limited to 'sw/source/core/txtnode/thints.cxx')
-rw-r--r-- | sw/source/core/txtnode/thints.cxx | 244 |
1 files changed, 197 insertions, 47 deletions
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index 451f57ff4348..35ce95c25ef4 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -123,7 +123,7 @@ struct TxtAttrContains TxtAttrContains( const xub_StrLen nPos ) : m_nPos( nPos ) { } bool operator() (SwTxtAttrEnd * const pAttr) { - return (*pAttr->GetStart() < m_nPos) && (m_nPos < *pAttr->GetEnd()); + return (*pAttr->GetStart() < m_nPos) && (m_nPos < *pAttr->End()); } }; @@ -167,7 +167,8 @@ static bool isSelfNestable(const sal_uInt16 nWhich) { if ((RES_TXTATR_INETFMT == nWhich) || - (RES_TXTATR_CJK_RUBY == nWhich)) + (RES_TXTATR_CJK_RUBY == nWhich) || + (RES_TXTATR_INPUTFIELD == nWhich)) return false; ASSERT((RES_TXTATR_META == nWhich) || (RES_TXTATR_METAFIELD == nWhich), "???"); @@ -181,7 +182,8 @@ bool isSplittable(const sal_uInt16 nWhich) (RES_TXTATR_CJK_RUBY == nWhich)) return true; ASSERT((RES_TXTATR_META == nWhich) || - (RES_TXTATR_METAFIELD == nWhich), "???"); + (RES_TXTATR_METAFIELD == nWhich) || + (RES_TXTATR_INPUTFIELD == nWhich), "???"); return false; } @@ -202,8 +204,10 @@ splitPolicy(const sal_uInt16 nWhichNew, const sal_uInt16 nWhichOther) } else { - if ((RES_TXTATR_INETFMT == nWhichNew) && - (RES_TXTATR_CJK_RUBY == nWhichOther)) + if ( RES_TXTATR_INPUTFIELD == nWhichNew ) + return FAIL; + else if ( (RES_TXTATR_INETFMT == nWhichNew) && + (RES_TXTATR_CJK_RUBY == nWhichOther) ) return SPLIT_NEW; else return SPLIT_OTHER; @@ -362,14 +366,14 @@ SwpHints::TryInsertNesting( SwTxtNode & rNode, SwTxtAttrNesting & rNewHint ) const sal_uInt16 nNewWhich( rNewHint.Which() ); const xub_StrLen nNewStart( *rNewHint.GetStart() ); const xub_StrLen nNewEnd ( *rNewHint.GetEnd() ); -//??? const bool bNoLengthAttribute( nNewStart == nNewEnd ); const bool bNewSelfNestable( isSelfNestable(nNewWhich) ); ASSERT( (RES_TXTATR_INETFMT == nNewWhich) || (RES_TXTATR_CJK_RUBY == nNewWhich) || (RES_TXTATR_META == nNewWhich) || - (RES_TXTATR_METAFIELD == nNewWhich), - "TryInsertNesting: Expecting INETFMT or RUBY or META or METAFIELD" ); + (RES_TXTATR_METAFIELD == nNewWhich) || + (RES_TXTATR_INPUTFIELD == nNewWhich), + "TryInsertNesting: Expecting INETFMT or RUBY or META or METAFIELD or INPUTFIELD" ); NestList_t OverlappingExisting; // existing hints to be split NestList_t OverwrittenExisting; // existing hints to be replaced @@ -681,7 +685,7 @@ void SwpHints::BuildPortions( SwTxtNode& rNode, SwTxtAttr& rNewHint, continue; const xub_StrLen nOtherStart = *pOther->GetStart(); - const xub_StrLen nOtherEnd = *pOther->GetEnd(); + const xub_StrLen nOtherEnd = *pOther->End(); aBounds.insert( nOtherStart ); aBounds.insert( nOtherEnd ); @@ -989,9 +993,13 @@ SwTxtAttr* MakeRedlineTxtAttr( SwDoc & rDoc, SfxPoolItem & rAttr ) } // create new text attribute -SwTxtAttr* MakeTxtAttr( SwDoc & rDoc, SfxPoolItem& rAttr, - xub_StrLen const nStt, xub_StrLen const nEnd, - CopyOrNew_t const bIsCopy, SwTxtNode *const pTxtNode) +SwTxtAttr* MakeTxtAttr( + SwDoc & rDoc, + SfxPoolItem& rAttr, + xub_StrLen const nStt, + xub_StrLen const nEnd, + CopyOrNew_t const bIsCopy, + SwTxtNode *const pTxtNode ) { if ( isCHRATR(rAttr.Which()) ) { @@ -1041,6 +1049,9 @@ SwTxtAttr* MakeTxtAttr( SwDoc & rDoc, SfxPoolItem& rAttr, case RES_TXTATR_FIELD: pNew = new SwTxtFld( static_cast<SwFmtFld &>(rNew), nStt ); break; + case RES_TXTATR_INPUTFIELD: + pNew = new SwTxtInputFld( static_cast<SwFmtFld &>(rNew), nStt, nEnd ); + break; case RES_TXTATR_FLYCNT: { // erst hier wird das Frame-Format kopiert (mit Inhalt) !! @@ -1126,6 +1137,7 @@ void SwTxtNode::DestroyAttr( SwTxtAttr* pAttr ) break; case RES_TXTATR_FIELD: + case RES_TXTATR_INPUTFIELD: if( !pDoc->IsInDtor() ) { // Wenn wir ein HiddenParaField sind, dann muessen wir @@ -1228,7 +1240,7 @@ SwTxtNode::InsertItem( SfxPoolItem& rAttr, // take ownership of pAttr; if insertion fails, delete pAttr bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode ) { - sal_Bool bHiddenPara = sal_False; + bool bHiddenPara = false; ASSERT( pAttr && *pAttr->GetStart() <= Len(), "StartIdx out of bounds!" ); ASSERT( !pAttr->GetEnd() || (*pAttr->GetEnd() <= Len()), @@ -1250,7 +1262,7 @@ bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode ) sal_uInt16 nInsMode = nMode; switch( pAttr->Which() ) { - case RES_TXTATR_FLYCNT: + case RES_TXTATR_FLYCNT: { SwTxtFlyCnt *pFly = (SwTxtFlyCnt *)pAttr; SwFrmFmt* pFmt = pAttr->GetFlyCnt().GetFrmFmt(); @@ -1264,7 +1276,7 @@ bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode ) // erfolgen (Fehleranfaellig !) const SwFmtAnchor* pAnchor = 0; pFmt->GetItemState( RES_ANCHOR, sal_False, - (const SfxPoolItem**)&pAnchor ); + (const SfxPoolItem**)&pAnchor ); SwIndex aIdx( this, *pAttr->GetStart() ); const sal_Unicode c = GetCharOfTxtAttr(*pAttr); @@ -1325,7 +1337,7 @@ bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode ) break; } - case RES_TXTATR_FTN : + case RES_TXTATR_FTN : { // Fussnoten, man kommt an alles irgendwie heran. // CntntNode erzeugen und in die Inserts-Section stellen @@ -1343,10 +1355,10 @@ bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode ) { // loesche das Zeichen aus dem String ! ASSERT( ( CH_TXTATR_BREAKWORD == - m_Text.GetChar(*pAttr->GetStart() ) || - CH_TXTATR_INWORD == - m_Text.GetChar(*pAttr->GetStart())), - "where is my attribute character?" ); + m_Text.GetChar(*pAttr->GetStart() ) || + CH_TXTATR_INWORD == + m_Text.GetChar(*pAttr->GetStart())), + "where is my attribute character?" ); m_Text.Erase( *pAttr->GetStart(), 1 ); // Indizies Updaten SwIndex aTmpIdx( this, *pAttr->GetStart() ); @@ -1403,8 +1415,8 @@ bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode ) pDoc->GetFtnIdxs().Remove( n ); break; } - // wenn ueber Undo der StartNode gesetzt wurde, kann - // der Index noch gar nicht in der Verwaltung stehen !! + // wenn ueber Undo der StartNode gesetzt wurde, kann + // der Index noch gar nicht in der Verwaltung stehen !! } if( !pTxtFtn ) pTxtFtn = (SwTxtFtn*)pAttr; @@ -1434,9 +1446,10 @@ bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode ) { // fuer HiddenParaFields Benachrichtigungsmechanismus // anwerfen - if( RES_HIDDENPARAFLD == - pAttr->GetFmtFld().GetField()->GetTyp()->Which() ) - bHiddenPara = sal_True; + if( RES_HIDDENPARAFLD == pAttr->GetFmtFld().GetField()->GetTyp()->Which() ) + { + bHiddenPara = true; + } } break; @@ -1459,25 +1472,144 @@ bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode ) } } + // handle attributes which provide content + xub_StrLen nEnd = nStart; + bool bInputFieldStartCharInserted = false; + bool bInputFieldEndCharInserted = false; + const bool bHasContent( pAttr->HasContent() ); + if ( bHasContent ) + { + switch( pAttr->Which() ) + { + case RES_TXTATR_INPUTFIELD: + { + SwTxtInputFld* pTxtInputFld = dynamic_cast<SwTxtInputFld*>(pAttr); + if ( pTxtInputFld ) + { + if( !(nsSetAttrMode::SETATTR_NOTXTATRCHR & nMode) ) + { + SwIndex aIdx( this, *pAttr->GetStart() ); + InsertText( CH_TXT_ATR_INPUTFIELDSTART, aIdx, nInsertFlags ); + const String aContent = pTxtInputFld->GetFieldContent(); + InsertText( aContent, aIdx, nInsertFlags ); + InsertText( CH_TXT_ATR_INPUTFIELDEND, aIdx, nInsertFlags ); + + xub_StrLen * const pEnd(pAttr->GetEnd()); + ASSERT( pEnd != NULL, "<SwTxtNode::InsertHint(..)> - missing end of RES_TXTATR_INPUTFIELD!" ); + if ( pEnd != NULL ) + { + *pEnd = *pEnd + 2 + aContent.Len(); + nEnd = *pEnd; + } + } + else + { + // assure that CH_TXT_ATR_INPUTFIELDSTART and CH_TXT_ATR_INPUTFIELDEND are inserted. + if ( m_Text.GetChar( *(pAttr->GetStart()) ) != CH_TXT_ATR_INPUTFIELDSTART ) + { + SwIndex aIdx( this, *pAttr->GetStart() ); + InsertText( CH_TXT_ATR_INPUTFIELDSTART, aIdx, nInsertFlags ); + bInputFieldStartCharInserted = true; + xub_StrLen * const pEnd(pAttr->GetEnd()); + ASSERT( pEnd != NULL, "<SwTxtNode::InsertHint(..)> - missing end of RES_TXTATR_INPUTFIELD!" ); + if ( pEnd != NULL ) + { + *pEnd = *pEnd + 1; + nEnd = *pEnd; + } + } + + xub_StrLen * const pEnd(pAttr->GetEnd()); + ASSERT( pEnd != NULL, "<SwTxtNode::InsertHint(..)> - missing end of RES_TXTATR_INPUTFIELD!" ); + if ( pEnd != NULL + && m_Text.GetChar( *(pEnd) - 1 ) != CH_TXT_ATR_INPUTFIELDEND ) + { + SwIndex aIdx( this, *(pEnd) ); + InsertText( CH_TXT_ATR_INPUTFIELDEND, aIdx, nInsertFlags ); + bInputFieldEndCharInserted = true; + *pEnd = *pEnd + 1; + nEnd = *pEnd; + } + } + } + } + break; + default: + break; + } + } + GetOrCreateSwpHints(); + // handle overlap with an existing InputField + bool bInsertHint = true; + { + const SwTxtInputFld* pTxtInputFld = GetOverlappingInputFld( *pAttr ); + if ( pTxtInputFld != NULL ) + { + if ( pAttr->End() == NULL ) + { + bInsertHint = false; + } + else + { + if ( *(pAttr->GetStart()) > *(pTxtInputFld->GetStart()) ) + { + *(pAttr->GetStart()) = *(pTxtInputFld->GetStart()); + } + if ( *(pAttr->End()) < *(pTxtInputFld->End()) ) + { + *(pAttr->GetEnd()) = *(pTxtInputFld->End()); + } + } + } + } + // 4263: AttrInsert durch TextInsert => kein Adjust - const bool bRet = m_pSwpHints->TryInsertHint( pAttr, *this, nMode ); + const bool bRet = bInsertHint + ? m_pSwpHints->TryInsertHint( pAttr, *this, nMode ) + : false; - if (!bRet && bDummyChar) + if ( !bRet ) { - // undo insertion of dummy character - // N.B. cannot insert the dummy character after inserting the hint, - // because if the hint has no extent it will be moved in InsertText, - // resulting in infinite recursion - if ( !(nsSetAttrMode::SETATTR_NOTXTATRCHR & nMode) ) + if ( bDummyChar + && !(nsSetAttrMode::SETATTR_NOTXTATRCHR & nMode) ) { + // undo insertion of dummy character + // N.B. cannot insert the dummy character after inserting the hint, + // because if the hint has no extent it will be moved in InsertText, + // resulting in infinite recursion ASSERT( ( CH_TXTATR_BREAKWORD == m_Text.GetChar(nStart) || - CH_TXTATR_INWORD == m_Text.GetChar(nStart) ), - "where is my attribute character?" ); + CH_TXTATR_INWORD == m_Text.GetChar(nStart) ), + "where is my attribute character?" ); SwIndex aIdx( this, nStart ); EraseText( aIdx, 1 ); } + + if ( bHasContent ) + { + if ( !(nsSetAttrMode::SETATTR_NOTXTATRCHR & nMode) + && (nEnd - nStart) > 0 ) + { + SwIndex aIdx( this, nStart ); + EraseText( aIdx, (nEnd - nStart) ); + } + else + { + if ( bInputFieldEndCharInserted + && (nEnd - nStart) > 0 ) + { + SwIndex aIdx( this, nEnd - 1 ); + EraseText( aIdx, 1 ); + } + + if ( bInputFieldStartCharInserted ) + { + SwIndex aIdx( this, nStart ); + EraseText( aIdx, 1 ); + } + } + } } if ( bHiddenPara ) @@ -1508,6 +1640,12 @@ void SwTxtNode::DeleteAttribute( SwTxtAttr * const pAttr ) // erase the CH_TXTATR, which will also delete pAttr EraseText( aIdx, 1 ); } + else if ( pAttr->HasContent() ) + { + const SwIndex aIdx( this, *pAttr->GetStart() ); + ASSERT( pAttr->End() != NULL, "<SwTxtNode::DeleteAttribute(..)> - missing End() at <SwTxtAttr> instance which has content" ); + EraseText( aIdx, *pAttr->End() - *pAttr->GetStart() ); + } else { // create MsgHint before start/end become invalid @@ -1526,8 +1664,10 @@ void SwTxtNode::DeleteAttribute( SwTxtAttr * const pAttr ) *************************************************************************/ //FIXME: this does NOT respect SORT NUMBER (for CHARFMT)! -void SwTxtNode::DeleteAttributes( const sal_uInt16 nWhich, - const xub_StrLen nStart, const xub_StrLen nEnd ) +void SwTxtNode::DeleteAttributes( + const sal_uInt16 nWhich, + const xub_StrLen nStart, + const xub_StrLen nEnd ) { if ( !HasHints() ) return; @@ -1555,7 +1695,7 @@ void SwTxtNode::DeleteAttributes( const sal_uInt16 nWhich, if ( SFX_ITEM_SET == pFmt->GetItemState( RES_CHRATR_HIDDEN, sal_True, &pItem ) ) SetCalcHiddenCharFlags(); } - // --> FME 2007-03-16 #i75430# Recalc hidden flags if necessary + // Recalc hidden flags if necessary else if ( nWhich == RES_TXTATR_AUTOFMT ) { // Check if auto style contains hidden attribute: @@ -1563,7 +1703,6 @@ void SwTxtNode::DeleteAttributes( const sal_uInt16 nWhich, if ( pHiddenItem ) SetCalcHiddenCharFlags(); } - // <-- xub_StrLen const * const pEndIdx = pTxtHt->GetEnd(); @@ -1574,6 +1713,12 @@ void SwTxtNode::DeleteAttributes( const sal_uInt16 nWhich, // erase the CH_TXTATR, which will also delete pTxtHt EraseText( aIdx, 1 ); } + else if ( pTxtHt->HasContent() ) + { + const SwIndex aIdx( this, nStart ); + ASSERT( pTxtHt->End() != NULL, "<SwTxtNode::DeleteAttributes(..)> - missing End() at <SwTxtAttr> instance which has content" ); + EraseText( aIdx, *pTxtHt->End() - nStart ); + } else if( *pEndIdx == nEnd ) { // den MsgHint jetzt fuettern, weil gleich sind @@ -1681,8 +1826,11 @@ bool SwTxtNode::TryCharSetExpandToNum(const SfxItemSet& aCharSet) // setze diese Attribute am TextNode. Wird der gesamte Bereich umspannt, // dann setze sie nur im AutoAttrSet (SwCntntNode:: SetAttr) -sal_Bool SwTxtNode::SetAttr( const SfxItemSet& rSet, xub_StrLen nStt, - xub_StrLen nEnd, const SetAttrMode nMode ) +sal_Bool SwTxtNode::SetAttr( + const SfxItemSet& rSet, + const xub_StrLen nStt, + const xub_StrLen nEnd, + const SetAttrMode nMode ) { if( !rSet.Count() ) return sal_False; @@ -1760,7 +1908,7 @@ sal_Bool SwTxtNode::SetAttr( const SfxItemSet& rSet, xub_StrLen nStt, static_cast<const SwFmtCharFmt*>(pItem)->GetCharFmt())) { SwIndex aIndex( this, nStt ); - RstAttr( aIndex, nEnd - nStt, RES_TXTATR_CHARFMT, 0 ); + RstTxtAttr( aIndex, nEnd - nStt, RES_TXTATR_CHARFMT, 0 ); DontExpandFmt( aIndex ); } else @@ -1947,7 +2095,7 @@ sal_Bool SwTxtNode::GetAttr( SfxItemSet& rSet, xub_StrLen nStt, xub_StrLen nEnd, if( nAttrStart > nEnd ) // ueber den Bereich hinaus break; - const xub_StrLen* pAttrEnd = pHt->GetEnd(); + const xub_StrLen* pAttrEnd = pHt->End(); if ( ! pAttrEnd ) // no attributes without end continue; @@ -1975,7 +2123,7 @@ sal_Bool SwTxtNode::GetAttr( SfxItemSet& rSet, xub_StrLen nStt, xub_StrLen nEnd, if( nAttrStart > nEnd ) // ueber den Bereich hinaus break; - const xub_StrLen* pAttrEnd = pHt->GetEnd(); + const xub_StrLen* pAttrEnd = pHt->End(); if ( ! pAttrEnd ) // no attributes without end continue; @@ -2208,7 +2356,7 @@ lcl_CollectHintSpans(const SwpHints& i_rHints, const sal_uInt16 nLength, const sal_uInt16 nWhich(pHint->Which()); if (nWhich == RES_TXTATR_CHARFMT || nWhich == RES_TXTATR_AUTOFMT) { - const AttrSpan_t aSpan(*pHint->GetStart(), *pHint->GetEnd()); + const AttrSpan_t aSpan(*pHint->GetStart(), *pHint->End()); o_rSpanMap.insert(AttrSpanMap_t::value_type(aSpan, pHint)); // < not != because there may be multiple CHARFMT at same range @@ -2555,7 +2703,7 @@ bool SwpHints::MergePortions( SwTxtNode& rNode ) { const SwTxtAttr* p1 = (*aIter1).second; const SwTxtAttr* p2 = (*aIter2).second; - if ( *p1->GetEnd() < *p2->GetStart() || p1->Which() != p2->Which() || !(*p1 == *p2) ) + if ( *p1->End() < *p2->GetStart() || p1->Which() != p2->Which() || !(*p1 == *p2) ) { bMerge = false; break; @@ -2632,7 +2780,7 @@ void lcl_CheckSortNumber( const SwpHints& rHints, SwTxtCharFmt& rNewCharFmt ) if ( RES_TXTATR_CHARFMT == pOtherHt->Which() ) { - const xub_StrLen nOtherEnd = *pOtherHt->GetEnd(); + const xub_StrLen nOtherEnd = *pOtherHt->End(); if ( nOtherStart == nHtStart && nOtherEnd == nHtEnd ) { @@ -2702,6 +2850,7 @@ bool SwpHints::TryInsertHint( SwTxtAttr* const pHint, SwTxtNode &rNode, static_cast<SwTxtINetFmt*>(pHint)->InitINetFmt(rNode); break; case RES_TXTATR_FIELD: + case RES_TXTATR_INPUTFIELD: { sal_Bool bDelFirst = 0 != ((SwTxtFld*)pHint)->GetpTxtNode(); ((SwTxtFld*)pHint)->ChgTxtNode( &rNode ); @@ -3023,6 +3172,7 @@ void SwTxtNode::ClearSwpHintsArr( bool bDelFields ) break; case RES_TXTATR_FIELD: + case RES_TXTATR_INPUTFIELD: if( bDelFields ) bDel = true; break; @@ -3071,7 +3221,7 @@ sal_uInt16 SwTxtNode::GetLang( const xub_StrLen nBegin, const xub_StrLen nLen, if( nWhichId == nWhich || ( ( pHt->IsCharFmtAttr() || RES_TXTATR_AUTOFMT == nWhich ) && CharFmt::IsItemIncluded( nWhichId, pHt ) ) ) { - const xub_StrLen *pEndIdx = pHt->GetEnd(); + const xub_StrLen *pEndIdx = pHt->End(); // Ueberlappt das Attribut den Bereich? if( pEndIdx && |