cool#16219 engine sd, RTF export: fix lost bullets of paragraphs
Add a few bulleted lines to a text frame in an Impress document, copy
them, paste in Writer: the paragraphs are imported with no bullet marks.
ImpEditEngine::WriteRTF() emits a bare \level<n> for the paragraph's
outline level, which editeng's own RTF importer reads back as a
bulleted item, but sw's RTF import ignores. The PowerPoint RTF clipboard
markup for the same thing is the RTF 1.0 old-style numbering pair: a
{\pntext <bullet>\tab} fallback and a {\*\pn\pnlvlblt{\pntxtb <bullet>}}
destination that contains the bullet character.
Fix the problem by emitting that pair alongside \level<n>, from the
paragraph loop in WriteRTF(), when the paragraph's EE_PARA_NUMBULLET
at that outline level is of type SVX_NUM_CHAR_SPECIAL.
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I18a022ac28d50a8b7557ee2282cd3fd8e7c37299
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/14439
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
(cherry picked from commit b7002f07f475ce4eb5cf7309dfe8e59ba21ecd7a)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211942
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
committed by
Xisco Fauli
parent
09d3cc2c14
commit
1886cb2ee3
@@ -11,8 +11,10 @@
|
|||||||
|
|
||||||
#include <editeng/eeitem.hxx>
|
#include <editeng/eeitem.hxx>
|
||||||
#include <editeng/editeng.hxx>
|
#include <editeng/editeng.hxx>
|
||||||
|
#include <editeng/numitem.hxx>
|
||||||
#include <editeng/wghtitem.hxx>
|
#include <editeng/wghtitem.hxx>
|
||||||
#include <sfx2/app.hxx>
|
#include <sfx2/app.hxx>
|
||||||
|
#include <svl/intitem.hxx>
|
||||||
#include <svtools/parrtf.hxx>
|
#include <svtools/parrtf.hxx>
|
||||||
#include <svtools/rtftoken.h>
|
#include <svtools/rtftoken.h>
|
||||||
|
|
||||||
@@ -213,6 +215,35 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf119192RTFFontAttributesInParagraphScope)
|
|||||||
bool bContains = (aCnt.find("{mytest}") != std::string::npos);
|
bool bContains = (aCnt.find("{mytest}") != std::string::npos);
|
||||||
CPPUNIT_ASSERT(bContains);
|
CPPUNIT_ASSERT(bContains);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPPUNIT_TEST_FIXTURE(Test, testRTFBullet)
|
||||||
|
{
|
||||||
|
// Given a document with a paragraph that is a bulleted item:
|
||||||
|
EditEngine aEditEngine(mpItemPool.get());
|
||||||
|
OUString aText = u"mytest"_ustr;
|
||||||
|
aEditEngine.SetText(aText);
|
||||||
|
SfxItemSet aItems(aEditEngine.GetParaAttribs(0));
|
||||||
|
aItems.Put(SfxInt16Item(EE_PARA_OUTLLEVEL, 0));
|
||||||
|
SvxNumRule aRule(SvxNumRuleFlags::BULLET_REL_SIZE, 10, false);
|
||||||
|
SvxNumberFormat aFmt(SVX_NUM_CHAR_SPECIAL);
|
||||||
|
aFmt.SetBulletChar(0x2022); // bullet
|
||||||
|
aRule.SetLevel(0, aFmt);
|
||||||
|
aItems.Put(SvxNumBulletItem(std::move(aRule), EE_PARA_NUMBULLET));
|
||||||
|
aEditEngine.SetParaAttribs(0, aItems);
|
||||||
|
|
||||||
|
// When copying to the clipboard as RTF:
|
||||||
|
uno::Reference<datatransfer::XTransferable> xData
|
||||||
|
= aEditEngine.CreateTransferable(ESelection(0, 0, 0, aText.getLength()));
|
||||||
|
|
||||||
|
// Then make sure the RTF carries the bullet so a non-editeng reader sees it:
|
||||||
|
auto pData = dynamic_cast<EditDataObject*>(xData.get());
|
||||||
|
SvMemoryStream& rStream = pData->GetRTFStream();
|
||||||
|
std::string aCnt{ static_cast<const char*>(rStream.GetData()),
|
||||||
|
static_cast<size_t>(rStream.GetSize()) };
|
||||||
|
// Without the accompanying fix in place, this failed, the export wrote
|
||||||
|
// only editeng's own \level0 and \pnlvlblt.
|
||||||
|
CPPUNIT_ASSERT(aCnt.find("\\pnlvlblt") != std::string::npos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <editeng/adjustitem.hxx>
|
#include <editeng/adjustitem.hxx>
|
||||||
#include <editeng/cmapitem.hxx>
|
#include <editeng/cmapitem.hxx>
|
||||||
#include <editeng/lspcitem.hxx>
|
#include <editeng/lspcitem.hxx>
|
||||||
|
#include <editeng/numitem.hxx>
|
||||||
#include <editeng/tstpitem.hxx>
|
#include <editeng/tstpitem.hxx>
|
||||||
|
|
||||||
#include "eertfpar.hxx"
|
#include "eertfpar.hxx"
|
||||||
@@ -644,6 +645,32 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, EditSelection aSel, bool bCl
|
|||||||
if ( bAttr )
|
if ( bAttr )
|
||||||
rOutput.WriteChar( ' ' ); // Separator
|
rOutput.WriteChar( ' ' ); // Separator
|
||||||
|
|
||||||
|
const SfxInt16Item& rOutlLevelItem = GetParaAttrib(nNode, EE_PARA_OUTLLEVEL);
|
||||||
|
sal_Int16 nOutlLevel = rOutlLevelItem.GetValue();
|
||||||
|
if (nOutlLevel >= 0)
|
||||||
|
{
|
||||||
|
// The paragraph has an outline level, check if that is a bullet.
|
||||||
|
const SvxNumBulletItem& rNumBullet = GetParaAttrib(nNode, EE_PARA_NUMBULLET);
|
||||||
|
const SvxNumberFormat* pFmt = rNumBullet.GetNumRule().Get(nOutlLevel);
|
||||||
|
if (pFmt && pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL)
|
||||||
|
{
|
||||||
|
sal_Unicode cBullet = static_cast<sal_Unicode>(pFmt->GetBulletChar());
|
||||||
|
OUString aBullet(&cBullet, 1);
|
||||||
|
rOutput.WriteChar('{').WriteOString(OOO_STRING_SVTOOLS_RTF_PNTEXT).WriteChar(' ');
|
||||||
|
RTFOutFuncs::Out_String(rOutput, aBullet, eDestEnc);
|
||||||
|
rOutput.WriteOString("\\tab}");
|
||||||
|
rOutput.WriteChar('{')
|
||||||
|
.WriteOString(OOO_STRING_SVTOOLS_RTF_IGNORE)
|
||||||
|
.WriteOString(OOO_STRING_SVTOOLS_RTF_PN)
|
||||||
|
.WriteOString(OOO_STRING_SVTOOLS_RTF_PNLVLBLT)
|
||||||
|
.WriteChar('{')
|
||||||
|
.WriteOString(OOO_STRING_SVTOOLS_RTF_PNTXTB)
|
||||||
|
.WriteChar(' ');
|
||||||
|
RTFOutFuncs::Out_String(rOutput, aBullet, eDestEnc);
|
||||||
|
rOutput.WriteOString("}}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ItemList aAttribItems;
|
ItemList aAttribItems;
|
||||||
ParaPortion* pParaPortion = FindParaPortion( pNode );
|
ParaPortion* pParaPortion = FindParaPortion( pNode );
|
||||||
DBG_ASSERT( pParaPortion, "Portion not found: WriteRTF" );
|
DBG_ASSERT( pParaPortion, "Portion not found: WriteRTF" );
|
||||||
|
|||||||
Reference in New Issue
Block a user