Kaydet (Commit) 9f5263c4 authored tarafından Miklos Vajna's avatar Miklos Vajna

fdo#44736 RTF import: ignore direct formatting which equals to style

Change-Id: Ie82f18381a95adbfedf7ea02d6844685e44b151d
üst 7bf64a5a
......@@ -399,6 +399,21 @@ void RTFDocumentImpl::setNeedPar(bool bNeedPar)
m_bNeedPar = bNeedPar;
}
writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms)
{
int nStyle = m_aStates.top().nCurrentStyleIndex;
RTFReferenceTable::Entries_t::iterator it = m_aStyleTableEntries.find(nStyle);
if (it != m_aStyleTableEntries.end())
{
RTFReferenceProperties& rProps = *(RTFReferenceProperties*)it->second.get();
// Get rid of direct formatting what is already in the style.
rSprms.deduplicate(rProps.getSprms());
rAttributes.deduplicate(rProps.getAttributes());
}
writerfilter::Reference<Properties>::Pointer_t pRet(new RTFReferenceProperties(rAttributes, rSprms));
return pRet;
}
void RTFDocumentImpl::checkNeedPap()
{
if (m_bNeedPap)
......@@ -407,7 +422,7 @@ void RTFDocumentImpl::checkNeedPap()
if (!m_pCurrentBuffer)
{
writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
new RTFReferenceProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
getProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
);
// Writer will ignore a page break before a text frame, so guard it with empty paragraphs
......@@ -441,9 +456,7 @@ void RTFDocumentImpl::runProps()
{
if (!m_pCurrentBuffer)
{
writerfilter::Reference<Properties>::Pointer_t const pProperties(
new RTFReferenceProperties(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms)
);
writerfilter::Reference<Properties>::Pointer_t const pProperties = getProperties(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms);
Mapper().props(pProperties);
}
else
......@@ -1677,7 +1690,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
new RTFReferenceProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
getProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
);
Mapper().props(pParagraphProperties);
......@@ -2623,6 +2636,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
}
break;
case RTF_S:
m_aStates.top().nCurrentStyleIndex = nParam;
if (m_aStates.top().nDestinationState == DESTINATION_STYLESHEET || m_aStates.top().nDestinationState == DESTINATION_STYLEENTRY)
{
m_nCurrentStyleIndex = nParam;
......@@ -4206,7 +4220,8 @@ RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl)
nMonth(0),
nDay(0),
nHour(0),
nMinute(0)
nMinute(0),
nCurrentStyleIndex(-1)
{
}
......
......@@ -399,6 +399,9 @@ namespace writerfilter {
/// Text from special destinations.
rtl::OUStringBuffer aDestinationText;
/// Same as the int value of NS_rtf::LN_ISTD in aParagraphAttributes, for performance reasons.
int nCurrentStyleIndex;
};
class RTFTokenizer;
......@@ -478,6 +481,7 @@ namespace writerfilter {
void runBreak();
void parBreak();
void tableBreak();
writerfilter::Reference<Properties>::Pointer_t getProperties(RTFSprms& rAttributes, RTFSprms& rSprms);
void checkNeedPap();
void sectBreak(bool bFinal);
void replayBuffer(RTFBuffer_t& rBuffer);
......
......@@ -62,6 +62,16 @@ std::string RTFReferenceProperties::getType() const
return "RTFReferenceProperties";
}
RTFSprms& RTFReferenceProperties::getAttributes()
{
return m_aAttributes;
}
RTFSprms& RTFReferenceProperties::getSprms()
{
return m_aSprms;
}
} // namespace rtftok
} // namespace writerfilter
......
......@@ -42,6 +42,8 @@ namespace writerfilter {
virtual ~RTFReferenceProperties();
virtual void resolve(Properties & rHandler);
virtual std::string getType() const;
RTFSprms& getAttributes();
RTFSprms& getSprms();
private:
RTFSprms m_aAttributes;
RTFSprms m_aSprms;
......
......@@ -29,6 +29,7 @@
#include <rtl/strbuf.hxx>
#include <resourcemodel/QNameToString.hxx>
#include <doctok/resourceids.hxx> // NS_rtf namespace
using rtl::OStringBuffer;
......@@ -130,6 +131,25 @@ bool RTFSprms::erase(Id nKeyword)
return false;
}
void RTFSprms::deduplicate(RTFSprms& rReference)
{
RTFSprms::Iterator_t i = m_aSprms.begin();
while (i != m_aSprms.end())
{
bool bIgnore = false;
if (i->first != NS_rtf::LN_ISTD)
{
RTFValue::Pointer_t pValue(rReference.find(i->first));
if (pValue.get() && i->second->equals(*pValue))
bIgnore = true;
}
if (bIgnore)
i = m_aSprms.erase(i);
else
++i;
}
}
RTFSprms::RTFSprms()
: m_aSprms()
{
......
......@@ -47,6 +47,8 @@ namespace writerfilter {
/// Does the same as ->push_back(), except that it can overwrite existing entries.
void set(Id nKeyword, RTFValue::Pointer_t pValue, bool bOverwrite = true);
bool erase(Id nKeyword);
/// Removes elements, which are already in the reference set.
void deduplicate(RTFSprms& rReference);
void swap(RTFSprms& rOther);
size_t size() const { return m_aSprms.size(); }
bool empty() const { return m_aSprms.empty(); }
......
......@@ -200,6 +200,11 @@ RTFValue* RTFValue::Clone()
return new RTFValue(m_nValue, m_sValue, *m_pAttributes, *m_pSprms, m_xShape, m_xStream, m_xObject, m_bForceString);
}
bool RTFValue::equals(RTFValue& rOther)
{
return m_nValue == rOther.m_nValue;
}
RTFSprms& RTFValue::getAttributes()
{
return *m_pAttributes;
......
......@@ -62,6 +62,7 @@ namespace writerfilter {
virtual RTFValue* Clone();
RTFSprms& getAttributes();
RTFSprms& getSprms();
bool equals(RTFValue& rOther);
private:
RTFValue& operator=(RTFValue const& rOther);
int m_nValue;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment