464 lines
12 KiB
C++
464 lines
12 KiB
C++
/*
|
|
* (c) Copyright Ascensio System SIA 2010-2023
|
|
*
|
|
* 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 20A-6 Ernesta Birznieka-Upish
|
|
* street, Riga, Latvia, EU, LV-1050.
|
|
*
|
|
* 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 "xlsx_textcontext.h"
|
|
#include "xlsx_conversion_context.h"
|
|
|
|
#include <iostream>
|
|
#include <list>
|
|
|
|
#include "../../Common/Utils/simple_xml_writer.h"
|
|
#include "../../../OOXML/Base/Unit.h"
|
|
|
|
namespace oox {
|
|
|
|
void removeCharsFromString( std::wstring &str, std::wstring charsToRemove )
|
|
{
|
|
for ( unsigned int i = 0; i < charsToRemove.length(); ++i )
|
|
{
|
|
str.erase( std::remove(str.begin(), str.end(), charsToRemove[i]), str.end() );
|
|
}
|
|
}
|
|
|
|
class xlsx_text_context::Impl: boost::noncopyable
|
|
{
|
|
public:
|
|
Impl();
|
|
public:
|
|
void add_text(const std::wstring & text);
|
|
|
|
void start_paragraph(const std::wstring & styleName);
|
|
void end_paragraph();
|
|
|
|
void start_span(const std::wstring & styleName);
|
|
void end_span();
|
|
std::wstring end_span2();
|
|
|
|
void start_cell_content();
|
|
void set_cell_text_properties( );
|
|
int end_cell_content(bool need_cache);
|
|
|
|
void start_comment_content();
|
|
std::wstring end_comment_content();
|
|
|
|
void start_drawing_content();
|
|
std::wstring end_drawing_content();
|
|
|
|
|
|
void ApplyTextProperties();
|
|
|
|
void set_local_styles_container();//это если стили объектов содержатся в другом документе
|
|
|
|
bool is_drawing_context(){return in_draw;}
|
|
|
|
void end_hyperlink(std::wstring hId);
|
|
void start_hyperlink();
|
|
|
|
private:
|
|
std::wstring hyperlink_hId;
|
|
|
|
bool in_draw;
|
|
bool in_comment;
|
|
bool in_span;
|
|
bool in_paragraph;
|
|
bool in_cell_content;
|
|
|
|
//odf_reader::styles_container & styles_;
|
|
//odf_reader::text_format_properties * text_properties_cell_;
|
|
//odf_reader::styles_container * local_styles_ptr_;
|
|
|
|
std::wstring dump_text();
|
|
void write_rPr(std::wostream & strm);
|
|
|
|
size_t paragraphs_cout_; //???? тока из за начала отсчета?
|
|
|
|
std::wstringstream text_;
|
|
std::wstringstream output_;
|
|
|
|
std::wstring paragraph_style_name_;//был вектор ... не нужен, так как в один момент времени может быть тока один стиль параграфа,текста,объекта при приходе нового - дампится
|
|
std::wstring span_style_name_;
|
|
|
|
};
|
|
|
|
|
|
|
|
xlsx_text_context::Impl::Impl(): paragraphs_cout_(0),
|
|
in_comment(false),in_draw(false),in_paragraph(false),in_span(false),in_cell_content(false)
|
|
{
|
|
//text_properties_cell_ = NULL;
|
|
}
|
|
|
|
void xlsx_text_context::Impl::add_text(const std::wstring & text)
|
|
{
|
|
text_ << text;
|
|
|
|
if (!in_comment && !in_draw)
|
|
dump_text();
|
|
}
|
|
|
|
void xlsx_text_context::Impl::set_local_styles_container(/*odf_reader::styles_container * local_styles_*/)
|
|
{
|
|
//local_styles_ptr_= local_styles_;
|
|
}
|
|
|
|
void xlsx_text_context::Impl::start_paragraph(const std::wstring & styleName)
|
|
{
|
|
if (paragraphs_cout_++ > 0)
|
|
{
|
|
if (paragraph_style_name_ != styleName)
|
|
{
|
|
dump_text();
|
|
}
|
|
}else
|
|
{
|
|
text_.str(std::wstring());
|
|
}
|
|
paragraph_style_name_ = styleName;
|
|
in_paragraph = true;
|
|
}
|
|
|
|
void xlsx_text_context::Impl::end_paragraph()
|
|
{
|
|
if (!in_comment && !in_draw)
|
|
{
|
|
dump_text();
|
|
paragraph_style_name_ = L"";
|
|
}
|
|
in_paragraph = false;
|
|
}
|
|
|
|
void xlsx_text_context::Impl::start_span(const std::wstring & styleName)//кусок текста в абзаце(параграфе) со своими свойствами - этто может быть и 1 буква
|
|
{
|
|
if (!in_comment && !in_draw)
|
|
{
|
|
text_.str(std::wstring());
|
|
}
|
|
else
|
|
{
|
|
if (span_style_name_ !=styleName || in_span)
|
|
{
|
|
dump_text();
|
|
}
|
|
}
|
|
span_style_name_ = styleName;
|
|
in_span=true;
|
|
}
|
|
|
|
void xlsx_text_context::Impl::end_span() //odf корявенько написан - возможны повторы стилей в последовательных кусках текста
|
|
//пока с анализом стилей тока комменты - остальные текстовые куски как есть.. с охрененным возможно дубляжом
|
|
{
|
|
if (!in_comment && !in_draw)
|
|
{
|
|
dump_text();
|
|
span_style_name_=L"";
|
|
}
|
|
in_span=false;
|
|
}
|
|
|
|
std::wstring xlsx_text_context::Impl::end_span2()
|
|
{
|
|
const std::wstring content = dump_text();
|
|
span_style_name_ = L"";
|
|
|
|
in_span = false;
|
|
return content;
|
|
}
|
|
void xlsx_text_context::Impl::start_hyperlink()
|
|
{
|
|
dump_text();
|
|
}
|
|
|
|
void xlsx_text_context::Impl::end_hyperlink(std::wstring hId)
|
|
{
|
|
hyperlink_hId = hId;
|
|
}
|
|
|
|
void xlsx_text_context::Impl::ApplyTextProperties(/*std::wstring style,odf_reader::text_format_properties & propertiesOut, odf_types::style_family::type Type*/)
|
|
{
|
|
|
|
}
|
|
|
|
void xlsx_text_context::Impl::set_cell_text_properties()
|
|
{
|
|
}
|
|
|
|
void xlsx_text_context::Impl::write_rPr(std::wostream & strm)
|
|
{
|
|
|
|
CP_XML_WRITER(strm)
|
|
{
|
|
if (in_draw)
|
|
{
|
|
//oox_serialize_style_text(strm,text_properties_);
|
|
//oox_serialize_style_text(strm,odf_reader::text_format_properties & properties);
|
|
CP_XML_NODE(L"a:rPr")
|
|
{
|
|
//стр 3197
|
|
//if (dValFontSize) {CP_XML_ATTR(L"sz", (int)(dValFontSize.get()*100));}
|
|
//if ((iValFontStyle) && (iValFontStyle.get() >0)) {CP_XML_ATTR(L"i", "1");} //"true");} Exercícios de Aprendizagem.ods
|
|
//if ((iValFontWeight) && (iValFontWeight.get() >0)) {CP_XML_ATTR(L"b", "1");} //"true");} Exercícios de Aprendizagem.ods
|
|
//if (sValFontFamily) {CP_XML_ATTR(L"typeface", sValFontFamily.get());}
|
|
//
|
|
//if (sValFontColor){CP_XML_NODE(L"a:solidFill") {CP_XML_NODE(L"a:srgbClr"){CP_XML_ATTR(L"val", sValFontColor.get());}}}
|
|
|
|
if (hyperlink_hId.length()>0)
|
|
{
|
|
CP_XML_NODE(L"a:hlinkClick ")
|
|
{
|
|
CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
|
|
CP_XML_ATTR(L"r:id", hyperlink_hId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CP_XML_NODE(L"rPr")
|
|
{
|
|
//if (sValFontFamily) {CP_XML_NODE(L"rFont") {CP_XML_ATTR(L"val", sValFontFamily.get());}}
|
|
//if (dValFontSize) {CP_XML_NODE(L"sz") {CP_XML_ATTR(L"val", (int)(dValFontSize.get()));}}
|
|
//if (sValFontColor) {CP_XML_NODE(L"color") {CP_XML_ATTR(L"rgb", sValFontColor.get());}}
|
|
//if ((iValFontStyle) && (iValFontStyle.get() >0)) {CP_XML_NODE(L"i") {CP_XML_ATTR(L"val", "true");}}
|
|
//if ((iValFontWeight) && (iValFontWeight.get() >0)){CP_XML_NODE(L"b") {CP_XML_ATTR(L"val", "true");}}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::wstring xlsx_text_context::Impl::dump_text()
|
|
{
|
|
const std::wstring content = XmlUtils::EncodeXmlString(text_.str());
|
|
|
|
if (content.empty())
|
|
return content;
|
|
|
|
std::wstring prefix_draw;
|
|
if (in_draw) prefix_draw=L"a:";
|
|
|
|
CP_XML_WRITER(output_)
|
|
{
|
|
if (!content.empty())
|
|
{
|
|
CP_XML_NODE(prefix_draw + L"r")
|
|
{
|
|
write_rPr(CP_XML_STREAM());
|
|
|
|
CP_XML_NODE(prefix_draw + L"t")
|
|
{
|
|
if (!in_draw)CP_XML_ATTR(L"xml:space", L"preserve");
|
|
CP_XML_STREAM() << content;
|
|
}
|
|
}
|
|
text_.str(std::wstring());
|
|
}
|
|
}
|
|
|
|
hyperlink_hId =L"";
|
|
return content;
|
|
}
|
|
|
|
void xlsx_text_context::Impl::start_cell_content()
|
|
{
|
|
paragraphs_cout_ = 0;
|
|
|
|
output_.str(std::wstring());//строка дампа
|
|
|
|
text_.str(std::wstring()); //приходящие куски текста
|
|
|
|
paragraph_style_name_ = L"";
|
|
span_style_name_ = L"";
|
|
|
|
in_cell_content = true;
|
|
|
|
}
|
|
|
|
void xlsx_text_context::Impl::start_comment_content()
|
|
{
|
|
paragraphs_cout_ = 0;
|
|
|
|
output_.str(std::wstring());
|
|
text_.str(std::wstring());
|
|
|
|
paragraph_style_name_ = L"";
|
|
span_style_name_ = L"";
|
|
|
|
in_comment = true;
|
|
}
|
|
void xlsx_text_context::Impl::start_drawing_content()
|
|
{
|
|
paragraphs_cout_ = 0;
|
|
|
|
output_.str(std::wstring());
|
|
text_.str(std::wstring());
|
|
|
|
paragraph_style_name_ = L"";
|
|
span_style_name_ = L"";
|
|
|
|
in_draw = true;
|
|
}
|
|
std::wstring xlsx_text_context::Impl::end_comment_content()
|
|
{
|
|
dump_text();//если в комменте куча абзацев со одним стилем - сдампится здесь - иначе дампится по мере прихода каждого нового стиля
|
|
|
|
std::wstring comment= output_.str();
|
|
|
|
paragraphs_cout_ = 0;
|
|
|
|
output_.str(std::wstring());
|
|
text_.str(std::wstring());
|
|
|
|
paragraph_style_name_ = L"";
|
|
span_style_name_=L"";
|
|
|
|
in_comment = false;
|
|
return comment;
|
|
}
|
|
std::wstring xlsx_text_context::Impl::end_drawing_content()
|
|
{
|
|
dump_text();//если в draw куча абзацев со одним стилем - сдампится здесь - иначе дампится по мере прихода каждого нового стиля
|
|
|
|
std::wstring draw= output_.str();
|
|
|
|
paragraphs_cout_ = 0;
|
|
|
|
output_.str(std::wstring());
|
|
text_.str(std::wstring());
|
|
|
|
paragraph_style_name_ = L"";
|
|
span_style_name_=L"";
|
|
|
|
in_draw = false;
|
|
return draw;
|
|
}
|
|
int xlsx_text_context::Impl::end_cell_content(bool need_cache)
|
|
{
|
|
dump_text();
|
|
|
|
const int sharedStrId = 0;//output_.str().empty() ? (-1) : static_cast<int>(xlsx_shared_strings_.add(output_.str()));
|
|
//???? нужно ли здесь очищать все ????? - проверить стили на кучках - и проверить как меняются стили внутри одной ячейки - то есть здешнее переопределение внешнего стиля
|
|
in_cell_content = false;
|
|
return sharedStrId;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
xlsx_text_context::xlsx_text_context(): impl_(new xlsx_text_context::Impl())
|
|
{}
|
|
|
|
|
|
xlsx_text_context::~xlsx_text_context()
|
|
{
|
|
}
|
|
void xlsx_text_context::set_local_styles_container()
|
|
{
|
|
return impl_->set_local_styles_container();
|
|
}
|
|
|
|
void xlsx_text_context::set_cell_text_properties()
|
|
{
|
|
return impl_->set_cell_text_properties();
|
|
}
|
|
|
|
|
|
void xlsx_text_context::add_text(const std::wstring & text)
|
|
{
|
|
return impl_->add_text(text);
|
|
}
|
|
|
|
void xlsx_text_context::start_paragraph(const std::wstring & styleName)
|
|
{
|
|
return impl_->start_paragraph(styleName);
|
|
}
|
|
|
|
void xlsx_text_context::end_paragraph()
|
|
{
|
|
return impl_->end_paragraph();
|
|
}
|
|
|
|
void xlsx_text_context::start_span(const std::wstring & styleName)
|
|
{
|
|
return impl_->start_span(styleName);
|
|
}
|
|
|
|
void xlsx_text_context::end_span()
|
|
{
|
|
return impl_->end_span();
|
|
}
|
|
|
|
std::wstring xlsx_text_context::end_span2()
|
|
{
|
|
return impl_->end_span2();
|
|
}
|
|
bool xlsx_text_context::is_drawing_context()
|
|
{
|
|
return impl_->is_drawing_context();
|
|
}
|
|
|
|
void xlsx_text_context::start_cell_content()
|
|
{
|
|
return impl_->start_cell_content();
|
|
}
|
|
|
|
int xlsx_text_context::end_cell_content(bool need_cache)
|
|
{
|
|
return impl_->end_cell_content(need_cache);
|
|
}
|
|
|
|
void xlsx_text_context::start_comment_content()
|
|
{
|
|
return impl_->start_comment_content();
|
|
}
|
|
|
|
std::wstring xlsx_text_context::end_comment_content()
|
|
{
|
|
return impl_->end_comment_content();
|
|
}
|
|
void xlsx_text_context::start_drawing_content()
|
|
{
|
|
return impl_->start_drawing_content();
|
|
}
|
|
void xlsx_text_context::start_hyperlink()
|
|
{
|
|
return impl_->start_hyperlink();
|
|
}
|
|
void xlsx_text_context::end_hyperlink(std::wstring hId)
|
|
{
|
|
return impl_->end_hyperlink(hId);
|
|
}
|
|
std::wstring xlsx_text_context::end_drawing_content()
|
|
{
|
|
return impl_->end_drawing_content();
|
|
}
|
|
|
|
|
|
}
|