diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2022-09-13 22:16:22 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2022-09-13 22:16:22 -0400 |
commit | 902b27227df7154655bb1d6733c6b1b97ef8b804 (patch) | |
tree | 8d93d2a9ef3fe3c1f0b23ddc700e6be5fa61aa4a | |
parent | ee154da63372d9ce25c9247b82fc353dacbd67c2 (diff) | |
download | orcus-feature/159-cell-hidden-and-locked.tar.gz |
Properly pick up cell protection properties
feature/159-cell-hidden-and-locked
-rw-r--r-- | include/orcus/spreadsheet/import_interface_styles.hpp | 29 | ||||
-rw-r--r-- | slickedit/orcus_cpp.h | 2 | ||||
-rw-r--r-- | src/liborcus/xls_xml_context.cpp | 26 | ||||
-rw-r--r-- | src/liborcus/xls_xml_context.hpp | 3 | ||||
-rw-r--r-- | src/orcus_test_xls_xml.cpp | 76 | ||||
-rw-r--r-- | test/xls-xml/cell-properties/locked-and-hidden.xml | 6 |
6 files changed, 129 insertions, 13 deletions
diff --git a/include/orcus/spreadsheet/import_interface_styles.hpp b/include/orcus/spreadsheet/import_interface_styles.hpp index 9627670f..b71db201 100644 --- a/include/orcus/spreadsheet/import_interface_styles.hpp +++ b/include/orcus/spreadsheet/import_interface_styles.hpp @@ -271,9 +271,38 @@ class ORCUS_DLLPUBLIC import_cell_protection public: virtual ~import_cell_protection(); + /** + * Hide the entire cell content when the sheet is protected. + * + * @param b whether to hide the entire cell content when the sheet is + * protected. + */ virtual void set_hidden(bool b) = 0; + + /** + * Lock the cell when the sheet is protected. + * + * @param b whether or not to lock the cell when the sheet is protected. + */ virtual void set_locked(bool b) = 0; + + /** + * Specify whether or not to print the cell content when the sheet is + * protected. + * + * + * @param b whether or not to print the cell content when the sheet is + * protected. + */ virtual void set_print_content(bool b) = 0; + + /** + * Hide the formula when the sheet is protected and the cell contains + * formula. + * + * @param b whether or not to hide the formula when the sheet is protected + * and the cell contains formula. + */ virtual void set_formula_hidden(bool b) = 0; /** diff --git a/slickedit/orcus_cpp.h b/slickedit/orcus_cpp.h index 830dad2a..5792705f 100644 --- a/slickedit/orcus_cpp.h +++ b/slickedit/orcus_cpp.h @@ -1,3 +1,5 @@ +#define IXION_DLLPUBLIC + #define ORCUS_DLLPUBLIC #define ORCUS_PSR_DLLPUBLIC diff --git a/src/liborcus/xls_xml_context.cpp b/src/liborcus/xls_xml_context.cpp index c7542829..3a009d21 100644 --- a/src/liborcus/xls_xml_context.cpp +++ b/src/liborcus/xls_xml_context.cpp @@ -1067,14 +1067,13 @@ void xls_xml_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_a { for (const xml_token_attr_t& attr : attrs) { - if (attr.ns == NS_xls_xml_x) + if (attr.ns == NS_xls_xml_x && attr.name == XML_HideFormula) { - switch (attr.name) - { - case XML_HideFormula: - m_current_style->cell_protection.hide_formula = to_bool(attr.value); - break; - } + m_current_style->cell_protection.hide_formula = to_bool(attr.value); + } + else if (attr.ns == NS_xls_xml_ss && attr.name == XML_Protected) + { + m_current_style->cell_protection.locked = to_bool(attr.value); } } } @@ -1928,8 +1927,8 @@ void xls_xml_context::commit_default_style() if (m_default_style) { const auto& cp = m_default_style->cell_protection; - if (cp.hide_formula) - cell_protection->set_formula_hidden(*cp.hide_formula); + cell_protection->set_locked(cp.locked); + cell_protection->set_formula_hidden(cp.hide_formula); } id = cell_protection->commit(); @@ -2034,6 +2033,15 @@ void xls_xml_context::commit_styles() xf->set_fill(fill_id); } + auto* protect = styles->get_cell_protection(); + ENSURE_INTERFACE(protect, import_cell_protection); + + protect->set_locked(style->cell_protection.locked); + protect->set_formula_hidden(style->cell_protection.hide_formula); + + std::size_t protect_id = protect->commit(); + xf->set_protection(protect_id); + if (!style->borders.empty()) { styles->set_border_count(style->borders.size()); diff --git a/src/liborcus/xls_xml_context.hpp b/src/liborcus/xls_xml_context.hpp index 39ee6b13..9b8452cc 100644 --- a/src/liborcus/xls_xml_context.hpp +++ b/src/liborcus/xls_xml_context.hpp @@ -162,7 +162,8 @@ class xls_xml_context : public xml_context_base struct cell_protection_type { - std::optional<bool> hide_formula; + bool locked = true; // NB: default is locked + bool hide_formula = false; }; struct style_type diff --git a/src/orcus_test_xls_xml.cpp b/src/orcus_test_xls_xml.cpp index aec0dff5..889bef16 100644 --- a/src/orcus_test_xls_xml.cpp +++ b/src/orcus_test_xls_xml.cpp @@ -1122,6 +1122,81 @@ void test_xls_xml_cell_properties_default_style() } } +void test_xls_xml_cell_properties_locked_and_hidden() +{ + test::stack_printer __sp__(__func__); + + auto doc = load_doc_from_filepath(SRCDIR"/test/xls-xml/cell-properties/locked-and-hidden.xml"); + const ixion::model_context& model = doc->get_model_context(); + + const ss::sheet* sh = doc->get_sheet(0); + assert(sh); + + { + // Check cell string values first. + + struct check_type + { + ixion::abs_address_t address; + std::string_view str; + }; + + const check_type checks[] = { + // sheet, row, column, expected cell string value + { { 0, 0, 0 }, "Default (Should be locked but not hidden)" }, + { { 0, 0, 1 }, "Not Locked and not hidden" }, + { { 0, 1, 0 }, "Locked and hidden" }, + { { 0, 1, 1 }, "Not locked and hidden" }, + }; + + for (const auto& c : checks) + { + ixion::string_id_t sid = model.get_string_identifier(c.address); + const std::string* s = model.get_string(sid); + assert(s); + assert(*s == c.str); + } + } + + { + // Check the cell protection attributes. + + struct check_type + { + ss::row_t row; + ss::col_t col; + bool locked; + bool formula_hidden; + }; + + const check_type checks[] = { + // row, column, locked, formula-hidden + { 0, 0, true, false }, + { 0, 1, false, false }, + { 1, 0, true, true }, + { 1, 1, false, true }, + }; + + const ss::styles& styles = doc->get_styles(); + + for (const auto& c : checks) + { + std::cout << "row=" << c.row << "; col=" << c.col << std::endl; + + std::size_t xfid = sh->get_cell_format(c.row, c.col); + const ss::cell_format_t* xf = styles.get_cell_format(xfid); + assert(xf); + + const ss::protection_t* prot = styles.get_protection(xf->protection); + assert(prot); + std::cout << " * locked: expected=" << c.locked << "; actual=" << prot->locked << std::endl; + assert(prot->locked == c.locked); + std::cout << " * formula-hidden: expected=" << c.formula_hidden << "; actual=" << prot->formula_hidden << std::endl; + assert(prot->formula_hidden == c.formula_hidden); + } + } +} + void test_xls_xml_view_cursor_per_sheet() { string path(SRCDIR"/test/xls-xml/view/cursor-per-sheet.xml"); @@ -1438,6 +1513,7 @@ int main() test_xls_xml_number_format(); test_xls_xml_cell_properties_wrap_and_shrink(); test_xls_xml_cell_properties_default_style(); + test_xls_xml_cell_properties_locked_and_hidden(); // view import test_xls_xml_view_cursor_per_sheet(); diff --git a/test/xls-xml/cell-properties/locked-and-hidden.xml b/test/xls-xml/cell-properties/locked-and-hidden.xml index 30304662..7b85e455 100644 --- a/test/xls-xml/cell-properties/locked-and-hidden.xml +++ b/test/xls-xml/cell-properties/locked-and-hidden.xml @@ -51,11 +51,11 @@ <Column ss:AutoFitWidth="0" ss:Width="132"/> <Row ss:Height="30"> <Cell><Data ss:Type="String">Default (Should be locked but not hidden)</Data></Cell> - <Cell ss:StyleID="s63"><Data ss:Type="String">Not Locked and not Hidden</Data></Cell> + <Cell ss:StyleID="s63"><Data ss:Type="String">Not Locked and not hidden</Data></Cell> </Row> <Row> - <Cell ss:StyleID="s64"><Data ss:Type="String">Locked and Hidden</Data></Cell> - <Cell ss:StyleID="s65"><Data ss:Type="String">Not Locked and hidden</Data></Cell> + <Cell ss:StyleID="s64"><Data ss:Type="String">Locked and hidden</Data></Cell> + <Cell ss:StyleID="s65"><Data ss:Type="String">Not locked and hidden</Data></Cell> </Row> </Table> <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"> |