diff options
Diffstat (limited to 'core/src/Model/Template/TableTemplate.cpp')
-rw-r--r-- | core/src/Model/Template/TableTemplate.cpp | 130 |
1 files changed, 126 insertions, 4 deletions
diff --git a/core/src/Model/Template/TableTemplate.cpp b/core/src/Model/Template/TableTemplate.cpp index 0684c77..258bb37 100644 --- a/core/src/Model/Template/TableTemplate.cpp +++ b/core/src/Model/Template/TableTemplate.cpp @@ -1,6 +1,11 @@ #include "TableTemplate.hpp" #include <xlsxwriter.h> +#include <map> + +bool TableCell::IsDataHoldingCell() const +{ +} bool TableCell::IsPrimaryCell() const { @@ -12,6 +17,45 @@ bool TableCell::IsMergedCell() const return PrimaryCellLocation.x == -1 || PrimaryCellLocation.y == -1; } +Vec2i TableCellArrayGroup::GetLeftCell() const +{ + return { Row, LeftCell }; +} + +Vec2i TableCellArrayGroup::GetRightCell() const +{ + return { Row, RightCell }; +} + +int TableCellArrayGroup::GetCount() const +{ + return RightCell - LeftCell + 1; +} + +TableInstanciationParameters::TableInstanciationParameters(const TableTemplate& table) + : mTable{ &table } +{ +} + +TableInstanciationParameters& TableInstanciationParameters::ResetTable(const TableTemplate& newTable) +{ + mTable = &newTable; + return *this; +} + +TableInstanciationParameters TableInstanciationParameters::RebindTable(const TableTemplate& newTable) const +{ + TableInstanciationParameters result(newTable); + result.SingularCells = this->SingularCells; + result.ArrayGroups = this->ArrayGroups; + return result; +} + +const TableTemplate& TableInstanciationParameters::GetTable() const +{ + return *mTable; +} + int TableTemplate::GetTableWidth() const { return mTableWidth; @@ -129,19 +173,97 @@ lxw_workbook* TableTemplate::InstanciateToExcelWorkbook(const TableInstanciation lxw_worksheet* TableTemplate::InstanciateToExcelWorksheet(lxw_workbook* workbook, const TableInstanciationParameters& params) const { - auto worksheet = workbook_add_worksheet(workbook, "Cplt Export"); + auto worksheet = workbook_add_worksheet(workbook, "CpltExport.xlsx"); + + // Map: row number -> length of generated ranges + std::map<int, int> generatedRanges; + for (size_t i = 0; i < mArrayGroups.size(); ++i) { + auto& info = mArrayGroups[i]; + auto& param = params.ArrayGroups[i]; + + auto iter = generatedRanges.find(i); + if (iter != generatedRanges.end()) { + int available = iter->second; + if (available >= param.size()) { + // Current space is enough to fit in this array group, skip + continue; + } + } + + // Not enough space to fit in this array group, update (or insert) the appropriate amount of generated rows + int row = i; + int count = param.size(); + generatedRanges.insert(row, count); + } + + auto GetOffset = [&](int y) -> int { + // std::find_if <values less than y> + int verticalOffset = 0; + for (auto it = generatedRanges.begin(); it != generatedRanges.end() && it->first < y; ++it) { + verticalOffset += it->second; + } + return verticalOffset; + }; + + auto WriteCell = [&](int row, int col, const TableCell& cell, const char* text) -> void { + if (cell.IsPrimaryCell()) { + int lastRow = row + cell.SpanY - 1; + int lastCol = col + cell.SpanX - 1; + // When both `string` and `format` are null, the top-left cell contents are untouched (what we just wrote in the above switch) + worksheet_merge_range(worksheet, row, col, lastRow, lastCol, text, nullptr); + } else { + worksheet_write_string(worksheet, row, col, text, nullptr); + } + }; + + // Write/instanciate all array groups + for (size_t i = 0; i < mArrayGroups.size(); ++i) { + auto& groupInfo = mArrayGroups[i]; + auto& groupParams = params.ArrayGroups[i]; + + int rowCellCount = groupInfo.GetCount(); + int row = groupInfo.Row + GetOffset(groupInfo.Row); + + // For each row that would be generated + for (auto& rowCells : groupParams) { + // For each cell in the row + for (int i = 0; i < rowCellCount; ++i) { + // TODO spport merged cells in array groups + worksheet_write_string(worksheet, row + i, col, rowCells[i].c_str(), nullptr); + } + } + } + + // Write all regular and singular parameter cells for (int y = 0; y < mTableHeight; ++y) { for (int x = 0; x < mTableWidth; ++x) { auto& cell = GetCell({ x, y }); + + if (!cell.IsDataHoldingCell()) { + continue; + } + switch (cell.Type) { case TableCell::ConstantCell: { - worksheet_write_string(worksheet, y, x, cell.Content.c_str(), nullptr); + int row = y + GetOffset(y); + int col = x; + + WriteCell(row, col, cell, cell.Content.c_str()); } break; - case TableCell::ParametricCell: { - // TODO + case TableCell::SingularParametricCell: { + int row = y + GetOffset(y); + int col = x; + + auto iter = params.SingularCells.find({ x, y }); + if (iter != params.SingularCells.end()) { + WriteCell(row, col, cell, iter.value().c_str()); + } } break; + + // See loop above that processes whole array groups at the same time + case TableCell::ArrayParametricCell: break; } } } |