720 lines
24 KiB
C++
720 lines
24 KiB
C++
/*
|
||
* (c) Copyright Ascensio System SIA 2010-2023
|
||
*
|
||
* 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. In accordance with
|
||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||
* of any third-party rights.
|
||
*
|
||
* 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: http://www.gnu.org/licenses/agpl-3.0.html
|
||
*
|
||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||
* street, Riga, Latvia, EU, LV-1050.
|
||
*
|
||
* The interactive user interfaces in modified source and object code versions
|
||
* of the Program must display Appropriate Legal Notices, as required under
|
||
* Section 5 of the GNU AGPL version 3.
|
||
*
|
||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||
* grant you any rights under trademark law for use of our trademarks.
|
||
*
|
||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||
* well as technical writing content are licensed under the terms of the
|
||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||
*
|
||
*/
|
||
|
||
#include "NumberingMapping.h"
|
||
|
||
namespace DocFileFormat
|
||
{
|
||
NumberingMapping::NumberingMapping(ConversionContext* context) : AbstractOpenXmlMapping(new XMLTools::CStringXmlWriter()), m_context(context), m_document(NULL), m_xmldocument(NULL)
|
||
{
|
||
if (m_context)
|
||
{
|
||
m_document = m_context->_doc;
|
||
m_xmldocument = m_context->_docx;
|
||
}
|
||
}
|
||
|
||
NumberingMapping::~NumberingMapping()
|
||
{
|
||
RELEASEOBJECT(m_pXmlWriter);
|
||
}
|
||
}
|
||
|
||
namespace DocFileFormat
|
||
{
|
||
void NumberingMapping::Apply(IVisitable* visited)
|
||
{
|
||
if ((NULL == m_document) || (NULL == m_xmldocument))
|
||
return;
|
||
|
||
ListTable* rglst = static_cast<ListTable*>(visited);
|
||
|
||
if ((rglst != NULL) && (!rglst->listData.empty() || !rglst->listNumbering.empty()))
|
||
{
|
||
m_xmldocument->RegisterNumbering();
|
||
|
||
//start the document
|
||
m_pXmlWriter->WriteNodeBegin( L"w:numbering", TRUE );
|
||
|
||
//write namespaces
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:w", OpenXmlNamespaces::WordprocessingML );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:v", OpenXmlNamespaces::VectorML );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:o", OpenXmlNamespaces::Office );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:w10", OpenXmlNamespaces::OfficeWord );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:r", OpenXmlNamespaces::Relationships );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:wpc", L"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:mc", L"http://schemas.openxmlformats.org/markup-compatibility/2006");
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:wp14", L"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing");
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:wp", L"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing");
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:w14", L"http://schemas.microsoft.com/office/word/2010/wordml" );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:wpg", L"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:wpi", L"http://schemas.microsoft.com/office/word/2010/wordprocessingInk" );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:wne", L"http://schemas.microsoft.com/office/word/2006/wordml" );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:wps", L"http://schemas.microsoft.com/office/word/2010/wordprocessingShape" );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:a", L"http://schemas.openxmlformats.org/drawingml/2006/main" );
|
||
m_pXmlWriter->WriteAttribute( L"xmlns:m", L"http://schemas.openxmlformats.org/officeDocument/2006/math" );
|
||
m_pXmlWriter->WriteAttribute( L"mc:Ignorable", L"w14 wp14" );
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
|
||
|
||
PictureBulletsMapping();
|
||
|
||
for (size_t i = 0; i < rglst->listData.size(); ++i)
|
||
{
|
||
//start abstractNum
|
||
m_pXmlWriter->WriteNodeBegin( L"w:abstractNum", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:abstractNumId", FormatUtils::SizeTToWideString( i /*+ 1 */));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
|
||
|
||
//nsid
|
||
m_pXmlWriter->WriteNodeBegin( L"w:nsid", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToFormattedWideString( rglst->listData[i]->lsid, L"%08X" ));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
//multiLevelType
|
||
m_pXmlWriter->WriteNodeBegin( L"w:multiLevelType", TRUE );
|
||
|
||
if ( rglst->listData[i]->fHybrid )
|
||
{
|
||
m_pXmlWriter->WriteAttribute( L"w:val", L"hybridMultilevel" );
|
||
}
|
||
else if ( rglst->listData[i]->fSimpleList )
|
||
{
|
||
m_pXmlWriter->WriteAttribute( L"w:val", L"singleLevel" );
|
||
}
|
||
else
|
||
{
|
||
m_pXmlWriter->WriteAttribute( L"w:val", L"multilevel" );
|
||
}
|
||
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
//template
|
||
m_pXmlWriter->WriteNodeBegin( L"w:tmpl", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToFormattedWideString( rglst->listData[i]->tplc, L"%08X"));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
// writes the levels
|
||
size_t length = rglst->listData[i]->rglvl->size();
|
||
|
||
for (size_t j = 0; j < length; ++j)
|
||
{
|
||
ListLevel* lvl = rglst->listData[i]->rglvl->at(j);
|
||
LevelMapping(lvl, j, rglst->listData[i]->rgistd[j]);
|
||
}
|
||
|
||
//end abstractNum
|
||
m_pXmlWriter->WriteNodeEnd( L"w:abstractNum" );
|
||
}
|
||
//write old style numbering (сложносоставных не сущестует)
|
||
for (size_t i = 0; i < rglst->listNumbering.size(); ++i)
|
||
{
|
||
//start abstractNum
|
||
m_pXmlWriter->WriteNodeBegin( L"w:abstractNum", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:abstractNumId", FormatUtils::SizeTToWideString( rglst->listNumbering[i]->id ));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
|
||
|
||
////nsid
|
||
//m_pXmlWriter->WriteNodeBegin( L"w:nsid", TRUE );
|
||
//m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToFormattedWideString( rglst->listNumbering[i]->lsid, L"%08x" ) ));
|
||
//m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
//multiLevelType
|
||
m_pXmlWriter->WriteNodeBegin( L"w:multiLevelType", TRUE );
|
||
{
|
||
m_pXmlWriter->WriteAttribute( L"w:val", L"singleLevel" );
|
||
}
|
||
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
LevelMapping(rglst->listNumbering[i], 0);
|
||
|
||
//end abstractNum
|
||
m_pXmlWriter->WriteNodeEnd( L"w:abstractNum" );
|
||
}
|
||
|
||
//write the overrides
|
||
for (size_t i = 0; i < m_document->listFormatOverrideTable->size(); ++i)
|
||
{
|
||
ListFormatOverride* lfo = m_document->listFormatOverrideTable->at(i);
|
||
|
||
//start num
|
||
m_pXmlWriter->WriteNodeBegin( L"w:num", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:numId", FormatUtils::SizeTToWideString(i + 1));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
|
||
|
||
int index = FindIndexbyId( rglst->listData, lfo->lsid );
|
||
|
||
m_pXmlWriter->WriteNodeBegin( L"w:abstractNumId", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToWideString( index ) );
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
for (std::vector<ListFormatOverrideLevel*>::const_iterator iter = lfo->rgLfoLvl.begin(); iter != lfo->rgLfoLvl.end(); ++iter)
|
||
{
|
||
m_pXmlWriter->WriteNodeBegin( L"w:lvlOverride", TRUE );
|
||
|
||
m_pXmlWriter->WriteAttribute( L"w:ilvl", FormatUtils::IntToWideString( (*iter)->ilvl ));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
|
||
|
||
if ( ( (*iter)->fStartAt ) && ( !(*iter)->fFormatting ) )
|
||
{
|
||
m_pXmlWriter->WriteNodeBegin( L"w:startOverride", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToWideString( (*iter)->iStartAt ));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
}
|
||
|
||
LevelMapping((*iter)->lvl, 0, ListData::ISTD_NIL);
|
||
|
||
m_pXmlWriter->WriteNodeEnd(L"w:lvlOverride");
|
||
}
|
||
|
||
m_pXmlWriter->WriteNodeEnd(L"w:num");
|
||
}
|
||
|
||
if (m_document->listFormatOverrideTable->empty() && !rglst->listNumbering.empty())
|
||
{
|
||
for (size_t i = 0; i < rglst->listNumbering.size(); ++i)
|
||
{
|
||
m_pXmlWriter->WriteNodeBegin( L"w:num", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:numId", FormatUtils::SizeTToWideString(rglst->listNumbering[i]->id));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
|
||
|
||
|
||
m_pXmlWriter->WriteNodeBegin( L"w:abstractNumId", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::SizeTToWideString( rglst->listNumbering[i]->id ));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
m_pXmlWriter->WriteNodeEnd(L"w:num");
|
||
}
|
||
}
|
||
|
||
m_pXmlWriter->WriteNodeEnd(L"w:numbering");
|
||
|
||
m_xmldocument->NumberingXML = std::wstring(m_pXmlWriter->GetXmlString());
|
||
}
|
||
}
|
||
|
||
int NumberingMapping::FindIndexbyId(std::vector<ListDataPtr>& listData, int lsid)
|
||
{
|
||
int ret = -1;
|
||
int i = 0;
|
||
|
||
for (size_t i = 0; i < listData.size(); ++i)
|
||
{
|
||
if (listData[i]->lsid == lsid)
|
||
{
|
||
return i;
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
// Converts the number text of the binary format to the number text of OOXML.
|
||
// OOXML uses different placeholders for the numbers.
|
||
|
||
std::wstring NumberingMapping::GetLvlText(const ListLevel* lvl, bool bIsSymbol) const
|
||
{
|
||
std::wstring ret;
|
||
|
||
if (lvl != NULL)
|
||
{
|
||
if (lvl->nfc == 0x17)
|
||
{
|
||
if (!lvl->xst.empty())
|
||
{
|
||
wchar_t xchBullet = lvl->xst[0];
|
||
|
||
// В символьном шрифте обрезать надо, в других случаях - нет
|
||
if (true == bIsSymbol && (xchBullet & 0xF000) != 0)
|
||
{
|
||
xchBullet &= 0x0FFF;
|
||
}
|
||
|
||
if (!FormatUtils::IsControlSymbol(xchBullet))
|
||
{
|
||
ret.push_back(lvl->xst[0]);//??? xchBullet
|
||
}
|
||
else
|
||
{
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ret = lvl->xst;
|
||
|
||
std::wstring::const_iterator result = lvl->xst.begin();
|
||
std::wstring::const_iterator newResult = lvl->xst.begin();
|
||
|
||
newResult = find_if(lvl->xst.begin(), lvl->xst.end(), &NumberingMapping::IsPlaceholder);
|
||
ret = std::wstring(lvl->xst.begin(), newResult);
|
||
result = newResult;
|
||
|
||
while (result != lvl->xst.end())
|
||
{
|
||
newResult = find_if((result + 1), lvl->xst.end(), &NumberingMapping::IsPlaceholder);
|
||
|
||
ret += L"%";
|
||
ret += FormatUtils::SizeTToWideString(*result + 1);
|
||
ret += std::wstring((result + 1), newResult);
|
||
result = newResult;
|
||
}
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
std::wstring NumberingMapping::GetLvlText(NumberingDescriptorPtr& lvl, bool bIsSymbol, int Before, int After) const
|
||
{
|
||
if (!lvl)return L"";
|
||
|
||
std::wstring ret;
|
||
|
||
if (lvl->nfc == 0xff)
|
||
{
|
||
if (!lvl->xst.empty())
|
||
{
|
||
wchar_t xchBullet = lvl->xst[0];
|
||
|
||
// В символьном шрифте обрезать надо, в других случаях - нет
|
||
if (bIsSymbol && (xchBullet & 0xF000) != 0)
|
||
{
|
||
xchBullet &= 0x0FFF;
|
||
}
|
||
|
||
if (!FormatUtils::IsControlSymbol(xchBullet))
|
||
{
|
||
ret.push_back(lvl->xst[0]);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ret.push_back(L'\xF0B7');
|
||
}
|
||
}
|
||
else
|
||
{
|
||
std::wstring strBefore = lvl->xst.substr(0, Before);
|
||
std::wstring strAfter = lvl->xst.substr(Before, After);
|
||
|
||
ret = strBefore + L"%1" + strAfter ;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
bool NumberingMapping::IsPlaceholder(wchar_t symbol)
|
||
{
|
||
if ((symbol == (wchar_t)0x0000) || (symbol == (wchar_t)0x0001) || (symbol == (wchar_t)0x0002) ||
|
||
(symbol == (wchar_t)0x0003) || (symbol == (wchar_t)0x0004) || (symbol == (wchar_t)0x0005) ||
|
||
(symbol == (wchar_t)0x0006) || (symbol == (wchar_t)0x0007) || (symbol == (wchar_t)0x0008))
|
||
{
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
std::wstring NumberingMapping::GetNumberFormatWideString(int nfc, int nWordVersion)
|
||
{
|
||
if (nWordVersion > 0 && nfc > 5)
|
||
{
|
||
if (nfc == 0xff) return std::wstring( L"bullet");
|
||
else return std::wstring( L"none");
|
||
}
|
||
|
||
switch ( nfc )
|
||
{
|
||
case 0:
|
||
return std::wstring( L"decimal" );
|
||
case 1:
|
||
return std::wstring( L"upperRoman" );
|
||
case 2:
|
||
return std::wstring( L"lowerRoman" );
|
||
case 3:
|
||
return std::wstring( L"upperLetter");
|
||
case 4:
|
||
return std::wstring( L"lowerLetter");
|
||
case 5:
|
||
return std::wstring( L"ordinal" );
|
||
case 6:
|
||
return std::wstring( L"cardinalText" );
|
||
case 7:
|
||
return std::wstring( L"ordinalText" );
|
||
case 8:
|
||
return std::wstring( L"hex" );
|
||
case 9:
|
||
return std::wstring( L"chicago" );
|
||
case 10:
|
||
return std::wstring( L"ideographDigital" );
|
||
case 11:
|
||
return std::wstring( L"japaneseCounting" );
|
||
case 12:
|
||
return std::wstring( L"aiueo" );
|
||
case 13:
|
||
return std::wstring( L"iroha" );
|
||
case 14:
|
||
return std::wstring( L"decimalFullWidth" );
|
||
case 15:
|
||
return std::wstring( L"decimalHalfWidth" );
|
||
case 16:
|
||
return std::wstring( L"japaneseLegal" );
|
||
case 17:
|
||
return std::wstring( L"japaneseDigitalTenThousand" );
|
||
case 18:
|
||
return std::wstring( L"decimalEnclosedCircle" );
|
||
case 19:
|
||
return std::wstring( L"decimalFullWidth2" );
|
||
case 20:
|
||
return std::wstring( L"aiueoFullWidth" );
|
||
case 21:
|
||
return std::wstring( L"irohaFullWidth" );
|
||
case 22:
|
||
return std::wstring( L"decimalZero" );
|
||
case 23:
|
||
return std::wstring( L"bullet" );
|
||
case 24:
|
||
return std::wstring( L"ganada" );
|
||
case 25:
|
||
return std::wstring( L"chosung" );
|
||
case 26:
|
||
return std::wstring( L"decimalEnclosedFullstop" );
|
||
case 27:
|
||
return std::wstring( L"decimalEnclosedParen" );
|
||
case 28:
|
||
return std::wstring( L"decimalEnclosedCircleChinese" );
|
||
case 29:
|
||
return std::wstring( L"ideographEnclosedCircle" );
|
||
case 30:
|
||
return std::wstring( L"ideographTraditional" );
|
||
case 31:
|
||
return std::wstring( L"ideographZodiac" );
|
||
case 32:
|
||
return std::wstring( L"ideographZodiacTraditional" );
|
||
case 33:
|
||
return std::wstring( L"taiwaneseCounting" );
|
||
case 34:
|
||
return std::wstring( L"ideographLegalTraditional" );
|
||
case 35:
|
||
return std::wstring( L"taiwaneseCountingThousand" );
|
||
case 36:
|
||
return std::wstring( L"taiwaneseDigital" );
|
||
case 37:
|
||
return std::wstring( L"chineseCounting" );
|
||
case 38:
|
||
return std::wstring( L"chineseLegalSimplified" );
|
||
case 39:
|
||
return std::wstring( L"chineseCountingThousand" );
|
||
case 40:
|
||
return std::wstring( L"koreanDigital" );
|
||
case 41:
|
||
return std::wstring( L"koreanCounting" );
|
||
case 42:
|
||
return std::wstring( L"koreanLegal" );
|
||
case 43:
|
||
return std::wstring( L"koreanDigital2" );
|
||
case 44:
|
||
return std::wstring( L"vietnameseCounting" );
|
||
case 45:
|
||
return std::wstring( L"russianLower" );
|
||
case 46:
|
||
return std::wstring( L"russianUpper" );
|
||
case 47:
|
||
return std::wstring( L"none" );
|
||
case 48:
|
||
return std::wstring( L"numberInDash" );
|
||
case 49:
|
||
return std::wstring( L"hebrew1" );
|
||
case 50:
|
||
return std::wstring( L"hebrew2" );
|
||
case 51:
|
||
return std::wstring( L"arabicAlpha" );
|
||
case 52:
|
||
return std::wstring( L"arabicAbjad" );
|
||
case 53:
|
||
return std::wstring( L"hindiVowels" );
|
||
case 54:
|
||
return std::wstring( L"hindiConsonants" );
|
||
case 55:
|
||
return std::wstring( L"hindiNumbers" );
|
||
case 56:
|
||
return std::wstring( L"hindiCounting" );
|
||
case 57:
|
||
return std::wstring( L"thaiLetters" );
|
||
case 58:
|
||
return std::wstring( L"thaiNumbers" );
|
||
case 59:
|
||
return std::wstring( L"thaiCounting" );
|
||
default:
|
||
return std::wstring( L"decimal" );
|
||
}
|
||
}
|
||
|
||
void NumberingMapping::LevelMapping(NumberingDescriptorPtr & lvl, unsigned int level)
|
||
{
|
||
if (!lvl) return;
|
||
|
||
std::wstring fontFamily;
|
||
bool isSymbol = false;
|
||
|
||
if( lvl->ftc < m_document->FontTable->Data.size() )
|
||
{
|
||
FontFamilyName* ffn = static_cast<FontFamilyName*>( m_document->FontTable->operator [] ( lvl->ftc ) );
|
||
isSymbol = (ffn->chs == 2);
|
||
fontFamily = FormatUtils::XmlEncode(ffn->xszFtn);
|
||
}
|
||
|
||
//--------------------------------------------------------------------------------
|
||
m_pXmlWriter->WriteNodeBegin( L"w:lvl", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:ilvl", FormatUtils::IntToWideString(level));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
|
||
|
||
m_pXmlWriter->WriteNodeBegin( L"w:start", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToWideString(lvl->iStartAt));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
m_pXmlWriter->WriteNodeBegin( L"w:numFmt", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", GetNumberFormatWideString(lvl->nfc, true));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
//// suffix
|
||
// m_pXmlWriter->WriteNodeBegin( L"w:suff", TRUE );
|
||
// m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::MapValueToWideString(lvl->ixchFollow, &FollowingCharMap[0][0], 3, 8));
|
||
// m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
// Number level text
|
||
std::wstring lvlText = GetLvlText(lvl, isSymbol, lvl->cbTextBefore, lvl->cbTextAfter);
|
||
|
||
//if (lvlText.empty() && lvl->ftc == 0)//auto
|
||
//{
|
||
// lvlText.push_back(L'\xF0B7');
|
||
// lvlText.push_back(L'\0');
|
||
|
||
// fontFamily = L"Wingdings";
|
||
//}
|
||
if (!lvlText.empty())
|
||
{
|
||
m_pXmlWriter->WriteNodeBegin(L"w:lvlText",TRUE);
|
||
m_pXmlWriter->WriteAttribute(L"w:val",lvlText);
|
||
m_pXmlWriter->WriteNodeEnd(L"", TRUE);
|
||
}
|
||
|
||
// jc
|
||
m_pXmlWriter->WriteNodeBegin( L"w:lvlJc", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::MapValueToWideString(lvl->jc, &LevelJustificationMap[0][0], 3, 7));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
// pPr
|
||
m_pXmlWriter->WriteNodeBegin( L"w:pPr", FALSE );
|
||
m_pXmlWriter->WriteNodeEnd(L"w:pPr");
|
||
|
||
// rPr
|
||
if (false == lvl->rPr.empty())
|
||
{
|
||
m_pXmlWriter->WriteString( lvl->rPr );
|
||
}
|
||
else
|
||
{
|
||
m_pXmlWriter->WriteNodeBegin( L"w:rPr", FALSE );
|
||
|
||
if (!fontFamily.empty())
|
||
{
|
||
m_pXmlWriter->WriteNodeBegin( L"w:rFonts", TRUE );
|
||
// w:hint="default"
|
||
m_pXmlWriter->WriteAttribute(L"w:hAnsi", fontFamily);
|
||
m_pXmlWriter->WriteAttribute(L"w:ascii", fontFamily);
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
}
|
||
m_pXmlWriter->WriteNodeEnd(L"w:rPr");
|
||
}
|
||
|
||
m_pXmlWriter->WriteNodeEnd(L"w:lvl");
|
||
}
|
||
|
||
void NumberingMapping::LevelMapping(const ListLevel* lvl, unsigned int level, short styleIndex)
|
||
{
|
||
if (!lvl) return;
|
||
|
||
XMLTools::CStringXmlWriter oWriterTemp; //Временный writer,что не нарушать последовательность записи
|
||
//rPr
|
||
RevisionData rev(lvl->grpprlChpx);
|
||
CharacterPropertiesMapping cpMapping(&oWriterTemp, m_document, &rev, lvl->grpprlPapx, false);
|
||
lvl->grpprlChpx->Convert(&cpMapping);
|
||
|
||
// Проверяем шрифт
|
||
|
||
m_pXmlWriter->WriteNodeBegin( L"w:lvl", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:ilvl", FormatUtils::IntToWideString(level));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
|
||
|
||
// starts at
|
||
|
||
m_pXmlWriter->WriteNodeBegin( L"w:start", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToWideString(lvl->iStartAt));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
// number format
|
||
|
||
m_pXmlWriter->WriteNodeBegin( L"w:numFmt", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", GetNumberFormatWideString(lvl->nfc));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
// suffix
|
||
|
||
m_pXmlWriter->WriteNodeBegin( L"w:suff", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::MapValueToWideString(lvl->ixchFollow, &FollowingCharMap[0][0], 3, 8));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
|
||
// style
|
||
// The style id is used for a reverse reference.
|
||
// It can happen that the reference points to the wrong style.
|
||
|
||
if (styleIndex != ListData::ISTD_NIL && styleIndex < m_document->Styles->Styles->size())
|
||
{
|
||
m_pXmlWriter->WriteNodeBegin( L"w:pStyle", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::XmlEncode(StyleSheetMapping::MakeStyleId(m_document->Styles->Styles->at(styleIndex))));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
}
|
||
|
||
// Number level text
|
||
|
||
m_pXmlWriter->WriteNodeBegin(L"w:lvlText",TRUE);
|
||
m_pXmlWriter->WriteAttribute(L"w:val",GetLvlText(lvl, cpMapping.CheckIsSymbolFont()));
|
||
m_pXmlWriter->WriteNodeEnd(L"",TRUE);
|
||
|
||
WriteLevelPictureBullet(lvl->grpprlChpx);
|
||
|
||
// legacy
|
||
if (lvl->fWord6)
|
||
{
|
||
m_pXmlWriter->WriteNodeBegin( L"w:legacy", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:legacy", L"1" );
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
}
|
||
// jc
|
||
m_pXmlWriter->WriteNodeBegin( L"w:lvlJc", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::MapValueToWideString(lvl->jc, &LevelJustificationMap[0][0], 3, 7));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
|
||
// pPr
|
||
bool isBidi = false;
|
||
ParagraphPropertiesMapping oppMapping(m_pXmlWriter, m_context, m_document, NULL, isBidi, NULL, -1, false);
|
||
lvl->grpprlPapx->Convert(&oppMapping);
|
||
|
||
// пишем rPr
|
||
|
||
m_pXmlWriter->WriteString(oWriterTemp.GetXmlString());
|
||
|
||
m_pXmlWriter->WriteNodeEnd(L"w:lvl");
|
||
}
|
||
|
||
void NumberingMapping::PictureBulletsMapping()
|
||
{
|
||
for (std::map<int, int>::const_iterator iter = m_document->PictureBulletsCPsMap.begin(); iter != m_document->PictureBulletsCPsMap.end(); ++iter)
|
||
{
|
||
int fc = m_document->FindFileCharPos(iter->second);
|
||
int fcEnd = m_document->FindFileCharPos(iter->second + 1);
|
||
|
||
if (fc < 0 || fcEnd < 0 ) break;
|
||
|
||
std::vector<CharacterPropertyExceptions*>* chpxs = m_document->GetCharacterPropertyExceptions(fc, fcEnd);
|
||
|
||
if ((chpxs != NULL) && (!chpxs->empty()))
|
||
{
|
||
PictureDescriptor pict(chpxs->front(), m_document->DataStream, fcEnd - fc, m_document->nWordVersion);
|
||
|
||
if ((pict.mfp.mm > 98) && (pict.shapeContainer != NULL))
|
||
{
|
||
m_pXmlWriter->WriteNodeBegin( L"w:numPicBullet", TRUE );
|
||
m_pXmlWriter->WriteAttribute( L"w:numPicBulletId", FormatUtils::IntToWideString( iter->first ));
|
||
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
|
||
m_pXmlWriter->WriteNodeBegin( L"w:pict" );
|
||
|
||
//inline picture + bullete props
|
||
if (pict.blipStoreEntry != NULL)
|
||
{
|
||
VMLPictureMapping oPicture(m_context, m_pXmlWriter, false, this, true);
|
||
oPicture.m_isBullete = true;
|
||
|
||
pict.Convert(&oPicture);
|
||
}
|
||
else
|
||
{
|
||
VMLShapeMapping oShape (m_context, m_pXmlWriter, NULL, &pict, this, true);
|
||
oShape.m_isBullete = true;
|
||
pict.shapeContainer->Convert(&oShape);
|
||
}
|
||
|
||
m_pXmlWriter->WriteNodeEnd(L"w:pict");
|
||
m_pXmlWriter->WriteNodeEnd(L"w:numPicBullet");
|
||
}
|
||
}
|
||
|
||
RELEASEOBJECT( chpxs );
|
||
}
|
||
}
|
||
|
||
void NumberingMapping::WriteLevelPictureBullet(const CharacterPropertyExceptions* grpprlChpx)
|
||
{
|
||
if (grpprlChpx)
|
||
{
|
||
unsigned int index = 0;
|
||
bool isPictureBullet = false;
|
||
|
||
for (std::vector<SinglePropertyModifier>::const_iterator iter = grpprlChpx->grpprl->begin(); iter != grpprlChpx->grpprl->end(); ++iter)
|
||
{
|
||
switch(iter->OpCode)
|
||
{
|
||
case sprmCPbiIBullet:
|
||
{
|
||
index = FormatUtils::BytesToUInt32(iter->Arguments, 0, iter->argumentsSize);
|
||
}break;
|
||
|
||
case sprmCPbiGrf:
|
||
{
|
||
isPictureBullet = FormatUtils::BitmaskToBool(FormatUtils::BytesToUInt16(iter->Arguments, 0, iter->argumentsSize), 0x1);
|
||
}break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (isPictureBullet && false == m_document->PictureBulletsCPsMap.empty())
|
||
{
|
||
m_pXmlWriter->WriteNodeBegin(L"w:lvlPicBulletId",TRUE);
|
||
m_pXmlWriter->WriteAttribute(L"w:val",FormatUtils::IntToWideString(index));
|
||
m_pXmlWriter->WriteNodeEnd(L"",TRUE);
|
||
}
|
||
}
|
||
}
|
||
}
|