mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
fix bug #68957
This commit is contained in:
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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<text_user_defined*>(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()
|
||||
|
||||
@ -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 ();
|
||||
|
||||
@ -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<std::wstring, std::wstring>::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<meta_user_defined*>(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<text_drop_down*>(elm_drop_down.get());
|
||||
text_drop_down* drop_down = dynamic_cast<text_drop_down*>(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<text_user_defined*>(current_fields.back().elm.get());
|
||||
|
||||
if (user_defined)
|
||||
{
|
||||
std::map<std::wstring, std::wstring>::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<std::wstring, int>::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<text_sequence*>(seq_elm.get());
|
||||
text_sequence* sequence = dynamic_cast<text_sequence*>(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<std::wstring, std::wstring> options = parse_instr_options(instr.substr(11));
|
||||
|
||||
std::map<std::wstring, std::wstring>::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<std::wstring, std::wstring> options = parse_instr_options(instr.substr(res1 + 1));
|
||||
if (current_fields.back().format.empty())
|
||||
{
|
||||
std::map<std::wstring, std::wstring> options = parse_instr_options(instr.substr(res1 + 1));
|
||||
|
||||
std::map<std::wstring, std::wstring>::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()
|
||||
|
||||
@ -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<std::wstring, int> mapSequenceDecls;
|
||||
std::map<int, std::wstring> mapBookmarks;
|
||||
std::map<std::wstring, std::wstring>mapUserDefineds;
|
||||
|
||||
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
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<text_user_defined>
|
||||
{
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user