/* * Copyright (C) Ascensio System SIA, 2009-2026 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation, together with the * additional terms provided in the LICENSE file. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: https://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA by email at info@onlyoffice.com * or by postal mail at 20A-6 Ernesta Birznieka-Upisha Street, Riga, * LV-1050, Latvia, European Union. * * The interactive user interfaces in modified versions of the Program * are required to display Appropriate Legal Notices in accordance with * Section 5 of the GNU AGPL version 3. * * No trademark rights are granted under this License. * * All non-code elements of the Product, including illustrations, * icon sets, and technical writing content, are licensed under the * Creative Commons Attribution-ShareAlike 4.0 International License: * https://creativecommons.org/licenses/by-sa/4.0/legalcode * * This license applies only to such non-code elements and does not * modify or replace the licensing terms applicable to the Program's * source code, which remains licensed under the GNU Affero General * Public License v3. * * SPDX-License-Identifier: AGPL-3.0-only */ #include "FootnoteConverter.h" #include "../../../DesktopEditor/common/File.h" #include "../Paragraph/CtrlAutoNumber.h" #include "../Paragraph/ParaText.h" #include "Converter2OOXML.h" namespace HWP { CFootnoteConverter::CFootnoteConverter() : m_ushCountFootnotes(0), m_ushCountEndnotes(0), m_ushHeaderCount(0), m_ushFooterCount(0) {} std::wstring CFootnoteConverter::CreateNote(const CCtrlNote* pNote, CConverter2OOXML& oConverter) { if (nullptr == pNote) return std::wstring(); NSStringUtils::CStringBuilder *pXMLBuilder = &m_oFootnoteXml; std::wstring wsPrefix = L"foot"; std::wstring wsIndex; if (L" ne" == pNote->GetID()) { wsPrefix = L"end"; pXMLBuilder = &m_oEndnoteXml; wsIndex = std::to_wstring(++m_ushCountEndnotes); } else wsIndex = std::to_wstring(++m_ushCountFootnotes); pXMLBuilder->WriteString(L""); TConversionState oState; oState.m_bIsNote = true; for (const CHWPPargraph* pParagraph : pNote->GetParagraphs()) oConverter.WriteParagraph(pParagraph, *pXMLBuilder, oState); pXMLBuilder->WriteString(L""); return L""; } std::wstring CFootnoteConverter::CreateHeadOrFoot(const CCtrlHeadFoot* pCtrlHeadFoot, CConverter2OOXML& oConverter) { if (nullptr == pCtrlHeadFoot) return std::wstring(); NSStringUtils::CStringBuilder oNewDocumentBuilder; TConversionState oState; VECTOR arRelationships; oState.m_pRelationships = &arRelationships; for (const CHWPPargraph* pParagraphs : pCtrlHeadFoot->GetParagraphs()) oConverter.WriteParagraph(pParagraphs, oNewDocumentBuilder, oState); const std::wstring wsFileName{(pCtrlHeadFoot->IsHeader() ? (L"header" + std::to_wstring(++m_ushHeaderCount)) : (L"footer" + std::to_wstring(++m_ushFooterCount))) + L".xml"}; NSFile::CFileBinary oFile; if (!oFile.CreateFileW(oConverter.GetTempDirectory() + L"/word/" + wsFileName)) return std::wstring(); const std::wstring wsNodeName{pCtrlHeadFoot->IsHeader() ? L"hdr" : L"ftr"}; oFile.WriteStringUTF8(L""); oFile.WriteStringUTF8(oNewDocumentBuilder.GetData()); oFile.WriteStringUTF8(L""); oFile.CloseFile(); if (arRelationships.empty()) return wsFileName; // TODO:: For now this is a copy from Converter2OOXML NSFile::CFileBinary oRelsWriter; if (oRelsWriter.CreateFileW(oConverter.GetTempDirectory() + L"/word/_rels/" + wsFileName + L".rels")) { oRelsWriter.WriteStringUTF8(L""); for (const TRelationship& oRelationship : arRelationships) { oRelsWriter.WriteStringUTF8(L""); else oRelsWriter.WriteStringUTF8(L"/>"); } oRelsWriter.WriteStringUTF8(L""); oRelsWriter.CloseFile(); } return wsFileName; } std::wstring CFootnoteConverter::CreatePageNum(const CCtrlPageNumPos* pCtrlPageNumPos, CConverter2OOXML& oConverter) { if (nullptr == pCtrlPageNumPos || ENumberShape2::DIGIT != pCtrlPageNumPos->GetFormatType() || ENumPos::NONE == pCtrlPageNumPos->GetPos()) return std::wstring(); std::wstring wsNodeName, wsJs; switch(pCtrlPageNumPos->GetPos()) { case ENumPos::TOP_LEFT: { wsNodeName = L"hdr"; wsJs = L"left"; break; } case ENumPos::TOP_CENTER: case ENumPos::TOP_OUTER: case ENumPos::TOP_INNER: { wsNodeName = L"hdr"; wsJs = L"center"; break; } case ENumPos::TOP_RIGHT: { wsNodeName = L"hdr"; wsJs = L"right"; break; } case ENumPos::BOTTOM_LEFT: { wsNodeName = L"ftr"; wsJs = L"left"; break; } case ENumPos::BOTTOM_CENTER: case ENumPos::BOTTOM_OUTER: case ENumPos::BOTTOM_INNER: { wsNodeName = L"ftr"; wsJs = L"center"; break; } case ENumPos::BOTTOM_RIGHT: { wsNodeName = L"ftr"; wsJs = L"right"; break; } case ENumPos::NONE: break; } const std::wstring wsFileName((L"hdr" == wsNodeName) ? (L"header" + std::to_wstring(++m_ushHeaderCount)) : (L"footer" + std::to_wstring(++m_ushFooterCount)) + L".xml"); NSFile::CFileBinary oFile; if (!oFile.CreateFileW(oConverter.GetTempDirectory() + L"/word/" + wsFileName)) return std::wstring(); oFile.WriteStringUTF8(L""); oFile.WriteStringUTF8(L""); oFile.WriteStringUTF8(L""); oFile.WriteStringUTF8(L""); oFile.WriteStringUTF8(L""); if (!pCtrlPageNumPos->GetPrefix().empty()) oFile.WriteStringUTF8(L"" + pCtrlPageNumPos->GetPrefix() + L""); oFile.WriteStringUTF8(L""); oFile.WriteStringUTF8(L"PAGE \\* MERGEFORMAT"); oFile.WriteStringUTF8(L""); oFile.WriteStringUTF8(L"2"); oFile.WriteStringUTF8(L""); if (!pCtrlPageNumPos->GetPostfix().empty()) oFile.WriteStringUTF8(L"" + pCtrlPageNumPos->GetPostfix() + L""); oFile.WriteStringUTF8(L""); oFile.WriteStringUTF8(L""); oFile.CloseFile(); return wsFileName; } bool CFootnoteConverter::SaveToFile(const std::wstring& wsDirectory) { if (0 == m_ushCountFootnotes && 0 == m_ushCountEndnotes && 0 == m_ushFooterCount && 0 == m_ushHeaderCount) return false; NSFile::CFileBinary oFootnoteWriter; if (!oFootnoteWriter.CreateFileW(wsDirectory + L"footnotes.xml")) return false; NSFile::CFileBinary oEndNotesWriter; if (!oEndNotesWriter.CreateFile(wsDirectory + L"endnotes.xml")) return false; oFootnoteWriter.WriteStringUTF8(L""); oFootnoteWriter.WriteStringUTF8(L" "); oFootnoteWriter.WriteStringUTF8(L""); oFootnoteWriter.WriteStringUTF8(m_oFootnoteXml.GetData()); oFootnoteWriter.WriteStringUTF8(L""); oFootnoteWriter.CloseFile(); oEndNotesWriter.WriteStringUTF8(L""); oEndNotesWriter.WriteStringUTF8(L""); oEndNotesWriter.WriteStringUTF8(m_oEndnoteXml.GetData()); oEndNotesWriter.WriteStringUTF8(L""); oEndNotesWriter.CloseFile(); return true; } } unsigned short HWP::CFootnoteConverter::GetFootnoteCount() const { return m_ushCountFootnotes; } unsigned short HWP::CFootnoteConverter::GetEndnoteCount() const { return m_ushCountEndnotes; }