Skip to content

Commit

Permalink
implementing lightweight variant of tables (#2140)
Browse files Browse the repository at this point in the history
  • Loading branch information
giuspen committed Dec 10, 2022
1 parent a9ed5b4 commit 9ed2bd0
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 122 deletions.
37 changes: 10 additions & 27 deletions src/ct/ct_state_machine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,16 @@ CtAnchoredWidget* CtAnchoredWidgetState_Codebox::to_widget(CtMainWin* pCtMainWin
}

// Table
CtAnchoredWidgetState_TableCommon::CtAnchoredWidgetState_TableCommon(CtTableCommon* table)
: CtAnchoredWidgetState{table->getOffset(), table->getJustification()}
, colWidthDefault{table->get_col_width_default()}
, colWidths{table->get_col_widths_raw()}
, currRow{table->current_row()}
, currCol{table->current_column()}
{
table->write_strings_matrix(rows);
}

bool CtAnchoredWidgetState_TableCommon::equal(std::shared_ptr<CtAnchoredWidgetState> state)
{
CtAnchoredWidgetState_TableCommon* other_state = dynamic_cast<CtAnchoredWidgetState_TableCommon*>(state.get());
Expand All @@ -176,33 +186,6 @@ bool CtAnchoredWidgetState_TableCommon::equal(std::shared_ptr<CtAnchoredWidgetSt
rows == other_state->rows;
}

CtAnchoredWidgetState_Table::CtAnchoredWidgetState_Table(CtTable* table)
: CtAnchoredWidgetState_TableCommon{table}
{
for (const auto& row : table->get_table_matrix()) {
rows.push_back(std::vector<Glib::ustring>{});
for (void* cell : row) {
rows.back().push_back(static_cast<CtTextCell*>(cell)->get_text_content());
}
}
}

CtAnchoredWidgetState_TableLight::CtAnchoredWidgetState_TableLight(CtTableLight* table)
: CtAnchoredWidgetState_TableCommon{table}
{
auto f_action = [this, table](const Gtk::TreeIter& treeIter)->bool{
Gtk::TreeRow treeRow = *treeIter;
rows.push_back(std::vector<Glib::ustring>{});
const size_t numCols = table->get_num_columns();
const CtTableLightColumns& cols = table->get_columns();
for (size_t c = 0u; c < numCols; ++c) {
rows.back().push_back(treeRow[cols.columnsText.at(c)]);
}
return false; /* to continue */
};
table->exec_action_on_every_tree_iter(f_action);
}

CtAnchoredWidget* CtAnchoredWidgetState_Table::to_widget(CtMainWin* pCtMainWin)
{
CtTableMatrix tableMatrix;
Expand Down
16 changes: 7 additions & 9 deletions src/ct/ct_state_machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,7 @@ class CtAnchoredWidgetState_Codebox : public CtAnchoredWidgetState

struct CtAnchoredWidgetState_TableCommon : public CtAnchoredWidgetState
{
CtAnchoredWidgetState_TableCommon(CtTableCommon* table)
: CtAnchoredWidgetState{table->getOffset(), table->getJustification()}
, colWidthDefault{table->get_col_width_default()}
, colWidths{table->get_col_widths_raw()}
, currRow{table->current_row()}
, currCol{table->current_column()}
{}
CtAnchoredWidgetState_TableCommon(CtTableCommon* table);

bool equal(std::shared_ptr<CtAnchoredWidgetState> state) override;

Expand All @@ -138,12 +132,16 @@ struct CtAnchoredWidgetState_TableCommon : public CtAnchoredWidgetState
};
struct CtAnchoredWidgetState_TableLight : public CtAnchoredWidgetState_TableCommon
{
CtAnchoredWidgetState_TableLight(CtTableLight* table);
CtAnchoredWidgetState_TableLight(CtTableLight* table)
: CtAnchoredWidgetState_TableCommon{table}
{}
CtAnchoredWidget* to_widget(CtMainWin* pCtMainWin) override;
};
struct CtAnchoredWidgetState_Table : public CtAnchoredWidgetState_TableCommon
{
CtAnchoredWidgetState_Table(CtTable* table);
CtAnchoredWidgetState_Table(CtTable* table)
: CtAnchoredWidgetState_TableCommon{table}
{}
CtAnchoredWidget* to_widget(CtMainWin* pCtMainWin) override;
};

Expand Down
100 changes: 51 additions & 49 deletions src/ct/ct_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,42 @@ CtTableCommon::CtTableCommon(CtMainWin* pCtMainWin,
{
}

void CtTableCommon::to_xml(xmlpp::Element* p_node_parent, const int offset_adjustment, CtStorageCache*)
{
std::vector<std::vector<Glib::ustring>> rows;
write_strings_matrix(rows);
CtXmlHelper::table_to_xml(p_node_parent, rows, _charOffset+offset_adjustment, _justification, _colWidthDefault, str::join_numbers(_colWidths, ","));
}

bool CtTableCommon::to_sqlite(sqlite3* pDb, const gint64 node_id, const int offset_adjustment, CtStorageCache*)
{
bool retVal{true};
sqlite3_stmt *p_stmt;
if (sqlite3_prepare_v2(pDb, CtStorageSqlite::TABLE_TABLE_INSERT, -1, &p_stmt, nullptr) != SQLITE_OK) {
spdlog::error("{}: {}", CtStorageSqlite::ERR_SQLITE_PREPV2, sqlite3_errmsg(pDb));
retVal = false;
}
else {
xmlpp::Document xml_doc;
xml_doc.create_root_node("table");
xml_doc.get_root_node()->set_attribute("col_widths", str::join_numbers(_colWidths, ","));
_populate_xml_rows_cells(xml_doc.get_root_node());
const std::string table_txt = xml_doc.write_to_string();
sqlite3_bind_int64(p_stmt, 1, node_id);
sqlite3_bind_int64(p_stmt, 2, _charOffset+offset_adjustment);
sqlite3_bind_text(p_stmt, 3, _justification.c_str(), _justification.size(), SQLITE_STATIC);
sqlite3_bind_text(p_stmt, 4, table_txt.c_str(), table_txt.size(), SQLITE_STATIC);
sqlite3_bind_int64(p_stmt, 5, _colWidthDefault); // todo get rid of column min
sqlite3_bind_int64(p_stmt, 6, _colWidthDefault);
if (sqlite3_step(p_stmt) != SQLITE_DONE) {
spdlog::error("{}: {}", CtStorageSqlite::ERR_SQLITE_STEP, sqlite3_errmsg(pDb));
retVal = false;
}
sqlite3_finalize(p_stmt);
}
return retVal;
}

CtTable::CtTable(CtMainWin* pCtMainWin,
CtTableMatrix& tableMatrix,
const int colWidthDefault,
Expand Down Expand Up @@ -96,6 +132,18 @@ CtTable::~CtTable()
}
}

void CtTable::write_strings_matrix(std::vector<std::vector<Glib::ustring>>& rows) const
{
rows.reserve(get_num_rows());
for (const auto& row : get_table_matrix()) {
rows.push_back(std::vector<Glib::ustring>{});
rows.back().reserve(get_num_columns());
for (void* cell : row) {
rows.back().push_back(static_cast<CtTextCell*>(cell)->get_text_content());
}
}
}

void CtTable::_new_text_cell_attach(const size_t rowIdx, const size_t colIdx, CtTextCell* pTextCell)
{
CtTextView& textView = pTextCell->get_text_view();
Expand Down Expand Up @@ -129,20 +177,7 @@ void CtTable::apply_syntax_highlighting(const bool forceReApply)
_apply_styles_to_cells(forceReApply);
}

void CtTable::to_xml(xmlpp::Element* p_node_parent, const int offset_adjustment, CtStorageCache*)
{
std::vector<std::vector<Glib::ustring>> rows;
rows.reserve(_tableMatrix.size());
for (auto& row : _tableMatrix) {
rows.push_back(std::vector<Glib::ustring>());
rows.back().reserve(row.size());
for (void* cell : row) rows.back().push_back(static_cast<CtTextCell*>(cell)->get_text_content());
}

CtXmlHelper::table_to_xml(p_node_parent, rows, _charOffset+offset_adjustment, _justification, _colWidthDefault, str::join_numbers(_colWidths, ","));
}

void CtTable::_populate_xml_rows_cells(xmlpp::Element* p_table_node)
void CtTable::_populate_xml_rows_cells(xmlpp::Element* p_table_node) const
{
auto row_to_xml = [&](const CtTableRow& tableRow) {
xmlpp::Element* p_row_node = p_table_node->add_child("row");
Expand All @@ -153,47 +188,14 @@ void CtTable::_populate_xml_rows_cells(xmlpp::Element* p_table_node)
};

// put header at the end
bool is_header = true;
for (const CtTableRow& tableRow : _tableMatrix)
{
bool is_header{true};
for (const CtTableRow& tableRow : _tableMatrix) {
if (is_header) { is_header = false; continue; }
row_to_xml(tableRow);
}
row_to_xml(_tableMatrix.front());
}

bool CtTable::to_sqlite(sqlite3* pDb, const gint64 node_id, const int offset_adjustment, CtStorageCache*)
{
bool retVal{true};
sqlite3_stmt *p_stmt;
if (sqlite3_prepare_v2(pDb, CtStorageSqlite::TABLE_TABLE_INSERT, -1, &p_stmt, nullptr) != SQLITE_OK)
{
spdlog::error("{}: {}", CtStorageSqlite::ERR_SQLITE_PREPV2, sqlite3_errmsg(pDb));
retVal = false;
}
else
{
xmlpp::Document xml_doc;
xml_doc.create_root_node("table");
xml_doc.get_root_node()->set_attribute("col_widths", str::join_numbers(_colWidths, ","));
_populate_xml_rows_cells(xml_doc.get_root_node());
const std::string table_txt = xml_doc.write_to_string();
sqlite3_bind_int64(p_stmt, 1, node_id);
sqlite3_bind_int64(p_stmt, 2, _charOffset+offset_adjustment);
sqlite3_bind_text(p_stmt, 3, _justification.c_str(), _justification.size(), SQLITE_STATIC);
sqlite3_bind_text(p_stmt, 4, table_txt.c_str(), table_txt.size(), SQLITE_STATIC);
sqlite3_bind_int64(p_stmt, 5, _colWidthDefault); // todo get rid of column min
sqlite3_bind_int64(p_stmt, 6, _colWidthDefault);
if (sqlite3_step(p_stmt) != SQLITE_DONE)
{
spdlog::error("{}: {}", CtStorageSqlite::ERR_SQLITE_STEP, sqlite3_errmsg(pDb));
retVal = false;
}
sqlite3_finalize(p_stmt);
}
return retVal;
}

std::string CtTable::to_csv() const
{
CtCSV::CtStringTable tbl;
Expand Down
38 changes: 20 additions & 18 deletions src/ct/ct_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,18 @@ class CtTableCommon : public CtAnchoredWidget
}
return colWidths;
}
void to_xml(xmlpp::Element* p_node_parent, const int offset_adjustment, CtStorageCache* cache) override;
bool to_sqlite(sqlite3* pDb, const gint64 node_id, const int offset_adjustment, CtStorageCache* cache) override;

virtual size_t current_row() = 0;
virtual size_t current_column() = 0;
virtual void write_strings_matrix(std::vector<std::vector<Glib::ustring>>& rows) const = 0;
virtual size_t get_num_rows() const = 0;
virtual size_t get_num_columns() const = 0;
size_t current_row() const { return _currentRow < get_num_rows() ? _currentRow : 0; }
size_t current_column() const { return _currentColumn < get_num_columns() ? _currentColumn : 0; }

protected:
virtual void _populate_xml_rows_cells(xmlpp::Element* p_table_node) const = 0;

int _colWidthDefault;
CtTableColWidths _colWidths;
size_t _currentRow{0};
Expand Down Expand Up @@ -88,27 +95,24 @@ class CtTableLight : public CtTableCommon
const CtTableColWidths& colWidths,
const size_t currRow = 0,
const size_t currCol = 0);
size_t get_num_rows() const { return _numRows; }
size_t get_num_columns() const { return _numColumns; }
void exec_action_on_every_tree_iter(const Gtk::TreeModel::SlotForeachIter& slot) const;

const CtTableLightColumns& get_columns() const { return *_pColumns; }

void apply_syntax_highlighting(const bool forceReApply) override {}
void to_xml(xmlpp::Element* p_node_parent, const int offset_adjustment, CtStorageCache* cache) override {}
bool to_sqlite(sqlite3* pDb, const gint64 node_id, const int offset_adjustment, CtStorageCache* cache) override {}
void apply_syntax_highlighting(const bool /*forceReApply*/) override {}
void set_modified_false() override {}
CtAnchWidgType get_type() override { return CtAnchWidgType::TableLight; }
std::shared_ptr<CtAnchoredWidgetState> get_state() override;

size_t current_row() override { return _currentRow < _numRows ? _currentRow : 0; }
size_t current_column() override { return _currentColumn < _numColumns ? _currentColumn : 0; }
void write_strings_matrix(std::vector<std::vector<Glib::ustring>>& rows) const override;
size_t get_num_rows() const override { return _pListStore->children().size(); }
size_t get_num_columns() const override { return _pColumns->columnsText.size(); }

protected:
static void _free_matrix(CtTableMatrix& tableMatrix);
void _populate_xml_rows_cells(xmlpp::Element* p_table_node) const override;

std::unique_ptr<CtTableLightColumns> _pColumns;
Gtk::TreeView* _pManagedTreeView;
size_t _numRows;
size_t _numColumns;
Glib::RefPtr<Gtk::ListStore> _pListStore;
};

Expand Down Expand Up @@ -137,8 +141,6 @@ class CtTable : public CtTableCommon
const Glib::ustring& justification);

