/* * (c) Copyright Ascensio System SIA 2010-2017 * * 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 Lubanas st. 125a-25, Riga, Latvia, * EU, LV-1021. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ #include "ChartSheetSubstream.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../XlsXlsxConverter/XlsConverter.h" #include "../../XlsXlsxConverter/xlsx_conversion_context.h" namespace XLS {; ChartSheetSubstream::ChartSheetSubstream() { } 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) { // pGlobalWorkbookInfo = proc.getGlobalWorkbookInfo(); // // if(!proc.mandatory()) // { // return false; // } // int count = 0 ; // // proc.optional(); // proc.optional(); // proc.optional(); // proc.repeated(0, 0); // proc.mandatory(); // proc.mandatory(); // proc.optional(); // // if (proc.optional()) // { // m_BACKGROUND = elements_.back(); // elements_.pop_back(); // } // // count = proc.repeated(0, 0); // while(count > 0) // { // m_arFbi.insert(m_arFbi.begin(), elements_.back()); // elements_.pop_back(); // count--; // } // count = proc.repeated(0, 0); // // while(count > 0 && m_arFbi.empty())//??? разделить // { // m_arFbi.insert(m_arFbi.begin(), elements_.back()); // elements_.pop_back(); // count--; // } // // proc.optional(); // proc.optional(); // proc.optional(); // proc.optional(); // proc.optional(); // proc.optional(); // // MsoDrawingGroup mso_drawing_group(true); // proc.optional(mso_drawing_group); // // OBJECTS objects(true); // if (proc.mandatory(objects)) // { // m_OBJECTSCHART = elements_.back(); // elements_.pop_back(); // } // // proc.mandatory(); // if ( proc.mandatory() ) // { // m_CHARTFORMATS = elements_.back(); // elements_.pop_back(); // // recalc((CHARTFORMATS*)m_CHARTFORMATS.get()); // } // if ( proc.mandatory() ) // { // m_SERIESDATA = elements_.back(); // elements_.pop_back(); // // recalc((SERIESDATA*)m_SERIESDATA.get()); // } // // count = proc.repeated(0, 0); // while(count > 0) // { // m_arWINDOW.insert(m_arWINDOW.begin(), elements_.back()); // elements_.pop_back(); // count--; // } // // count = proc.repeated(0, 0); // while(count > 0) // { // m_arCUSTOMVIEW.insert(m_arCUSTOMVIEW.begin(), elements_.back()); // elements_.pop_back(); // count--; // } // // proc.optional(); // proc.optional(); // //#pragma message("####################### Some trash records may be skipped here") // proc.SeekToEOF(); // Thus we skip problems with the trash at the end of the stream (found in Domens.xls) // // proc.mandatory(); // // return true; //------------------------------------------------------------------------------ pGlobalWorkbookInfo = proc.getGlobalWorkbookInfo(); int count = 0 ; if(!proc.mandatory()) { return false; } while (true) { CFRecordType::TypeId type = proc.getNextRecordType(); //Log::warning(CFRecordType::getStringById(type)); if (type == rt_NONE || type == rt_BOF ) break; if (type == rt_EOF) { proc.mandatory(); break; } switch(type) { case rt_WriteProtect: proc.optional(); break; case rt_SheetExt: proc.optional(); break; case rt_WebPub: proc.optional(); break; case rt_HFPicture: proc.repeated(0, 0); break; case rt_Header: case rt_Footer: case rt_BottomMargin: case rt_TopMargin: case rt_LeftMargin: case rt_RightMargin: proc.mandatory(); break; case rt_PrintSize: proc.mandatory(); break; case rt_HeaderFooter: proc.optional(); break; case rt_BkHim: { if (proc.optional()) { m_BACKGROUND = elements_.back(); elements_.pop_back(); } }break; case rt_Fbi: { count = proc.repeated(0, 0); while(count > 0) { m_arFbi.insert(m_arFbi.begin(), elements_.back()); elements_.pop_back(); count--; } }break; case rt_Fbi2: { count = proc.repeated(0, 0); while(count > 0 && m_arFbi.empty())//??? разделить { m_arFbi.insert(m_arFbi.begin(), elements_.back()); elements_.pop_back(); count--; } } case rt_ClrtClient: proc.optional(); break; case rt_Protect: case rt_ScenarioProtect: case rt_ObjProtect: case rt_Password: proc.optional(); break; case rt_Palette: proc.optional(); break; case rt_SXViewLink: proc.optional(); break; case rt_PivotChartBits: proc.optional(); break; case rt_SBaseRef: proc.optional(); 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_OBJECTSCHART = elements_.back(); elements_.pop_back(); } }break; case rt_ExternSheet: { if (proc.optional()) { } }break; case rt_Units: proc.mandatory(); break; case rt_Chart: { if ( proc.mandatory() ) { m_CHARTFORMATS = elements_.back(); elements_.pop_back(); recalc((CHARTFORMATS*)m_CHARTFORMATS.get()); } }break; case rt_Dimensions: case rt_SIIndex: { if ( proc.mandatory() ) { m_SERIESDATA = elements_.back(); elements_.pop_back(); recalc((SERIESDATA*)m_SERIESDATA.get()); } }break; case rt_Window2: { count = proc.repeated(0, 0); while(count > 0) { m_arWINDOW.insert(m_arWINDOW.begin(), elements_.back()); elements_.pop_back(); count--; } }break; case rt_UserSViewBegin: { count = proc.repeated(0, 0); while(count > 0) { m_arCUSTOMVIEW.insert(m_arCUSTOMVIEW.begin(), elements_.back()); elements_.pop_back(); count--; } }break; case rt_CodeName: proc.optional(); break; case rt_CrtMlFrt: proc.optional(); break; default://unknown .... skip { proc.SkipRecord(); }break; } } 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(charts->m_arAXISPARENT[ind_AXIS].get()); int iCrt = -1; for (int i = 0 ; i < charts->m_arSERIESFORMAT.size(); i++) { SERIESFORMAT * series = dynamic_cast(charts->m_arSERIESFORMAT[i].get()); if (series == NULL) continue; SerToCrt * serCrt = dynamic_cast(series->m_SerToCrt.get()); if ( serCrt == NULL) { //для доп линий может и не существовать - брать предыдущий - и объеденить!!! std::map>::iterator it = m_mapTypeChart.find(iCrt); if (it != m_mapTypeChart.end()) { SERIESFORMAT * series_prev = dynamic_cast(charts->m_arSERIESFORMAT[it->second.back()].get()); if (series_prev) { series_prev->m_SERIESFORMAT_ext = charts->m_arSERIESFORMAT[i]; } } continue; } iCrt = serCrt->id; while ((parent0->m_arCRT.size() <= iCrt) && (ind_AXIS < charts->m_arAXISPARENT.size()) && (charts->m_arAXISPARENT.size() > 1)) { parent0 = dynamic_cast(charts->m_arAXISPARENT[++ind_AXIS].get()); } if (iCrt >= parent0->m_arCRT.size() || iCrt < 0) continue; CRT * crt = dynamic_cast(parent0->m_arCRT[iCrt].get()); std::map>::iterator it = m_mapTypeChart.find(iCrt); if (it == m_mapTypeChart.end()) { std::vector ser; ser.push_back(i); m_mapTypeChart.insert(std::pair>(iCrt, ser)); } else { it->second.push_back(i); } } } void ChartSheetSubstream::recalc(SERIESDATA* data) { } int ChartSheetSubstream::serialize (std::wostream & _stream) { AreaFormat *chart_area_format = NULL; CHARTFORMATS *chart_formats = dynamic_cast(m_CHARTFORMATS.get()); if (!chart_formats) return 0; FRAME *chart_frame = dynamic_cast(chart_formats->m_FRAME.get()); if (chart_frame) chart_area_format = dynamic_cast(chart_frame->m_AreaFormat.get()); ShtProps *sht_props = dynamic_cast(chart_formats->m_ShtProps.get()); Chart *chart_rect = dynamic_cast(chart_formats->m_ChartRect.get()); CP_XML_WRITER(_stream) { 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); } CP_XML_NODE(L"c:chart") { 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 (chart_rect) { pGlobalWorkbookInfo->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(m_CHARTFORMATS.get()); if (!chart_formats) return 0; Chart3d *chart3D = NULL; BaseObjectPtr wallSpPr; BaseObjectPtr floorSpPr; for (int i = 0; i < chart_formats->m_arAXISPARENT.size(); i++) { AXISPARENT* parent = dynamic_cast (chart_formats->m_arAXISPARENT[i].get()); AxisParent* ax_parent = dynamic_cast (parent->m_AxisParent.get()); if ((bool)ax_parent->iax == false) //primary axes { for (int i = 0 ; i < parent->m_arCRT.size() ; i++) { CRT* crt = dynamic_cast(parent->m_arCRT[i].get()); if((crt) && (crt->m_Chart3d)) { chart3D = dynamic_cast(crt->m_Chart3d.get()); break; } } AXES * axes = dynamic_cast (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->pcHeight != 100) { CP_XML_NODE(L"c:hPercent") { CP_XML_ATTR (L"val" , chart3D->pcHeight); } } 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"true"); } } else { CP_XML_NODE(L"c:perspective") { CP_XML_ATTR (L"val" , chart3D->pcDist); CP_XML_NODE(L"c:rAngAx") { CP_XML_ATTR (L"val" , L"false"); } } } } 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(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(attached_label.get()); if (title_label == NULL) return 0; AI* title_text = dynamic_cast(title_label->m_AI.get()); if (title_text == NULL) return 0; if (!title_text->m_SeriesText && !title_text->m_BRAI) return 0; // если не выкидывать будет рисоваться placeholder 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(m_CHARTFORMATS.get()); if (!chart_formats) return 0; AXISPARENT* parent0 = dynamic_cast(chart_formats->m_arAXISPARENT[0].get()); if (parent0 == NULL) return 0; if (parent0->m_arCRT.size() < 1) return 0; //DAT* DAT_ = dynamic_cast(chart_formats->m_DAT.get()); //Dat *dat_legend = NULL; //LD *dat_ld = NULL; //if (DAT_) //{ // dat_legend = dynamic_cast(DAT_->m_Dat.get()); // dat_ld = dynamic_cast(DAT_->m_LD.get()); //} //todooo разобраться с разными типами в одном чарте .. считать количество серий?? std::map< int, std::vector>::iterator it = m_mapTypeChart.begin(); if (it != m_mapTypeChart.end()) { CRT * crt = dynamic_cast(parent0->m_arCRT[it->first].get()); LD * ld = dynamic_cast(crt->m_LD.get()); if (ld == NULL) return 0; CP_XML_WRITER(_stream) { CP_XML_NODE(L"c:legend") { ld->m_countSeries = it->second.size(); ld->serialize(CP_XML_STREAM(), legend_entries); } } } return 0; } int ChartSheetSubstream::serialize_plot_area (std::wostream & _stream) { CHARTFORMATS *chart_formats = dynamic_cast(m_CHARTFORMATS.get()); if (!chart_formats) return 0; AXISPARENT* parent0 = dynamic_cast(chart_formats->m_arAXISPARENT[0].get()); if (parent0 == NULL) return 0; FRAME *PlotAreaFRAME = NULL; Pos *PlotAreaPos = NULL; AxisParent* ax_parent = dynamic_cast (parent0->m_AxisParent.get()); AXES* axes = dynamic_cast (parent0->m_AXES.get()); if (((bool)ax_parent->iax == false) && axes) //primary axes { PlotAreaFRAME = dynamic_cast (axes->m_PlotArea_FRAME.get()); PlotAreaPos = dynamic_cast (parent0->m_Pos.get()); if (PlotAreaPos && !parent0->m_arCRT.empty()) { CRT * crt = dynamic_cast(parent0->m_arCRT[0].get()); if ((crt) && ( crt->m_iChartType == CHART_TYPE_Radar || crt->m_iChartType == CHART_TYPE_RadarArea))//еще? { PlotAreaPos->m_iLayoutTarget = 2; //inner } } if (PlotAreaPos && PlotAreaFRAME) { PlotAreaPos->m_Frame = PlotAreaFRAME->m_Frame; } } ShtProps *sht_props = dynamic_cast(chart_formats->m_ShtProps.get()); std::wstringstream stream_legend_entries; CP_XML_WRITER(_stream) { CP_XML_NODE(L"c:plotArea") { for (int i = 0; i < chart_formats->m_arAXISPARENT.size(); i++) { AXISPARENT* parent = dynamic_cast (chart_formats->m_arAXISPARENT[i].get()); ax_parent = dynamic_cast (parent->m_AxisParent.get()); axes = dynamic_cast (parent->m_AXES.get()); //if (((bool)ax_parent->iax == false) && axes) //primary axes //{ // PlotAreaFRAME = dynamic_cast (axes->m_PlotArea_FRAME.get()); // PlotAreaPos = dynamic_cast (parent->m_Pos.get()); // // if (PlotAreaFRAME && PlotAreaPos) // { // PlotAreaPos->m_Frame = PlotAreaFRAME->m_Frame; // } //} } if (PlotAreaPos && (sht_props) && (sht_props->fAlwaysAutoPlotArea != false)) { PlotAreaPos->serialize(CP_XML_STREAM()); } for (std::map>::iterator it = m_mapTypeChart.begin(); it != m_mapTypeChart.end(); it++) { CRT * crt = dynamic_cast(parent0->m_arCRT[it->first].get()); ChartFormat *format = dynamic_cast(crt->m_ChartFormat.get()); AXISPARENT *parent = dynamic_cast(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 (int i = 0 ; i < it->second.size(); i++) { SERIESFORMAT * series = dynamic_cast(chart_formats->m_arSERIESFORMAT[it->second[i]].get()); if (series == NULL) continue; SS * series_ss = dynamic_cast(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(series_ss->m_DataFormat.get()); int series_id = series_data_format->iss; Series * ser = dynamic_cast(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_id); } series->m_arAI[0]->serialize(CP_XML_STREAM()); series_ss->serialize(CP_XML_STREAM(), crt->m_iChartType); serialize_dPt(CP_XML_STREAM(), it->second[i], crt, (std::max)(ser->cValx, ser->cValy));//+bubbles 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) 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 ( } series->serialize_legend(stream_legend_entries, it->second[i]); } for (int i = 0 ; i < crt->m_arCrtLine.size(); i++) { CrtLine* crtLine = dynamic_cast(crt->m_arCrtLine[i].get()); if (crtLine == NULL) continue; 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(parent->m_AXES.get()); if (axes) { for (int 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 (int i = 0; i < chart_formats->m_arAXISPARENT.size(); i++) { AXISPARENT* parent = dynamic_cast (chart_formats->m_arAXISPARENT[i].get()); AxisParent* ax_parent = dynamic_cast (parent->m_AxisParent.get()); AXES* axes = dynamic_cast (parent->m_AXES.get()); bool secondary = ax_parent->iax; if (axes) { axes->serialize(CP_XML_STREAM(), 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 - так как есть отдельные настройки 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(m_CHARTFORMATS.get()); SERIESFORMAT *series = dynamic_cast(chart_formats->m_arSERIESFORMAT[id].get()); ChartFormat *format = dynamic_cast(crt->m_ChartFormat.get()); std::map present_idx; CP_XML_WRITER(_stream) { for (int i = 0 ; i < series->m_arPtSS.size(); i++) { CP_XML_NODE(L"c:dPt") { SS * series_ss = dynamic_cast(series->m_arPtSS[i].get()); DataFormat * series_data_format = dynamic_cast(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::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); } } 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(series->m_SS.get()); int vari_color = 0; for (int i = 0 ; i < count_point; i++) { std::map::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(m_CHARTFORMATS.get()); SERIESFORMAT *series = dynamic_cast(chart_formats->m_arSERIESFORMAT[id].get()); SS *series_ss = dynamic_cast(series->m_SS.get()); DataFormat *series_df = dynamic_cast(series_ss->m_DataFormat.get()); bool is_area = (crt->m_iChartType == CHART_TYPE_Area || crt->m_iChartType == CHART_TYPE_RadarArea); int series_id = series_df->iss; std::vector> 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(series_ss->m_AttachedLabel.get()); ATTACHEDLABEL * AT_LABEL = dynamic_cast(chart_formats->find_label(4, id).get()); if (AT_LABEL) text = dynamic_cast (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(AT_LABEL->m_DataLabExtContents.get()); if (!data_ext_cont && crt) data_ext_cont = dynamic_cast(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()) {//есть лэйблы отдельных точек, а вот общие никак не обозначены need_add_labels = true; } } if (text) { CP_XML_NODE(L"c:showLegendKey") {CP_XML_ATTR(L"val", text->fShowKey);} need_add_labels = true; } Pie *pie = dynamic_cast(crt->m_ChartType.get()); 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); } } //подписи к точкам (отдельные) for (int 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(labels[i].second.get()); if (AT_LABEL) { text = dynamic_cast (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(crt->m_DataLabExtContents.get()); if (!data_ext_cont && AT_LABEL) data_ext_cont = dynamic_cast(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); } } } } 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_.get()); BRAI * brai = dynamic_cast(ai->m_BRAI.get()); std::wstring formula = brai->formula.getAssembledFormula(); 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(m_SERIESDATA.get()); SIIndex * series_cash = NULL; int type_val = 0; for (int i = 0; (series_data) && (i < series_data->m_arSIIndex.size()); i++) { SIIndex * si_in = dynamic_cast(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; } 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); // count_found использовать нельзя - тут должно быть максимальное всех точек отчета } 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); // count_found использовать нельзя - тут должно быть максимальное всех точек отчета } CP_XML_STREAM() << _stream_cash.str(); } } result = 1; } } } } return result; } } // namespace XLS