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

fdo#57708 fix fake page break problem during RTF import

The core of this change is: so far the continous section break at the
end of the document was sent as a normal section break. This was
introduced in commit 892d33c8, probably
as a workaround (sadly it's not documented and I no longer remember).
Don't do this, since it causes additional page breaks during import.
Instead, fix properly whatever was broken after getting rid of this
workaround.

Change-Id: I28c372d539c150fe21ff9db31209f9935a5e9063
üst 42f6308d
...@@ -272,7 +272,9 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x ...@@ -272,7 +272,9 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
m_bIsInFrame(false), m_bIsInFrame(false),
m_aUnicodeBuffer(), m_aUnicodeBuffer(),
m_aHexBuffer(), m_aHexBuffer(),
m_bDeferredContSectBreak(false) m_bIgnoreNextContSectBreak(false),
m_bNeedSect(true),
m_bWasInFrame(false)
{ {
OSL_ASSERT(xInputStream.is()); OSL_ASSERT(xInputStream.is());
m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, sal_True)); m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, sal_True));
...@@ -399,6 +401,11 @@ void RTFDocumentImpl::setNeedPar(bool bNeedPar) ...@@ -399,6 +401,11 @@ void RTFDocumentImpl::setNeedPar(bool bNeedPar)
m_bNeedPar = bNeedPar; m_bNeedPar = bNeedPar;
} }
void RTFDocumentImpl::setNeedSect(bool bNeedSect)
{
m_bNeedSect = bNeedSect;
}
writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms) writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms)
{ {
int nStyle = m_aStates.top().nCurrentStyleIndex; int nStyle = m_aStates.top().nCurrentStyleIndex;
...@@ -496,6 +503,8 @@ void RTFDocumentImpl::parBreak() ...@@ -496,6 +503,8 @@ void RTFDocumentImpl::parBreak()
void RTFDocumentImpl::sectBreak(bool bFinal = false) void RTFDocumentImpl::sectBreak(bool bFinal = false)
{ {
SAL_INFO("writerfilter", OSL_THIS_FUNC << ": final? " << bFinal << ", needed? " << m_bNeedSect);
bool bNeedSect = m_bNeedSect;
// If there is no paragraph in this section, then insert a dummy one, as required by Writer // If there is no paragraph in this section, then insert a dummy one, as required by Writer
if (m_bNeedPar) if (m_bNeedPar)
dispatchSymbol(RTF_PAR); dispatchSymbol(RTF_PAR);
...@@ -512,10 +521,15 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false) ...@@ -512,10 +521,15 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false)
resolveSubstream(aPair.second, aPair.first); resolveSubstream(aPair.second, aPair.first);
} }
RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc); // Normally a section break at the end of the doc is necessary. Unless the
// In case the last section is a continous one, we don't need to output a section break. // last control word in the document is a section break itself.
if (bFinal && pBreak.get() && !pBreak->getInt()) if (!bNeedSect)
m_aStates.top().aSectionSprms.erase(NS_sprm::LN_SBkc); {
RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
// In case the last section is a continous one, we don't need to output a section break.
if (bFinal && pBreak.get() && !pBreak->getInt())
m_aStates.top().aSectionSprms.erase(NS_sprm::LN_SBkc);
}
// Section properties are a paragraph sprm. // Section properties are a paragraph sprm.
RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aSectionAttributes, m_aStates.top().aSectionSprms)); RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aSectionAttributes, m_aStates.top().aSectionSprms));
...@@ -536,6 +550,7 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false) ...@@ -536,6 +550,7 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false)
Mapper().startParagraphGroup(); Mapper().startParagraphGroup();
} }
m_bNeedPar = true; m_bNeedPar = true;
m_bNeedSect = false;
} }
void RTFDocumentImpl::seek(sal_uInt32 nPos) void RTFDocumentImpl::seek(sal_uInt32 nPos)
...@@ -1126,7 +1141,7 @@ void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer) ...@@ -1126,7 +1141,7 @@ void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer)
int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword) int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
{ {
checkUnicode(); checkUnicode();
checkDeferredContSectBreak(); setNeedSect();
RTFSkipDestination aSkip(*this); RTFSkipDestination aSkip(*this);
switch (nKeyword) switch (nKeyword)
{ {
...@@ -1551,7 +1566,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) ...@@ -1551,7 +1566,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
{ {
if (nKeyword != RTF_HEXCHAR) if (nKeyword != RTF_HEXCHAR)
checkUnicode(); checkUnicode();
checkDeferredContSectBreak(); setNeedSect();
RTFSkipDestination aSkip(*this); RTFSkipDestination aSkip(*this);
sal_uInt8 cCh = 0; sal_uInt8 cCh = 0;
...@@ -1609,13 +1624,8 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) ...@@ -1609,13 +1624,8 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
break; break;
case RTF_SECT: case RTF_SECT:
{ {
RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc); if (m_bIgnoreNextContSectBreak)
if (pBreak.get() && !pBreak->getInt()) m_bIgnoreNextContSectBreak = false;
{
// This is a continous section break, don't send it yet.
// It's possible that we'll have nothing after this token, and then we should ignore it.
m_bDeferredContSectBreak = true;
}
else else
sectBreak(); sectBreak();
} }
...@@ -1759,9 +1769,17 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) ...@@ -1759,9 +1769,17 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc); RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
if (pBreak.get() && !pBreak->getInt()) if (pBreak.get() && !pBreak->getInt())
{ {
if (m_bWasInFrame)
{
dispatchSymbol(RTF_PAR);
m_bWasInFrame = false;
}
dispatchFlag(RTF_SBKPAGE); dispatchFlag(RTF_SBKPAGE);
sectBreak(); sectBreak();
dispatchFlag(RTF_SBKNONE); dispatchFlag(RTF_SBKNONE);
if (m_bNeedPar)
dispatchSymbol(RTF_PAR);
m_bIgnoreNextContSectBreak = true;
} }
else else
{ {
...@@ -1792,7 +1810,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) ...@@ -1792,7 +1810,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
{ {
checkUnicode(); checkUnicode();
checkDeferredContSectBreak(); setNeedSect();
RTFSkipDestination aSkip(*this); RTFSkipDestination aSkip(*this);
int nParam = -1; int nParam = -1;
int nSprm = -1; int nSprm = -1;
...@@ -2474,7 +2492,7 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) ...@@ -2474,7 +2492,7 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
{ {
checkUnicode(nKeyword != RTF_U, true); checkUnicode(nKeyword != RTF_U, true);
checkDeferredContSectBreak(); setNeedSect();
RTFSkipDestination aSkip(*this); RTFSkipDestination aSkip(*this);
int nSprm = 0; int nSprm = 0;
RTFValue::Pointer_t pIntValue(new RTFValue(nParam)); RTFValue::Pointer_t pIntValue(new RTFValue(nParam));
...@@ -3282,7 +3300,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) ...@@ -3282,7 +3300,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam) int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam)
{ {
checkUnicode(); checkUnicode();
checkDeferredContSectBreak(); setNeedSect();
RTFSkipDestination aSkip(*this); RTFSkipDestination aSkip(*this);
int nSprm = -1; int nSprm = -1;
RTFValue::Pointer_t pBoolValue(new RTFValue(!bParam || nParam != 0)); RTFValue::Pointer_t pBoolValue(new RTFValue(!bParam || nParam != 0));
...@@ -3477,6 +3495,7 @@ int RTFDocumentImpl::popState() ...@@ -3477,6 +3495,7 @@ int RTFDocumentImpl::popState()
checkUnicode(); checkUnicode();
RTFParserState aState(m_aStates.top()); RTFParserState aState(m_aStates.top());
m_bWasInFrame = aState.aFrame.inFrame();
sal_Int32 nMathToken = 0; sal_Int32 nMathToken = 0;
switch (m_aStates.top().nDestinationState) switch (m_aStates.top().nDestinationState)
...@@ -3950,7 +3969,6 @@ int RTFDocumentImpl::popState() ...@@ -3950,7 +3969,6 @@ int RTFDocumentImpl::popState()
{ {
if (m_bNeedCr) if (m_bNeedCr)
dispatchSymbol(RTF_PAR); dispatchSymbol(RTF_PAR);
m_bDeferredContSectBreak = false;
sectBreak(true); sectBreak(true);
} }
...@@ -4170,15 +4188,6 @@ void RTFDocumentImpl::checkUnicode(bool bUnicode, bool bHex) ...@@ -4170,15 +4188,6 @@ void RTFDocumentImpl::checkUnicode(bool bUnicode, bool bHex)
} }
} }
void RTFDocumentImpl::checkDeferredContSectBreak()
{
if (m_bDeferredContSectBreak)
{
m_bDeferredContSectBreak = false;
sectBreak();
}
}
RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl) RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl)
: m_pDocumentImpl(pDocumentImpl), : m_pDocumentImpl(pDocumentImpl),
nInternalState(INTERNAL_NORMAL), nInternalState(INTERNAL_NORMAL),
......
...@@ -487,8 +487,8 @@ namespace writerfilter { ...@@ -487,8 +487,8 @@ namespace writerfilter {
void replayBuffer(RTFBuffer_t& rBuffer); void replayBuffer(RTFBuffer_t& rBuffer);
/// If we have some unicode or hex characters to send. /// If we have some unicode or hex characters to send.
void checkUnicode(bool bUnicode = true, bool bHex = true); void checkUnicode(bool bUnicode = true, bool bHex = true);
/// If we have a pending continous section break. /// If we need a final section break at the end of the document.
void checkDeferredContSectBreak(); void setNeedSect(bool bNeedSect = true);
uno::Reference<uno::XComponentContext> const& m_xContext; uno::Reference<uno::XComponentContext> const& m_xContext;
uno::Reference<io::XInputStream> const& m_xInputStream; uno::Reference<io::XInputStream> const& m_xInputStream;
...@@ -581,7 +581,12 @@ namespace writerfilter { ...@@ -581,7 +581,12 @@ namespace writerfilter {
rtl::OStringBuffer m_aHexBuffer; rtl::OStringBuffer m_aHexBuffer;
/// Formula import. /// Formula import.
oox::formulaimport::XmlStreamBuilder m_aMathBuffer; oox::formulaimport::XmlStreamBuilder m_aMathBuffer;
bool m_bDeferredContSectBreak; /// If the next continous section break should be ignored.
bool m_bIgnoreNextContSectBreak;
/// If a section break is needed before the end of the doc (false right after a section break).
bool m_bNeedSect;
/// If aFrame.inFrame() was true in the previous state.
bool m_bWasInFrame;
}; };
} // namespace rtftok } // namespace rtftok
} // namespace writerfilter } // namespace writerfilter
......
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