From 21ba3ac0c9c5f56a499580ff56af1c87f73877ad Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Thu, 4 Jul 2024 15:35:36 +0300 Subject: [PATCH] fix bug #68957 --- OdfFile/Projects/Windows/OdfFormatW.vcxproj | 4 +- OdfFile/Reader/Format/paragraph_elements.h | 3 +- .../Writer/Format/odf_conversion_context.cpp | 5 + .../Writer/Format/odf_conversion_context.h | 1 + OdfFile/Writer/Format/odf_text_context.cpp | 21 ++-- OdfFile/Writer/Format/odf_text_context.h | 5 +- .../Writer/Format/odt_conversion_context.cpp | 95 +++++++++++++++---- .../Writer/Format/odt_conversion_context.h | 6 ++ OdfFile/Writer/Format/paragraph_elements.cpp | 44 +++++++++ OdfFile/Writer/Format/paragraph_elements.h | 52 +++++++--- X2tConverter/test/win32Test/X2tTest.vcxproj | 2 +- 11 files changed, 190 insertions(+), 48 deletions(-) diff --git a/OdfFile/Projects/Windows/OdfFormatW.vcxproj b/OdfFile/Projects/Windows/OdfFormatW.vcxproj index 2a11d476f3..f3700f4dee 100644 --- a/OdfFile/Projects/Windows/OdfFormatW.vcxproj +++ b/OdfFile/Projects/Windows/OdfFormatW.vcxproj @@ -62,7 +62,9 @@ - + + /bigobj %(AdditionalOptions) + diff --git a/OdfFile/Reader/Format/paragraph_elements.h b/OdfFile/Reader/Format/paragraph_elements.h index 7551c1ecf5..2b0df58891 100644 --- a/OdfFile/Reader/Format/paragraph_elements.h +++ b/OdfFile/Reader/Format/paragraph_elements.h @@ -1481,8 +1481,7 @@ private: _CP_OPT(odf_types::Bool) text_fixed_; odf_types::common_value_and_type_attlist office_value_; - office_element_ptr text_; - + office_element_ptr text_; }; CP_REGISTER_OFFICE_ELEMENT2(text_user_defined); //--------------------------------------------------------------------------------------------------- diff --git a/OdfFile/Writer/Format/odf_conversion_context.cpp b/OdfFile/Writer/Format/odf_conversion_context.cpp index 849724ada1..6b3ede1376 100644 --- a/OdfFile/Writer/Format/odf_conversion_context.cpp +++ b/OdfFile/Writer/Format/odf_conversion_context.cpp @@ -520,6 +520,11 @@ office_element_ptr odf_conversion_context::start_tabs() create_element(L"style", L"tab-stops", temporary_.elm, this, true); return temporary_.elm; } +void odf_conversion_context::add_meta(const office_element_ptr& elm) +{ + if (!elm) return; + objects_[current_object_]->meta.push_back(elm); +} void odf_conversion_context::add_meta(const std::wstring & ns, const std::wstring & name, const std::wstring & content) { if (name.empty()) return; diff --git a/OdfFile/Writer/Format/odf_conversion_context.h b/OdfFile/Writer/Format/odf_conversion_context.h index c16098f3c5..542c278920 100644 --- a/OdfFile/Writer/Format/odf_conversion_context.h +++ b/OdfFile/Writer/Format/odf_conversion_context.h @@ -127,6 +127,7 @@ public: std::wstring add_imageobject(const std::wstring & ole_file_name, bool bExternal = false); void add_meta(const std::wstring & ns, const std::wstring & name, const std::wstring & content); + void add_meta(const office_element_ptr &elm); virtual odf_style_context_ptr styles_context(); virtual void set_styles_context(odf_style_context_ptr styles_context); diff --git a/OdfFile/Writer/Format/odf_text_context.cpp b/OdfFile/Writer/Format/odf_text_context.cpp index aafce02d4c..286ca3c708 100644 --- a/OdfFile/Writer/Format/odf_text_context.cpp +++ b/OdfFile/Writer/Format/odf_text_context.cpp @@ -528,12 +528,12 @@ void odf_text_context::end_list() } //------------------------------------------------------------------------------------------ LIST -bool odf_text_context::start_field(int type, const std::wstring& value, const std::wstring& format) +office_element_ptr odf_text_context::start_field(int type, const std::wstring& value, const std::wstring& format) { - if (single_paragraph_ == true) return false; - office_element_ptr elm; + if (single_paragraph_ == true) return elm; + switch(type) { case fieldXE: @@ -614,6 +614,15 @@ bool odf_text_context::start_field(int type, const std::wstring& value, const st } }break; + case fieldUserDefined: + { + create_element(L"text", L"user-defined", elm, odf_context_); + text_user_defined* user_defined = dynamic_cast(elm.get()); + if (user_defined) + { + if (false == value.empty()) user_defined->text_name_ = value; + } + }break; } if (elm) @@ -622,10 +631,8 @@ bool odf_text_context::start_field(int type, const std::wstring& value, const st start_element(elm); current_level_.back().type = 3; - - return true; - } - return false; + } + return elm; } void odf_text_context::end_field() diff --git a/OdfFile/Writer/Format/odf_text_context.h b/OdfFile/Writer/Format/odf_text_context.h index 960a18d382..c39bce1f7c 100644 --- a/OdfFile/Writer/Format/odf_text_context.h +++ b/OdfFile/Writer/Format/odf_text_context.h @@ -59,6 +59,7 @@ namespace odf_writer fieldDate, fieldTime, fieldRef, + fieldUserDefined, fieldBibliography = 0xff + 1, fieldIndex, @@ -112,8 +113,8 @@ public: void add_element_in_span_or_par(office_element_ptr & elm); - bool start_field (int type, const std::wstring& value, const std::wstring& format); - void end_field (); + office_element_ptr start_field(int type, const std::wstring& value, const std::wstring& format); + void end_field(); void start_span (bool styled = false); void end_span (); diff --git a/OdfFile/Writer/Format/odt_conversion_context.cpp b/OdfFile/Writer/Format/odt_conversion_context.cpp index bdebe6ca24..134761cf27 100644 --- a/OdfFile/Writer/Format/odt_conversion_context.cpp +++ b/OdfFile/Writer/Format/odt_conversion_context.cpp @@ -134,6 +134,22 @@ void odt_conversion_context::end_document() } root_document_->add_child_element(seq_decls); } + if (false == mapUserDefineds.empty()) + { + office_element_ptr elm; + for (std::map::iterator it = mapUserDefineds.begin(); it != mapUserDefineds.end(); ++it) + { + create_element(L"meta", L"user-defined", elm, this, true); + + meta_user_defined * meta_user = dynamic_cast(elm.get()); + if (meta_user) + { + meta_user->meta_name_ = it->first; + meta_user->add_text(it->second); + add_meta(elm); + } + } + } if (controls_context()->is_exist_content()) { office_element_ptr forms_root_elm; @@ -620,10 +636,9 @@ void odt_conversion_context::end_hyperlink() } void odt_conversion_context::start_drop_down() { - office_element_ptr elm_drop_down; - create_element(L"text", L"drop-down", elm_drop_down, this); + create_element(L"text", L"drop-down", current_fields.back().elm, this); - text_drop_down* drop_down = dynamic_cast(elm_drop_down.get()); + text_drop_down* drop_down = dynamic_cast(current_fields.back().elm.get()); if (drop_down) drop_down->text_name_ = current_fields.back().name; @@ -638,14 +653,36 @@ void odt_conversion_context::start_drop_down() label->text_value_ = current_fields.back().items[i].first; } - elm_drop_down->add_child_element(elm); + current_fields.back().elm->add_child_element(elm); } - text_context()->start_element(elm_drop_down); + text_context()->start_element(current_fields.back().elm); } void odt_conversion_context::end_drop_down() { text_context()->end_element(); } +void odt_conversion_context::start_user_defined() +{ + mapUserDefineds.insert(std::make_pair(current_fields.back().value, L"")); + + current_fields.back().elm = text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); +} +void odt_conversion_context::end_user_defined() +{ + text_user_defined* user_defined = dynamic_cast(current_fields.back().elm.get()); + + if (user_defined) + { + std::map::iterator pFind = mapUserDefineds.find(current_fields.back().value); + + if (pFind != mapUserDefineds.end()) + { + pFind->second = user_defined->get_text_content(); + } + } + + text_context()->end_field(); +} void odt_conversion_context::start_sequence() { std::map::iterator pFind = mapSequenceDecls.find(current_fields.back().value); @@ -659,10 +696,9 @@ void odt_conversion_context::start_sequence() { index = ++pFind->second; } - office_element_ptr seq_elm; - create_element(L"text", L"sequence", seq_elm, this); + create_element(L"text", L"sequence", current_fields.back().elm, this); - text_sequence* sequence = dynamic_cast(seq_elm.get()); + text_sequence* sequence = dynamic_cast(current_fields.back().elm.get()); if (sequence) { sequence->name_ = current_fields.back().value; @@ -670,7 +706,7 @@ void odt_conversion_context::start_sequence() sequence->formula_ = L"ooow:" + current_fields.back().value + L"+1"; sequence->style_num_format_ = style_numformat(style_numformat::arabic); - text_context()->start_element(seq_elm); + text_context()->start_element(current_fields.back().elm); } } void odt_conversion_context::end_sequence() @@ -870,6 +906,20 @@ void odt_conversion_context::set_field_instr() current_fields.back().type = fieldIndex; current_fields.back().in_span = false; } + res1 = instr.find(L"DOCPROPERTY"); + if (std::wstring::npos != res1 && current_fields.back().type == 0) + { + current_fields.back().type = fieldUserDefined; + current_fields.back().in_span = false; + + std::map options = parse_instr_options(instr.substr(11)); + + std::map::iterator pFind = options.find(L" "); + if (pFind != options.end()) + { + current_fields.back().value = pFind->second; + } + } res1 = instr.find(L"TOC"); if (std::wstring::npos != res1 && current_fields.back().type == 0) { @@ -928,25 +978,25 @@ void odt_conversion_context::set_field_instr() current_fields.back().bHidePageNumbers = true; } } - ////////////////////////////////////////// + +////////////////////////////////////////// res1 = instr.find(L" "); if (std::wstring::npos != res1) { + if (current_fields.back().type == 0) + { + current_fields.back().name = instr.substr(0, res1); + } + + std::map options = parse_instr_options(instr.substr(res1 + 1)); if (current_fields.back().format.empty()) { - std::map options = parse_instr_options(instr.substr(res1 + 1)); - std::map::iterator pFind = options.find(L"@"); if (pFind != options.end()) { current_fields.back().format = pFind->second; } } - - if (current_fields.back().type == 0) - { - current_fields.back().name = instr.substr(0, res1); - } } } void odt_conversion_context::set_field_date_time(const std::wstring &date_time) @@ -1161,8 +1211,9 @@ void odt_conversion_context::end_field() } else if (current_fields.back().type == fieldSeq) start_sequence(); else if (current_fields.back().type == fieldDropDown) start_drop_down(); + else if (current_fields.back().type == fieldUserDefined)start_user_defined(); else - text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); + current_fields.back().elm = text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); } if (current_fields.back().status == 2) { @@ -1173,6 +1224,7 @@ void odt_conversion_context::end_field() if (current_fields.back().type == fieldHyperlink) end_hyperlink(); else if (current_fields.back().type == fieldSeq) end_sequence(); else if (current_fields.back().type == fieldDropDown) end_drop_down(); + else if (current_fields.back().type == fieldUserDefined)end_user_defined(); else text_context()->end_field(); current_fields.pop_back(); @@ -1320,8 +1372,9 @@ void odt_conversion_context::start_run(bool styled) } else if (current_fields.back().type == fieldSeq) start_sequence(); else if (current_fields.back().type == fieldDropDown) start_drop_down(); - else - text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); + else if (current_fields.back().type == fieldUserDefined)start_user_defined(); + else + current_fields.back().elm = text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); } text_context()->start_span(styled); @@ -1336,7 +1389,7 @@ void odt_conversion_context::start_run(bool styled) if (!current_fields.empty() && current_fields.back().status == 1 && current_fields.back().in_span)//поле стартуется в span - нужно для сохранения стиля { current_fields.back().status = 2; - text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); + current_fields.back().elm = text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); } } void odt_conversion_context::end_run() diff --git a/OdfFile/Writer/Format/odt_conversion_context.h b/OdfFile/Writer/Format/odt_conversion_context.h index b4ceae02df..02871fe5dd 100644 --- a/OdfFile/Writer/Format/odt_conversion_context.h +++ b/OdfFile/Writer/Format/odt_conversion_context.h @@ -101,6 +101,9 @@ public: void start_drop_down(); void end_drop_down(); + void start_user_defined(); + void end_user_defined(); + void start_table_of_content (); void end_table_of_content (); @@ -223,6 +226,7 @@ private: std::map mapSequenceDecls; std::map mapBookmarks; + std::mapmapUserDefineds; void add_to_root(); @@ -238,6 +242,8 @@ private: _CP_OPT(color) color_; + office_element_ptr elm; + short status = 0;//0, 1, 2, 3 - init, prapare, start, finish bool in_span = false; bool result = false; //after separate diff --git a/OdfFile/Writer/Format/paragraph_elements.cpp b/OdfFile/Writer/Format/paragraph_elements.cpp index 7be3984343..e9efafe615 100644 --- a/OdfFile/Writer/Format/paragraph_elements.cpp +++ b/OdfFile/Writer/Format/paragraph_elements.cpp @@ -1192,5 +1192,49 @@ void text_label::serialize(std::wostream & _Wostream) } } } +//---------------------------------------------------------------------------------- +// text:user-defined +//---------------------------------------------------------------------------------- +const wchar_t* text_user_defined::ns = L"text"; +const wchar_t* text_user_defined::name = L"user-defined"; + +void text_user_defined::add_child_element(const office_element_ptr& child_element) +{ + if (!child_element) return; + + content_.push_back(child_element); +} +std::wstring text_user_defined::get_text_content() +{ + std::wstringstream strm; + for (size_t i = 0; i < content_.size(); i++) + { + content_[i]->text_to_stream(strm); + } + return strm.str(); +} + +void text_user_defined::add_text(const std::wstring& Text) +{ + text_ = Text; +} +void text_user_defined::serialize(std::wostream& _Wostream) +{ + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE() + { + CP_XML_ATTR_OPT(L"text:name", text_name_); + + if (text_) + CP_XML_CONTENT(*text_); + + for (size_t i = 0; i < content_.size(); i++) + { + content_[i]->text_to_stream(CP_XML_STREAM()); + } + } + } +} } } diff --git a/OdfFile/Writer/Format/paragraph_elements.h b/OdfFile/Writer/Format/paragraph_elements.h index 9b1fb663fd..865aa75d38 100644 --- a/OdfFile/Writer/Format/paragraph_elements.h +++ b/OdfFile/Writer/Format/paragraph_elements.h @@ -658,8 +658,7 @@ public: static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextSequence; - + static const ElementType type = typeTextSequence; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element( const office_element_ptr & child_element); @@ -765,7 +764,7 @@ public: static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextTocMarkStart; + static const ElementType type = typeTextTocMarkStart; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} @@ -786,7 +785,7 @@ public: static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextTocMarkEnd; + static const ElementType type = typeTextTocMarkEnd; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} @@ -806,7 +805,7 @@ public: static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextTocMark; + static const ElementType type = typeTextTocMark; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} @@ -827,7 +826,7 @@ public: static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextAlphabeticalIndexMarkStart; + static const ElementType type = typeTextAlphabeticalIndexMarkStart; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} @@ -853,7 +852,7 @@ public: static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextAlphabeticalIndexMarkEnd; + static const ElementType type = typeTextAlphabeticalIndexMarkEnd; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} @@ -873,8 +872,7 @@ public: static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextAlphabeticalIndexMark; - + static const ElementType type = typeTextAlphabeticalIndexMark; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} virtual void add_child_element ( const office_element_ptr & child_element){} @@ -899,7 +897,7 @@ public: static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextBibliographyMark; + static const ElementType type = typeTextBibliographyMark; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} virtual void add_child_element ( const office_element_ptr & child_element){} @@ -969,8 +967,7 @@ public: static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextDropDown; - + static const ElementType type = typeTextDropDown; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element ( const office_element_ptr & child_element); @@ -993,8 +990,7 @@ public: static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextLabel; - + static const ElementType type = typeTextLabel; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} virtual void add_child_element ( const office_element_ptr & child_element){} @@ -1007,5 +1003,33 @@ public: _CP_OPT(std::wstring) text_; }; CP_REGISTER_OFFICE_ELEMENT2(text_label); +//------------------------------------------------------------------------------------------------------------------- +//text:user-defined +//--------------------------------------------------------------------------------------------------- +class text_user_defined : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const ElementType type = typeTextUserDefined; + + virtual void create_child_element(const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_child_element(const office_element_ptr& child_element); + + virtual void add_text(const std::wstring& Text); + virtual void serialize(std::wostream& _Wostream); + + std::wstring get_text_content(); + + _CP_OPT(std::wstring) style_data_style_name_; + _CP_OPT(std::wstring) text_name_; + _CP_OPT(odf_types::Bool) text_fixed_; + odf_types::common_value_and_type_attlist office_value_; + + _CP_OPT(std::wstring) text_; + office_element_ptr_array content_; +}; +CP_REGISTER_OFFICE_ELEMENT2(text_user_defined); } // namespace odf_writer } // namespace cpdoccore diff --git a/X2tConverter/test/win32Test/X2tTest.vcxproj b/X2tConverter/test/win32Test/X2tTest.vcxproj index 8223bda761..85c39cbf4c 100644 --- a/X2tConverter/test/win32Test/X2tTest.vcxproj +++ b/X2tConverter/test/win32Test/X2tTest.vcxproj @@ -74,7 +74,7 @@ ..\..\..\Common\3dParty\boost\build\win_32\lib;$(LibraryPath) - $(Platform)\$(Configuration)\ + ../../../build/lib/win_64/debug/ $(Platform)\$(Configuration)\ true ..\..\..\Common\3dParty\boost\build\win_64\include;$(IncludePath)