aboutsummaryrefslogtreecommitdiff
path: root/core/src/Model
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/Model')
-rw-r--r--core/src/Model/Project.cpp134
-rw-r--r--core/src/Model/Project.hpp22
-rw-r--r--core/src/Model/Template/TableTemplate.cpp63
-rw-r--r--core/src/Model/Template/TableTemplate.hpp12
-rw-r--r--core/src/Model/Template/Template.hpp45
-rw-r--r--core/src/Model/Template/Template_Main.cpp5
-rw-r--r--core/src/Model/Template/Template_RTTI.cpp21
-rw-r--r--core/src/Model/Template/fwd.hpp4
-rw-r--r--core/src/Model/Workflow/Workflow.hpp2
-rw-r--r--core/src/Model/fwd.hpp2
10 files changed, 253 insertions, 57 deletions
diff --git a/core/src/Model/Project.cpp b/core/src/Model/Project.cpp
index 2d7c82a..3cb3cb4 100644
--- a/core/src/Model/Project.cpp
+++ b/core/src/Model/Project.cpp
@@ -25,19 +25,19 @@ void ReadItemList(ItemList<T>& list, const fs::path& filePath)
}
}
-Project::Project(const fs::path& rootPath)
- : mRootPath{ rootPath }
+Project::Project(fs::path rootPath)
+ : mRootPath{ std::move(rootPath) }
, mRootPathString{ mRootPath.string() }
, Database(*this)
{
// TODO better diagnostic
const char* kInvalidFormatErr = "Failed to load project: invalid format.";
- std::ifstream ifs(rootPath / "cplt_project.json");
+ std::ifstream ifs(mRootPath / "cplt_project.json");
if (!ifs) {
std::string message;
message += "Failed to load project file at '";
- message += rootPath.string();
+ message += mRootPath.string();
message += "'.";
throw std::runtime_error(message);
}
@@ -81,7 +81,7 @@ Project::Project(const fs::path& rootPath)
}
}
-Project::Project(std::filesystem::path rootPath, std::string name)
+Project::Project(fs::path rootPath, std::string name)
: mRootPath{ std::move(rootPath) }
, mRootPathString{ mRootPath.string() }
, mName{ std::move(name) }
@@ -99,6 +99,36 @@ const std::string& Project::GetPathString() const
return mRootPathString;
}
+fs::path Project::GetDatabasesDirectory() const
+{
+ return mRootPath / "databases";
+}
+
+fs::path Project::GetItemsDirectory() const
+{
+ return mRootPath / "items";
+}
+
+fs::path Project::GetWorkflowsDirectory() const
+{
+ return mRootPath / "workflows";
+}
+
+fs::path Project::GetWorkflowPath(std::string_view name) const
+{
+ return (mRootPath / "workflows" / name).concat(".cplt-workflow");
+}
+
+fs::path Project::GetTemplatesDirectory() const
+{
+ return mRootPath / "templates";
+}
+
+fs::path Project::GetTemplatePath(std::string_view name) const
+{
+ return (mRootPath / "templates" / name).concat(".cplt-template");
+}
+
const std::string& Project::GetName() const
{
return mName;
@@ -109,7 +139,7 @@ void Project::SetName(std::string name)
mName = std::move(name);
}
-const decltype(Project::mWorkflows)& Project::GetWorkflows() const
+const tsl::array_map<char, WorkflowInfo>& Project::GetWorkflows() const
{
return mWorkflows;
}
@@ -132,11 +162,12 @@ std::unique_ptr<Workflow> Project::CreateWorkflow(std::string_view name)
}
auto workflow = std::make_unique<Workflow>();
- auto [it, DISCARD] = mWorkflows.insert(name, WorkflowInfo{});
- auto& info = it.value();
-
- info.Name = name;
- info.Path = GetWorkflowPath(name);
+ auto [it, DISCARD] = mWorkflows.insert(
+ name,
+ WorkflowInfo{
+ .Path = GetWorkflowPath(name),
+ .Name = std::string(name),
+ });
return workflow;
}
@@ -155,9 +186,9 @@ bool Project::RemoveWorkflow(std::string_view name)
return true;
}
-bool Project::RenameWorkflow(std::string_view name, std::string_view newName)
+bool Project::RenameWorkflow(std::string_view oldName, std::string_view newName)
{
- auto iter = mWorkflows.find(name);
+ auto iter = mWorkflows.find(oldName);
if (iter == mWorkflows.end()) return false;
auto info = std::move(iter.value());
@@ -173,6 +204,63 @@ bool Project::RenameWorkflow(std::string_view name, std::string_view newName)
return true;
}
+const tsl::array_map<char, TemplateInfo>& Project::GetTemplates() const
+{
+ return mTemplates;
+}
+
+std::unique_ptr<Template> Project::LoadTemplate(std::string_view name)
+{
+ auto iter = mTemplates.find(name);
+ if (iter == mTemplates.end()) {
+ return iter.value().LoadFromDisk();
+ } else {
+ return nullptr;
+ }
+}
+
+TemplateInfo* Project::InsertTemplate(std::string_view name, TemplateInfo info)
+{
+ auto [it, inserted] = mTemplates.insert(name, info);
+ if (inserted) {
+ return &it.value();
+ } else {
+ return nullptr;
+ }
+}
+
+bool Project::RemoveTemplate(std::string_view name)
+{
+ auto iter = mTemplates.find(name);
+ if (iter == mTemplates.end()) {
+ return false;
+ }
+ auto& info = iter.value();
+
+ fs::remove(info.Path);
+ mTemplates.erase(iter);
+
+ return true;
+}
+
+bool Project::RenameTemplate(std::string_view oldName, std::string_view newName)
+{
+ auto iter = mTemplates.find(oldName);
+ if (iter == mTemplates.end()) return false;
+
+ auto info = std::move(iter.value());
+
+ auto& oldPath = info.Path;
+ auto newPath = GetTemplatePath(newName);
+ fs::rename(oldPath, newPath);
+ info.Path = std::move(newPath);
+
+ mTemplates.insert(newName, std::move(info));
+ mTemplates.erase(iter);
+
+ return true;
+}
+
Json::Value Project::Serialize()
{
Json::Value root(Json::objectValue);
@@ -201,23 +289,3 @@ void Project::WriteToDisk()
WriteItemList(Factories, itemsDir / "factories.json");
WriteItemList(Customers, itemsDir / "customers.json");
}
-
-std::filesystem::path Project::GetDatabasesDirectory() const
-{
- return mRootPath / "databases";
-}
-
-std::filesystem::path Project::GetItemsDirectory() const
-{
- return mRootPath / "items";
-}
-
-std::filesystem::path Project::GetWorkflowsDirectory() const
-{
- return mRootPath / "workflows";
-}
-
-std::filesystem::path Project::GetWorkflowPath(std::string_view name) const
-{
- return (mRootPath / "workflows" / name).concat(".cplt-workflow");
-}
diff --git a/core/src/Model/Project.hpp b/core/src/Model/Project.hpp
index 5f26532..bce58c2 100644
--- a/core/src/Model/Project.hpp
+++ b/core/src/Model/Project.hpp
@@ -1,7 +1,9 @@
#pragma once
#include "Model/Items.hpp"
+#include "Model/Template/Template.hpp"
#include "Model/TransactionsModel.hpp"
+#include "Model/Workflow/Workflow.hpp"
#include <json/forwards.h>
#include <tsl/array_map.h>
@@ -15,17 +17,21 @@ public:
ItemList<ProductItem> Products;
ItemList<FactoryItem> Factories;
ItemList<CustomerItem> Customers;
- TransactionModel Database;
private:
tsl::array_map<char, WorkflowInfo> mWorkflows;
+ tsl::array_map<char, TemplateInfo> mTemplates;
std::filesystem::path mRootPath;
std::string mRootPathString;
std::string mName;
+ // This is put after the private fields, so that when TransactionModel's constructor runs, all of them will be initialized
+public:
+ TransactionModel Database;
+
public:
/// Load the project from a directory containing the cplt_project.json file.
- Project(const std::filesystem::path& rootPath);
+ Project(std::filesystem::path rootPath);
/// Create a project with the given name in the given path. Note that the path should be a directory that will contain the project files once created.
/// This function assumes the given directory will exist and is empty.
@@ -39,15 +45,23 @@ public:
std::filesystem::path GetItemsDirectory() const;
std::filesystem::path GetWorkflowsDirectory() const;
std::filesystem::path GetWorkflowPath(std::string_view name) const;
+ std::filesystem::path GetTemplatesDirectory() const;
+ std::filesystem::path GetTemplatePath(std::string_view name) const;
const std::string& GetName() const;
void SetName(std::string name);
- const decltype(mWorkflows)& GetWorkflows() const;
+ const tsl::array_map<char, WorkflowInfo>& GetWorkflows() const;
std::unique_ptr<Workflow> LoadWorkflow(std::string_view name);
std::unique_ptr<Workflow> CreateWorkflow(std::string_view name);
bool RemoveWorkflow(std::string_view name);
- bool RenameWorkflow(std::string_view name, std::string_view newName);
+ bool RenameWorkflow(std::string_view oldName, std::string_view newName);
+
+ const tsl::array_map<char, TemplateInfo>& GetTemplates() const;
+ std::unique_ptr<Template> LoadTemplate(std::string_view name);
+ bool InsertTemplate(std::string_view name, TemplateInfo info);
+ bool RemoveTemplate(std::string_view name);
+ bool RenameTemplate(std::string_view oldName, std::string_view newName);
Json::Value Serialize();
void WriteToDisk();
diff --git a/core/src/Model/Template/TableTemplate.cpp b/core/src/Model/Template/TableTemplate.cpp
index 258bb37..0ad1cca 100644
--- a/core/src/Model/Template/TableTemplate.cpp
+++ b/core/src/Model/Template/TableTemplate.cpp
@@ -5,6 +5,7 @@
bool TableCell::IsDataHoldingCell() const
{
+ return IsPrimaryCell() || !IsMergedCell();
}
bool TableCell::IsPrimaryCell() const
@@ -58,12 +59,12 @@ const TableTemplate& TableInstanciationParameters::GetTable() const
int TableTemplate::GetTableWidth() const
{
- return mTableWidth;
+ return mColumnWidths.size();
}
int TableTemplate::GetTableHeight() const
{
- return mTableHeight;
+ return mRowHeights.size();
}
void TableTemplate::Resize(int newWidth, int newHeight)
@@ -73,10 +74,13 @@ void TableTemplate::Resize(int newWidth, int newHeight)
std::vector<TableCell> cells;
cells.reserve(newWidth * newHeight);
- int yEnd = std::min(mTableHeight, newHeight);
- int xEnd = std::min(mTableWidth, newWidth);
+ int tableWidth = GetTableWidth();
+ int tableHeight = GetTableHeight();
+
+ int yEnd = std::min(tableHeight, newHeight);
+ int xEnd = std::min(tableWidth, newWidth);
for (int y = 0; y < yEnd; ++y) {
- if (y >= mTableHeight) {
+ if (y >= tableHeight) {
for (int x = 0; x < xEnd; ++x) {
cells.push_back(TableCell{});
}
@@ -84,7 +88,7 @@ void TableTemplate::Resize(int newWidth, int newHeight)
}
for (int x = 0; x < xEnd; ++x) {
- if (x >= mTableWidth) {
+ if (x >= tableWidth) {
cells.push_back(TableCell{});
} else {
auto& cell = GetCell({ x, y });
@@ -96,9 +100,30 @@ void TableTemplate::Resize(int newWidth, int newHeight)
mCells = std::move(cells);
}
+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
{
- return mCells[pos.y * mTableWidth + pos.x];
+ int tableWidth = GetTableWidth();
+ return mCells[pos.y * tableWidth + pos.x];
}
TableCell& TableTemplate::GetCell(Vec2i pos)
@@ -194,7 +219,7 @@ lxw_worksheet* TableTemplate::InstanciateToExcelWorksheet(lxw_workbook* workbook
// 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);
+ generatedRanges.try_emplace(row, count);
}
auto GetOffset = [&](int y) -> int {
@@ -217,27 +242,33 @@ lxw_worksheet* TableTemplate::InstanciateToExcelWorksheet(lxw_workbook* workbook
}
};
- // Write/instanciate all array groups
+ // 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 row = groupInfo.Row + GetOffset(groupInfo.Row);
+ int rowCount = groupParams.size();
+ int baseRowIdx = groupInfo.Row + GetOffset(groupInfo.Row);
// For each row that would be generated
- for (auto& rowCells : groupParams) {
+ for (int rowIdx = 0; rowIdx < rowCount; ++rowIdx) {
+ auto& row = groupParams[rowIdx];
+
// 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);
+ 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 < mTableHeight; ++y) {
- for (int x = 0; x < mTableWidth; ++x) {
+ for (int y = 0; y < tableHeight; ++y) {
+ for (int x = 0; x < tableWidth; ++x) {
auto& cell = GetCell({ x, y });
if (!cell.IsDataHoldingCell()) {
diff --git a/core/src/Model/Template/TableTemplate.hpp b/core/src/Model/Template/TableTemplate.hpp
index be043a9..688192a 100644
--- a/core/src/Model/Template/TableTemplate.hpp
+++ b/core/src/Model/Template/TableTemplate.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "Model/Template/Template.hpp"
#include "Utils/Vector.hpp"
#include "Utils/VectorHash.hpp"
#include "cplt_fwd.hpp"
@@ -127,19 +128,24 @@ public:
/// parametric rows/columns, and grids are also supported.
///
/// This current supports exporting to xlsx files.
-class TableTemplate
+class TableTemplate : public Template
{
private:
std::vector<TableCell> mCells;
std::vector<TableCellArrayGroup> mArrayGroups;
- int mTableWidth;
- int mTableHeight;
+ std::vector<int> mRowHeights;
+ std::vector<int> mColumnWidths;
public:
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);
diff --git a/core/src/Model/Template/Template.hpp b/core/src/Model/Template/Template.hpp
new file mode 100644
index 0000000..0901a1b
--- /dev/null
+++ b/core/src/Model/Template/Template.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include "cplt_fwd.hpp"
+
+#include <filesystem>
+#include <iosfwd>
+#include <memory>
+#include <string>
+
+class Template
+{
+public:
+ enum Kind
+ {
+ KD_Table,
+
+ InvalidKind,
+ KindCount = InvalidKind,
+ };
+
+public:
+ static const char* FormatKind(Kind kind);
+ static std::unique_ptr<Template> CreateByKind(Kind kind);
+
+ virtual ~Template() = default;
+
+ enum class ReadResult
+ {
+ RR_Success,
+ RR_InvalidFormat,
+ };
+ ReadResult ReadFrom(std::istream& stream) = 0;
+ void WriteTo(std::ostream& stream) const = 0;
+};
+
+class TemplateInfo
+{
+public:
+ std::filesystem::path Path;
+ std::string Name;
+ std::string PathStringCache = Path.string();
+ Template::Kind Kind;
+
+ std::unique_ptr<Template> LoadFromDisk() const;
+};
diff --git a/core/src/Model/Template/Template_Main.cpp b/core/src/Model/Template/Template_Main.cpp
new file mode 100644
index 0000000..eeb6871
--- /dev/null
+++ b/core/src/Model/Template/Template_Main.cpp
@@ -0,0 +1,5 @@
+#include "Template.hpp"
+
+std::unique_ptr<Template> TemplateInfo::LoadFromDisk() const
+{
+}
diff --git a/core/src/Model/Template/Template_RTTI.cpp b/core/src/Model/Template/Template_RTTI.cpp
new file mode 100644
index 0000000..042aaec
--- /dev/null
+++ b/core/src/Model/Template/Template_RTTI.cpp
@@ -0,0 +1,21 @@
+#include "Template.hpp"
+
+#include "Model/Template/TableTemplate.hpp"
+
+inline const char* Template::FormatKind(Kind kind)
+{
+ switch (kind) {
+ case KD_Table: return "Table template";
+
+ case InvalidKind: return "<invalid kind>";
+ }
+}
+
+inline std::unique_ptr<Template> Template::CreateByKind(Kind kind)
+{
+ switch (kind) {
+ case KD_Table: return std::make_unique<TableTemplate>();
+
+ case InvalidKind: return nullptr;
+ }
+}
diff --git a/core/src/Model/Template/fwd.hpp b/core/src/Model/Template/fwd.hpp
index 2f41f22..6bc7349 100644
--- a/core/src/Model/Template/fwd.hpp
+++ b/core/src/Model/Template/fwd.hpp
@@ -5,3 +5,7 @@ class TableCell;
class TableCellArrayGroup;
class TableInstanciationParameters;
class TableTemplate;
+
+// Template.hpp
+class Template;
+class TemplateInfo;
diff --git a/core/src/Model/Workflow/Workflow.hpp b/core/src/Model/Workflow/Workflow.hpp
index 99e4e90..ded9bfb 100644
--- a/core/src/Model/Workflow/Workflow.hpp
+++ b/core/src/Model/Workflow/Workflow.hpp
@@ -173,9 +173,9 @@ protected:
struct WorkflowInfo
{
+ std::filesystem::path Path;
std::string Name;
std::string PathStringCache = Path.string();
- std::filesystem::path Path;
std::unique_ptr<Workflow> LoadFromDisk() const;
};
diff --git a/core/src/Model/fwd.hpp b/core/src/Model/fwd.hpp
index 6fa29c5..09b0c75 100644
--- a/core/src/Model/fwd.hpp
+++ b/core/src/Model/fwd.hpp
@@ -3,6 +3,8 @@
#include "Model/Template/fwd.hpp"
#include "Model/Workflow/fwd.hpp"
+// Assets.hpp
+
// Filter.hpp
class TableRowsFilter;