Reorganise the tree into business vs frontend as separate directories:
src/core/{domain,imports,app} (was system/, imports/, app/)
src/frontends/tui/ (was tui/ + main.cpp)
tests/tui/ (the FTXUI-coupled helper test)
All cross-dir #include paths rewritten; same-dir includes untouched.
CMake: essim_core is the frontend-agnostic business library — links libzip,
pugixml and bsdl, NO GUI toolkit. Each frontend is a self-contained
src/frontends/<name>/ (own CMakeLists, toolkit, main.cpp) that links
essim_core, selected with -DESSIM_FRONTEND=<name> (default tui; 'none' = core +
tests only, no toolkit fetched). FTXUI moved into the tui frontend. Tests are
split: essim_tests links essim_core (no FTXUI), essim_tui_tests links essim_tui.
Verified: default tui build green (ctest 2/2); ESSIM_FRONTEND=none builds the
core + tests with FTXUI never fetched and no `essim` binary.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
63 lines
2.0 KiB
C++
63 lines
2.0 KiB
C++
#ifndef _IMPORTS_ODS_WRITER_HPP_
|
|
#define _IMPORTS_ODS_WRITER_HPP_
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
// Minimal OpenDocument Spreadsheet (.ods) writer. Backed by libzip +
|
|
// pugixml (already in the build for the ODS *importer*). Produces
|
|
// multi-sheet workbooks; each sheet is a 2-D grid of string cells.
|
|
//
|
|
// Usage:
|
|
// OdsWriter w;
|
|
// auto *s1 = w.add_sheet("connection A");
|
|
// s1->set(0, 0, "header1");
|
|
// s1->set(0, 1, "header2");
|
|
// s1->set(1, 0, "value");
|
|
// std::string err;
|
|
// bool ok = w.save("out.ods", err);
|
|
//
|
|
// Limitations (intentional, the format is huge):
|
|
// - string cells only (no numbers / dates / formulas)
|
|
// - no styles, no merged cells, no formatting
|
|
// - a single empty row is emitted when a row has at least one set cell;
|
|
// trailing empty rows are skipped.
|
|
|
|
class OdsSheet {
|
|
public:
|
|
explicit OdsSheet(std::string name) : name_(std::move(name)) {}
|
|
|
|
void set(int row, int col, std::string value);
|
|
|
|
// Index of the row that holds the column headers — gets the bold/grey
|
|
// style, anchors the freeze, and is the first row of the auto-filter
|
|
// range. Rows above it are rendered un-styled (a place for free-form
|
|
// metadata such as the connection name). Default 0 = first row is
|
|
// the header (no meta block).
|
|
void set_header_row(int r) { header_row_ = r; }
|
|
int header_row() const { return header_row_; }
|
|
|
|
const std::string &name() const { return name_; }
|
|
int rows() const { return (int)cells_.size(); }
|
|
int cols() const;
|
|
const std::string &cell(int row, int col) const;
|
|
|
|
private:
|
|
std::string name_;
|
|
int header_row_ = 0;
|
|
// Row-major sparse storage: cells_[r][c] = value. Rows/cols are grown
|
|
// lazily on set().
|
|
std::vector<std::vector<std::string>> cells_;
|
|
};
|
|
|
|
class OdsWriter {
|
|
public:
|
|
OdsSheet *add_sheet(const std::string &name);
|
|
bool save(const std::string &path, std::string &error) const;
|
|
|
|
private:
|
|
std::vector<OdsSheet> sheets_;
|
|
};
|
|
|
|
#endif // _IMPORTS_ODS_WRITER_HPP_
|