From 01776552f5b79214d6af04918b1e3549c808e588 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 27 Nov 2023 23:17:54 +0300 Subject: [PATCH] fix bug #65260 --- OdfFile/Reader/Converter/oox_plot_area.cpp | 35 ++++++++++++++------- OdfFile/Reader/Format/chart_build_oox.cpp | 1 + OdfFile/Writer/Converter/XlsxConverter.cpp | 7 +++-- OdfFile/Writer/Format/odf_chart_context.cpp | 5 +++ OdfFile/Writer/Format/ods_table_context.cpp | 28 ++++++++++++----- OdfFile/Writer/Format/ods_table_state.cpp | 9 +++++- OdfFile/Writer/Format/ods_table_state.h | 2 ++ 7 files changed, 65 insertions(+), 22 deletions(-) diff --git a/OdfFile/Reader/Converter/oox_plot_area.cpp b/OdfFile/Reader/Converter/oox_plot_area.cpp index 8abc6d61b0..1c699d53d6 100644 --- a/OdfFile/Reader/Converter/oox_plot_area.cpp +++ b/OdfFile/Reader/Converter/oox_plot_area.cpp @@ -102,7 +102,7 @@ namespace cpdoccore { charts_.push_back(chart); } - void oox_plot_area::add_axis(int type, odf_reader::chart::axis & content) + void oox_plot_area::add_axis(int type, odf_reader::chart::axis& content) { unsigned int id = axis_id_++; oox_axis_content_ptr ax = oox_axis_content::create(type, id); @@ -114,7 +114,7 @@ namespace cpdoccore { { no_used_local_tables_ = val; } - void oox_plot_area::set_data_table(odf_reader::chart::simple & content) + void oox_plot_area::set_data_table(odf_reader::chart::simple& content) { data_table_content_ = content; } @@ -142,12 +142,14 @@ namespace cpdoccore { } } } - void oox_plot_area::oox_serialize_view3D(std::wostream & _Wostream) + void oox_plot_area::oox_serialize_view3D(std::wostream& _Wostream) { _CP_OPT(std::wstring) strVal; _CP_OPT(double) doubleVal; + _CP_OPT(bool) perspective; odf_reader::GetProperty(properties_, L"transform", strVal); + odf_reader::GetProperty(properties_, L"perspective", perspective); if (!strVal) return; @@ -202,13 +204,20 @@ namespace cpdoccore { theta_z /= DEG2RAD; + if (this->current_chart_->type_ == CHART_TYPE_RADAR || + this->current_chart_->type_ == CHART_TYPE_PIE || + this->current_chart_->type_ == CHART_TYPE_DOUGHNUT) + { + theta_x += 90; + } + else theta_x = (std::abs)(theta_x); CP_XML_WRITER(_Wostream) { CP_XML_NODE(L"c:view3D") { CP_XML_NODE(L"c:rotX") { - CP_XML_ATTR(L"val", (int)(theta_x + 90.5)); + CP_XML_ATTR(L"val", (int)(theta_x + 0.5)); } CP_XML_NODE(L"c:rotY") { @@ -218,25 +227,27 @@ namespace cpdoccore { { CP_XML_ATTR(L"val", 100); } - if (theta_z == 0) + if (theta_z > 0 || (perspective && *perspective)) { CP_XML_NODE(L"c:rAngAx") { - CP_XML_ATTR(L"val", 1); + CP_XML_ATTR(L"val", 0); + } + if (theta_z > 0) + { + CP_XML_NODE(L"c:perspective") + { + CP_XML_ATTR(L"val", (int)(theta_z * 2 + 0.5)); + } } } else { CP_XML_NODE(L"c:rAngAx") { - CP_XML_ATTR(L"val", 0); - } - CP_XML_NODE(L"c:perspective") - { - CP_XML_ATTR(L"val", (int)(theta_z * 2 + 0.5)); + CP_XML_ATTR(L"val", 1); } } - } } } diff --git a/OdfFile/Reader/Format/chart_build_oox.cpp b/OdfFile/Reader/Format/chart_build_oox.cpp index a0d364c7dd..2fa5f2097f 100644 --- a/OdfFile/Reader/Format/chart_build_oox.cpp +++ b/OdfFile/Reader/Format/chart_build_oox.cpp @@ -967,6 +967,7 @@ void process_build_object::visit(chart_plot_area& val) if (attr_3d.transform_) object_odf_context_.plot_area_.properties_->push_back(_property(L"transform", attr_3d.transform_.get()) ); if (attr_3d.distance_) object_odf_context_.plot_area_.properties_->push_back(_property(L"distance", attr_3d.distance_->get_value_unit(length::pt)) ); if (attr_3d.focal_length_) object_odf_context_.plot_area_.properties_->push_back(_property(L"focal", attr_3d.focal_length_->get_value_unit(length::pt)) ); + if (attr_3d.projection_) object_odf_context_.plot_area_.properties_->push_back(_property(L"perspective", *attr_3d.projection_ == L"perspective")); } void process_build_object::visit(chart_axis& val) diff --git a/OdfFile/Writer/Converter/XlsxConverter.cpp b/OdfFile/Writer/Converter/XlsxConverter.cpp index 61d9fba8bb..880cb9f6c7 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.cpp +++ b/OdfFile/Writer/Converter/XlsxConverter.cpp @@ -3391,9 +3391,12 @@ void XlsxConverter::convert(OOX::Spreadsheet::CSparklines *sparklines) ods_context->current_table()->start_sparklines(); for (size_t i = 0; i < sparklines->m_arrItems.size(); ++i) { + if (!sparklines->m_arrItems[i]) continue; ods_context->current_table()->start_sparkline(); - ods_context->current_table()->set_sparkline_range(*sparklines->m_arrItems[i]->m_oRef); - ods_context->current_table()->set_sparkline_cell(*sparklines->m_arrItems[i]->m_oSqRef); + if (sparklines->m_arrItems[i]->m_oRef.IsInit()) + ods_context->current_table()->set_sparkline_range(*sparklines->m_arrItems[i]->m_oRef); + if (sparklines->m_arrItems[i]->m_oSqRef.IsInit()) + ods_context->current_table()->set_sparkline_cell(*sparklines->m_arrItems[i]->m_oSqRef); ods_context->current_table()->end_sparkline(); } ods_context->current_table()->end_sparklines(); diff --git a/OdfFile/Writer/Format/odf_chart_context.cpp b/OdfFile/Writer/Format/odf_chart_context.cpp index 36a5605897..9e07bf202b 100644 --- a/OdfFile/Writer/Format/odf_chart_context.cpp +++ b/OdfFile/Writer/Format/odf_chart_context.cpp @@ -642,6 +642,11 @@ void odf_chart_context::set_view3D(int rotX, int rotY, int depthPercent, int per if (impl_->current_level_.back().chart_properties) { impl_->current_level_.back().chart_properties->right_angled_axes_ = angAx; + + if (!angAx) + { + plot_area->chart_plot_area_attlist_.common_dr3d_attlist_.projection_ = L"perspective"; + } } } } diff --git a/OdfFile/Writer/Format/ods_table_context.cpp b/OdfFile/Writer/Format/ods_table_context.cpp index ba405cc273..adce22be35 100644 --- a/OdfFile/Writer/Format/ods_table_context.cpp +++ b/OdfFile/Writer/Format/ods_table_context.cpp @@ -89,7 +89,7 @@ ods_table_state_ptr & ods_table_context::state() void ods_table_context::start_table_part(const std::wstring &name, std::wstring ref) { - if (!table_database_ranges_.root) create_element(L"table", L"database-ranges",table_database_ranges_.root,&context_); + if (!table_database_ranges_.root) create_element(L"table", L"database-ranges", table_database_ranges_.root, &context_); office_element_ptr elm; create_element(L"table", L"database-range",elm, &context_); @@ -118,11 +118,17 @@ void ods_table_context::start_table_part(const std::wstring &name, std::wstring part_state.name = name; part_state.ref = ref; - int r = ref.rfind(L":"); - if (r < 0) return;//тута однозначно .. по правилам оох + size_t pos = ref.rfind(L"!"); + if (pos != std::wstring::npos) + { + ref = ref.substr(pos + 1); + } - utils::parsing_ref (ref.substr(0, r), part_state.col_start, part_state.row_start); - utils::parsing_ref (ref.substr(r + 1, ref.size() - r), part_state.col_end, part_state.row_end); + pos = ref.rfind(L":"); + if (pos == std::wstring::npos) return;//тута однозначно .. по правилам оох + + utils::parsing_ref (ref.substr(0, pos), part_state.col_start, part_state.row_start); + utils::parsing_ref (ref.substr(pos + 1, ref.size() - pos), part_state.col_end, part_state.row_end); state()->table_parts_.push_back(part_state); } @@ -138,14 +144,22 @@ void ods_table_context::add_table_part_column(std::wstring name) bool bQuotes = (std::wstring::npos != table_state_list_.back()->office_table_name_.find(L" ")); std::wstring ref = L"$"; - + std::wstring refUse = L"$"; + ref += (bQuotes ? L"'" : L"") + table_state_list_.back()->office_table_name_ + (bQuotes ? L"'" : L"") + L"."; + refUse += (bQuotes ? L"'" : L"") + table_state_list_.back()->office_table_name_ + (bQuotes ? L"'" : L"") + L"."; ref += sCol + std::to_wstring(state()->table_parts_.back().row_start); ref += L":"; ref += sCol + std::to_wstring(state()->table_parts_.back().row_end); - state()->table_parts_.back().columns.push_back(std::make_pair(name, ref)); + refUse += sCol + std::to_wstring(state()->table_parts_.back().row_start + 1); + refUse += L":"; + refUse += sCol + std::to_wstring(state()->table_parts_.back().row_end); + + state()->mapTabled.insert(std::make_pair(name, refUse)); + + state()->table_parts_.back().columns.push_back(std::make_pair(name, refUse)); } void ods_table_context::set_table_part_autofilter(bool val) { diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index ba6ddbe5dd..e51324774f 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -990,7 +990,14 @@ void ods_table_state::set_cell_spanned(int spanned_cols, int spanned_rows) } void ods_table_state::set_cell_formula(std::wstring & formula) { - if (formula.empty())return; + if (formula.empty()) return; + + //todooo used tabled columns in formula - TableName[TableColumn] + for (size_t i = 0; i < table_parts_.size(); ++i) + { + if (std::wstring::npos != formula.find(table_parts_[i].name + L"[")) + return; + } ods_conversion_context* ods_context = dynamic_cast(context_); diff --git a/OdfFile/Writer/Format/ods_table_state.h b/OdfFile/Writer/Format/ods_table_state.h index 960a6e23d0..fccbe0efa1 100644 --- a/OdfFile/Writer/Format/ods_table_state.h +++ b/OdfFile/Writer/Format/ods_table_state.h @@ -552,6 +552,8 @@ private: std::vector hyperlinks_; std::map shared_formulas_; + std::map mapTabled; // for formula used ... perhaps + std::vector table_parts_; std::vector data_validations_;