From 9601d90671fd709fd4c96d7b2fd3d56a6457b10c Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Mon, 23 Jul 2018 17:31:39 +0300 Subject: [PATCH] OdfFormatReader - fix dataValidations, conditional formating --- .../DocFormatLib/Win32/DocFormatLib.vcproj | 2 +- .../DocFormatTest/DocFormatTest.vcproj | 4 +- .../src/docx/docx_conversion_context.cpp | 29 +++- .../src/docx/docx_conversion_context.h | 12 +- .../src/docx/xlsx_conditionalFormatting.cpp | 4 +- .../src/docx/xlsx_data_validation.cpp | 143 ++++++++++++++---- .../src/docx/xlsx_data_validation.h | 4 +- ASCOfficeOdfFile/src/odf/table_xlsx.cpp | 10 +- ASCOfficePPTXFile/PPTXLib/PPTXFormat.vcproj | 3 +- .../source/win32/XlsFormat.vcproj | 2 +- Common/3dParty/cryptopp/cryptlib.vcproj | 6 +- .../DocxFormat/Projects/DocxFormat2005.vcproj | 2 +- 12 files changed, 169 insertions(+), 52 deletions(-) diff --git a/ASCOfficeDocFile/DocFormatLib/Win32/DocFormatLib.vcproj b/ASCOfficeDocFile/DocFormatLib/Win32/DocFormatLib.vcproj index bd4f7d690c..d201419d7c 100644 --- a/ASCOfficeDocFile/DocFormatLib/Win32/DocFormatLib.vcproj +++ b/ASCOfficeDocFile/DocFormatLib/Win32/DocFormatLib.vcproj @@ -172,7 +172,7 @@ "; + output_stream() << L""; } void docx_conversion_context::end_bookmark (const std::wstring &name) diff --git a/ASCOfficeOdfFile/src/docx/docx_conversion_context.h b/ASCOfficeOdfFile/src/docx/docx_conversion_context.h index 02dbc545ef..172892b897 100644 --- a/ASCOfficeOdfFile/src/docx/docx_conversion_context.h +++ b/ASCOfficeOdfFile/src/docx/docx_conversion_context.h @@ -683,13 +683,15 @@ public: } void end_level() { - current_template.insert(std::make_pair(current_state.name, current_state)); + current_template.push_back(current_state); + + map_current_template.insert(std::make_pair(current_state.name, current_state)); current_state.clear(); } void set_current_level(const std::wstring &name) { - std::map::iterator pFind = current_template.find(name); - if (pFind == current_template.end()) + std::map::iterator pFind = map_current_template.find(name); + if (pFind == map_current_template.end()) { current_content_template_.clear(); } @@ -726,6 +728,7 @@ public: current_content_template_index_ = 0; current_content_template_.clear(); current_template.clear(); + map_current_template.clear(); current_state.clear(); caption_sequence_name.clear(); min_outline_level = -1; @@ -757,12 +760,13 @@ public: int max_outline_level; std::map outline_level_styles; bool bSeparators; + std::vector<_state> current_template; private: std::vector current_content_template_; int current_content_template_index_; - std::map current_template; + std::map map_current_template; _state current_state; //std::map sequences; std::vector sequences; diff --git a/ASCOfficeOdfFile/src/docx/xlsx_conditionalFormatting.cpp b/ASCOfficeOdfFile/src/docx/xlsx_conditionalFormatting.cpp index 1e61699ebd..92d360c624 100644 --- a/ASCOfficeOdfFile/src/docx/xlsx_conditionalFormatting.cpp +++ b/ASCOfficeOdfFile/src/docx/xlsx_conditionalFormatting.cpp @@ -61,7 +61,9 @@ namespace oox { case 3: CP_XML_ATTR(L"type", L"min"); break; case 4: CP_XML_ATTR(L"type", L"max"); break; //todooo ext - autoMax case 5: CP_XML_ATTR(L"type", L"min"); break; - case 6: CP_XML_ATTR(L"type", L"formula"); break; + case 6: CP_XML_ATTR(L"type", L"formula"); break; + case 7: CP_XML_ATTR(L"type", L"percentile");break;//BOA PARA ESTUDAR - JOGAR LOTOFACIL minha predileta 1.ods + } if (val) { diff --git a/ASCOfficeOdfFile/src/docx/xlsx_data_validation.cpp b/ASCOfficeOdfFile/src/docx/xlsx_data_validation.cpp index 81b5fe6452..187d0e5797 100644 --- a/ASCOfficeOdfFile/src/docx/xlsx_data_validation.cpp +++ b/ASCOfficeOdfFile/src/docx/xlsx_data_validation.cpp @@ -45,21 +45,20 @@ namespace cpdoccore { namespace oox { -class xlsx_dataValidation +struct xlsx_dataValidation { -public: - xlsx_dataValidation() : showErrorMessage(false), showInputMessage(false), showDropDown(false), allowBlank(false) {} - std::wstring ref; - std::wstring activate_ref; + //std::wstring activate_ref; + std::map> mapCells; + std::wstring type; std::wstring formula1; std::wstring formula2; std::wstring operator_; - bool showErrorMessage; - bool showInputMessage; - bool showDropDown; - bool allowBlank; + bool showErrorMessage = false; + bool showInputMessage = false; + bool showDropDown = false; + bool allowBlank = false; }; typedef shared_ptr::Type xlsx_dataValidation_ptr; @@ -80,9 +79,61 @@ public: for (std::map::iterator it = mapActivateDataValidations.begin(); it != mapActivateDataValidations.end(); ++it) { + //prepare + std::map>> mapCells; + for (std::map>::iterator jt = it->second->mapCells.begin(); jt != it->second->mapCells.end(); ++jt) + { + std::sort(jt->second.begin(), jt->second.end()); + std::vector> arr; + MakePairVector(jt->second, arr); + + mapCells.insert(std::make_pair(jt->first, arr)); + } + std::wstring activate_ref; + + std::map>>::iterator jt1 = mapCells.begin(); + while ( jt1 != mapCells.end() ) + { + for (size_t i = 0; i < jt1->second.size(); i++) + { + std::map>>::iterator jt2 = jt1; + while(jt2 != mapCells.end()) + { + std::map>>::iterator jt2_next = jt2; ++jt2_next; + if (jt2_next == mapCells.end() || jt2->first + 1 != jt2_next->first) + break; + + size_t j = 0; bool bFound = false; + for (size_t j = 0; j < jt2_next->second.size(); j++) + { + if (jt1->second[i].first == jt2_next->second[j].first || + jt1->second[i].second == jt2_next->second[j].second) + { + bFound = true; + break; + } + } + if (bFound) + { + jt2_next->second.erase(jt2_next->second.begin() + j, jt2_next->second.begin() + j + 1); + } + else + { + break; + } + jt2 = jt2_next; + } + if (!activate_ref.empty()) activate_ref += L" "; + activate_ref += oox::getCellAddress(jt1->first, jt1->second[i].first); + + if (jt1->first != jt2->first || jt1->second[i].first != jt1->second[i].second) + activate_ref += L":" + oox::getCellAddress(jt2->first, jt1->second[i].second); + } + ++jt1; + } CP_XML_NODE(L"dataValidation") { - CP_XML_ATTR(L"sqref", it->second->activate_ref); + CP_XML_ATTR(L"sqref", activate_ref); CP_XML_ATTR(L"allowBlank", it->second->allowBlank); CP_XML_ATTR(L"operator", it->second->operator_); CP_XML_ATTR(L"showDropDown", it->second->showDropDown); @@ -115,6 +166,21 @@ public: std::map mapDataValidations; //for all tables std::map mapActivateDataValidations; //in current table + +private: + void MakePairVector(std::vector & arInput, std::vector> &arOutput) + { + int pos = arInput[0]; + for (size_t i = 1; i < arInput.size(); i++) + { + if (arInput[i-1] + 1 != arInput[i]) + { + arOutput.push_back(std::make_pair(pos, arInput[i - 1])); + pos = arInput[i]; + } + } + arOutput.push_back(std::make_pair(pos, arInput[arInput.size() - 1])); + } }; xlsx_dataValidations_context::xlsx_dataValidations_context() : @@ -128,24 +194,48 @@ void xlsx_dataValidations_context::serialize(std::wostream & _Wostream) { return impl_->serialize(_Wostream); } -void xlsx_dataValidations_context::activate(const std::wstring & name, const std::wstring & ref) +void xlsx_dataValidations_context::activate(const std::wstring & name, int col, int row/*const std::wstring & ref*/) { std::map::iterator pFindActivate = impl_->mapActivateDataValidations.find(name); - - if (pFindActivate != impl_->mapActivateDataValidations.end()) - { - pFindActivate->second->activate_ref += L" " + ref; - } - else + + if (pFindActivate == impl_->mapActivateDataValidations.end()) { std::map::iterator pFind = impl_->mapDataValidations.find(name); + xlsx_dataValidation_ptr _new; if (pFind != impl_->mapDataValidations.end()) { - pFind->second->activate_ref = ref; - impl_->mapActivateDataValidations.insert(std::make_pair(name, pFind->second)); + _new = pFind->second; } + else + { + _new = xlsx_dataValidation_ptr(new xlsx_dataValidation); + } + impl_->mapActivateDataValidations.insert(std::make_pair(name, _new)); + + pFindActivate = impl_->mapActivateDataValidations.find(name); } + + std::map>::iterator pFindCol = pFindActivate->second->mapCells.find(col); + + if (pFindCol == pFindActivate->second->mapCells.end()) + { + std::vector rows; rows.push_back(row); + pFindActivate->second->mapCells.insert(std::make_pair(col, rows)); + } + else + { + pFindCol->second.push_back(row); + } +} +void xlsx_dataValidations_context::add(const std::wstring & name, const std::wstring &ref) +{ + xlsx_dataValidation_ptr _new = xlsx_dataValidation_ptr(new xlsx_dataValidation); + + formulasconvert::odf2oox_converter converter; + _new->ref = converter.convert_named_ref(ref, false, L";"); + + impl_->mapDataValidations.insert(std::make_pair(name, _new)); } void xlsx_dataValidations_context::add_help_msg(const std::wstring & name, bool val) { @@ -164,17 +254,6 @@ void xlsx_dataValidations_context::add_error_msg(const std::wstring & name, bool pFind->second->showErrorMessage = val; } - -void xlsx_dataValidations_context::add(const std::wstring & name, const std::wstring &ref) -{ - xlsx_dataValidation_ptr _new = xlsx_dataValidation_ptr(new xlsx_dataValidation()); - - formulasconvert::odf2oox_converter converter; - _new->ref = converter.convert_named_ref(ref, false, L";"); - - impl_->mapDataValidations.insert(std::make_pair(name, _new)); -} - void xlsx_dataValidations_context::add_formula(const std::wstring & name, const std::wstring & f) // todooo пооптимальней { std::map::iterator pFind = impl_->mapDataValidations.find(name); @@ -192,11 +271,13 @@ void xlsx_dataValidations_context::add_formula(const std::wstring & name, const if ( val.substr(0, 1) == L"\"") { + std::wstring keep = val; XmlUtils::replace_all(val, L"\"", L""); pFind->second->formula1 = converter.convert(val); - if ( std::wstring::npos != val.find(L";") )//convert formula replacing ; on , + if ( (std::wstring::npos != val.find(L";")) || //convert formula replacing ; on , + L"\"" + pFind->second->formula1 + L"\"" == keep) { pFind->second->formula1 = L"\"" + pFind->second->formula1 + L"\""; } diff --git a/ASCOfficeOdfFile/src/docx/xlsx_data_validation.h b/ASCOfficeOdfFile/src/docx/xlsx_data_validation.h index 5319c9ac3d..4dcf29da46 100644 --- a/ASCOfficeOdfFile/src/docx/xlsx_data_validation.h +++ b/ASCOfficeOdfFile/src/docx/xlsx_data_validation.h @@ -44,12 +44,12 @@ public: xlsx_dataValidations_context(); ~xlsx_dataValidations_context(); - void add(const std::wstring & name, const std::wstring & ref); + void add(const std::wstring & name, /*int col, int row*/const std::wstring & ref); void add_formula(const std::wstring & name, const std::wstring & f); void add_help_msg(const std::wstring & name, bool val); void add_error_msg(const std::wstring & name, bool val); - void activate(const std::wstring & name, const std::wstring & ref); + void activate(const std::wstring & name, int col, int row/*const std::wstring & ref*/); void serialize(std::wostream & _Wostream); private: diff --git a/ASCOfficeOdfFile/src/odf/table_xlsx.cpp b/ASCOfficeOdfFile/src/odf/table_xlsx.cpp index 8f23b18027..b804a23f8d 100644 --- a/ASCOfficeOdfFile/src/odf/table_xlsx.cpp +++ b/ASCOfficeOdfFile/src/odf/table_xlsx.cpp @@ -835,7 +835,7 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context) const int sharedStringId = content_.xlsx_convert(Context, &textFormatProperties); - if (t_val == oox::XlsxCellType::str && sharedStringId >=0) + if (t_val == oox::XlsxCellType::str && sharedStringId >= 0) t_val = oox::XlsxCellType::s;//в случае текста, если он есть берем кэшированное значение if (skip_next_cell)break; @@ -846,7 +846,7 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context) std::wstring ref = oox::getCellAddress(Context.current_table_column(), Context.current_table_row()); if (attlist_.table_content_validation_name_) { - Context.get_dataValidations_context().activate(*attlist_.table_content_validation_name_, ref); + Context.get_dataValidations_context().activate(*attlist_.table_content_validation_name_, /*ref*/Context.current_table_column(), Context.current_table_row()); } CP_XML_WRITER(strm) { @@ -1087,7 +1087,7 @@ void table_covered_table_cell::xlsx_convert(oox::xlsx_conversion_context & Conte is_style_visible = (!cellStyleName.empty() || defaultColumnCellStyle) ? true : false; - if ( content_.elements_.size() > 0 || + if ( content_.elements_.size() > 0 || attlist_.table_content_validation_name_ || !formula.empty() || ( t_val == oox::XlsxCellType::n && !number_val.empty()) || ( t_val == oox::XlsxCellType::b && bool_val) || @@ -1111,6 +1111,10 @@ void table_covered_table_cell::xlsx_convert(oox::xlsx_conversion_context & Conte { Context.start_table_covered_cell (); + if (attlist_.table_content_validation_name_) + { + Context.get_dataValidations_context().activate(*attlist_.table_content_validation_name_, /*ref*/Context.current_table_column(), Context.current_table_row()); + } if (is_style_visible) Context.set_current_cell_style_id(xfId_last_set); diff --git a/ASCOfficePPTXFile/PPTXLib/PPTXFormat.vcproj b/ASCOfficePPTXFile/PPTXLib/PPTXFormat.vcproj index d42f93b7ac..049c73534b 100644 --- a/ASCOfficePPTXFile/PPTXLib/PPTXFormat.vcproj +++ b/ASCOfficePPTXFile/PPTXLib/PPTXFormat.vcproj @@ -183,7 +183,7 @@ FavorSizeOrSpeed="1" WholeProgramOptimization="false" AdditionalIncludeDirectories="..\..\Common\ASCDocxFormat\Source\Utility;..\..\Common\ASCDocxFormat\Source\XML;..\..\Common\ASCDocxFormat\Source;..\..\Common\DocxFormat\Source\XML\libxml2\XML\include;"..\..\DesktopEditor\freetype-2.5.2\include"" - PreprocessorDefinitions="NDEBUG;_LIB;_USE_MATH_DEFINES;NODOCX;PPTX_DEF;PPT_DEF;ENABLE_PPT_TO_PPTX_CONVERT;_AVS_PPT_SHAPE_INCLUDE_;_USE_LIBXML2_READER_;LIBXML_READER_ENABLED;USE_LITE_READER;_USE_XMLLITE_READER_;BUILD_CONFIG_FULL_VERSION;DONT_WRITE_EMBEDDED_FONTS" + PreprocessorDefinitions="NDEBUG;_LIB;_USE_MATH_DEFINES;_USE_LIBXML2_READER_;LIBXML_READER_ENABLED;USE_LITE_READER;_USE_XMLLITE_READER_;AVS_USE_CONVERT_PPTX_TOCUSTOM_VML;DONT_WRITE_EMBEDDED_FONTS" RuntimeLibrary="2" UsePrecompiledHeader="0" WarningLevel="3" @@ -2580,6 +2580,7 @@ > diff --git a/ASCOfficeXlsFile2/source/win32/XlsFormat.vcproj b/ASCOfficeXlsFile2/source/win32/XlsFormat.vcproj index 00a85a61ec..7886b13928 100644 --- a/ASCOfficeXlsFile2/source/win32/XlsFormat.vcproj +++ b/ASCOfficeXlsFile2/source/win32/XlsFormat.vcproj @@ -174,7 +174,7 @@