aboutsummaryrefslogtreecommitdiff
path: root/core/src/Model/Template
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/Model/Template')
-rw-r--r--core/src/Model/Template/TableTemplate.cpp591
-rw-r--r--core/src/Model/Template/TableTemplate.hpp223
-rw-r--r--core/src/Model/Template/TableTemplateIterator.cpp52
-rw-r--r--core/src/Model/Template/TableTemplateIterator.hpp35
-rw-r--r--core/src/Model/Template/Template.hpp68
-rw-r--r--core/src/Model/Template/Template_Main.cpp214
-rw-r--r--core/src/Model/Template/Template_RTTI.cpp29
-rw-r--r--core/src/Model/Template/fwd.hpp11
8 files changed, 0 insertions, 1223 deletions
diff --git a/core/src/Model/Template/TableTemplate.cpp b/core/src/Model/Template/TableTemplate.cpp
deleted file mode 100644
index 57caac4..0000000
--- a/core/src/Model/Template/TableTemplate.cpp
+++ /dev/null
@@ -1,591 +0,0 @@
-#include "TableTemplate.hpp"
-
-#include "Utils/IO/StringIntegration.hpp"
-#include "Utils/IO/TslArrayIntegration.hpp"
-#include "Utils/IO/VectorIntegration.hpp"
-
-#include <xlsxwriter.h>
-#include <algorithm>
-#include <charconv>
-#include <cstddef>
-#include <cstdint>
-#include <iostream>
-#include <map>
-
-bool TableCell::IsDataHoldingCell() const
-{
- return IsPrimaryCell() || !IsMergedCell();
-}
-
-bool TableCell::IsPrimaryCell() const
-{
- return PrimaryCellLocation == Location;
-}
-
-bool TableCell::IsMergedCell() const
-{
- return PrimaryCellLocation.x == -1 || PrimaryCellLocation.y == -1;
-}
-
-template <class TTableCell, class TStream>
-void OperateStreamForTableCell(TTableCell& cell, TStream& proxy)
-{
- proxy.template ObjectAdapted<DataStreamAdapters::String>(cell.Content);
- proxy.Object(cell.Location);
- proxy.Object(cell.PrimaryCellLocation);
- proxy.Value(cell.SpanX);
- proxy.Value(cell.SpanY);
- proxy.Enum(cell.HorizontalAlignment);
- proxy.Enum(cell.VerticalAlignment);
- proxy.Enum(cell.Type);
- proxy.Value(cell.DataId);
-}
-
-void TableCell::ReadFromDataStream(InputDataStream& stream)
-{
- ::OperateStreamForTableCell(*this, stream);
-}
-
-void TableCell::WriteToDataStream(OutputDataStream& stream) const
-{
- ::OperateStreamForTableCell(*this, stream);
-}
-
-Vec2i TableArrayGroup::GetLeftCell() const
-{
- return { Row, LeftCell };
-}
-
-Vec2i TableArrayGroup::GetRightCell() const
-{
- return { Row, RightCell };
-}
-
-int TableArrayGroup::GetCount() const
-{
- return RightCell - LeftCell + 1;
-}
-
-Vec2i TableArrayGroup::FindCell(std::string_view name)
-{
- // TODO
- return Vec2i{};
-}
-
-template <class TMap>
-static bool UpdateElementName(TMap& map, std::string_view oldName, std::string_view newName)
-{
- auto iter = map.find(oldName);
- if (iter == map.end()) {
- return false;
- }
-
- auto elm = iter.value();
- auto [DISCARD, inserted] = map.insert(newName, elm);
- if (!inserted) {
- return false;
- }
-
- map.erase(iter);
- return true;
-}
-
-bool TableArrayGroup::UpdateCellName(std::string_view oldName, std::string_view newName)
-{
- return ::UpdateElementName(mName2Cell, oldName, newName);
-}
-
-template <class TTableArrayGroup, class TStream>
-void OperateStreamForTableArrayGroup(TTableArrayGroup& group, TStream& stream)
-{
- stream.Value(group.Row);
- stream.Value(group.LeftCell);
- stream.Value(group.RightCell);
-}
-
-void TableArrayGroup::ReadFromDataStream(InputDataStream& stream)
-{
- ::OperateStreamForTableArrayGroup(*this, stream);
-}
-
-void TableArrayGroup::WriteToDataStream(OutputDataStream& stream) const
-{
- ::OperateStreamForTableArrayGroup(*this, stream);
-}
-
-TableInstantiationParameters::TableInstantiationParameters(const TableTemplate& table)
- : mTable{ &table }
-{
-}
-
-TableInstantiationParameters& TableInstantiationParameters::ResetTable(const TableTemplate& newTable)
-{
- mTable = &newTable;
- return *this;
-}
-
-TableInstantiationParameters TableInstantiationParameters::RebindTable(const TableTemplate& newTable) const
-{
- TableInstantiationParameters result(newTable);
- result.SingularCells = this->SingularCells;
- result.ArrayGroups = this->ArrayGroups;
- return result;
-}
-
-const TableTemplate& TableInstantiationParameters::GetTable() const
-{
- return *mTable;
-}
-
-bool TableTemplate::IsInstance(const Template* tmpl)
-{
- return tmpl->GetKind() == KD_Table;
-}
-
-TableTemplate::TableTemplate()
- : Template(KD_Table)
-{
-}
-
-int TableTemplate::GetTableWidth() const
-{
- return mColumnWidths.size();
-}
-
-int TableTemplate::GetTableHeight() const
-{
- return mRowHeights.size();
-}
-
-void TableTemplate::Resize(int newWidth, int newHeight)
-{
- // TODO this doesn't gracefully handle resizing to a smaller size which trims some merged cells
-
- std::vector<TableCell> cells;
- cells.reserve(newWidth * newHeight);
-
- int tableWidth = GetTableWidth();
- int tableHeight = GetTableHeight();
-
- for (int y = 0; y < newHeight; ++y) {
- if (y >= tableHeight) {
- for (int x = 0; x < newWidth; ++x) {
- cells.push_back(TableCell{});
- }
- continue;
- }
-
- for (int x = 0; x < newWidth; ++x) {
- if (x >= tableWidth) {
- cells.push_back(TableCell{});
- } else {
- auto& cell = GetCell({ x, y });
- cells.push_back(std::move(cell));
- }
- }
- }
-
- mCells = std::move(cells);
- mColumnWidths.resize(newWidth, 80);
- mRowHeights.resize(newHeight, 20);
-}
-
-int TableTemplate::GetRowHeight(int row) const
-{
- return mRowHeights[row];
-}
-
-void TableTemplate::SetRowHeight(int row, int height)
-{
- mRowHeights[row] = height;
-}
-
-int TableTemplate::GetColumnWidth(int column) const
-{
- return mColumnWidths[column];
-}
-
-void TableTemplate::SetColumnWidth(int column, int width)
-{
- mColumnWidths[column] = width;
-}
-
-const TableCell& TableTemplate::GetCell(Vec2i pos) const
-{
- int tableWidth = GetTableWidth();
- return mCells[pos.y * tableWidth + pos.x];
-}
-
-TableCell& TableTemplate::GetCell(Vec2i pos)
-{
- return const_cast<TableCell&>(const_cast<const TableTemplate*>(this)->GetCell(pos));
-}
-
-void TableTemplate::SetCellType(Vec2i pos, TableCell::CellType type)
-{
- auto& cell = GetCell(pos);
- if (cell.Type == type) {
- return;
- }
-
- switch (cell.Type) {
- // Nothing to change
- case TableCell::ConstantCell: break;
-
- case TableCell::SingularParametricCell:
- mName2Parameters.erase(cell.Content);
- break;
-
- case TableCell::ArrayParametricCell: {
- auto& ag = mArrayGroups[cell.DataId];
- if (pos.x == ag.LeftCell) {
- ag.LeftCell++;
- } else if (pos.x == ag.RightCell) {
- ag.RightCell--;
- } else {
- }
- } break;
- }
-
- switch (type) {
- // Nothing to do
- case TableCell::ConstantCell: break;
-
- case TableCell::SingularParametricCell: {
- int idx = pos.y * GetTableWidth() + pos.x;
- auto [DISCARD, inserted] = mName2Parameters.insert(cell.Content, idx);
-
- // Duplicate name
- if (!inserted) {
- return;
- }
- } break;
-
- case TableCell::ArrayParametricCell: {
- auto ptr = AddArrayGroup(pos.y, pos.x, pos.x);
-
- // Duplicate name
- if (ptr == nullptr) {
- return;
- }
- } break;
- }
-
- cell.Type = type;
-}
-
-bool TableTemplate::UpdateParameterName(std::string_view oldName, std::string_view newName)
-{
- return ::UpdateElementName(mName2Parameters, oldName, newName);
-}
-
-int TableTemplate::GetArrayGroupCount() const
-{
- return mArrayGroups.size();
-}
-
-const TableArrayGroup& TableTemplate::GetArrayGroup(int id) const
-{
- return mArrayGroups[id];
-}
-
-TableArrayGroup& TableTemplate::GetArrayGroup(int id)
-{
- return mArrayGroups[id];
-}
-
-TableArrayGroup* TableTemplate::AddArrayGroup(int row, int left, int right)
-{
- // size_t max value: 18446744073709551615
- // ^~~~~~~~~~~~~~~~~~~~ 20 chars
- char name[20];
- auto res = std::to_chars(std::begin(name), std::end(name), mArrayGroups.size());
- std::string_view nameStr(name, res.ptr - name);
-
- return AddArrayGroup(nameStr, row, left, right);
-}
-
-TableArrayGroup* TableTemplate::AddArrayGroup(std::string_view name, int row, int left, int right)
-{
- assert(row >= 0 && row < GetTableHeight());
- assert(left >= 0 && left < GetTableWidth());
- assert(right >= 0 && right < GetTableWidth());
-
- // TODO check for overlap
-
- if (left > right) {
- std::swap(left, right);
- }
-
- auto [DISCARD, inserted] = mName2ArrayGroups.insert(name, (int)mArrayGroups.size());
- if (!inserted) {
- return nullptr;
- }
-
- mArrayGroups.push_back(TableArrayGroup{
- .Row = row,
- .LeftCell = left,
- .RightCell = right,
- });
- auto& ag = mArrayGroups.back();
-
- for (int x = left; x <= right; x++) {
- auto& cell = GetCell({ x, row });
-
- // Update type
- cell.Type = TableCell::ArrayParametricCell;
-
- // Insert parameter name lookup
- while (true) {
- auto [DISCARD, inserted] = ag.mName2Cell.insert(cell.Content, x);
- if (inserted) {
- break;
- }
-
- cell.Content += "-";
- }
- }
-
- return &ag;
-}
-
-bool TableTemplate::UpdateArrayGroupName(std::string_view oldName, std::string_view newName)
-{
- return ::UpdateElementName(mName2ArrayGroups, oldName, newName);
-}
-
-bool TableTemplate::ExtendArrayGroupLeft(int id, int n)
-{
- assert(n > 0);
-
- auto& ag = mArrayGroups[id];
- ag.LeftCell -= n;
-
- return false;
-}
-
-bool TableTemplate::ExtendArrayGroupRight(int id, int n)
-{
- assert(n > 0);
-
- auto& ag = mArrayGroups[id];
- ag.RightCell += n;
-
- return false;
-}
-
-TableCell* TableTemplate::FindCell(std::string_view name)
-{
- auto iter = mName2Parameters.find(name);
- if (iter != mName2Parameters.end()) {
- return &mCells[iter.value()];
- } else {
- return nullptr;
- }
-}
-
-TableArrayGroup* TableTemplate::FindArrayGroup(std::string_view name)
-{
- auto iter = mName2ArrayGroups.find(name);
- if (iter != mName2ArrayGroups.end()) {
- return &mArrayGroups[iter.value()];
- } else {
- return nullptr;
- }
-}
-
-TableTemplate::MergeCellsResult TableTemplate::MergeCells(Vec2i topLeft, Vec2i bottomRight)
-{
- auto SortTwo = [](int& a, int& b) {
- if (a > b) {
- std::swap(a, b);
- }
- };
- SortTwo(topLeft.x, bottomRight.x);
- SortTwo(topLeft.y, bottomRight.y);
-
- auto ResetProgress = [&]() {
- for (int y = topLeft.y; y < bottomRight.y; ++y) {
- for (int x = topLeft.x; x < bottomRight.x; ++x) {
- auto& cell = GetCell({ x, y });
- cell.PrimaryCellLocation = { -1, -1 };
- }
- }
- };
-
- for (int y = topLeft.y; y < bottomRight.y; ++y) {
- for (int x = topLeft.x; x < bottomRight.x; ++x) {
- auto& cell = GetCell({ x, y });
- if (cell.IsMergedCell()) {
- ResetProgress();
- return MCR_CellAlreadyMerged;
- }
-
- cell.PrimaryCellLocation = topLeft;
- }
- }
-
- auto& primaryCell = GetCell(topLeft);
- primaryCell.SpanX = bottomRight.x - topLeft.x;
- primaryCell.SpanY = bottomRight.y - topLeft.y;
-
- return MCR_Success;
-}
-
-TableTemplate::BreakCellsResult TableTemplate::BreakCells(Vec2i topLeft)
-{
- auto& primaryCell = GetCell(topLeft);
- if (!primaryCell.IsMergedCell()) {
- return BCR_CellNotMerged;
- }
-
- for (int dy = 0; dy < primaryCell.SpanY; ++dy) {
- for (int dx = 0; dx < primaryCell.SpanX; ++dx) {
- auto& cell = GetCell({ topLeft.x + dx, topLeft.y + dy });
- cell.PrimaryCellLocation = { -1, -1 };
- }
- }
-
- primaryCell.SpanX = 1;
- primaryCell.SpanY = 1;
-
- return BCR_Success;
-}
-
-lxw_workbook* TableTemplate::InstantiateToExcelWorkbook(const TableInstantiationParameters& params) const
-{
- auto workbook = workbook_new("Table.xlsx");
- InstantiateToExcelWorksheet(workbook, params);
- return workbook;
-}
-
-lxw_worksheet* TableTemplate::InstantiateToExcelWorksheet(lxw_workbook* workbook, const TableInstantiationParameters& params) const
-{
- 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.try_emplace(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/instantiate 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 rowCount = groupParams.size();
- int baseRowIdx = groupInfo.Row + GetOffset(groupInfo.Row);
-
- // For each row that would be generated
- for (int rowIdx = 0; rowIdx < rowCount; ++rowIdx) {
- auto& row = groupParams[rowIdx];
-
- // For each cell in the row
- for (int rowCellIdx = 0; rowCellIdx < rowCellCount; ++rowCellIdx) {
- // TODO support merged cells in array groups
- worksheet_write_string(worksheet, baseRowIdx + rowIdx, rowCellIdx, row[rowCellIdx].c_str(), nullptr);
- }
- }
- }
-
- int tableWidth = GetTableWidth();
- int tableHeight = GetTableHeight();
-
- // Write all regular and singular parameter cells
- for (int y = 0; y < tableHeight; ++y) {
- for (int x = 0; x < tableWidth; ++x) {
- auto& cell = GetCell({ x, y });
-
- if (!cell.IsDataHoldingCell()) {
- continue;
- }
-
- switch (cell.Type) {
- case TableCell::ConstantCell: {
- int row = y + GetOffset(y);
- int col = x;
-
- WriteCell(row, col, cell, cell.Content.c_str());
- } break;
-
- 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;
- }
- }
- }
-
- return worksheet;
-}
-
-class TableTemplate::Private
-{
-public:
- template <class TTableTemplate, class TProxy>
- static void OperateStream(TTableTemplate& table, TProxy& proxy)
- {
- proxy.template ObjectAdapted<DataStreamAdapters::Vector<>>(table.mColumnWidths);
- proxy.template ObjectAdapted<DataStreamAdapters::Vector<>>(table.mRowHeights);
- proxy.template ObjectAdapted<DataStreamAdapters::Vector<>>(table.mCells);
- proxy.template ObjectAdapted<DataStreamAdapters::Vector<>>(table.mArrayGroups);
- proxy.template ObjectAdapted<DataStreamAdapters::TslArrayMap<>>(table.mName2Parameters);
- proxy.template ObjectAdapted<DataStreamAdapters::TslArrayMap<>>(table.mName2ArrayGroups);
- }
-};
-
-void TableTemplate::ReadFromDataStream(InputDataStream& stream)
-{
- Private::OperateStream(*this, stream);
-}
-
-void TableTemplate::WriteToDataStream(OutputDataStream& stream) const
-{
- Private::OperateStream(*this, stream);
-}
diff --git a/core/src/Model/Template/TableTemplate.hpp b/core/src/Model/Template/TableTemplate.hpp
deleted file mode 100644
index 8771867..0000000
--- a/core/src/Model/Template/TableTemplate.hpp
+++ /dev/null
@@ -1,223 +0,0 @@
-#pragma once
-
-#include "Model/Template/Template.hpp"
-#include "Utils/Vector.hpp"
-#include "Utils/VectorHash.hpp"
-#include "cplt_fwd.hpp"
-
-#include <tsl/array_map.h>
-#include <tsl/robin_map.h>
-#include <string>
-#include <string_view>
-#include <vector>
-
-class TableCell
-{
-public:
- enum TextAlignment
- {
- /// For horizontal alignment, this means align left. For vertical alignment, this means align top.
- AlignAxisMin,
- /// Align middle of the text to the middle of the axis.
- AlignCenter,
- /// For horizontal alignment, this means align right. For vertical alignment, this means align bottom.
- AlignAxisMax,
- };
-
- enum CellType
- {
- ConstantCell,
- SingularParametricCell,
- ArrayParametricCell,
- };
-
-public:
- /// Display content of this cell. This doesn't necessarily have to line up with the parameter name (if this cell is one).
- std::string Content;
- Vec2i Location;
- /// Location of the primary (top left) cell, if this cell is a part of a merged group.
- /// Otherwise, either component of this field shall be -1.
- Vec2i PrimaryCellLocation{ -1, -1 };
- int SpanX = 0;
- int SpanY = 0;
- TextAlignment HorizontalAlignment = AlignCenter;
- TextAlignment VerticalAlignment = AlignCenter;
- CellType Type = ConstantCell;
- /// The id of the group description object, if this cell isn't a constant or singular 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;
-
- void ReadFromDataStream(InputDataStream& stream);
- void WriteToDataStream(OutputDataStream& stream) const;
-};
-
-// TODO support reverse (bottom to top) filling order
-// TODO support horizontal filling order
-
-/// Parameter group information for a grouped array of cells. When instantiated, 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 instantiated with the n-th element in the provided array.
-/// \code
-/// [["foo", "bar", "foobar"],
-/// ["a", "b", c"],
-/// ["1", "2", "3"],
-/// ["x", "y", "z"]]
-/// // ... may be more
-/// \endcode
-/// 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:
-/// \code
-/// | 2 elements was fed to it
-/// | | 1 element was fed to it
-/// V V
-/// {~~~~~~~~~~~~~~~~}{~~~~~~~~~~~~~~}
-/// +------+---------+---------------+
-/// | Foo | Example | Another group |
-/// +------+---------+---------------+
-/// | Cool | Example | |
-/// +------+---------+---------------+
-/// \endcode
-///
-/// \see TableCell
-/// \see TableInstantiationParameters
-/// \see TableTemplate
-class TableArrayGroup
-{
-public:
- /// Parameter name mapped to cell location (index from LeftCell).
- tsl::array_map<char, int> mName2Cell;
- int Row;
- /// Leftmost cell in this group
- int LeftCell;
- /// Rightmost cell in this group
- int RightCell;
-
-public:
- Vec2i GetLeftCell() const;
- Vec2i GetRightCell() const;
- int GetCount() const;
-
- /// Find the location of the cell within this array group that has the given name.
- Vec2i FindCell(std::string_view name);
- bool UpdateCellName(std::string_view oldName, std::string_view newName);
-
- void ReadFromDataStream(InputDataStream& stream);
- void WriteToDataStream(OutputDataStream& stream) const;
-};
-
-// Forward declaration of libxlsxwriter structs
-struct lxw_workbook;
-struct lxw_worksheet;
-
-/// An object containing the necessary information to instantiate a table template.
-/// \see TableTemplate
-class TableInstantiationParameters
-{
-private:
- const TableTemplate* mTable;
-
-public:
- tsl::robin_map<Vec2i, std::string> SingularCells;
-
- using ArrayGroupRow = std::vector<std::string>;
- using ArrayGroupData = std::vector<ArrayGroupRow>;
- std::vector<ArrayGroupData> ArrayGroups;
-
-public:
- TableInstantiationParameters(const TableTemplate& table);
-
- TableInstantiationParameters& ResetTable(const TableTemplate& newTable);
- TableInstantiationParameters RebindTable(const TableTemplate& newTable) const;
-
- const TableTemplate& GetTable() const;
-};
-
-/// A table template, where individual cells can be filled by workflows instantiating this template. Merged cells,
-/// parametric rows/columns, and grids are also supported.
-///
-/// This current supports exporting to xlsx files.
-class TableTemplate : public Template
-{
- friend class TableSingleParamsIter;
- friend class TableArrayGroupsIter;
- class Private;
-
-private:
- /// Map from parameter name to index of the parameter cell (stored in mCells).
- tsl::array_map<char, int> mName2Parameters;
- /// Map from array group name to the index of the array group (stored in mArrayGroups).
- tsl::array_map<char, int> mName2ArrayGroups;
- std::vector<TableCell> mCells;
- std::vector<TableArrayGroup> mArrayGroups;
- std::vector<int> mRowHeights;
- std::vector<int> mColumnWidths;
-
-public:
- static bool IsInstance(const Template* tmpl);
- TableTemplate();
-
- int GetTableWidth() const;
- int GetTableHeight() const;
- void Resize(int newWidth, int newHeight);
-
- int GetRowHeight(int row) const;
- void SetRowHeight(int row, int height);
- int GetColumnWidth(int column) const;
- void SetColumnWidth(int column, int width);
-
- const TableCell& GetCell(Vec2i pos) const;
- TableCell& GetCell(Vec2i pos);
- /// <ul>
- /// <li> In case of becoming a SingularParametricCell: the parameter name is filled with TableCell::Content.
- /// <li> In case of becoming a ArrayGroupParametricCell: the array group name is automatically generated as the nth group it would be come.
- /// i.e., if there aRe currently 3 groups, the newly created group would be named "4".
- /// If this name collides with an existing group, hyphens \c - will be append to the name until no collision happens.
- /// </ul>
- void SetCellType(Vec2i pos, TableCell::CellType type);
-
- /// Updates the parameter cell to a new name. Returns true on success and false on failure (param not found or name duplicates).
- bool UpdateParameterName(std::string_view oldName, std::string_view newName);
-
- int GetArrayGroupCount() const;
- const TableArrayGroup& GetArrayGroup(int id) const;
- TableArrayGroup& GetArrayGroup(int id);
- TableArrayGroup* AddArrayGroup(int row, int left, int right);
- TableArrayGroup* AddArrayGroup(std::string_view name, int row, int left, int right);
- bool UpdateArrayGroupName(std::string_view oldName, std::string_view newName);
- bool ExtendArrayGroupLeft(int id, int n);
- bool ExtendArrayGroupRight(int id, int n);
-
- /// Find a singular parameter cell by its name. This does not include cells within an array group.
- TableCell* FindCell(std::string_view name);
-
- /// Find an array group by its name.
- TableArrayGroup* FindArrayGroup(std::string_view name);
-
- enum MergeCellsResult
- {
- MCR_CellAlreadyMerged,
- MCR_Success,
- };
- MergeCellsResult MergeCells(Vec2i topLeft, Vec2i bottomRight);
-
- enum BreakCellsResult
- {
- BCR_CellNotMerged,
- BCR_Success,
- };
- BreakCellsResult BreakCells(Vec2i topLeft);
-
- lxw_workbook* InstantiateToExcelWorkbook(const TableInstantiationParameters& params) const;
- lxw_worksheet* InstantiateToExcelWorksheet(lxw_workbook* workbook, const TableInstantiationParameters& params) const;
-
- void ReadFromDataStream(InputDataStream& stream) override;
- void WriteToDataStream(OutputDataStream& stream) const override;
-};
diff --git a/core/src/Model/Template/TableTemplateIterator.cpp b/core/src/Model/Template/TableTemplateIterator.cpp
deleted file mode 100644
index 19e30b9..0000000
--- a/core/src/Model/Template/TableTemplateIterator.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "TableTemplateIterator.hpp"
-
-TableSingleParamsIter::TableSingleParamsIter(TableTemplate& tmpl)
- : mTemplate{ &tmpl }
- , mIter{ tmpl.mName2Parameters.begin() }
-{
-}
-
-bool TableSingleParamsIter::HasNext() const
-{
- return mIter != mTemplate->mName2Parameters.end();
-}
-
-TableCell& TableSingleParamsIter::Next()
-{
- int id = mIter.value();
- ++mIter;
-
- return mTemplate->mCells[id];
-}
-
-TableArrayGroupsIter::TableArrayGroupsIter(TableTemplate& tmpl)
- : mTemplate{ &tmpl }
- , mIter{ tmpl.mName2ArrayGroups.begin() }
-{
-}
-
-bool TableArrayGroupsIter::HasNext() const
-{
- return mIter != mTemplate->mName2ArrayGroups.end();
-}
-
-TableArrayGroup& TableArrayGroupsIter::Peek() const
-{
- int id = mIter.value();
- return mTemplate->mArrayGroups[id];
-}
-
-std::string_view TableArrayGroupsIter::PeekName() const
-{
- return mIter.key_sv();
-}
-
-const char* TableArrayGroupsIter::PeekNameCStr() const
-{
- return mIter.key();
-}
-
-void TableArrayGroupsIter::Next()
-{
- ++mIter;
-}
diff --git a/core/src/Model/Template/TableTemplateIterator.hpp b/core/src/Model/Template/TableTemplateIterator.hpp
deleted file mode 100644
index bf7f517..0000000
--- a/core/src/Model/Template/TableTemplateIterator.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include "Model/Template/TableTemplate.hpp"
-#include "Model/Template/Template.hpp"
-
-#include <string_view>
-
-class TableSingleParamsIter
-{
-private:
- TableTemplate* mTemplate;
- tsl::array_map<char, int>::iterator mIter;
-
-public:
- TableSingleParamsIter(TableTemplate& tmpl);
-
- bool HasNext() const;
- TableCell& Next();
-};
-
-class TableArrayGroupsIter
-{
-private:
- TableTemplate* mTemplate;
- tsl::array_map<char, int>::iterator mIter;
-
-public:
- TableArrayGroupsIter(TableTemplate& tmpl);
-
- bool HasNext() const;
- TableArrayGroup& Peek() const;
- std::string_view PeekName() const;
- const char* PeekNameCStr() const;
- void Next();
-};
diff --git a/core/src/Model/Template/Template.hpp b/core/src/Model/Template/Template.hpp
deleted file mode 100644
index 061cc07..0000000
--- a/core/src/Model/Template/Template.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#pragma once
-
-#include "Model/Assets.hpp"
-#include "cplt_fwd.hpp"
-
-#include <filesystem>
-#include <iosfwd>
-#include <memory>
-#include <string>
-
-class Template : public Asset
-{
-public:
- enum Kind
- {
- KD_Table,
-
- InvalidKind,
- KindCount = InvalidKind,
- };
-
- using CategoryType = TemplateAssetList;
-
-private:
- Kind mKind;
-
-public:
- static const char* FormatKind(Kind kind);
- static std::unique_ptr<Template> CreateByKind(Kind kind);
-
- static bool IsInstance(const Template* tmpl);
-
- Template(Kind kind);
- ~Template() override = default;
-
- Kind GetKind() const;
-
- virtual void ReadFromDataStream(InputDataStream& stream) = 0;
- virtual void WriteToDataStream(OutputDataStream& stream) const = 0;
-};
-
-class TemplateAssetList final : public AssetListTyped<Template>
-{
-private:
- // AC = Asset Creator
- std::string mACNewName;
- NameSelectionError mACNewNameError = NameSelectionError::Empty;
- Template::Kind mACNewKind = Template::InvalidKind;
-
-public:
- // Inherit constructors
- using AssetListTyped::AssetListTyped;
-
-protected:
- void DiscoverFiles(const std::function<void(SavedAsset)>& callback) const override;
-
- std::string RetrieveNameFromFile(const std::filesystem::path& file) const override;
- uuids::uuid RetrieveUuidFromFile(const std::filesystem::path& file) const override;
- std::filesystem::path RetrievePathFromAsset(const SavedAsset& asset) const override;
-
- bool SaveInstance(const SavedAsset& assetInfo, const Asset* asset) const override;
- Template* LoadInstance(const SavedAsset& assetInfo) const override;
- Template* CreateInstance(const SavedAsset& assetInfo) const override;
- bool RenameInstanceOnDisk(const SavedAsset& assetInfo, std::string_view oldName) const override;
-
- void DisplayAssetCreator(ListState& state) override;
- void DisplayDetailsTable(ListState& state) const override;
-};
diff --git a/core/src/Model/Template/Template_Main.cpp b/core/src/Model/Template/Template_Main.cpp
deleted file mode 100644
index 4d6b67c..0000000
--- a/core/src/Model/Template/Template_Main.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-#include "Template.hpp"
-
-#include "Model/GlobalStates.hpp"
-#include "Model/Project.hpp"
-#include "UI/UI.hpp"
-#include "Utils/I18n.hpp"
-#include "Utils/IO/Archive.hpp"
-#include "Utils/UUID.hpp"
-
-#include <imgui.h>
-#include <imgui_stdlib.h>
-#include <algorithm>
-#include <cstdint>
-#include <fstream>
-
-using namespace std::literals::string_view_literals;
-namespace fs = std::filesystem;
-
-Template::Template(Kind kind)
- : mKind{ kind }
-{
-}
-
-Template::Kind Template::GetKind() const
-{
- return mKind;
-}
-
-void TemplateAssetList::DiscoverFiles(const std::function<void(SavedAsset)>& callback) const
-{
- auto dir = GetConnectedProject().GetTemplatesDirectory();
- DiscoverFilesByExtension(callback, dir, ".cplt-template"sv);
-}
-
-std::string TemplateAssetList::RetrieveNameFromFile(const fs::path& file) const
-{
- auto res = DataArchive::LoadFile(file);
- if (!res) return "";
- auto& stream = res.value();
-
- SavedAsset assetInfo;
- stream.ReadObject(assetInfo);
-
- return assetInfo.Name;
-}
-
-uuids::uuid TemplateAssetList::RetrieveUuidFromFile(const fs::path& file) const
-{
- return uuids::uuid::from_string(file.stem().string());
-}
-
-fs::path TemplateAssetList::RetrievePathFromAsset(const SavedAsset& asset) const
-{
- auto fileName = uuids::to_string(asset.Uuid);
- return GetConnectedProject().GetTemplatePath(fileName);
-}
-
-bool TemplateAssetList::SaveInstance(const SavedAsset& assetInfo, const Asset* asset) const
-{
- auto path = RetrievePathFromAsset(assetInfo);
- auto res = DataArchive::SaveFile(path);
- if (!res) return false;
- auto& stream = res.value();
-
- stream.WriteObject(assetInfo);
- // This cast is fine: calls to this class will always be wrapped in TypedAssetList<T>, which will ensure `asset` points to some Template
- if (auto tmpl = static_cast<const Template*>(asset)) { // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
- stream.WriteObject(*tmpl);
- }
-
- return true;
-}
-
-static std::unique_ptr<Template> LoadTemplateFromFile(const fs::path& path)
-{
- auto res = DataArchive::LoadFile(path);
- if (!res) return nullptr;
- auto& stream = res.value();
-
- SavedAsset assetInfo;
- stream.ReadObject(assetInfo);
-
- auto kind = static_cast<Template::Kind>(assetInfo.Payload);
- auto tmpl = Template::CreateByKind(kind);
- stream.ReadObject(*tmpl);
-
- return tmpl;
-}
-
-Template* TemplateAssetList::LoadInstance(const SavedAsset& assetInfo) const
-{
- return ::LoadTemplateFromFile(RetrievePathFromAsset(assetInfo)).release();
-}
-
-Template* TemplateAssetList::CreateInstance(const SavedAsset& assetInfo) const
-{
- auto kind = static_cast<Template::Kind>(assetInfo.Payload);
- return Template::CreateByKind(kind).release();
-}
-
-bool TemplateAssetList::RenameInstanceOnDisk(const SavedAsset& assetInfo, std::string_view oldName) const
-{
- // Get asset path, which is only dependent on UUID
- auto path = RetrievePathFromAsset(assetInfo);
-
- auto tmpl = ::LoadTemplateFromFile(path);
- if (!tmpl) return false;
-
- // Rewrite the asset with the updated name (note the given assetInfo already has the update name)
- SaveInstance(assetInfo, tmpl.get());
-
- return true;
-}
-
-void TemplateAssetList::DisplayAssetCreator(ListState& state)
-{
- auto ValidateNewName = [&]() -> void {
- if (mACNewName.empty()) {
- mACNewNameError = NameSelectionError::Empty;
- return;
- }
-
- if (FindByName(mACNewName)) {
- mACNewNameError = NameSelectionError::Duplicated;
- return;
- }
-
- mACNewNameError = NameSelectionError::None;
- };
-
- auto ShowNewNameErrors = [&]() -> void {
- switch (mACNewNameError) {
- case NameSelectionError::None: break;
- case NameSelectionError::Duplicated:
- ImGui::ErrorMessage(I18N_TEXT("Duplicate name", L10N_DUPLICATE_NAME_ERROR));
- break;
- case NameSelectionError::Empty:
- ImGui::ErrorMessage(I18N_TEXT("Name cannot be empty", L10N_EMPTY_NAME_ERROR));
- break;
- }
- };
-
- auto ShowNewKindErrors = [&]() -> void {
- if (mACNewKind == Template::InvalidKind) {
- ImGui::ErrorMessage(I18N_TEXT("Invalid template type", L10N_TEMPLATE_INVALID_TYPE_ERROR));
- }
- };
-
- auto IsInputValid = [&]() -> bool {
- return mACNewNameError == NameSelectionError::None &&
- mACNewKind != Template::InvalidKind;
- };
-
- auto ResetState = [&]() -> void {
- mACNewName.clear();
- mACNewKind = Template::InvalidKind;
- ValidateNewName();
- };
-
- if (ImGui::InputText(I18N_TEXT("Name", L10N_NAME), &mACNewName)) {
- ValidateNewName();
- }
-
- if (ImGui::BeginCombo(I18N_TEXT("Type", L10N_TYPE), Template::FormatKind(mACNewKind))) {
- for (int i = 0; i < Template::KindCount; ++i) {
- auto kind = static_cast<Template::Kind>(i);
- if (ImGui::Selectable(Template::FormatKind(kind), mACNewKind == kind)) {
- mACNewKind = kind;
- }
- }
- ImGui::EndCombo();
- }
-
- ShowNewNameErrors();
- ShowNewKindErrors();
-
- if (ImGui::Button(I18N_TEXT("OK", L10N_CONFIRM), !IsInputValid())) {
- ImGui::CloseCurrentPopup();
-
- Create(SavedAsset{
- .Name = mACNewName,
- .Payload = static_cast<uint64_t>(mACNewKind),
- });
- ResetState();
- }
- ImGui::SameLine();
- if (ImGui::Button(I18N_TEXT("Cancel", L10N_CANCEL))) {
- ImGui::CloseCurrentPopup();
- }
-}
-
-void TemplateAssetList::DisplayDetailsTable(ListState& state) const
-{
- ImGui::BeginTable("AssetDetailsTable", 2, ImGuiTableFlags_Borders);
-
- ImGui::TableSetupColumn(I18N_TEXT("Name", L10N_NAME));
- ImGui::TableSetupColumn(I18N_TEXT("Type", L10N_TYPE));
- ImGui::TableHeadersRow();
-
- for (auto& asset : this->GetAssets()) {
- ImGui::TableNextRow();
-
- ImGui::TableNextColumn();
- if (ImGui::Selectable(asset.Name.c_str(), state.SelectedAsset == &asset, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_DontClosePopups)) {
- state.SelectedAsset = &asset;
- }
-
- ImGui::TableNextColumn();
- auto kind = static_cast<Template::Kind>(asset.Payload);
- ImGui::TextUnformatted(Template::FormatKind(kind));
- }
-
- ImGui::EndTable();
-}
diff --git a/core/src/Model/Template/Template_RTTI.cpp b/core/src/Model/Template/Template_RTTI.cpp
deleted file mode 100644
index d1affe7..0000000
--- a/core/src/Model/Template/Template_RTTI.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "Template.hpp"
-
-#include "Model/Template/TableTemplate.hpp"
-#include "Utils/I18n.hpp"
-
-const char* Template::FormatKind(Kind kind)
-{
- switch (kind) {
- case KD_Table: return I18N_TEXT("Table template", L10N_TEMPLATE_TABLE);
-
- case InvalidKind: break;
- }
- return "";
-}
-
-std::unique_ptr<Template> Template::CreateByKind(Kind kind)
-{
- switch (kind) {
- case KD_Table: return std::make_unique<TableTemplate>();
-
- case InvalidKind: break;
- }
- return nullptr;
-}
-
-bool Template::IsInstance(const Template* tmpl)
-{
- return true;
-}
diff --git a/core/src/Model/Template/fwd.hpp b/core/src/Model/Template/fwd.hpp
deleted file mode 100644
index 8378871..0000000
--- a/core/src/Model/Template/fwd.hpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#pragma once
-
-// TableTemplate.hpp
-class TableCell;
-class TableArrayGroup;
-class TableInstantiationParameters;
-class TableTemplate;
-
-// Template.hpp
-class Template;
-class TemplateAssetList;