Fix bug in HWP/HWPX with breaks

This commit is contained in:
Green
2025-06-13 01:05:20 +03:00
parent d287fc016e
commit 405a2c1f59
2 changed files with 35 additions and 15 deletions

View File

@ -18,7 +18,27 @@ struct TConversionState
bool m_bOpenedR; bool m_bOpenedR;
bool m_bIsNote; bool m_bIsNote;
bool m_bInTable; bool m_bInTable;
ECtrlObjectType m_ePrevElementType;
struct TLastNode
{
unsigned int m_unParaIndex;
enum class ELastNodeType
{
Empty,
Paragraph,
Table
} m_eType;
TLastNode()
: m_unParaIndex(0), m_eType(ELastNodeType::Empty)
{}
void Clear()
{
m_unParaIndex = 0;
m_eType = ELastNodeType::Empty;
}
} m_oLastNode;
bool m_bInTextBox; // TODO:: используется, чтобы в wps:txbx не появилась новая фигура (посмотреть этот момент нужно подробнее) bool m_bInTextBox; // TODO:: используется, чтобы в wps:txbx не появилась новая фигура (посмотреть этот момент нужно подробнее)
@ -47,7 +67,7 @@ struct TConversionState
std::map<unsigned int, const CCtrlField*> m_mOpenField; std::map<unsigned int, const CCtrlField*> m_mOpenField;
TConversionState() TConversionState()
: m_bOpenedP(false), m_bOpenedR(false), m_bIsNote(false), m_bInTable(false), m_ePrevElementType(ECtrlObjectType::Empty), m_bInTextBox(false), m_ushLastCharShapeId(-1), m_ushSecdIndex(0), m_unParaIndex(0), : m_bOpenedP(false), m_bOpenedR(false), m_bIsNote(false), m_bInTable(false), m_bInTextBox(false), m_ushLastCharShapeId(-1), m_ushSecdIndex(0), m_unParaIndex(0),
m_pSectionDef(nullptr), m_pColumnDef(nullptr), m_pPageNum(nullptr), m_pNewNumber(nullptr), m_pRelationships(nullptr), m_eBreakType(EBreakType::None) m_pSectionDef(nullptr), m_pColumnDef(nullptr), m_pPageNum(nullptr), m_pNewNumber(nullptr), m_pRelationships(nullptr), m_eBreakType(EBreakType::None)
{} {}
}; };

View File

