Files
GostGenerator/model/simplelisttablemodel.cpp
T
2026-09-02 12:48:03 +03:00

379 lines
11 KiB
C++

#include "simplelisttablemodel.h"
#include "componentmodel.h"
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
// Регистрируем структуры для работы с QVariant
Q_DECLARE_METATYPE(SimpleListCellData)
Q_DECLARE_METATYPE(SimpleListRowData)
// Статические константы
const QStringList SimpleListTableModel::DEFAULT_HEADERS = QStringList() << "Поз.обозначение" << "Наименование" << "Кол.";
SimpleListTableModel::SimpleListTableModel(QObject *parent)
: QAbstractTableModel(parent)
, m_techReservePercent(10)
{
qDebug() << "SimpleListTableModel::SimpleListTableModel: Создана модель";
}
int SimpleListTableModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return m_rows.size();
}
int SimpleListTableModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return COLUMN_COUNT;
}
QVariant SimpleListTableModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() >= m_rows.size())
return QVariant();
const SimpleListRowData &row = m_rows[index.row()];
if (role == Qt::DisplayRole || role == Qt::EditRole) {
switch (index.column()) {
case 0: return row.designator.value;
case 1: return row.name.value;
case 2: return row.quantity.value;
default: return QVariant();
}
} else if (role == Qt::UserRole) {
// Возвращаем структуру ячейки для дополнительной информации
switch (index.column()) {
case 0: return QVariant::fromValue(row.designator);
case 1: return QVariant::fromValue(row.name);
case 2: return QVariant::fromValue(row.quantity);
default: return QVariant();
}
}
return QVariant();
}
QVariant SimpleListTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal) {
if (section < DEFAULT_HEADERS.size()) {
QString header = DEFAULT_HEADERS[section];
// Для столбца "Кол." (индекс 2) добавляем процент тех запаса
if (section == 2) {
header = QString("Кол-во (+%1%)").arg(m_techReservePercent);
}
return header;
}
} else {
return section + 1;
}
return QVariant();
}
bool SimpleListTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid() || index.row() >= m_rows.size() || role != Qt::EditRole)
return false;
if (!canEditRow(index.row())) {
qDebug() << "SimpleListTableModel::setData: Строка" << index.row() << "не может быть отредактирована";
return false;
}
SimpleListRowData &row = m_rows[index.row()];
QString newValue = value.toString();
switch (index.column()) {
case 0:
row.designator.value = newValue;
row.designator.isAutoGenerated = false;
row.designator.isEmpty = newValue.isEmpty();
break;
case 1:
row.name.value = newValue;
row.name.isAutoGenerated = false;
row.name.isEmpty = newValue.isEmpty();
break;
case 2:
row.quantity.value = newValue;
row.quantity.isAutoGenerated = false;
row.quantity.isEmpty = newValue.isEmpty();
break;
default:
return false;
}
// Обновляем флаг isEmpty для строки
updateRowEmptyStatus(index.row());
emit dataChanged(index, index, QVector<int>() << role);
return true;
}
Qt::ItemFlags SimpleListTableModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::NoItemFlags;
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
// Разрешаем редактирование только для редактируемых строк
if (canEditRow(index.row())) {
flags |= Qt::ItemIsEditable;
}
return flags;
}
void SimpleListTableModel::addRow(const SimpleListRowData &rowData)
{
beginInsertRows(QModelIndex(), m_rows.size(), m_rows.size());
m_rows.append(rowData);
endInsertRows();
emit modelDataChanged();
}
void SimpleListTableModel::insertRow(int position, const SimpleListRowData &rowData)
{
if (position < 0 || position > m_rows.size())
return;
beginInsertRows(QModelIndex(), position, position);
m_rows.insert(position, rowData);
endInsertRows();
emit modelDataChanged();
}
void SimpleListTableModel::removeRow(int row)
{
if (row < 0 || row >= m_rows.size())
return;
beginRemoveRows(QModelIndex(), row, row);
m_rows.removeAt(row);
endRemoveRows();
emit modelDataChanged();
}
void SimpleListTableModel::clear()
{
qDebug() << "SimpleListTableModel::clear: Очищаем таблицу, строк:" << m_rows.size();
if (m_rows.isEmpty()) {
return;
}
beginResetModel();
m_rows.clear();
endResetModel();
emit modelDataChanged();
}
void SimpleListTableModel::setComponents(const QList<ComponentModel*> &components)
{
qDebug() << "SimpleListTableModel::setComponents: Получено" << components.size() << "компонентов";
// Проверяем компоненты на null
QList<ComponentModel*> validComponents;
for (ComponentModel *component : components) {
if (component) {
validComponents.append(component);
}
}
m_components = validComponents;
qDebug() << "SimpleListTableModel::setComponents: Сохранено" << m_components.size() << "валидных компонентов";
}
QByteArray SimpleListTableModel::saveToDatabase() const
{
qDebug() << "SimpleListTableModel::saveToDatabase: Начинаем сохранение в БД";
qDebug() << "SimpleListTableModel::saveToDatabase: Количество строк:" << m_rows.size();
QJsonObject root;
QJsonArray rowsArray;
for (const SimpleListRowData &row : m_rows) {
QJsonObject rowObj;
// Сохраняем данные ячеек
QJsonObject designatorObj;
designatorObj["value"] = row.designator.value;
designatorObj["isAutoGenerated"] = row.designator.isAutoGenerated;
designatorObj["isEmpty"] = row.designator.isEmpty;
rowObj["designator"] = designatorObj;
QJsonObject nameObj;
nameObj["value"] = row.name.value;
nameObj["isAutoGenerated"] = row.name.isAutoGenerated;
nameObj["isEmpty"] = row.name.isEmpty;
rowObj["name"] = nameObj;
QJsonObject quantityObj;
quantityObj["value"] = row.quantity.value;
quantityObj["isAutoGenerated"] = row.quantity.isAutoGenerated;
quantityObj["isEmpty"] = row.quantity.isEmpty;
rowObj["quantity"] = quantityObj;
rowObj["isEmpty"] = row.isEmpty;
rowsArray.append(rowObj);
}
root["rows"] = rowsArray;
QJsonDocument doc(root);
QByteArray result = doc.toJson();
qDebug() << "SimpleListTableModel::saveToDatabase: Сохранение завершено, размер данных:" << result.size() << "байт";
return result;
}
void SimpleListTableModel::loadFromDatabase(const QByteArray &data)
{
qDebug() << "SimpleListTableModel::loadFromDatabase: Начинаем загрузку из БД, размер данных:" << data.size();
QJsonDocument doc = QJsonDocument::fromJson(data);
if (!doc.isObject()) {
qDebug() << "SimpleListTableModel::loadFromDatabase: Ошибка парсинга JSON";
return;
}
QJsonObject root = doc.object();
// Загружаем строки
clear();
if (root.contains("rows")) {
QJsonArray rowsArray = root["rows"].toArray();
for (const QJsonValue &value : rowsArray) {
QJsonObject rowObj = value.toObject();
SimpleListRowData row;
if (rowObj.contains("designator")) {
QJsonObject desObj = rowObj["designator"].toObject();
row.designator = SimpleListCellData(
desObj["value"].toString(),
desObj["isAutoGenerated"].toBool(),
desObj["isEmpty"].toBool()
);
}
if (rowObj.contains("name")) {
QJsonObject nameObj = rowObj["name"].toObject();
row.name = SimpleListCellData(
nameObj["value"].toString(),
nameObj["isAutoGenerated"].toBool(),
nameObj["isEmpty"].toBool()
);
}
if (rowObj.contains("quantity")) {
QJsonObject qtyObj = rowObj["quantity"].toObject();
row.quantity = SimpleListCellData(
qtyObj["value"].toString(),
qtyObj["isAutoGenerated"].toBool(),
qtyObj["isEmpty"].toBool()
);
}
row.isEmpty = rowObj["isEmpty"].toBool();
addRow(row);
}
}
qDebug() << "SimpleListTableModel::loadFromDatabase: Загружено строк:" << m_rows.size();
}
QString SimpleListTableModel::getDocumentTitle() const
{
return "Список элементов";
}
QString SimpleListTableModel::getDocumentType() const
{
return "SimpleList";
}
void SimpleListTableModel::addEmptyRow()
{
SimpleListRowData emptyRow = createEmptyRow();
addRow(emptyRow);
}
void SimpleListTableModel::addEmptyRowAt(int position)
{
SimpleListRowData emptyRow = createEmptyRow();
insertRow(position, emptyRow);
}
SimpleListRowData SimpleListTableModel::createEmptyRow() const
{
SimpleListRowData row;
row.isEmpty = false;
row.designator = SimpleListCellData("", false, true);
row.name = SimpleListCellData("", false, true);
row.quantity = SimpleListCellData("", false, true);
return row;
}
bool SimpleListTableModel::canEditRow(int row) const
{
if (row < 0 || row >= m_rows.size())
return false;
return true;
}
void SimpleListTableModel::updateRowEmptyStatus(int row)
{
if (row < 0 || row >= m_rows.size())
return;
SimpleListRowData &rowData = m_rows[row];
// Проверяем, пустые ли все ячейки
bool allEmpty = rowData.designator.value.isEmpty() &&
rowData.name.value.isEmpty() &&
rowData.quantity.value.isEmpty();
// Обновляем флаг isEmpty для строки
if (rowData.isEmpty != allEmpty) {
rowData.isEmpty = allEmpty;
}
}
SimpleListCellData SimpleListTableModel::createCellData(const QString &value, bool isAuto, bool isEmpty)
{
return SimpleListCellData(value, isAuto, isEmpty);
}
void SimpleListTableModel::setTechReservePercent(int percent)
{
if (m_techReservePercent != percent) {
m_techReservePercent = percent;
// Обновляем заголовок столбца количества
emit headerDataChanged(Qt::Horizontal, 2, 2);
}
}
int SimpleListTableModel::getTechReservePercent() const
{
return m_techReservePercent;
}