#include "Base_Table_Model.h" #include "Widget/base/Generate_Mock_Data.h" #include "Renderive/base/global.h" #include "Base_Info.h" #include "Base_Table_Data.h" namespace Psc { struct Row_Info; Pos get_pos(Base_Info** infos, int n, int space, int pos, int margin) { int cur_line_pos = margin; int last_i = 0; for (int i = 0; i < n - 1; ++i) { auto cur = infos[i]; if (cur->hide) { continue; } int step = cur->len + space; if (cur_line_pos + step > pos) { return {i, cur_line_pos, pos - cur_line_pos}; } cur_line_pos += step; last_i = i; } return {std::max(0, n - 1), cur_line_pos, pos - cur_line_pos}; } Base_Table_Model::Base_Table_Model() {} Row_Info* Base_Table_Model::create_row_info(int h) { return new Row_Info(h, ""); } Col_Info* Base_Table_Model::create_col_info(int w) { return new Col_Info(w, ""); } // 核心位置计算 int Memory_Table_Model::cell_x(int index) { if (index == 0) return 0; int ret = 0; for (int i = 0; i < index; i++) { auto cur = col_info_list[i]; if (cur->hide) continue; ret += cur->len + col_space; } return ret; } int Memory_Table_Model::cell_y(int index) { if (index == 0) return 0; int ret = 0; for (int i = 0; i < index; i++) { auto cur = row_info_list[i]; if (cur->hide) continue; ret += cur->len + row_space; } return ret; } int Memory_Table_Model::row_span_len(int row, int row_span) { int ret = -row_space; for (int i = 0; i < row_span; i++) { auto cur = row_info_list[row + i]; if (cur->hide) continue; ret += cur->len + row_space; } return ret; } int Memory_Table_Model::col_span_len(int col, int col_span) { int ret = -col_space; for (int i = 0; i < col_span; i++) { auto cur = col_info_list[col + i]; if (cur->hide) continue; ret += cur->len + col_space; } return ret; } Pos Memory_Table_Model::get_col(int x) { return get_pos((Base_Info**)col_info_list.data(), col_info_list.size(), col_space, x, 0); } Pos Memory_Table_Model::get_row(int y) { return get_pos((Base_Info**)row_info_list.data(), row_info_list.size(), row_space, y, 0); } std::vector> exchange_row_col(const std::vector>& data) { std::vector> ret; int m = data.size(); int n = data.front().size(); for (int i = 0; i < n; ++i) { std::vector t; for (int j = 0; j < m; ++j) { t.push_back(data[j][i]); } ret.push_back(t); } return ret; }; enum Cell_Type { Merge_head, Merge_Cell, Normal }; Cell_Type cell_type(const std::vector>& data, int col, int row) { auto that = data[col][row]; if (that->parent != that) return Merge_Cell; if (data[col + 1][row]->parent == that) return Merge_head; if (data[col][row + 1]->parent == that) return Merge_head; return Normal; } Cell_Info Base_Table_Model::get_span(int xi, int yi) { return Cell_Info(xi, yi, col_span_len(xi, 1), row_span_len(yi, 1)); } Find_Ret Base_Table_Model::find_parent(Base_Table_Data* parent, int xi, int yi) { return Find_Ret(xi, yi); } void Memory_Table_Model::split(int row, int col, int row_span, int col_span) { for (int i = 0; i < col_span; ++i) { for (int j = 0; j < row_span; ++j) { auto cur = data[col + i][row + j]; cur->parent = cur; } } } void Memory_Table_Model::merge(int row, int col, int row_span, int col_span) { auto start = data[col][row]; for (int i = 0; i < row_span; ++i) { for (int j = 0; j < col_span; ++j) { if (i == 0 && j == 0) continue; int cur_row = row + i; int cur_col = col + j; auto cur = data[cur_col][cur_row]; cur->parent = start; } } } // parent 是复刻他上一行的parent bool Memory_Table_Model::insert_row(int pos, const std::vector& infos, const std::vector>& d, Edge_Expand_Type t) { int col_num = col_info_list.size(); int insert_row_num = infos.size(); if (!d.empty() && d.front().size() != col_num) { qDebug() << VAR_QSTR_2(d.front().size(), col_num) << " " << QLOG_POS; return false; } // 行结构转列结构 auto insert_col_list = exchange_row_col(d); for (int col = 0; col < col_num; ++col) { Base_Table_Data* prev = nullptr; Base_Table_Data* next = nullptr; Base_Table_Data* par = nullptr; int row_num = total_row(); if (pos - 1 > 0 && pos - 1 < row_num) { prev = data[col][pos - 1]; } if (pos < row_num) { next = data[col][pos]; } if (t == Edge_Expand_Type::Positive) { if (prev && prev->parent != prev) { par = prev->parent; } } else if (t == Edge_Expand_Type::Negative) { if (next && next->parent != next) { par = next->parent; } } else if (t == Edge_Expand_Type::None) { if (next && prev && prev->parent == next->parent) { par = prev->parent; } } for (int j = 0; j < insert_row_num; ++j) { auto cur = insert_col_list[col][j]; cur->parent = par ? par : cur; } data[col].insert(data[col].begin() + pos, insert_col_list[col].begin(), insert_col_list[col].end()); } row_info_list.insert(row_info_list.begin() + pos, infos.begin(), infos.end()); return true; } bool Memory_Table_Model::insert_col(int pos, const std::vector& infos, const std::vector>& d, Edge_Expand_Type t) { int row_num = row_info_list.size(); int insert_col_num = infos.size(); if (!d.empty() && d.front().size() != row_num) { qDebug() << VAR_QSTR_2(d.front().size(), row_num) << " " << QLOG_POS; return false; } for (int row = 0; row < row_num; ++row) { Base_Table_Data* prev = nullptr; Base_Table_Data* next = nullptr; Base_Table_Data* par = nullptr; int col_num = total_col(); if (pos - 1 > 0 && pos - 1 < col_num) { prev = data[pos - 1][row]; } if (pos < col_num) { next = data[pos][row]; } if (t == Edge_Expand_Type::Positive) { if (prev && prev->parent != prev) { par = prev->parent; } } else if (t == Edge_Expand_Type::Negative) { if (next && next->parent != next) { par = next->parent; } } else if (t == Edge_Expand_Type::None) { if (next && prev && prev->parent == next->parent) { par = prev->parent; } } for (int col = 0; col < insert_col_num; ++col) { auto cur = d[col][row]; cur->parent = par ? par : cur; } } data.insert(data.begin() + pos, d.begin(), d.end()); col_info_list.insert(col_info_list.begin() + pos, infos.begin(), infos.end()); return true; } bool Memory_Table_Model::remove_row(int pos, int num) { if (pos + num >= row_info_list.size()) { qDebug() << VAR_QSTR_3(pos, num, row_info_list.size()) << " " << QLOG_POS; return false; } for (auto& col : data) { for (auto item = col.begin() + pos; item != col.begin() + pos + num; ++item) delete *item; col.erase(col.begin() + pos, col.begin() + pos + num); } for (int i = 0; i < num; ++i) { delete row_info_list[pos + i]; } row_info_list.erase(row_info_list.begin() + pos, row_info_list.begin() + pos + num); return true; } bool Memory_Table_Model::remove_col(int pos, int num) { if (pos + num >= col_info_list.size()) { qDebug() << VAR_QSTR_3(pos, num, col_info_list.size()) << " " << QLOG_POS; return false; } for (auto column = data.begin() + pos; column != data.begin() + pos + num; ++column) { for (auto* item : *column) delete item; } data.erase(data.begin() + pos, data.begin() + pos + num); for (int i = 0; i < num; ++i) { delete col_info_list[pos + i]; } col_info_list.erase(col_info_list.begin() + pos, col_info_list.begin() + pos + num); return true; } Cell_Info Memory_Table_Model::get_span(int xi, int yi) { int col_num = data.size(); int row_num = data.front().size(); Base_Table_Data* that = data[xi][yi]; int col_span = 1; int row_span = 1; int sw = col_info_list[xi]->len; int sh = row_info_list[yi]->len; while (true) { int index = xi + col_span; if (index >= col_num) break; auto cur = data[index][yi]; if (cur->parent != that) { break; } sw += col_info_list[index]->len + col_space; col_span++; } while (true) { int index = yi + row_span; if (index >= row_num) break; auto cur = data[xi][index]; if (cur->parent != that) { break; } sh += row_info_list[index]->len + row_space; row_span++; } return {col_span, row_span, sw, sh}; } Find_Ret Memory_Table_Model::find_parent(Base_Table_Data* parent, int xi, int yi) { int cur_x = xi; int cur_y = yi; if (xi != 0) { while (true) { auto cur = data[cur_x - 1][yi]; if (cur->parent != parent && cur->parent != nullptr) { break; } cur_x--; if (cur_x == 0) break; } } if (yi != 0) { while (true) { auto cur = data[xi][cur_y - 1]; if (cur->parent != parent && cur->parent != nullptr) { break; } cur_y--; if (cur_y == 0) break; } } // qDebug() << "find_parent: " << data[xi][yi]->content << " " << cur_x << " " << cur_y; return {cur_x, cur_y}; } } // namespace Psc