@ -282,6 +282,8 @@ void CConverter2OOXML::Convert()
m_oDocXml.WriteString(L"</w:pPr></w:p>"); m_oDocXml.WriteString(L"</w:pPr></w:p>");
++oState.m_ushSecdIndex; ++oState.m_ushSecdIndex;
oState.m_oLastNode.Clear();
} }
} }
@ -300,9 +302,10 @@ void CConverter2OOXML::WriteCharacter(const CCtrlCharacter* pCharacter, short sh
case ECtrlCharType::PARAGRAPH_BREAK: case ECtrlCharType::PARAGRAPH_BREAK:
{ {
// Таблицы пишутся без тега <w:p>, поэтому для них не открывается параграф // Таблицы пишутся без тега <w:p>, поэтому для них не открывается параграф
if (ECtrlObjectType::Table == oState.m_ePrevElementType && !oState.m_bInTable) if (TConversionState::TLastNode::ELastNodeType::Table == oState.m_oLastNode.m_eType &&
oState.m_unParaIndex == oState.m_oLastNode.m_unParaIndex && !oState.m_bInTable)
{ {
oState.m_ePrevElementType = ECtrlObjectType::Character; oState.m_oLastNode.m_eType = TConversionState::TLastNode::ELastNodeType::Table;
break; break;
} }
@ -329,8 +332,6 @@ void CConverter2OOXML::WriteShape(const CCtrlGeneralShape* pShape, short shParaS
if (nullptr == pShape || oState.m_bInTextBox) if (nullptr == pShape || oState.m_bInTextBox)
return; return;
oState.m_ePrevElementType = ECtrlObjectType::Shape;
switch (pShape->GetShapeType()) switch (pShape->GetShapeType())
{ {
case EShapeType::Arc: case EShapeType::Arc:
@ -380,8 +381,6 @@ void CConverter2OOXML::WriteNote(const CCtrlNote* pNote, short shParaShapeID, NS
if (nullptr == pNote) if (nullptr == pNote)
return; return;
oState.m_ePrevElementType = ECtrlObjectType::Note;
oBuilder.WriteString(L"<w:r>"); oBuilder.WriteString(L"<w:r>");
CRunnerStyle oRunnerStyle; CRunnerStyle oRunnerStyle;
@ -399,8 +398,6 @@ void CConverter2OOXML::WriteField(const CCtrlField* pShape, short shParaShapeID,
if (nullptr == pShape) if (nullptr == pShape)
return; return;
oState.m_ePrevElementType = ECtrlObjectType::AutoNumber;
switch (pShape->GetType()) switch (pShape->GetType())
{ {
case EFieldType::Hyperlink: case EFieldType::Hyperlink:
@ -680,7 +677,8 @@ void CConverter2OOXML::WriteTable(const CCtrlTable* pTable, short shParaShapeID,
if (nullptr == pTable || pTable->Empty()) if (nullptr == pTable || pTable->Empty())
return; return;
oState.m_ePrevElementType = ECtrlObjectType::Table; if (TConversionState::TLastNode::ELastNodeType::Table == oState.m_oLastNode.m_eType)
oBuilder.WriteString(L"<w:p><w:r><w:rPr><w:vanish/></w:rPr></w:r></w:p>");
CloseParagraph(oBuilder, oState); CloseParagraph(oBuilder, oState);
@ -768,6 +766,9 @@ void CConverter2OOXML::WriteTable(const CCtrlTable* pTable, short shParaShapeID,
oBuilder.WriteString(L"</w:tbl>"); oBuilder.WriteString(L"</w:tbl>");
oState.m_oLastNode.m_eType = TConversionState::TLastNode::ELastNodeType::Table;
oState.m_oLastNode.m_unParaIndex = oState.m_unParaIndex;
oState.m_bInTable = bTableInTable; oState.m_bInTable = bTableInTable;
} }
@ -1763,6 +1764,9 @@ void CConverter2OOXML::CloseParagraph(NSStringUtils::CStringBuilder& oBuilder, T
oBuilder.WriteString(L"</w:p>"); oBuilder.WriteString(L"</w:p>");
oState.m_bOpenedP = false; oState.m_bOpenedP = false;
oState.m_oLastNode.m_unParaIndex = oState.m_unParaIndex;
oState.m_oLastNode.m_eType = TConversionState::TLastNode::ELastNodeType::Paragraph;
} }
void CConverter2OOXML::WriteText(const CParaText* pParaText, const std::vector<TRangeTag>& arRangeTags, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) void CConverter2OOXML::WriteText(const CParaText* pParaText, const std::vector<TRangeTag>& arRangeTags, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
@ -1875,8 +1879,6 @@ void CConverter2OOXML::WriteText(const HWP_STRING& wsText, short shParaShapeID,
if (!oState.m_bOpenedP && wsText.empty()) if (!oState.m_bOpenedP && wsText.empty())
return; return;
oState.m_ePrevElementType = ECtrlObjectType::ParaText;
OpenParagraph(shParaShapeID, shParaStyleID, oBuilder, oState); OpenParagraph(shParaShapeID, shParaStyleID, oBuilder, oState);
if (wsText.empty()) if (wsText.empty())
@ -2057,8 +2059,6 @@ void CConverter2OOXML::WriteAutoNumber(const CCtrlAutoNumber* pAutoNumber, short
if (nullptr == pAutoNumber) if (nullptr == pAutoNumber)
return; return;
oState.m_ePrevElementType = ECtrlObjectType::AutoNumber;
unsigned short ushValue = 0; unsigned short ushValue = 0;
HWP_STRING wsType; HWP_STRING wsType;