implement sheet view selection consumption, closes #164

This commit is contained in:
Thomas Fussell 2017-09-13 09:36:42 -04:00
parent 9d71dda531
commit 81812d6e29
5 changed files with 114 additions and 11 deletions

View File

@ -193,14 +193,16 @@ public:
}
/// <summary>
/// Returns true if this view is requal to rhs based on its id, grid lines setting,
/// Returns true if this view is equal to rhs based on its id, grid lines setting,
/// default grid color, pane, and selections.
/// </summary>
bool operator==(const sheet_view &rhs) const
{
return id_ == rhs.id_ && show_grid_lines_ == rhs.show_grid_lines_
return id_ == rhs.id_
&& show_grid_lines_ == rhs.show_grid_lines_
&& default_grid_color_ == rhs.default_grid_color_
&& pane_ == rhs.pane_ && selections_ == rhs.selections_;
&& pane_ == rhs.pane_
&& selections_ == rhs.selections_;
}
private:

View File

@ -630,6 +630,21 @@ public:
/// </summary>
void add_view(const sheet_view &new_view);
/// <summary>
/// Set the active cell on the default worksheet view to the given reference.
/// </summary>
void active_cell(const cell_reference &ref);
/// <summary>
/// Returns true if the worksheet has a view and the view has an active cell.
/// </summary>
bool has_active_cell() const;
/// <summary>
/// Returns the active cell on the default worksheet view.
/// </summary>
cell_reference active_cell() const;
// page breaks
/// <summary>
@ -658,10 +673,10 @@ public:
/// </summary>
void page_break_at_column(column_t column);
/// <summary>
/// Creates a conditional format for the given range with the given condition.
/// </summary>
xlnt::conditional_format conditional_format(const range_reference &ref, const condition &when);
/// <summary>
/// Creates a conditional format for the given range with the given condition.
/// </summary>
xlnt::conditional_format conditional_format(const range_reference &ref, const condition &when);
private:
friend class cell;
@ -690,7 +705,7 @@ private:
/// Removes calcChain part from manifest if no formulae remain in workbook.
/// </summary>
void garbage_collect_formulae();
/// <summary>
/// Sets the parent of this worksheet to wb.
/// </summary>

View File

@ -39,6 +39,7 @@
#include <xlnt/utils/optional.hpp>
#include <xlnt/utils/path.hpp>
#include <xlnt/workbook/workbook.hpp>
#include <xlnt/worksheet/selection.hpp>
#include <xlnt/worksheet/worksheet.hpp>
namespace std {
@ -222,7 +223,7 @@ cell xlsx_consumer::read_cell()
{
cell.format(target_.format(std::stoull(parser().attribute("s"))));
}
auto has_value = false;
auto value_string = std::string();
@ -418,7 +419,8 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
if (parser().attribute_present("view") && parser().attribute("view") != "normal")
{
new_view.type(parser().attribute("view") == "pageBreakPreview" ? sheet_view_type::page_break_preview
new_view.type(parser().attribute("view") == "pageBreakPreview"
? sheet_view_type::page_break_preview
: sheet_view_type::page_layout);
}
@ -463,6 +465,17 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
}
else if (sheet_view_child_element == qn("spreadsheetml", "selection")) // CT_Selection 0-4
{
selection current_selection;
if (parser().attribute_present("activeCell"))
{
current_selection.active_cell(parser().attribute("activeCell"));
}
current_selection.pane(pane_corner::top_left);
new_view.add_selection(current_selection);
skip_remaining_content(sheet_view_child_element);
}
else if (sheet_view_child_element == qn("spreadsheetml", "pivotSelection")) // CT_PivotSelection 0-4
@ -596,7 +609,7 @@ void xlsx_consumer::read_worksheet_sheetdata()
auto has_type = parser().attribute_present("t");
auto type = has_type ? parser().attribute("t") : "n";
if (parser().attribute_present("s"))
{
cell.format(target_.format(std::stoull(parser().attribute("s"))));

View File

@ -350,6 +350,51 @@ void worksheet::unfreeze_panes()
primary_view.clear_pane();
}
void worksheet::active_cell(const cell_reference &ref)
{
if (!has_view())
{
d_->views_.push_back(sheet_view());
}
auto &primary_view = d_->views_.front();
if (!primary_view.has_selections())
{
primary_view.add_selection(selection());
}
auto &primary_selection = primary_view.selection(0);
primary_selection.active_cell(ref);
}
bool worksheet::has_active_cell() const
{
if (!has_view()) return false;
auto &primary_view = d_->views_.front();
if (!primary_view.has_selections()) return false;
auto primary_selection = primary_view.selection(0);
return primary_selection.has_active_cell();
}
cell_reference worksheet::active_cell() const
{
if (!has_view())
{
throw xlnt::exception("Worksheet has no view.");
}
auto &primary_view = d_->views_.front();
if (!primary_view.has_selections())
{
throw xlnt::exception("Default worksheet view has no selections.");
}
return primary_view.selection(0).active_cell();
}
cell worksheet::cell(const cell_reference &reference)
{
auto &row = d_->cell_map_[reference.row()];

View File

@ -94,6 +94,7 @@ public:
register_test(test_named_range_named_cell_reference);
register_test(test_iteration_skip_empty);
register_test(test_dimensions);
register_test(test_view_properties_serialization);
}
void test_new_worksheet()
@ -1102,4 +1103,31 @@ public:
xlnt_assert_equals(sheet_range.width(), 4);
xlnt_assert_equals(sheet_range.height(), 35);
}
void test_view_properties_serialization()
{
xlnt::workbook wb;
auto ws = wb.active_sheet();
ws.cell("A1").value("A1");
ws.cell("A2").value("A2");
ws.cell("B1").value("B1");
ws.cell("B2").value("B2");
xlnt_assert(!ws.has_active_cell());
ws.active_cell("B1");
xlnt_assert(ws.has_active_cell());
xlnt_assert_equals(ws.active_cell(), "B1");
wb.save("temp.xlsx");
xlnt::workbook wb2;
wb2.load("temp.xlsx");
auto ws2 = wb2.active_sheet();
xlnt_assert(ws2.has_active_cell());
xlnt_assert_equals(ws2.active_cell(), "B1");
}
};