summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2022-09-13 22:16:22 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2022-09-13 22:16:22 -0400
commit902b27227df7154655bb1d6733c6b1b97ef8b804 (patch)
tree8d93d2a9ef3fe3c1f0b23ddc700e6be5fa61aa4a
parentee154da63372d9ce25c9247b82fc353dacbd67c2 (diff)
downloadorcus-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.hpp29
-rw-r--r--slickedit/orcus_cpp.h2
-rw-r--r--src/liborcus/xls_xml_context.cpp26
-rw-r--r--src/liborcus/xls_xml_context.hpp3
-rw-r--r--src/orcus_test_xls_xml.cpp76
-rw-r--r--test/xls-xml/cell-properties/locked-and-hidden.xml6
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">