From ecbc73d33b3d2ea2c816458b866e9d23f217f1cb Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 23 Dec 2021 20:37:19 +0300 Subject: [PATCH] OdfFormatWriter - add convert math equation in spreadsheets and presentation --- .../OdfFormat/odf_conversion_context.cpp | 22 ++++++---- .../source/OdfFormat/odf_drawing_context.cpp | 42 +++++++++++++++---- .../source/OdfFormat/odf_drawing_context.h | 4 +- .../source/OdfFormat/odf_math_context.cpp | 4 +- .../source/OdfFormat/odf_math_context.h | 6 ++- .../Oox2OdfConverter/ConvertDrawing.cpp | 7 ++++ .../source/Oox2OdfConverter/MathConverter.cpp | 5 ++- 7 files changed, 69 insertions(+), 21 deletions(-) diff --git a/ASCOfficeOdfFileW/source/OdfFormat/odf_conversion_context.cpp b/ASCOfficeOdfFileW/source/OdfFormat/odf_conversion_context.cpp index 2e5723e2f2..3d31b26615 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/odf_conversion_context.cpp +++ b/ASCOfficeOdfFileW/source/OdfFormat/odf_conversion_context.cpp @@ -303,10 +303,13 @@ bool odf_conversion_context::start_math() { if (false == math_context_.isEmpty()) return false; - drawing_context()->start_drawing(); - drawing_context()->set_anchor(anchor_type::AsChar); - - drawing_context()->start_object(get_next_name_object()); //имитация рисованного объекта - высота-ширина ???? + if (false == math_context_.in_text_box_) + { + drawing_context()->start_drawing(); + drawing_context()->set_anchor(anchor_type::AsChar); + } + drawing_context()->start_object(get_next_name_object(), !math_context_.in_text_box_); + //имитация рисованного объекта - высота-ширина ???? create_object(false); create_element(L"math", L"math", objects_.back().content, this, true); @@ -331,10 +334,15 @@ void odf_conversion_context::end_math() _CP_OPT(double)width = convert_symbol_width(count_symbol_width); _CP_OPT(double)height = convert_symbol_width(count_symbol_height); - //drawing_context()->set_size(width, height); + //if (false == math_context_.in_text_box_) + // drawing_context()->set_size(width, height); - drawing_context()->end_object(); - drawing_context()->end_drawing(); + drawing_context()->end_object(!math_context_.in_text_box_); + + if (false == math_context_.in_text_box_) + { + drawing_context()->end_drawing(); + } } void odf_conversion_context::end_text() { diff --git a/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.cpp b/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.cpp index 72f6c19a72..7f9309a516 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.cpp +++ b/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.cpp @@ -1254,8 +1254,16 @@ void odf_drawing_context::start_element(office_element_ptr elm, office_element_p { size_t level = (int)impl_->current_level_.size(); - if (false == impl_->current_level_.empty() && elm) - impl_->current_level_.back()->add_child_element(elm); + //если фейковый предыдущий уровень (для сохранения порядка выше) - привязывааем к уровню выше + + for (int i = impl_->current_level_.size() - 1; elm && i >= 0; i--) + { + if (impl_->current_level_[i]) + { + impl_->current_level_[i]->add_child_element(elm); + break; + } + } std::wstring style_name; style* style_ = dynamic_cast(style_elm.get()); @@ -2641,9 +2649,26 @@ void odf_drawing_context::start_image(std::wstring odf_path) set_image_style_repeat(1);//default } -void odf_drawing_context::start_object(std::wstring name) +void odf_drawing_context::start_object(std::wstring name, bool in_frame) { - start_frame(); + if (in_frame) + start_frame(); + else + { + //remove text_box - он лишний (оставляя фейковый, который не запишется) + impl_->current_level_.back() = office_element_ptr(); // чтоб внутрении элементы добавлялись к тому что выше + + if (impl_->current_level_.size() > 1) + { + draw_base* draw = dynamic_cast(impl_->current_level_[impl_->current_level_.size() - 2].get()); + if (draw) + { + if (false == draw->content_.empty()) + draw->content_.pop_back(); + } + + } + } office_element_ptr object_elm; create_element(L"draw", L"object", object_elm, impl_->odf_context_); @@ -3033,11 +3058,12 @@ void odf_drawing_context::end_text_box() end_frame(); } -void odf_drawing_context::end_object() +void odf_drawing_context::end_object(bool in_frame) { end_element(); - end_frame(); + if (in_frame) + end_frame(); } void odf_drawing_context::start_object_ole(std::wstring ref) { @@ -3105,11 +3131,13 @@ void odf_drawing_context::set_text(odf_text_context* text_context) { if (text_context == NULL || impl_->current_level_.empty() ) return; + if (!impl_->current_level_.back()) return; // фейковый текстбокс к примеру + //if (impl_->is_presentation_ && *impl_->is_presentation_) return; for (size_t i = 0; i < text_context->text_elements_list_.size(); i++) { - if (text_context->text_elements_list_[i].level ==0) + if (text_context->text_elements_list_[i].level == 0) { impl_->current_level_.back()->add_child_element(text_context->text_elements_list_[i].elm); } diff --git a/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.h b/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.h index 807729effd..9691333539 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.h +++ b/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.h @@ -152,8 +152,8 @@ public: void set_text_box_tableframe (bool val); void end_text_box (); - void start_object(std::wstring ref); //формулы, диаграммы ... - void end_object(); + void start_object(std::wstring ref, bool in_frame = true); //формулы, диаграммы ... + void end_object(bool in_frame = true); void start_object_ole(std::wstring ref); void end_object_ole(); diff --git a/ASCOfficeOdfFileW/source/OdfFormat/odf_math_context.cpp b/ASCOfficeOdfFileW/source/OdfFormat/odf_math_context.cpp index 53d92a89d6..098fae5147 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/odf_math_context.cpp +++ b/ASCOfficeOdfFileW/source/OdfFormat/odf_math_context.cpp @@ -127,12 +127,12 @@ namespace odf_writer {L"̿", L"═"}, {L"⏞", L"⏞"}, {L"⃖", L"←"}, {L"⃗", L"→"}, {L"⃡", L"↔"}, {L"⃐", L"↼"}, {L"⃑", L"⇀"}, {L"̲", L"-"} //{L'', L''}, { L'', L'' }, { L'', L'' }, { L'', L'' }, { L'', L'' }, { L'', L'' }, { L'', L'' } }; - debug_stream.open(fileName); + //debug_stream.open(debug_fileName); } odf_math_context::~odf_math_context() { - debug_stream.close(); + //debug_stream.close(); } void odf_math_context::set_styles_context(odf_style_context * style_context) diff --git a/ASCOfficeOdfFileW/source/OdfFormat/odf_math_context.h b/ASCOfficeOdfFileW/source/OdfFormat/odf_math_context.h index e2ff3b6c84..d223e63719 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/odf_math_context.h +++ b/ASCOfficeOdfFileW/source/OdfFormat/odf_math_context.h @@ -89,9 +89,11 @@ namespace cpdoccore { void end_math(); - std::wofstream debug_stream;// (L"C://RK-Tech//debug.txt", std::wofstream::out); - std::string fileName = "C:\\RK-Tech\\debugLog.txt"; + std::wofstream debug_stream; + std::string debug_fileName = "debugLog.txt"; bool isEmpty(); + + bool in_text_box_ = false; private: class Impl; _CP_PTR(Impl) impl_; diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertDrawing.cpp b/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertDrawing.cpp index b098268979..177953aa6d 100644 --- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertDrawing.cpp +++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertDrawing.cpp @@ -2461,6 +2461,13 @@ void OoxConverter::convert(PPTX::Logic::Br *oox_br) void OoxConverter::convert(PPTX::Logic::MathParaWrapper *oox_math) { if (!oox_math) return; + + odf_context()->math_context()->in_text_box_ = true; + + convert(oox_math->m_oMathPara.GetPointer()); + convert(oox_math->m_oMath.GetPointer()); + + odf_context()->math_context()->in_text_box_ = false; } void OoxConverter::convert(PPTX::Logic::LineTo *oox_geom_path) { diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/MathConverter.cpp b/ASCOfficeOdfFileW/source/Oox2OdfConverter/MathConverter.cpp index d99b7b4341..a73b119fba 100644 --- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/MathConverter.cpp +++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/MathConverter.cpp @@ -954,7 +954,10 @@ namespace Oox2Odf { if (!oox_nary) return; nullable>* ref = NULL; - if(oox_nary->m_oNaryPr->m_oCtrlPr->m_oRPr->m_oColor.IsInit()) + + if (oox_nary->m_oNaryPr->m_oCtrlPr.IsInit() && + oox_nary->m_oNaryPr->m_oCtrlPr->m_oRPr.IsInit() && + oox_nary->m_oNaryPr->m_oCtrlPr->m_oRPr->m_oColor.IsInit()) { ref = &(oox_nary->m_oNaryPr->m_oCtrlPr->m_oRPr->m_oColor->m_oVal); }