react-native-nitro-xlsx 0.1.4 → 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 +27 -27
- package/Package.swift +35 -10
- package/README.md +220 -58
- package/android/CMakeLists.txt +24 -27
- package/android/cpp-adapter.cpp +12 -0
- package/android/src/main/java/com/margelo/nitro/xlsx/NitroXlsxPackage.kt +9 -0
- package/cpp/HybridNitroXlsx.cpp +25 -179
- package/cpp/HybridNitroXlsx.hpp +2 -2
- package/cpp/HybridXlsxConditionalFormat.cpp +252 -0
- package/cpp/HybridXlsxConditionalFormat.hpp +62 -0
- package/cpp/HybridXlsxConditionalFormats.cpp +46 -0
- package/cpp/HybridXlsxConditionalFormats.hpp +28 -0
- package/cpp/HybridXlsxWorkbook.cpp +159 -196
- package/cpp/HybridXlsxWorkbook.hpp +7 -2
- package/cpp/HybridXlsxWorksheet.cpp +433 -62
- package/cpp/HybridXlsxWorksheet.hpp +73 -26
- package/cpp/XlsxCacheDir.cpp +76 -0
- package/cpp/XlsxCacheDir.hpp +27 -0
- package/cpp/XlsxError.hpp +68 -0
- package/cpp/XlsxJson.cpp +185 -0
- package/cpp/XlsxJson.hpp +36 -0
- package/ios/XlsxCacheDir.mm +60 -0
- package/nitrogen/generated/android/NitroXlsx+autolinking.cmake +2 -0
- package/nitrogen/generated/shared/c++/HybridNitroXlsxSpec.hpp +5 -3
- package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatSpec.cpp +54 -0
- package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatSpec.hpp +95 -0
- package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatsSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatsSpec.hpp +68 -0
- package/nitrogen/generated/shared/c++/HybridXlsxWorkbookSpec.cpp +3 -0
- package/nitrogen/generated/shared/c++/HybridXlsxWorkbookSpec.hpp +6 -1
- package/nitrogen/generated/shared/c++/HybridXlsxWorksheetSpec.cpp +47 -19
- package/nitrogen/generated/shared/c++/HybridXlsxWorksheetSpec.hpp +52 -20
- package/package.json +3 -3
- package/scripts/run-cpp-tests.sh +14 -0
- package/src/__mocks__/react-native-nitro-modules.ts +1 -0
- package/src/__tests__/index.test.ts +76 -7
- package/src/index.ts +107 -18
- package/src/specs/NitroXlsx.nitro.ts +141 -44
- 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/ios/dummy.swift +0 -2
- package/scripts/prepare-openxlsx.js +0 -109
|
@@ -0,0 +1,784 @@
|
|
|
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 <algorithm>
|
|
48
|
+
#include <cctype> // std::isdigit (issue #330)
|
|
49
|
+
#include <iostream> // std::cerr
|
|
50
|
+
#include <string> // std::string
|
|
51
|
+
|
|
52
|
+
// ===== OpenXLSX Includes ===== //
|
|
53
|
+
#include "XLDocument.hpp" // pugi_parse_settings
|
|
54
|
+
#include "XLDrawing.hpp"
|
|
55
|
+
#include "XLXmlParser.hpp" // pugixml wrapper
|
|
56
|
+
#include "utilities/XLUtilities.hpp" // OpenXLSX::ignore, appendAndGetNode
|
|
57
|
+
|
|
58
|
+
using namespace OpenXLSX;
|
|
59
|
+
|
|
60
|
+
namespace OpenXLSX
|
|
61
|
+
{
|
|
62
|
+
const std::string ShapeNodeName = "v:shape";
|
|
63
|
+
const std::string ShapeTypeNodeName = "v:shapetype";
|
|
64
|
+
|
|
65
|
+
// utility functions
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @brief test if v:shapetype attribute id already exists at begin of file
|
|
69
|
+
* @param rootNode the parent that holds all v:shapetype nodes to be compared
|
|
70
|
+
* @param shapeTypeNode the node to check for a duplicate id
|
|
71
|
+
* @return true if node would be a duplicate (and can be deleted), false if node is unique (so far)
|
|
72
|
+
*/
|
|
73
|
+
bool wouldBeDuplicateShapeType(XMLNode const& rootNode, XMLNode const& shapeTypeNode)
|
|
74
|
+
{
|
|
75
|
+
std::string id = shapeTypeNode.attribute("id").value();
|
|
76
|
+
XMLNode node = rootNode.first_child_of_type(pugi::node_element);
|
|
77
|
+
using namespace std::literals::string_literals;
|
|
78
|
+
while (node != shapeTypeNode && node.raw_name() == ShapeTypeNodeName) { // do not compare shapeTypeNode with itself, and abort on first non-shapetype node
|
|
79
|
+
if (node.attribute("id").value() == id) return true; // found an existing shapetype with the same id
|
|
80
|
+
node = node.next_sibling_of_type(pugi::node_element);
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @brief move an xml node to a new position within the same root node
|
|
87
|
+
* @param rootNode the parent that can perform inserts / deletes
|
|
88
|
+
* @param node the node to move
|
|
89
|
+
* @param insertAfter the reference for the new location, if insertAfter.empty(): move node to first position in rootNode
|
|
90
|
+
* @param withWhitespaces if true, move all node_pcdata nodes preceeding node, together with the node
|
|
91
|
+
* @return the node as inserted at the destination - empty node if insertion can't be performed (rootNode or node are empty)
|
|
92
|
+
*/
|
|
93
|
+
XMLNode moveNode(XMLNode& rootNode, XMLNode& node, XMLNode const& insertAfter, bool withWhitespaces = true)
|
|
94
|
+
{
|
|
95
|
+
if (rootNode.empty() || node.empty()) return XMLNode{}; // can't perform move
|
|
96
|
+
if (node == insertAfter || node == insertAfter.next_sibling()) return node; // nothing to do
|
|
97
|
+
|
|
98
|
+
XMLNode newNode{};
|
|
99
|
+
if (insertAfter.empty())
|
|
100
|
+
newNode = rootNode.prepend_copy(node);
|
|
101
|
+
else
|
|
102
|
+
newNode = rootNode.insert_copy_after(node, insertAfter);
|
|
103
|
+
|
|
104
|
+
if (withWhitespaces) {
|
|
105
|
+
copyLeadingWhitespaces(rootNode, node, newNode); // copy leading whitespaces
|
|
106
|
+
while (node.previous_sibling().type() == pugi::node_pcdata) // then remove whitespaces that were just copied to newNode
|
|
107
|
+
rootNode.remove_child(node.previous_sibling());
|
|
108
|
+
}
|
|
109
|
+
rootNode.remove_child(node); // remove node that was just copied to new location
|
|
110
|
+
|
|
111
|
+
return newNode;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
XLShapeTextVAlign XLShapeTextVAlignFromString(std::string const& vAlignString)
|
|
115
|
+
{
|
|
116
|
+
if (vAlignString == "Center") return XLShapeTextVAlign::Center;
|
|
117
|
+
if (vAlignString == "Top" ) return XLShapeTextVAlign::Top;
|
|
118
|
+
if (vAlignString == "Bottom") return XLShapeTextVAlign::Bottom;
|
|
119
|
+
std::cerr << __func__ << ": invalid XLShapeTextVAlign setting" << vAlignString << std::endl;
|
|
120
|
+
return XLShapeTextVAlign::Invalid;
|
|
121
|
+
|
|
122
|
+
}
|
|
123
|
+
std::string XLShapeTextVAlignToString(XLShapeTextVAlign vAlign)
|
|
124
|
+
{
|
|
125
|
+
switch (vAlign) {
|
|
126
|
+
case XLShapeTextVAlign::Center: return "Center";
|
|
127
|
+
case XLShapeTextVAlign::Top: return "Top";
|
|
128
|
+
case XLShapeTextVAlign::Bottom: return "Bottom";
|
|
129
|
+
case XLShapeTextVAlign::Invalid: [[fallthrough]];
|
|
130
|
+
default: return "(invalid)";
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
XLShapeTextHAlign XLShapeTextHAlignFromString(std::string const& hAlignString)
|
|
134
|
+
{
|
|
135
|
+
if (hAlignString == "Left" ) return XLShapeTextHAlign::Left;
|
|
136
|
+
if (hAlignString == "Right" ) return XLShapeTextHAlign::Right;
|
|
137
|
+
if (hAlignString == "Center") return XLShapeTextHAlign::Center;
|
|
138
|
+
std::cerr << __func__ << ": invalid XLShapeTextHAlign setting" << hAlignString << std::endl;
|
|
139
|
+
return XLShapeTextHAlign::Invalid;
|
|
140
|
+
}
|
|
141
|
+
std::string XLShapeTextHAlignToString(XLShapeTextHAlign hAlign)
|
|
142
|
+
{
|
|
143
|
+
switch (hAlign) {
|
|
144
|
+
case XLShapeTextHAlign::Left: return "Left";
|
|
145
|
+
case XLShapeTextHAlign::Right: return "Right";
|
|
146
|
+
case XLShapeTextHAlign::Center: return "Center";
|
|
147
|
+
case XLShapeTextHAlign::Invalid: [[fallthrough]];
|
|
148
|
+
default: return "(invalid)";
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
} // namespace OpenXLSX
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
// ========== XLShapeClientData Member Functions
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @details default constructor
|
|
159
|
+
*/
|
|
160
|
+
XLShapeClientData::XLShapeClientData()
|
|
161
|
+
: m_clientDataNode(std::make_unique<XMLNode>())
|
|
162
|
+
{}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @details XMLNode constructor
|
|
166
|
+
*/
|
|
167
|
+
XLShapeClientData::XLShapeClientData(const XMLNode& node)
|
|
168
|
+
: m_clientDataNode(std::make_unique<XMLNode>(node))
|
|
169
|
+
{}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @details copy constructor
|
|
173
|
+
*/
|
|
174
|
+
XLShapeClientData::XLShapeClientData(const XLShapeClientData& other)
|
|
175
|
+
: m_clientDataNode(std::make_unique<XMLNode>(*other.m_clientDataNode))
|
|
176
|
+
{}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @details explicit default move constructor
|
|
180
|
+
*/
|
|
181
|
+
XLShapeClientData::XLShapeClientData(XLShapeClientData&& other) noexcept = default;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @details explicit default destructor
|
|
185
|
+
*/
|
|
186
|
+
XLShapeClientData::~XLShapeClientData() = default;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @details explicit copy assignment operator
|
|
190
|
+
*/
|
|
191
|
+
XLShapeClientData& XLShapeClientData::operator=(const XLShapeClientData& other)
|
|
192
|
+
{
|
|
193
|
+
if (&other != this) {
|
|
194
|
+
XLShapeClientData temp = other; // copy-construct
|
|
195
|
+
*this = std::move(temp); // move-assign & invalidate temp
|
|
196
|
+
}
|
|
197
|
+
return *this;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* @details explicit default move assignment operator
|
|
202
|
+
*/
|
|
203
|
+
XLShapeClientData& XLShapeClientData::operator=(XLShapeClientData&& other) noexcept = default;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @details XLShapeClientData getter functions
|
|
207
|
+
*/
|
|
208
|
+
bool elementTextAsBool(XMLNode const& node) {
|
|
209
|
+
if (node.empty()) return false; // node doesn't exist: false
|
|
210
|
+
if (node.text().empty()) return true; // node exists but has no setting: true
|
|
211
|
+
char c = node.text().get()[0]; // node exists and has a setting:
|
|
212
|
+
if (c == 't' || c == 'T') return true; // check true setting on first letter only
|
|
213
|
+
return false; // otherwise return false
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
std::string XLShapeClientData::objectType() const { return appendAndGetAttribute(*m_clientDataNode, "ObjectType", "Note" ).value() ; }
|
|
217
|
+
bool XLShapeClientData::moveWithCells() const { return elementTextAsBool ( m_clientDataNode->child("x:MoveWithCells")) ; }
|
|
218
|
+
bool XLShapeClientData::sizeWithCells() const { return elementTextAsBool ( m_clientDataNode->child("x:SizeWithCells")) ; }
|
|
219
|
+
std::string XLShapeClientData::anchor() const { return m_clientDataNode->child("x:Anchor").value() ; }
|
|
220
|
+
bool XLShapeClientData::autoFill() const { return elementTextAsBool ( m_clientDataNode->child("x:AutoFill")) ; }
|
|
221
|
+
XLShapeTextVAlign XLShapeClientData::textVAlign() const {
|
|
222
|
+
return XLShapeTextVAlignFromString(m_clientDataNode->child("x:TextVAlign").text().get());
|
|
223
|
+
// XMLNode vAlign = m_clientDataNode->child("x:TextVAlign");
|
|
224
|
+
// if (vAlign.empty()) return XLDefaultShapeTextVAlign;
|
|
225
|
+
// return XLShapeTextVAlignFromString(vAlign.text().get());
|
|
226
|
+
}
|
|
227
|
+
XLShapeTextHAlign XLShapeClientData::textHAlign() const {
|
|
228
|
+
return XLShapeTextHAlignFromString(m_clientDataNode->child("x:TextHAlign").text().get());
|
|
229
|
+
// XMLNode hAlign = m_clientDataNode->child("x:TextHAlign");
|
|
230
|
+
// if (hAlign.empty()) return XLDefaultShapeTextHAlign;
|
|
231
|
+
// return XLShapeTextHAlignFromString(hAlign.text().get());
|
|
232
|
+
}
|
|
233
|
+
uint32_t XLShapeClientData::row() const {
|
|
234
|
+
return appendAndGetNode(*m_clientDataNode, "x:Row", m_nodeOrder, XLForceNamespace).text().as_uint(0);
|
|
235
|
+
}
|
|
236
|
+
uint16_t XLShapeClientData::column() const {
|
|
237
|
+
return appendAndGetNode(*m_clientDataNode, "x:Column", m_nodeOrder, XLForceNamespace).text().as_uint(0);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* @details XLShapeClientData setter functions
|
|
242
|
+
*/
|
|
243
|
+
bool XLShapeClientData::setObjectType(std::string newObjectType) { return appendAndSetAttribute(*m_clientDataNode, "ObjectType", newObjectType ).empty() == false; }
|
|
244
|
+
bool XLShapeClientData::setMoveWithCells(bool set)
|
|
245
|
+
{ return appendAndGetNode(*m_clientDataNode, "x:MoveWithCells", m_nodeOrder, XLForceNamespace).text().set(set ? "" : "False");
|
|
246
|
+
// XMLNode moveWithCellsNode = appendAndGetNode(*m_clientDataNode, "x:MoveWithCells", m_nodeOrder, XLForceNamespace);
|
|
247
|
+
// if (moveWithCellsNode.empty()) return false;
|
|
248
|
+
// return moveWithCellsNode.text().set(set ? "True" : "False");
|
|
249
|
+
}
|
|
250
|
+
bool XLShapeClientData::setSizeWithCells(bool set)
|
|
251
|
+
{ return appendAndGetNode(*m_clientDataNode, "x:SizeWithCells", m_nodeOrder, XLForceNamespace).text().set(set ? "" : "False"); }
|
|
252
|
+
|
|
253
|
+
bool XLShapeClientData::setAnchor (std::string newAnchor)
|
|
254
|
+
{ return appendAndGetNode(*m_clientDataNode, "x:Anchor", m_nodeOrder, XLForceNamespace).text().set(newAnchor.c_str()); }
|
|
255
|
+
|
|
256
|
+
bool XLShapeClientData::setAutoFill (bool set)
|
|
257
|
+
{ return appendAndGetNode(*m_clientDataNode, "x:AutoFill", m_nodeOrder, XLForceNamespace).text().set(set ? "True" : "False"); }
|
|
258
|
+
|
|
259
|
+
bool XLShapeClientData::setTextVAlign (XLShapeTextVAlign newTextVAlign)
|
|
260
|
+
{ return appendAndGetNode(*m_clientDataNode, "x:TextVAlign", m_nodeOrder, XLForceNamespace).text().set(XLShapeTextVAlignToString(newTextVAlign).c_str()); }
|
|
261
|
+
|
|
262
|
+
bool XLShapeClientData::setTextHAlign (XLShapeTextHAlign newTextHAlign)
|
|
263
|
+
{ return appendAndGetNode(*m_clientDataNode, "x:TextHAlign", m_nodeOrder, XLForceNamespace).text().set(XLShapeTextHAlignToString(newTextHAlign).c_str()); }
|
|
264
|
+
|
|
265
|
+
bool XLShapeClientData::setRow (uint32_t newRow)
|
|
266
|
+
{ return appendAndGetNode(*m_clientDataNode, "x:Row", m_nodeOrder, XLForceNamespace).text().set(newRow); }
|
|
267
|
+
|
|
268
|
+
bool XLShapeClientData::setColumn (uint16_t newColumn)
|
|
269
|
+
{ return appendAndGetNode(*m_clientDataNode, "x:Column", m_nodeOrder, XLForceNamespace).text().set(newColumn); }
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
// ========== XLShape Member Functions
|
|
273
|
+
/**
|
|
274
|
+
* @details
|
|
275
|
+
*/
|
|
276
|
+
XLShapeStyle::XLShapeStyle()
|
|
277
|
+
: m_style(""),
|
|
278
|
+
m_styleAttribute(std::make_unique<XMLAttribute>())
|
|
279
|
+
{
|
|
280
|
+
setPosition("absolute");
|
|
281
|
+
setMarginLeft(100);
|
|
282
|
+
setMarginTop(0);
|
|
283
|
+
setWidth(80);
|
|
284
|
+
setHeight(50);
|
|
285
|
+
setMsoWrapStyle("none");
|
|
286
|
+
setVTextAnchor("middle");
|
|
287
|
+
hide();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* @details
|
|
292
|
+
*/
|
|
293
|
+
XLShapeStyle::XLShapeStyle(const std::string& styleAttribute)
|
|
294
|
+
: m_style(styleAttribute),
|
|
295
|
+
m_styleAttribute(std::make_unique<XMLAttribute>())
|
|
296
|
+
{}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @details
|
|
300
|
+
*/
|
|
301
|
+
XLShapeStyle::XLShapeStyle(const XMLAttribute& styleAttribute)
|
|
302
|
+
: m_style(""),
|
|
303
|
+
m_styleAttribute(std::make_unique<XMLAttribute>(styleAttribute))
|
|
304
|
+
{}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* @brief explicit default destructor
|
|
308
|
+
*/
|
|
309
|
+
XLShapeStyle::~XLShapeStyle() = default;
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* @details find attributeName in m_nodeOrder, then return index
|
|
313
|
+
*/
|
|
314
|
+
int16_t XLShapeStyle::attributeOrderIndex(std::string const& attributeName) const
|
|
315
|
+
{
|
|
316
|
+
// std::string m_style{"position:absolute;margin-left:100pt;margin-top:0pt;width:50pt;height:50.0pt;mso-wrap-style:none;v-text-anchor:middle;visibility:hidden"};
|
|
317
|
+
auto attributeIterator = std::find(m_nodeOrder.begin(), m_nodeOrder.end(), attributeName);
|
|
318
|
+
if (attributeIterator == m_nodeOrder.end())
|
|
319
|
+
return -1;
|
|
320
|
+
return attributeIterator - m_nodeOrder.begin();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* @details
|
|
325
|
+
*/
|
|
326
|
+
XLShapeStyleAttribute XLShapeStyle::getAttribute(std::string const& attributeName, std::string const& valIfNotFound) const
|
|
327
|
+
{
|
|
328
|
+
if (attributeOrderIndex(attributeName) == -1) {
|
|
329
|
+
using namespace std::literals::string_literals;
|
|
330
|
+
throw XLInternalError("XLShapeStyle.getAttribute: attribute "s + attributeName + " is not defined in class"s);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// if attribute is linked, re-read m_style each time in case the underlying XML has changed
|
|
334
|
+
if (not m_styleAttribute->empty()) m_style = std::string(m_styleAttribute->value());
|
|
335
|
+
|
|
336
|
+
size_t lastPos = 0;
|
|
337
|
+
XLShapeStyleAttribute result;
|
|
338
|
+
result.name = ""; // indicates "not found"
|
|
339
|
+
result.value = ""; // default in case attribute name is found but has no value
|
|
340
|
+
|
|
341
|
+
do {
|
|
342
|
+
size_t pos = m_style.find(';', lastPos);
|
|
343
|
+
std::string attrPair = m_style.substr(lastPos, pos - lastPos);
|
|
344
|
+
if (attrPair.length() > 0) {
|
|
345
|
+
size_t separatorPos = attrPair.find(':');
|
|
346
|
+
if (attributeName == attrPair.substr(0, separatorPos)) { // found!
|
|
347
|
+
result.name = attributeName;
|
|
348
|
+
if( separatorPos != std::string::npos )
|
|
349
|
+
result.value = attrPair.substr(separatorPos + 1);
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
lastPos = pos+1;
|
|
354
|
+
} while (lastPos < m_style.length());
|
|
355
|
+
if (lastPos >= m_style.length()) // attribute was not found
|
|
356
|
+
result.value = valIfNotFound; // -> return default value
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* @details
|
|
362
|
+
*/
|
|
363
|
+
bool XLShapeStyle::setAttribute(std::string const& attributeName, std::string const& attributeValue)
|
|
364
|
+
{
|
|
365
|
+
int16_t attrIndex = attributeOrderIndex(attributeName);
|
|
366
|
+
if (attrIndex == -1) {
|
|
367
|
+
using namespace std::literals::string_literals;
|
|
368
|
+
throw XLInternalError("XLShapeStyle.setAttribute: attribute "s + attributeName + " is not defined in class"s);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// if attribute is linked, re-read m_style each time in case the underlying XML has changed
|
|
372
|
+
if (not m_styleAttribute->empty()) m_style = std::string(m_styleAttribute->value());
|
|
373
|
+
|
|
374
|
+
size_t lastPos = 0;
|
|
375
|
+
size_t appendPos = 0;
|
|
376
|
+
do {
|
|
377
|
+
size_t pos = m_style.find(';', lastPos);
|
|
378
|
+
|
|
379
|
+
std::string attrPair = m_style.substr(lastPos, pos - lastPos);
|
|
380
|
+
if (attrPair.length() > 0) {
|
|
381
|
+
size_t separatorPos = attrPair.find(':');
|
|
382
|
+
int16_t thisAttrIndex = attributeOrderIndex(attrPair.substr(0, separatorPos));
|
|
383
|
+
if (thisAttrIndex >= attrIndex) { // can insert or update
|
|
384
|
+
appendPos = (thisAttrIndex == attrIndex ? pos : lastPos); // if match: append from following attribute, if not found, append from current (insert)
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if(pos == std::string::npos)
|
|
389
|
+
lastPos = pos;
|
|
390
|
+
else
|
|
391
|
+
lastPos = pos + 1;
|
|
392
|
+
} while (lastPos < m_style.length());
|
|
393
|
+
if (lastPos >= m_style.length() || appendPos > m_style.length()) { // if attribute needs to be appended or was found at last position
|
|
394
|
+
appendPos = m_style.length(); // then nothing remains from m_style to follow (appended) attribute
|
|
395
|
+
|
|
396
|
+
// for semi-colon logic, lastPos needs to be capped at string length (so that it can be 0 for empty string)
|
|
397
|
+
if (lastPos > m_style.length()) lastPos = m_style.length();
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
using namespace std::literals::string_literals;
|
|
401
|
+
m_style = m_style.substr(0, lastPos) + ((lastPos != 0 && appendPos == m_style.length()) ? ";"s : ""s) // prepend ';' if attribute is appended to non-empty string
|
|
402
|
+
/**/ + attributeName + ":"s + attributeValue // insert attribute:value pair
|
|
403
|
+
/**/ + (appendPos < m_style.length() ? ";"s : ""s) + m_style.substr(appendPos); // append ';' if attribute is inserted before other data
|
|
404
|
+
|
|
405
|
+
// if attribute is linked, update it with the new style value
|
|
406
|
+
if (not m_styleAttribute->empty()) m_styleAttribute->set_value(m_style.c_str());
|
|
407
|
+
|
|
408
|
+
return true;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* @details XLShapeStyle getter functions
|
|
413
|
+
*/
|
|
414
|
+
std::string XLShapeStyle::position () const { return getAttribute("position" ).value ; }
|
|
415
|
+
uint16_t XLShapeStyle::marginLeft () const { return static_cast<uint16_t>(std::stoi(getAttribute("margin-left" ).value)); }
|
|
416
|
+
uint16_t XLShapeStyle::marginTop () const { return static_cast<uint16_t>(std::stoi(getAttribute("margin-top" ).value)); }
|
|
417
|
+
uint16_t XLShapeStyle::width () const { return static_cast<uint16_t>(std::stoi(getAttribute("width" ).value)); }
|
|
418
|
+
uint16_t XLShapeStyle::height () const { return static_cast<uint16_t>(std::stoi(getAttribute("height" ).value)); }
|
|
419
|
+
std::string XLShapeStyle::msoWrapStyle() const { return getAttribute("mso-wrap-style").value ; }
|
|
420
|
+
std::string XLShapeStyle::vTextAnchor () const { return getAttribute("v-text-anchor" ).value ; }
|
|
421
|
+
bool XLShapeStyle::hidden () const { return ("hidden" == getAttribute("visibility" ).value ); }
|
|
422
|
+
bool XLShapeStyle::visible () const { return !hidden(); }
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* @details XLShapeStyle setter functions
|
|
426
|
+
*/
|
|
427
|
+
bool XLShapeStyle::setPosition (std::string newPosition) { return setAttribute("position", newPosition ); }
|
|
428
|
+
bool XLShapeStyle::setMarginLeft (uint16_t newMarginLeft) { return setAttribute("margin-left", std::to_string(newMarginLeft) + std::string("pt")); }
|
|
429
|
+
bool XLShapeStyle::setMarginTop (uint16_t newMarginTop) { return setAttribute("margin-top", std::to_string(newMarginTop) + std::string("pt")); }
|
|
430
|
+
bool XLShapeStyle::setWidth (uint16_t newWidth) { return setAttribute("width", std::to_string(newWidth) + std::string("pt")); }
|
|
431
|
+
bool XLShapeStyle::setHeight (uint16_t newHeight) { return setAttribute("height", std::to_string(newHeight) + std::string("pt")); }
|
|
432
|
+
bool XLShapeStyle::setMsoWrapStyle(std::string newMsoWrapStyle) { return setAttribute("mso-wrap-style", newMsoWrapStyle ); }
|
|
433
|
+
bool XLShapeStyle::setVTextAnchor (std::string newVTextAnchor) { return setAttribute("v-text-anchor", newVTextAnchor ); }
|
|
434
|
+
bool XLShapeStyle::hide () { return setAttribute("visibility", "hidden" ); }
|
|
435
|
+
bool XLShapeStyle::show () { return setAttribute("visibility", "visible" ); }
|
|
436
|
+
|
|
437
|
+
// ========== XLShape Member Functions
|
|
438
|
+
XLShape::XLShape() : m_shapeNode(std::make_unique<XMLNode>(XMLNode())) {}
|
|
439
|
+
|
|
440
|
+
XLShape::XLShape(const XMLNode& node) : m_shapeNode(std::make_unique<XMLNode>(node)) {}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* @details copy constructor
|
|
444
|
+
*/
|
|
445
|
+
XLShape::XLShape(const XLShape& other)
|
|
446
|
+
: m_shapeNode(std::make_unique<XMLNode>(*other.m_shapeNode))
|
|
447
|
+
{}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* @details explicit default move constructor
|
|
451
|
+
*/
|
|
452
|
+
XLShape::XLShape(XLShape&& other) noexcept = default;
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* @details explicit default destructor
|
|
456
|
+
*/
|
|
457
|
+
XLShape::~XLShape() = default;
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* @details copy assignment operator
|
|
461
|
+
*/
|
|
462
|
+
XLShape& XLShape::operator=(const XLShape& other)
|
|
463
|
+
{
|
|
464
|
+
if (&other != this) {
|
|
465
|
+
XLShape temp = other; // copy-construct
|
|
466
|
+
*this = std::move(temp); // move-assign & invalidate temp
|
|
467
|
+
}
|
|
468
|
+
return *this;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* @details explicit default move assignment operator
|
|
473
|
+
*/
|
|
474
|
+
XLShape& XLShape::operator=(XLShape&& other) noexcept = default;
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* @details getter functions: return the shape's attributes
|
|
478
|
+
*/
|
|
479
|
+
std::string XLShape::shapeId() const { return m_shapeNode->attribute("id").value() ; } // const for user, managed by parent
|
|
480
|
+
std::string XLShape::fillColor() const { return appendAndGetAttribute(*m_shapeNode, "fillcolor", "#ffffc0").value() ; }
|
|
481
|
+
bool XLShape::stroked() const { return appendAndGetAttribute(*m_shapeNode, "stroked", "t" ).as_bool() ; }
|
|
482
|
+
std::string XLShape::type() const { return appendAndGetAttribute(*m_shapeNode, "type", "" ).value() ; }
|
|
483
|
+
bool XLShape::allowInCell() const { return appendAndGetAttribute(*m_shapeNode, "o:allowincell", "f" ).as_bool() ; }
|
|
484
|
+
XLShapeStyle XLShape::style() { return XLShapeStyle(appendAndGetAttribute(*m_shapeNode, "style", "" ) ); }
|
|
485
|
+
|
|
486
|
+
XLShapeClientData XLShape::clientData() {
|
|
487
|
+
return XLShapeClientData(appendAndGetNode(*m_shapeNode, "x:ClientData", m_nodeOrder, XLForceNamespace));
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* @details setter functions: assign the shape's attributes
|
|
492
|
+
*/
|
|
493
|
+
bool XLShape::setFillColor (std::string const& newFillColor) { return appendAndSetAttribute(*m_shapeNode, "fillcolor", newFillColor ).empty() == false; }
|
|
494
|
+
bool XLShape::setStroked (bool set) { return appendAndSetAttribute(*m_shapeNode, "stroked", (set ? "t" : "f")).empty() == false; }
|
|
495
|
+
bool XLShape::setType (std::string const& newType) { return appendAndSetAttribute(*m_shapeNode, "type", newType ).empty() == false; }
|
|
496
|
+
bool XLShape::setAllowInCell(bool set) { return appendAndSetAttribute(*m_shapeNode, "o:allowincell", (set ? "t" : "f")).empty() == false; }
|
|
497
|
+
bool XLShape::setStyle (std::string const& newStyle) { return appendAndSetAttribute(*m_shapeNode, "style", newStyle ).empty() == false; }
|
|
498
|
+
bool XLShape::setStyle (XLShapeStyle const& newStyle) { return setStyle( newStyle.raw() ); }
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
// ========== XLVmlDrawing Member Functions
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* @details The constructor creates an instance of the superclass, XLXmlFile
|
|
505
|
+
*/
|
|
506
|
+
XLVmlDrawing::XLVmlDrawing(XLXmlData* xmlData)
|
|
507
|
+
: XLXmlFile(xmlData)
|
|
508
|
+
{
|
|
509
|
+
if (xmlData->getXmlType() != XLContentType::VMLDrawing)
|
|
510
|
+
throw XLInternalError("XLVmlDrawing constructor: Invalid XML data.");
|
|
511
|
+
|
|
512
|
+
XMLDocument & doc = xmlDocument();
|
|
513
|
+
if (doc.document_element().empty()) // handle a bad (no document element) drawing XML file -> XML namespaces are ensured via appendAndGetAttribute below
|
|
514
|
+
doc.load_string(
|
|
515
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
|
516
|
+
"<xml>"
|
|
517
|
+
// "<xml"
|
|
518
|
+
// " xmlns:v=\"urn:schemas-microsoft-com:vml\""
|
|
519
|
+
// " xmlns:o=\"urn:schemas-microsoft-com:office:office\""
|
|
520
|
+
// " xmlns:x=\"urn:schemas-microsoft-com:office:excel\""
|
|
521
|
+
// " xmlns:w10=\"urn:schemas-microsoft-com:office:word\""
|
|
522
|
+
// ">"
|
|
523
|
+
"\n</xml>",
|
|
524
|
+
pugi_parse_settings
|
|
525
|
+
);
|
|
526
|
+
|
|
527
|
+
XMLNode rootNode = doc.document_element();
|
|
528
|
+
|
|
529
|
+
// 2026-06-10: ensure that XML namespaces are defined in existing documents, too
|
|
530
|
+
appendAndGetAttribute(rootNode, "xmlns:v", "urn:schemas-microsoft-com:vml");
|
|
531
|
+
appendAndGetAttribute(rootNode, "xmlns:o", "urn:schemas-microsoft-com:office:office");
|
|
532
|
+
appendAndGetAttribute(rootNode, "xmlns:x", "urn:schemas-microsoft-com:office:excel");
|
|
533
|
+
appendAndGetAttribute(rootNode, "xmlns:w10", "urn:schemas-microsoft-com:office:word");
|
|
534
|
+
|
|
535
|
+
// ===== Re-sort the document: move all v:shapetype nodes to the beginning of the XML document element and eliminate duplicates
|
|
536
|
+
// ===== Also: determine highest used shape id, regardless of basename (pattern [^0-9]*[0-9]*) and m_shapeCount
|
|
537
|
+
using namespace std::literals::string_literals;
|
|
538
|
+
|
|
539
|
+
XMLNode node = rootNode.first_child_of_type(pugi::node_element);
|
|
540
|
+
XMLNode lastShapeTypeNode{};
|
|
541
|
+
while (not node.empty()) {
|
|
542
|
+
XMLNode nextNode = node.next_sibling_of_type(pugi::node_element); // determine next node early because node may be invalidated by moveNode
|
|
543
|
+
if (node.raw_name() == ShapeTypeNodeName) {
|
|
544
|
+
if (wouldBeDuplicateShapeType(rootNode, node)) { // if shapetype attribute id already exists at begin of file
|
|
545
|
+
while(node.previous_sibling().type() == pugi::node_pcdata) // delete preceeding whitespaces
|
|
546
|
+
rootNode.remove_child(node.previous_sibling()); // ...
|
|
547
|
+
rootNode.remove_child(node); // and the v:shapetype node, as it can not be referenced for lack of a unique id
|
|
548
|
+
}
|
|
549
|
+
else
|
|
550
|
+
lastShapeTypeNode = moveNode(rootNode, node, lastShapeTypeNode); // move node to end of continuous list of shapetype nodes
|
|
551
|
+
}
|
|
552
|
+
else if (node.raw_name() == ShapeNodeName) {
|
|
553
|
+
++m_shapeCount;
|
|
554
|
+
std::string strNodeId = node.attribute("id").value();
|
|
555
|
+
size_t pos = strNodeId.length();
|
|
556
|
+
uint32_t nodeId = 0;
|
|
557
|
+
while (pos > 0 && std::isdigit(strNodeId[--pos])) // determine any trailing nodeId
|
|
558
|
+
nodeId = 10*nodeId + strNodeId[pos] - '0';
|
|
559
|
+
m_lastAssignedShapeId = std::max(m_lastAssignedShapeId, nodeId);
|
|
560
|
+
}
|
|
561
|
+
node = nextNode;
|
|
562
|
+
}
|
|
563
|
+
// Henceforth: assume that it is safe to consider shape nodes a continuous list (well - unless there are other node types as well)
|
|
564
|
+
|
|
565
|
+
XMLNode shapeTypeNode{};
|
|
566
|
+
if (not lastShapeTypeNode.empty()) {
|
|
567
|
+
shapeTypeNode = rootNode.first_child_of_type(pugi::node_element);
|
|
568
|
+
while (not shapeTypeNode.empty() && shapeTypeNode.raw_name() != ShapeTypeNodeName)
|
|
569
|
+
shapeTypeNode = shapeTypeNode.next_sibling_of_type(pugi::node_element);
|
|
570
|
+
}
|
|
571
|
+
if (shapeTypeNode.empty()) {
|
|
572
|
+
shapeTypeNode = rootNode.prepend_child(ShapeTypeNodeName.c_str(), XLForceNamespace);
|
|
573
|
+
rootNode.prepend_child(pugi::node_pcdata).set_value("\n\t");
|
|
574
|
+
}
|
|
575
|
+
if (shapeTypeNode.first_child().empty())
|
|
576
|
+
shapeTypeNode.append_child(pugi::node_pcdata).set_value("\n\t"); // insert indentation if node was empty
|
|
577
|
+
|
|
578
|
+
// ===== Ensure that attributes exist for first shapetype node, default-initialize if needed:
|
|
579
|
+
m_defaultShapeTypeId = appendAndGetAttribute(shapeTypeNode, "id", "_x0000_t202").value();
|
|
580
|
+
appendAndGetAttribute(shapeTypeNode, "coordsize", "21600,21600");
|
|
581
|
+
appendAndGetAttribute(shapeTypeNode, "o:spt", "202");
|
|
582
|
+
appendAndGetAttribute(shapeTypeNode, "path", "m,l,21600l21600,21600l21600,xe");
|
|
583
|
+
|
|
584
|
+
XMLNode strokeNode = shapeTypeNode.child("v:stroke");
|
|
585
|
+
if (strokeNode.empty()) {
|
|
586
|
+
strokeNode = shapeTypeNode.prepend_child("v:stroke", XLForceNamespace);
|
|
587
|
+
shapeTypeNode.prepend_child(pugi::node_pcdata).set_value("\n\t\t");
|
|
588
|
+
}
|
|
589
|
+
appendAndGetAttribute(strokeNode, "joinstyle", "miter");
|
|
590
|
+
|
|
591
|
+
XMLNode pathNode = shapeTypeNode.child("v:path");
|
|
592
|
+
if (pathNode.empty()) {
|
|
593
|
+
pathNode = shapeTypeNode.insert_child_after("v:path", strokeNode, XLForceNamespace);
|
|
594
|
+
copyLeadingWhitespaces(shapeTypeNode, strokeNode, pathNode);
|
|
595
|
+
}
|
|
596
|
+
appendAndGetAttribute(pathNode, "gradientshapeok", "t");
|
|
597
|
+
appendAndGetAttribute(pathNode, "o:connecttype", "rect");
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* @details copy constructor
|
|
602
|
+
*/
|
|
603
|
+
XLVmlDrawing::XLVmlDrawing(const XLVmlDrawing& other)
|
|
604
|
+
: XLXmlFile(other), // base-class copy-constructor
|
|
605
|
+
m_shapeCount(other.m_shapeCount),
|
|
606
|
+
m_lastAssignedShapeId(other.m_lastAssignedShapeId),
|
|
607
|
+
m_defaultShapeTypeId(other.m_defaultShapeTypeId)
|
|
608
|
+
{}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* @details explicit default move constructor
|
|
612
|
+
*/
|
|
613
|
+
XLVmlDrawing::XLVmlDrawing(XLVmlDrawing&& other) noexcept = default;
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* @details explicit default destructor
|
|
617
|
+
*/
|
|
618
|
+
XLVmlDrawing::~XLVmlDrawing() = default;
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* @details copy assignment operator
|
|
622
|
+
*/
|
|
623
|
+
XLVmlDrawing& XLVmlDrawing::operator=(const XLVmlDrawing& other)
|
|
624
|
+
{
|
|
625
|
+
if (&other != this) {
|
|
626
|
+
XLVmlDrawing temp = other; // copy-construct
|
|
627
|
+
*this = std::move(temp); // move-assign & invalidate temp
|
|
628
|
+
}
|
|
629
|
+
return *this;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* @details explicit default move assignment operator
|
|
634
|
+
*/
|
|
635
|
+
XLVmlDrawing& XLVmlDrawing::operator=(XLVmlDrawing&& other) noexcept = default;
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* @details get first shape node in document_element
|
|
639
|
+
* @return first shape node, empty node if none found
|
|
640
|
+
*/
|
|
641
|
+
XMLNode XLVmlDrawing::firstShapeNode() const
|
|
642
|
+
{
|
|
643
|
+
using namespace std::literals::string_literals;
|
|
644
|
+
|
|
645
|
+
XMLNode node = xmlDocument().document_element().first_child_of_type(pugi::node_element);
|
|
646
|
+
while (not node.empty() && node.raw_name() != ShapeNodeName) // skip non shape nodes
|
|
647
|
+
node = node.next_sibling_of_type(pugi::node_element);
|
|
648
|
+
return node;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* @details get last shape node in document_element
|
|
653
|
+
* @return last shape node, empty node if none found
|
|
654
|
+
*/
|
|
655
|
+
XMLNode XLVmlDrawing::lastShapeNode() const
|
|
656
|
+
{
|
|
657
|
+
using namespace std::literals::string_literals;
|
|
658
|
+
|
|
659
|
+
XMLNode node = xmlDocument().document_element().last_child_of_type(pugi::node_element);
|
|
660
|
+
while (not node.empty() && node.raw_name() != ShapeNodeName)
|
|
661
|
+
node = node.previous_sibling_of_type(pugi::node_element);
|
|
662
|
+
return node;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* @details get last shape node at index in document_element
|
|
667
|
+
* @return shape node at index - throws if index is out of bounds
|
|
668
|
+
*/
|
|
669
|
+
XMLNode XLVmlDrawing::shapeNode(uint32_t index) const
|
|
670
|
+
{
|
|
671
|
+
using namespace std::literals::string_literals;
|
|
672
|
+
|
|
673
|
+
XMLNode node{}; // scope declaration, ensures node.empty() when index >= m_shapeCount
|
|
674
|
+
if (index < m_shapeCount) {
|
|
675
|
+
uint16_t i = 0;
|
|
676
|
+
node = firstShapeNode();
|
|
677
|
+
while (i != index && not node.empty() && node.raw_name() == ShapeNodeName) { // follow shape index
|
|
678
|
+
++i;
|
|
679
|
+
node = node.next_sibling_of_type(pugi::node_element);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
if (node.empty() || node.raw_name() != ShapeNodeName)
|
|
683
|
+
throw XLException("XLVmlDrawing: shape index "s + std::to_string(index) + " is out of bounds"s);
|
|
684
|
+
|
|
685
|
+
return node;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* @details
|
|
690
|
+
*/
|
|
691
|
+
XMLNode XLVmlDrawing::shapeNode(std::string const& cellRef) const
|
|
692
|
+
{
|
|
693
|
+
XLCellReference destRef(cellRef);
|
|
694
|
+
uint32_t destRow = destRef.row() - 1; // for accessing a shape: x:Row and x:Column are zero-indexed
|
|
695
|
+
uint16_t destCol = destRef.column() - 1; // ..
|
|
696
|
+
|
|
697
|
+
XMLNode node = firstShapeNode();
|
|
698
|
+
while (not node.empty()) {
|
|
699
|
+
if ((destRow == node.child("x:ClientData").child("x:Row").text().as_uint())
|
|
700
|
+
&&(destCol == node.child("x:ClientData").child("x:Column").text().as_uint()))
|
|
701
|
+
break; // found shape for cellRef
|
|
702
|
+
|
|
703
|
+
do { // locate next shape node
|
|
704
|
+
node = node.next_sibling_of_type(pugi::node_element);
|
|
705
|
+
} while (not node.empty() && node.name() != ShapeNodeName);
|
|
706
|
+
}
|
|
707
|
+
return node;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* @details TODO: write doxygen headers for functions in this module
|
|
712
|
+
*/
|
|
713
|
+
uint32_t XLVmlDrawing::shapeCount() const { return m_shapeCount; }
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* @details TODO: write doxygen headers for functions in this module
|
|
717
|
+
*/
|
|
718
|
+
XLShape XLVmlDrawing::shape(uint32_t index) const { return XLShape(shapeNode(index)); }
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* @details TODO: write doxygen headers for functions in this module
|
|
722
|
+
*/
|
|
723
|
+
bool XLVmlDrawing::deleteShape(uint32_t index)
|
|
724
|
+
{
|
|
725
|
+
XMLNode rootNode = xmlDocument().document_element();
|
|
726
|
+
XMLNode node = shapeNode(index); // returns a valid node or throws
|
|
727
|
+
--m_shapeCount; // if shapeNode(index) did not throw: decrement shape count
|
|
728
|
+
while (node.previous_sibling().type() == pugi::node_pcdata) // remove leading whitespaces
|
|
729
|
+
rootNode.remove_child(node.previous_sibling());
|
|
730
|
+
rootNode.remove_child(node); // then remove shape node itself
|
|
731
|
+
|
|
732
|
+
return true;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* @details TODO: write doxygen headers for functions in this module
|
|
737
|
+
*/
|
|
738
|
+
bool XLVmlDrawing::deleteShape(std::string const& cellRef)
|
|
739
|
+
{
|
|
740
|
+
XMLNode rootNode = xmlDocument().document_element();
|
|
741
|
+
XMLNode node = shapeNode(cellRef);
|
|
742
|
+
if (node.empty()) return false; // nothing found to delete
|
|
743
|
+
|
|
744
|
+
--m_shapeCount; // if shapeNode(cellRef) returned a non-empty node: decrement shape count
|
|
745
|
+
while (node.previous_sibling().type() == pugi::node_pcdata) // remove leading whitespaces
|
|
746
|
+
rootNode.remove_child(node.previous_sibling());
|
|
747
|
+
rootNode.remove_child(node); // then remove shape node itself
|
|
748
|
+
|
|
749
|
+
return true;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* @details insert shape and return index
|
|
754
|
+
*/
|
|
755
|
+
XLShape XLVmlDrawing::createShape([[maybe_unused]] const XLShape& shapeTemplate )
|
|
756
|
+
{
|
|
757
|
+
|
|
758
|
+
XMLNode rootNode = xmlDocument().document_element();
|
|
759
|
+
XMLNode node = lastShapeNode();
|
|
760
|
+
if (node.empty()) {
|
|
761
|
+
node = rootNode.last_child_of_type(pugi::node_element);
|
|
762
|
+
}
|
|
763
|
+
if (not node.empty()) { // default case: a previous element node exists
|
|
764
|
+
node = rootNode.insert_child_after(ShapeNodeName.c_str(), node, XLForceNamespace); // insert the node after the last shape node if any
|
|
765
|
+
copyLeadingWhitespaces(rootNode, node.previous_sibling(), node); // copy whitespaces from node after which this one was just inserted
|
|
766
|
+
}
|
|
767
|
+
else { // else: shouldn't happen - but just in case
|
|
768
|
+
node = rootNode.prepend_child(ShapeNodeName.c_str(), XLForceNamespace); // insert node prior to trailing whitespaces
|
|
769
|
+
rootNode.prepend_child(pugi::node_pcdata).set_value("\n\t"); // prefix new node with whitespaces
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
// ===== Assign a new shape id & account for it in m_lastAssignedShapeId
|
|
773
|
+
using namespace std::literals::string_literals;
|
|
774
|
+
node.prepend_attribute("id").set_value(("shape_"s + std::to_string( m_lastAssignedShapeId++ )).c_str());
|
|
775
|
+
node.append_attribute("type").set_value(("#"s + m_defaultShapeTypeId).c_str());
|
|
776
|
+
|
|
777
|
+
m_shapeCount++;
|
|
778
|
+
return XLShape(node); // return object to manipulate new shape
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* @details Print the underlying XML using pugixml::xml_node::print
|
|
783
|
+
*/
|
|
784
|
+
void XLVmlDrawing::print(std::basic_ostream<char>& ostr) const { xmlDocument().document_element().print( ostr ); }
|