summaryrefslogtreecommitdiff
path: root/core/src/Model
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2021-05-29 13:01:01 -0700
committerrtk0c <[email protected]>2021-05-29 13:34:43 -0700
commit088da97531935a61870ecada10f06b9b9a8255d1 (patch)
tree04ad2015d8af3555353c6ea84a1c312fa67c8600 /core/src/Model
parentf957f4094a8d98ad0de294c3e6325ce9a860994e (diff)
Table instaciation to xlsx complete
Diffstat (limited to 'core/src/Model')
-rw-r--r--core/src/Model/Template/TableTemplate.cpp130
-rw-r--r--core/src/Model/Template/TableTemplate.hpp66
-rw-r--r--core/src/Model/Template/fwd.hpp2
3 files changed, 171 insertions, 27 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;
}
}
}
diff --git a/core/src/Model/Template/TableTemplate.hpp b/core/src/Model/Template/TableTemplate.hpp
index 6454ccd..be043a9 100644
--- a/core/src/Model/Template/TableTemplate.hpp
+++ b/core/src/Model/Template/TableTemplate.hpp
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include "Utils/Vector.hpp"
#include "Utils/VectorHash.hpp"
@@ -24,7 +24,8 @@ public:
enum CellType
{
ConstantCell,
- ParametricCell,
+ SingularParametricCell,
+ ArrayParametricCell,
};
public:
@@ -38,15 +39,23 @@ public:
TextAlignment HorizontalAlignment = AlignAxisMin;
TextAlignment VerticalAlignment = AlignAxisMin;
CellType Type;
+ /// The id of the group description object, if this cell isn't a constant or singluar parameter cell. Otherwise, this value is -1.
+ int DataId = -1;
public:
+ /// Return whether this cell holds meaningful data, i.e. true when this cell is either unmerged or the primary cell of a merged range.
+ bool IsDataHoldingCell() const;
+ /// Return whether this cell is the primary (i.e. top left) cell of a merged range or not.
bool IsPrimaryCell() const;
+ /// Return whether this cell is a part of a merged range or not. Includes the primary cell.
bool IsMergedCell() const;
};
-/// Parameter group information for a grouped array of cells, either horizontal or vertical.
-/// These cells can have "expansion behavior", i.e. when instanciating, a list of cell values would be provided by
-/// the caller:
+// TODO support reverse (bottom to top) filling order
+// TODO support horizontal filling order
+/// Parameter group information for a grouped array of cells. When instanciated, an array of 0 or more
+/// elements shall be provided by the user, which will replace the group of templated cells with a list
+/// of rows, each instanciated with the n-th element in the provided array.
/// \code
/// [["foo", "bar", "foobar"],
/// ["a", "b", c"],
@@ -54,11 +63,9 @@ public:
/// ["x", "y", "z"]]
/// // ... may be more
/// \endcode
+/// This would create 4 rows of data in the place of the original parameter group.
///
-/// For a array parameter group that vertically expands, this would create 4 rows of data in the place of the
-/// original parameter group. If more than one array parameter groups are on the same row, they would share space
-/// between each other :
-///
+/// If more than one array parameter groups are on the same row, they would share space between each other:
/// \code
/// | 2 elements was fed to it
/// | | 1 element was fed to it
@@ -70,19 +77,23 @@ public:
/// | Cool | Example | |
/// +------+---------+---------------+
/// \endcode
-class TableArrayParameterGroup
+///
+/// \see TableCell
+/// \see TableInstanciationParameters
+/// \see TableTemplate
+class TableCellArrayGroup
{
public:
- enum ExpansionDirection
- {
- ExpandUp,
- ExpandDown,
- ExpandLeft,
- ExpandRight,
- };
+ int Row;
+ /// Leftmost cell in this group
+ int LeftCell;
+ /// Rightmost cell in this group
+ int RightCell;
public:
- ExpansionDirection ExpandDirection;
+ Vec2i GetLeftCell() const;
+ Vec2i GetRightCell() const;
+ int GetCount() const;
};
// Forward declaration of libxlsxwriter structs
@@ -94,11 +105,22 @@ struct lxw_worksheet;
class TableInstanciationParameters
{
private:
- TableTemplate* mTemplate;
- tsl::robin_map<Vec2i, std::string> ParametricCells;
+ const TableTemplate* mTable;
public:
- // TODO
+ tsl::robin_map<Vec2i, std::string> SingularCells;
+
+ using ArrayGroupRow = std::vector<std::string>;
+ using ArrayGroupData = std::vector<ArrayGroupRow>;
+ std::vector<ArrayGroupData> ArrayGroups;
+
+public:
+ TableInstanciationParameters(const TableTemplate& table);
+
+ TableInstanciationParameters& ResetTable(const TableTemplate& newTable);
+ TableInstanciationParameters RebindTable(const TableTemplate& newTable) const;
+
+ const TableTemplate& GetTable() const;
};
/// A table template, where individual cells can be filled by workflows instanciating this template. Merged cells,
@@ -109,7 +131,7 @@ class TableTemplate
{
private:
std::vector<TableCell> mCells;
- std::vector<TableArrayParameterGroup> mArrayGroups;
+ std::vector<TableCellArrayGroup> mArrayGroups;
int mTableWidth;
int mTableHeight;
diff --git a/core/src/Model/Template/fwd.hpp b/core/src/Model/Template/fwd.hpp
index d62552f..2f41f22 100644
--- a/core/src/Model/Template/fwd.hpp
+++ b/core/src/Model/Template/fwd.hpp
@@ -2,6 +2,6 @@
// TableTemplate.hpp
class TableCell;
-class TableArrayParameterGroup;
+class TableCellArrayGroup;
class TableInstanciationParameters;
class TableTemplate;