Files
core/OOXML/PPTXFormat/Logic/SmartArt.cpp
Alexander Trofimov 76ee07f61c [copyright] Update copyright header
Co-authored-by: Alexander Trofimov <alexander.trofimov@onlyoffice.com>
Co-committed-by: Alexander Trofimov <alexander.trofimov@onlyoffice.com>
2026-05-14 08:23:56 +00:00

759 lines
28 KiB
C++

/*
* Copyright (C) Ascensio System SIA, 2009-2026
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation, together with the
* additional terms provided in the LICENSE file.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: https://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA by email at info@onlyoffice.com
* or by postal mail at 20A-6 Ernesta Birznieka-Upisha Street, Riga,
* LV-1050, Latvia, European Union.
*
* The interactive user interfaces in modified versions of the Program
* are required to display Appropriate Legal Notices in accordance with
* Section 5 of the GNU AGPL version 3.
*
* No trademark rights are granted under this License.
*
* All non-code elements of the Product, including illustrations,
* icon sets, and technical writing content, are licensed under the
* Creative Commons Attribution-ShareAlike 4.0 International License:
* https://creativecommons.org/licenses/by-sa/4.0/legalcode
*
* This license applies only to such non-code elements and does not
* modify or replace the licensing terms applicable to the Program's
* source code, which remains licensed under the GNU Affero General
* Public License v3.
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
#include "SmartArt.h"
#include "../Slide.h"
#include "../SlideLayout.h"
#include "../SlideMaster.h"
#include "../../PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.h"
#include "../../Binary/Sheets/Reader/BinaryWriterS.h"
#include "../../Binary/Document/DocWrapper/XlsxSerializer.h"
#include "../../Binary/Document/DocWrapper/FontProcessor.h"
#include "../../Binary/Document/BinWriter/BinaryWriterD.h"
#include "../../XlsxFormat/Chart/Chart.h"
#include "../../DocxFormat/Diagram/DiagramData.h"
#include "../../DocxFormat/Diagram/DiagramDrawing.h"
#include "../../DocxFormat/Diagram/DiagramColors.h"
#include "../../DocxFormat/Diagram/DiagramQuickStyle.h"
#include "../../DocxFormat/Diagram/DiagramLayout.h"
#include "../../../Common/OfficeFileFormatChecker.h"
#include "../../../OfficeUtils/src/OfficeUtils.h"
#include "../../../DesktopEditor/common/Directory.h"
namespace PPTX
{
namespace Logic
{
SmartArt::SmartArt()
{
}
SmartArt& SmartArt::operator=(const SmartArt& oSrc)
{
parentFile = oSrc.parentFile;
parentElement = oSrc.parentElement;
return *this;
}
OOX::EElementType SmartArt::getType () const
{
return OOX::et_dgm_DiagrammParts;
}
void SmartArt::fromXML(XmlUtils::CXmlLiteReader& oReader)
{
ReadAttributes( oReader );
}
void SmartArt::fromXML(XmlUtils::CXmlNode& node)
{
XmlMacroReadAttributeBase(node, L"r:dm", id_data);
XmlMacroReadAttributeBase(node, L"r:cs", id_color);
XmlMacroReadAttributeBase(node, L"r:lo", id_layout);
XmlMacroReadAttributeBase(node, L"r:qs", id_style);
}
smart_ptr<OOX::File> SmartArt::FindDiagramDrawing(OOX::CDiagramData* pDiagramData) const
{
if (!pDiagramData) return NULL;
// easy4cargo1.pptx - slide 2 - in the Smart diagram, instead of a reference to drawing.xml there is a reference to an external image
OOX::CPath pathDiagramData = pDiagramData->m_strFilename;
int a1 = (int)pathDiagramData.GetFilename().find(L".");
std::wstring strId = pathDiagramData.GetFilename().substr(4, pathDiagramData.GetFilename().length() - 8);
//standardized names only
OOX::CPath pathDiagramDrawing = pathDiagramData.GetDirectory() + FILE_SEPARATOR_STR + L"drawing" + strId + L".xml";
return smart_ptr<OOX::File>(dynamic_cast<OOX::File*>(new OOX::CDiagramDrawing(NULL, pathDiagramDrawing)));
}
bool SmartArt::LoadDrawing(OOX::IFileContainer* pRels)
{
if (m_oDrawing.IsInit())
return true;
if (id_data.IsInit() == false) return false;
if (pRels == NULL) return false;
smart_ptr<OOX::File> oFileData = pRels->Find(*id_data);
OOX::CDiagramData* pDiagramData = dynamic_cast<OOX::CDiagramData*>(oFileData.GetPointer());
if (!pDiagramData) return false;
if (pDiagramData->m_oDataModel.IsInit())
m_oDataBg = pDiagramData->m_oDataModel->m_oBg;
m_pDataContainer = oFileData.smart_dynamic_cast<OOX::IFileContainer>();
// this is smart art.. whether it has a drawing or not doesn't matter
smart_ptr<OOX::File> oFileDrawing;
OOX::CDiagramDrawing* pDiagramDrawing = NULL;
if (pDiagramData->id_drawing.IsInit())
{
if (parentFileIs<OOX::IFileContainer>()) oFileDrawing = parentFileAs<OOX::IFileContainer>().Find(*pDiagramData->id_drawing);
else if (pRels != NULL) oFileDrawing = pRels->Find(*pDiagramData->id_drawing);
}
else
{
//Monetizing_Innovation.pptx (slide 13) - diagrams/data1.xml doesn't reference diagrams/drawing1.xml
//try using the same path with data.xml number - see below
}
pDiagramDrawing = dynamic_cast<OOX::CDiagramDrawing*>(oFileDrawing.GetPointer());
if (!pDiagramDrawing)
{
oFileDrawing = FindDiagramDrawing(pDiagramData);
pDiagramDrawing = dynamic_cast<OOX::CDiagramDrawing*>(oFileDrawing.GetPointer());
}
if ((pDiagramDrawing) && (pDiagramDrawing->m_oShapeTree.IsInit()))
{
m_oDrawing = pDiagramDrawing->m_oShapeTree;
FillParentPointersForChilds();
m_pDrawingContainer = oFileDrawing.smart_dynamic_cast<OOX::IFileContainer>();
if (!m_oDrawing->grpSpPr.xfrm.IsInit())
m_oDrawing->grpSpPr.xfrm = new PPTX::Logic::Xfrm;
}
//else
//{
// //parse pDiagramData !!
//}
return true;
}
void SmartArt::LoadDrawing(NSBinPptxRW::CBinaryFileWriter* pWriter)
{
if (m_oDrawing.IsInit())
return;
bool result = false;
if (parentFileIs<OOX::IFileContainer>())
{
OOX::IFileContainer & pRelsPPTX = parentFileAs<OOX::IFileContainer>();
result = LoadDrawing(&pRelsPPTX);
}
if (!result && pWriter)
{
OOX::IFileContainer * pRels = pWriter->GetRelsPtr();
result = LoadDrawing(pRels);
}
}
void SmartArt::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const
{
OOX::IFileContainer* pDocumentRels = pWriter->GetRelsPtr();
BinDocxRW::CDocxSerializer *main_document = pWriter->m_pDocxSerializer;
pWriter->m_pDocxSerializer = NULL;
if (id_data.IsInit())
{
smart_ptr<OOX::File> oFileData;
if (parentFileIs<OOX::IFileContainer>()) oFileData = parentFileAs<OOX::IFileContainer>().Find(*id_data);
else if (pDocumentRels != NULL) oFileData = pDocumentRels->Find(*id_data);
OOX::CDiagramData* pDiagramData = dynamic_cast<OOX::CDiagramData*>(oFileData.GetPointer());
if (pDiagramData)
{
OOX::CDiagramDrawing* pDiagramDrawing = NULL;
smart_ptr<OOX::File> oFileDrawing;
if (pDiagramData->id_drawing.IsInit())
{
if (parentFileIs<OOX::IFileContainer>()) oFileDrawing = parentFileAs<OOX::IFileContainer>().Find(*pDiagramData->id_drawing);
else if (pDocumentRels != NULL) oFileDrawing = pDocumentRels->Find(*pDiagramData->id_drawing);
pDiagramDrawing = dynamic_cast<OOX::CDiagramDrawing*>(oFileDrawing.GetPointer());
}
if (!pDiagramDrawing)
{
//Demo-Hayden-Management-v2.docx
oFileDrawing = FindDiagramDrawing(pDiagramData);
pDiagramDrawing = dynamic_cast<OOX::CDiagramDrawing*>(oFileDrawing.GetPointer());
}
if (pDiagramDrawing)
{
pWriter->SetRelsPtr(dynamic_cast<OOX::IFileContainer*>(oFileDrawing.GetPointer()));
pWriter->StartRecord(0);
pDiagramDrawing->toPPTY(pWriter);
pWriter->EndRecord();
}
pWriter->SetRelsPtr(dynamic_cast<OOX::IFileContainer*>(oFileData.GetPointer()));
pWriter->StartRecord(1);
pDiagramData->toPPTY(pWriter);
pWriter->EndRecord();
}
}
if (id_color.IsInit())
{
smart_ptr<OOX::File> oFileColors;
if (parentFileIs<OOX::IFileContainer>()) oFileColors = parentFileAs<OOX::IFileContainer>().Find(*id_color);
else if (pDocumentRels != NULL) oFileColors = pDocumentRels->Find(*id_color);
OOX::CDiagramColors* pDiagramColors = dynamic_cast<OOX::CDiagramColors*>(oFileColors.GetPointer());
if (pDiagramColors)
{
pWriter->SetRelsPtr(dynamic_cast<OOX::IFileContainer*>(oFileColors.GetPointer()));
pWriter->StartRecord(2);
pDiagramColors->toPPTY(pWriter);
pWriter->EndRecord();
}
}
if (id_layout.IsInit())
{
smart_ptr<OOX::File> oFileLayout;
if (parentFileIs<OOX::IFileContainer>()) oFileLayout = parentFileAs<OOX::IFileContainer>().Find(*id_layout);
else if (pDocumentRels != NULL) oFileLayout = pDocumentRels->Find(*id_layout);
OOX::CDiagramLayout* pDiagramLayout = dynamic_cast<OOX::CDiagramLayout*>(oFileLayout.GetPointer());
if (pDiagramLayout)
{
pWriter->SetRelsPtr(dynamic_cast<OOX::IFileContainer*>(oFileLayout.GetPointer()));
pWriter->StartRecord(3);
pDiagramLayout->toPPTY(pWriter);
pWriter->EndRecord();
}
}
if (id_style.IsInit())
{
smart_ptr<OOX::File> oFileStyle;
if (parentFileIs<OOX::IFileContainer>()) oFileStyle = parentFileAs<OOX::IFileContainer>().Find(*id_style);
else if (pDocumentRels != NULL) oFileStyle = pDocumentRels->Find(*id_style);
OOX::CDiagramQuickStyle* pDiagramStyle = dynamic_cast<OOX::CDiagramQuickStyle*>(oFileStyle.GetPointer());
if (pDiagramStyle)
{
pWriter->SetRelsPtr(dynamic_cast<OOX::IFileContainer*>(oFileStyle.GetPointer()));
pWriter->StartRecord(4);
pDiagramStyle->toPPTY(pWriter);
pWriter->EndRecord();
}
}
pWriter->SetRelsPtr(pDocumentRels);
pWriter->m_pDocxSerializer = main_document;
}
void SmartArt::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader)
{
int mainDocumentType = pReader->m_nDocumentType;
pReader->m_nDocumentType = pReader->m_pRels->m_pManager->m_nDocumentType = XMLWRITER_DOC_TYPE_DIAGRAM;
int nCountDiagram = pReader->m_nCountDiagram;
pReader->m_nCountDiagram++;
std::wstring strDstDiagram = pReader->m_pRels->m_pManager->GetDstDiagram();
std::wstring contenttype_override_path = (mainDocumentType == XMLWRITER_DOC_TYPE_DOCX) ? L"/word/diagrams" :
((mainDocumentType == XMLWRITER_DOC_TYPE_XLSX) ? L"/xl/diagrams" : L"/ppt/diagrams");
std::wstring rels_path = (mainDocumentType == XMLWRITER_DOC_TYPE_DOCX) ? L"diagrams/" : L"../diagrams/";
if (strDstDiagram.empty())
{
strDstDiagram = pReader->m_pRels->m_pManager->GetDstFolder() + FILE_SEPARATOR_STR + L"diagrams";
pReader->m_pRels->m_pManager->SetDstCharts(strDstDiagram);
}
NSDirectory::CreateDirectory(strDstDiagram);
NSDirectory::CreateDirectory(strDstDiagram + FILE_SEPARATOR_STR + L"_rels");
//--------------------------------------------------------------------------------------------------
smart_ptr<OOX::CDiagramDrawing> pDiagramDrawing;
LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4;
while (pReader->GetPos() < end)
{
BYTE _rec = pReader->GetUChar();
switch (_rec)
{
case 0:
{
pReader->SetDstContentRels();
pDiagramDrawing = new OOX::CDiagramDrawing(NULL);
pDiagramDrawing->m_sOutputFilename = L"drawing" + std::to_wstring(nCountDiagram) + L".xml";
pDiagramDrawing->fromPPTY(pReader);
pDiagramDrawing->write(strDstDiagram + FILE_SEPARATOR_STR + pDiagramDrawing->m_sOutputFilename, contenttype_override_path, *pReader->m_pRels->m_pManager->m_pContentTypes);
pReader->SaveDstContentRels(strDstDiagram + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"drawing" + std::to_wstring(nCountDiagram) + L".xml.rels");
pDiagramDrawing->m_sOutputFilename = rels_path + pDiagramDrawing->m_sOutputFilename;
}break;
case 1:
{
pReader->SetDstContentRels();
smart_ptr<OOX::CDiagramData> pDiagramData = new OOX::CDiagramData(NULL);
pDiagramData->m_sOutputFilename = L"data" + std::to_wstring(nCountDiagram) + L".xml";
pDiagramData->fromPPTY(pReader);
pReader->SaveDstContentRels(strDstDiagram + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + pDiagramData->m_sOutputFilename + L".rels");
// !!! id_drawing that is written to data is relative to the container above
if (pDiagramDrawing.IsInit())
{
unsigned int nRId = pReader->m_pRels->WriteRels(pDiagramDrawing->type().RelationType(), pDiagramDrawing->m_sOutputFilename, L"");
pDiagramData->id_drawing = new OOX::RId(nRId);
pDiagramData->m_oDataModel->m_oExtLst.Init();
pDiagramData->m_oDataModel->m_oExtLst->m_arrExt.push_back(new OOX::Drawing::COfficeArtExtension());
pDiagramData->m_oDataModel->m_oExtLst->m_arrExt[0]->m_oDataModelExt.Init();
pDiagramData->m_oDataModel->m_oExtLst->m_arrExt[0]->m_sUri = L"http://schemas.microsoft.com/office/drawing/2008/diagram";
pDiagramData->m_oDataModel->m_oExtLst->m_arrExt[0]->m_oDataModelExt->m_oRelId = pDiagramData->id_drawing->ToString();
}
pDiagramData->write(strDstDiagram + FILE_SEPARATOR_STR + pDiagramData->m_sOutputFilename, contenttype_override_path, *pReader->m_pRels->m_pManager->m_pContentTypes);
pDiagramData->m_sOutputFilename = rels_path + pDiagramData->m_sOutputFilename;
unsigned int nRId = pReader->m_pRels->WriteRels(pDiagramData->type().RelationType(), pDiagramData->m_sOutputFilename, L"");
id_data = new OOX::RId(nRId);
}break;
case 2:
{
smart_ptr<OOX::CDiagramColors> pDiagramColors = new OOX::CDiagramColors(NULL);
pDiagramColors->m_sOutputFilename = L"colors" + std::to_wstring(nCountDiagram) + L".xml";
pDiagramColors->fromPPTY(pReader);
pDiagramColors->write(strDstDiagram + FILE_SEPARATOR_STR + pDiagramColors->m_sOutputFilename, contenttype_override_path, *pReader->m_pRels->m_pManager->m_pContentTypes);
pDiagramColors->m_sOutputFilename = rels_path + pDiagramColors->m_sOutputFilename;
unsigned int nRId = pReader->m_pRels->WriteRels(pDiagramColors->type().RelationType(), pDiagramColors->m_sOutputFilename, L"");
id_color = new OOX::RId(nRId);
}break;
case 3:
{
smart_ptr<OOX::CDiagramLayout> pDiagramLayout = new OOX::CDiagramLayout(NULL);
pDiagramLayout->m_sOutputFilename = L"layout" + std::to_wstring(nCountDiagram) + L".xml";
pDiagramLayout->fromPPTY(pReader);
pDiagramLayout->write(strDstDiagram + FILE_SEPARATOR_STR + pDiagramLayout->m_sOutputFilename, contenttype_override_path, *pReader->m_pRels->m_pManager->m_pContentTypes);
pDiagramLayout->m_sOutputFilename = rels_path + pDiagramLayout->m_sOutputFilename;
unsigned int nRId = pReader->m_pRels->WriteRels(pDiagramLayout->type().RelationType(), pDiagramLayout->m_sOutputFilename, L"");
id_layout = new OOX::RId(nRId);
}break;
case 4:
{
smart_ptr<OOX::CDiagramQuickStyle> pDiagramStyle = new OOX::CDiagramQuickStyle(NULL);
pDiagramStyle->m_sOutputFilename = L"quickStyle" + std::to_wstring(nCountDiagram) + L".xml";
pDiagramStyle->fromPPTY(pReader);
pDiagramStyle->write(strDstDiagram + FILE_SEPARATOR_STR + pDiagramStyle->m_sOutputFilename, contenttype_override_path, *pReader->m_pRels->m_pManager->m_pContentTypes);
pDiagramStyle->m_sOutputFilename = rels_path + pDiagramStyle->m_sOutputFilename;
unsigned int nRId = pReader->m_pRels->WriteRels(pDiagramStyle->type().RelationType(), pDiagramStyle->m_sOutputFilename, L"");
id_style = new OOX::RId(nRId);
}break;
default:
{
pReader->SkipRecord();
}break;
}
}
pReader->Seek(end);
pReader->m_nDocumentType = pReader->m_pRels->m_pManager->m_nDocumentType = mainDocumentType;
}
std::wstring SmartArt::toXML() const
{
if (!id_data.is_init())
return L"";
std::wstring strData = L"<dgm:relIds xmlns:dgm=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"";
strData += L" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"";
strData += L" r:dm=\"" + id_data->ToString() + L"\"";
if (id_layout.IsInit()) strData += L" r:lo=\"" + id_layout->ToString() + L"\"";
if (id_style.IsInit()) strData += L" r:qs=\"" + id_style->ToString() + L"\"";
if (id_color.IsInit()) strData += L" r:cs=\"" + id_color->ToString() + L"\"";
strData += L"/>";
return strData;
}
void SmartArt::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const
{
pWriter->WriteString(toXML());
}
void SmartArt::FillParentPointersForChilds()
{
}
void SmartArt::ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
WritingElement_ReadAttributes_Start(oReader)
WritingElement_ReadAttributes_Read_if(oReader, (L"r:cs"), id_color)
WritingElement_ReadAttributes_Read_else_if(oReader, (L"r:dm"), id_data)
WritingElement_ReadAttributes_Read_else_if(oReader, (L"r:lo"), id_layout)
WritingElement_ReadAttributes_Read_else_if(oReader, (L"r:qs"), id_style)
WritingElement_ReadAttributes_End(oReader)
}
ChartRec::ChartRec()
{
}
ChartRec::ChartRec(const ChartRec& oSrc)
{
*this = oSrc;
}
ChartRec& ChartRec::operator=(const ChartRec& oSrc)
{
parentFile = oSrc.parentFile;
parentElement = oSrc.parentElement;
return *this;
}
void ChartRec::ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
WritingElement_ReadAttributes_Start_No_NS( oReader )
WritingElement_ReadAttributes_ReadSingle ( oReader, L"id", id_data )
WritingElement_ReadAttributes_End_No_NS ( oReader )
}
void ChartRec::fromXML(XmlUtils::CXmlLiteReader& oReader)
{
std::wstring ns = XmlUtils::GetNamespace(oReader.GetName());
m_bChartEx = false;
ReadAttributes( oReader );
FillParentPointersForChilds();
if (ns == L"cx")
{
m_bChartEx = true;
}
}
void ChartRec::fromXML(XmlUtils::CXmlNode& node)
{
m_bChartEx = false;
std::wstring ns = XmlUtils::GetNamespace(node.GetName());
XmlMacroReadAttributeBase(node, L"r:id", id_data);
FillParentPointersForChilds();
if (ns == L"cx")
{
m_bChartEx = true;
}
}
void ChartRec::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const
{
OOX::IFileContainer* pRels = pWriter->GetRelsPtr();
smart_ptr<OOX::File> file;
if(id_data.IsInit())
{
if(parentFileIs<OOX::IFileContainer>()) file = parentFileAs<OOX::IFileContainer>().Find(*id_data);
else if (pRels != NULL) file = pRels->Find(*id_data);
}
smart_ptr<OOX::Spreadsheet::CChartFile> pChart = file.smart_dynamic_cast<OOX::Spreadsheet::CChartFile>();
smart_ptr<OOX::Spreadsheet::CChartExFile> pChartEx = file.smart_dynamic_cast<OOX::Spreadsheet::CChartExFile>();
if (false == pChart.IsInit() && false == pChartEx.IsInit()) return;
//----------------------------------------------------------------
std::wstring id;
if ((pChart.IsInit()) && (pChart->m_oChartSpace.m_externalData) && (pChart->m_oChartSpace.m_externalData->m_id.IsInit()))
id = *pChart->m_oChartSpace.m_externalData->m_id;
else if ((pChartEx.IsInit()) && (true == pChartEx->m_oChartSpace.m_chartData.m_externalData.IsInit()))
id = pChartEx->m_oChartSpace.m_chartData.m_externalData->m_id.get_value_or(L"");
if (false == id.empty())
{
smart_ptr<OOX::File> oFile = pChart.IsInit() ? pChart->Find(id) : pChartEx->Find(id);
smart_ptr<OOX::Media> oMediaFile = oFile.smart_dynamic_cast<OOX::Media>();
if (oMediaFile.IsInit())
{
if (oMediaFile->IsExternal())
{
pWriter->StartRecord(/*c_oserct_chartspaceXLSXEXTERRNAL = */19);
pWriter->WriteStringW4(oMediaFile->filename().GetPath());
pWriter->EndRecord();
}
else
{
OOX::CPath oox_file = oMediaFile->filename();
OOX::CPath embed_folder = oox_file.GetDirectory(true);
OOX::CPath oox_unpacked = embed_folder + L"Temp_unpacked";
NSDirectory::CreateDirectory(oox_unpacked.GetPath());
COfficeUtils oOfficeUtils(NULL);
oOfficeUtils.ExtractToDirectory(oox_file.GetPath(), oox_unpacked.GetPath(), NULL, 0);
COfficeFileFormatChecker office_checker;
office_checker.isOOXFormatFile(oox_file.GetPath());
if (office_checker.nFileType == AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX ||
office_checker.nFileType == AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM)
{
DocWrapper::FontProcessor oFontProcessor;
NSBinPptxRW::CDrawingConverter oDrawingConverter;
OOX::IFileContainer* old_rels = pWriter->GetRelsPtr();
NSCommon::smart_ptr<PPTX::Theme> old_theme = *pWriter->m_pTheme;
NSShapeImageGen::CMediaManager* old_manager = oDrawingConverter.m_pBinaryWriter->m_pCommon->m_pMediaManager;
oDrawingConverter.m_pBinaryWriter->m_pCommon->m_pMediaManager = pWriter->m_pCommon->m_pMediaManager;
oDrawingConverter.SetFontPicker(pWriter->m_pCommon->m_pFontPicker);
//----------------------------
BinXlsxRW::BinaryFileWriter xlsxBinaryWriter(oFontProcessor);
OOX::Spreadsheet::CXlsx *pXlsxEmbedded = NULL;
NSBinPptxRW::CXlsbBinaryWriter oXlsbWriter;
if (office_checker.nFileType == AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB)
pXlsxEmbedded = new OOX::Spreadsheet::CXlsb();
else
pXlsxEmbedded = new OOX::Spreadsheet::CXlsx();
//startheader for test
//oXlsbWriter.WriteStringUtf8(xlsxBinaryWriter.WriteFileHeader(0, BinXlsxRW::g_nFormatVersionNoBase64));
oXlsbWriter.WriteReserved(xlsxBinaryWriter.GetMainTableSize());
unsigned int nXlsbWriterStartPos = oXlsbWriter.GetPositionAbsolute();
pXlsxEmbedded->m_pXlsbWriter = &oXlsbWriter;
pXlsxEmbedded->m_bNeedCalcChain = false;
pXlsxEmbedded->Read(oox_unpacked);
pXlsxEmbedded->PrepareWorkbook();
unsigned int nXlsbWriterEndPos = oXlsbWriter.GetPositionAbsolute();
if (office_checker.nFileType == AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB)
{
dynamic_cast<OOX::Spreadsheet::CXlsb*>(pXlsxEmbedded)->PrepareSi();
dynamic_cast<OOX::Spreadsheet::CXlsb*>(pXlsxEmbedded)->PrepareTableFormula();
dynamic_cast<OOX::Spreadsheet::CXlsb*>(pXlsxEmbedded)->ReadSheetData();
}
//startheader for test
//oDrawingConverter.m_pBinaryWriter->WriteStringUtf8(xlsxBinaryWriter.WriteFileHeader(0, BinXlsxRW::g_nFormatVersionNoBase64));
xlsxBinaryWriter.WriteMainTableStart(*oDrawingConverter.m_pBinaryWriter);
if (nXlsbWriterEndPos > nXlsbWriterStartPos)
{
xlsxBinaryWriter.WriteBinaryTable(oXlsbWriter.GetBuffer() + nXlsbWriterStartPos, nXlsbWriterEndPos - nXlsbWriterStartPos);
}
xlsxBinaryWriter.WriteContent(pXlsxEmbedded, NULL, &oDrawingConverter);
xlsxBinaryWriter.WriteMainTableEnd();
pXlsxEmbedded->m_pXlsbWriter = NULL;
delete pXlsxEmbedded;
//------------------------------
pWriter->SetRelsPtr(old_rels);
*pWriter->m_pTheme = old_theme;
oDrawingConverter.m_pBinaryWriter->m_pCommon->m_pMediaManager = old_manager;
pWriter->StartRecord(/*c_oserct_chartspaceXLSX*/16);
BYTE* pbBinBuffer = oDrawingConverter.m_pBinaryWriter->GetBuffer();
int nBinBufferLen = oDrawingConverter.m_pBinaryWriter->GetPosition();
pWriter->WriteBYTEArray(pbBinBuffer, nBinBufferLen);
pWriter->EndRecord();
//for test
//NSFile::CFileBinary oFile;
//oFile.CreateFileW(L"d:\\Editor.bin");
//oFile.WriteFile(pbBinBuffer, nBinBufferLen);
//oFile.CloseFile();
}
NSDirectory::DeleteDirectory(oox_unpacked.GetPath());
}
}
}
//----------------------------------------------------------------
NSBinPptxRW::CDrawingConverter oDrawingConverter;
NSBinPptxRW::CBinaryFileWriter *pOldDrawingWriter = oDrawingConverter.m_pBinaryWriter;
BinDocxRW::CDocxSerializer *pOldMainDocument = pWriter->m_pDocxSerializer;
pWriter->m_pDocxSerializer = NULL;
oDrawingConverter.m_pBinaryWriter = pWriter;
OOX::IFileContainer* oldRels = oDrawingConverter.GetRelsPtr();
oDrawingConverter.SetRelsPtr(dynamic_cast<OOX::IFileContainer*>(file.GetPointer()));
BinXlsxRW::BinaryChartWriter oBinaryChartWriter(*pWriter, &oDrawingConverter);
if (pChart.IsInit())
{
oBinaryChartWriter.WriteCT_ChartFile(*pChart);
}
else if (pChartEx.IsInit())
{
oBinaryChartWriter.WriteCT_ChartExFile(*pChartEx);
}
//----------------------------------------------------------------
std::vector<smart_ptr<OOX::File>>& container = pChartEx.IsInit() ? pChartEx->GetContainer() : pChart->GetContainer();
for (size_t i = 0; i < container.size(); ++i)
{
if (OOX::FileTypes::ThemeOverride == container[i]->type())
{
PPTX::Theme* pThemeOverride = dynamic_cast<PPTX::Theme*>(container[i].GetPointer());
pWriter->StartRecord(/*c_oserct_chartspaceTHEMEOVERRIDE = */15);
pThemeOverride->toPPTY(pWriter);
pWriter->EndRecord();
}
else if (OOX::FileTypes::ChartStyle == container[i]->type())
{
OOX::Spreadsheet::CChartStyleFile* pChartStyle = dynamic_cast<OOX::Spreadsheet::CChartStyleFile*>(container[i].GetPointer());
pWriter->StartRecord(/*c_oserct_chartspaceSTYLES = */17);
oBinaryChartWriter.WriteCT_ChartStyle(*pChartStyle);
pWriter->EndRecord();
}
else if (OOX::FileTypes::ChartColors == container[i]->type())
{
OOX::Spreadsheet::CChartColorsFile* pChartColors = dynamic_cast<OOX::Spreadsheet::CChartColorsFile*>(container[i].GetPointer());
pWriter->StartRecord(/*c_oserct_chartspaceCOLORS = */18);
oBinaryChartWriter.WriteCT_ChartColor(*pChartColors);
pWriter->EndRecord();
}
}
//----------------------------------------------------------------
oDrawingConverter.SetRelsPtr(oldRels);
oDrawingConverter.m_pBinaryWriter = pOldDrawingWriter;
pWriter->m_pDocxSerializer = pOldMainDocument;
}
std::wstring ChartRec::toXML() const
{
if (!id_data.is_init())
return L"";
std::wstring strData;
if (m_bChartEx)
{
strData = L"<cx:chart xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\"";
}
else
{
strData = L"<c:chart xmlns:c=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"";
}
strData += L" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:id=\"" + id_data->ToString() + L"\"/>";
return strData;
}
void ChartRec::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const
{
pWriter->WriteString(toXML());
}
void ChartRec::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader)
{
ULONG lLen = pReader->GetLong();
m_nCountCharts = pReader->m_nCountCharts;
pReader->m_nCountCharts++;
BinXlsxRW::CXlsxSerializer oXlsxSerializer;
NSBinPptxRW::CDrawingConverter oDrawingConverter;
NSBinPptxRW::CImageManager2* pOldImageManager = oDrawingConverter.m_pImageManager;
NSBinPptxRW::CBinaryFileReader* pOldReader = oDrawingConverter.m_pBinaryReader;
oDrawingConverter.m_pImageManager = pReader->m_pRels->m_pManager;
oDrawingConverter.m_pBinaryReader = pReader;
oXlsxSerializer.setDrawingConverter(&oDrawingConverter);
std::wstring strDstChart = pReader->m_pRels->m_pManager->GetDstFolder() + FILE_SEPARATOR_STR + L"charts";
pReader->m_pRels->m_pManager->SetDstCharts(strDstChart);
NSDirectory::CreateDirectory(strDstChart);
smart_ptr<OOX::File> file;
if (m_bChartEx)
{
smart_ptr<OOX::Spreadsheet::CChartExFile> chartEx = new OOX::Spreadsheet::CChartExFile(NULL);
chartEx->SetGlobalNumber(m_nCountCharts);
file = chartEx.smart_dynamic_cast<OOX::File>();
}
else
{
smart_ptr<OOX::Spreadsheet::CChartFile> chart = new OOX::Spreadsheet::CChartFile(NULL);
chart->SetGlobalNumber(m_nCountCharts);
file = chart.smart_dynamic_cast<OOX::File>();
}
if (true == oXlsxSerializer.saveChart(pReader, lLen, file))
{
if (m_bChartEx)
{
unsigned int nRId = pReader->m_pRels->WriteRels(L"http://schemas.microsoft.com/office/2014/relationships/chartEx", file->m_sOutputFilename, L"");
id_data = new OOX::RId(nRId);
}
else
{
unsigned int nRId = pReader->m_pRels->WriteRels(L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", file->m_sOutputFilename, L"");
id_data = new OOX::RId(nRId);
}
}
oDrawingConverter.m_pBinaryReader = pOldReader;
oDrawingConverter.m_pImageManager = pOldImageManager;
}
void ChartRec::FillParentPointersForChilds()
{
}
} // namespace Logic
} // namespace PPTX