/* * (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 * */ #pragma once #include "../Drawing/Document.h" #include "../../../OOXML/Binary/Presentation/DefaultNotesMaster.h" #include "../../../OOXML/Binary/Presentation/DefaultNotesTheme.h" #include "../../../OOXML/PPTXFormat/NotesMaster.h" #include "../../../OOXML/PPTXFormat/SlideMaster.h" #include "../../../OOXML/PPTXFormat/HandoutMaster.h" #include "TableWriter.h" #include "../Reader/PPTDocumentInfo.h" #include "ShapeWriter.h" #include "StylesWriter.h" #include "Converter.h" #include "../Converter/timing.h" #include "../Converter/Animation/AnimationParser.h" #include "../Converter/transition.h" #include "../../Common/Utils/simple_xml_writer.h" #include "../Reader/RoundTripExtractor.h" #include "../../../DesktopEditor/common/Directory.h" #include "../../../DesktopEditor/common/SystemUtils.h" #include #include #include typedef boost::uuids::detail::md5 MD5; namespace PPT { static std::string md5(const BYTE* pData, const ULONG dataLen) { std::string strHash; boost::uuids::detail::md5 hash; boost::uuids::detail::md5::digest_type digest; hash.process_bytes(pData, dataLen); hash.get_digest(digest); const auto charDigest = reinterpret_cast(&digest); boost::algorithm::hex(charDigest, charDigest + sizeof(boost::uuids::detail::md5::digest_type), std::back_inserter(strHash)); return strHash; } namespace NSPPTXWriterConst { static std::wstring g_string_rels_presentation = L"\ \ \ \ \ "; static std::wstring g_string_core = L"\ \ Slide 1\ 1\ "; } CPPTXWriter::CPPTXWriter(const std::wstring& destPath) : m_strDestPath(destPath) { m_pDocument = NULL; m_pUserInfo = NULL; m_pShapeWriter = new CShapeWriter(); } CPPTXWriter::~CPPTXWriter() { RELEASEOBJECT(m_pShapeWriter); } void CPPTXWriter::CreateFile(CPPTUserInfo* pUserInfo) { m_pUserInfo = pUserInfo; m_pDocument = dynamic_cast(pUserInfo); m_oManager.Clear(); m_oManager.SetDstMedia(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"media" + FILE_SEPARATOR_STR); m_oManager.SetDstEmbeddings(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"embeddings" + FILE_SEPARATOR_STR); m_oManager.SetTempMedia(m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); m_pShapeWriter->InitNextId(); NSDirectory::CreateDirectory(m_strDestPath); NSFile::CFileBinary oFile; std::wstring strMemory; // _rels NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"_rels"); oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L".rels"); strMemory = NSPPTXWriterConst::g_string_rels_presentation; oFile.WriteStringUTF8(strMemory); oFile.CloseFile(); // docProps NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"docProps"); // core oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + L"core.xml"); if (m_xmlCore.empty()) m_xmlCore = NSPPTXWriterConst::g_string_core; oFile.WriteStringUTF8(m_xmlCore); oFile.CloseFile(); // app oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + L"app.xml"); WriteApp(oFile); oFile.CloseFile(); // content types WriteContentTypes(); // ppt NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"ppt"); WritePresInfo(); WriteAll(); } void CPPTXWriter::CreateFile(CDocument* pDocument) { m_pDocument = pDocument; m_oManager.Clear(); m_oManager.SetDstMedia(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"media" + FILE_SEPARATOR_STR); m_oManager.SetDstEmbeddings(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"embeddings" + FILE_SEPARATOR_STR); m_pShapeWriter->InitNextId(); NSDirectory::CreateDirectory(m_strDestPath); NSFile::CFileBinary oFile; std::wstring strMemory; // _rels NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"_rels"); oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L".rels"); strMemory = NSPPTXWriterConst::g_string_rels_presentation; oFile.WriteStringUTF8(strMemory); oFile.CloseFile(); // docProps NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"docProps"); // core oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + L"core.xml"); strMemory = NSPPTXWriterConst::g_string_core; oFile.WriteStringUTF8(strMemory); oFile.CloseFile(); // app oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + L"app.xml"); WriteApp(oFile); oFile.CloseFile(); // content types WriteContentTypes(); // ppt NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"ppt"); WritePresInfo(); WriteAll(); } void CPPTXWriter::CloseFile() { m_oManager.Clear(); } void CPPTXWriter::WriteContentTypes() { std::wstring strContentTypes = L"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "; if (m_pDocument->m_bMacroEnabled) { strContentTypes += L"\ "; } else { strContentTypes += L""; } strContentTypes += L"\ \ \ \ "; int nIndexLayout = 1, nIndexTheme = 1; for (size_t nT = 0; nT < m_pDocument->m_arThemes.size(); nT++, nIndexTheme++) { strContentTypes += L""; strContentTypes += L""; for (size_t nL = 0; nL < m_pDocument->m_arThemes[nT]->m_arLayouts.size(); nL++, nIndexLayout++) { strContentTypes += L""; } } if (m_pDocument->m_pNotesMaster) { strContentTypes += L""; strContentTypes += L""; } if (m_pDocument->m_pHandoutMaster) { strContentTypes += L""; strContentTypes += L""; } for (size_t nS = 0; nS < m_pDocument->m_arSlides.size(); ++nS) { strContentTypes += L""; } for (size_t nS = 0; nS < m_pDocument->m_arNotes.size(); ++nS) { strContentTypes += L""; } strContentTypes += L""; NSFile::CFileBinary oFile; oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"[Content_Types].xml"); oFile.WriteStringUTF8(strContentTypes); oFile.CloseFile(); } void CPPTXWriter::WriteApp(NSFile::CFileBinary& oFile) { if (m_xmlApp.empty()) { std::wstringstream strm; CP_XML_WRITER(strm) { CP_XML_NODE(L"Properties") { CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"); CP_XML_ATTR(L"xmlns:vt", L"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"); CP_XML_NODE(L"TotalTime") { CP_XML_STREAM() << 0; } CP_XML_NODE(L"Words") { CP_XML_STREAM() << 0; } std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); if (sApplication.empty()) sApplication = NSSystemUtils::gc_EnvApplicationNameDefault; #if defined(INTVER) std::string s = VALUE2STR(INTVER); sApplication += L"/" + std::wstring(s.begin(), s.end()); #endif CP_XML_NODE(L"Application") { CP_XML_STREAM() << sApplication; } //CP_XML_NODE(L"AppVersion") //{ // CP_XML_STREAM() << L"1.0"; //} CP_XML_NODE(L"Paragraphs") { CP_XML_STREAM() << 0; } CP_XML_NODE(L"PresentationFormat") { CP_XML_STREAM() << L"On-screen Show (4:3)"; } CP_XML_NODE(L"Slides") { CP_XML_STREAM() << m_pDocument->m_arSlides.size(); } CP_XML_NODE(L"Notes") { CP_XML_STREAM() << m_pDocument->m_arNotes.size(); } CP_XML_NODE(L"HiddenSlides") { CP_XML_STREAM() << 0; } CP_XML_NODE(L"MMClips") { CP_XML_STREAM() << 0; } CP_XML_NODE(L"ScaleCrop") { CP_XML_STREAM() << L"false"; } CP_XML_NODE(L"HeadingPairs") { CP_XML_NODE(L"vt:vector") { CP_XML_ATTR(L"size", 4); CP_XML_ATTR(L"baseType", L"variant"); CP_XML_NODE(L"vt:variant") { CP_XML_NODE(L"vt:lpstr") { CP_XML_STREAM() << L"Theme"; } } CP_XML_NODE(L"vt:variant") { CP_XML_NODE(L"vt:i4") { CP_XML_STREAM() << m_pDocument->m_arThemes.size(); } } CP_XML_NODE(L"vt:variant") { CP_XML_NODE(L"vt:lpstr") { CP_XML_STREAM() << L"Slide Titles"; } } CP_XML_NODE(L"vt:variant") { CP_XML_NODE(L"vt:i4") CP_XML_STREAM() << m_pDocument->m_arSlides.size(); } } } CP_XML_NODE(L"TitlesOfParts") { CP_XML_NODE(L"vt:vector") { CP_XML_ATTR(L"size", m_pDocument->m_arSlides.size() + m_pDocument->m_arThemes.size()); CP_XML_ATTR(L"baseType", L"lpstr"); for (size_t i = 1; i <= m_pDocument->m_arThemes.size(); ++i) { CP_XML_NODE(L"vt:lpstr") { CP_XML_STREAM() << L"Theme " << i; } } for (size_t i = 1; i <= m_pDocument->m_arSlides.size(); ++i) { CP_XML_NODE(L"vt:lpstr") { CP_XML_STREAM() << L"Slide " << i; } } } } //CP_XML_NODE(L"Company"); CP_XML_NODE(L"LinksUpToDate") { CP_XML_STREAM() << L"false"; } CP_XML_NODE(L"SharedDoc") { CP_XML_STREAM() << L"false"; } CP_XML_NODE(L"HyperlinksChanged") { CP_XML_STREAM() << L"false"; } } } m_xmlApp = strm.str(); } oFile.WriteStringUTF8(L""); oFile.WriteStringUTF8(m_xmlApp); } void CPPTXWriter::WritePresInfo() { NSFile::CFileBinary oFile; // tableStyles.xml oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"tableStyles.xml"); oFile.WriteStringUTF8(L"\ "); oFile.CloseFile(); // presProps.xml oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"presProps.xml"); oFile.WriteStringUTF8(L"\ \ \ \ \ \ "); oFile.CloseFile(); // viewProps.xml oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"viewProps.xml"); oFile.WriteStringUTF8(L"\ \ \ \ \ "); oFile.CloseFile(); // presentation.xml + _rels/presentation.xml.rels std::wstring strPresRels; std::wstring strPresMasters; std::wstring strPresSlides; std::wstring strNotesIDs; std::wstring strHandoutIDs; size_t nCountLayouts = 0; for (size_t nIndexTheme = 0; nIndexTheme < m_pDocument->m_arThemes.size(); ++nIndexTheme) { strPresRels += L""; strPresRels += L""; strPresMasters += L""; nCountLayouts += m_pDocument->m_arThemes[nIndexTheme]->m_arLayouts.size(); nCountLayouts += 1; } int nCurrentRels = (int)(2 * m_pDocument->m_arThemes.size() + 1); if (m_pDocument->m_pNotesMaster) { strNotesIDs = L""; strPresRels += L""; ++nCurrentRels; } if (m_pDocument->m_pHandoutMaster) { strHandoutIDs = L""; strPresRels += L""; ++nCurrentRels; } for (size_t nIndexSlide = 0; nIndexSlide < m_pDocument->m_arSlides.size(); ++nIndexSlide, ++nCurrentRels) { strPresRels += L""; strPresSlides += L""; } strPresRels += L""; strPresRels += L""; strPresRels += L""; if (m_pDocument->m_bMacroEnabled) { std::wstring strVbaProject = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"vbaProject.bin"; if (CDirectory::CopyFile(m_pDocument->m_sVbaProjectFile, strVbaProject)) { strPresRels += L""; } } strPresRels = L"" + strPresRels + L""; std::wstring strPptRels = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"_rels"; NSDirectory::CreateDirectory(strPptRels); oFile.CreateFileW(strPptRels + FILE_SEPARATOR_STR + L"presentation.xml.rels"); oFile.WriteStringUTF8(strPresRels); oFile.CloseFile(); std::wstring strSizePres = L"m_lSlideWidth) + L"\" cy=\"" + std::to_wstring(m_pDocument->m_lSlideHeight) + L"\" type=\"screen4x3\" />m_lNotesWidth) + L"\" cy=\"" + std::to_wstring(m_pDocument->m_lNotesHeight) + L"\"/>"; std::wstring strDefaultTextStyle = L""; if (false == m_pDocument->m_arThemes.empty()) { CStylesWriter styleWriter(m_pDocument->m_arThemes[0].get()); strDefaultTextStyle += styleWriter.ConvertStyles(m_pDocument->m_arThemes[0]->m_pStyles[0], 9); } strDefaultTextStyle += L""; std::wstring strPres = L""; strPres += L"m_bRtl)) { strPres += L" rtl=\"1\""; } strPres += L">"; strPres += L"" + strPresMasters + L""; strPres += strNotesIDs; strPres += strHandoutIDs; strPres += L"" + strPresSlides + L""; strPres += strSizePres; strPres += strDefaultTextStyle; strPres += L""; oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"presentation.xml"); oFile.WriteStringUTF8(strPres); oFile.CloseFile(); } void CPPTXWriter::WriteAll() { std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR; NSDirectory::CreateDirectory(strPptDirectory + L"theme"); NSDirectory::CreateDirectory(strPptDirectory + L"slideMasters"); NSDirectory::CreateDirectory(strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + L"_rels"); NSDirectory::CreateDirectory(strPptDirectory + L"slideLayouts"); NSDirectory::CreateDirectory(strPptDirectory + L"slideLayouts" + FILE_SEPARATOR_STR + L"_rels"); NSDirectory::CreateDirectory(strPptDirectory + L"slides"); NSDirectory::CreateDirectory(strPptDirectory + L"slides" + FILE_SEPARATOR_STR + L"_rels"); if (m_pDocument->m_pHandoutMaster) { NSDirectory::CreateDirectory(strPptDirectory + L"handoutMasters"); NSDirectory::CreateDirectory(strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + L"_rels"); } if (m_pDocument->m_pNotesMaster) { NSDirectory::CreateDirectory(strPptDirectory + L"notesMasters"); NSDirectory::CreateDirectory(strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + L"_rels"); } if (!m_pDocument->m_arNotes.empty()) { NSDirectory::CreateDirectory(strPptDirectory + L"notesSlides"); NSDirectory::CreateDirectory(strPptDirectory + L"notesSlides" + FILE_SEPARATOR_STR + L"_rels"); } WriteThemes(); WriteSlides(); WriteNotes(); m_pShapeWriter->SetRelsGenerator(NULL); } // todo reforming and refactoring! void CPPTXWriter::WriteThemes() { int nStartLayout = 0, nIndexTheme = 0; if (HasRoundTrips() && m_pDocument->m_arThemes.size()) { std::unordered_set writedFilesHash; for (const auto& oIterSlide : m_pUserInfo->m_mapMasters) { WriteRoundTripTheme(oIterSlide.second, writedFilesHash, nIndexTheme, nStartLayout); } writedFilesHash.clear(); for (const auto& oIterSlide : m_pUserInfo->m_mapNotesMasters) WriteRoundTripTheme(oIterSlide.second, writedFilesHash, nIndexTheme, nStartLayout); writedFilesHash.clear(); for (const auto& oIterSlide : m_pUserInfo->m_mapHandoutMasters) WriteRoundTripTheme(oIterSlide.second, writedFilesHash, nIndexTheme, nStartLayout); } else { for (size_t i = 0; i < m_pDocument->m_arThemes.size(); i++) { m_pShapeWriter->m_pTheme = m_pDocument->m_arThemes[i].get(); WriteTheme(m_pDocument->m_arThemes[i], nIndexTheme, nStartLayout); m_pShapeWriter->m_pTheme = NULL; } WriteTheme(m_pDocument->m_pNotesMaster, nIndexTheme, nStartLayout); WriteTheme(m_pDocument->m_pHandoutMaster, nIndexTheme, nStartLayout); } } bool CPPTXWriter::HasRoundTrips() const { if (m_pUserInfo == nullptr || m_pUserInfo->m_mapMasters.empty() || m_pUserInfo->m_mapMasters.begin()->second == nullptr) return false; std::vector arrRTTheme; std::vector arrRTLayouts; std::vector arrRTNotes; auto pSlide = m_pUserInfo->m_mapMasters.begin()->second; pSlide->GetRecordsByType(&arrRTLayouts, false, false); pSlide->GetRecordsByType(&arrRTTheme, false, true); pSlide->GetRecordsByType(&arrRTNotes, false, true); if (m_pDocument->m_pNotesMaster && arrRTNotes.empty()) return false; if (m_pDocument->m_pHandoutMaster) { for (const auto& oIterSlide : m_pUserInfo->m_mapHandoutMasters) { std::vector arrRTTheme; oIterSlide.second->GetRecordsByType(&arrRTTheme, false, true); if (arrRTTheme.empty()) return false; } } return arrRTTheme.size() && arrRTLayouts.size(); } bool CPPTXWriter::WriteRoundTripTheme(const CRecordSlide* pSlide, std::unordered_set& writedFilesHash, int& nIndexTheme, int& nStartLayout) { if (!pSlide) return false; // Write Theme CRelsGenerator themeRels(&m_oManager); std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR; std::wstring strThemeDirectory = strPptDirectory + FILE_SEPARATOR + L"theme"; if (nIndexTheme == 0) NSDirectory::CreateDirectory(strThemeDirectory); std::vector arrRTTheme; std::vector arrRTColor; std::vector arrRTLayouts; std::vector arrRTMaster; std::vector arrRTNotes; pSlide->GetRecordsByType(&arrRTLayouts, false, false); pSlide->GetRecordsByType(&arrRTTheme, false, true); pSlide->GetRecordsByType(&arrRTColor, false, true); pSlide->GetRecordsByType(&arrRTMaster, false, true); pSlide->GetRecordsByType(&arrRTNotes, false, true); const int oldThemeSize = m_pDocument->m_arThemes.size(); const unsigned oldThemeIndex = nIndexTheme < oldThemeSize ? nIndexTheme : oldThemeSize - 1; if (arrRTLayouts.size()) m_pShapeWriter->m_pTheme = m_pDocument->m_arThemes[oldThemeIndex].get(); else if (arrRTNotes.size()) m_pShapeWriter->m_pTheme = m_pDocument->m_pNotesMaster.get(); else if (m_pDocument->m_pHandoutMaster.get()) m_pShapeWriter->m_pTheme = m_pDocument->m_pHandoutMaster.get(); if (m_pShapeWriter->m_pTheme == nullptr) return false; auto themeType = m_pShapeWriter->m_pTheme->m_eType; if (arrRTTheme.empty()) return false; RoundTripExtractor extractor(arrRTTheme[0], m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); std::wstring oneThemePathS = std::wstring(L"theme") + FILE_SEPARATOR_STR; std::wstring twoThemePathS = oneThemePathS + std::wstring(L"theme") + FILE_SEPARATOR_STR; auto strThemePath = extractor.getOneFile(twoThemePathS + L"theme1.xml"); if (strThemePath.empty()) return false; auto themeRelsPath = extractor.getOneFile(twoThemePathS + L"_rels" + FILE_SEPARATOR_STR + L"theme1.xml.rels"); auto arrImagesPaths = extractor.find(L".*image[0-9]+.*"); BYTE* utf8Data = NULL; ULONG utf8DataSize = 0; bool wasThemeWrite = false; bool needRels = false; // read file bytes NSFile::CFileBinary::ReadAllBytes(strThemePath, &utf8Data, utf8DataSize); // compare hash char* pointerToThemeElems = strstr((char*)utf8Data, ""); UINT hashShift = pointerToThemeElems ? pointerToThemeElems - (char*)utf8Data : 0; auto strHash = md5(utf8Data + hashShift, utf8DataSize - hashShift); needRels = (int)std::string(utf8Data, utf8Data + utf8DataSize).find("rId") != -1; // cp file with new name or write bytes if (writedFilesHash.find(strHash) == writedFilesHash.end()) { std::wstring strThemeFile = L"theme" + std::to_wstring(++nIndexTheme) + L".xml"; std::wstring outputThemePath = strThemeDirectory + FILE_SEPARATOR_STR + strThemeFile; NSFile::CFileBinary file; file.CreateFileW(outputThemePath); file.WriteFile(utf8Data, utf8DataSize); file.CloseFile(); // clear bytes RELEASEOBJECT(utf8Data); utf8DataSize = 0; writedFilesHash.insert(strHash); wasThemeWrite = true; for (auto& strImagePath : arrImagesPaths) { themeRels.WriteImage(strImagePath); } } // if (wasThemeWrite == false) // return; // write theme _rels if (!themeRelsPath.empty() && needRels) { std::wstring relsFolder = strPptDirectory + L"theme" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR; std::wstring relsName = L"theme" + std::to_wstring(nIndexTheme) + L".xml.rels"; NSDirectory::CreateDirectory(relsFolder); NSFile::CFileBinary::ReadAllBytes(themeRelsPath, &utf8Data, utf8DataSize); NSFile::CFileBinary oFile; oFile.CreateFileW(relsFolder + relsName); oFile.WriteFile(utf8Data, utf8DataSize); oFile.CloseFile(); RELEASEOBJECT(utf8Data); utf8DataSize = 0; } // get slide master ID std::vector arrMasterID; pSlide->GetRecordsByType(&arrMasterID, false, true); // Write layouts if (themeType == _typeMaster::typeMaster) { std::wstring strOutputLayoutsPath = strPptDirectory + FILE_SEPARATOR_STR + L"slideLayouts" + FILE_SEPARATOR_STR; std::wstring strOutputRelsLayoutsPath = strOutputLayoutsPath + L"_rels" + FILE_SEPARATOR_STR; if (nIndexTheme == 1) { NSDirectory::CreateDirectory(strOutputLayoutsPath); NSDirectory::CreateDirectory(strOutputRelsLayoutsPath); } } // Write Masters if (wasThemeWrite) { CStringWriter oWriter; CRelsGenerator oRels(&m_oManager); int nCountLayouts = m_pShapeWriter->m_pTheme->m_arLayouts.size(); oRels.StartMaster(nIndexTheme - 1, nStartLayout, nCountLayouts); auto* pTheme = m_pShapeWriter->m_pTheme; oWriter.WriteString(L""); if (pTheme->m_eType == typeMaster) { oWriter.WriteString(L""); } else if (pTheme->m_eType == typeNotesMaster) { oWriter.WriteString(L""); } else if (pTheme->m_eType == typeHandoutMaster) { oWriter.WriteString(L""); } oWriter.WriteString(L""); if (pTheme->m_bIsBackground) { WriteBackground(oWriter, oRels, pTheme->m_oBackground); } oWriter.WriteString(L"\ "); CGroupElement* pGroupElement = !pTheme->m_arElements.empty() ? dynamic_cast(pTheme->m_arElements[0].get()) : NULL; size_t start_index = 0; if (pGroupElement) { for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) { if (isBodyPlaceholder(pGroupElement->m_pChildElements[i]->m_lPlaceholderType)) pGroupElement->m_pChildElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! //if (pGroupElement->m_pChildElements[i]->m_bAnchorEnabled == false && // pGroupElement->m_pChildElements[i]->m_bChildAnchorEnabled == false) // continue; //if (pTheme->m_eType == typeNotesMaster) //{ // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; //} //else if (pTheme->m_eType == typeHandoutMaster) //{ // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; // pGroupElement->m_pChildElements[i]->m_lPlaceholderSizePreset = -1; //} WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); } start_index = 1; } for (size_t i = start_index; i < pTheme->m_arElements.size(); ++i) { if (isBodyPlaceholder(pTheme->m_arElements[i]->m_lPlaceholderType)) pTheme->m_arElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! //if (pTheme->m_arElements[i]->m_bAnchorEnabled == false && // pTheme->m_arElements[i]->m_bChildAnchorEnabled == false) // continue; //if (pTheme->m_eType == typeNotesMaster) //{ // pTheme->m_arElements[i]->m_lPlaceholderID = -1; //} //else if (pTheme->m_eType == typeHandoutMaster) //{ // pTheme->m_arElements[i]->m_lPlaceholderID = -1; // pTheme->m_arElements[i]->m_lPlaceholderSizePreset = -1; //} WriteElement(oWriter, oRels, pTheme->m_arElements[i]); } oWriter.WriteString(std::wstring(L"")); // std::wstring strOverrideColorScheme = L""); oWriter.WriteString(arrRTColor[0]->getPClrMap()); if (pTheme->m_eType == typeMaster) { oWriter.WriteString(std::wstring(L"")); for (int nIndexLayout = 0; nIndexLayout < nCountLayouts; ++nIndexLayout) { const unsigned sldLayoutId = 0x80000000 + nIndexTheme + nStartLayout + nIndexLayout; oWriter.WriteString(L""); WriteLayout(pTheme->m_arLayouts[nIndexLayout], nIndexLayout, nStartLayout, nIndexTheme - 1); } oWriter.WriteString(std::wstring(L"")); } if (pTheme->m_bHasDate || pTheme->m_bHasFooter || pTheme->m_bHasSlideNumber) { oWriter.WriteString(std::wstring(L"m_bHasDate) oWriter.WriteString(std::wstring(L" dt=\"0\"")); if (!pTheme->m_bHasSlideNumber) oWriter.WriteString(std::wstring(L" sldNum=\"0\"")); oWriter.WriteString(std::wstring(L" hdr=\"0\"")); if (!pTheme->m_bHasFooter) oWriter.WriteString(std::wstring(L" ftr=\"0\"")); oWriter.WriteString(std::wstring(L"/>")); } CStylesWriter styleWriter; styleWriter.m_pTheme = pTheme; // inserted roundtrip master // add media here rId if (pTheme->m_eType == typeMaster && arrRTMaster.size()) { RoundTripExtractor extractorMaster(arrRTMaster[0], m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); auto masterPath = extractorMaster.getOneFile(std::wstring(L"drs") + FILE_SEPARATOR_STR + L"slideMasters" + FILE_SEPARATOR_STR + L"slideMaster1.xml"); auto mediaPathes = extractorMaster.find(L".*image[0-9]+.*"); int rIdShift = oRels.getRId() - 1; for (auto& strMediaPath : mediaPathes) { oRels.WriteImage(strMediaPath); } std::wstring utf8strMaster; NSFile::CFileBinary::ReadAllTextUtf8(masterPath, utf8strMaster); auto txStylesIter = utf8strMaster.find(L"m_eType == typeNotesMaster) { oWriter.WriteString(std::wstring(L"")); RoundTripExtractor extractorNotes(arrRTNotes[0], m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); auto masterPath = extractorNotes.getOneFile(std::wstring(L"drs") + FILE_SEPARATOR_STR + L"slideMasters" + FILE_SEPARATOR_STR + L"slideMaster1.xml"); std::wstring utf8strNotes; NSFile::CFileBinary::ReadAllTextUtf8(masterPath, utf8strNotes); auto lvl1pPrIter = utf8strNotes.find(L""); if (lvl1pPrIter != (UINT)-1 && bodyStyleIter != (UINT)-1) oWriter.WriteString(utf8strNotes.substr(lvl1pPrIter, bodyStyleIter - lvl1pPrIter)); oWriter.WriteString(std::wstring(L"")); } std::wstring strSlideMasterFile; std::wstring strSlideMasterRelsFile; if (pTheme->m_eType == typeMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml"; strSlideMasterFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml.rels"; strSlideMasterRelsFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } else if (pTheme->m_eType == typeNotesMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"notesMaster1.xml"; strSlideMasterFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"notesMaster1.xml.rels"; strSlideMasterRelsFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } else if (pTheme->m_eType == typeHandoutMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"handoutMaster1.xml"; strSlideMasterFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"handoutMaster1.xml.rels"; strSlideMasterRelsFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } NSFile::CFileBinary oFile; oFile.CreateFileW(strSlideMasterFile); std::wstring strMaster = oWriter.GetData(); oFile.WriteStringUTF8(strMaster); oFile.CloseFile(); oRels.CloseRels(); oRels.SaveRels(strSlideMasterRelsFile); nStartLayout += nCountLayouts; } m_pShapeWriter->m_pTheme = NULL; return true; } void CPPTXWriter::WriteTheme(CThemePtr pTheme, int& nIndexTheme, int& nStartLayout) { if (!pTheme) return; std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR; std::wstring strThemeFile = L"theme" + std::to_wstring(nIndexTheme + 1) + L".xml"; strThemeFile = strPptDirectory + L"theme" + FILE_SEPARATOR_STR + strThemeFile; NSFile::CFileBinary oFile; oFile.CreateFileW(strThemeFile); CStringWriter oStringWriter; oStringWriter.WriteString(std::wstring(L"m_sThemeName); oStringWriter.WriteString(std::wstring(L"\">")); WriteColorScheme(oStringWriter, L"Default", pTheme->m_arColorScheme); if (!pTheme->m_arFonts.empty()) { oStringWriter.WriteString(std::wstring(L"m_arFonts[0].Name); oStringWriter.WriteString(std::wstring(L"\"/>")); oStringWriter.WriteString(std::wstring(L"m_arFonts.size() > 1) oStringWriter.WriteString(pTheme->m_arFonts[1].Name); else oStringWriter.WriteStringXML(pTheme->m_arFonts[0].Name); } oStringWriter.WriteString(std::wstring(L"\"/>")); oStringWriter.WriteString(std::wstring(L"")); oStringWriter.WriteString(std::wstring(L"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ")); oStringWriter.WriteString(std::wstring(L"")); if (pTheme->m_arExtraColorScheme.size()) { oStringWriter.WriteString(std::wstring(L"")); for (size_t i = 0; i < pTheme->m_arExtraColorScheme.size(); i++) { std::wstring str = L" " + std::to_wstring(i + 1); WriteColorScheme(oStringWriter, pTheme->m_sThemeName + str, pTheme->m_arExtraColorScheme[i], true); //extra } oStringWriter.WriteString(std::wstring(L"")); } else oStringWriter.WriteString(std::wstring(L"")); oStringWriter.WriteString(std::wstring(L"")); oFile.WriteStringUTF8(oStringWriter.GetData()); oFile.CloseFile(); CRelsGenerator oRels(&m_oManager); int nCountLayouts = (int)pTheme->m_arLayouts.size(); oRels.StartMaster(nIndexTheme, nStartLayout, nCountLayouts); CStringWriter oWriter; oWriter.WriteString(L""); if (pTheme->m_eType == typeMaster) { oWriter.WriteString(L""); } else if (pTheme->m_eType == typeNotesMaster) { oWriter.WriteString(L""); } else if (pTheme->m_eType == typeHandoutMaster) { oWriter.WriteString(L""); } oWriter.WriteString(L""); if (pTheme->m_bIsBackground) { WriteBackground(oWriter, oRels, pTheme->m_oBackground); } oWriter.WriteString(L"\ "); CGroupElement* pGroupElement = !pTheme->m_arElements.empty() ? dynamic_cast(pTheme->m_arElements[0].get()) : NULL; size_t start_index = 0; if (pGroupElement) { for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) { if (isBodyPlaceholder(pGroupElement->m_pChildElements[i]->m_lPlaceholderType)) pGroupElement->m_pChildElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! //if (pGroupElement->m_pChildElements[i]->m_bAnchorEnabled == false && // pGroupElement->m_pChildElements[i]->m_bChildAnchorEnabled == false) // continue; //if (pTheme->m_eType == typeNotesMaster) //{ // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; //} //else if (pTheme->m_eType == typeHandoutMaster) //{ // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; // pGroupElement->m_pChildElements[i]->m_lPlaceholderSizePreset = -1; //} WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); } start_index = 1; } for (size_t i = start_index; i < pTheme->m_arElements.size(); ++i) { if (isBodyPlaceholder(pTheme->m_arElements[i]->m_lPlaceholderType)) pTheme->m_arElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! //if (pTheme->m_arElements[i]->m_bAnchorEnabled == false && // pTheme->m_arElements[i]->m_bChildAnchorEnabled == false) // continue; //if (pTheme->m_eType == typeNotesMaster) //{ // pTheme->m_arElements[i]->m_lPlaceholderID = -1; //} //else if (pTheme->m_eType == typeHandoutMaster) //{ // pTheme->m_arElements[i]->m_lPlaceholderID = -1; // pTheme->m_arElements[i]->m_lPlaceholderSizePreset = -1; //} WriteElement(oWriter, oRels, pTheme->m_arElements[i]); } oWriter.WriteString(std::wstring(L"")); std::wstring strOverrideColorScheme = L""; oWriter.WriteString(strOverrideColorScheme); if (pTheme->m_eType == typeMaster) { oWriter.WriteString(std::wstring(L"")); for (int nIndexLayout = 0; nIndexLayout < nCountLayouts; ++nIndexLayout) { oWriter.WriteString(L""); WriteLayout(pTheme->m_arLayouts[nIndexLayout], nIndexLayout, nStartLayout, nIndexTheme); } oWriter.WriteString(std::wstring(L"")); } if (pTheme->m_bHasDate || pTheme->m_bHasFooter || pTheme->m_bHasSlideNumber) { oWriter.WriteString(std::wstring(L"m_bHasDate) oWriter.WriteString(std::wstring(L" dt=\"0\"")); if (!pTheme->m_bHasSlideNumber) oWriter.WriteString(std::wstring(L" sldNum=\"0\"")); oWriter.WriteString(std::wstring(L" hdr=\"0\"")); if (!pTheme->m_bHasFooter) oWriter.WriteString(std::wstring(L" ftr=\"0\"")); oWriter.WriteString(std::wstring(L"/>")); } CStylesWriter styleWriter; styleWriter.m_pTheme = pTheme.get(); if (pTheme->m_eType == typeMaster) { oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); styleWriter.ConvertStyles(pTheme->m_pStyles[2], oWriter, 9); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); styleWriter.ConvertStyles(pTheme->m_pStyles[3], oWriter, 9); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); } else if (pTheme->m_eType == typeNotesMaster) { oWriter.WriteString(std::wstring(L"")); styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); oWriter.WriteString(std::wstring(L"")); } std::wstring strSlideMasterFile; std::wstring strSlideMasterRelsFile; if (pTheme->m_eType == typeMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"slideMaster" + std::to_wstring(nIndexTheme + 1) + L".xml"; strSlideMasterFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"slideMaster" + std::to_wstring(nIndexTheme + 1) + L".xml.rels"; strSlideMasterRelsFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } else if (pTheme->m_eType == typeNotesMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"notesMaster1.xml"; strSlideMasterFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"notesMaster1.xml.rels"; strSlideMasterRelsFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } else if (pTheme->m_eType == typeHandoutMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"handoutMaster1.xml"; strSlideMasterFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"handoutMaster1.xml.rels"; strSlideMasterRelsFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } oFile.CreateFileW(strSlideMasterFile); std::wstring strMaster = oWriter.GetData(); oFile.WriteStringUTF8(strMaster); oFile.CloseFile(); oRels.CloseRels(); oRels.SaveRels(strSlideMasterRelsFile); nStartLayout += nCountLayouts; nIndexTheme++; } void CPPTXWriter::WriteColorScheme(CStringWriter& oStringWriter, const std::wstring& name, const std::vector& colors, bool extra) { if (colors.size() < 1) { oStringWriter.WriteString(L"\ \ \ \ \ "); return; } if (extra) oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); if (extra) { oStringWriter.WriteString(L""); oStringWriter.WriteString(L""); } } void CPPTXWriter::WriteBackground(CStringWriter& oWriter, CRelsGenerator& oRels, CBrush& oBackground) { m_pShapeWriter->SetRelsGenerator(&oRels); std::wstring sBg = m_pShapeWriter->ConvertBrush(oBackground); if (false == sBg.empty()) { oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(sBg); oWriter.WriteString(std::wstring(L"")); } } void CPPTXWriter::WriteGroup(CStringWriter& oWriter, CRelsGenerator& oRels, CElementPtr pElement, CLayout* pLayout) { CGroupElement* pGroupElement = dynamic_cast(pElement.get()); m_pShapeWriter->SetElement(pElement); oWriter.WriteString(m_pShapeWriter->ConvertGroup()); for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); i++) { WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i], pLayout); } oWriter.WriteString(L""); } void CPPTXWriter::WriteTable(CStringWriter& oWriter, CRelsGenerator& oRels, CElementPtr pElement, CLayout* pLayout) { CTableElement* pTableElement = dynamic_cast(pElement.get()); PPTX::Logic::GraphicFrame gf; TableWriter table(pTableElement, &oRels); if (pTableElement->m_xmlRawData.empty()) { table.Convert(gf); oWriter.WriteString(gf.toXML()); } else { oWriter.WriteString(table.getXmlForGraphicFrame(pElement->m_lID, pElement->m_lPlaceholderID)); } } void CPPTXWriter::WriteElement(CStringWriter& oWriter, CRelsGenerator& oRels, CElementPtr pElement, CLayout* pLayout) { if (!pElement) return; CTableElement* pTableElement = dynamic_cast(pElement.get()); if (pTableElement) { return WriteTable(oWriter, oRels, pElement, pLayout); } CGroupElement* pGroupElement = dynamic_cast(pElement.get()); if (pGroupElement) { return WriteGroup(oWriter, oRels, pElement, pLayout); } bool bObject = m_pShapeWriter->SetElement(pElement); if (bObject) { m_pShapeWriter->SetRelsGenerator(&oRels); if (NULL != pLayout) { if (-1 != pElement->m_lPlaceholderType) { size_t nCountElements = pLayout->m_arElements.size(); for (size_t nIndex = 0; nIndex < nCountElements; ++nIndex) { if ((pElement->m_lPlaceholderType == pLayout->m_arElements[nIndex]->m_lPlaceholderType) && (pElement->m_lPlaceholderID == pLayout->m_arElements[nIndex]->m_lPlaceholderID)) { CElementPtr pElLayout = pLayout->m_arElements[nIndex]; bool bIsEqualTransform = ((pElement->m_dRotate == pElLayout->m_dRotate) && (pElement->m_bFlipH == pElLayout->m_bFlipH) && (pElement->m_bFlipV == pElLayout->m_bFlipV)); if (bIsEqualTransform) { if (pElement->m_bAnchorEnabled == pElLayout->m_bAnchorEnabled && pElLayout->m_bAnchorEnabled == true) { if (pElement->m_rcAnchor.IsEqual(pElLayout->m_rcAnchor, 0.5)) pElement->m_bAnchorEnabled = false; } if (pElement->m_bChildAnchorEnabled == pElLayout->m_bChildAnchorEnabled && pElLayout->m_bChildAnchorEnabled == true) { if (pElement->m_rcChildAnchor.IsEqual(pElLayout->m_rcChildAnchor, 0.5)) pElement->m_bChildAnchorEnabled = false; } } break; } } } } oWriter.WriteString(m_pShapeWriter->ConvertShape()); } } void CPPTXWriter::WriteLayout(CLayoutPtr pLayout, int nIndexLayout, int nStartLayout, int nIndexTheme) { if (!pLayout) return; CStringWriter oWriter; CRelsGenerator oRels(&m_oManager); oRels.StartLayout(nIndexTheme); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"m_strLayoutType + L"\""); oWriter.WriteString(std::wstring(L" showMasterSp=\"") + (pLayout->m_bShowMasterShapes ? L"1" : L"0")); oWriter.WriteString(std::wstring(L"\" preserve=\"1\">m_sName.empty() == false) oWriter.WriteString(std::wstring(L" name=\"") + pLayout->m_sName + std::wstring(L"\"")); oWriter.WriteString(std::wstring(L">")); if (pLayout->m_bIsBackground) { WriteBackground(oWriter, oRels, pLayout->m_oBackground); } std::wstring strElems = L"\ "; oWriter.WriteString(strElems); size_t start_index = 0; if (pLayout->m_bIsTitleMaster) { CGroupElement* pGroupElement = (!pLayout->m_arElements.empty()) ? dynamic_cast(pLayout->m_arElements[0].get()) : NULL; if (pGroupElement) { for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) { WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); } start_index = 1; } } for (size_t i = start_index; i < pLayout->m_arElements.size(); ++i) { WriteElement(oWriter, oRels, pLayout->m_arElements[i]); } oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); oRels.CloseRels(); std::wstring strXml = oWriter.GetData(); std::wstring strFile = L"slideLayout" + std::to_wstring(nIndexLayout + nStartLayout + 1) + L".xml"; NSFile::CFileBinary oFile; std::wstring strFileLayoutPath = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"slideLayouts" + FILE_SEPARATOR_STR; oFile.CreateFileW(strFileLayoutPath + strFile); oFile.WriteStringUTF8(strXml); oFile.CloseFile(); strFile = L"slideLayout" + std::to_wstring(nIndexLayout + nStartLayout + 1) + L".xml.rels"; oRels.SaveRels(strFileLayoutPath + L"_rels" + FILE_SEPARATOR_STR + strFile); } void CPPTXWriter::WriteSlide(int nIndexSlide) { CStringWriter oWriter; CRelsGenerator oRels(&m_oManager); CSlide* pSlide = m_pDocument->m_arSlides[nIndexSlide]; if (0 == pSlide->m_lThemeID) oRels.StartSlide(pSlide->m_lLayoutID, pSlide->m_lNotesID); else { int nLayout = pSlide->m_lLayoutID; for (int i = 0; i < pSlide->m_lThemeID; ++i) { nLayout += (int)m_pDocument->m_arThemes[i]->m_arLayouts.size(); } oRels.StartSlide(nLayout, pSlide->m_lNotesID); } m_pShapeWriter->SetRelsGenerator(&oRels); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"m_bShowMasterShapes) oWriter.WriteString(std::wstring(L" showMasterSp=\"0\"")); if (pSlide->m_bHidden) oWriter.WriteString(std::wstring(L" show=\"0\"")); oWriter.WriteString(std::wstring(L">")); oWriter.WriteString(std::wstring(L"m_sName.empty() == false) oWriter.WriteString(std::wstring(L" name=\"") + pSlide->m_sName + std::wstring(L"\"")); oWriter.WriteString(std::wstring(L">")); if (pSlide->m_bIsBackground) { WriteBackground(oWriter, oRels, pSlide->m_oBackground); } oWriter.WriteString(std::wstring(L"\ ")); CGroupElement* pGroupElement = !pSlide->m_arElements.empty() ? dynamic_cast(pSlide->m_arElements[0].get()) : NULL; size_t start_index = 0; if (pGroupElement) { for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) { auto& element = pGroupElement->m_pChildElements[i]; WriteElement(oWriter, oRels, element); } start_index = 1; } for (size_t i = start_index; i < pSlide->m_arElements.size(); ++i) { auto& element = pSlide->m_arElements[i]; WriteElement(oWriter, oRels, element); } oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); WriteTransition(oWriter, pSlide->m_oSlideShow); // TODO write new method and class for timing WriteTiming(oWriter, oRels, nIndexSlide); oWriter.WriteString(std::wstring(L"")); oRels.CloseRels(); std::wstring strXml = oWriter.GetData(); std::wstring strFile = L"slide" + std::to_wstring(nIndexSlide + 1) + L".xml"; std::wstring strFileSlidePath = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"slides" + FILE_SEPARATOR_STR; NSFile::CFileBinary oFile; oFile.CreateFileW(strFileSlidePath + strFile); oFile.WriteStringUTF8(strXml); oFile.CloseFile(); strFile = L"slide" + std::to_wstring(nIndexSlide + 1) + L".xml.rels"; oRels.SaveRels(strFileSlidePath + L"_rels" + FILE_SEPARATOR_STR + strFile); } void CPPTXWriter::WriteTransition(CStringWriter& oWriter, CSlideShowInfo& oSSInfo) { Converter::Transition transitionConverter(oSSInfo, m_pShapeWriter->m_pRels); auto transition = transitionConverter.Convert(); oWriter.WriteString(transition.toXML()); } void CPPTXWriter::WriteNotes(int nIndexNotes) { CStringWriter oWriter; CRelsGenerator oRels(&m_oManager); CSlide* pNotes = m_pDocument->m_arNotes[nIndexNotes]; oRels.StartNotes(pNotes->m_lSlideID, m_pDocument->m_pNotesMaster != NULL); m_pShapeWriter->SetRelsGenerator(&oRels); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"m_bShowMasterShapes) oWriter.WriteString(std::wstring(L" showMasterSp=\"0\"")); oWriter.WriteString(std::wstring(L">")); oWriter.WriteString(std::wstring(L"")); if (pNotes->m_bIsBackground) { WriteBackground(oWriter, oRels, pNotes->m_oBackground); } oWriter.WriteString(std::wstring(L"\ ")); CGroupElement* pGroupElement = !pNotes->m_arElements.empty() ? dynamic_cast(pNotes->m_arElements[0].get()) : NULL; size_t start_index = 0; if (pGroupElement) { for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) { WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); } start_index = 1; } for (size_t i = start_index; i < pNotes->m_arElements.size(); ++i) { WriteElement(oWriter, oRels, pNotes->m_arElements[i]); } oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); oRels.CloseRels(); std::wstring strXml = oWriter.GetData(); std::wstring strFile = L"notesSlide" + std::to_wstring(nIndexNotes + 1) + L".xml"; std::wstring strFileSlidePath = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"notesSlides" + FILE_SEPARATOR_STR; NSFile::CFileBinary oFile; oFile.CreateFileW(strFileSlidePath + strFile); oFile.WriteStringUTF8(strXml); oFile.CloseFile(); strFile = L"notesSlide" + std::to_wstring(nIndexNotes + 1) + L".xml.rels"; oRels.SaveRels(strFileSlidePath + L"_rels" + FILE_SEPARATOR_STR + strFile); } void CPPTXWriter::WriteSlides() { m_oManager.WriteAudioCollection(m_pUserInfo->m_oExMedia.m_arAudioCollection); for (size_t nIndexS = 0; nIndexS < m_pDocument->m_arSlides.size(); ++nIndexS) { WriteSlide((int)nIndexS); } } void CPPTXWriter::WriteNotes() { for (size_t nIndexS = 0; nIndexS < m_pDocument->m_arNotes.size(); ++nIndexS) { WriteNotes((int)nIndexS); } } void CPPTXWriter::WriteLayoutAfterTheme(CThemePtr pTheme, const int nIndexTheme, int& nStartLayout) {//nIndexTheme тут уже +1 CRelsGenerator oRels(&m_oManager); int nCountLayouts = (int)pTheme->m_arLayouts.size(); oRels.StartMaster(nIndexTheme - 1, nStartLayout, nCountLayouts); CStringWriter oWriter; oWriter.WriteString(L""); if (pTheme->m_eType == typeMaster) { oWriter.WriteString(L""); } else if (pTheme->m_eType == typeNotesMaster) { oWriter.WriteString(L""); } else if (pTheme->m_eType == typeHandoutMaster) { oWriter.WriteString(L""); } oWriter.WriteString(L""); if (pTheme->m_bIsBackground) { WriteBackground(oWriter, oRels, pTheme->m_oBackground); } oWriter.WriteString(L"\ "); CGroupElement* pGroupElement = !pTheme->m_arElements.empty() ? dynamic_cast(pTheme->m_arElements[0].get()) : NULL; size_t start_index = 0; if (pGroupElement) { for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) { if (isBodyPlaceholder(pGroupElement->m_pChildElements[i]->m_lPlaceholderType)) pGroupElement->m_pChildElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! //if (pGroupElement->m_pChildElements[i]->m_bAnchorEnabled == false && // pGroupElement->m_pChildElements[i]->m_bChildAnchorEnabled == false) // continue; //if (pTheme->m_eType == typeNotesMaster) //{ // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; //} //else if (pTheme->m_eType == typeHandoutMaster) //{ // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; // pGroupElement->m_pChildElements[i]->m_lPlaceholderSizePreset = -1; //} WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); } start_index = 1; } for (size_t i = start_index; i < pTheme->m_arElements.size(); ++i) { if (isBodyPlaceholder(pTheme->m_arElements[i]->m_lPlaceholderType)) pTheme->m_arElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! //if (pTheme->m_arElements[i]->m_bAnchorEnabled == false && // pTheme->m_arElements[i]->m_bChildAnchorEnabled == false) // continue; //if (pTheme->m_eType == typeNotesMaster) //{ // pTheme->m_arElements[i]->m_lPlaceholderID = -1; //} //else if (pTheme->m_eType == typeHandoutMaster) //{ // pTheme->m_arElements[i]->m_lPlaceholderID = -1; // pTheme->m_arElements[i]->m_lPlaceholderSizePreset = -1; //} WriteElement(oWriter, oRels, pTheme->m_arElements[i]); } oWriter.WriteString(std::wstring(L"")); std::wstring strOverrideColorScheme = L""; oWriter.WriteString(strOverrideColorScheme); if (pTheme->m_eType == typeMaster) { oWriter.WriteString(std::wstring(L"")); size_t __nCountLayouts = 0; for (int nIndexLayout = 0; nIndexLayout < nCountLayouts; ++nIndexLayout) { oWriter.WriteString(L""); WriteLayout(pTheme->m_arLayouts[nIndexLayout], nIndexLayout, nStartLayout, nIndexTheme - 1); } oWriter.WriteString(std::wstring(L"")); } if (pTheme->m_bHasDate || pTheme->m_bHasFooter || pTheme->m_bHasSlideNumber) { oWriter.WriteString(std::wstring(L"m_bHasDate) oWriter.WriteString(std::wstring(L" dt=\"0\"")); if (!pTheme->m_bHasSlideNumber) oWriter.WriteString(std::wstring(L" sldNum=\"0\"")); oWriter.WriteString(std::wstring(L" hdr=\"0\"")); if (!pTheme->m_bHasFooter) oWriter.WriteString(std::wstring(L" ftr=\"0\"")); oWriter.WriteString(std::wstring(L"/>")); } CStylesWriter styleWriter; styleWriter.m_pTheme = pTheme.get(); if (pTheme->m_eType == typeMaster) { oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); styleWriter.ConvertStyles(pTheme->m_pStyles[2], oWriter, 9); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); styleWriter.ConvertStyles(pTheme->m_pStyles[3], oWriter, 9); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"")); } else if (pTheme->m_eType == typeNotesMaster) { oWriter.WriteString(std::wstring(L"")); styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); oWriter.WriteString(std::wstring(L"")); } std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR; std::wstring strSlideMasterFile; std::wstring strSlideMasterRelsFile; if (pTheme->m_eType == typeMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml"; strSlideMasterFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml.rels"; strSlideMasterRelsFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } else if (pTheme->m_eType == typeNotesMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"notesMaster1.xml"; strSlideMasterFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"notesMaster1.xml.rels"; strSlideMasterRelsFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } else if (pTheme->m_eType == typeHandoutMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"handoutMaster1.xml"; strSlideMasterFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"handoutMaster1.xml.rels"; strSlideMasterRelsFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } NSFile::CFileBinary oFile; oFile.CreateFileW(strSlideMasterFile); std::wstring strMaster = oWriter.GetData(); oFile.WriteStringUTF8(strMaster); oFile.CloseFile(); oRels.CloseRels(); oRels.SaveRels(strSlideMasterRelsFile); nStartLayout += nCountLayouts; } void CPPTXWriter::WriteTiming(CStringWriter& oWriter, CRelsGenerator& oRels, int nIndexSlide) { auto slide_iter = m_pUserInfo->m_mapSlides.find(m_pUserInfo->m_arrSlidesOrder[nIndexSlide]); CSlide* pCSlide = m_pDocument->m_arSlides[nIndexSlide]; auto intermediateSlideAnimation = Intermediate::ParseSlideAnimation(slide_iter->second, pCSlide); auto timing = Converter::Timing(intermediateSlideAnimation). Convert(&(m_pUserInfo->m_oExMedia), &oRels); oWriter.WriteString(timing.toXML()); } std::vector CPPTXWriter::GrepPaths(const std::vector& paths, const std::wstring& strRegEx) { std::vector filtredPaths; try { boost::wregex regEx(strRegEx); boost::wsmatch wSmath; for (const auto& path : paths) { if (boost::regex_match(path, wSmath, regEx)) filtredPaths.push_back(path); } } catch (...) {} return filtredPaths; } }