mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 05:24:10 +08:00
Co-authored-by: Alexander Trofimov <alexander.trofimov@onlyoffice.com> Co-committed-by: Alexander Trofimov <alexander.trofimov@onlyoffice.com>
1527 lines
40 KiB
C++
1527 lines
40 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 "ChartSheetSubstream.h"
|
|
|
|
#include "Biff_records/WriteProtect.h"
|
|
#include "Biff_records/SheetExt.h"
|
|
#include "Biff_records/WebPub.h"
|
|
#include "Biff_records/HFPicture.h"
|
|
#include "Biff_records/PrintSize.h"
|
|
#include "Biff_records/Fbi.h"
|
|
#include "Biff_records/Fbi2.h"
|
|
#include "Biff_records/ClrtClient.h"
|
|
#include "Biff_records/Palette.h"
|
|
#include "Biff_records/SXViewLink.h"
|
|
#include "Biff_records/PivotChartBits.h"
|
|
#include "Biff_records/SBaseRef.h"
|
|
#include "Biff_records/MsoDrawingGroup.h"
|
|
#include "Biff_records/Units.h"
|
|
#include "Biff_records/CodeName.h"
|
|
#include "Biff_records/EOF.h"
|
|
#include "Biff_records/BOF.h"
|
|
#include "Biff_records/AreaFormat.h"
|
|
#include "Biff_records/SerToCrt.h"
|
|
#include "Biff_records/AxisParent.h"
|
|
#include "Biff_records/Series.h"
|
|
#include "Biff_records/BRAI.h"
|
|
#include "Biff_records/SIIndex.h"
|
|
#include "Biff_records/DataFormat.h"
|
|
#include "Biff_records/Text.h"
|
|
#include "Biff_records/Pos.h"
|
|
#include "Biff_records/Pie.h"
|
|
#include "Biff_records/ShtProps.h"
|
|
#include "Biff_records/Chart3d.h"
|
|
#include "Biff_records/ChartFormat.h"
|
|
#include "Biff_records/Legend.h"
|
|
#include "Biff_records/AttachedLabel.h"
|
|
#include "Biff_records/DataLabExtContents.h"
|
|
#include "Biff_records/CrtLine.h"
|
|
#include "Biff_records/Dat.h"
|
|
#include "Biff_records/Chart.h"
|
|
#include "Biff_records/ExternSheet.h"
|
|
#include "Biff_records/FrtFontList.h"
|
|
#include "Biff_records/ChartFrtInfo.h"
|
|
#include "Biff_records/SerParent.h"
|
|
|
|
#include "Biff_unions/FONTLIST.h"
|
|
#include "Biff_unions/PAGESETUP.h"
|
|
#include "Biff_unions/BACKGROUND.h"
|
|
#include "Biff_unions/PROTECTION_COMMON.h"
|
|
#include "Biff_unions/OBJECTS.h"
|
|
#include "Biff_unions/CHARTFOMATS.h"
|
|
#include "Biff_unions/SERIESDATA.h"
|
|
#include "Biff_unions/WINDOW.h"
|
|
#include "Biff_unions/CUSTOMVIEW.h"
|
|
#include "Biff_unions/CRTMLFRT.h"
|
|
#include "Biff_unions/FRAME.h"
|
|
#include "Biff_unions/ATTACHEDLABEL.h"
|
|
#include "Biff_unions/SERIESFORMAT.h"
|
|
#include "Biff_unions/CRT.h"
|
|
#include "Biff_unions/AXISPARENT.h"
|
|
#include "Biff_unions/AXES.h"
|
|
#include "Biff_unions/SS.h"
|
|
#include "Biff_unions/AI.h"
|
|
#include "Biff_unions/LD.h"
|
|
#include "Biff_unions/DAT.h"
|
|
#include "Biff_unions/PIVOTVIEW.h"
|
|
#include "Biff_unions/RECORD12.h"
|
|
#include "Biff_unions/ATTACHEDLABEL.h"
|
|
#include "Biff_unions/DFTTEXT.h"
|
|
|
|
#include "../../Converter/XlsConverter.h"
|
|
#include "../../Converter/xlsx_conversion_context.h"
|
|
|
|
|
|
namespace XLS
|
|
{;
|
|
|
|
|
|
ChartSheetSubstream::ChartSheetSubstream(const size_t ws_index) : CommonSubstream(ws_index)
|
|
{
|
|
}
|
|
|
|
|
|
ChartSheetSubstream::~ChartSheetSubstream()
|
|
{
|
|
}
|
|
|
|
|
|
BaseObjectPtr ChartSheetSubstream::clone()
|
|
{
|
|
return BaseObjectPtr(new ChartSheetSubstream(*this));
|
|
}
|
|
|
|
|
|
/*
|
|
CHARTSHEET = BOF CHARTSHEETCONTENT
|
|
|
|
CHARTSHEETCONTENT = [WriteProtect] [SheetExt] [WebPub] *HFPicture PAGESETUP PrintSize [HeaderFooter]
|
|
[BACKGROUND] *Fbi *Fbi2 [ClrtClient] [PROTECTION] [Palette] [SXViewLink]
|
|
[PivotChartBits] [SBaseRef] [MsoDrawingGroup] OBJECTS Units CHARTFOMATS SERIESDATA
|
|
*WINDOW *CUSTOMVIEW [CodeName] [CRTMLFRT] EOF
|
|
*/
|
|
const bool ChartSheetSubstream::loadContent(BinProcessor& proc)
|
|
{
|
|
global_info_ = proc.getGlobalWorkbookInfo();
|
|
global_info_->current_sheet = ws_index_ + 1;
|
|
|
|
int count = 0 ;
|
|
|
|
if(!proc.mandatory<BOF>())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
while (true)
|
|
{
|
|
CFRecordType::TypeId type = proc.getNextRecordType();
|
|
|
|
//Log::warning(CFRecordType::getStringById(type));
|
|
|
|
if (type == rt_NONE || proc.isBOF(type)) break;
|
|
if (type == rt_EOF)
|
|
{
|
|
proc.mandatory<EOF_T>();
|
|
break;
|
|
}
|
|
|
|
switch(type)
|
|
{
|
|
case rt_WriteProtect:
|
|
{
|
|
if (proc.optional<WriteProtect>())
|
|
{
|
|
m_WriteProtect = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_SheetExt:
|
|
{
|
|
if (proc.optional<SheetExt>())
|
|
{
|
|
m_SheetExt = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_WebPub: proc.optional<WebPub>(); break;
|
|
case rt_HFPicture:
|
|
{
|
|
count = proc.repeated<HFPicture>(0, 0);
|
|
while(count > 0)
|
|
{
|
|
m_arHFPicture.insert(m_arHFPicture.begin(), elements_.back());
|
|
elements_.pop_back();
|
|
count--;
|
|
}
|
|
}break;
|
|
case rt_Header:
|
|
case rt_Footer:
|
|
case rt_BottomMargin:
|
|
case rt_TopMargin:
|
|
case rt_LeftMargin:
|
|
case rt_RightMargin:
|
|
{
|
|
if (proc.mandatory<PAGESETUP>())
|
|
{
|
|
m_PAGESETUP = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_PrintSize:
|
|
{
|
|
if (proc.mandatory<PrintSize>())
|
|
{
|
|
m_PrintSize = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_HeaderFooter:
|
|
{
|
|
count = proc.repeated<RECORD12> (0, 0);
|
|
while(count > 0)
|
|
{
|
|
m_arRECORD12.insert(m_arRECORD12.begin(), elements_.back());
|
|
elements_.pop_back();
|
|
count--;
|
|
}
|
|
}break;
|
|
case rt_BkHim:
|
|
{
|
|
if (proc.optional<BACKGROUND>())
|
|
{
|
|
m_BACKGROUND = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_Fbi:
|
|
{
|
|
count = proc.repeated<Fbi>(0, 0);
|
|
while(count > 0)
|
|
{
|
|
m_arFbi.insert(m_arFbi.begin(), elements_.back());
|
|
elements_.pop_back();
|
|
count--;
|
|
}
|
|
}break;
|
|
case rt_Fbi2:
|
|
{
|
|
count = proc.repeated<Fbi2>(0, 0);
|
|
while(count > 0 && m_arFbi.empty())//??? split
|
|
{
|
|
m_arFbi.insert(m_arFbi.begin(), elements_.back());
|
|
elements_.pop_back();
|
|
count--;
|
|
}
|
|
}
|
|
|
|
case rt_ClrtClient: proc.optional<ClrtClient>(); break;
|
|
|
|
case rt_Protect:
|
|
case rt_ScenarioProtect:
|
|
case rt_ObjProtect:
|
|
case rt_Password:
|
|
{
|
|
if (proc.optional<PROTECTION_COMMON>())
|
|
{
|
|
m_PROTECTION = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_Palette:
|
|
{
|
|
if (proc.optional<Palette>())
|
|
{
|
|
m_Palette = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_SXViewLink:
|
|
{
|
|
if (proc.optional<SXViewLink>())
|
|
{
|
|
m_SXViewLink = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_PivotChartBits:
|
|
{
|
|
if (proc.optional<PivotChartBits>())
|
|
{
|
|
m_PivotChartBits = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_SBaseRef:
|
|
{
|
|
if (proc.optional<SBaseRef>())
|
|
{
|
|
m_SBaseRef = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_Obj:
|
|
case rt_MsoDrawing:
|
|
{
|
|
MsoDrawingGroup mso_drawing_group(true);
|
|
proc.optional(mso_drawing_group);
|
|
|
|
OBJECTS objects(true);
|
|
if (proc.mandatory(objects))
|
|
{
|
|
m_OBJECTS = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
|
|
case rt_ExternSheet:
|
|
{
|
|
if (proc.optional<ExternSheet>())
|
|
{
|
|
m_ExternSheet = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_Units:
|
|
{
|
|
if (proc.mandatory<Units>())
|
|
{
|
|
m_Units = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
|
|
case rt_Chart:
|
|
{
|
|
if ( proc.mandatory<CHARTFORMATS>() )
|
|
{
|
|
m_CHARTFORMATS = elements_.back();
|
|
elements_.pop_back();
|
|
|
|
recalc((CHARTFORMATS*)m_CHARTFORMATS.get());
|
|
}
|
|
}break;
|
|
case rt_Dimensions:
|
|
case rt_SIIndex:
|
|
{
|
|
if ( proc.mandatory<SERIESDATA>() )
|
|
{
|
|
m_SERIESDATA = elements_.back();
|
|
elements_.pop_back();
|
|
|
|
recalc((SERIESDATA*)m_SERIESDATA.get());
|
|
}
|
|
}break;
|
|
|
|
case rt_Window2:
|
|
{
|
|
count = proc.repeated<WINDOW>(0, 0);
|
|
while(count > 0)
|
|
{
|
|
m_arWINDOW.insert(m_arWINDOW.begin(), elements_.back());
|
|
elements_.pop_back();
|
|
count--;
|
|
}
|
|
}break;
|
|
|
|
case rt_UserSViewBegin:
|
|
{
|
|
count = proc.repeated<CUSTOMVIEW>(0, 0);
|
|
while(count > 0)
|
|
{
|
|
m_arCUSTOMVIEW.insert(m_arCUSTOMVIEW.begin(), elements_.back());
|
|
elements_.pop_back();
|
|
count--;
|
|
}
|
|
}break;
|
|
|
|
case rt_CodeName:
|
|
{
|
|
if (proc.optional<CodeName>())
|
|
{
|
|
m_CodeName = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_CrtMlFrt:
|
|
{
|
|
if (proc.optional<CRTMLFRT>())
|
|
{
|
|
m_CRTMLFRT = elements_.back();
|
|
elements_.pop_back();
|
|
}
|
|
}break;
|
|
case rt_FrtFontList: //error in stream !!
|
|
{
|
|
count = proc.repeated<FONTLIST>(0, 0);
|
|
while(count > 0)
|
|
{
|
|
elements_.pop_back();
|
|
count--;
|
|
}
|
|
}break;
|
|
case rt_ChartFrtInfo:
|
|
{
|
|
//skipped record
|
|
count = proc.repeated<ChartFrtInfo>(0, 0);
|
|
}break;
|
|
default://unknown .... skip
|
|
{
|
|
proc.SkipRecord();
|
|
}break;
|
|
}
|
|
}
|
|
LoadHFPicture();
|
|
|
|
return true;
|
|
}
|
|
|
|
const bool ChartSheetSubstream::saveContent(BinProcessor& proc)
|
|
{
|
|
auto globInfo = proc.getGlobalWorkbookInfo();
|
|
{
|
|
if(separate && globInfo->sheets_info.size() > globInfo->current_sheet)
|
|
globInfo->sheets_info.at(globInfo->current_sheet).StreamPos = proc.GetRecordPosition();
|
|
|
|
BOF bof;
|
|
bof.dt= 0x0020;
|
|
proc.mandatory(bof);
|
|
}
|
|
if(m_WriteProtect != nullptr)
|
|
proc.mandatory(*m_WriteProtect);
|
|
if(m_SheetExt != nullptr)
|
|
proc.mandatory(*m_SheetExt);
|
|
for(auto i : m_arHFPicture)
|
|
if(i != nullptr)
|
|
proc.mandatory(*i);
|
|
if(m_PAGESETUP != nullptr)
|
|
proc.mandatory(*m_PAGESETUP);
|
|
if(m_PrintSize != nullptr)
|
|
proc.mandatory(*m_PrintSize);
|
|
else
|
|
proc.mandatory<PrintSize>();
|
|
if(!m_arRECORD12.empty())
|
|
if(m_arRECORD12[0] != nullptr)
|
|
proc.mandatory(*m_arRECORD12[0]);
|
|
if(m_BACKGROUND != nullptr)
|
|
proc.mandatory(*m_BACKGROUND);
|
|
for(auto i : m_arFbi)
|
|
if(i != nullptr)
|
|
proc.mandatory(*i);
|
|
if(m_PROTECTION != nullptr)
|
|
proc.mandatory(*m_PROTECTION);
|
|
if(m_Palette != nullptr)
|
|
proc.mandatory(*m_Palette);
|
|
if(m_SXViewLink != nullptr)
|
|
proc.mandatory(*m_SXViewLink);
|
|
if(m_PivotChartBits != nullptr)
|
|
proc.mandatory(*m_PivotChartBits);
|
|
if(m_SBaseRef != nullptr)
|
|
proc.mandatory(*m_SBaseRef);
|
|
if(m_OBJECTS != nullptr)
|
|
proc.mandatory(*m_OBJECTS);
|
|
proc.mandatory<Units>();
|
|
if(m_CHARTFORMATS != nullptr)
|
|
proc.mandatory(*m_CHARTFORMATS);
|
|
if(m_SERIESDATA != nullptr)
|
|
proc.mandatory(*m_SERIESDATA);
|
|
for(auto i : m_arWINDOW)
|
|
if(i != nullptr)
|
|
proc.mandatory(*i);
|
|
for(auto i : m_arCUSTOMVIEW)
|
|
if(i != nullptr)
|
|
proc.mandatory(*i);
|
|
if(m_CodeName != nullptr)
|
|
proc.mandatory(*m_CodeName);
|
|
proc.mandatory<EOF_T>();
|
|
return true;
|
|
}
|
|
|
|
void ChartSheetSubstream::recalc(CHARTFORMATS* charts)
|
|
{
|
|
if (charts == NULL) return;
|
|
if (charts->m_arAXISPARENT.empty()) return;
|
|
|
|
int ind_AXIS = 0;
|
|
AXISPARENT* parent0 = dynamic_cast<AXISPARENT*>(charts->m_arAXISPARENT[ind_AXIS].get());
|
|
|
|
int iCrt = -1;
|
|
for (size_t i = 0; i < parent0->m_arCRT.size(); i++)
|
|
{
|
|
CRT* crt= dynamic_cast<CRT*>(parent0->m_arCRT[i].get());
|
|
if (crt)
|
|
{
|
|
parent0->m_mapCRTIndex.insert(std::make_pair(crt->m_indexCrt, i));
|
|
}
|
|
}
|
|
for (size_t i = 0 ; i < charts->m_arSERIESFORMAT.size(); i++)
|
|
{
|
|
SERIESFORMAT * series = dynamic_cast<SERIESFORMAT *>(charts->m_arSERIESFORMAT[i].get());
|
|
if (series == NULL) continue;
|
|
|
|
SerParent *parent = dynamic_cast<SerParent*>(series->m_SerParent.get());
|
|
if ( (parent) && (parent->series > 0 && parent->series <= charts->m_arSERIESFORMAT.size()))
|
|
{
|
|
SERIESFORMAT *series_owner = dynamic_cast<SERIESFORMAT *>(charts->m_arSERIESFORMAT[parent->series - 1].get());
|
|
if (series_owner)
|
|
{
|
|
series_owner->m_arSERIESFORMAT_ext.push_back(charts->m_arSERIESFORMAT[i]);
|
|
charts->m_arSERIESFORMAT[i] = BaseObjectPtr();
|
|
}
|
|
}
|
|
}
|
|
for (size_t i = 0 ; i < charts->m_arSERIESFORMAT.size(); i++)
|
|
{
|
|
SERIESFORMAT * series = dynamic_cast<SERIESFORMAT *>(charts->m_arSERIESFORMAT[i].get());
|
|
if (series == NULL) continue;
|
|
|
|
SerToCrt * serCrt = dynamic_cast<SerToCrt *>(series->m_SerToCrt.get());
|
|
if ( serCrt == NULL) continue;
|
|
|
|
iCrt = serCrt->id;
|
|
|
|
while ((parent0->m_arCRT.size() <= iCrt) && (ind_AXIS + 1 < charts->m_arAXISPARENT.size()) && (charts->m_arAXISPARENT.size() > 1))
|
|
{
|
|
parent0 = dynamic_cast<AXISPARENT*>(charts->m_arAXISPARENT[++ind_AXIS].get());
|
|
|
|
}
|
|
|
|
if (iCrt >= parent0->m_arCRT.size() || iCrt < 0)
|
|
continue;
|
|
|
|
CRT * crt = dynamic_cast<CRT*>(parent0->m_arCRT[iCrt].get());
|
|
|
|
std::unordered_map<int,std::vector<int>>::iterator it = m_mapTypeChart.find(iCrt);
|
|
if (it == m_mapTypeChart.end())
|
|
{
|
|
std::vector<int> ser;
|
|
ser.push_back(i);
|
|
m_mapTypeChart.insert(std::make_pair(iCrt, ser));
|
|
}
|
|
else
|
|
{
|
|
it->second.push_back(i);
|
|
}
|
|
}
|
|
for (size_t i = 0; i < parent0->m_arCRT.size(); i++)
|
|
{
|
|
std::unordered_map<int,std::vector<int>>::iterator it = m_mapTypeChart.find(i);
|
|
if (it == m_mapTypeChart.end())
|
|
{
|
|
std::vector<int> ser;
|
|
m_mapTypeChart.insert(std::make_pair(i, ser));
|
|
}
|
|
}
|
|
}
|
|
|
|
void ChartSheetSubstream::recalc(SERIESDATA* data)
|
|
{
|
|
}
|
|
|
|
int ChartSheetSubstream::serialize(std::wostream & _stream)
|
|
{
|
|
CHARTFORMATS *chart_formats = dynamic_cast<CHARTFORMATS*>(m_CHARTFORMATS.get());
|
|
if (!chart_formats) return 0;
|
|
|
|
AreaFormat *chart_area_format = NULL;
|
|
FRAME *chart_frame = dynamic_cast<FRAME*>(chart_formats->m_FRAME.get());
|
|
if (chart_frame) chart_area_format = dynamic_cast<AreaFormat*>(chart_frame->m_AreaFormat.get());
|
|
|
|
ShtProps *sht_props = dynamic_cast<ShtProps*>(chart_formats->m_ShtProps.get());
|
|
Chart *chart_rect = dynamic_cast<Chart*>(chart_formats->m_ChartRect.get());
|
|
|
|
DFTTEXT *default_text = (false == chart_formats->m_arDFTTEXT.empty()) ? dynamic_cast<DFTTEXT*>(chart_formats->m_arDFTTEXT[0].get()) : NULL;
|
|
|
|
std::wstring namePivotTable;
|
|
CP_XML_WRITER(_stream)
|
|
{
|
|
CP_XML_NODE(L"c:lang")
|
|
{
|
|
CP_XML_ATTR(L"val",L"en-US");
|
|
}
|
|
|
|
CP_XML_NODE(L"c:roundedCorners")
|
|
{
|
|
if ((chart_area_format) && (chart_area_format->fInvertNeg)) CP_XML_ATTR(L"val", 1); //????
|
|
else CP_XML_ATTR(L"val", 0);
|
|
}
|
|
if (m_SXViewLink)
|
|
{
|
|
SXViewLink *link = dynamic_cast<SXViewLink*>(m_SXViewLink.get());
|
|
|
|
CP_XML_NODE(L"c:pivotSource")
|
|
{
|
|
CP_XML_NODE(L"c:name")
|
|
{
|
|
std::wstring name = link->stPivotTable.value();
|
|
|
|
std::wstring::size_type pos = name.find(L"]");
|
|
std::wstring::size_type pos1 = name.find(L"!", pos);
|
|
|
|
if (std::wstring::npos != pos1)
|
|
namePivotTable = name.substr(pos1 + 1);
|
|
|
|
if (std::wstring::npos != pos)
|
|
name = L"[]" + name.substr(pos + 1);
|
|
|
|
CP_XML_STREAM() << name;
|
|
}
|
|
CP_XML_NODE(L"c:fmtId")
|
|
{
|
|
CP_XML_ATTR(L"val", 0);
|
|
}
|
|
}
|
|
}
|
|
CP_XML_NODE(L"c:chart")
|
|
{
|
|
if (false == namePivotTable.empty())
|
|
{
|
|
std::map<std::wstring, BaseObjectPtr>::iterator pFindTable = global_info_->mapPivotTableViews.find(namePivotTable);
|
|
if (pFindTable != global_info_->mapPivotTableViews.end())
|
|
{
|
|
}
|
|
//CP_XML_NODE(L"c:pivotFmts")
|
|
//{
|
|
// CP_XML_NODE(L"c:pivotFmt")
|
|
// {
|
|
// CP_XML_NODE(L"c:idx")
|
|
// {
|
|
// CP_XML_ATTR(L"val", 0);
|
|
// //<c:marker>
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
}
|
|
serialize_title (CP_XML_STREAM());
|
|
serialize_3D (CP_XML_STREAM());
|
|
serialize_plot_area (CP_XML_STREAM());
|
|
|
|
if (sht_props)
|
|
{
|
|
if (sht_props->fPlotVisOnly == true)
|
|
{
|
|
CP_XML_NODE(L"c:plotVisOnly") { CP_XML_ATTR(L"val", sht_props->fPlotVisOnly); }
|
|
}
|
|
CP_XML_NODE(L"c:dispBlanksAs")
|
|
{
|
|
switch(sht_props->mdBlank)
|
|
{
|
|
case 0: CP_XML_ATTR(L"val", L"gap"); break;
|
|
case 1: CP_XML_ATTR(L"val", L"zero"); break;
|
|
case 2: CP_XML_ATTR(L"val", L"span"); break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (chart_frame)
|
|
chart_frame->serialize(_stream);
|
|
else
|
|
{
|
|
CP_XML_NODE(L"c:spPr")
|
|
{
|
|
CP_XML_NODE(L"a:noFill");
|
|
CP_XML_NODE(L"a:ln")
|
|
{
|
|
CP_XML_NODE(L"a:noFill");
|
|
}
|
|
}
|
|
}
|
|
if ((default_text) && (default_text->m_ATTACHEDLABEL))
|
|
{
|
|
ATTACHEDLABEL* attach_lablel = dynamic_cast<ATTACHEDLABEL*>(default_text->m_ATTACHEDLABEL.get());
|
|
|
|
attach_lablel->serialize_txPr(_stream);
|
|
}
|
|
if (m_SXViewLink)
|
|
{
|
|
CP_XML_NODE(L"c:extLst")
|
|
{
|
|
CP_XML_NODE(L"c:ext")
|
|
{
|
|
CP_XML_ATTR(L"uri", L"{781A3756-C4B2-4CAC-9D66-4F8BD8637D16}");
|
|
CP_XML_ATTR(L"xmlns:c14", L"http://schemas.microsoft.com/office/drawing/2007/8/2/chart");
|
|
CP_XML_NODE(L"c14:pivotOptions")
|
|
{
|
|
CP_XML_NODE(L"c14:dropZoneFilter")
|
|
{
|
|
CP_XML_ATTR(L"val", 1);
|
|
}
|
|
CP_XML_NODE(L"c14:dropZoneCategories")
|
|
{
|
|
CP_XML_ATTR(L"val", 1);
|
|
}
|
|
CP_XML_NODE(L"c14:dropZoneData")
|
|
{
|
|
CP_XML_ATTR(L"val", 1);
|
|
}
|
|
CP_XML_NODE(L"c14:dropZoneSeries")
|
|
{
|
|
CP_XML_ATTR(L"val", 1);
|
|
}
|
|
CP_XML_NODE(L"c14:dropZonesVisible")
|
|
{
|
|
CP_XML_ATTR(L"val", 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (chart_rect)
|
|
{
|
|
global_info_->xls_converter->xlsx_context->get_drawing_context().set_absolute_anchor(
|
|
0, 0, chart_rect->dx.dVal, chart_rect->dy.dVal);
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
int ChartSheetSubstream::serialize_3D (std::wostream & _stream)
|
|
{
|
|
CHARTFORMATS *chart_formats = dynamic_cast<CHARTFORMATS*>(m_CHARTFORMATS.get());
|
|
if (!chart_formats) return 0;
|
|
|
|
Chart3d *chart3D = NULL;
|
|
|
|
BaseObjectPtr wallSpPr;
|
|
BaseObjectPtr floorSpPr;
|
|
|
|
for (size_t i = 0; i < chart_formats->m_arAXISPARENT.size(); i++)
|
|
{
|
|
AXISPARENT* parent = dynamic_cast<AXISPARENT*> (chart_formats->m_arAXISPARENT[i].get());
|
|
AxisParent* ax_parent = dynamic_cast<AxisParent*> (parent->m_AxisParent.get());
|
|
|
|
if (ax_parent->iax == 0) //primary axes
|
|
{
|
|
for (size_t i = 0 ; i < parent->m_arCRT.size() ; i++)
|
|
{
|
|
CRT* crt = dynamic_cast<CRT*>(parent->m_arCRT[i].get());
|
|
if((crt) && (crt->m_Chart3d))
|
|
{
|
|
chart3D = dynamic_cast<Chart3d*>(crt->m_Chart3d.get());
|
|
break;
|
|
}
|
|
}
|
|
|
|
AXES * axes = dynamic_cast<AXES*> (parent->m_AXES.get());
|
|
if (axes)
|
|
{
|
|
wallSpPr = axes->m_Wall_FRAME;
|
|
floorSpPr = axes->m_Floor_FRAME;
|
|
}
|
|
}
|
|
}
|
|
if (!chart3D) return 0;
|
|
|
|
CP_XML_WRITER(_stream)
|
|
{
|
|
CP_XML_NODE(L"c:view3D")
|
|
{
|
|
if (chart3D->anElev != 0)
|
|
{
|
|
CP_XML_NODE(L"c:rotX")
|
|
{
|
|
CP_XML_ATTR (L"val" , chart3D->anElev);
|
|
}
|
|
}
|
|
if (chart3D->pcHeight3D != 100 && chart3D->pcHeight3D >= 5 && chart3D->pcHeight3D <= 500)
|
|
{
|
|
CP_XML_NODE(L"c:hPercent")
|
|
{
|
|
CP_XML_ATTR (L"val" , chart3D->pcHeight3D);
|
|
}
|
|
}
|
|
if (chart3D->anRot != 0)
|
|
{
|
|
CP_XML_NODE(L"c:rotY")
|
|
{
|
|
CP_XML_ATTR (L"val" , chart3D->anRot);
|
|
}
|
|
}
|
|
CP_XML_NODE(L"c:depthPercent")
|
|
{
|
|
CP_XML_ATTR (L"val" , chart3D->pcDepth);
|
|
}
|
|
if (chart3D->fPerspective == false)
|
|
{
|
|
CP_XML_NODE(L"c:rAngAx") { CP_XML_ATTR (L"val" , L"1"); }
|
|
}
|
|
else
|
|
{
|
|
CP_XML_NODE(L"c:rAngAx")
|
|
{
|
|
CP_XML_ATTR (L"val" , L"0");
|
|
}
|
|
CP_XML_NODE(L"c:perspective")
|
|
{
|
|
CP_XML_ATTR (L"val" , chart3D->pcDist);
|
|
}
|
|
}
|
|
}
|
|
|
|
CP_XML_NODE(L"c:floor")
|
|
{
|
|
if (floorSpPr)
|
|
{
|
|
CP_XML_NODE(L"c:spPr")
|
|
{
|
|
floorSpPr->serialize(CP_XML_STREAM());
|
|
}
|
|
}
|
|
}
|
|
CP_XML_NODE(L"c:sideWall")
|
|
{
|
|
if (wallSpPr)
|
|
{
|
|
CP_XML_NODE(L"c:spPr")
|
|
{
|
|
wallSpPr->serialize(CP_XML_STREAM());
|
|
}
|
|
}
|
|
}
|
|
CP_XML_NODE(L"c:backWall")
|
|
{
|
|
if (wallSpPr)
|
|
{
|
|
CP_XML_NODE(L"c:spPr")
|
|
{
|
|
wallSpPr->serialize(CP_XML_STREAM());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
int ChartSheetSubstream::serialize_title (std::wostream & _stream)
|
|
{
|
|
CHARTFORMATS *chart_formats = dynamic_cast<CHARTFORMATS*>(m_CHARTFORMATS.get());
|
|
if (!chart_formats) return 0;
|
|
|
|
BaseObjectPtr attached_label = chart_formats->find_label(1, 0xffff);
|
|
//BaseObjectPtr dft_text = chart_formats->find_default_text(2);
|
|
|
|
ATTACHEDLABEL * title_label = dynamic_cast<ATTACHEDLABEL *>(attached_label.get());
|
|
if (title_label == NULL) return 0;
|
|
|
|
AI* title_text = dynamic_cast<AI *>(title_label->m_AI.get());
|
|
|
|
if (title_text == NULL) return 0;
|
|
if (title_text->empty()) return 0;
|
|
|
|
CP_XML_WRITER(_stream)
|
|
{
|
|
CP_XML_NODE(L"c:title")
|
|
{
|
|
attached_label->serialize(CP_XML_STREAM());
|
|
}
|
|
if (!title_text->m_SeriesText)
|
|
{
|
|
CP_XML_NODE(L"c:autoTitleDeleted")
|
|
{
|
|
CP_XML_ATTR (L"val" , 0);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
int ChartSheetSubstream::serialize_legend (std::wostream & _stream, const std::wstring & legend_entries)
|
|
{
|
|
CHARTFORMATS *chart_formats = dynamic_cast<CHARTFORMATS*>(m_CHARTFORMATS.get());
|
|
if (!chart_formats) return 0;
|
|
|
|
AXISPARENT* parent0 = dynamic_cast<AXISPARENT*>(chart_formats->m_arAXISPARENT[0].get());
|
|
if (parent0 == NULL) return 0;
|
|
|
|
if (parent0->m_arCRT.size() < 1) return 0;
|
|
|
|
//DAT* DAT_ = dynamic_cast<DAT*>(chart_formats->m_DAT.get());
|
|
//Dat *dat_legend = NULL;
|
|
//LD *dat_ld = NULL;
|
|
//if (DAT_)
|
|
//{
|
|
// dat_legend = dynamic_cast<Dat*>(DAT_->m_Dat.get());
|
|
// dat_ld = dynamic_cast<LD*>(DAT_->m_LD.get());
|
|
//}
|
|
|
|
//todooo figure out different types in one chart.. count number of series??
|
|
std::unordered_map< int, std::vector<int>>::iterator it = m_mapTypeChart.begin();
|
|
while (it != m_mapTypeChart.end())
|
|
{
|
|
CRT * crt = dynamic_cast<CRT*>(parent0->m_arCRT[it->first].get());
|
|
if (crt == NULL)
|
|
{
|
|
++it;
|
|
continue;
|
|
}
|
|
LD * ld = dynamic_cast<LD*>(crt->m_LD.get());
|
|
if (ld == NULL)
|
|
{
|
|
++it;
|
|
continue;
|
|
}
|
|
|
|
CP_XML_WRITER(_stream)
|
|
{
|
|
CP_XML_NODE(L"c:legend")
|
|
{
|
|
ld->m_countSeries = it->second.size();
|
|
ld->serialize(CP_XML_STREAM(), legend_entries);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
int ChartSheetSubstream::serialize_plot_area (std::wostream & _stream)
|
|
{
|
|
CHARTFORMATS *chart_formats = dynamic_cast<CHARTFORMATS*>(m_CHARTFORMATS.get());
|
|
if (!chart_formats) return 0;
|
|
|
|
if (chart_formats->m_arAXISPARENT.empty())
|
|
return 0;
|
|
|
|
AXISPARENT* parent0 = dynamic_cast<AXISPARENT*>(chart_formats->m_arAXISPARENT[0].get());
|
|
if (parent0 == NULL) return 0;
|
|
|
|
FRAME *PlotAreaFRAME = NULL;
|
|
Pos *PlotAreaPos = NULL;
|
|
|
|
AxisParent* ax_parent = dynamic_cast<AxisParent*> (parent0->m_AxisParent.get());
|
|
AXES* axes = dynamic_cast<AXES*> (parent0->m_AXES.get());
|
|
|
|
if ((ax_parent->iax == 0) && axes) //primary axes
|
|
{
|
|
PlotAreaFRAME = dynamic_cast<FRAME*> (axes->m_PlotArea_FRAME.get());
|
|
PlotAreaPos = dynamic_cast<Pos*> (parent0->m_Pos.get()); //outer plot area
|
|
|
|
if (PlotAreaPos && !parent0->m_arCRT.empty())
|
|
{
|
|
CRT * crt = dynamic_cast<CRT*>(parent0->m_arCRT[0].get());
|
|
if ((crt) && ( crt->m_iChartType == CHART_TYPE_Radar ||
|
|
crt->m_iChartType == CHART_TYPE_RadarArea ||
|
|
crt->m_iChartType == CHART_TYPE_Scatter))//more?
|
|
{
|
|
PlotAreaPos->m_iLayoutTarget = 2; //inner
|
|
}
|
|
}
|
|
|
|
if (PlotAreaPos && PlotAreaFRAME)
|
|
{
|
|
//FRAME *FRAME_ = dynamic_cast<FRAME*> (chart_formats->m_FRAME.get());
|
|
|
|
PlotAreaPos->m_Frame = PlotAreaFRAME->m_Frame;//FRAME_->m_Frame;
|
|
}
|
|
}
|
|
|
|
ShtProps *sht_props = dynamic_cast<ShtProps*>(chart_formats->m_ShtProps.get());
|
|
|
|
std::wstringstream stream_legend_entries;
|
|
|
|
CP_XML_WRITER(_stream)
|
|
{
|
|
CP_XML_NODE(L"c:plotArea")
|
|
{
|
|
if ((sht_props) && (sht_props->fAlwaysAutoPlotArea != false))
|
|
{
|
|
if (chart_formats->m_CrtLayout12A)
|
|
{
|
|
chart_formats->m_CrtLayout12A->serialize(CP_XML_STREAM());
|
|
}
|
|
else if (PlotAreaPos)
|
|
{
|
|
PlotAreaPos->serialize(CP_XML_STREAM());
|
|
}
|
|
}
|
|
|
|
int series_order = 0;
|
|
|
|
for (std::unordered_map<int, std::vector<int>>::iterator it = m_mapTypeChart.begin(); it != m_mapTypeChart.end(); ++it)
|
|
{
|
|
std::map<int, int>::iterator pFindIndexCrt = parent0->m_mapCRTIndex.find(it->first);
|
|
|
|
if (pFindIndexCrt == parent0->m_mapCRTIndex.end())
|
|
continue;
|
|
|
|
CRT * crt = dynamic_cast<CRT*>(parent0->m_arCRT[pFindIndexCrt->second].get());
|
|
|
|
ChartFormat *format = dynamic_cast<ChartFormat*>(crt->m_ChartFormat.get());
|
|
AXISPARENT *parent = dynamic_cast<AXISPARENT*>(chart_formats->m_arAXISPARENT[crt->m_indAXISPARENT].get());
|
|
|
|
CP_XML_NODE(crt->getOoxChartType())
|
|
{
|
|
crt->m_ChartType->serialize_attribute( CP_GET_XML_NODE());
|
|
|
|
if (crt->m_iChartType == CHART_TYPE_Scatter)
|
|
{
|
|
serialize_scatter_style(CP_XML_STREAM(), crt);
|
|
}
|
|
else if (crt->m_iChartType != CHART_TYPE_Stock)
|
|
{
|
|
crt->m_ChartType->serialize(CP_XML_STREAM());
|
|
}
|
|
|
|
format->serialize(CP_XML_STREAM());
|
|
for (size_t i = 0 ; i < it->second.size(); i++)
|
|
{
|
|
SERIESFORMAT * series = dynamic_cast<SERIESFORMAT *>(chart_formats->m_arSERIESFORMAT[it->second[i]].get());
|
|
if (series == NULL) continue;
|
|
|
|
SS * series_ss = dynamic_cast<SS *>(series->m_SS.get());
|
|
if (series_ss == NULL) continue;
|
|
|
|
series_ss->apply_crt_ss(crt->m_SS);
|
|
series_ss->m_is3D = crt->m_bIs3D;
|
|
|
|
if (crt->m_iChartType == CHART_TYPE_Pie ||
|
|
crt->m_iChartType == CHART_TYPE_BopPop ||
|
|
crt->m_iChartType == CHART_TYPE_Doughnut ||
|
|
crt->m_iChartType == CHART_TYPE_Surf )
|
|
series_ss->m_isVaried = format->fVaried;
|
|
|
|
DataFormat * series_data_format = dynamic_cast<DataFormat *>(series_ss->m_DataFormat.get());
|
|
int series_id = series_data_format->iss;
|
|
|
|
Series * ser = dynamic_cast<Series *>(series->m_Series.get());
|
|
|
|
CP_XML_NODE(L"c:ser")
|
|
{
|
|
CP_XML_NODE(L"c:idx") { CP_XML_ATTR (L"val" , series_id); }
|
|
CP_XML_NODE(L"c:order") { CP_XML_ATTR (L"val" , series_order++); }
|
|
|
|
if (!series->m_arAI.empty())
|
|
{
|
|
series->m_arAI[0]->serialize(CP_XML_STREAM());
|
|
}
|
|
|
|
series_ss->serialize(CP_XML_STREAM(), crt->m_iChartType, -1);
|
|
|
|
serialize_dPt(CP_XML_STREAM(), it->second[i], crt, (std::max)(ser->cValx, ser->cValy));//+bubbles
|
|
|
|
/* if (arPivotData.empty() == false)
|
|
{
|
|
series->set_ref(arPivotData, i * 2);
|
|
}*/
|
|
|
|
if (series->m_arAI.size() > 1)
|
|
{
|
|
if (crt->m_iChartType == CHART_TYPE_Scatter ||
|
|
crt->m_iChartType == CHART_TYPE_Bubble)
|
|
{
|
|
serialize_ser(L"c:xVal", CP_XML_STREAM(), series_id, series->m_arAI[2], ser->sdtX, ser->cValx);
|
|
serialize_ser(L"c:yVal", CP_XML_STREAM(), series_id, series->m_arAI[1], ser->sdtY, ser->cValy);
|
|
|
|
if (crt->m_iChartType == CHART_TYPE_Bubble && series->m_arAI.size() > 2)
|
|
serialize_ser(L"c:bubbleSize", CP_XML_STREAM(), series_id, series->m_arAI[3], ser->sdtBSize, ser->cValBSize);
|
|
}
|
|
else
|
|
{
|
|
|
|
serialize_ser(L"c:cat", CP_XML_STREAM(), series_id, series->m_arAI[2], ser->sdtX, ser->cValx);
|
|
serialize_ser(L"c:val", CP_XML_STREAM(), series_id, series->m_arAI[1], ser->sdtY, ser->cValy);
|
|
}
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
series->serialize_parent(CP_XML_STREAM(), chart_formats);
|
|
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
std::wstringstream stream_dLbls;
|
|
serialize_dLbls(stream_dLbls, it->second[i], crt);
|
|
|
|
if (stream_dLbls.str().empty() == false)
|
|
{
|
|
CP_XML_NODE(L"c:dLbls")
|
|
{
|
|
CP_XML_STREAM() << stream_dLbls.str();
|
|
}
|
|
}
|
|
series_ss->serialize2(CP_XML_STREAM(), crt->m_iChartType); //xlsx specifics (
|
|
}
|
|
|
|
series->serialize_legend(stream_legend_entries, it->second[i]);
|
|
}
|
|
for (size_t i = 0 ; i < crt->m_arCrtLine.size(); i++)
|
|
{
|
|
CrtLine* crtLine = dynamic_cast<CrtLine*>(crt->m_arCrtLine[i].get());
|
|
if (crtLine == NULL) continue;
|
|
if (crtLine->id == 3) continue; // leaderLines in dLbls
|
|
|
|
crtLine->m_iChartType = crt->m_iChartType;
|
|
crtLine->serialize(CP_XML_STREAM());
|
|
}
|
|
|
|
if (crt->m_DROPBAR[0] || crt->m_DROPBAR[1])
|
|
{
|
|
CP_XML_NODE(L"c:upDownBars")
|
|
{
|
|
if (crt->m_DROPBAR[0])
|
|
{
|
|
CP_XML_NODE(L"c:upBars")
|
|
{
|
|
crt->m_DROPBAR[0]->serialize(CP_XML_STREAM());
|
|
}
|
|
}
|
|
if (crt->m_DROPBAR[1])
|
|
{
|
|
CP_XML_NODE(L"c:downBars")
|
|
{
|
|
crt->m_DROPBAR[1]->serialize(CP_XML_STREAM());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
AXES * axes = dynamic_cast<AXES*>(parent->m_AXES.get());
|
|
if (axes)
|
|
{
|
|
for (size_t a = 0 ; a < axes->m_arAxesId.size(); a++)
|
|
{
|
|
CP_XML_NODE(L"c:axId")
|
|
{
|
|
CP_XML_ATTR(L"val", axes->m_arAxesId[a].first);
|
|
}
|
|
}
|
|
}
|
|
//else error complex_29s.xls
|
|
}
|
|
}
|
|
|
|
for (size_t i = 0; i < chart_formats->m_arAXISPARENT.size(); i++)
|
|
{
|
|
AXISPARENT* parent = dynamic_cast<AXISPARENT*> (chart_formats->m_arAXISPARENT[i].get());
|
|
AxisParent* ax_parent = parent ? dynamic_cast<AxisParent*>(parent->m_AxisParent.get()) : NULL;
|
|
AXES* axes = parent ? dynamic_cast<AXES*>(parent->m_AXES.get()) : NULL;
|
|
|
|
if (axes)
|
|
{
|
|
axes->serialize(CP_XML_STREAM(), ax_parent ? (ax_parent->iax != 0) : false); //secondary
|
|
}
|
|
//else error complex_29s.xls
|
|
}
|
|
|
|
if (PlotAreaFRAME)
|
|
PlotAreaFRAME->serialize(CP_XML_STREAM());
|
|
}
|
|
|
|
serialize_legend (_stream, stream_legend_entries.str());
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
int ChartSheetSubstream::serialize_scatter_style(std::wostream & _stream, CRT *crt)
|
|
{
|
|
bool bMarker = true, bSmooth = false, bLine = true;//todooo - since there are separate settings
|
|
|
|
CP_XML_WRITER(_stream)
|
|
{
|
|
CP_XML_NODE(L"c:scatterStyle")
|
|
{
|
|
if (bLine)
|
|
{
|
|
if (bSmooth && bMarker) CP_XML_ATTR (L"val" , L"smoothMarker");
|
|
else if (bSmooth) CP_XML_ATTR (L"val" , L"smooth");
|
|
else if (bMarker) CP_XML_ATTR (L"val" , L"lineMarker");
|
|
else CP_XML_ATTR (L"val" , L"line");
|
|
}
|
|
else
|
|
{
|
|
if (bMarker) CP_XML_ATTR (L"val" , L"marker");
|
|
else CP_XML_ATTR (L"val" , L"none");
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
int ChartSheetSubstream::serialize_dPt(std::wostream & _stream, int id, CRT *crt, int count_point)
|
|
{
|
|
if (crt == NULL) return 0;//1 (318).xls
|
|
|
|
CHARTFORMATS *chart_formats = dynamic_cast<CHARTFORMATS*>(m_CHARTFORMATS.get());
|
|
SERIESFORMAT *series = dynamic_cast<SERIESFORMAT *>(chart_formats->m_arSERIESFORMAT[id].get());
|
|
|
|
ChartFormat *format = dynamic_cast<ChartFormat*>(crt->m_ChartFormat.get());
|
|
|
|
std::map<int, bool> present_idx;
|
|
|
|
CP_XML_WRITER(_stream)
|
|
{
|
|
for (size_t i = 0 ; i < series->m_arPtSS.size(); i++)
|
|
{
|
|
CP_XML_NODE(L"c:dPt")
|
|
{
|
|
SS * series_ss = dynamic_cast<SS *>(series->m_arPtSS[i].get());
|
|
DataFormat * series_data_format = dynamic_cast<DataFormat *>(series_ss->m_DataFormat.get());
|
|
|
|
series_ss->m_is3D = crt->m_bIs3D;
|
|
|
|
if (crt->m_iChartType == CHART_TYPE_Pie ||
|
|
crt->m_iChartType == CHART_TYPE_BopPop ||
|
|
crt->m_iChartType == CHART_TYPE_Doughnut ||
|
|
crt->m_iChartType == CHART_TYPE_Surf )
|
|
series_ss->m_isVaried = format->fVaried;
|
|
|
|
CP_XML_NODE(L"c:idx")
|
|
{
|
|
CP_XML_ATTR(L"val", series_data_format->xi);
|
|
|
|
if (format->fVaried)
|
|
present_idx.insert(std::make_pair(series_data_format->xi, true));
|
|
}
|
|
series_ss->serialize (CP_XML_STREAM(), crt->m_iChartType, series_data_format->xi);
|
|
//series_ss->serialize2 (CP_XML_STREAM(), crt->m_iChartType); // 3d shape box not needed - Book 78 3D.xls
|
|
}
|
|
}
|
|
|
|
bool varied = false;
|
|
if (crt->m_iChartType == CHART_TYPE_Pie ||
|
|
crt->m_iChartType == CHART_TYPE_BopPop ||
|
|
crt->m_iChartType == CHART_TYPE_Doughnut ||
|
|
crt->m_iChartType == CHART_TYPE_Surf )
|
|
varied = format->fVaried;
|
|
|
|
if (varied && present_idx.size() < count_point)
|
|
{
|
|
SS * series_ss = dynamic_cast<SS *>(series->m_SS.get());
|
|
|
|
int vari_color = 0;
|
|
for (int i = 0 ; i < count_point; i++)
|
|
{
|
|
std::map<int, bool>::iterator it = present_idx.find(i);
|
|
|
|
if (it == present_idx.end())
|
|
{
|
|
CP_XML_NODE(L"c:dPt")
|
|
{
|
|
CP_XML_NODE(L"c:idx")
|
|
{
|
|
CP_XML_ATTR(L"val", i );
|
|
}
|
|
series_ss->serialize_default(CP_XML_STREAM(), crt->m_iChartType, i/*vari_color++*/);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int ChartSheetSubstream::serialize_dLbls (std::wostream & _stream, int id, CRT *crt)
|
|
{
|
|
CHARTFORMATS *chart_formats = dynamic_cast<CHARTFORMATS*>(m_CHARTFORMATS.get());
|
|
SERIESFORMAT *series = dynamic_cast<SERIESFORMAT *>(chart_formats->m_arSERIESFORMAT[id].get());
|
|
SS *series_ss = dynamic_cast<SS *>(series->m_SS.get());
|
|
DataFormat *series_df = dynamic_cast<DataFormat *>(series_ss->m_DataFormat.get());
|
|
|
|
bool is_area = (crt->m_iChartType == CHART_TYPE_Area || crt->m_iChartType == CHART_TYPE_RadarArea || crt->m_iChartType == CHART_TYPE_Bar);
|
|
int series_id = series_df->iss;
|
|
|
|
std::vector<std::pair<int, BaseObjectPtr>> labels = chart_formats->find_labels ( 4, id);
|
|
|
|
bool add_labels = false;
|
|
bool need_add_labels = false;
|
|
|
|
CP_XML_WRITER(_stream)
|
|
{
|
|
Text * text = NULL;
|
|
AttachedLabel * att_label = dynamic_cast<AttachedLabel*>(series_ss->m_AttachedLabel.get());
|
|
ATTACHEDLABEL * AT_LABEL = dynamic_cast<ATTACHEDLABEL*>(chart_formats->find_label(4, id).get());
|
|
|
|
if (AT_LABEL) text = dynamic_cast<Text*> (AT_LABEL->m_TextProperties.get());
|
|
|
|
if (att_label)
|
|
{
|
|
att_label->is_area = is_area;
|
|
series_ss->m_AttachedLabel->serialize(_stream);
|
|
add_labels = true;
|
|
}
|
|
else
|
|
{
|
|
if ((AT_LABEL) && (AT_LABEL->m_FRAME))
|
|
{
|
|
AT_LABEL->m_FRAME->serialize(_stream);
|
|
add_labels = true;
|
|
}
|
|
DataLabExtContents * data_ext_cont = NULL;
|
|
|
|
if (!data_ext_cont && AT_LABEL)
|
|
data_ext_cont = dynamic_cast<DataLabExtContents *>(AT_LABEL->m_DataLabExtContents.get());
|
|
|
|
if (!data_ext_cont && crt)
|
|
data_ext_cont = dynamic_cast<DataLabExtContents *>(crt->m_DataLabExtContents.get());
|
|
|
|
if (data_ext_cont)
|
|
{
|
|
data_ext_cont->is_area = is_area;
|
|
data_ext_cont->serialize(_stream);
|
|
add_labels = true;
|
|
}
|
|
else if (text)
|
|
{
|
|
text->is_area = is_area;
|
|
text->serialize(_stream);
|
|
add_labels = true;
|
|
}
|
|
else if (!labels.empty())
|
|
{//there are labels for individual points, but general ones are not marked
|
|
need_add_labels = true;
|
|
}
|
|
}
|
|
Pie *pie = dynamic_cast<Pie *>(crt->m_ChartType.get());
|
|
|
|
if (text)
|
|
{
|
|
if (text->dlp > 0 && text->dlp < 9 && !crt->m_Chart3d)
|
|
{
|
|
CP_XML_NODE(L"c:dLblPos")
|
|
{
|
|
switch(text->dlp)
|
|
{
|
|
case 1: CP_XML_ATTR(L"val", L"outEnd"); break;
|
|
case 2: CP_XML_ATTR(L"val", L"inEnd"); break;
|
|
case 3: CP_XML_ATTR(L"val", L"ctr"); break;
|
|
case 4: CP_XML_ATTR(L"val", L"inBase"); break;
|
|
case 5: CP_XML_ATTR(L"val", L"t"); break;
|
|
case 6: CP_XML_ATTR(L"val", L"b"); break;
|
|
case 7: CP_XML_ATTR(L"val", L"l"); break;
|
|
case 8: CP_XML_ATTR(L"val", L"r"); break;
|
|
}
|
|
}
|
|
}
|
|
CP_XML_NODE(L"c:showLegendKey") {CP_XML_ATTR(L"val", text->fShowKey);}
|
|
need_add_labels = true;
|
|
}
|
|
|
|
if ( (pie) && (pie->fShowLdrLines) )
|
|
{
|
|
CP_XML_NODE(L"c:showLeaderLines") {CP_XML_ATTR(L"val", pie->fShowLdrLines);}
|
|
need_add_labels = true;
|
|
|
|
}
|
|
if (!add_labels && need_add_labels)
|
|
{
|
|
CP_XML_NODE(L"c:showLegendKey") { CP_XML_ATTR (L"val" , 0); }
|
|
CP_XML_NODE(L"c:showVal") { CP_XML_ATTR (L"val" , 0); }
|
|
CP_XML_NODE(L"c:showPercent") { CP_XML_ATTR (L"val" , 0); }
|
|
CP_XML_NODE(L"c:showBubbleSize"){ CP_XML_ATTR (L"val" , 0); }
|
|
CP_XML_NODE(L"c:showCatName") { CP_XML_ATTR (L"val" , 0); }
|
|
CP_XML_NODE(L"c:showSerName") { CP_XML_ATTR (L"val" , 0); }
|
|
}
|
|
//labels for points (individual)
|
|
for (size_t i = 0; i < labels.size(); i++)
|
|
{
|
|
CP_XML_NODE(L"c:dLbl")
|
|
{
|
|
CP_XML_NODE(L"c:idx") {CP_XML_ATTR(L"val", labels[i].first);}
|
|
|
|
Text * text = NULL;
|
|
ATTACHEDLABEL* AT_LABEL = dynamic_cast<ATTACHEDLABEL*>(labels[i].second.get());
|
|
if (AT_LABEL)
|
|
{
|
|
//if (AT_LABEL->m_CrtLayout12) AT_LABEL->m_CrtLayout12->serialize(_stream);
|
|
//else
|
|
//if (AT_LABEL->m_Pos) AT_LABEL->m_Pos->serialize(_stream);
|
|
|
|
text = dynamic_cast<Text*> (AT_LABEL->m_TextProperties.get());
|
|
|
|
if (AT_LABEL->m_FRAME)
|
|
AT_LABEL->m_FRAME->serialize(_stream);
|
|
|
|
AT_LABEL->serialize_txPr(CP_XML_STREAM());
|
|
if (text)
|
|
{
|
|
CP_XML_NODE(L"c:showLegendKey") {CP_XML_ATTR(L"val", text->fShowKey);}
|
|
}
|
|
else
|
|
CP_XML_NODE(L"c:showLegendKey") {CP_XML_ATTR(L"val", 0);}
|
|
|
|
}
|
|
DataLabExtContents * data_ext_cont = dynamic_cast<DataLabExtContents *>(crt->m_DataLabExtContents.get());
|
|
|
|
if (!data_ext_cont && AT_LABEL)
|
|
data_ext_cont = dynamic_cast<DataLabExtContents *>(AT_LABEL->m_DataLabExtContents.get());
|
|
|
|
if (data_ext_cont)
|
|
{
|
|
data_ext_cont->is_area = is_area;
|
|
data_ext_cont->serialize(_stream);
|
|
}
|
|
else if (text)
|
|
{
|
|
text->is_area = is_area;
|
|
text->serialize(_stream);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (size_t i = 0 ; i < crt->m_arCrtLine.size(); i++)
|
|
{
|
|
CrtLine* crtLine = dynamic_cast<CrtLine*>(crt->m_arCrtLine[i].get());
|
|
if (crtLine == NULL) continue;
|
|
if (crtLine->id != 3) continue; // only leaderLines in dLbls
|
|
|
|
crtLine->m_iChartType = crt->m_iChartType;
|
|
crtLine->serialize(_stream);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int ChartSheetSubstream::serialize_ser (std::wstring sNodeSer, std::wostream & _stream, int series_id, const BaseObjectPtr & ai_, int type, int count)
|
|
{
|
|
int result = 0;
|
|
|
|
AI * ai = dynamic_cast<AI *>(ai_.get());
|
|
BRAI * brai = dynamic_cast<BRAI *>(ai->m_BRAI.get());
|
|
|
|
std::wstring formula = brai->formula.getAssembledFormula(true);
|
|
|
|
int rt = brai->rt;
|
|
bool b = brai->fUnlinkedIfmt;
|
|
int fmt = brai->ifmt;
|
|
|
|
//id
|
|
// 0 - name
|
|
// 1 - val || yVal
|
|
// 2 - cat || xVal
|
|
// 3 - bubble size
|
|
SERIESDATA * series_data = dynamic_cast<SERIESDATA *>(m_SERIESDATA.get());
|
|
SIIndex * series_cash = NULL;
|
|
|
|
int type_val = 0;
|
|
for (size_t i = 0; (series_data) && (i < series_data->m_arSIIndex.size()); i++)
|
|
{
|
|
SIIndex * si_in = dynamic_cast<SIIndex *>(series_data->m_arSIIndex[i].get());
|
|
|
|
int a1 = si_in->numIndex;
|
|
int a2 = brai->id;
|
|
if (a1 == a2)
|
|
{
|
|
if (si_in->m_arData.empty() == false)
|
|
{
|
|
switch(si_in->m_arData[0]->get_type())
|
|
{
|
|
case typeNumber: type_val = 1; break;
|
|
case typeBoolErr: type_val = 2; break;
|
|
case typeBlank: type_val = 3; break;
|
|
case typeLabel: type_val = 4; break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
series_cash = si_in;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
std::wstringstream _stream_cash;
|
|
int count_found = 0;
|
|
|
|
if ((series_cash) && (!series_cash->m_arData.empty()))
|
|
{
|
|
for (int i =0; i < count; i++)
|
|
{
|
|
CellRef ref( i, series_id , true, true);
|
|
if (series_cash->serialize(_stream_cash, i, ref.toString()) == 1) count_found++;
|
|
}
|
|
}
|
|
|
|
if ((formula.empty()) && count_found > 0)
|
|
{
|
|
std::wstring sNodeLit;
|
|
if (type == 1 ) sNodeLit = L"c:numLit";
|
|
if (type == 3 ) sNodeLit = L"c:strLit";
|
|
|
|
CP_XML_WRITER(_stream)
|
|
{
|
|
CP_XML_NODE(sNodeSer)
|
|
{
|
|
CP_XML_NODE(sNodeLit)
|
|
{
|
|
//CP_XML_NODE(L"c:formatCode") { CP_XML_STREAM() << L"General"; }
|
|
|
|
CP_XML_NODE(L"c:ptCount")
|
|
{
|
|
CP_XML_ATTR(L"val", count); // cannot use count_found - must be maximum of all report points
|
|
}
|
|
CP_XML_STREAM() << _stream_cash.str();
|
|
|
|
result = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (!formula.empty())
|
|
{
|
|
std::wstring sNodeRef;
|
|
if (type == 1) sNodeRef = L"c:numRef";
|
|
if (type == 3) sNodeRef = L"c:strRef";
|
|
|
|
CP_XML_WRITER(_stream)
|
|
{
|
|
CP_XML_NODE(sNodeSer)
|
|
{
|
|
CP_XML_NODE(sNodeRef)
|
|
{
|
|
//CP_XML_NODE(L"c:formatCode") { CP_XML_STREAM() << L"General"; }
|
|
|
|
CP_XML_NODE(L"c:f")
|
|
{
|
|
CP_XML_STREAM() << formula;
|
|
}
|
|
if (count_found > 0)
|
|
{
|
|
if (type == 1) sNodeRef = L"c:numCache";
|
|
if (type == 3) sNodeRef = L"c:strCache";
|
|
CP_XML_NODE(sNodeRef)
|
|
{
|
|
CP_XML_NODE(L"c:ptCount")
|
|
{
|
|
CP_XML_ATTR(L"val", count); // cannot use count_found - must be maximum of all report points
|
|
}
|
|
CP_XML_STREAM() << _stream_cash.str();
|
|
}
|
|
}
|
|
result = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
} // namespace XLS
|
|
|