diff options
author | rtk0c <[email protected]> | 2021-05-30 23:00:41 -0700 |
---|---|---|
committer | rtk0c <[email protected]> | 2021-05-30 23:00:41 -0700 |
commit | c90f78df080a9891930ee346b0ad87498ba5b697 (patch) | |
tree | c4f4c475086337e25cbb985625423591c47310e1 /core/src/Model | |
parent | 088da97531935a61870ecada10f06b9b9a8255d1 (diff) |
Initial work on templates UI
Diffstat (limited to 'core/src/Model')
-rw-r--r-- | core/src/Model/Project.cpp | 134 | ||||
-rw-r--r-- | core/src/Model/Project.hpp | 22 | ||||
-rw-r--r-- | core/src/Model/Template/TableTemplate.cpp | 63 | ||||
-rw-r--r-- | core/src/Model/Template/TableTemplate.hpp | 12 | ||||
-rw-r--r-- | core/src/Model/Template/Template.hpp | 45 | ||||
-rw-r--r-- | core/src/Model/Template/Template_Main.cpp | 5 | ||||
-rw-r--r-- | core/src/Model/Template/Template_RTTI.cpp | 21 | ||||
-rw-r--r-- | core/src/Model/Template/fwd.hpp | 4 | ||||
-rw-r--r-- | core/src/Model/Workflow/Workflow.hpp | 2 | ||||
-rw-r--r-- | core/src/Model/fwd.hpp | 2 |
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; |