void apply_syntax_highlighting(const bool forceReApply) override;
void to_xml(xmlpp::Element* p_node_parent, const int offset_adjustment, CtStorageCache* cache) override;
bool to_sqlite(sqlite3* pDb, const gint64 node_id, const int offset_adjustment, CtStorageCache* cache) override;
/**
* @brief Serialise to csv format
* The output CSV excel csv with double quotes around cells and newlines for each record
Expand All @@ -151,9 +153,9 @@ class CtTable : public CtTableCommon

const CtTableMatrix& get_table_matrix() const { return _tableMatrix; }

public:
size_t current_row() override { return _currentRow < _tableMatrix.size() ? _currentRow : 0; }
size_t current_column() override { return _currentColumn < _tableMatrix.front().size() ? _currentColumn : 0; }
void write_strings_matrix(std::vector<std::vector<Glib::ustring>>& rows) const override;
size_t get_num_rows() const override { return _tableMatrix.size(); }
size_t get_num_columns() const override { return _tableMatrix.front().size(); }

void column_add(const size_t afterColIdx);
void column_delete(const size_t colIdx);
Expand All @@ -176,7 +178,7 @@ class CtTable : public CtTableCommon
void _apply_remove_header_style(const bool isApply, CtTextView& textView);

protected:
void _populate_xml_rows_cells(xmlpp::Element* p_table_node);
void _populate_xml_rows_cells(xmlpp::Element* p_table_node) const override;

private:
void _on_populate_popup_cell(Gtk::Menu* menu);
Expand Down
Loading

0 comments on commit 9ed2bd0

Please sign in to comment.