/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// The SvRTF parser expects the Which-mapping passed on in the pool, not // dependent on a secondary.
SfxItemPool* pPool = &maEditDoc.GetItemPool(); while (pPool->GetSecondaryPool() && pPool->GetName() != "EditEngineItemPool")
{
pPool = pPool->GetSecondaryPool();
}
// Write out ColorList ...
SvxColorList aColorList; // COL_AUTO should be the default color, always put it first
aColorList.emplace_back(COL_AUTO);
SvxColorItem const& rDefault(maEditDoc.GetItemPool().GetUserOrPoolDefaultItem(EE_CHAR_COLOR)); if (rDefault.GetValue() != COL_AUTO) // is the default always AUTO?
{
aColorList.push_back(rDefault.GetValue());
} for (const SfxPoolItem* pItem : maEditDoc.GetItemPool().GetItemSurrogates(EE_CHAR_COLOR))
{ auto pColorItem(dynamic_cast<SvxColorItem const*>(pItem)); if (pColorItem && pColorItem->GetValue() != COL_AUTO) // may be null!
{
aColorList.push_back(pColorItem->GetValue());
}
}
rOutput.WriteChar( '{' ).WriteOString( OOO_STRING_SVTOOLS_RTF_COLORTBL ); for ( SvxColorList::size_type j = 0; j < aColorList.size(); j++ )
{
Color const color = aColorList[j]; if (color != COL_AUTO) // auto is represented by "empty" element
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_RED );
rOutput.WriteNumberAsString( color.GetRed() );
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_GREEN );
rOutput.WriteNumberAsString( color.GetGreen() );
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_BLUE );
rOutput.WriteNumberAsString( color.GetBlue() );
}
rOutput.WriteChar( ';' );
}
rOutput.WriteChar( '}' );
rOutput << endl;
std::unordered_map<SfxStyleSheetBase*, sal_uInt32> aStyleSheetToIdMap; // StyleSheets... if ( GetStyleSheetPool() )
{ // Collect used paragraph styles when copying to the clipboard.
std::set<SfxStyleSheetBase*> aUsedParagraphStyles; if (bClipboard)
{ for (sal_Int32 nNode = nStartNode; nNode <= nEndNode; nNode++)
{
ContentNode* pNode = maEditDoc.GetObject(nNode); if (!pNode)
{ continue;
}
SfxStyleSheet* pParaStyle = pNode->GetStyleSheet(); if (!pParaStyle)
{ continue;
}
aUsedParagraphStyles.insert(pParaStyle);
// Collect parents of the style recursively.
OUString aParent = pParaStyle->GetParent(); while (!aParent.isEmpty())
{ auto pParent = static_cast<SfxStyleSheet*>(
GetStyleSheetPool()->Find(aParent, pParaStyle->GetFamily())); if (!pParent)
{ break;
}
// Collect follows of the style recursively.
OUString aFollow = pParaStyle->GetFollow(); while (!aFollow.isEmpty())
{ auto pFollow = static_cast<SfxStyleSheet*>(
GetStyleSheetPool()->Find(aFollow, pParaStyle->GetFamily())); if (!pFollow)
{ break;
}
auto it = aUsedParagraphStyles.insert(pFollow); // A style is fine to have itself as a follow. if (!it.second)
{ // No insertion happened, so this is visited already. break;
}
aFollow = pFollow->GetFollow();
}
}
}
std::shared_ptr<SfxStyleSheetIterator> aSSSIterator = std::make_shared<SfxStyleSheetIterator>(GetStyleSheetPool(),
SfxStyleFamily::All); // fill aStyleSheetToIdMap
sal_uInt32 nId = 1; for ( SfxStyleSheetBase* pStyle = aSSSIterator->First(); pStyle;
pStyle = aSSSIterator->Next() )
{ if (bClipboard && !aUsedParagraphStyles.contains(pStyle))
{ // Don't include unused paragraph styles in the clipboard case. continue;
}
aStyleSheetToIdMap[pStyle] = nId;
nId++;
}
// Parent ... (only if necessary) if ( !pStyle->GetParent().isEmpty() && ( pStyle->GetParent() != pStyle->GetName() ) )
{
SfxStyleSheet* pParent = static_cast<SfxStyleSheet*>(GetStyleSheetPool()->Find( pStyle->GetParent(), pStyle->GetFamily() ));
DBG_ASSERT( pParent, "Parent not found!" );
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_SBASEDON ); auto iter = aStyleSheetToIdMap.find(pParent);
assert(iter != aStyleSheetToIdMap.end());
nNumber = iter->second;
rOutput.WriteNumberAsString( nNumber );
}
// Next Style... (more) // we assume that we have only SfxStyleSheet in the pool
SfxStyleSheet* pNext = static_cast<SfxStyleSheet*>(pStyle); if ( !pStyle->GetFollow().isEmpty() && ( pStyle->GetFollow() != pStyle->GetName() ) )
pNext = static_cast<SfxStyleSheet*>(GetStyleSheetPool()->Find( pStyle->GetFollow(), pStyle->GetFamily() ));
DBG_ASSERT( pNext, "Next not found!" );
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_SNEXT ); auto iter = aStyleSheetToIdMap.find(pNext);
assert(iter != aStyleSheetToIdMap.end());
nNumber = iter->second;
rOutput.WriteNumberAsString( nNumber );
// Name of the template...
rOutput.WriteOString( " " );
RTFOutFuncs::Out_String( rOutput, pStyle->GetName(), eDestEnc );
rOutput.WriteOString( ";}" );
nStyle++;
}
rOutput.WriteChar( '}' );
rOutput << endl;
}
}
if ( nNode == nStartNode )
{
nStartPos = aSel.Min().GetIndex();
nStartPortion = pParaPortion->GetTextPortions().FindPortion( nStartPos, nPortionStart ); if ( nStartPos != 0 )
{
aAttribItems.Clear();
lcl_FindValidAttribs( aAttribItems, pNode, nStartPos, GetI18NScriptType( EditPaM( pNode, 0 ) ) ); if ( aAttribItems.Count() )
{ // These attributes may not apply to the entire paragraph:
rOutput.WriteChar( '{' );
WriteItemListAsRTF( aAttribItems, rOutput, nNode, nStartPos, aFontTable, aColorList );
bFinishPortion = true;
}
aAttribItems.Clear();
}
} if ( nNode == nEndNode ) // can also be == nStart!
{
nEndPos = aSel.Max().GetIndex();
nEndPortion = pParaPortion->GetTextPortions().FindPortion( nEndPos, nPortionStart );
}
const EditCharAttrib* pNextFeature = pNode->GetCharAttribs().FindFeature(nIndex); // start at 0, so the index is right ... for ( sal_Int32 n = 0; n <= nEndPortion; n++ )
{ const TextPortion& rTextPortion = pParaPortion->GetTextPortions()[n]; if ( n < nStartPortion )
{
nIndex = nIndex + rTextPortion.GetLen(); continue;
}
if ( pNextFeature && ( pNextFeature->GetStart() == nIndex ) && ( pNextFeature->GetItem()->Which() != EE_FEATURE_FIELD ) )
{
WriteItemAsRTF( *pNextFeature->GetItem(), rOutput, nNode, nIndex, aFontTable, aColorList );
pNextFeature = pNode->GetCharAttribs().FindFeature( pNextFeature->GetStart() + 1 );
} else
{
aAttribItems.Clear();
sal_uInt16 nScriptTypeI18N = GetI18NScriptType( EditPaM( pNode, nIndex+1 ) );
SvtScriptType nScriptType = SvtLanguageOptions::FromI18NToSvtScriptType(nScriptTypeI18N);
rtl_TextEncoding actEncoding = eDestEnc; if ( !n || IsScriptChange( EditPaM( pNode, nIndex ) ) )
{
SfxItemSet aAttribs = GetAttribs( nNode, nIndex+1, nIndex+1 ); auto& item = aAttribs.Get(GetScriptItemId(EE_CHAR_FONTINFO, nScriptType));
aAttribItems.Insert(&item); // The actual encoding that RTF uses for the portion is defined by the font if (auto i = GetFontIndex(item, aFontTable);
i < aFontTable.size()
&& aFontTable[i]->GetCharSet() != RTL_TEXTENCODING_DONTKNOW)
actEncoding = aFontTable[i]->GetCharSet();
aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_FONTHEIGHT, nScriptType ) ) );
aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_WEIGHT, nScriptType ) ) );
aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_ITALIC, nScriptType ) ) );
aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType ) ) );
// tdf#119192: Write these font attributes at paragraph scope, so they can be // reused across multiple runs.
WriteItemListAsRTF(aAttribItems, rOutput, nNode, nIndex, aFontTable,
aColorList);
aAttribItems.Clear();
} // Insert hard attribs AFTER CJK attribs...
lcl_FindValidAttribs( aAttribItems, pNode, nIndex, nScriptTypeI18N );
void ImpEditEngine::WriteItemAsRTF( const SfxPoolItem& rItem, SvStream& rOutput, sal_Int32 nPara, sal_Int32 nPos, const std::vector<std::unique_ptr<SvxFontItem>>& rFontTable, SvxColorList& rColorList )
{
sal_uInt16 nWhich = rItem.Which(); switch ( nWhich )
{ case EE_PARA_WRITINGDIR:
{ const SvxFrameDirectionItem& rWritingMode = static_cast<const SvxFrameDirectionItem&>(rItem); if ( rWritingMode.GetValue() == SvxFrameDirection::Horizontal_RL_TB )
rOutput.WriteOString( "\\rtlpar" ); else
rOutput.WriteOString( "\\ltrpar" );
} break; case EE_PARA_OUTLLEVEL:
{
sal_Int32 nLevel = static_cast<const SfxInt16Item&>(rItem).GetValue(); if( nLevel >= 0 )
{
rOutput.WriteOString( "\\level" );
rOutput.WriteNumberAsString( nLevel );
}
} break; case EE_PARA_OUTLLRSPACE: case EE_PARA_LRSPACE:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_FI );
sal_Int32 nTxtFirst
= static_cast<const SvxLRSpaceItem&>(rItem).ResolveTextFirstLineOffset({});
nTxtFirst = LogicToTwips( nTxtFirst );
rOutput.WriteNumberAsString( nTxtFirst );
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_LI );
sal_uInt32 nTxtLeft = static_cast<const SvxLRSpaceItem&>(rItem).ResolveTextLeft({});
nTxtLeft = static_cast<sal_uInt32>(LogicToTwips( nTxtLeft ));
rOutput.WriteNumberAsString( nTxtLeft );
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_RI );
sal_uInt32 nTxtRight = static_cast<const SvxLRSpaceItem&>(rItem).ResolveRight({});
nTxtRight = LogicToTwips( nTxtRight);
rOutput.WriteNumberAsString( nTxtRight );
} break; case EE_PARA_ULSPACE:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_SB );
sal_uInt32 nUpper = static_cast<const SvxULSpaceItem&>(rItem).GetUpper();
nUpper = static_cast<sal_uInt32>(LogicToTwips( nUpper ));
rOutput.WriteNumberAsString( nUpper );
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_SA );
sal_uInt32 nLower = static_cast<const SvxULSpaceItem&>(rItem).GetLower();
nLower = LogicToTwips( nLower );
rOutput.WriteNumberAsString( nLower );
} break; case EE_PARA_SBL:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_SL );
sal_Int32 nVal = static_cast<const SvxLineSpacingItem&>(rItem).GetLineHeight(); char cMult = '0'; if ( static_cast<const SvxLineSpacingItem&>(rItem).GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop )
{ // From where do I get the value now? // The SwRTF parser is based on a 240 Font!
nVal = static_cast<const SvxLineSpacingItem&>(rItem).GetPropLineSpace();
nVal *= 240;
nVal /= 100;
cMult = '1';
}
rOutput.WriteNumberAsString( nVal );
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_SLMULT ).WriteChar( cMult );
} break; case EE_PARA_JUST:
{
SvxAdjust eJustification = static_cast<const SvxAdjustItem&>(rItem).GetAdjust(); switch ( eJustification )
{ case SvxAdjust::Center: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_QC ); break; case SvxAdjust::Right: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_QR ); break; default: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_QL ); break;
}
} break; case EE_PARA_TABS:
{ const SvxTabStopItem& rTabs = static_cast<const SvxTabStopItem&>(rItem); for ( sal_uInt16 i = 0; i < rTabs.Count(); i++ )
{ const SvxTabStop& rTab = rTabs[i];
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_TX );
rOutput.WriteNumberAsString( LogicToTwips( rTab.GetTabPos() ) );
}
} break; case EE_CHAR_COLOR:
{
SvxColorList::const_iterator const iter = std::find(
rColorList.begin(), rColorList.end(), static_cast<SvxColorItem const&>(rItem).GetValue());
assert(iter != rColorList.end());
sal_uInt32 const n = iter - rColorList.begin();
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_CF );
rOutput.WriteNumberAsString( n );
} break; case EE_CHAR_FONTINFO: case EE_CHAR_FONTINFO_CJK: case EE_CHAR_FONTINFO_CTL:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_F );
rOutput.WriteNumberAsString(GetFontIndex(rItem, rFontTable));
} break; case EE_CHAR_FONTHEIGHT: case EE_CHAR_FONTHEIGHT_CJK: case EE_CHAR_FONTHEIGHT_CTL:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_FS );
sal_Int32 nHeight = static_cast<const SvxFontHeightItem&>(rItem).GetHeight();
nHeight = LogicToTwips( nHeight ); // Twips => HalfPoints
nHeight /= 10;
rOutput.WriteNumberAsString( nHeight );
} break; case EE_CHAR_WEIGHT: case EE_CHAR_WEIGHT_CJK: case EE_CHAR_WEIGHT_CTL:
{
FontWeight e = static_cast<const SvxWeightItem&>(rItem).GetWeight(); switch ( e )
{ case WEIGHT_BOLD: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_B ); break; default: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_B ).WriteChar( '0' ); break;
}
} break; case EE_CHAR_UNDERLINE:
{ // Must underlined if in WordLineMode, but the information is // missing here
FontLineStyle e = static_cast<const SvxUnderlineItem&>(rItem).GetLineStyle(); switch ( e )
{ case LINESTYLE_NONE: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_ULNONE ); break; case LINESTYLE_SINGLE: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_UL ); break; case LINESTYLE_DOUBLE: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_ULDB ); break; case LINESTYLE_DOTTED: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_ULD ); break; default: break;
}
} break; case EE_CHAR_OVERLINE:
{
FontLineStyle e = static_cast<const SvxOverlineItem&>(rItem).GetLineStyle(); switch ( e )
{ case LINESTYLE_NONE: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_OLNONE ); break; case LINESTYLE_SINGLE: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_OL ); break; case LINESTYLE_DOUBLE: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_OLDB ); break; case LINESTYLE_DOTTED: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_OLD ); break; default: break;
}
} break; case EE_CHAR_STRIKEOUT:
{
FontStrikeout e = static_cast<const SvxCrossedOutItem&>(rItem).GetStrikeout(); switch ( e )
{ case STRIKEOUT_SINGLE: case STRIKEOUT_DOUBLE: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_STRIKE ); break; case STRIKEOUT_NONE: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_STRIKE ).WriteChar( '0' ); break; default: break;
}
} break; case EE_CHAR_ITALIC: case EE_CHAR_ITALIC_CJK: case EE_CHAR_ITALIC_CTL:
{
FontItalic e = static_cast<const SvxPostureItem&>(rItem).GetPosture(); switch ( e )
{ case ITALIC_OBLIQUE: case ITALIC_NORMAL: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_I ); break; case ITALIC_NONE: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_I ).WriteChar( '0' ); break; default: break;
}
} break; case EE_CHAR_OUTLINE:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_OUTL ); if ( !static_cast<const SvxContourItem&>(rItem).GetValue() )
rOutput.WriteChar( '0' );
} break; case EE_CHAR_RELIEF:
{
FontRelief nRelief = static_cast<const SvxCharReliefItem&>(rItem).GetValue(); if ( nRelief == FontRelief::Embossed )
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_EMBO ); if ( nRelief == FontRelief::Engraved )
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_IMPR );
} break; case EE_CHAR_EMPHASISMARK:
{
FontEmphasisMark nMark = static_cast<const SvxEmphasisMarkItem&>(rItem).GetEmphasisMark(); if ( nMark == FontEmphasisMark::NONE )
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_ACCNONE ); elseif ( nMark == (FontEmphasisMark::Accent | FontEmphasisMark::PosAbove) )
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_ACCCOMMA ); else
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_ACCDOT );
} break; case EE_CHAR_SHADOW:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_SHAD ); if ( !static_cast<const SvxShadowedItem&>(rItem).GetValue() )
rOutput.WriteChar( '0' );
} break; case EE_FEATURE_TAB:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_TAB );
} break; case EE_FEATURE_LINEBR:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_LINE );
} break; case EE_CHAR_KERNING:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_EXPNDTW );
rOutput.WriteNumberAsString( LogicToTwips( static_cast<const SvxKerningItem&>(rItem).GetValue() ) );
} break; case EE_CHAR_PAIRKERNING:
{
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_KERNING );
rOutput.WriteNumberAsString( static_cast<const SvxAutoKernItem&>(rItem).GetValue() ? 1 : 0 );
} break; case EE_CHAR_ESCAPEMENT:
{
SvxFont aFont;
ContentNode* pNode = maEditDoc.GetObject( nPara );
SeekCursor( pNode, nPos, aFont );
MapMode aPntMode( MapUnit::MapPoint );
tools::Long nFontHeight = GetRefDevice()->LogicToLogic(
aFont.GetFontSize(), &GetRefMapMode(), &aPntMode ).Height();
nFontHeight *=2; // Half Points
sal_uInt16 const nProp = static_cast<const SvxEscapementItem&>(rItem).GetProportionalHeight();
sal_uInt16 nProp100 = nProp*100; // For SWG-Token Prop in 100th percent. short nEsc = static_cast<const SvxEscapementItem&>(rItem).GetEsc(); const FontMetric aFontMetric = GetRefDevice()->GetFontMetric(); double fFontHeight = aFontMetric.GetAscent() + aFontMetric.GetDescent(); double fAutoAscent = .8; double fAutoDescent = .2; if ( fFontHeight )
{
fAutoAscent = aFontMetric.GetAscent() / fFontHeight;
fAutoDescent = aFontMetric.GetDescent() / fFontHeight;
} if ( nEsc == DFLT_ESC_AUTO_SUPER )
{
nEsc = fAutoAscent * (100 - nProp);
nProp100++; // A 1 afterwards means 'automatic'.
} elseif ( nEsc == DFLT_ESC_AUTO_SUB )
{
nEsc = fAutoDescent * -(100 - nProp);
nProp100++;
} // SWG: if ( nEsc )
{
rOutput.WriteOString( "{\\*\\updnprop" ).WriteNumberAsString(
nProp100 ).WriteChar( '}' );
}
tools::Long nUpDown = nFontHeight * std::abs( nEsc ) / 100; if ( nEsc < 0 )
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_DN ); elseif ( nEsc > 0 )
rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_UP );
rOutput.WriteNumberAsString(nUpDown);
} break; case EE_CHAR_CASEMAP:
{ const SvxCaseMapItem& rCaseMap = static_cast<const SvxCaseMapItem&>(rItem); switch (rCaseMap.GetValue())
{ case SvxCaseMap::SmallCaps:
rOutput.WriteOString(OOO_STRING_SVTOOLS_RTF_SCAPS); break; case SvxCaseMap::Uppercase:
rOutput.WriteOString(OOO_STRING_SVTOOLS_RTF_CAPS); break; default: // Something that rtf does not support
rOutput.WriteOString(OOO_STRING_SVTOOLS_RTF_SCAPS);
rOutput.WriteNumberAsString(0);
rOutput.WriteOString(OOO_STRING_SVTOOLS_RTF_CAPS);
rOutput.WriteNumberAsString(0); break;
}
} break;
}
}
// Currently not good enough to be used for a ::Write of EETextFormat::Html, it // only supports hyperlinks over plain text
OString ImpEditEngine::GetSimpleHtml() const
{
OStringBuffer aOutput;
// If possible online spelling if ( bAllowBigObjects && bOnlyFullParagraphs && pNode->GetWrongList() )
pC->SetWrongList( pNode->GetWrongList()->Clone() );
}
// Remember the portions info in case of large text objects: // sleeper set up when Olli paragraphs not hacked! if ( bAllowBigObjects && bOnlyFullParagraphs && IsFormatted() && IsUpdateLayout() && ( nTextPortions >= nBigObjectStart ) )
{
XParaPortionList* pXList = new XParaPortionList(GetRefDevice(), GetColumnWidth(maPaperSize),
maScalingParameters.fFontX, maScalingParameters.fFontY,
maScalingParameters.fSpacingX, maScalingParameters.fSpacingY);
pTxtObj->SetPortionInfo(std::unique_ptr<XParaPortionList>(pXList)); for ( nNode = nStartNode; nNode <= nEndNode; nNode++ )
{
ParaPortion const& rParaPortion = GetParaPortions().getRef(nNode);
XParaPortion* pX = new XParaPortion;
pXList->push_back(pX);
// The TextPortions
sal_uInt16 nCount = rParaPortion.GetTextPortions().Count();
sal_uInt16 n; for ( n = 0; n < nCount; n++ )
{ const TextPortion& rTextPortion = rParaPortion.GetTextPortions()[n];
TextPortion* pNew = new TextPortion( rTextPortion );
pX->aTextPortions.Append(pNew);
}
// The lines
nCount = rParaPortion.GetLines().Count(); for ( n = 0; n < nCount; n++ )
{ const EditLine& rLine = rParaPortion.GetLines()[n];
pX->aLines.Append(std::unique_ptr<EditLine>(rLine.Clone()));
} #ifdef DBG_UTIL
sal_uInt16 nTest; int nTPLen = 0, nTxtLen = 0; for (nTest = rParaPortion.GetTextPortions().Count(); nTest;)
nTPLen += rParaPortion.GetTextPortions()[--nTest].GetLen(); for (nTest = rParaPortion.GetLines().Count(); nTest; )
nTxtLen += rParaPortion.GetLines()[--nTest].GetLen();
DBG_ASSERT(nTPLen == rParaPortion.GetNode()->Len() && nTxtLen == rParaPortion.GetNode()->Len(), "CreateBinTextObject: ParaPortion not completely formatted!"); #endif
}
} return pTxtObj;
}
void ImpEditEngine::SetText( const EditTextObject& rTextObject )
{ // Since setting a text object is not undo-able!
ResetUndoManager(); bool _bUpdate = IsUpdateLayout(); bool _bUndo = IsUndoEnabled();
DBG_ASSERT( !HasUndoManager() || !GetUndoManager().GetUndoActionCount(), "From where comes the Undo in SetText ?!" );
SetUpdateLayout( _bUpdate );
EnableUndo( _bUndo );
}
// Before, paragraph count was of type sal_uInt16 so if nContents exceeded // 0xFFFF this wouldn't have worked anyway, given that nPara is used to // number paragraphs and is fearlessly incremented.
sal_Int32 nContents = static_cast<sal_Int32>(rTextObjectImpl.GetContents().size());
SAL_WARN_IF( nContents < 0, "editeng", "ImpEditEngine::InsertTextObject - contents overflow " << nContents);
sal_Int32 nPara = maEditDoc.GetPos( aPaM.GetNode() );
for (sal_Int32 n = 0; n < nContents; ++n, ++nPara)
{ const ContentInfo* pC = rTextObjectImpl.GetContents()[n].get(); bool bNewContent = aPaM.GetNode()->Len() == 0; const sal_Int32 nStartPos = aPaM.GetIndex();
// Wrap when followed by other ... if ( n < ( nContents-1) )
{ if ( bNewContent )
aPaM = ImpFastInsertParagraph( nPara+1 ); else
aPaM = ImpInsertParaBreak( aPaM, false );
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.