diff options
Diffstat (limited to 'src/spreadsheet/view.cpp')
-rw-r--r-- | src/spreadsheet/view.cpp | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/src/spreadsheet/view.cpp b/src/spreadsheet/view.cpp new file mode 100644 index 0000000..7e21fff --- /dev/null +++ b/src/spreadsheet/view.cpp @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/spreadsheet/view.hpp" +#include "orcus/spreadsheet/document.hpp" + +#include <cassert> +#include <iostream> + +namespace orcus { namespace spreadsheet { + +struct view::impl +{ + document& m_doc; + + std::vector<std::unique_ptr<sheet_view>> m_sheet_views; + sheet_t m_active_sheet; + + impl(document& doc) : m_doc(doc), m_active_sheet(0) {} +}; + +view::view(document& doc) : mp_impl(std::make_unique<impl>(doc)) {} +view::~view() {} + +sheet_view* view::get_or_create_sheet_view(sheet_t sheet) +{ + if (sheet < 0) + return nullptr; + + sheet_t n = mp_impl->m_doc.get_sheet_count(); + if (sheet >= n) + return nullptr; + + // Make sure the container is large enough for the requested sheet view index. + n = mp_impl->m_sheet_views.size(); + if (sheet >= n) + mp_impl->m_sheet_views.resize(sheet+1); + + if (!mp_impl->m_sheet_views[sheet]) + mp_impl->m_sheet_views[sheet] = std::make_unique<sheet_view>(*this); + + return mp_impl->m_sheet_views[sheet].get(); +} + +const sheet_view* view::get_sheet_view(sheet_t sheet) const +{ + if (sheet < 0) + return nullptr; + + sheet_t n = mp_impl->m_doc.get_sheet_count(); + if (sheet >= n) + return nullptr; + + n = mp_impl->m_sheet_views.size(); + if (sheet >= n) + return nullptr; + + assert(mp_impl->m_sheet_views[sheet]); + return mp_impl->m_sheet_views[sheet].get(); +} + +void view::set_active_sheet(sheet_t sheet) +{ + mp_impl->m_active_sheet = sheet; +} + +sheet_t view::get_active_sheet() const +{ + return mp_impl->m_active_sheet; +} + +namespace { + +/** + * Stores all data for a single sheet pane. + */ +struct sheet_pane_data +{ + range_t m_selection; + + sheet_pane_data() + { + m_selection.first.row = -1; + m_selection.first.column = -1; + m_selection.last = m_selection.first; + } +}; + +size_t to_pane_index(sheet_pane_t pos) +{ + switch (pos) + { + case sheet_pane_t::top_left: + return 0; + case sheet_pane_t::top_right: + return 1; + case sheet_pane_t::bottom_left: + return 2; + case sheet_pane_t::bottom_right: + return 3; + case sheet_pane_t::unspecified: + default: + throw std::runtime_error("invalid sheet pane."); + } +} + +} // anonymous namespace + +struct sheet_view::impl +{ + view& m_doc_view; + sheet_pane_data m_panes[4]; + sheet_pane_t m_active_pane; + split_pane_t m_split_pane; + frozen_pane_t m_frozen_pane; + + sheet_pane_data& get_pane(sheet_pane_t pos) + { + return m_panes[to_pane_index(pos)]; + } + + const sheet_pane_data& get_pane(sheet_pane_t pos) const + { + return m_panes[to_pane_index(pos)]; + } + + impl(view& doc_view) : m_doc_view(doc_view), m_active_pane(sheet_pane_t::top_left) + { + m_split_pane.hor_split = 0.0; + m_split_pane.ver_split = 0.0; + m_split_pane.top_left_cell.row = -1; + m_split_pane.top_left_cell.column = -1; + m_frozen_pane.visible_columns = 0; + m_frozen_pane.visible_rows = 0; + m_frozen_pane.top_left_cell.row = -1; + m_frozen_pane.top_left_cell.column = -1; + } +}; + +sheet_view::sheet_view(view& doc_view) : mp_impl(std::make_unique<impl>(doc_view)) {} +sheet_view::~sheet_view() {} + +const range_t& sheet_view::get_selection(sheet_pane_t pos) const +{ + const sheet_pane_data& pd = mp_impl->get_pane(pos); + return pd.m_selection; +} + +void sheet_view::set_selection(sheet_pane_t pos, const range_t& range) +{ + sheet_pane_data& pd = mp_impl->get_pane(pos); + pd.m_selection = range; +} + +void sheet_view::set_active_pane(sheet_pane_t pos) +{ + mp_impl->m_active_pane = pos; +} + +sheet_pane_t sheet_view::get_active_pane() const +{ + return mp_impl->m_active_pane; +} + +void sheet_view::set_split_pane( + double hor_split, double ver_split, const address_t& top_left_cell) +{ + mp_impl->m_split_pane.hor_split = hor_split; + mp_impl->m_split_pane.ver_split = ver_split; + mp_impl->m_split_pane.top_left_cell = top_left_cell; +} + +const split_pane_t& sheet_view::get_split_pane() const +{ + return mp_impl->m_split_pane; +} + +void sheet_view::set_frozen_pane(col_t visible_cols, row_t visible_rows, const address_t& top_left_cell) +{ + mp_impl->m_frozen_pane.visible_columns = visible_cols; + mp_impl->m_frozen_pane.visible_rows = visible_rows; + mp_impl->m_frozen_pane.top_left_cell = top_left_cell; +} + +const frozen_pane_t& sheet_view::get_frozen_pane() const +{ + return mp_impl->m_frozen_pane; +} + +view& sheet_view::get_document_view() +{ + return mp_impl->m_doc_view; +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |