318 lines
10 KiB
C++
318 lines
10 KiB
C++
#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<std::vector<Base_Table_Data*>> exchange_row_col(const std::vector<std::vector<Base_Table_Data*>>& data) {
|
|
std::vector<std::vector<Base_Table_Data*>> ret;
|
|
int m = data.size();
|
|
int n = data.front().size();
|
|
for (int i = 0; i < n; ++i) {
|
|
std::vector<Base_Table_Data*> 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<std::vector<Base_Table_Data*>>& 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<Row_Info*>& infos, const std::vector<std::vector<Base_Table_Data*>>& 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<Col_Info*>& infos, const std::vector<std::vector<Base_Table_Data*>>& 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
|