react-native-nitro-xlsx 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NitroXlsx.podspec +26 -27
- package/Package.swift +31 -10
- package/README.md +1 -1
- package/android/CMakeLists.txt +20 -27
- package/package.json +2 -2
- package/scripts/run-cpp-tests.sh +1 -1
- package/thirdparty/OpenXLSX/.clang-format +118 -0
- package/thirdparty/OpenXLSX/.clang-tidy +28 -0
- package/thirdparty/OpenXLSX/.gitignore +130 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_before_XMLNode_wrappers +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_and_stripping +49 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_char_support +49 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_support +49 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespaced_name_disabled +49 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-08-11-benchmarks_post-XLCellIterator-Rework +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-08-14-benchmarks_post-default-row-column-style-support +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-09-02-benchmarks +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-12-19-benchmarks +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-12-30-benchmarks-post-XLSharedStrings-by-ref +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-01-09-benchmarks-post-conditionalFormatsAndSheetProtection +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-01-10-benchmarks-post-XLCellValue-bugfix +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-01-31-benchmarks-post-XLComments-implementation +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-02-02-benchmarks-post-XLRowIterator-Rework +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-07-20-benchmarks-after-hiding-pugixml-internals +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-08-29-benchmarks-after-code-review-with-libzip +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/Benchmark.cpp +249 -0
- package/thirdparty/OpenXLSX/Benchmarks/CMakeLists.txt +19 -0
- package/thirdparty/OpenXLSX/CMakeLists.txt +466 -0
- package/thirdparty/OpenXLSX/Documentation/CMakeLists.txt +31 -0
- package/thirdparty/OpenXLSX/Documentation/Doxyfile.in +2471 -0
- package/thirdparty/OpenXLSX/Documentation/DoxygenLayout.xml +194 -0
- package/thirdparty/OpenXLSX/Documentation/customdoxygen.css +1355 -0
- package/thirdparty/OpenXLSX/Examples/CMakeLists.txt +103 -0
- package/thirdparty/OpenXLSX/Examples/Demo1.cpp +279 -0
- package/thirdparty/OpenXLSX/Examples/Demo10.cpp +545 -0
- package/thirdparty/OpenXLSX/Examples/Demo1A.cpp +137 -0
- package/thirdparty/OpenXLSX/Examples/Demo2.cpp +65 -0
- package/thirdparty/OpenXLSX/Examples/Demo3.cpp +89 -0
- package/thirdparty/OpenXLSX/Examples/Demo4.cpp +86 -0
- package/thirdparty/OpenXLSX/Examples/Demo5.cpp +77 -0
- package/thirdparty/OpenXLSX/Examples/Demo6.cpp +103 -0
- package/thirdparty/OpenXLSX/Examples/Demo7.cpp +79 -0
- package/thirdparty/OpenXLSX/Examples/Demo8.cpp +117 -0
- package/thirdparty/OpenXLSX/Examples/Demo9.cpp +363 -0
- package/thirdparty/OpenXLSX/Examples/cmake/FindLIBZIP.cmake +61 -0
- package/thirdparty/OpenXLSX/Examples/external/CustomZip/CustomZip.hpp +256 -0
- package/thirdparty/OpenXLSX/LICENSE.md +29 -0
- package/thirdparty/OpenXLSX/Makefile.GNU +530 -0
- package/thirdparty/OpenXLSX/Notes/TBDs.txt +16 -0
- package/thirdparty/OpenXLSX/Notes/confirmed-TBCs.txt +8 -0
- package/thirdparty/OpenXLSX/Notes/styles-missing-support.xml +12 -0
- package/thirdparty/OpenXLSX/Notes/todo-list.txt +108 -0
- package/thirdparty/OpenXLSX/OpenXLSX/CMakeLists.txt +631 -0
- package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSX.hpp +63 -0
- package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSXConfig.cmake +11 -0
- package/thirdparty/OpenXLSX/OpenXLSX/cmake/bundle_static_library.cmake +198 -0
- package/thirdparty/OpenXLSX/OpenXLSX/cmake/patch_pkg_config.cmake +69 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/IZipArchive.hpp +361 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX-Exports.hpp +12 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCell.hpp +367 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellIterator.hpp +252 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellRange.hpp +223 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellReference.hpp +317 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellValue.hpp +793 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColor.hpp +232 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColumn.hpp +159 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCommandQuery.hpp +228 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLComments.hpp +270 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLConstants.hpp +18 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLContentTypes.hpp +264 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDateTime.hpp +175 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDocument.hpp +505 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDrawing.hpp +452 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLException.hpp +161 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLFormula.hpp +375 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLIterator.hpp +40 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLMergeCells.hpp +216 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLProperties.hpp +348 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRelationships.hpp +348 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRow.hpp +721 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRowData.hpp +488 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSharedStrings.hpp +204 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSheet.hpp +1640 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLStyles.hpp +2390 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLTables.hpp +132 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLWorkbook.hpp +404 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlData.hpp +283 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlFile.hpp +194 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParser.hpp +282 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParserForwardDeclarations.hpp +85 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLZipArchive.hpp +232 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/LibZip.hpp +447 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/OpenXLSXFileSystemTools.hpp +207 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/Zippy.hpp +1375 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCell.cpp +340 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellIterator.cpp +427 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellRange.cpp +221 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellReference.cpp +408 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellValue.cpp +519 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColor.cpp +202 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColumn.cpp +141 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLComments.cpp +637 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLContentTypes.cpp +329 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDateTime.cpp +269 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDocument.cpp +1678 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDrawing.cpp +784 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLFormula.cpp +201 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLMergeCells.cpp +357 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLProperties.cpp +810 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRelationships.cpp +529 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRow.cpp +918 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRowData.cpp +508 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSharedStrings.cpp +220 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSheet.cpp +1970 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLStyles.cpp +3014 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLTables.cpp +125 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLWorkbook.cpp +784 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlData.cpp +247 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlFile.cpp +160 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlParser.cpp +261 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLZipArchive.cpp +266 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/utilities/XLUtilities.hpp +478 -0
- package/thirdparty/OpenXLSX/README.md +1279 -0
- package/thirdparty/OpenXLSX/Scripts/cmake-cleanup.sh +102 -0
- package/thirdparty/OpenXLSX/Scripts/compile.sh +23 -0
- package/thirdparty/OpenXLSX/Scripts/demos-cleanup.sh +25 -0
- package/thirdparty/OpenXLSX/Scripts/demos-run-all.sh +60 -0
- package/thirdparty/OpenXLSX/Scripts/guarded-xml-format.sh +47 -0
- package/thirdparty/OpenXLSX/Scripts/make-gnu.sh +11 -0
- package/thirdparty/OpenXLSX/Scripts/uninstall-manifest.sh +48 -0
- package/thirdparty/OpenXLSX/Scripts/xml-format-all.sh +19 -0
- package/thirdparty/OpenXLSX/Scripts/xml-format.sh +38 -0
- package/thirdparty/OpenXLSX/Tests/CMakeLists.txt +37 -0
- package/thirdparty/OpenXLSX/Tests/catch/catch.hpp +17799 -0
- package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_automake.hpp +68 -0
- package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_sonarqube.hpp +182 -0
- package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_tap.hpp +278 -0
- package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_teamcity.hpp +212 -0
- package/thirdparty/OpenXLSX/Tests/main.cpp +55 -0
- package/thirdparty/OpenXLSX/Tests/testXLCell.cpp +176 -0
- package/thirdparty/OpenXLSX/Tests/testXLCellRange.cpp +180 -0
- package/thirdparty/OpenXLSX/Tests/testXLCellReference.cpp +160 -0
- package/thirdparty/OpenXLSX/Tests/testXLCellValue.cpp +366 -0
- package/thirdparty/OpenXLSX/Tests/testXLCellValueProxy.cpp +255 -0
- package/thirdparty/OpenXLSX/Tests/testXLColor.cpp +75 -0
- package/thirdparty/OpenXLSX/Tests/testXLDateTime.cpp +229 -0
- package/thirdparty/OpenXLSX/Tests/testXLDocument.cpp +197 -0
- package/thirdparty/OpenXLSX/Tests/testXLFormula.cpp +131 -0
- package/thirdparty/OpenXLSX/Tests/testXLRow.cpp +597 -0
- package/thirdparty/OpenXLSX/Tests/testXLSheet.cpp +77 -0
- package/thirdparty/OpenXLSX/Tests/ziptest-with-libs.cpp +88 -0
- package/thirdparty/OpenXLSX/Tests/ziptest.cpp +735 -0
- package/thirdparty/OpenXLSX/cmake/get-git-HEAD-ID.cmake +45 -0
- package/thirdparty/OpenXLSX/cmake/libopenxlsxCPackOptions.cmake.in +20 -0
- package/thirdparty/OpenXLSX/cmake/manage_dependency.cmake +813 -0
- package/thirdparty/OpenXLSX/cmake/recursive_library_type_test.cmake +52 -0
- package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-shared.hpp +42 -0
- package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-static.hpp +42 -0
- package/thirdparty/OpenXLSX/vcpkg.json +24 -0
- package/thirdparty/README.md +42 -0
- package/thirdparty/miniz/.clang-format +47 -0
- package/thirdparty/miniz/.travis.yml +2 -0
- package/thirdparty/miniz/CMakeLists.txt +333 -0
- package/thirdparty/miniz/CMakePresets.json +31 -0
- package/thirdparty/miniz/ChangeLog.md +272 -0
- package/thirdparty/miniz/Config.cmake.in +1 -0
- package/thirdparty/miniz/LICENSE +22 -0
- package/thirdparty/miniz/amalgamate.sh +57 -0
- package/thirdparty/miniz/examples/example1.c +105 -0
- package/thirdparty/miniz/examples/example2.c +164 -0
- package/thirdparty/miniz/examples/example3.c +269 -0
- package/thirdparty/miniz/examples/example4.c +102 -0
- package/thirdparty/miniz/examples/example5.c +327 -0
- package/thirdparty/miniz/examples/example6.c +189 -0
- package/thirdparty/miniz/meson.build +21 -0
- package/thirdparty/miniz/miniz.c +646 -0
- package/thirdparty/miniz/miniz.h +615 -0
- package/thirdparty/miniz/miniz.pc.in +13 -0
- package/thirdparty/miniz/miniz_common.h +89 -0
- package/thirdparty/miniz/miniz_export.h +20 -0
- package/thirdparty/miniz/miniz_tdef.c +1602 -0
- package/thirdparty/miniz/miniz_tdef.h +199 -0
- package/thirdparty/miniz/miniz_tinfl.c +778 -0
- package/thirdparty/miniz/miniz_tinfl.h +150 -0
- package/thirdparty/miniz/miniz_zip.c +4895 -0
- package/thirdparty/miniz/miniz_zip.h +454 -0
- package/thirdparty/miniz/readme.md +46 -0
- package/thirdparty/miniz/test.sh +36 -0
- package/thirdparty/miniz/tests/add_in_place_fuzzer.c +87 -0
- package/thirdparty/miniz/tests/catch_amalgamated.cpp +10795 -0
- package/thirdparty/miniz/tests/catch_amalgamated.hpp +13143 -0
- package/thirdparty/miniz/tests/checksum_fuzzer.c +26 -0
- package/thirdparty/miniz/tests/compress_fuzzer.c +91 -0
- package/thirdparty/miniz/tests/flush_fuzzer.c +88 -0
- package/thirdparty/miniz/tests/fuzz_main.c +55 -0
- package/thirdparty/miniz/tests/large_fuzzer.c +133 -0
- package/thirdparty/miniz/tests/main.cpp +185 -0
- package/thirdparty/miniz/tests/miniz_tdefl_fuzzer.cc +115 -0
- package/thirdparty/miniz/tests/miniz_tester.cpp +1881 -0
- package/thirdparty/miniz/tests/miniz_zip_validate_fuzzer.cc +71 -0
- package/thirdparty/miniz/tests/miniz_zip_writer_fuzzer.cc +96 -0
- package/thirdparty/miniz/tests/ossfuzz.sh +48 -0
- package/thirdparty/miniz/tests/small_fuzzer.c +126 -0
- package/thirdparty/miniz/tests/timer.cpp +152 -0
- package/thirdparty/miniz/tests/timer.h +40 -0
- package/thirdparty/miniz/tests/uncompress2_fuzzer.c +21 -0
- package/thirdparty/miniz/tests/uncompress_fuzzer.c +30 -0
- package/thirdparty/miniz/tests/zip.dict +9 -0
- package/thirdparty/miniz/tests/zip_fuzzer.c +63 -0
- package/thirdparty/pugixml/.codecov.yml +7 -0
- package/thirdparty/pugixml/.gitattributes +1 -0
- package/thirdparty/pugixml/CMakeLists.txt +330 -0
- package/thirdparty/pugixml/LICENSE.md +24 -0
- package/thirdparty/pugixml/Makefile +98 -0
- package/thirdparty/pugixml/README.md +81 -0
- package/thirdparty/pugixml/SECURITY.md +9 -0
- package/thirdparty/pugixml/appveyor.yml +50 -0
- package/thirdparty/pugixml/docs/config.adoc +7 -0
- package/thirdparty/pugixml/docs/images/dom_tree.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_link1.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_link2.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_pch1.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_pch2.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_pch3.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_pch4.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2010_link1.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2010_link2.png +0 -0
- package/thirdparty/pugixml/docs/manual.adoc +3326 -0
- package/thirdparty/pugixml/docs/manual.html +6395 -0
- package/thirdparty/pugixml/docs/quickstart.adoc +287 -0
- package/thirdparty/pugixml/docs/quickstart.html +1107 -0
- package/thirdparty/pugixml/docs/samples/character.xml +8 -0
- package/thirdparty/pugixml/docs/samples/custom_memory_management.cpp +27 -0
- package/thirdparty/pugixml/docs/samples/include.cpp +64 -0
- package/thirdparty/pugixml/docs/samples/load_error_handling.cpp +33 -0
- package/thirdparty/pugixml/docs/samples/load_file.cpp +16 -0
- package/thirdparty/pugixml/docs/samples/load_memory.cpp +66 -0
- package/thirdparty/pugixml/docs/samples/load_options.cpp +30 -0
- package/thirdparty/pugixml/docs/samples/load_stream.cpp +97 -0
- package/thirdparty/pugixml/docs/samples/modify_add.cpp +29 -0
- package/thirdparty/pugixml/docs/samples/modify_base.cpp +43 -0
- package/thirdparty/pugixml/docs/samples/modify_remove.cpp +27 -0
- package/thirdparty/pugixml/docs/samples/save_custom_writer.cpp +116 -0
- package/thirdparty/pugixml/docs/samples/save_declaration.cpp +27 -0
- package/thirdparty/pugixml/docs/samples/save_file.cpp +17 -0
- package/thirdparty/pugixml/docs/samples/save_options.cpp +48 -0
- package/thirdparty/pugixml/docs/samples/save_stream.cpp +18 -0
- package/thirdparty/pugixml/docs/samples/save_subtree.cpp +26 -0
- package/thirdparty/pugixml/docs/samples/text.cpp +35 -0
- package/thirdparty/pugixml/docs/samples/transitions.xml +7 -0
- package/thirdparty/pugixml/docs/samples/traverse_base.cpp +51 -0
- package/thirdparty/pugixml/docs/samples/traverse_iter.cpp +27 -0
- package/thirdparty/pugixml/docs/samples/traverse_predicate.cpp +48 -0
- package/thirdparty/pugixml/docs/samples/traverse_rangefor.cpp +32 -0
- package/thirdparty/pugixml/docs/samples/traverse_walker.cpp +35 -0
- package/thirdparty/pugixml/docs/samples/tree.xml +12 -0
- package/thirdparty/pugixml/docs/samples/weekly-shift_jis.xml +78 -0
- package/thirdparty/pugixml/docs/samples/weekly-utf-16.xml +0 -0
- package/thirdparty/pugixml/docs/samples/weekly-utf-8.xml +78 -0
- package/thirdparty/pugixml/docs/samples/xgconsole.xml +12 -0
- package/thirdparty/pugixml/docs/samples/xpath_error.cpp +43 -0
- package/thirdparty/pugixml/docs/samples/xpath_query.cpp +36 -0
- package/thirdparty/pugixml/docs/samples/xpath_select.cpp +28 -0
- package/thirdparty/pugixml/docs/samples/xpath_variables.cpp +38 -0
- package/thirdparty/pugixml/readme.txt +50 -0
- package/thirdparty/pugixml/scripts/archive.py +54 -0
- package/thirdparty/pugixml/scripts/cocoapods_push.sh +4 -0
- package/thirdparty/pugixml/scripts/natvis/pugixml.natvis +77 -0
- package/thirdparty/pugixml/scripts/natvis/pugixml_compact.natvis +506 -0
- package/thirdparty/pugixml/scripts/nuget/build/native/pugixml-propertiesui.xml +17 -0
- package/thirdparty/pugixml/scripts/nuget/build/native/pugixml.targets +28 -0
- package/thirdparty/pugixml/scripts/nuget/pugixml.nuspec +20 -0
- package/thirdparty/pugixml/scripts/nuget_build.ps1 +60 -0
- package/thirdparty/pugixml/scripts/premake4.lua +92 -0
- package/thirdparty/pugixml/scripts/pugixml-config.cmake.in +12 -0
- package/thirdparty/pugixml/scripts/pugixml.pc.in +11 -0
- package/thirdparty/pugixml/scripts/pugixml.podspec +14 -0
- package/thirdparty/pugixml/scripts/pugixml.xcodeproj/project.pbxproj +212 -0
- package/thirdparty/pugixml/scripts/pugixml_airplay.mkf +13 -0
- package/thirdparty/pugixml/scripts/pugixml_codeblocks.cbp +44 -0
- package/thirdparty/pugixml/scripts/pugixml_codelite.project +56 -0
- package/thirdparty/pugixml/scripts/pugixml_dll.rc +45 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2005.vcproj +343 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2005_static.vcproj +343 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2008.vcproj +339 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2008_static.vcproj +339 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2010.vcxproj +191 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2010_static.vcxproj +191 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2013.vcxproj +199 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2013_static.vcxproj +199 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2015.vcxproj +172 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2015_static.vcxproj +176 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2017.vcxproj +172 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2017_static.vcxproj +176 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2019.vcxproj +176 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2019_static.vcxproj +180 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2022.vcxproj +176 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2022_static.vcxproj +180 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2026.vcxproj +176 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2026_static.vcxproj +180 -0
- package/thirdparty/pugixml/scripts/sbom.cdx.json +47 -0
- package/thirdparty/pugixml/src/pugiconfig.hpp +81 -0
- package/thirdparty/pugixml/src/pugixml.cpp +13776 -0
- package/thirdparty/pugixml/src/pugixml.hpp +1604 -0
- package/thirdparty/pugixml/tests/allocator.cpp +175 -0
- package/thirdparty/pugixml/tests/allocator.hpp +10 -0
- package/thirdparty/pugixml/tests/autotest-appveyor.ps1 +93 -0
- package/thirdparty/pugixml/tests/cmake-appveyor.ps1 +57 -0
- package/thirdparty/pugixml/tests/data/empty.xml +0 -0
- package/thirdparty/pugixml/tests/data/large.xml +1 -0
- package/thirdparty/pugixml/tests/data/latintest_latin1.xml +1 -0
- package/thirdparty/pugixml/tests/data/latintest_utf8.xml +1 -0
- package/thirdparty/pugixml/tests/data/multiline.xml +3 -0
- package/thirdparty/pugixml/tests/data/small.xml +1 -0
- package/thirdparty/pugixml/tests/data/truncation.xml +19 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_be.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_be_bom.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_be_clean.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_be_nodecl.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_le.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_le_bom.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_le_clean.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_le_nodecl.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_be.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_be_bom.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_be_clean.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_be_nodecl.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_le.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_le_bom.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_le_clean.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_le_nodecl.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf8.xml +87 -0
- package/thirdparty/pugixml/tests/data/utftest_utf8_bom.xml +87 -0
- package/thirdparty/pugixml/tests/data/utftest_utf8_clean.xml +84 -0
- package/thirdparty/pugixml/tests/data/utftest_utf8_nodecl.xml +86 -0
- package/thirdparty/pugixml/tests/data//321/202/320/265/321/201/321/202.xml +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/basic.xml +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/doctype.xml +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/refs.xml +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/types.xml +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/utf16.xml +0 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/utf32.xml +0 -0
- package/thirdparty/pugixml/tests/data_fuzz_xpath/basic.xpath +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_xpath/functions.xpath +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_xpath/math.xpath +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_xpath/path.xpath +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_xpath/predicate.xpath +1 -0
- package/thirdparty/pugixml/tests/fuzz_parse.cpp +14 -0
- package/thirdparty/pugixml/tests/fuzz_parse.dict +72 -0
- package/thirdparty/pugixml/tests/fuzz_setup.sh +11 -0
- package/thirdparty/pugixml/tests/fuzz_xpath.cpp +46 -0
- package/thirdparty/pugixml/tests/fuzz_xpath.dict +72 -0
- package/thirdparty/pugixml/tests/helpers.hpp +114 -0
- package/thirdparty/pugixml/tests/main.cpp +218 -0
- package/thirdparty/pugixml/tests/test.cpp +220 -0
- package/thirdparty/pugixml/tests/test.hpp +175 -0
- package/thirdparty/pugixml/tests/test_compact.cpp +150 -0
- package/thirdparty/pugixml/tests/test_deprecated.cpp +25 -0
- package/thirdparty/pugixml/tests/test_document.cpp +1910 -0
- package/thirdparty/pugixml/tests/test_dom_modify.cpp +2122 -0
- package/thirdparty/pugixml/tests/test_dom_text.cpp +601 -0
- package/thirdparty/pugixml/tests/test_dom_traverse.cpp +1481 -0
- package/thirdparty/pugixml/tests/test_header_guard.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_iosfwd_1.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_iosfwd_2.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_iostream_1.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_iostream_2.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_only_1.cpp +21 -0
- package/thirdparty/pugixml/tests/test_header_only_2.cpp +21 -0
- package/thirdparty/pugixml/tests/test_header_string_1.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_string_2.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_string_iostream.cpp +5 -0
- package/thirdparty/pugixml/tests/test_memory.cpp +303 -0
- package/thirdparty/pugixml/tests/test_parse.cpp +1463 -0
- package/thirdparty/pugixml/tests/test_parse_doctype.cpp +366 -0
- package/thirdparty/pugixml/tests/test_unicode.cpp +152 -0
- package/thirdparty/pugixml/tests/test_version.cpp +5 -0
- package/thirdparty/pugixml/tests/test_write.cpp +757 -0
- package/thirdparty/pugixml/tests/test_xpath.cpp +833 -0
- package/thirdparty/pugixml/tests/test_xpath_api.cpp +646 -0
- package/thirdparty/pugixml/tests/test_xpath_functions.cpp +844 -0
- package/thirdparty/pugixml/tests/test_xpath_operators.cpp +566 -0
- package/thirdparty/pugixml/tests/test_xpath_parse.cpp +428 -0
- package/thirdparty/pugixml/tests/test_xpath_paths.cpp +787 -0
- package/thirdparty/pugixml/tests/test_xpath_paths_abbrev_w3c.cpp +219 -0
- package/thirdparty/pugixml/tests/test_xpath_paths_w3c.cpp +312 -0
- package/thirdparty/pugixml/tests/test_xpath_variables.cpp +683 -0
- package/thirdparty/pugixml/tests/test_xpath_xalan_1.cpp +411 -0
- package/thirdparty/pugixml/tests/test_xpath_xalan_2.cpp +417 -0
- package/thirdparty/pugixml/tests/test_xpath_xalan_3.cpp +321 -0
- package/thirdparty/pugixml/tests/test_xpath_xalan_4.cpp +300 -0
- package/thirdparty/pugixml/tests/test_xpath_xalan_5.cpp +295 -0
- package/thirdparty/pugixml/tests/writer_string.cpp +79 -0
- package/thirdparty/pugixml/tests/writer_string.hpp +27 -0
- package/scripts/prepare-openxlsx.js +0 -126
|
@@ -0,0 +1,810 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
____ ____ ___ ____ ____ ____ ___
|
|
4
|
+
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
|
|
5
|
+
8P Y8 `MM. d' MM 6M' ` `MM. d'
|
|
6
|
+
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
|
|
7
|
+
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
|
|
8
|
+
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
|
|
9
|
+
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
|
|
10
|
+
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
|
|
11
|
+
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
|
|
12
|
+
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
|
|
13
|
+
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
|
|
14
|
+
MM
|
|
15
|
+
MM
|
|
16
|
+
_MM_
|
|
17
|
+
|
|
18
|
+
Copyright (c) 2018, Kenneth Troldal Balslev
|
|
19
|
+
|
|
20
|
+
All rights reserved.
|
|
21
|
+
|
|
22
|
+
Redistribution and use in source and binary forms, with or without
|
|
23
|
+
modification, are permitted provided that the following conditions are met:
|
|
24
|
+
- Redistributions of source code must retain the above copyright
|
|
25
|
+
notice, this list of conditions and the following disclaimer.
|
|
26
|
+
- Redistributions in binary form must reproduce the above copyright
|
|
27
|
+
notice, this list of conditions and the following disclaimer in the
|
|
28
|
+
documentation and/or other materials provided with the distribution.
|
|
29
|
+
- Neither the name of the author nor the
|
|
30
|
+
names of any contributors may be used to endorse or promote products
|
|
31
|
+
derived from this software without specific prior written permission.
|
|
32
|
+
|
|
33
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
34
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
35
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
36
|
+
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
37
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
38
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
39
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
40
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
41
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
42
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
43
|
+
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
// ===== External Includes ===== //
|
|
47
|
+
#include <string>
|
|
48
|
+
#include <vector>
|
|
49
|
+
|
|
50
|
+
// ===== OpenXLSX Includes ===== //
|
|
51
|
+
#include "XLDocument.hpp"
|
|
52
|
+
#include "XLProperties.hpp"
|
|
53
|
+
#include "XLRelationships.hpp" // GetStringFromType
|
|
54
|
+
#include "XLXmlParser.hpp" // pugixml wrapper
|
|
55
|
+
#include "utilities/XLUtilities.hpp" // appendAndGetAttribute
|
|
56
|
+
|
|
57
|
+
#include "XLException.hpp"
|
|
58
|
+
|
|
59
|
+
using namespace OpenXLSX;
|
|
60
|
+
|
|
61
|
+
namespace // anonymous namespace for module local functions
|
|
62
|
+
{
|
|
63
|
+
/**
|
|
64
|
+
* @brief insert node with nodeNameToInsert before insertBeforeThis and copy all the consecutive whitespace nodes preceeding insertBeforeThis
|
|
65
|
+
* @param nodeNameToInsert create a new element node with this name
|
|
66
|
+
* @param insertBeforeThis self-explanatory, isn't it? :)
|
|
67
|
+
* @returns the inserted XMLNode
|
|
68
|
+
* @throws XLInternalError if insertBeforeThis has no parent node
|
|
69
|
+
*/
|
|
70
|
+
XMLNode prettyInsertXmlNodeBefore(std::string nodeNameToInsert, XMLNode insertBeforeThis)
|
|
71
|
+
{
|
|
72
|
+
XMLNode parentNode = insertBeforeThis.parent();
|
|
73
|
+
if (parentNode.empty())
|
|
74
|
+
throw XLInternalError("prettyInsertXmlNodeBefore can not insert before a node that has no parent");
|
|
75
|
+
|
|
76
|
+
// ===== Find potential whitespaces preceeding insertBeforeThis
|
|
77
|
+
XMLNode whitespaces = insertBeforeThis;
|
|
78
|
+
while (whitespaces.previous_sibling().type() == pugi::node_pcdata) whitespaces = whitespaces.previous_sibling();
|
|
79
|
+
|
|
80
|
+
// ===== Insert the nodeNameToInsert before insertBeforeThis, "hijacking" the preceeding whitespace nodes
|
|
81
|
+
XMLNode insertedNode = parentNode.insert_child_before(nodeNameToInsert.c_str(), insertBeforeThis);
|
|
82
|
+
// ===== Copy all hijacked whitespaces to also preceed (again) the node insertBeforeThis
|
|
83
|
+
while( whitespaces.type() == pugi::node_pcdata ) {
|
|
84
|
+
parentNode.insert_copy_before(whitespaces, insertBeforeThis);
|
|
85
|
+
whitespaces = whitespaces.next_sibling();
|
|
86
|
+
}
|
|
87
|
+
return insertedNode;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @brief fetch the <HeadingPairs><vt:vector> node from docNode, create if not existing
|
|
92
|
+
* @param docNode the xml document from which to fetch
|
|
93
|
+
* @returns an XMLNode for the <vt:vector> child of <HeadingPairs>
|
|
94
|
+
* @throws XLInternalError in case either XML element does not exist and fails to create
|
|
95
|
+
*/
|
|
96
|
+
XMLNode headingPairsNode(XMLNode docNode)
|
|
97
|
+
{
|
|
98
|
+
XMLNode headingPairs = docNode.child("HeadingPairs");
|
|
99
|
+
if (headingPairs.empty()) {
|
|
100
|
+
XMLNode titlesOfParts = docNode.child("TitlesOfParts"); // attempt to locate TitlesOfParts to insert HeadingPairs right before
|
|
101
|
+
if( titlesOfParts.empty() )
|
|
102
|
+
headingPairs = docNode.append_child("HeadingPairs");
|
|
103
|
+
else
|
|
104
|
+
headingPairs = prettyInsertXmlNodeBefore("HeadingPairs", titlesOfParts);
|
|
105
|
+
if (headingPairs.empty())
|
|
106
|
+
throw XLInternalError("headingPairsNode was unable to create XML element HeadingPairs");
|
|
107
|
+
}
|
|
108
|
+
XMLNode node = headingPairs.first_child_of_type(pugi::node_element);
|
|
109
|
+
if (node.empty()) { // heading pairs child "vt:vector" does not exist
|
|
110
|
+
node = headingPairs.append_child("vt:vector", XLForceNamespace);
|
|
111
|
+
if (node.empty())
|
|
112
|
+
throw XLInternalError("headingPairsNode was unable to create HeadingPairs child element <vt:vector>");
|
|
113
|
+
node.append_attribute("size") = 0; // NOTE: size counts each heading pair as 2 - but for now, there are no entries
|
|
114
|
+
node.append_attribute("baseType") = "variant";
|
|
115
|
+
}
|
|
116
|
+
// ===== Finally, return what should be a good "vt:vector" node with all the heading pairs
|
|
117
|
+
return node;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
XMLAttribute headingPairsSize(XMLNode docNode)
|
|
121
|
+
{
|
|
122
|
+
return docNode.child("HeadingPairs").first_child_of_type(pugi::node_element).attribute("size");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
#ifdef __GNUC__ // conditionally enable GCC specific pragmas to suppress unused function warning
|
|
126
|
+
# pragma GCC diagnostic push
|
|
127
|
+
# pragma GCC diagnostic ignored "-Wunused-function"
|
|
128
|
+
#endif // __GNUC__
|
|
129
|
+
std::vector<std::string> headingPairsCategoriesStrings(XMLNode docNode)
|
|
130
|
+
{
|
|
131
|
+
// 2024-05-28 DONE: tested this code with two pairs in headingPairsNode
|
|
132
|
+
std::vector<std::string> result;
|
|
133
|
+
XMLNode item = headingPairsNode(docNode).first_child_of_type(pugi::node_element);
|
|
134
|
+
while (not item.empty()) {
|
|
135
|
+
result.push_back(item.first_child_of_type(pugi::node_element).child_value());
|
|
136
|
+
item = item.next_sibling_of_type(pugi::node_element)
|
|
137
|
+
.next_sibling_of_type(pugi::node_element); // advance two elements to skip count node
|
|
138
|
+
}
|
|
139
|
+
return result; // 2024-05-28: std::move should not be used when the operand of a return statement is the name of a local variable
|
|
140
|
+
// as this can prevent named return value optimization (NRVO, copy elision)
|
|
141
|
+
}
|
|
142
|
+
#ifdef __GNUC__ // conditionally enable GCC specific pragmas to suppress unused function warning
|
|
143
|
+
# pragma GCC diagnostic pop
|
|
144
|
+
#endif // __GNUC__
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @brief fetch the <TitlesOfParts><vt:vector> XML node, create if not existing
|
|
148
|
+
* @param docNode the xml document from which to fetch
|
|
149
|
+
* @returns an XMLNode for the <vt:vector> child of <TitlesOfParts>
|
|
150
|
+
* @throws XLInternalError in case either XML element does not exist and fails to create
|
|
151
|
+
*/
|
|
152
|
+
XMLNode sheetNames(XMLNode docNode)
|
|
153
|
+
{
|
|
154
|
+
XMLNode titlesOfParts = docNode.child("TitlesOfParts");
|
|
155
|
+
if (titlesOfParts.empty()) {
|
|
156
|
+
// ===== Attempt to find a good position to insert TitlesOfParts
|
|
157
|
+
XMLNode node = docNode.first_child_of_type(pugi::node_element);
|
|
158
|
+
std::string nodeName = node.name();
|
|
159
|
+
while (not node.empty() && (
|
|
160
|
+
/**/ nodeName == "Application"
|
|
161
|
+
/**/ || nodeName == "AppVersion"
|
|
162
|
+
/**/ || nodeName == "DocSecurity"
|
|
163
|
+
/**/ || nodeName == "ScaleCrop"
|
|
164
|
+
/**/ || nodeName == "Template"
|
|
165
|
+
/**/ || nodeName == "TotalTime"
|
|
166
|
+
/**/ || nodeName == "HeadingPairs"
|
|
167
|
+
/**/ )) {
|
|
168
|
+
node = node.next_sibling_of_type(pugi::node_element);
|
|
169
|
+
nodeName = node.name();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (node.empty())
|
|
173
|
+
titlesOfParts = docNode.append_child("TitlesOfParts");
|
|
174
|
+
else
|
|
175
|
+
titlesOfParts = prettyInsertXmlNodeBefore("TitlesOfParts", node);
|
|
176
|
+
}
|
|
177
|
+
XMLNode vtVector = titlesOfParts.first_child_of_type(pugi::node_element);
|
|
178
|
+
if (vtVector.empty()) {
|
|
179
|
+
vtVector = titlesOfParts.prepend_child("vt:vector", XLForceNamespace);
|
|
180
|
+
if (vtVector.empty())
|
|
181
|
+
throw XLInternalError("sheetNames was unable to create TitlesOfParts child element <vt:vector>");
|
|
182
|
+
vtVector.append_attribute("size") = 0;
|
|
183
|
+
vtVector.append_attribute("baseType") = "lpstr";
|
|
184
|
+
}
|
|
185
|
+
return vtVector;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
XMLAttribute sheetCount(XMLNode docNode) { return sheetNames(docNode).attribute("size"); }
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @brief from the HeadingPairs node, look up name and return the next sibling (which should be the associated value node)
|
|
192
|
+
* @param docNode the XML document giving access to the <HeadingPairs> node
|
|
193
|
+
* @param name the value pair whose attribute to return
|
|
194
|
+
* @returns XMLNode where the value associated with name is stored (the next element sibling from the node matching name)
|
|
195
|
+
* @returns XMLNode{} (empty) if name is not found or has no next element sibling
|
|
196
|
+
*/
|
|
197
|
+
XMLNode getHeadingPairsValue(XMLNode docNode, std::string name)
|
|
198
|
+
{
|
|
199
|
+
XMLNode item = headingPairsNode(docNode).first_child_of_type(pugi::node_element);
|
|
200
|
+
while (not item.empty() && item.first_child_of_type(pugi::node_element).child_value() != name)
|
|
201
|
+
item = item.next_sibling_of_type(pugi::node_element)
|
|
202
|
+
.next_sibling_of_type(pugi::node_element); // advance two elements to skip count node
|
|
203
|
+
if (not item.empty()) // if name was found
|
|
204
|
+
item = item.next_sibling_of_type(pugi::node_element); // advance once more to the value node
|
|
205
|
+
|
|
206
|
+
// ===== Return the first element child of the <vt:variant> node containing the heading pair value
|
|
207
|
+
// (returns an empty node if item or first_child_of_type is empty)
|
|
208
|
+
return item.first_child_of_type(pugi::node_element);
|
|
209
|
+
}
|
|
210
|
+
} // anonymous namespace
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @details
|
|
214
|
+
*/
|
|
215
|
+
void XLProperties::ensureXmlNamespaces(XMLNode & props)
|
|
216
|
+
{
|
|
217
|
+
// ===== OpenXLSX_XLRelationships::GetStringFromType yields almost the string needed here, with added /relationships
|
|
218
|
+
// TBD: use hardcoded string?
|
|
219
|
+
std::string xmlns = OpenXLSX_XLRelationships::GetStringFromType(XLRelationshipType::CoreProperties);
|
|
220
|
+
const std::string rels = "/relationships/";
|
|
221
|
+
size_t pos = xmlns.find(rels);
|
|
222
|
+
if (pos != std::string::npos)
|
|
223
|
+
xmlns.replace(pos, rels.size(), "/");
|
|
224
|
+
else
|
|
225
|
+
xmlns = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"; // fallback to hardcoded string
|
|
226
|
+
|
|
227
|
+
appendAndGetAttribute(props, "xmlns:cp", xmlns.c_str());
|
|
228
|
+
appendAndGetAttribute(props, "xmlns:dc", "http://purl.org/dc/elements/1.1/");
|
|
229
|
+
appendAndGetAttribute(props, "xmlns:dcterms", "http://purl.org/dc/terms/");
|
|
230
|
+
appendAndGetAttribute(props, "xmlns:dcmitype", "http://purl.org/dc/dcmitype/");
|
|
231
|
+
appendAndGetAttribute(props, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
|
|
232
|
+
|
|
233
|
+
// props.append_attribute("xmlns:cp") = xmlns.c_str();
|
|
234
|
+
// props.append_attribute("xmlns:dc") = "http://purl.org/dc/elements/1.1/";
|
|
235
|
+
// props.append_attribute("xmlns:dcterms") = "http://purl.org/dc/terms/";
|
|
236
|
+
// props.append_attribute("xmlns:dcmitype") = "http://purl.org/dc/dcmitype/";
|
|
237
|
+
// props.append_attribute("xmlns:xsi") = "http://www.w3.org/2001/XMLSchema-instance";
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* @details
|
|
242
|
+
*/
|
|
243
|
+
void XLProperties::createFromTemplate()
|
|
244
|
+
{
|
|
245
|
+
// std::cout << "XLProperties created with empty docProps/core.xml, creating from scratch!" << std::endl;
|
|
246
|
+
if(m_xmlData == nullptr)
|
|
247
|
+
throw XLInternalError("XLProperties m_xmlData is nullptr");
|
|
248
|
+
|
|
249
|
+
XMLNode props = xmlDocument().prepend_child("cp:coreProperties");
|
|
250
|
+
ensureXmlNamespaces(props);
|
|
251
|
+
props.append_child("dc:creator").text().set("Kenneth Balslev");
|
|
252
|
+
props.append_child("cp:lastModifiedBy").text().set("Kenneth Balslev");
|
|
253
|
+
|
|
254
|
+
XMLNode prop {};
|
|
255
|
+
prop = props.append_child("dcterms:created");
|
|
256
|
+
prop.append_attribute("xsi:type") = "dcterms:W3CDTF";
|
|
257
|
+
prop.text().set("2019-08-16T00:34:14Z");
|
|
258
|
+
prop = props.append_child("dcterms:modified");
|
|
259
|
+
prop.append_attribute("xsi:type") = "dcterms:W3CDTF";
|
|
260
|
+
prop.text().set("2019-08-16T00:34:26Z");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* @details
|
|
265
|
+
*/
|
|
266
|
+
XLProperties::XLProperties() = default;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @details
|
|
270
|
+
*/
|
|
271
|
+
XLProperties::XLProperties(XLXmlData* xmlData) : XLXmlFile(xmlData)
|
|
272
|
+
{
|
|
273
|
+
XMLNode doc = xmlData->getXmlDocument()->document_element();
|
|
274
|
+
XMLNode child = doc.first_child_of_type(pugi::node_element);
|
|
275
|
+
size_t childCount = 0;
|
|
276
|
+
while (not child.empty()) {
|
|
277
|
+
++childCount;
|
|
278
|
+
child = child.next_sibling_of_type(pugi::node_element);
|
|
279
|
+
break; // one child is enough to determine document is not empty.
|
|
280
|
+
}
|
|
281
|
+
if (!childCount)
|
|
282
|
+
createFromTemplate();
|
|
283
|
+
else { // 2026-06-10: ensure that cp::coreProperties and XML namespaces are defined in existing documents, too
|
|
284
|
+
XMLNode props = xmlDocument().child("cp:coreProperties");
|
|
285
|
+
if (props.empty())
|
|
286
|
+
props = xmlDocument().prepend_child("cp:coreProperties");
|
|
287
|
+
ensureXmlNamespaces(props);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* @details copy constructor
|
|
293
|
+
*/
|
|
294
|
+
XLProperties::XLProperties(const XLProperties& other)
|
|
295
|
+
: XLXmlFile(other)
|
|
296
|
+
{}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @details move constructor
|
|
300
|
+
*/
|
|
301
|
+
XLProperties::XLProperties(XLProperties&& other) noexcept = default;
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* @details copy assignment operator
|
|
305
|
+
*/
|
|
306
|
+
XLProperties& XLProperties::operator=(const XLProperties& other)
|
|
307
|
+
{
|
|
308
|
+
if (&other != this) {
|
|
309
|
+
XLProperties temp = other; // copy-construct
|
|
310
|
+
*this = std::move(temp); // move-assign & invalidate temp
|
|
311
|
+
}
|
|
312
|
+
return *this;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* @details move assignment operator
|
|
317
|
+
*/
|
|
318
|
+
XLProperties& XLProperties::operator=(XLProperties&& other) = default;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* @details
|
|
322
|
+
*/
|
|
323
|
+
XLProperties::~XLProperties() = default;
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* @details
|
|
327
|
+
*/
|
|
328
|
+
void XLProperties::setProperty(const std::string& name, const std::string& value)
|
|
329
|
+
{
|
|
330
|
+
if (m_xmlData == nullptr) return;
|
|
331
|
+
XMLNode node = xmlDocument().document_element().child(name.c_str());
|
|
332
|
+
if (node.empty())
|
|
333
|
+
node = xmlDocument().document_element().append_child(name.c_str()); // .append_child, to be in line with ::property behavior
|
|
334
|
+
|
|
335
|
+
node.text().set(value.c_str());
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* @details
|
|
340
|
+
*/
|
|
341
|
+
void XLProperties::setProperty(const std::string& name, int value) { setProperty(name, std::to_string(value)); }
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* @details
|
|
345
|
+
*/
|
|
346
|
+
void XLProperties::setProperty(const std::string& name, double value) { setProperty(name, std::to_string(value)); }
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* @details
|
|
350
|
+
*/
|
|
351
|
+
std::string XLProperties::property(const std::string& name) const
|
|
352
|
+
{
|
|
353
|
+
if (m_xmlData == nullptr) return "";
|
|
354
|
+
XMLNode property = xmlDocument().document_element().child(name.c_str());
|
|
355
|
+
if (property.empty()) property = xmlDocument().document_element().append_child(name.c_str());
|
|
356
|
+
|
|
357
|
+
return property.text().get();
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* @details
|
|
362
|
+
*/
|
|
363
|
+
void XLProperties::deleteProperty(const std::string& name)
|
|
364
|
+
{
|
|
365
|
+
if (m_xmlData == nullptr) return;
|
|
366
|
+
if (const XMLNode property = xmlDocument().document_element().child(name.c_str()); not property.empty())
|
|
367
|
+
xmlDocument().document_element().remove_child(property);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* @details
|
|
373
|
+
*/
|
|
374
|
+
void XLAppProperties::ensureXmlNamespaces(XMLNode & props)
|
|
375
|
+
{
|
|
376
|
+
// ===== OpenXLSX_XLRelationships::GetStringFromType yields almost the string needed here, with added /relationships
|
|
377
|
+
// TBD: use hardcoded string?
|
|
378
|
+
std::string xmlns = OpenXLSX_XLRelationships::GetStringFromType(XLRelationshipType::ExtendedProperties);
|
|
379
|
+
const std::string rels = "/relationships/";
|
|
380
|
+
size_t pos = xmlns.find(rels);
|
|
381
|
+
if (pos != std::string::npos)
|
|
382
|
+
xmlns.replace(pos, rels.size(), "/");
|
|
383
|
+
else
|
|
384
|
+
xmlns = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"; // fallback to hardcoded string
|
|
385
|
+
|
|
386
|
+
appendAndGetAttribute(props, "xmlns", xmlns.c_str());
|
|
387
|
+
appendAndGetAttribute(props, "xmlns:vt", "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes");
|
|
388
|
+
|
|
389
|
+
// props.append_attribute("xmlns") = xmlns.c_str();
|
|
390
|
+
// props.append_attribute("xmlns:vt") = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes";
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* @details
|
|
396
|
+
*/
|
|
397
|
+
void XLAppProperties::createFromTemplate(XMLDocument const & workbookXml)
|
|
398
|
+
{
|
|
399
|
+
// std::cout << "XLAppProperties created with empty docProps/app.xml, creating from scratch!" << std::endl;
|
|
400
|
+
if(m_xmlData == nullptr)
|
|
401
|
+
throw XLInternalError("XLAppProperties m_xmlData is nullptr");
|
|
402
|
+
|
|
403
|
+
std::map< uint32_t, std::string > sheetsOrderedById;
|
|
404
|
+
|
|
405
|
+
auto sheet = workbookXml.document_element().child("sheets").first_child_of_type(pugi::node_element);
|
|
406
|
+
while (not sheet.empty()) {
|
|
407
|
+
std::string sheetName = sheet.attribute("name").as_string();
|
|
408
|
+
uint32_t sheetId = sheet.attribute("sheetId").as_uint();
|
|
409
|
+
sheetsOrderedById.insert(std::pair<uint32_t, std::string>(sheetId, sheetName));
|
|
410
|
+
sheet = sheet.next_sibling_of_type();
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
uint32_t worksheetCount = 0;
|
|
414
|
+
for (const auto & [key, value] : sheetsOrderedById) {
|
|
415
|
+
if (key != ++worksheetCount)
|
|
416
|
+
throw XLInputError( "xl/workbook.xml is missing sheet with sheetId=\"" + std::to_string(worksheetCount) + "\"" );
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
XMLNode props = xmlDocument().prepend_child("Properties");
|
|
420
|
+
ensureXmlNamespaces(props);
|
|
421
|
+
props.append_child("Application").text().set("Microsoft Macintosh Excel");
|
|
422
|
+
props.append_child("DocSecurity").text().set(0);
|
|
423
|
+
props.append_child("ScaleCrop").text().set(false);
|
|
424
|
+
|
|
425
|
+
XMLNode headingPairs = props.append_child("HeadingPairs");
|
|
426
|
+
XMLNode vecHP = headingPairs.append_child("vt:vector", XLForceNamespace);
|
|
427
|
+
vecHP.append_attribute("size") = 2;
|
|
428
|
+
vecHP.append_attribute("baseType") = "variant";
|
|
429
|
+
vecHP.append_child("vt:variant", XLForceNamespace).append_child("vt:lpstr", XLForceNamespace).text().set("Worksheets");
|
|
430
|
+
// ===== 2024-09-02 minor bugfix issue #220, "vt:i4" value of "Worksheets" pair should be sheet count
|
|
431
|
+
vecHP.append_child("vt:variant", XLForceNamespace).append_child("vt:i4", XLForceNamespace).text().set(worksheetCount);
|
|
432
|
+
|
|
433
|
+
XMLNode sheetsVector = props.append_child("TitlesOfParts").append_child("vt:vector", XLForceNamespace); // 2024-08-17 BUGFIX: TitlesOfParts was wrongly appended to headingPairs
|
|
434
|
+
sheetsVector.append_attribute("size") = worksheetCount;
|
|
435
|
+
sheetsVector.append_attribute("baseType") = "lpstr";
|
|
436
|
+
for (const auto & [key, value] : sheetsOrderedById)
|
|
437
|
+
sheetsVector.append_child("vt:lpstr", XLForceNamespace).text().set(value.c_str());
|
|
438
|
+
|
|
439
|
+
// NOTE 2024-07-24: for an empty string, .text().set("") would create a "<Company></Company>" node that
|
|
440
|
+
// would get reduced to <Company/> on a simple open + save operation and thereby cause the *only* diff
|
|
441
|
+
// to the uncompressed workbook. For this cosmetic reasons, text().set was removed in this case
|
|
442
|
+
props.append_child("Company"); // .text().set("");
|
|
443
|
+
props.append_child("LinksUpToDate").text().set(false);
|
|
444
|
+
props.append_child("SharedDoc").text().set(false);
|
|
445
|
+
props.append_child("HyperlinksChanged").text().set(false);
|
|
446
|
+
props.append_child("AppVersion").text().set("16.0300");
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* @details
|
|
451
|
+
*/
|
|
452
|
+
XLAppProperties::XLAppProperties() = default;
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* @details
|
|
456
|
+
*/
|
|
457
|
+
XLAppProperties::XLAppProperties(XLXmlData* xmlData, XMLDocument const & workbookXml)
|
|
458
|
+
: XLXmlFile(xmlData)
|
|
459
|
+
{
|
|
460
|
+
XMLNode doc = xmlData->getXmlDocument()->document_element();
|
|
461
|
+
XMLNode child = doc.first_child_of_type(pugi::node_element);
|
|
462
|
+
size_t childCount = 0;
|
|
463
|
+
while (not child.empty()) {
|
|
464
|
+
++childCount;
|
|
465
|
+
child = child.next_sibling_of_type(pugi::node_element);
|
|
466
|
+
break; // one child is enough to determine document is not empty.
|
|
467
|
+
}
|
|
468
|
+
if (!childCount)
|
|
469
|
+
createFromTemplate(workbookXml); // create fresh docProps/app.xml
|
|
470
|
+
else { // 2026-06-10: ensure that cp::coreProperties and XML namespaces are defined in existing documents, too
|
|
471
|
+
XMLNode props = xmlDocument().child("Properties");
|
|
472
|
+
if (props.empty())
|
|
473
|
+
props = xmlDocument().prepend_child("Properties");
|
|
474
|
+
ensureXmlNamespaces(props);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* @details
|
|
480
|
+
*/
|
|
481
|
+
XLAppProperties::XLAppProperties(XLXmlData* xmlData) : XLXmlFile(xmlData) {}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* @details copy constructor
|
|
485
|
+
*/
|
|
486
|
+
XLAppProperties::XLAppProperties(const XLAppProperties& other)
|
|
487
|
+
: XLXmlFile(other)
|
|
488
|
+
{}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* @details move constructor
|
|
492
|
+
*/
|
|
493
|
+
XLAppProperties::XLAppProperties(XLAppProperties&& other) noexcept = default;
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* @details copy assignment operator
|
|
497
|
+
*/
|
|
498
|
+
XLAppProperties& XLAppProperties::operator=(const XLAppProperties& other)
|
|
499
|
+
{
|
|
500
|
+
if (&other != this) {
|
|
501
|
+
XLAppProperties temp = other; // copy-construct
|
|
502
|
+
*this = std::move(temp); // move-assign & invalidate temp
|
|
503
|
+
}
|
|
504
|
+
return *this;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* @details move assignment operator
|
|
509
|
+
*/
|
|
510
|
+
XLAppProperties& XLAppProperties::operator=(XLAppProperties&& other) noexcept = default;
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* @details
|
|
514
|
+
*/
|
|
515
|
+
XLAppProperties::~XLAppProperties() = default;
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* @details
|
|
519
|
+
* @note increment == 0 is tolerated for now, used by alignWorksheets to add the value to HeadingPairs if not present
|
|
520
|
+
* However, generally this function should only be called with increment == -1 or increment == +1
|
|
521
|
+
*/
|
|
522
|
+
void XLAppProperties::incrementSheetCount(int16_t increment)
|
|
523
|
+
{
|
|
524
|
+
int32_t newCount = sheetCount(xmlDocument().document_element()).as_int() + increment;
|
|
525
|
+
if (newCount < 1)
|
|
526
|
+
throw XLInternalError("must not decrement sheet count below 1");
|
|
527
|
+
sheetCount(xmlDocument().document_element()).set_value(newCount);
|
|
528
|
+
XMLNode headingPairWorksheetsValue = getHeadingPairsValue(xmlDocument().document_element(), "Worksheets");
|
|
529
|
+
if (headingPairWorksheetsValue.empty()) // seems heading pair does not exist
|
|
530
|
+
addHeadingPair("Worksheets", newCount);
|
|
531
|
+
else
|
|
532
|
+
headingPairWorksheetsValue.text().set(newCount);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* @details ensure that <TitlesOfParts> contains the correct workbook sheet names and <HeadingPairs> Worksheets entry
|
|
537
|
+
* has the correct worksheet count
|
|
538
|
+
*/
|
|
539
|
+
void XLAppProperties::alignWorksheets(std::vector<std::string> const & workbookSheetNames)
|
|
540
|
+
{
|
|
541
|
+
XMLNode titlesOfParts = sheetNames(xmlDocument().document_element()); // creates <TitlesOfParts><vt:vector> if not existing
|
|
542
|
+
XMLNode sheetName = titlesOfParts.first_child_of_type(pugi::node_element);
|
|
543
|
+
// size_t sheetCount = workbookSheetNames.size();
|
|
544
|
+
for (std::string workbookSheetName : workbookSheetNames) {
|
|
545
|
+
if (sheetName.empty())
|
|
546
|
+
sheetName = titlesOfParts.append_child("vt:lpstr", XLForceNamespace);
|
|
547
|
+
sheetName.text().set(workbookSheetName.c_str());
|
|
548
|
+
sheetName = sheetName.next_sibling_of_type(pugi::node_element); // advance to next entry in <TitlesOfParts>, potentially becomes an empty XMLNode()
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// ===== If there are any excess sheet names, clean up.
|
|
552
|
+
if (not sheetName.empty()) {
|
|
553
|
+
// ===== Delete all whitespace nodes prior to the sheet names to be deleted
|
|
554
|
+
while (sheetName.previous_sibling().type() == pugi::node_pcdata) titlesOfParts.remove_child(sheetName.previous_sibling());
|
|
555
|
+
|
|
556
|
+
XMLNode lastSheetName = titlesOfParts.last_child_of_type(pugi::node_element); // delete up to & including this node, preserve whitespaces after
|
|
557
|
+
if (sheetName != lastSheetName) { // If lastSheetName is a node *behind* sheetName
|
|
558
|
+
// ===== Delete all nodes (elements and whitespace) up until lastSheetName
|
|
559
|
+
while (sheetName.next_sibling() != lastSheetName)
|
|
560
|
+
titlesOfParts.remove_child(sheetName.next_sibling());
|
|
561
|
+
// ===== Delete lastSheetName
|
|
562
|
+
titlesOfParts.remove_child(lastSheetName);
|
|
563
|
+
}
|
|
564
|
+
// ===== Delete sheetName
|
|
565
|
+
titlesOfParts.remove_child(sheetName);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
sheetCount(xmlDocument().document_element()).set_value(workbookSheetNames.size()); // save size of <TitlesOfParts><vt:vector>
|
|
569
|
+
incrementSheetCount(0); // ensure that the sheet count is correctly reflected in <HeadingPairs> Worksheets entry
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* @details
|
|
574
|
+
*/
|
|
575
|
+
void XLAppProperties::addSheetName(const std::string& title)
|
|
576
|
+
{
|
|
577
|
+
if (m_xmlData == nullptr) return;
|
|
578
|
+
XMLNode theNode = sheetNames(xmlDocument().document_element()).append_child("vt:lpstr", XLForceNamespace);
|
|
579
|
+
theNode.text().set(title.c_str());
|
|
580
|
+
incrementSheetCount(+1);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* @details
|
|
585
|
+
*/
|
|
586
|
+
void XLAppProperties::deleteSheetName(const std::string& title)
|
|
587
|
+
{
|
|
588
|
+
if (m_xmlData == nullptr) return;
|
|
589
|
+
XMLNode theNode = sheetNames(xmlDocument().document_element()).first_child_of_type(pugi::node_element);
|
|
590
|
+
while (not theNode.empty()) {
|
|
591
|
+
if (theNode.child_value() == title) {
|
|
592
|
+
sheetNames(xmlDocument().document_element()).remove_child(theNode);
|
|
593
|
+
incrementSheetCount(-1);
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
theNode = theNode.next_sibling_of_type(pugi::node_element);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* @details
|
|
602
|
+
*/
|
|
603
|
+
void XLAppProperties::setSheetName(const std::string& oldTitle, const std::string& newTitle)
|
|
604
|
+
{
|
|
605
|
+
if (m_xmlData == nullptr) return;
|
|
606
|
+
XMLNode theNode = sheetNames(xmlDocument().document_element()).first_child_of_type(pugi::node_element);
|
|
607
|
+
while (not theNode.empty()) {
|
|
608
|
+
if (theNode.child_value() == oldTitle) {
|
|
609
|
+
theNode.text().set(newTitle.c_str());
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
theNode = theNode.next_sibling_of_type(pugi::node_element);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* @details
|
|
618
|
+
*/
|
|
619
|
+
void XLAppProperties::addHeadingPair(const std::string& name, int value)
|
|
620
|
+
{
|
|
621
|
+
if (m_xmlData == nullptr) return;
|
|
622
|
+
|
|
623
|
+
XMLNode HeadingPairsNode = headingPairsNode(xmlDocument().document_element());
|
|
624
|
+
XMLNode item = HeadingPairsNode.first_child_of_type(pugi::node_element);
|
|
625
|
+
while (not item.empty() && item.first_child_of_type(pugi::node_element).child_value() != name)
|
|
626
|
+
item = item.next_sibling_of_type(pugi::node_element)
|
|
627
|
+
.next_sibling_of_type(pugi::node_element); // advance two elements to skip count node
|
|
628
|
+
|
|
629
|
+
XMLNode pairCategory = item; // could be an empty node
|
|
630
|
+
XMLNode pairValue {}; // initialize to empty node
|
|
631
|
+
if (not pairCategory.empty())
|
|
632
|
+
pairValue = pairCategory.next_sibling_of_type(pugi::node_element).first_child_of_type(pugi::node_element);
|
|
633
|
+
else {
|
|
634
|
+
item = HeadingPairsNode.last_child_of_type(pugi::node_element);
|
|
635
|
+
if (not item.empty())
|
|
636
|
+
pairCategory = HeadingPairsNode.insert_child_after("vt:variant", item, XLForceNamespace);
|
|
637
|
+
else
|
|
638
|
+
pairCategory = HeadingPairsNode.append_child("vt:variant", XLForceNamespace);
|
|
639
|
+
XMLNode categoryName = pairCategory.append_child("vt:lpstr", XLForceNamespace);
|
|
640
|
+
categoryName.text().set(name.c_str());
|
|
641
|
+
XMLNode pairValueParent = HeadingPairsNode.insert_child_after("vt:variant", pairCategory, XLForceNamespace);
|
|
642
|
+
pairValue = pairValueParent.append_child("vt:i4", XLForceNamespace);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
if (not pairValue.empty())
|
|
646
|
+
pairValue.text().set(std::to_string(value).c_str());
|
|
647
|
+
else {
|
|
648
|
+
using namespace std::literals::string_literals;
|
|
649
|
+
throw XLInternalError("XLAppProperties::addHeadingPair: found no matching pair count value to name "s + name);
|
|
650
|
+
}
|
|
651
|
+
headingPairsSize(xmlDocument().document_element()).set_value(HeadingPairsNode.child_count_of_type());
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* @details
|
|
656
|
+
*/
|
|
657
|
+
void XLAppProperties::deleteHeadingPair(const std::string& name)
|
|
658
|
+
{
|
|
659
|
+
if (m_xmlData == nullptr) return;
|
|
660
|
+
|
|
661
|
+
XMLNode HeadingPairsNode = headingPairsNode(xmlDocument().document_element());
|
|
662
|
+
XMLNode item = HeadingPairsNode.first_child_of_type(pugi::node_element);
|
|
663
|
+
while (not item.empty() && item.first_child_of_type(pugi::node_element).child_value() != name)
|
|
664
|
+
item = item.next_sibling_of_type(pugi::node_element)
|
|
665
|
+
.next_sibling_of_type(pugi::node_element); // advance two elements to skip count node
|
|
666
|
+
|
|
667
|
+
// ===== If item with name was found, remove pair and update headingPairsSize
|
|
668
|
+
if (not item.empty()) {
|
|
669
|
+
const XMLNode count = item.next_sibling_of_type(pugi::node_element);
|
|
670
|
+
// ===== 2024-05-28: delete all (non-element) nodes between item and count node, *then* delete non-element nodes following a count node
|
|
671
|
+
if (not count.empty()) {
|
|
672
|
+
while (item.next_sibling() != count)
|
|
673
|
+
HeadingPairsNode.remove_child(item.next_sibling()); // remove nodes between item & count nodes to be deleted jointly
|
|
674
|
+
|
|
675
|
+
// ===== Delete all non-element nodes following the count node
|
|
676
|
+
while ((not count.next_sibling().empty()) && (count.next_sibling().type() != pugi::node_element))
|
|
677
|
+
HeadingPairsNode.remove_child(count.next_sibling()); // remove all non-element nodes following a count node
|
|
678
|
+
|
|
679
|
+
HeadingPairsNode.remove_child(count);
|
|
680
|
+
}
|
|
681
|
+
// REMOVED: formatting doesn't get prettier by removing whitespaces on both sides of a pair
|
|
682
|
+
// while (item.previous_sibling().type() == pugi::node_pcdata) HeadingPairsNode.remove_child(item.previous_sibling());
|
|
683
|
+
|
|
684
|
+
HeadingPairsNode.remove_child(item);
|
|
685
|
+
headingPairsSize(xmlDocument().document_element()).set_value(HeadingPairsNode.child_count_of_type());
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* @details
|
|
691
|
+
*/
|
|
692
|
+
void XLAppProperties::setHeadingPair(const std::string& name, int newValue)
|
|
693
|
+
{
|
|
694
|
+
if (m_xmlData == nullptr) return;
|
|
695
|
+
|
|
696
|
+
XMLNode pairValue = getHeadingPairsValue(xmlDocument().document_element(), name);
|
|
697
|
+
using namespace std::literals::string_literals;
|
|
698
|
+
if (not pairValue.empty() && (pairValue.raw_name() == "vt:i4"s))
|
|
699
|
+
pairValue.text().set(std::to_string(newValue).c_str());
|
|
700
|
+
else
|
|
701
|
+
throw XLInternalError("XLAppProperties::setHeadingPair: found no matching pair count value to name "s + name);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* @details
|
|
706
|
+
*/
|
|
707
|
+
void XLAppProperties::setProperty(const std::string& name, const std::string& value)
|
|
708
|
+
{
|
|
709
|
+
if (m_xmlData == nullptr) return;
|
|
710
|
+
auto property = xmlDocument().document_element().child(name.c_str());
|
|
711
|
+
if (property.empty()) xmlDocument().document_element().append_child(name.c_str());
|
|
712
|
+
property.text().set(value.c_str());
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* @details
|
|
717
|
+
*/
|
|
718
|
+
std::string XLAppProperties::property(const std::string& name) const
|
|
719
|
+
{
|
|
720
|
+
if (m_xmlData == nullptr) return "";
|
|
721
|
+
XMLNode property = xmlDocument().document_element().child(name.c_str());
|
|
722
|
+
if (property.empty())
|
|
723
|
+
property = xmlDocument().document_element().append_child(name.c_str()); // BUGFIX 2024-05-21: re-assign the newly created node to
|
|
724
|
+
// property, so that .text().get() is defined behavior
|
|
725
|
+
return property.text().get();
|
|
726
|
+
// NOTE 2024-05-21: this was previously defined behavior because XMLNode::text() called from an empty xml_node returns an xml_text node
|
|
727
|
+
// constructed on an empty _root pointer, while in turn xml_text::get() returns a PUGIXML_TEXT("") for an empty xml_text node
|
|
728
|
+
// However, relying on all this implicit functionality was really ugly ;)
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* @details
|
|
733
|
+
*/
|
|
734
|
+
void XLAppProperties::deleteProperty(const std::string& name)
|
|
735
|
+
{
|
|
736
|
+
if (m_xmlData == nullptr) return;
|
|
737
|
+
const auto property = xmlDocument().document_element().child(name.c_str());
|
|
738
|
+
if (property.empty()) return;
|
|
739
|
+
|
|
740
|
+
xmlDocument().document_element().remove_child(property);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* @details
|
|
745
|
+
*/
|
|
746
|
+
void XLAppProperties::appendSheetName(const std::string& sheetName)
|
|
747
|
+
{
|
|
748
|
+
if (m_xmlData == nullptr) return;
|
|
749
|
+
auto theNode = sheetNames(xmlDocument().document_element()).append_child("vt:lpstr", XLForceNamespace);
|
|
750
|
+
theNode.text().set(sheetName.c_str());
|
|
751
|
+
incrementSheetCount(+1);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* @details
|
|
756
|
+
*/
|
|
757
|
+
void XLAppProperties::prependSheetName(const std::string& sheetName)
|
|
758
|
+
{
|
|
759
|
+
if (m_xmlData == nullptr) return;
|
|
760
|
+
auto theNode = sheetNames(xmlDocument().document_element()).prepend_child("vt:lpstr", XLForceNamespace);
|
|
761
|
+
theNode.text().set(sheetName.c_str());
|
|
762
|
+
incrementSheetCount(+1);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* @details
|
|
767
|
+
*/
|
|
768
|
+
void XLAppProperties::insertSheetName(const std::string& sheetName, unsigned int index)
|
|
769
|
+
{
|
|
770
|
+
if (m_xmlData == nullptr) return;
|
|
771
|
+
|
|
772
|
+
if (index <= 1) {
|
|
773
|
+
prependSheetName(sheetName);
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// ===== If sheet needs to be appended...
|
|
778
|
+
if (index > sheetCount(xmlDocument().document_element()).as_uint()) {
|
|
779
|
+
// ===== If at least one sheet node exists, apply some pretty formatting by appending new sheet name between last sheet and trailing
|
|
780
|
+
// whitespaces.
|
|
781
|
+
const XMLNode lastSheet = sheetNames(xmlDocument().document_element()).last_child_of_type(pugi::node_element);
|
|
782
|
+
if (not lastSheet.empty()) {
|
|
783
|
+
XMLNode theNode = sheetNames(xmlDocument().document_element()).insert_child_after("vt:lpstr", lastSheet, XLForceNamespace);
|
|
784
|
+
theNode.text().set(sheetName.c_str());
|
|
785
|
+
// ===== Update sheet count before return statement.
|
|
786
|
+
incrementSheetCount(+1);
|
|
787
|
+
}
|
|
788
|
+
else
|
|
789
|
+
appendSheetName(sheetName);
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
XMLNode curNode = sheetNames(xmlDocument().document_element()).first_child_of_type(pugi::node_element);
|
|
794
|
+
unsigned idx = 1;
|
|
795
|
+
while (not curNode.empty()) {
|
|
796
|
+
if (idx == index) break;
|
|
797
|
+
curNode = curNode.next_sibling_of_type(pugi::node_element);
|
|
798
|
+
++idx;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (curNode.empty()) {
|
|
802
|
+
appendSheetName(sheetName);
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
XMLNode theNode = sheetNames(xmlDocument().document_element()).insert_child_before("vt:lpstr", curNode, XLForceNamespace);
|
|
807
|
+
theNode.text().set(sheetName.c_str());
|
|
808
|
+
|
|
809
|
+
incrementSheetCount(+1);
|
|
810
|
+
}
|