Files
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

575 lines
22 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 "OpenXmlPackage.h"
#include "Converter.h"
#include "NumberingMapping.h"
#include "CommentsMapping.h"
#include "EndnotesMapping.h"
#include "FootnotesMapping.h"
#include "FooterMapping.h"
#include "HeaderMapping.h"
#include "MainDocumentMapping.h"
#include "OleObjectMapping.h"
#include "VMLPictureMapping.h"
#include "FormFieldDataMapping.h"
#include "../../DesktopEditor/common/File.h"
#include "../../DesktopEditor/common/Directory.h"
#include "../Common/Base/XmlTools.h"
namespace DocFileFormat
{
OpenXmlPackage::OpenXmlPackage(const WordDocument* _docFile) : m_strOutputPath(L""), relID(1), _imageCounter(0), _headerCounter(0), _footerCounter(0),
_oleCounter(0), docFile(NULL), DocumentRelationshipsFile( L"word/_rels/document.xml.rels"), MainRelationshipsFile( L"_rels/.rels"),
FootnotesRelationshipsFile( L"word/_rels/footnotes.xml.rels"), EndnotesRelationshipsFile( L"word/_rels/endnotes.xml.rels"),
CommentsRelationshipsFile( L"word/_rels/comments.xml.rels"), NumberingRelationshipsFile( L"word/_rels/numbering.xml.rels")
{
docFile = _docFile;
DocumentContentTypesFile._defaultTypes.insert( make_pair( L"rels", std::wstring( OpenXmlContentTypes::Relationships ) ) );
DocumentContentTypesFile._defaultTypes.insert( make_pair( L"xml", std::wstring( OpenXmlContentTypes::Xml ) ) );
MainRelationshipsFile.Relationships.push_back( Relationship( std::wstring( L"rId1"), OpenXmlRelationshipTypes::OfficeDocument, L"word/document.xml") );
MainRelationshipsFile.Relationships.push_back( Relationship( std::wstring( L"rId2"), OpenXmlRelationshipTypes::CoreProperties, L"docProps/core.xml") );
MainRelationshipsFile.Relationships.push_back( Relationship( std::wstring( L"rId3"), OpenXmlRelationshipTypes::ExtendedProperties, L"docProps/app.xml") );
}
void OpenXmlPackage::WritePackage()
{
NSDirectory::CreateDirectory(m_strOutputPath + FILE_SEPARATOR_STR + L"_rels" );
WriteRelsFile( MainRelationshipsFile );
NSDirectory::CreateDirectory( m_strOutputPath + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"_rels" );
WriteRelsFile( DocumentRelationshipsFile );
WriteRelsFile( FootnotesRelationshipsFile );
WriteRelsFile( EndnotesRelationshipsFile );
WriteRelsFile( CommentsRelationshipsFile );
WriteRelsFile( NumberingRelationshipsFile );
for (auto& iter : HeaderRelationshipsFiles)
{
WriteRelsFile( iter );
}
for (auto& iter : FooterRelationshipsFiles)
{
WriteRelsFile( iter );
}
WriteContentTypesFile( DocumentContentTypesFile );
}
void OpenXmlPackage::SaveToFile( const std::wstring& outputDir, const std::wstring& fileName, const std::wstring& XMLContent )
{
if ( !XMLContent.empty() )
{
NSFile::CFileBinary file;
std::wstring pathFileName = outputDir + FILE_SEPARATOR_STR + fileName;
if (file.CreateFileW(pathFileName))
{
std::string root = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
file.WriteFile((BYTE*)root.c_str(), root.length());
file.WriteStringUTF8(XMLContent);
file.CloseFile();
}
}
}
void OpenXmlPackage::SaveToFile( const std::wstring& outputDir, const std::wstring& fileName, const void* buf, unsigned int size )
{
if ( buf != NULL )
{
int fileHandle = 0;
unsigned bytesWritten = 0;
std::wstring pathFileName = outputDir + FILE_SEPARATOR_STR + fileName;
NSFile::CFileBinary file;
if (file.CreateFileW(pathFileName))
{
file.WriteFile( (BYTE*)buf, size );
file.CloseFile();
}
}
}
bool OpenXmlPackage::SaveEmbeddedObject( const std::wstring& fileName, const OleObjectFileStructure& object )
{
if (object.bNativeOnly)
{
POLE::Storage * storageOut = new POLE::Storage(fileName.c_str());
if ( (storageOut) && (storageOut->open(true, true)))
{
_UINT32 zero = 0, str_size = 0;
//Ole
BYTE dataOleInfo[] = {0x01,0x00,0x00,0x02,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
POLE::Stream oStream3(storageOut, L"\001Ole", true, 20);
oStream3.write(dataOleInfo, 20);
oStream3.flush();
//CompObj
BYTE dataCompObjHeader[28] = {0x01,0x00,0xfe,0xff,0x03,0x0a,0x00,0x00,0xff,0xff,0xff,0xff
,0x30,0x08,0x02
//,0x0a,0x00,0x03
,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46};
POLE::Stream oStream1(storageOut, L"\001CompObj", true, 28 + (object.clsid.length() + 5) +
(object.clsid.length() + 5) +
(object.clsid.length() + 5) + 4 * 4);
oStream1.write(dataCompObjHeader, 28);
str_size = object.clsid.length() + 1;
oStream1.write((BYTE*)&str_size, 4);
oStream1.write((BYTE*)object.clsid.c_str(), object.clsid.length());
oStream1.write((BYTE*)&zero, 1);
str_size = object.clsid.length() + 1;
oStream1.write((BYTE*)&str_size, 4);
oStream1.write((BYTE*)object.clsid.c_str(), object.clsid.length());
oStream1.write((BYTE*)&zero, 1);
str_size = object.clsid.length() + 1;
oStream1.write((BYTE*)&str_size, 4);
oStream1.write((BYTE*)object.clsid.c_str(), object.clsid.length());
oStream1.write((BYTE*)&zero, 1);
_UINT32 nUnicodeMarker = 0x71B239F4;
oStream1.write((BYTE*)&nUnicodeMarker, 4);
oStream1.write((BYTE*)&zero, 4); // UnicodeUserType
oStream1.write((BYTE*)&zero, 4); // UnicodeClipboardFormat
oStream1.write((BYTE*)&zero, 4); //
oStream1.flush();
//ObjInfo
BYTE dataObjInfo[] = {0x00,0x00,0x03,0x00,0x01,0x00};//{0x00,0x00,0x03,0x00,0x0D,0x00};
POLE::Stream oStream2(storageOut, L"\003ObjInfo", true, 6);
oStream2.write(dataObjInfo, 6);
oStream2.flush();
//Ole10Native
size_t nativeDataSize = object.data.second;
POLE::Stream streamData(storageOut, L"\001Ole10Native", true, nativeDataSize + 4);
streamData.write((BYTE*)&nativeDataSize, 4);
streamData.write((BYTE*)object.data.first.get(), nativeDataSize);
streamData.flush();
storageOut->close();
delete storageOut;
}
}
else
{
NSFile::CFileBinary file;
file.CreateFileW(fileName);
file.WriteFile((BYTE*)object.data.first.get(), (_UINT32)object.data.second);
file.CloseFile();
}
return true;
}
bool OpenXmlPackage::SaveOLEObject( const std::wstring& fileName, const OleObjectFileStructure& object )
{
if (docFile == NULL) return false;
POLE::Storage *storageOut = new POLE::Storage(fileName.c_str());
if (storageOut == NULL) return false;
if (storageOut->open(true, true)==false)
{
delete storageOut;
return false;
}
POLE::Storage *storageInp = docFile->GetStorage()->GetStorage();
{
POLE::Stream* oleStorage = new POLE::Stream(storageInp, object.objectID);
if (oleStorage)
{
std::wstring path = L"ObjectPool/" + object.objectID;
std::list<std::wstring> entries = storageInp->entries_with_prefix(path);
for (std::list<std::wstring>::iterator it = entries.begin(); it != entries.end(); ++it)
{
std::wstring stream_name_open = (*it);
std::wstring stream_name_create = (*it);
if (stream_name_open[0] < 32)
stream_name_open = stream_name_open.substr(1);
POLE::Stream *stream_inp = new POLE::Stream(storageInp, path + L"/"+ stream_name_open);
if (stream_inp == NULL)continue;
POLE::uint64 size = stream_inp->size();
POLE::Stream *stream_out = new POLE::Stream(storageOut, stream_name_create, true, size);
if (stream_out)
{
unsigned char* buffer = new unsigned char[size];
if (buffer)
{
stream_inp->read(buffer,size);
stream_out->write(buffer,size);
delete []buffer;
}
}
stream_out->flush();
delete stream_inp;
delete stream_out;
}
}
}
storageOut->close();
delete storageOut;
return true;
}
void OpenXmlPackage::RegisterDocPr()
{
AddPart( L"docProps", L"app.xml", DocPrContentTypes::App, L"");
AddPart( L"docProps", L"core.xml", DocPrContentTypes::Core, L"");
}
void OpenXmlPackage::RegisterDocument()
{
AddPart( L"word", L"document.xml", WordprocessingMLContentTypes::MainDocument, L"");
}
void OpenXmlPackage::RegisterDocumentMacros()
{
AddPart( L"word", L"document.xml", WordprocessingMLContentTypes::MainDocumentMacro, L"");
}
int OpenXmlPackage::RegisterVbaProject()
{
return AddPart( L"word", L"vbaProject.bin", MicrosoftWordContentTypes::VbaProject, OpenXmlRelationshipTypes::VbaProject );
}
int OpenXmlPackage::RegisterFontTable()
{
return AddPart( L"word", L"fontTable.xml", WordprocessingMLContentTypes::FontTable, OpenXmlRelationshipTypes::FontTable );
}
int OpenXmlPackage::RegisterNumbering()
{
return AddPart( L"word", L"numbering.xml", WordprocessingMLContentTypes::Numbering, OpenXmlRelationshipTypes::Numbering );
}
int OpenXmlPackage::RegisterSettings()
{
return AddPart( L"word", L"settings.xml", WordprocessingMLContentTypes::Settings, OpenXmlRelationshipTypes::Settings );
}
int OpenXmlPackage::RegisterStyleSheet()
{
return AddPart( L"word", L"styles.xml", WordprocessingMLContentTypes::Styles, OpenXmlRelationshipTypes::Styles );
}
int OpenXmlPackage::RegisterHeader()
{
HeaderRelationshipsFiles.push_back( RelationshipsFile( ( std::wstring( L"word/_rels/header") + FormatUtils::IntToWideString( ++_headerCounter ) + std::wstring( L".xml.rels" ) ) ) );
return AddPart( L"word", ( std::wstring( L"header") + FormatUtils::IntToWideString( _headerCounter ) + std::wstring( L".xml" ) ), WordprocessingMLContentTypes::Header, OpenXmlRelationshipTypes::Header );
}
int OpenXmlPackage::AddHeaderPart( const std::wstring& fileName, const std::wstring& relationshipType, const std::wstring& targetMode )
{
int relID = 0;
if ( !HeaderRelationshipsFiles.empty() )
{
HeaderRelationshipsFiles.back().Relationships.push_back( Relationship( ( std::wstring( L"rId") + FormatUtils::IntToWideString( ++HeaderRelationshipsFiles.back().RelID ) ), relationshipType, fileName, targetMode ) );
relID = HeaderRelationshipsFiles.back().RelID;
}
return relID;
}
int OpenXmlPackage::RegisterFooter()
{
FooterRelationshipsFiles.push_back( RelationshipsFile( ( std::wstring( L"word/_rels/footer" ) + FormatUtils::IntToWideString( ++_footerCounter ) + std::wstring( L".xml.rels" ) ) ) );
return AddPart( L"word", ( std::wstring( L"footer" ) + FormatUtils::IntToWideString( _footerCounter ) + std::wstring( L".xml") ), WordprocessingMLContentTypes::Footer, OpenXmlRelationshipTypes::Footer );
}
int OpenXmlPackage::AddFooterPart( const std::wstring& fileName, const std::wstring& relationshipType, const std::wstring& targetMode )
{
int relID = 0;
if ( !FooterRelationshipsFiles.empty() )
{
FooterRelationshipsFiles.back().Relationships.push_back( Relationship( ( std::wstring( L"rId" ) + FormatUtils::IntToWideString( ++FooterRelationshipsFiles.back().RelID ) ), relationshipType, fileName, targetMode ) );
relID = FooterRelationshipsFiles.back().RelID;
}
return relID;
}
int OpenXmlPackage::RegisterFootnotes()
{
return AddPart( L"word", L"footnotes.xml", WordprocessingMLContentTypes::Footnotes, OpenXmlRelationshipTypes::Footnotes );
}
int OpenXmlPackage::AddFootnotesPart( const std::wstring& fileName, const std::wstring& relationshipType, const std::wstring& targetMode )
{
FootnotesRelationshipsFile.Relationships.push_back( Relationship( ( std::wstring( L"rId" ) + FormatUtils::IntToWideString( ++FootnotesRelationshipsFile.RelID ) ), relationshipType, fileName, targetMode ) );
return FootnotesRelationshipsFile.RelID;
}
int OpenXmlPackage::RegisterEndnotes()
{
return AddPart( L"word", L"endnotes.xml", WordprocessingMLContentTypes::Endnotes, OpenXmlRelationshipTypes::Endnotes );
}
int OpenXmlPackage::AddEndnotesPart( const std::wstring& fileName, const std::wstring& relationshipType, const std::wstring& targetMode )
{
EndnotesRelationshipsFile.Relationships.push_back( Relationship( ( std::wstring( L"rId" ) + FormatUtils::IntToWideString( ++EndnotesRelationshipsFile.RelID ) ), relationshipType, fileName, targetMode ) );
return EndnotesRelationshipsFile.RelID;
}
int OpenXmlPackage::RegisterComments()
{
return AddPart( L"word", L"comments.xml", WordprocessingMLContentTypes::Comments, OpenXmlRelationshipTypes::Comments );
}
int OpenXmlPackage::RegisterCommentsExtended()
{
return AddPart( L"word", L"commentsExtended.xml", WordprocessingMLContentTypes::CommentsExtended, OpenXmlRelationshipTypes::CommentsExtended );
}
int OpenXmlPackage::AddCommentsPart( const std::wstring& fileName, const std::wstring& relationshipType, const std::wstring& targetMode )
{
CommentsRelationshipsFile.Relationships.push_back( Relationship( ( std::wstring( L"rId" ) + FormatUtils::IntToWideString( ++CommentsRelationshipsFile.RelID ) ), relationshipType, fileName, targetMode ) );
return CommentsRelationshipsFile.RelID;
}
int OpenXmlPackage::AddNumberingPart( const std::wstring& fileName, const std::wstring& relationshipType, const std::wstring& targetMode )
{
NumberingRelationshipsFile.Relationships.push_back( Relationship( ( std::wstring( L"rId" ) + FormatUtils::IntToWideString( ++NumberingRelationshipsFile.RelID ) ), relationshipType, fileName, targetMode ) );
return NumberingRelationshipsFile.RelID;
}
void OpenXmlPackage::WriteRelsFile( const RelationshipsFile& relationshipsFile )
{
if ( !relationshipsFile.Relationships.empty() )
{
XMLTools::CStringXmlWriter writer;
writer.WriteNodeBegin( L"Relationships", TRUE );
//write namespaces
writer.WriteAttribute( L"xmlns", OpenXmlNamespaces::RelationshipsPackage );
writer.WriteNodeEnd( L"", TRUE, FALSE );
for ( std::vector<Relationship>::const_iterator iter = relationshipsFile.Relationships.begin(); iter != relationshipsFile.Relationships.end(); iter++ )
{
writer.WriteNodeBegin( L"Relationship", TRUE );
writer.WriteAttribute( L"Id", iter->Id );
writer.WriteAttribute( L"Type", iter->Type );
writer.WriteAttribute( L"Target", iter->Target );
if ( !iter->TargetMode.empty() )
{
writer.WriteAttribute( L"TargetMode", iter->TargetMode );
}
writer.WriteNodeEnd( L"", TRUE );
}
writer.WriteNodeEnd( L"Relationships" );
std::wstring pathFileName = m_strOutputPath + FILE_SEPARATOR_STR + relationshipsFile.FileName;
writer.SaveToFile(pathFileName, TRUE);
}
}
void OpenXmlPackage::WriteContentTypesFile( const ContentTypesFile& contentTypesFile )
{
XMLTools::CStringXmlWriter writer;
// write content types
writer.WriteNodeBegin( L"Types", TRUE );
//write namespaces
writer.WriteAttribute( L"xmlns", OpenXmlNamespaces::ContentTypes );
writer.WriteNodeEnd( L"", TRUE, FALSE );
for ( std::map<std::wstring, std::wstring>::iterator iter = DocumentContentTypesFile._defaultTypes.begin(); iter != DocumentContentTypesFile._defaultTypes.end(); iter++ )
{
writer.WriteNodeBegin( L"Default", TRUE );
writer.WriteAttribute( L"Extension", iter->first );
writer.WriteAttribute( L"ContentType", DocumentContentTypesFile._defaultTypes[iter->first] );
writer.WriteNodeEnd( L"", TRUE );
}
for ( std::map<std::wstring, std::wstring>::iterator iter = DocumentContentTypesFile._partOverrides.begin(); iter != DocumentContentTypesFile._partOverrides.end(); iter++ )
{
writer.WriteNodeBegin( L"Override", TRUE );
writer.WriteAttribute( L"PartName", iter->first );
writer.WriteAttribute( L"ContentType", DocumentContentTypesFile._partOverrides[iter->first] );
writer.WriteNodeEnd( L"", TRUE );
}
writer.WriteNodeEnd( L"Types" );
std::wstring pathFileName = m_strOutputPath + FILE_SEPARATOR_STR + L"[Content_Types].xml" ;
writer.SaveToFile(pathFileName, TRUE);
}
int OpenXmlPackage::RegisterImage(const IMapping* mapping, Global::BlipType blipType)
{
std::wstring fileName = ( std::wstring( L"media/image" ) + FormatUtils::IntToWideString( ++_imageCounter ) + VMLPictureMapping::GetTargetExt( blipType ) );
DocumentContentTypesFile._defaultTypes.insert( std::make_pair( VMLPictureMapping::GetTargetExt( blipType ).erase( 0, 1 ), VMLPictureMapping::GetContentType( blipType ) ) );
DocumentContentTypesFile._defaultTypes.insert( std::make_pair( L"vml", std::wstring( OpenXmlContentTypes::Vml ) ));
return AddPart( mapping, L"word", fileName, VMLPictureMapping::GetContentType( blipType ), OpenXmlRelationshipTypes::Image );
}
int OpenXmlPackage::RegisterHyperlink(const IMapping* mapping, const std::wstring& link)
{
return AddPart(mapping, L"", link, L"", OpenXmlRelationshipTypes::Hyperlink, L"External");
}
int OpenXmlPackage::RegisterOLEObject(const IMapping* mapping, const std::wstring& objectType)
{
std::wstring fileName = ( std::wstring( L"embeddings/oleObject" ) + FormatUtils::IntToWideString( ++_oleCounter ) + OleObjectMapping::GetTargetExt(objectType));
DocumentContentTypesFile._defaultTypes.insert( std::make_pair( OleObjectMapping::GetTargetExt( objectType ).erase( 0, 1 ), OleObjectMapping::GetContentType(objectType)));
return AddPart( mapping, L"word", fileName, OleObjectMapping::GetContentType( objectType ), OpenXmlRelationshipTypes::OleObject );
}
int OpenXmlPackage::RegisterPackage(const IMapping* mapping, const std::wstring& objectType)
{
std::wstring fileName = ( std::wstring( L"embeddings/oleObject") + FormatUtils::IntToWideString( ++_oleCounter ) + OleObjectMapping::GetTargetExt(objectType));
DocumentContentTypesFile._defaultTypes.insert( std::make_pair( OleObjectMapping::GetTargetExt( objectType ).erase( 0, 1 ), OleObjectMapping::GetContentType(objectType)));
return AddPart( mapping, L"word", fileName, OleObjectMapping::GetContentType( objectType ), OpenXmlRelationshipTypes::Package);
}
int OpenXmlPackage::RegisterExternalOLEObject(const IMapping* mapping, const std::wstring& objectType, const std::wstring& uri)
{
std::wstring fullUri = std::wstring(L"file:///") + uri;
std::wstring fileName = ReplaceString(fullUri, L" ", L"%20");
DocumentContentTypesFile._defaultTypes.insert(std::make_pair(OleObjectMapping::GetTargetExt(objectType).erase(0, 1), OleObjectMapping::GetContentType(objectType)));
return AddPart(mapping, L"", fileName, OleObjectMapping::GetContentType(objectType), OpenXmlRelationshipTypes::OleObject, L"External");
}
int OpenXmlPackage::AddPart( const std::wstring& packageDir, const std::wstring& fileName, const std::wstring& contentType, const std::wstring& relationshipType, const std::wstring& targetMode )
{
if (( contentType != L"" ) &&
( contentType != OpenXmlContentTypes::Xml ) &&
( contentType != OpenXmlContentTypes::MSWordDocx ) &&
( contentType != OpenXmlContentTypes::OleObject ) &&
( contentType != OpenXmlContentTypes::MSExcel ) &&
( contentType != OpenXmlContentTypes::MSWord ) &&
( contentType != OpenXmlContentTypes::MSPowerpoint ) )
{
std::wstring partOverride;
if (packageDir != std::wstring ( L"") )
{
partOverride = std::wstring ( L"/" ) + packageDir + std::wstring( L"/");
}
partOverride += fileName;
DocumentContentTypesFile._partOverrides.insert( make_pair( partOverride, contentType ) );
}
if ( relationshipType != L"" )
{
DocumentRelationshipsFile.Relationships.push_back( Relationship( L"rId" + FormatUtils::IntToWideString( ++relID ), relationshipType, fileName, targetMode ) );
}
return relID;
}
int OpenXmlPackage::AddPart( const IMapping* mapping, const std::wstring& packageDir, const std::wstring& fileName, const std::wstring& contentType, const std::wstring& relationshipType, const std::wstring& targetMode )
{
int relID = 0;
if ( mapping != NULL )
{
if ( typeid(*mapping) == typeid(MainDocumentMapping) )
{
relID = AddPart( packageDir, fileName, contentType, relationshipType, targetMode );
}
else if ( typeid(*mapping) == typeid(HeaderMapping) )
{
relID = AddHeaderPart( fileName, relationshipType, targetMode );
}
else if ( typeid(*mapping) == typeid(FooterMapping) )
{
relID = AddFooterPart( fileName, relationshipType, targetMode );
}
else if ( typeid(*mapping) == typeid(FootnotesMapping) )
{
relID = AddFootnotesPart( fileName, relationshipType, targetMode );
}
else if ( typeid(*mapping) == typeid(EndnotesMapping) )
{
relID = AddEndnotesPart( fileName, relationshipType, targetMode );
}
else if ( typeid(*mapping) == typeid(CommentsMapping) )
{
relID = AddCommentsPart( fileName, relationshipType, targetMode );
}
else if ( typeid(*mapping) == typeid(NumberingMapping) )
{
relID = AddNumberingPart( fileName, relationshipType, targetMode );
}
}
return relID;
}
}