summaryrefslogtreecommitdiff
path: root/sw/source/core/txtnode/thints.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/txtnode/thints.cxx')
-rw-r--r--sw/source/core/txtnode/thints.cxx244
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 &&