/* * 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 "NumberingConverter.h" #include "../../../DesktopEditor/common/File.h" #include "Converter2OOXML.h" namespace HWP { CNumberingConverter::CNumberingConverter() {} unsigned int CNumberingConverter::GetCountNumbering() const { return m_arUsedNumbering.size(); } std::wstring HeadingTypeToWSTR(EHeadingType eHeadingType) { switch(eHeadingType) { case EHeadingType::NONE: return std::wstring(); case EHeadingType::OUTLINE: return std::wstring(); case EHeadingType::NUMBER: return std::wstring(L"decimal"); case EHeadingType::BULLET: return std::wstring(L"bullet"); } } int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering, EHeadingType eHeadingType, CConverter2OOXML& oConverter) { if (nullptr == pNumbering || eHeadingType == EHeadingType::NONE || EHeadingType::OUTLINE == eHeadingType) return 0; std::vector>::const_iterator itFound = std::find_if(m_arUsedNumbering.cbegin(), m_arUsedNumbering.cend(), [pNumbering, eHeadingType](const std::pair& oValue) { return eHeadingType == oValue.first && pNumbering == oValue.second;}); if (m_arUsedNumbering.cend() != itFound) return itFound - m_arUsedNumbering.cbegin() + 1; m_arUsedNumbering.push_back(std::make_pair(eHeadingType, pNumbering)); m_oNumberXml.WriteString(L""); const std::wstring wsNumFormat{HeadingTypeToWSTR(eHeadingType)}; std::wstring wsLvlText; if (EHeadingType::NUMBER == eHeadingType) { for (short shIndex = 0; shIndex < 7; ++shIndex) { m_oNumberXml.WriteString(L""); m_oNumberXml.WriteString(L"GetStartNumber(shIndex)) + L"\"/>"); m_oNumberXml.WriteString(L""); m_oNumberXml.WriteString(L""); wsLvlText = pNumbering->GetNumFormat(shIndex); if (wsLvlText.empty()) { for (short shLvl = 0; shLvl <= shIndex; ++shLvl) wsLvlText += L'%' + std::to_wstring(shLvl + 1) + L'.'; } else std::replace(wsLvlText.begin(), wsLvlText.end(), L'^', L'%'); m_oNumberXml.WriteString(L""); m_oNumberXml.WriteString(L"GetAlign(shIndex)) { default: case 0x0: m_oNumberXml.WriteString(L"start"); break; case 0x1: m_oNumberXml.WriteString(L"center"); break; case 0x2: m_oNumberXml.WriteString(L"right"); break; } m_oNumberXml.WriteString(L"\"/>"); int nCharShape = pNumbering->GetCharShape(shIndex); if (INT_MAX == nCharShape) nCharShape = 0; TConversionState oState; oConverter.WriteRunnerStyle(nCharShape, m_oNumberXml, oState); m_oNumberXml.WriteString(L""); } } else if (EHeadingType::BULLET == eHeadingType) { for (short shIndex = 0; shIndex < 9; ++shIndex) { m_oNumberXml.WriteString(L""); m_oNumberXml.WriteString(L""); m_oNumberXml.WriteString(L""); m_oNumberXml.WriteString(L"GetAlign(shIndex)) { default: case 0x0: m_oNumberXml.WriteString(L"start"); break; case 0x1: m_oNumberXml.WriteString(L"center"); break; case 0x2: m_oNumberXml.WriteString(L"right"); break; } m_oNumberXml.WriteString(L"\"/>"); switch (shIndex % 3) { case 0: { m_oNumberXml.WriteString(L""); m_oNumberXml.WriteString(L""); break; } case 1: { m_oNumberXml.WriteString(L""); m_oNumberXml.WriteString(L""); break; } case 2: { m_oNumberXml.WriteString(L""); m_oNumberXml.WriteString(L""); break; } } m_oNumberXml.WriteString(L""); } } m_oNumberXml.WriteString(L""); return m_arUsedNumbering.size(); } bool CNumberingConverter::SaveToFile(const std::wstring& wsDirectory) { if (m_arUsedNumbering.empty()) return false; NSStringUtils::CStringBuilder oNumberingData; oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(m_oNumberXml.GetData()); if (m_arUsedNumbering.empty()) { oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); oNumberingData.WriteString(L""); } else { for (unsigned short ushIndex = 1; ushIndex <= m_arUsedNumbering.size(); ++ushIndex) oNumberingData.WriteString(L""); } oNumberingData.WriteString(L""); NSFile::CFileBinary oNumberingWriter; if (!oNumberingWriter.CreateFileW(wsDirectory + L"numbering.xml")) return false; oNumberingWriter.WriteStringUTF8(oNumberingData.GetData()); oNumberingWriter.CloseFile(); return true; } }