summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2014-07-22 15:05:24 +0200
committerMichael Stahl <mstahl@redhat.com>2014-07-22 16:32:36 +0200
commit82e17dbb2a16c7653a163139f0eea51faa4d46b8 (patch)
tree7dda49d5d83cdb129ae785a830e8bb3c256e07d8
parent78234837352b9417573a4bd1efa8cfe68902e24b (diff)
fdo#77996: writerfilter: RTF import: re-work destination text buffering
The problem in the bugdoc is that the ';' style terminator is encoded as {\uc1 \u59 ?}, i.e. inside a group, so when reading the ';' the aDestinationText of the top group is empty and the style name is lost. Or since the style name characters are encoded in the same way, every character is lost once the group closes. The same problem affects some of the document properties. Introduce an abstraction of RTFParserState::aDestinationText so that for every destination only one of these buffers is used, regardless of nested group structures; the aDestinationText buffer is only switched when entering a new destination. Also, the \revtbl and \stylesheet destinations do not contain entries directly, i.e., every entry must be in a sub-group, so remove some special-casing for these; however, for \fonttbl the entries may be in groups or not. Change-Id: Ica276a8b730e4a707530471ba27bfdd1582b8890
-rw-r--r--sw/qa/extras/rtfimport/data/fdo77996.rtf35
-rw-r--r--sw/qa/extras/rtfimport/rtfimport.cxx22
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx148
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx2
4 files changed, 161 insertions, 46 deletions
diff --git a/sw/qa/extras/rtfimport/data/fdo77996.rtf b/sw/qa/extras/rtfimport/data/fdo77996.rtf
new file mode 100644
index 000000000000..b5b4fdec7905
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/fdo77996.rtf
@@ -0,0 +1,35 @@
+{\rtf \ansi \ansicpg0 \deff0 \stshfdbch1 \stshfloch0 \stshfhich0 \deflang1033 \deflangfe1033
+
+{\fonttbl
+{\f0 \froman \fcharset0 \fprq2 Times New Roman{\*\falt Times New Roman};}
+{\f1 \fnil \fcharset134 \fprq0 {\uc1 \u23435 ?}{\uc1 \u20307 ?}{\*\falt {\uc1 \u23435 ?}{\uc1 \u20307 ?}};}
+{\f6 \fnil \fcharset0 \fprq0 Wingdings{\*\falt Wingdings};}
+{\f10 \fnil \fcharset0 \fprq0 Calibri{\*\falt Calibri};}
+{\f11 \fnil \fcharset134 \fprq0 {\uc1 \u24494 ?}{\uc1 \u36719 ?}{\uc1 \u38597 ?}{\uc1 \u40657 ?}{\*\falt {\uc1 \u24494 ?}{\uc1 \u36719 ?}{\uc1 \u38597 ?}{\uc1 \u40657 ?}};}
+}
+
+{\stylesheet
+{\qj \li0 \ri0 \nowidctlpar \aspalpha \aspnum \adjustright \lin0 \rin0 \itap0 \fs21 \kerning2 \dbch \af1 \hich \af10 \loch \f10 \lang1033 \langnp1033 \langfe2052 \langfenp2052 \snext0 Normal{\uc1 \u59 ?}}
+{\s1 \ql \li0 \ri0 \sb100 \lisb0 \sa100 \lisa0 \sbauto1 \saauto1 \widctlpar \aspalpha \aspnum \adjustright \lin0 \rin0 \itap0 \outlinelevel0 \b1 \fs48 \kerning36 \dbch \af1 \hich \af1 \loch \f1 \lang1033 \langnp1033 \langfe2052 \langfenp2052 \sbasedon0 \snext1 \slink18 heading 1{\uc1 \u59 ?}}
+{\s2 \ql \li0 \ri0 \sb100 \lisb0 \sa100 \lisa0 \sbauto1 \saauto1 \widctlpar \aspalpha \aspnum \adjustright \lin0 \rin0 \itap0 \outlinelevel1 \b1 \fs36 \kerning0 \dbch \af1 \hich \af1 \loch \f1 \lang1033 \langnp1033 \langfe2052 \langfenp2052 \sbasedon0 \snext2 \slink16 heading 2{\uc1 \u59 ?}}
+{\*\cs10 \snext10 Default Paragraph Font{\uc1 \u59 ?}}
+{\*\cs15 \fs18 \v0 \sbasedon10 \snext15 {\uc1 \u97 ?}{\uc1 \u117 ?}{\uc1 \u116 ?}{\uc1 \u104 ?}{\uc1 \u111 ?}{\uc1 \u114 ?}{\uc1 \u59 ?}}
+{\*\cs16 \b1 \fs36 \kerning0 \dbch \af1 \hich \af1 \loch \f1 \sbasedon10 \snext16 \slink2 {\uc1 \u26631 ?}{\uc1 \u39064 ?}{\uc1 \u32 ?}{\uc1 \u50 ?}{\uc1 \u32 ?}{\uc1 \u67 ?}{\uc1 \u104 ?}{\uc1 \u97 ?}{\uc1 \u114 ?}{\uc1 \u59 ?}}
+{\*\cs17 \b1 \sbasedon10 \snext17 strong{\uc1 \u59 ?}}
+{\*\cs18 \b1 \fs48 \kerning36 \dbch \af1 \hich \af1 \loch \f1 \sbasedon10 \snext18 \slink1 {\uc1 \u26631 ?}{\uc1 \u39064 ?}{\uc1 \u32 ?}{\uc1 \u49 ?}{\uc1 \u32 ?}{\uc1 \u67 ?}{\uc1 \u104 ?}{\uc1 \u97 ?}{\uc1 \u114 ?}{\uc1 \u59 ?}}
+{\s19 \ql \li0 \ri0 \sb375 \lisb0 \sa100 \lisa0 \saauto1 \widctlpar \aspalpha \aspnum \adjustright \lin0 \rin0 \itap0 \fs18 \kerning0 \dbch \af1 \hich \af1 \loch \f1 \lang1033 \langnp1033 \langfe2052 \langfenp2052 \sbasedon0 \snext19 {\uc1 \u101 ?}{\uc1 \u120 ?}{\uc1 \u116 ?}{\uc1 \u114 ?}{\uc1 \u97 ?}{\uc1 \u99 ?}{\uc1 \u116 ?}{\uc1 \u50 ?}{\uc1 \u59 ?}}
+}
+
+{\info
+{\title {\uc1 \u21414 ?}{\uc1 \u38376 ?}{\uc1 \u38056 ?}{\uc1 \u19994 ?}{\uc1 \u32929 ?}{\uc1 \u20221 ?}{\uc1 \u26377 ?}{\uc1 \u38480 ?}{\uc1 \u20844 ?}{\uc1 \u21496 ?}}
+{\author {\uc1 \u65 ?}{\uc1 \u108 ?}{\uc1 \u110 ?}{\uc1 \u32 ?}{\uc1 \u76 ?}{\uc1 \u105 ?}{\uc1 \u110 ?}{\uc1 \u32 ?}{\uc1 \u40 ?}{\uc1 \u66 ?}{\uc1 \u101 ?}{\uc1 \u105 ?}{\uc1 \u32 ?}{\uc1 \u74 ?}{\uc1 \u105 ?}{\uc1 \u110 ?}{\uc1 \u103 ?}{\uc1 \u41 ?}}
+{\operator {\uc1 \u106 ?}{\uc1 \u97 ?}{\uc1 \u121 ?}}
+}
+
+
+{\loch \af11 \hich \af11 \dbch \f11
+{\uc1 \u21414 ?}{\uc1 \u38376 ?}{\uc1 \u38056 ?}{\uc1 \u19994 ?}{\uc1 \u32929 ?}{\uc1 \u20221 ?}{\uc1 \u26377 ?}{\uc1 \u38480 ?}{\uc1 \u20844 ?}{\uc1 \u21496 ?}
+}
+\par
+
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index 97847361a9d6..14a8728befa2 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -1323,6 +1323,28 @@ DECLARE_RTFIMPORT_TEST(testN823675, "n823675.rtf")
CPPUNIT_ASSERT_EQUAL(OUString("Symbol"), aFont.Name);
}
+DECLARE_RTFIMPORT_TEST(testFdo77996, "fdo77996.rtf")
+{
+ // all styles were imported as name "0"
+ uno::Reference<container::XNameAccess> xChars(getStyles("CharacterStyles"));
+ CPPUNIT_ASSERT(!xChars->hasByName("0"));
+ CPPUNIT_ASSERT(xChars->hasByName("strong"));
+ CPPUNIT_ASSERT(xChars->hasByName("author"));
+ uno::Reference<container::XNameAccess> xParas(getStyles("ParagraphStyles"));
+ CPPUNIT_ASSERT(!xParas->hasByName("0"));
+ CPPUNIT_ASSERT(xParas->hasByName("extract2"));
+ // some document properties were lost
+ uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<document::XDocumentProperties> xProps(xDocumentPropertiesSupplier->getDocumentProperties());
+ CPPUNIT_ASSERT_EQUAL(OUString("Aln Lin (Bei Jing)"), xProps->getAuthor());
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("\xe5\x8e\xa6\xe9\x97\xa8\xe9\x92\xa8\xe4\xb8\x9a\xe8\x82\xa1\xe4\xbb\xbd\xe6\x9c\x89\xe9\x99\x90\xe5\x85\xac\xe5\x8f\xb8", 30,
+ RTL_TEXTENCODING_UTF8),
+ xProps->getTitle());
+ uno::Reference<beans::XPropertySet> xUDProps(xProps->getUserDefinedProperties(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("jay"), getProperty<OUString>(xUDProps, "Operator"));
+}
+
DECLARE_RTFIMPORT_TEST(testFdo47802, "fdo47802.rtf")
{
uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 879bc2250250..f25e51884891 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -705,7 +705,9 @@ int RTFDocumentImpl::resolvePict(bool const bInline, uno::Reference<drawing::XSh
int b = 0, count = 2;
// Feed the destination text to a stream.
- OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
+ OString aStr = OUStringToOString(
+ m_aStates.top().aDestinationText.makeStringAndClear(),
+ RTL_TEXTENCODING_ASCII_US);
const char* str = aStr.getStr();
for (int i = 0; i < aStr.getLength(); ++i)
{
@@ -1093,12 +1095,12 @@ void RTFDocumentImpl::text(OUString& rString)
bool bRet = true;
switch (m_aStates.top().nDestinationState)
{
+ // Note: in fonttbl there may or may not be groups; in stylesheet
+ // and revtbl groups are mandatory
case DESTINATION_FONTTABLE:
case DESTINATION_FONTENTRY:
- case DESTINATION_STYLESHEET:
case DESTINATION_STYLEENTRY:
case DESTINATION_LISTNAME:
- case DESTINATION_REVISIONTABLE:
case DESTINATION_REVISIONENTRY:
{
// ; is the end of the entry
@@ -1108,15 +1110,16 @@ void RTFDocumentImpl::text(OUString& rString)
rString = rString.copy(0, rString.getLength() - 1);
bEnd = true;
}
- m_aStates.top().aDestinationText.append(rString);
+ m_aStates.top().pDestinationText->append(rString);
if (bEnd)
{
+ // always clear, necessary in case of group-less fonttable
+ OUString const aName = m_aStates.top().pDestinationText->makeStringAndClear();
switch (m_aStates.top().nDestinationState)
{
case DESTINATION_FONTTABLE:
case DESTINATION_FONTENTRY:
{
- OUString aName = m_aStates.top().aDestinationText.makeStringAndClear();
m_aFontNames[m_nCurrentFontIndex] = aName;
if (m_nCurrentEncoding > 0)
{
@@ -1139,11 +1142,9 @@ void RTFDocumentImpl::text(OUString& rString)
m_aFontTableEntries.insert(lb, make_pair(m_nCurrentFontIndex, pProp));
}
break;
- case DESTINATION_STYLESHEET:
case DESTINATION_STYLEENTRY:
if (m_aStates.top().aTableAttributes.find(NS_ooxml::LN_CT_Style_type))
{
- OUString aName = m_aStates.top().aDestinationText.makeStringAndClear();
m_aStyleNames[m_nCurrentStyleIndex] = aName;
RTFValue::Pointer_t pValue(new RTFValue(aName));
m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_Style_styleId, pValue);
@@ -1159,11 +1160,9 @@ void RTFDocumentImpl::text(OUString& rString)
break;
case DESTINATION_LISTNAME:
// TODO: what can be done with a list name?
- m_aStates.top().aDestinationText.makeStringAndClear();
break;
- case DESTINATION_REVISIONTABLE:
case DESTINATION_REVISIONENTRY:
- m_aAuthors[m_aAuthors.size()] = m_aStates.top().aDestinationText.makeStringAndClear();
+ m_aAuthors[m_aAuthors.size()] = aName;
break;
default:
break;
@@ -1213,7 +1212,7 @@ void RTFDocumentImpl::text(OUString& rString)
case DESTINATION_MSUPHIDE:
case DESTINATION_MTYPE:
case DESTINATION_MGROW:
- m_aStates.top().aDestinationText.append(rString);
+ m_aStates.top().pDestinationText->append(rString);
break;
default:
bRet = false;
@@ -1243,7 +1242,7 @@ void RTFDocumentImpl::text(OUString& rString)
// Don't return earlier, a bookmark start has to be in a paragraph group.
if (m_aStates.top().nDestinationState == DESTINATION_BOOKMARKSTART)
{
- m_aStates.top().aDestinationText.append(rString);
+ m_aStates.top().pDestinationText->append(rString);
return;
}
@@ -1962,6 +1961,9 @@ int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
break;
}
+ // new destination => use new destination text
+ m_aStates.top().pDestinationText = &m_aStates.top().aDestinationText;
+
return 0;
}
@@ -4681,19 +4683,23 @@ int RTFDocumentImpl::pushState()
else
{
if (m_aStates.top().nDestinationState == DESTINATION_MR)
- lcl_DestinationToMath(m_aStates.top().aDestinationText, m_aMathBuffer, m_bMathNor);
+ lcl_DestinationToMath(*m_aStates.top().pDestinationText, m_aMathBuffer, m_bMathNor);
m_aStates.push(m_aStates.top());
}
- m_aStates.top().aDestinationText.setLength(0);
+ m_aStates.top().aDestinationText.setLength(0); // was copied: always reset!
m_pTokenizer->pushGroup();
switch (m_aStates.top().nDestinationState)
{
case DESTINATION_FONTTABLE:
+ // this is a "faked" destination for the font entry
+ m_aStates.top().pDestinationText = &m_aStates.top().aDestinationText;
m_aStates.top().nDestinationState = DESTINATION_FONTENTRY;
break;
case DESTINATION_STYLESHEET:
+ // this is a "faked" destination for the style sheet entry
+ m_aStates.top().pDestinationText = &m_aStates.top().aDestinationText;
m_aStates.top().nDestinationState = DESTINATION_STYLEENTRY;
{
// the *default* is \s0 i.e. paragraph style default
@@ -4722,6 +4728,8 @@ int RTFDocumentImpl::pushState()
m_aStates.top().nDestinationState = DESTINATION_MR;
break;
case DESTINATION_REVISIONTABLE:
+ // this is a "faked" destination for the revision table entry
+ m_aStates.top().pDestinationText = &m_aStates.top().aDestinationText;
m_aStates.top().nDestinationState = DESTINATION_REVISIONENTRY;
break;
default:
@@ -4835,7 +4843,9 @@ int RTFDocumentImpl::popState()
break;
case DESTINATION_LEVELTEXT:
{
- OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear();
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ OUString aStr = m_aStates.top().pDestinationText->makeStringAndClear();
// The first character is the length of the string (the rest should be ignored).
sal_Int32 nLength(aStr.toChar());
@@ -4874,12 +4884,15 @@ int RTFDocumentImpl::popState()
}
break;
case DESTINATION_SHAPEPROPERTYNAME:
- aState.aShape.aProperties.push_back(make_pair(m_aStates.top().aDestinationText.makeStringAndClear(), OUString()));
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ aState.aShape.aProperties.push_back(make_pair(
+ m_aStates.top().pDestinationText->makeStringAndClear(), OUString()));
break;
case DESTINATION_SHAPEPROPERTYVALUE:
if (aState.aShape.aProperties.size())
{
- aState.aShape.aProperties.back().second = m_aStates.top().aDestinationText.makeStringAndClear();
+ aState.aShape.aProperties.back().second = m_aStates.top().pDestinationText->makeStringAndClear();
if (m_aStates.top().bHadShapeText)
m_pSdrImport->append(aState.aShape.aProperties.back().first, aState.aShape.aProperties.back().second);
else if (aState.bInShapeGroup && !aState.bInShape && aState.aShape.aProperties.back().first == "rotation")
@@ -4908,30 +4921,40 @@ int RTFDocumentImpl::popState()
break;
case DESTINATION_BOOKMARKSTART:
{
- OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear();
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ OUString aStr = m_aStates.top().pDestinationText->makeStringAndClear();
int nPos = m_aBookmarks.size();
m_aBookmarks[aStr] = nPos;
Mapper().props(lcl_getBookmarkProperties(nPos, aStr));
}
break;
case DESTINATION_BOOKMARKEND:
- Mapper().props(lcl_getBookmarkProperties(m_aBookmarks[m_aStates.top().aDestinationText.makeStringAndClear()]));
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ Mapper().props(lcl_getBookmarkProperties(m_aBookmarks[m_aStates.top().pDestinationText->makeStringAndClear()]));
break;
case DESTINATION_FORMFIELDNAME:
{
- RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().pDestinationText->makeStringAndClear()));
m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFData_name, pValue);
}
break;
case DESTINATION_FORMFIELDLIST:
{
- RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().pDestinationText->makeStringAndClear()));
m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_listEntry, pValue);
}
break;
case DESTINATION_DATAFIELD:
{
- OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), aState.nCurrentEncoding);
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ OString aStr = OUStringToOString(m_aStates.top().pDestinationText->makeStringAndClear(), aState.nCurrentEncoding);
// decode hex dump
OStringBuffer aBuf;
const char* str = aStr.getStr();
@@ -4999,30 +5022,51 @@ int RTFDocumentImpl::popState()
m_xDocumentProperties->setPrintDate(lcl_getDateTime(aState));
break;
case DESTINATION_AUTHOR:
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
if (m_xDocumentProperties.is())
- m_xDocumentProperties->setAuthor(m_aStates.top().aDestinationText.makeStringAndClear());
+ m_xDocumentProperties->setAuthor(m_aStates.top().pDestinationText->makeStringAndClear());
break;
case DESTINATION_KEYWORDS:
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
if (m_xDocumentProperties.is())
- m_xDocumentProperties->setKeywords(comphelper::string::convertCommaSeparated(m_aStates.top().aDestinationText.makeStringAndClear()));
+ m_xDocumentProperties->setKeywords(comphelper::string::convertCommaSeparated(m_aStates.top().pDestinationText->makeStringAndClear()));
break;
case DESTINATION_COMMENT:
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
if (m_xDocumentProperties.is())
- m_xDocumentProperties->setGenerator(m_aStates.top().aDestinationText.makeStringAndClear());
+ m_xDocumentProperties->setGenerator(m_aStates.top().pDestinationText->makeStringAndClear());
break;
case DESTINATION_SUBJECT:
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
if (m_xDocumentProperties.is())
- m_xDocumentProperties->setSubject(m_aStates.top().aDestinationText.makeStringAndClear());
+ m_xDocumentProperties->setSubject(m_aStates.top().pDestinationText->makeStringAndClear());
break;
+ case DESTINATION_TITLE:
+ {
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ if (m_xDocumentProperties.is())
+ m_xDocumentProperties->setTitle(aState.pDestinationText->makeStringAndClear());
+ }
+ break;
+
case DESTINATION_DOCCOMM:
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
if (m_xDocumentProperties.is())
- m_xDocumentProperties->setDescription(m_aStates.top().aDestinationText.makeStringAndClear());
+ m_xDocumentProperties->setDescription(m_aStates.top().pDestinationText->makeStringAndClear());
break;
case DESTINATION_OPERATOR:
case DESTINATION_COMPANY:
{
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
OUString aName = aState.nDestinationState == DESTINATION_OPERATOR ? OUString("Operator") : OUString("Company");
- uno::Any aValue = uno::makeAny(m_aStates.top().aDestinationText.makeStringAndClear());
+ uno::Any aValue = uno::makeAny(m_aStates.top().pDestinationText->makeStringAndClear());
if (m_xDocumentProperties.is())
{
uno::Reference<beans::XPropertyContainer> xUserDefinedProperties = m_xDocumentProperties->getUserDefinedProperties();
@@ -5037,11 +5081,14 @@ int RTFDocumentImpl::popState()
break;
case DESTINATION_OBJDATA:
{
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+
m_pObjectData.reset(new SvMemoryStream());
int b = 0, count = 2;
// Feed the destination text to a stream.
- OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
+ OString aStr = OUStringToOString(m_aStates.top().pDestinationText->makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
const char* str = aStr.getStr();
for (int i = 0; i < aStr.getLength(); ++i)
{
@@ -5119,7 +5166,9 @@ int RTFDocumentImpl::popState()
break;
case DESTINATION_ANNOTATIONDATE:
{
- OUString aStr(OStringToOUString(lcl_DTTM22OString(m_aStates.top().aDestinationText.makeStringAndClear().toInt32()),
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ OUString aStr(OStringToOUString(lcl_DTTM22OString(m_aStates.top().pDestinationText->makeStringAndClear().toInt32()),
aState.nCurrentEncoding));
RTFValue::Pointer_t pValue(new RTFValue(aStr));
RTFSprms aAnnAttributes;
@@ -5129,15 +5178,21 @@ int RTFDocumentImpl::popState()
}
break;
case DESTINATION_ANNOTATIONAUTHOR:
- m_aAuthor = m_aStates.top().aDestinationText.makeStringAndClear();
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ m_aAuthor = m_aStates.top().pDestinationText->makeStringAndClear();
break;
case DESTINATION_ATNID:
- m_aAuthorInitials = m_aStates.top().aDestinationText.makeStringAndClear();
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ m_aAuthorInitials = m_aStates.top().pDestinationText->makeStringAndClear();
break;
case DESTINATION_ANNOTATIONREFERENCESTART:
case DESTINATION_ANNOTATIONREFERENCEEND:
{
- OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear();
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ OUString aStr = m_aStates.top().pDestinationText->makeStringAndClear();
RTFValue::Pointer_t pValue(new RTFValue(aStr.toInt32()));
RTFSprms aAttributes;
if (aState.nDestinationState == DESTINATION_ANNOTATIONREFERENCESTART)
@@ -5150,7 +5205,9 @@ int RTFDocumentImpl::popState()
break;
case DESTINATION_ANNOTATIONREFERENCE:
{
- OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear();
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ OUString aStr = m_aStates.top().pDestinationText->makeStringAndClear();
RTFSprms aAnnAttributes;
aAnnAttributes.set(NS_ooxml::LN_CT_Markup_id, RTFValue::Pointer_t(new RTFValue(aStr.toInt32())));
Mapper().props(writerfilter::Reference<Properties>::Pointer_t(new RTFReferenceProperties(aAnnAttributes)));
@@ -5158,7 +5215,9 @@ int RTFDocumentImpl::popState()
break;
case DESTINATION_FALT:
{
- OUString aStr(m_aStates.top().aDestinationText.makeStringAndClear());
+ if (&m_aStates.top().aDestinationText != m_aStates.top().pDestinationText)
+ break; // not for nested group
+ OUString aStr(m_aStates.top().pDestinationText->makeStringAndClear());
RTFValue::Pointer_t pValue(new RTFValue(aStr));
aState.aTableSprms.set(NS_ooxml::LN_CT_Font_altName, pValue);
}
@@ -5250,7 +5309,7 @@ int RTFDocumentImpl::popState()
}
break;
case DESTINATION_MR:
- lcl_DestinationToMath(m_aStates.top().aDestinationText, m_aMathBuffer, m_bMathNor);
+ lcl_DestinationToMath(*m_aStates.top().pDestinationText, m_aMathBuffer, m_bMathNor);
break;
case DESTINATION_MF:
m_aMathBuffer.appendClosingTag(M_TOKEN(f));
@@ -5330,7 +5389,7 @@ int RTFDocumentImpl::popState()
}
oox::formulaimport::XmlStream::AttributeList aAttribs;
- aAttribs[M_TOKEN(val)] = m_aStates.top().aDestinationText.makeStringAndClear();
+ aAttribs[M_TOKEN(val)] = m_aStates.top().pDestinationText->makeStringAndClear();
m_aMathBuffer.appendOpeningTag(nMathToken, aAttribs);
m_aMathBuffer.appendClosingTag(nMathToken);
}
@@ -5561,12 +5620,14 @@ int RTFDocumentImpl::popState()
break;
case DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER:
{
+ // FIXME: don't use pDestinationText, points to popped state
RTFValue::Pointer_t pValue(new RTFValue(aState.aDestinationText.makeStringAndClear(), true));
m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_LevelSuffix_val, pValue);
}
break;
case DESTINATION_PARAGRAPHNUMBERING_TEXTBEFORE:
{
+ // FIXME: don't use pDestinationText, points to popped state
RTFValue::Pointer_t pValue(new RTFValue(aState.aDestinationText.makeStringAndClear(), true));
m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_LevelText_val, pValue);
}
@@ -5633,6 +5694,7 @@ int RTFDocumentImpl::popState()
case DESTINATION_SHAPEPROPERTYVALUEPICT:
{
m_aStates.top().aPicture = aState.aPicture;
+ // both \sp and \sv are destinations, copy the text up-ward for later
m_aStates.top().aDestinationText = aState.aDestinationText;
}
break;
@@ -5663,15 +5725,6 @@ int RTFDocumentImpl::popState()
m_aListTableSprms.set(NS_ooxml::LN_CT_Numbering_numPicBullet, pValue, OVERWRITE_NO_APPEND);
}
break;
- case DESTINATION_TITLE:
- {
- if (m_aStates.top().nDestinationState == DESTINATION_TITLE)
- // The parent is a title as well, just append what we have so far.
- m_aStates.top().aDestinationText.append(aState.aDestinationText.makeStringAndClear());
- else if (m_xDocumentProperties.is())
- m_xDocumentProperties->setTitle(aState.aDestinationText.makeStringAndClear());
- }
- break;
case DESTINATION_SHAPETEXT:
// If we're leaving the shapetext group (it may have nested ones) and this is a shape, not an old drawingobject.
if (m_aStates.top().nDestinationState != DESTINATION_SHAPETEXT && !m_aStates.top().aDrawingObject.bHadShapeText)
@@ -5747,6 +5800,8 @@ void RTFDocumentImpl::setDestinationState(RTFDestinationState nDestinationState)
m_aStates.top().nDestinationState = nDestinationState;
}
+// this is a questionably named method that is used only in a very special
+// situation where it looks like the "current" buffer is needed?
void RTFDocumentImpl::setDestinationText(OUString& rString)
{
m_aStates.top().aDestinationText.setLength(0);
@@ -5815,6 +5870,7 @@ RTFParserState::RTFParserState(RTFDocumentImpl* pDocumentImpl)
nDay(0),
nHour(0),
nMinute(0),
+ pDestinationText(0),
nCurrentStyleIndex(-1),
pCurrentBuffer(0),
bInListpicture(false),
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 39a665469b18..94f43bf0f622 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -270,6 +270,8 @@ public:
/// Text from special destinations.
OUStringBuffer aDestinationText;
+ /// point to the buffer of the current destination
+ OUStringBuffer * pDestinationText;
/// Index of the current style.
int nCurrentStyleIndex;