/* -*- 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 "table_handler.hpp" namespace ixion { table_handler::entry::entry() : name(empty_string_id), range(abs_range_t::invalid), totals_row_count(0) {} table_handler::~table_handler() {} abs_range_t table_handler::get_range( const abs_address_t& pos, string_id_t column_first, string_id_t column_last, table_areas_t areas) const { entries_type::const_iterator it = m_entries.begin(), it_end = m_entries.end(); for (; it != it_end; ++it) { const entry& e = *it->second; if (!e.range.contains(pos)) continue; return get_column_range(e, column_first, column_last, areas); } return abs_range_t(abs_range_t::invalid); } abs_range_t table_handler::get_range( string_id_t table, string_id_t column_first, string_id_t column_last, table_areas_t areas) const { entries_type::const_iterator it = m_entries.find(table); if (it == m_entries.end()) // Table name not found. return abs_range_t(abs_range_t::invalid); const entry& e = *it->second; return get_column_range(e, column_first, column_last, areas); } void table_handler::insert(std::unique_ptr& p) { if (!p) return; string_id_t name = p->name; m_entries.insert( entries_type::value_type( name, std::unique_ptr(p.release()))); } void adjust_table_area(abs_range_t& range, const table_handler::entry& e, table_areas_t areas) { bool headers = (areas & table_area_headers); bool data = (areas & table_area_data); bool totals = (areas & table_area_totals); if (headers) { if (data) { if (totals) { // All areas. return; } // Headers + data areas range.last.row -= e.totals_row_count; return; } // Headers only. range.last.row = range.first.row; return; } // No header row. --range.first.row; if (data) { if (totals) { // Data + totals areas return; } // Data area only. range.last.row -= e.totals_row_count; return; } // Totals area only. if (e.totals_row_count <= 0) { range = abs_range_t(abs_range_t::invalid); return; } range.first.row = range.last.row; range.first.row -= e.totals_row_count - 1; } abs_range_t table_handler::get_column_range( const entry& e, string_id_t column_first, string_id_t column_last, table_areas_t areas) const { if (column_first == empty_string_id) { // Area specifiers only. abs_range_t ret = e.range; adjust_table_area(ret, e, areas); return ret; } for (size_t i = 0, n = e.columns.size(); i < n; ++i) { if (e.columns[i] == column_first) { // Matching column name found. abs_range_t ret = e.range; col_t col = e.range.first.column + i; ret.first.column = col; ret.last.column = col; adjust_table_area(ret, e, areas); return ret; } } return abs_range_t(abs_range_t::invalid); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */