2083 lines
110 KiB
C++
2083 lines
110 KiB
C++
#include "documentprocessor.h"
|
|
#include "../model/perechentablemodel.h"
|
|
#include "../model/specificationpcbtablemodel.h"
|
|
#include "../model/specificationtablemodel.h"
|
|
#include "../model/vedomosttablemodel.h"
|
|
#include "../model/pcbmaterialmodel.h"
|
|
#include "columnsettingsdialog.h"
|
|
#include "cellsettingsdialog.h"
|
|
#include "../controller/maincontroller.h"
|
|
#include <QStandardItemModel>
|
|
#include <QHeaderView>
|
|
|
|
// Регистрируем метатипы для работы с QVariant
|
|
// Примечание: SpecificationPCBCellData уже объявлен в specificationpcbtablemodel.h
|
|
Q_DECLARE_METATYPE(PerechenCellData)
|
|
Q_DECLARE_METATYPE(SpecificationCellData)
|
|
Q_DECLARE_METATYPE(VedomostCellData)
|
|
|
|
#include <QFileDialog>
|
|
#include <QMessageBox>
|
|
#include <QDebug>
|
|
#include <QVector>
|
|
#include <QMenu>
|
|
#include <QList>
|
|
#include <algorithm>
|
|
|
|
// DocumentProcessor
|
|
DocumentProcessor::DocumentProcessor(QObject *parent)
|
|
: QObject(parent)
|
|
{
|
|
}
|
|
|
|
// PerechenProcessor
|
|
PerechenProcessor::PerechenProcessor(QObject *parent)
|
|
: DocumentProcessor(parent)
|
|
, m_controller(new PerechenTableController(this))
|
|
{
|
|
}
|
|
|
|
PerechenProcessor::~PerechenProcessor()
|
|
{
|
|
// m_controller удалится автоматически, так как он является дочерним объектом
|
|
}
|
|
|
|
void PerechenProcessor::processComponents(const QList<ComponentModel*> &components)
|
|
{
|
|
qDebug() << "PerechenProcessor::processComponents: Получено" << components.size() << "компонентов";
|
|
// Передаем компоненты в контроллер
|
|
if (m_controller) {
|
|
m_controller->setComponents(components);
|
|
}
|
|
}
|
|
|
|
void PerechenProcessor::processProjectParams(const QMap<QString, QString> ¶ms)
|
|
{
|
|
qDebug() << "PerechenProcessor::processProjectParams: Получено" << params.size() << "параметров";
|
|
// Пока не используем параметры проекта для Perechen
|
|
}
|
|
|
|
QTableView* PerechenProcessor::createTableView()
|
|
{
|
|
QTableView *tableView = new QTableView();
|
|
if (m_controller) {
|
|
// НЕ генерируем таблицу автоматически - только отображаем существующую модель
|
|
qDebug() << "PerechenProcessor::createTableView: Отображаем существующую модель без генерации";
|
|
|
|
tableView->setModel(m_controller->getTableModel());
|
|
|
|
// Настройка растягивания столбцов для заполнения всего виджета
|
|
QHeaderView *horizontalHeader = tableView->horizontalHeader();
|
|
|
|
// Отключаем автоматическое изменение размера по содержимому
|
|
horizontalHeader->setStretchLastSection(false);
|
|
|
|
// Устанавливаем режимы для каждого столбца - все интерактивные (изменяемые по ширине)
|
|
horizontalHeader->setSectionResizeMode(0, QHeaderView::Interactive); // Поз.обозначение
|
|
horizontalHeader->setSectionResizeMode(1, QHeaderView::Interactive); // Наименование
|
|
horizontalHeader->setSectionResizeMode(2, QHeaderView::Interactive); // Кол.
|
|
horizontalHeader->setSectionResizeMode(3, QHeaderView::Interactive); // Примечание
|
|
|
|
// Устанавливаем начальные размеры для столбцов
|
|
horizontalHeader->resizeSection(0, 100); // Поз.обозначение - 100px
|
|
horizontalHeader->resizeSection(1, 200); // Наименование - 200px
|
|
horizontalHeader->resizeSection(2, 60); // Кол. - 60px
|
|
horizontalHeader->resizeSection(3, 150); // Примечание - 150px
|
|
|
|
// Настройка вертикального заголовка
|
|
QHeaderView *verticalHeader = tableView->verticalHeader();
|
|
verticalHeader->setDefaultSectionSize(25); // Устанавливаем высоту строки
|
|
verticalHeader->setSectionResizeMode(QHeaderView::Fixed);
|
|
|
|
// Принудительно обновляем размеры столбцов
|
|
//horizontalHeader->resizeSections();
|
|
|
|
qDebug() << "PerechenProcessor::createTableView: Настроено растягивание столбцов";
|
|
} else {
|
|
// Если контроллер не установлен, создаем временную модель для корректной настройки заголовков
|
|
QStandardItemModel *tempModel = new QStandardItemModel(tableView);
|
|
QStringList headers;
|
|
headers << "Поз.обозначение" << "Наименование" << "Кол." << "Примечание";
|
|
tempModel->setHorizontalHeaderLabels(headers);
|
|
|
|
// Устанавливаем временную модель для корректной настройки заголовков
|
|
tableView->setModel(tempModel);
|
|
|
|
// Настройка растягивания столбцов для заполнения всего виджета
|
|
QHeaderView *horizontalHeader = tableView->horizontalHeader();
|
|
|
|
// Отключаем автоматическое изменение размера по содержимому
|
|
horizontalHeader->setStretchLastSection(false);
|
|
|
|
// Устанавливаем режимы для каждого столбца - все интерактивные (изменяемые по ширине)
|
|
horizontalHeader->setSectionResizeMode(0, QHeaderView::Interactive); // Поз.обозначение
|
|
horizontalHeader->setSectionResizeMode(1, QHeaderView::Interactive); // Наименование
|
|
horizontalHeader->setSectionResizeMode(2, QHeaderView::Interactive); // Кол.
|
|
horizontalHeader->setSectionResizeMode(3, QHeaderView::Interactive); // Примечание
|
|
|
|
// Устанавливаем начальные размеры для столбцов
|
|
horizontalHeader->resizeSection(0, 100); // Поз.обозначение - 100px
|
|
horizontalHeader->resizeSection(1, 200); // Наименование - 200px
|
|
horizontalHeader->resizeSection(2, 60); // Кол. - 60px
|
|
horizontalHeader->resizeSection(3, 150); // Примечание - 150px
|
|
|
|
// Настройка вертикального заголовка
|
|
QHeaderView *verticalHeader = tableView->verticalHeader();
|
|
verticalHeader->setDefaultSectionSize(25); // Устанавливаем высоту строки
|
|
verticalHeader->setSectionResizeMode(QHeaderView::Fixed);
|
|
|
|
qDebug() << "PerechenProcessor::createTableView: Создана временная модель для настройки заголовков";
|
|
}
|
|
return tableView;
|
|
}
|
|
|
|
void PerechenProcessor::setColumnMappings(const QStringList &mappings)
|
|
{
|
|
if (m_controller) {
|
|
m_controller->setColumnMappings(mappings);
|
|
}
|
|
}
|
|
|
|
QStringList PerechenProcessor::getColumnMappings() const
|
|
{
|
|
if (m_controller) {
|
|
return m_controller->getColumnMappings();
|
|
}
|
|
return QStringList();
|
|
}
|
|
|
|
QStringList PerechenProcessor::getAvailableProperties() const
|
|
{
|
|
if (m_controller) {
|
|
return m_controller->getAvailableProperties();
|
|
}
|
|
return QStringList();
|
|
}
|
|
|
|
void PerechenProcessor::updateTable()
|
|
{
|
|
qDebug() << "PerechenProcessor::updateTable: Обновляем таблицу по кнопке";
|
|
if (m_controller) {
|
|
m_controller->updateTableFromComponents();
|
|
}
|
|
}
|
|
|
|
void PerechenProcessor::setController(PerechenTableController *controller)
|
|
{
|
|
if (m_controller != controller) {
|
|
qDebug() << "PerechenProcessor::setController: Заменяем контроллер";
|
|
m_controller = controller;
|
|
}
|
|
}
|
|
|
|
void PerechenProcessor::setModel(PerechenTableModel *model)
|
|
{
|
|
if (m_controller && model) {
|
|
qDebug() << "PerechenProcessor::setModel: Устанавливаем модель в контроллер";
|
|
m_controller->setModel(model);
|
|
}
|
|
}
|
|
|
|
// SpecificationProcessor
|
|
SpecificationProcessor::SpecificationProcessor(QObject *parent)
|
|
: DocumentProcessor(parent)
|
|
, m_controller(new SpecificationController(this))
|
|
{
|
|
}
|
|
|
|
|
|
void SpecificationProcessor::processComponents(const QList<ComponentModel*> &components)
|
|
{
|
|
qDebug() << "SpecificationProcessor::processComponents: Получено" << components.size() << "компонентов";
|
|
// Для спецификации материалов компоненты не используются
|
|
}
|
|
|
|
void SpecificationProcessor::processProjectParams(const QMap<QString, QString> ¶ms)
|
|
{
|
|
qDebug() << "SpecificationProcessor::processProjectParams: Получено" << params.size() << "параметров";
|
|
// Пока не используем параметры проекта для Specification
|
|
}
|
|
|
|
QTableView* SpecificationProcessor::createTableView()
|
|
{
|
|
QTableView *tableView = new QTableView();
|
|
if (m_controller) {
|
|
// НЕ генерируем таблицу автоматически - только отображаем существующую модель
|
|
qDebug() << "SpecificationProcessor::createTableView: Отображаем существующую модель без генерации";
|
|
|
|
tableView->setModel(m_controller->getTableModel());
|
|
|
|
// Настройка растягивания столбцов для заполнения всего виджета
|
|
QHeaderView *horizontalHeader = tableView->horizontalHeader();
|
|
|
|
// Отключаем автоматическое изменение размера по содержимому
|
|
horizontalHeader->setStretchLastSection(false);
|
|
|
|
// Устанавливаем режимы для каждого столбца - все интерактивные (изменяемые по ширине)
|
|
horizontalHeader->setSectionResizeMode(0, QHeaderView::Interactive); // Формат
|
|
horizontalHeader->setSectionResizeMode(1, QHeaderView::Interactive); // Зона
|
|
horizontalHeader->setSectionResizeMode(2, QHeaderView::Interactive); // Поз.
|
|
horizontalHeader->setSectionResizeMode(3, QHeaderView::Interactive); // Обозначение
|
|
horizontalHeader->setSectionResizeMode(4, QHeaderView::Interactive); // Наименование
|
|
horizontalHeader->setSectionResizeMode(5, QHeaderView::Interactive); // Кол.
|
|
horizontalHeader->setSectionResizeMode(6, QHeaderView::Interactive); // Примечание
|
|
|
|
// Устанавливаем начальные размеры для столбцов
|
|
horizontalHeader->resizeSection(0, 60); // Формат - 60px
|
|
horizontalHeader->resizeSection(1, 50); // Зона - 50px
|
|
horizontalHeader->resizeSection(2, 80); // Поз. - 80px
|
|
horizontalHeader->resizeSection(3, 150); // Обозначение - 150px
|
|
horizontalHeader->resizeSection(4, 200); // Наименование - 200px
|
|
horizontalHeader->resizeSection(5, 60); // Кол. - 60px
|
|
horizontalHeader->resizeSection(6, 150); // Примечание - 150px
|
|
|
|
// Столбец 4 (Наименование) в режиме Stretch займет оставшееся пространство
|
|
|
|
// Настройка вертикального заголовка
|
|
QHeaderView *verticalHeader = tableView->verticalHeader();
|
|
verticalHeader->setDefaultSectionSize(25); // Устанавливаем высоту строки
|
|
verticalHeader->setSectionResizeMode(QHeaderView::Fixed);
|
|
|
|
qDebug() << "SpecificationProcessor::createTableView: Настроено растягивание столбцов";
|
|
} else {
|
|
// Если контроллер не установлен, создаем временную модель для корректной настройки заголовков
|
|
QStandardItemModel *tempModel = new QStandardItemModel(tableView);
|
|
QStringList headers;
|
|
headers << "Формат" << "Зона" << "Позиция" << "Обозначение" << "Наименование" << "Кол." << "Примечание";
|
|
tempModel->setHorizontalHeaderLabels(headers);
|
|
|
|
// Устанавливаем временную модель для корректной настройки заголовков
|
|
tableView->setModel(tempModel);
|
|
|
|
// Настройка растягивания столбцов для заполнения всего виджета
|
|
QHeaderView *horizontalHeader = tableView->horizontalHeader();
|
|
|
|
// Отключаем автоматическое изменение размера по содержимому
|
|
horizontalHeader->setStretchLastSection(false);
|
|
|
|
// Устанавливаем режимы для каждого столбца - все интерактивные (изменяемые по ширине)
|
|
horizontalHeader->setSectionResizeMode(0, QHeaderView::Interactive); // Формат
|
|
horizontalHeader->setSectionResizeMode(1, QHeaderView::Interactive); // Зона
|
|
horizontalHeader->setSectionResizeMode(2, QHeaderView::Interactive); // Позиция
|
|
horizontalHeader->setSectionResizeMode(3, QHeaderView::Interactive); // Обозначение
|
|
horizontalHeader->setSectionResizeMode(4, QHeaderView::Interactive); // Наименование
|
|
horizontalHeader->setSectionResizeMode(5, QHeaderView::Interactive); // Кол.
|
|
horizontalHeader->setSectionResizeMode(6, QHeaderView::Interactive); // Примечание
|
|
|
|
// Устанавливаем начальные размеры для столбцов
|
|
horizontalHeader->resizeSection(0, 60); // Формат - 60px
|
|
horizontalHeader->resizeSection(1, 50); // Зона - 50px
|
|
horizontalHeader->resizeSection(2, 80); // Позиция - 80px
|
|
horizontalHeader->resizeSection(3, 120); // Обозначение - 120px
|
|
horizontalHeader->resizeSection(4, 200); // Наименование - 200px
|
|
horizontalHeader->resizeSection(5, 60); // Кол. - 60px
|
|
horizontalHeader->resizeSection(6, 150); // Примечание - 150px
|
|
|
|
qDebug() << "SpecificationProcessor::createTableView: Создана временная модель для настройки заголовков";
|
|
}
|
|
|
|
return tableView;
|
|
}
|
|
|
|
void SpecificationProcessor::setColumnMappings(const QStringList &mappings)
|
|
{
|
|
if (m_controller) {
|
|
m_controller->setColumnMappings(mappings);
|
|
}
|
|
}
|
|
|
|
QStringList SpecificationProcessor::getColumnMappings() const
|
|
{
|
|
if (m_controller) {
|
|
return m_controller->getColumnMappings();
|
|
}
|
|
return QStringList();
|
|
}
|
|
|
|
QStringList SpecificationProcessor::getAvailableProperties() const
|
|
{
|
|
if (m_controller) {
|
|
return m_controller->getAvailableProperties();
|
|
}
|
|
return QStringList();
|
|
}
|
|
|
|
void SpecificationProcessor::updateTable()
|
|
{
|
|
if (m_controller) {
|
|
m_controller->updateTableFromMaterials();
|
|
}
|
|
}
|
|
|
|
void SpecificationProcessor::setController(SpecificationController *controller)
|
|
{
|
|
if (m_controller != controller) {
|
|
m_controller = controller;
|
|
qDebug() << "SpecificationProcessor::setController: Контроллер заменен";
|
|
}
|
|
}
|
|
|
|
void SpecificationProcessor::setModel(SpecificationTableModel *model)
|
|
{
|
|
if (m_controller) {
|
|
m_controller->setModel(model);
|
|
}
|
|
}
|
|
|
|
// SpecificationPCBProcessor
|
|
SpecificationPCBProcessor::SpecificationPCBProcessor(QObject *parent)
|
|
: DocumentProcessor(parent)
|
|
, m_controller(nullptr)
|
|
{
|
|
}
|
|
|
|
SpecificationPCBProcessor::~SpecificationPCBProcessor()
|
|
{
|
|
// m_controller удалится автоматически, так как он является дочерним объектом
|
|
}
|
|
|
|
void SpecificationPCBProcessor::processComponents(const QList<ComponentModel*> &components)
|
|
{
|
|
qDebug() << "SpecificationPCBProcessor::processComponents: Получено" << components.size() << "компонентов";
|
|
// Компоненты будут обрабатываться через главный контроллер
|
|
}
|
|
|
|
void SpecificationPCBProcessor::processProjectParams(const QMap<QString, QString> ¶ms)
|
|
{
|
|
qDebug() << "SpecificationPCBProcessor::processProjectParams: Получено" << params.size() << "параметров";
|
|
// Пока не используем параметры проекта для SpecificationPCB
|
|
}
|
|
|
|
QTableView* SpecificationPCBProcessor::createTableView()
|
|
{
|
|
QTableView *tableView = new QTableView();
|
|
|
|
qDebug() << "SpecificationPCBProcessor::createTableView: Контроллер доступен:" << (m_controller ? "да" : "нет");
|
|
if (m_controller) {
|
|
qDebug() << "SpecificationPCBProcessor::createTableView: Модель в контроллере доступна:" << (m_controller->getTableModel() ? "да" : "нет");
|
|
if (m_controller->getTableModel()) {
|
|
qDebug() << "SpecificationPCBProcessor::createTableView: Количество строк в модели:" << m_controller->getTableModel()->rowCount();
|
|
qDebug() << "SpecificationPCBProcessor::createTableView: Количество колонок в модели:" << m_controller->getTableModel()->columnCount();
|
|
}
|
|
}
|
|
|
|
// Если контроллер доступен, используем его модель
|
|
if (m_controller && m_controller->getTableModel()) {
|
|
tableView->setModel(m_controller->getTableModel());
|
|
qDebug() << "SpecificationPCBProcessor::createTableView: Используем модель из контроллера";
|
|
} else {
|
|
// Создаем временную модель с 7 столбцами для корректной настройки заголовков
|
|
QStandardItemModel *tempModel = new QStandardItemModel(tableView);
|
|
QStringList headers;
|
|
headers << "Формат" << "Зона" << "Поз." << "Обозначение" << "Наименование" << "Кол." << "Примечание";
|
|
tempModel->setHorizontalHeaderLabels(headers);
|
|
|
|
// Устанавливаем временную модель для корректной настройки заголовков
|
|
tableView->setModel(tempModel);
|
|
qDebug() << "SpecificationPCBProcessor::createTableView: Создана временная модель для настройки заголовков";
|
|
}
|
|
|
|
// Настройка растягивания столбцов для заполнения всего виджета
|
|
QHeaderView *horizontalHeader = tableView->horizontalHeader();
|
|
|
|
// Отключаем автоматическое изменение размера по содержимому
|
|
horizontalHeader->setStretchLastSection(false);
|
|
|
|
// Устанавливаем режимы для каждого столбца - все интерактивные (изменяемые по ширине)
|
|
horizontalHeader->setSectionResizeMode(0, QHeaderView::Interactive); // Формат
|
|
horizontalHeader->setSectionResizeMode(1, QHeaderView::Interactive); // Зона
|
|
horizontalHeader->setSectionResizeMode(2, QHeaderView::Interactive); // Поз.
|
|
horizontalHeader->setSectionResizeMode(3, QHeaderView::Interactive); // Обозначение
|
|
horizontalHeader->setSectionResizeMode(4, QHeaderView::Interactive); // Наименование
|
|
horizontalHeader->setSectionResizeMode(5, QHeaderView::Interactive); // Кол.
|
|
horizontalHeader->setSectionResizeMode(6, QHeaderView::Interactive); // Примечание
|
|
|
|
// Устанавливаем начальные размеры для столбцов
|
|
horizontalHeader->resizeSection(0, 60); // Формат - 60px
|
|
horizontalHeader->resizeSection(1, 50); // Зона - 50px
|
|
horizontalHeader->resizeSection(2, 80); // Поз. - 80px
|
|
horizontalHeader->resizeSection(3, 150); // Обозначение - 150px
|
|
horizontalHeader->resizeSection(4, 200); // Наименование - 200px
|
|
horizontalHeader->resizeSection(5, 60); // Кол. - 60px
|
|
horizontalHeader->resizeSection(6, 150); // Примечание - 150px
|
|
|
|
// Настройка вертикального заголовка
|
|
QHeaderView *verticalHeader = tableView->verticalHeader();
|
|
verticalHeader->setDefaultSectionSize(25); // Устанавливаем высоту строки
|
|
verticalHeader->setSectionResizeMode(QHeaderView::Fixed);
|
|
|
|
qDebug() << "SpecificationPCBProcessor::createTableView: Настроено растягивание столбцов";
|
|
return tableView;
|
|
}
|
|
|
|
void SpecificationPCBProcessor::setColumnMappings(const QStringList &mappings)
|
|
{
|
|
qDebug() << "SpecificationPCBProcessor::setColumnMappings: Настройки колонок обновлены:" << mappings;
|
|
}
|
|
|
|
QStringList SpecificationPCBProcessor::getColumnMappings() const
|
|
{
|
|
return QStringList();
|
|
}
|
|
|
|
QStringList SpecificationPCBProcessor::getAvailableProperties() const
|
|
{
|
|
return QStringList();
|
|
}
|
|
|
|
void SpecificationPCBProcessor::updateTable()
|
|
{
|
|
qDebug() << "SpecificationPCBProcessor::updateTable: Обновляем таблицу по кнопке";
|
|
}
|
|
|
|
void SpecificationPCBProcessor::setController(SpecificationPCBController *controller)
|
|
{
|
|
qDebug() << "SpecificationPCBProcessor::setController: Устанавливаем контроллер";
|
|
m_controller = controller;
|
|
if (m_controller) {
|
|
qDebug() << "SpecificationPCBProcessor::setController: Контроллер установлен";
|
|
} else {
|
|
qDebug() << "SpecificationPCBProcessor::setController: Контроллер сброшен";
|
|
}
|
|
}
|
|
|
|
void SpecificationPCBProcessor::setModel(SpecificationPCBTableModel *model)
|
|
{
|
|
qDebug() << "SpecificationPCBProcessor::setModel: Модель установлена в контроллер";
|
|
if (m_controller) {
|
|
m_controller->setModel(model);
|
|
qDebug() << "SpecificationPCBProcessor::setModel: Модель передана в контроллер";
|
|
} else {
|
|
qDebug() << "SpecificationPCBProcessor::setModel: Контроллер недоступен";
|
|
}
|
|
}
|
|
|
|
// VedomostProcessor
|
|
VedomostProcessor::VedomostProcessor(QObject *parent)
|
|
: DocumentProcessor(parent)
|
|
, m_controller(nullptr)
|
|
{
|
|
}
|
|
|
|
VedomostProcessor::~VedomostProcessor()
|
|
{
|
|
// m_controller удалится автоматически, так как он является дочерним объектом
|
|
}
|
|
|
|
void VedomostProcessor::processComponents(const QList<ComponentModel*> &components)
|
|
{
|
|
qDebug() << "VedomostProcessor::processComponents: Получено" << components.size() << "компонентов";
|
|
|
|
// Только передаем компоненты в контроллер, но не генерируем таблицу
|
|
if (m_controller) {
|
|
m_controller->setComponents(components);
|
|
qDebug() << "VedomostProcessor::processComponents: Компоненты переданы в контроллер";
|
|
} else {
|
|
qDebug() << "VedomostProcessor::processComponents: Контроллер недоступен";
|
|
}
|
|
}
|
|
|
|
void VedomostProcessor::processProjectParams(const QMap<QString, QString> ¶ms)
|
|
{
|
|
qDebug() << "VedomostProcessor::processProjectParams: Получено" << params.size() << "параметров";
|
|
// Пока не используем параметры проекта для Vedomost
|
|
}
|
|
|
|
QTableView* VedomostProcessor::createTableView()
|
|
{
|
|
QTableView *tableView = new QTableView();
|
|
|
|
qDebug() << "VedomostProcessor::createTableView: Контроллер доступен:" << (m_controller ? "да" : "нет");
|
|
if (m_controller) {
|
|
qDebug() << "VedomostProcessor::createTableView: Модель в контроллере доступна:" << (m_controller->getTableModel() ? "да" : "нет");
|
|
if (m_controller->getTableModel()) {
|
|
qDebug() << "VedomostProcessor::createTableView: Количество строк в модели:" << m_controller->getTableModel()->rowCount();
|
|
qDebug() << "VedomostProcessor::createTableView: Количество колонок в модели:" << m_controller->getTableModel()->columnCount();
|
|
}
|
|
}
|
|
|
|
// Если контроллер доступен, используем его модель
|
|
if (m_controller && m_controller->getTableModel()) {
|
|
tableView->setModel(m_controller->getTableModel());
|
|
qDebug() << "VedomostProcessor::createTableView: Используем модель из контроллера";
|
|
} else {
|
|
// Создаем временную модель с 10 столбцами для корректной настройки заголовков
|
|
QStandardItemModel *tempModel = new QStandardItemModel(tableView);
|
|
QStringList headers;
|
|
headers << "Наименование" << "Код продукции" << "Обозначение документа на поставку"
|
|
<< "Поставщик" << "Куда входит (обозначение)" << "Количество на изделие"
|
|
<< "Количество в комплекте" << "Количество на регулир" << "Количество всего" << "Примечание";
|
|
tempModel->setHorizontalHeaderLabels(headers);
|
|
|
|
// Устанавливаем временную модель для корректной настройки заголовков
|
|
tableView->setModel(tempModel);
|
|
qDebug() << "VedomostProcessor::createTableView: Создана временная модель для настройки заголовков";
|
|
}
|
|
|
|
// Настройка растягивания столбцов для заполнения всего виджета
|
|
QHeaderView *horizontalHeader = tableView->horizontalHeader();
|
|
|
|
// Отключаем автоматическое изменение размера по содержимому
|
|
horizontalHeader->setStretchLastSection(false);
|
|
|
|
// Устанавливаем режимы для каждого столбца - все интерактивные (изменяемые по ширине)
|
|
horizontalHeader->setSectionResizeMode(0, QHeaderView::Interactive); // Наименование
|
|
horizontalHeader->setSectionResizeMode(1, QHeaderView::Interactive); // Код продукции
|
|
horizontalHeader->setSectionResizeMode(2, QHeaderView::Interactive); // Обозначение документа на поставку
|
|
horizontalHeader->setSectionResizeMode(3, QHeaderView::Interactive); // Поставщик
|
|
horizontalHeader->setSectionResizeMode(4, QHeaderView::Interactive); // Куда входит (обозначение)
|
|
horizontalHeader->setSectionResizeMode(5, QHeaderView::Interactive); // Количество на изделие
|
|
horizontalHeader->setSectionResizeMode(6, QHeaderView::Interactive); // Количество в комплекте
|
|
horizontalHeader->setSectionResizeMode(7, QHeaderView::Interactive); // Количество на регулир
|
|
horizontalHeader->setSectionResizeMode(8, QHeaderView::Interactive); // Количество всего
|
|
horizontalHeader->setSectionResizeMode(9, QHeaderView::Interactive); // Примечание
|
|
|
|
// Устанавливаем начальные размеры для столбцов
|
|
horizontalHeader->resizeSection(0, 200); // Наименование - 200px
|
|
horizontalHeader->resizeSection(1, 120); // Код продукции - 120px
|
|
horizontalHeader->resizeSection(2, 150); // Обозначение документа на поставку - 150px
|
|
horizontalHeader->resizeSection(3, 100); // Поставщик - 100px
|
|
horizontalHeader->resizeSection(4, 120); // Куда входит (обозначение) - 120px
|
|
horizontalHeader->resizeSection(5, 100); // Количество на изделие - 100px
|
|
horizontalHeader->resizeSection(6, 100); // Количество в комплекте - 100px
|
|
horizontalHeader->resizeSection(7, 100); // Количество на регулир - 100px
|
|
horizontalHeader->resizeSection(8, 100); // Количество всего - 100px
|
|
horizontalHeader->resizeSection(9, 150); // Примечание - 150px
|
|
|
|
// Настройка вертикального заголовка
|
|
QHeaderView *verticalHeader = tableView->verticalHeader();
|
|
verticalHeader->setDefaultSectionSize(25); // Устанавливаем высоту строки
|
|
verticalHeader->setSectionResizeMode(QHeaderView::Fixed);
|
|
|
|
qDebug() << "VedomostProcessor::createTableView: Настроено растягивание столбцов";
|
|
return tableView;
|
|
}
|
|
|
|
void VedomostProcessor::setColumnMappings(const QStringList &mappings)
|
|
{
|
|
qDebug() << "VedomostProcessor::setColumnMappings: Настройки колонок обновлены:" << mappings;
|
|
|
|
if (m_controller) {
|
|
m_controller->setColumnMappings(mappings);
|
|
qDebug() << "VedomostProcessor::setColumnMappings: Настройки переданы в контроллер";
|
|
} else {
|
|
qDebug() << "VedomostProcessor::setColumnMappings: Контроллер недоступен";
|
|
}
|
|
}
|
|
|
|
QStringList VedomostProcessor::getColumnMappings() const
|
|
{
|
|
if (m_controller) {
|
|
return m_controller->getColumnMappings();
|
|
}
|
|
return QStringList();
|
|
}
|
|
|
|
QStringList VedomostProcessor::getAvailableProperties() const
|
|
{
|
|
if (m_controller) {
|
|
return m_controller->getAvailableProperties();
|
|
}
|
|
return QStringList();
|
|
}
|
|
|
|
void VedomostProcessor::updateTable()
|
|
{
|
|
qDebug() << "VedomostProcessor::updateTable: Обновляем таблицу по кнопке";
|
|
|
|
if (m_controller) {
|
|
m_controller->updateTableFromComponents();
|
|
qDebug() << "VedomostProcessor::updateTable: Таблица обновлена через контроллер";
|
|
} else {
|
|
qDebug() << "VedomostProcessor::updateTable: Контроллер недоступен";
|
|
}
|
|
}
|
|
|
|
void VedomostProcessor::setController(VedomostController *controller)
|
|
{
|
|
qDebug() << "VedomostProcessor::setController: Устанавливаем контроллер";
|
|
m_controller = controller;
|
|
if (m_controller) {
|
|
qDebug() << "VedomostProcessor::setController: Контроллер установлен";
|
|
} else {
|
|
qDebug() << "VedomostProcessor::setController: Контроллер сброшен";
|
|
}
|
|
}
|
|
|
|
void VedomostProcessor::setModel(VedomostTableModel *model)
|
|
{
|
|
qDebug() << "VedomostProcessor::setModel: Модель установлена в контроллер";
|
|
if (m_controller) {
|
|
m_controller->setModel(model);
|
|
qDebug() << "VedomostProcessor::setModel: Модель передана в контроллер";
|
|
} else {
|
|
qDebug() << "VedomostProcessor::setModel: Контроллер недоступен";
|
|
}
|
|
}
|
|
|
|
// DocumentEditWidget
|
|
DocumentEditWidget::DocumentEditWidget(DocumentProcessor *processor, QWidget *parent)
|
|
: QWidget(parent)
|
|
, m_processor(processor)
|
|
, m_componentModel(nullptr)
|
|
, m_projectParamModel(nullptr)
|
|
, m_controller(nullptr)
|
|
, m_titleInscriptionsModel(nullptr)
|
|
{
|
|
qDebug() << "DocumentEditWidget: Конструктор без контроллера, processor:" << (processor ? "доступен" : "nullptr");
|
|
setUp();
|
|
}
|
|
|
|
DocumentEditWidget::DocumentEditWidget(DocumentProcessor *processor, MainController *controller, QWidget *parent)
|
|
: QWidget(parent)
|
|
, m_processor(processor)
|
|
, m_componentModel(nullptr)
|
|
, m_projectParamModel(nullptr)
|
|
, m_controller(controller)
|
|
, m_titleInscriptionsModel(nullptr)
|
|
{
|
|
qDebug() << "DocumentEditWidget: Конструктор с контроллером, processor:" << (processor ? "доступен" : "nullptr")
|
|
<< "controller:" << (controller ? "доступен" : "nullptr");
|
|
setUp();
|
|
}
|
|
|
|
void DocumentEditWidget::setUp()
|
|
{
|
|
qDebug() << "DocumentEditWidget::setUp: Начинаем настройку виджета";
|
|
setWidgets();
|
|
setUpLayout();
|
|
setUpConnections();
|
|
|
|
// Инициализируем состояние кнопок
|
|
m_insertRowButton->setEnabled(false); // Кнопка вставки неактивна по умолчанию
|
|
m_removeRowButton->setEnabled(false); // Кнопка удаления неактивна по умолчанию
|
|
|
|
// Применяем настройки растягивания столбцов к пустой таблице
|
|
applyColumnStretching();
|
|
|
|
qDebug() << "DocumentEditWidget::setUp: Настройка виджета завершена";
|
|
}
|
|
|
|
void DocumentEditWidget::setWidgets()
|
|
{
|
|
qDebug() << "DocumentEditWidget::setWidgets: Создаем виджеты";
|
|
m_openSettingsButton = new QPushButton("Настройки документа", this);
|
|
m_generateTableButton = new QPushButton("Генерация таблицы", this);
|
|
m_recalculateTableButton = new QPushButton("Пересчет таблицы", this);
|
|
|
|
// Новые кнопки для управления строками
|
|
m_addRowButton = new QPushButton("+ Добавить строку", this);
|
|
m_insertRowButton = new QPushButton("+ Вставить строку", this);
|
|
m_removeRowButton = new QPushButton("- Удалить строку", this);
|
|
|
|
m_tableView = new QTableView(this);
|
|
// Настраиваем таблицу для растягивания на весь виджет
|
|
m_tableView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
m_tableView->horizontalHeader()->setStretchLastSection(false);
|
|
// Включаем контекстное меню
|
|
m_tableView->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
// Устанавливаем режим множественного выбора строк
|
|
m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
m_tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
m_settingsGroupBox = new QGroupBox("Настройки", this);
|
|
qDebug() << "DocumentEditWidget::setWidgets: Виджеты созданы";
|
|
}
|
|
|
|
void DocumentEditWidget::setUpLayout()
|
|
{
|
|
qDebug() << "DocumentEditWidget::setUpLayout: Настраиваем компоновку";
|
|
|
|
// Настраиваем политику размера для всего виджета
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
QVBoxLayout* mainLayout = new QVBoxLayout(this);
|
|
|
|
// Группа настроек
|
|
QHBoxLayout* groupBoxLayout = new QHBoxLayout(m_settingsGroupBox);
|
|
|
|
// Левая группа кнопок
|
|
groupBoxLayout->addWidget(m_openSettingsButton);
|
|
|
|
// Растягивающийся элемент для разделения
|
|
groupBoxLayout->addStretch();
|
|
|
|
// Средняя группа кнопок для управления строками
|
|
groupBoxLayout->addWidget(m_addRowButton);
|
|
groupBoxLayout->addWidget(m_insertRowButton);
|
|
groupBoxLayout->addWidget(m_removeRowButton);
|
|
|
|
// Растягивающийся элемент для разделения
|
|
groupBoxLayout->addStretch();
|
|
|
|
// Правая группа кнопок
|
|
groupBoxLayout->addWidget(m_generateTableButton);
|
|
groupBoxLayout->addWidget(m_recalculateTableButton);
|
|
|
|
mainLayout->addWidget(m_settingsGroupBox);
|
|
mainLayout->addWidget(m_tableView, 1); // Растягиваем таблицу на все доступное пространство
|
|
qDebug() << "DocumentEditWidget::setUpLayout: Компоновка настроена";
|
|
}
|
|
|
|
void DocumentEditWidget::setUpConnections()
|
|
{
|
|
qDebug() << "DocumentEditWidget::setUpConnections: Настраиваем соединения сигналов";
|
|
connect(m_generateTableButton, &QPushButton::clicked, this, &DocumentEditWidget::onGenerateTable);
|
|
connect(m_recalculateTableButton, &QPushButton::clicked, this, &DocumentEditWidget::onRecalculateTable);
|
|
connect(m_openSettingsButton, &QPushButton::clicked, this, &DocumentEditWidget::onOpenColumnSettings);
|
|
|
|
// Соединения для новых кнопок управления строками
|
|
connect(m_addRowButton, &QPushButton::clicked, this, &DocumentEditWidget::onAddRow);
|
|
connect(m_insertRowButton, &QPushButton::clicked, this, &DocumentEditWidget::onInsertRow);
|
|
connect(m_removeRowButton, &QPushButton::clicked, this, &DocumentEditWidget::onRemoveRow);
|
|
|
|
// Соединение для контекстного меню
|
|
connect(m_tableView, &QTableView::customContextMenuRequested, this, &DocumentEditWidget::onContextMenuRequested);
|
|
|
|
// Соединение для обновления состояния кнопок при изменении выбора
|
|
// Будем устанавливать это соединение после того, как таблица получит модель
|
|
// connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
|
// this, &DocumentEditWidget::onSelectionChanged);
|
|
|
|
qDebug() << "DocumentEditWidget::setUpConnections: Соединения сигналов настроены";
|
|
}
|
|
|
|
void DocumentEditWidget::onOpenColumnSettings()
|
|
{
|
|
qDebug() << "DocumentEditWidget::onOpenColumnSettings: Нажата кнопка настроек колонок";
|
|
|
|
// Определяем тип документа
|
|
DocumentType docType = DocumentType::Perechen; // По умолчанию
|
|
|
|
if (qobject_cast<PerechenProcessor*>(m_processor)) {
|
|
docType = DocumentType::Perechen;
|
|
} else if (qobject_cast<SpecificationPCBProcessor*>(m_processor)) {
|
|
docType = DocumentType::SpecificationPCB;
|
|
} else if (qobject_cast<SpecificationProcessor*>(m_processor)) {
|
|
docType = DocumentType::Specification;
|
|
} else if (qobject_cast<VedomostProcessor*>(m_processor)) {
|
|
docType = DocumentType::Vedomost;
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onOpenColumnSettings: Процессор не поддерживает настройки";
|
|
return;
|
|
}
|
|
|
|
// Создаем универсальный диалог настроек
|
|
DocumentSettingsDialog dialog(docType, m_controller, this);
|
|
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
QStringList newTableMappings = dialog.getTableColumnMappings();
|
|
QMap<int, QString> newInscriptionValues = dialog.getTitleInscriptionValues();
|
|
|
|
qDebug() << "DocumentEditWidget::onOpenColumnSettings: Получены настройки таблицы:" << newTableMappings;
|
|
qDebug() << "DocumentEditWidget::onOpenColumnSettings: Получены настройки надписей:" << newInscriptionValues;
|
|
|
|
// Настройки таблицы и надписей уже сохранены в диалоге
|
|
qDebug() << "DocumentEditWidget::onOpenColumnSettings: Настройки обновлены, но таблица не генерируется автоматически";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onOpenColumnSettings: Диалог настроек отменен";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void DocumentEditWidget::onGenerateTable()
|
|
{
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Нажата кнопка генерации таблицы";
|
|
|
|
// Проверяем, является ли процессор PerechenProcessor
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor) {
|
|
if (m_controller && m_controller->perechenTableController()) {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Генерируем таблицу через PerechenTableController";
|
|
m_controller->perechenTableController()->generateTableFromComponents();
|
|
|
|
// Устанавливаем модель из контроллера
|
|
if (m_controller->perechenTableModel()) {
|
|
m_tableView->setModel(m_controller->perechenTableModel());
|
|
applyColumnStretching();
|
|
setupSelectionConnection();
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Модель PerechenTableModel установлена";
|
|
}
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: PerechenTableController недоступен";
|
|
}
|
|
} else {
|
|
// Проверяем, является ли процессор SpecificationPCBProcessor
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor) {
|
|
if (m_controller && m_controller->specificationPCBController()) {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Генерируем таблицу через SpecificationPCBController";
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Компонентов в модели:" << m_componentModel->getComponents().size();
|
|
|
|
// Передаем компоненты в контроллер
|
|
m_controller->specificationPCBController()->setComponents(m_componentModel->getComponents());
|
|
|
|
m_controller->specificationPCBController()->generateTableFromComponents();
|
|
|
|
// Устанавливаем модель из контроллера
|
|
if (m_controller->specificationPCBTableModel()) {
|
|
m_tableView->setModel(m_controller->specificationPCBTableModel());
|
|
applyColumnStretching();
|
|
setupSelectionConnection();
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Модель SpecificationPCBTableModel установлена";
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Количество строк в модели:" << m_controller->specificationPCBTableModel()->rowCount();
|
|
}
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: SpecificationPCBController недоступен";
|
|
}
|
|
} else {
|
|
// Проверяем, является ли процессор SpecificationProcessor
|
|
SpecificationProcessor *specProcessor = qobject_cast<SpecificationProcessor*>(m_processor);
|
|
if (specProcessor) {
|
|
if (m_controller && m_controller->specificationController()) {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Генерируем таблицу через SpecificationController";
|
|
|
|
// Получаем PCB модель материалов
|
|
PCBMaterialModel* pcbMaterialModel = m_controller->pcbMaterialModel();
|
|
if (pcbMaterialModel) {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: PCB модель материалов доступна, материалов:" << pcbMaterialModel->getMaterialCount();
|
|
|
|
// Передаем PCB модель в контроллер
|
|
m_controller->specificationController()->setPCBMaterialModel(pcbMaterialModel);
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: PCB модель материалов недоступна";
|
|
// Передаем nullptr
|
|
m_controller->specificationController()->setPCBMaterialModel(nullptr);
|
|
}
|
|
|
|
m_controller->specificationController()->generateTableFromMaterials();
|
|
|
|
// Устанавливаем модель из контроллера
|
|
if (m_controller->specificationTableModel()) {
|
|
m_tableView->setModel(m_controller->specificationTableModel());
|
|
applyColumnStretching();
|
|
setupSelectionConnection();
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Модель SpecificationTableModel установлена";
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Количество строк в модели:" << m_controller->specificationTableModel()->rowCount();
|
|
}
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: SpecificationController недоступен";
|
|
}
|
|
} else {
|
|
// Проверяем, является ли процессор VedomostProcessor
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor) {
|
|
if (m_controller && m_controller->vedomostController()) {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Генерируем таблицу через VedomostController";
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Компонентов в модели:" << m_componentModel->getComponents().size();
|
|
|
|
// Передаем компоненты в контроллер
|
|
m_controller->vedomostController()->setComponents(m_componentModel->getComponents());
|
|
|
|
m_controller->vedomostController()->generateTableFromComponents();
|
|
|
|
// Устанавливаем модель из контроллера
|
|
if (m_controller->vedomostTableModel()) {
|
|
m_tableView->setModel(m_controller->vedomostTableModel());
|
|
applyColumnStretching();
|
|
setupSelectionConnection();
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Модель VedomostTableModel установлена";
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Количество строк в модели:" << m_controller->vedomostTableModel()->rowCount();
|
|
|
|
}
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: VedomostController недоступен";
|
|
}
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onGenerateTable: Процессор не является PerechenProcessor, SpecificationPCBProcessor, SpecificationProcessor или VedomostProcessor";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DocumentEditWidget::onRecalculateTable()
|
|
{
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Нажата кнопка пересчета таблицы";
|
|
|
|
// Проверяем, является ли процессор PerechenProcessor
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor) {
|
|
if (m_controller && m_controller->perechenTableModel()) {
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Пересчитываем таблицу PerechenTableModel";
|
|
PerechenTableModel *model = m_controller->perechenTableModel();
|
|
model->updateRowNumbers();
|
|
model->updatePageNumbers(); // updatePageNumbers уже уведомляет об изменениях
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Пересчет PerechenTableModel завершен";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: PerechenTableModel недоступна";
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор SpecificationPCBProcessor
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor) {
|
|
if (m_controller && m_controller->specificationPCBTableModel()) {
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Пересчитываем таблицу SpecificationPCBTableModel";
|
|
SpecificationPCBTableModel *model = m_controller->specificationPCBTableModel();
|
|
model->updateRowNumbers();
|
|
model->updatePageNumbers(); // updatePageNumbers уже уведомляет об изменениях
|
|
|
|
// Вызываем optimizePageBreaks через контроллер, который также пересчитывает позиции
|
|
if (m_controller->specificationPCBController()) {
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Вызываем optimizePageBreaks для пересчета позиций";
|
|
m_controller->specificationPCBController()->optimizePageBreaks();
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Пересчет SpecificationPCBTableModel завершен";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: SpecificationPCBTableModel недоступна";
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор SpecificationProcessor
|
|
SpecificationProcessor *specProcessor = qobject_cast<SpecificationProcessor*>(m_processor);
|
|
if (specProcessor) {
|
|
if (m_controller && m_controller->specificationTableModel()) {
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Пересчитываем таблицу SpecificationTableModel";
|
|
SpecificationTableModel *model = m_controller->specificationTableModel();
|
|
model->updateRowNumbers();
|
|
model->updatePageNumbers(); // updatePageNumbers уже уведомляет об изменениях
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Пересчет SpecificationTableModel завершен";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: SpecificationTableModel недоступна";
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор VedomostProcessor
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor) {
|
|
if (m_controller && m_controller->vedomostTableModel()) {
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Пересчитываем таблицу VedomostTableModel";
|
|
VedomostTableModel *model = m_controller->vedomostTableModel();
|
|
model->updateRowNumbers();
|
|
model->updatePageNumbers();
|
|
// Пересчитываем totalQuantity для всех строк
|
|
// updateTotalQuantity уже уведомляет об изменениях через emit dataChanged
|
|
for (int row = 0; row < model->rowCount(); ++row) {
|
|
model->updateTotalQuantity(row);
|
|
}
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Пересчет VedomostTableModel завершен";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: VedomostTableModel недоступна";
|
|
}
|
|
return;
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onRecalculateTable: Процессор не является PerechenProcessor, SpecificationPCBProcessor, SpecificationProcessor или VedomostProcessor";
|
|
}
|
|
|
|
void DocumentEditWidget::setData(ComponentTableModel *componentModel, ProjectParamTableModel *projectParamModel)
|
|
{
|
|
qDebug() << "DocumentEditWidget::setData: Устанавливаем данные, componentModel:" << (componentModel ? "доступен" : "nullptr")
|
|
<< "projectParamModel:" << (projectParamModel ? "доступен" : "nullptr");
|
|
|
|
m_componentModel = componentModel;
|
|
m_projectParamModel = projectParamModel;
|
|
|
|
// Передаем DesignatorMappingModel в PerechenTableController, если это PerechenProcessor
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor && m_controller) {
|
|
// Получаем контроллер из PerechenProcessor
|
|
PerechenTableController *perecheController = perechenProcessor->getController();
|
|
if (perecheController) {
|
|
// Передаем модель маппинга дезигнаторов
|
|
perecheController->setDesignatorMappingModel(m_controller->designatorMappingModel());
|
|
qDebug() << "DocumentEditWidget::setData: DesignatorMappingModel передан в PerechenTableController";
|
|
}
|
|
}
|
|
|
|
// Передаем DesignatorMappingModel в SpecificationPCBController, если это SpecificationPCBProcessor
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor && m_controller) {
|
|
// Получаем контроллер из SpecificationPCBProcessor
|
|
SpecificationPCBController *specPCBController = specPCBProcessor->getController();
|
|
if (specPCBController) {
|
|
// Передаем модель маппинга дезигнаторов
|
|
specPCBController->setDesignatorMappingModel(m_controller->designatorMappingModel());
|
|
qDebug() << "DocumentEditWidget::setData: DesignatorMappingModel передан в SpecificationPCBController";
|
|
}
|
|
}
|
|
|
|
// Передаем DesignatorMappingModel в VedomostController, если это VedomostProcessor
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor && m_controller) {
|
|
// Получаем контроллер из VedomostProcessor
|
|
VedomostController *vedomostController = vedomostProcessor->getController();
|
|
if (vedomostController) {
|
|
// Передаем модель маппинга дезигнаторов
|
|
vedomostController->setDesignatorMappingModel(m_controller->designatorMappingModel());
|
|
qDebug() << "DocumentEditWidget::setData: DesignatorMappingModel передан в VedomostController";
|
|
}
|
|
}
|
|
|
|
// Не вызываем updateView() автоматически - таблица будет генерироваться только по нажатию кнопки
|
|
qDebug() << "DocumentEditWidget::setData: Данные установлены";
|
|
}
|
|
|
|
void DocumentEditWidget::updateView()
|
|
{
|
|
//qDebug() << "DocumentEditWidget::updateView: Начинаем обновление представления для типа документа:" << m_processor->getDocumentType();
|
|
|
|
if (!m_processor || !m_componentModel || !m_projectParamModel) {
|
|
qDebug() << "DocumentEditWidget::updateView: Один из указателей null - processor:" << (m_processor ? "доступен" : "nullptr")
|
|
<< "componentModel:" << (m_componentModel ? "доступен" : "nullptr")
|
|
<< "projectParamModel:" << (m_projectParamModel ? "доступен" : "nullptr");
|
|
return;
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::updateView: Компонентов в модели:" << m_componentModel->getComponents().size();
|
|
|
|
// Проверяем, является ли процессор VedomostProcessor
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor) {
|
|
// Для ведомости только передаем компоненты в контроллер, но не генерируем таблицу
|
|
qDebug() << "DocumentEditWidget::updateView: VedomostProcessor - только передаем компоненты в контроллер";
|
|
if (vedomostProcessor->getController()) {
|
|
vedomostProcessor->getController()->setComponents(m_componentModel->getComponents());
|
|
}
|
|
} else {
|
|
// Для других процессоров обрабатываем данные и генерируем таблицу
|
|
m_processor->processComponents(m_componentModel->getComponents());
|
|
m_processor->processProjectParams(m_projectParamModel->getDataAsMap());
|
|
}
|
|
|
|
// Создаем новую таблицу
|
|
QTableView *newTableView = m_processor->createTableView();
|
|
|
|
if (!newTableView || !newTableView->model()) {
|
|
qDebug() << "DocumentEditWidget::updateView: Не удалось создать таблицу или модель";
|
|
delete newTableView;
|
|
return;
|
|
}
|
|
|
|
// Безопасно заменяем модель
|
|
QAbstractItemModel *oldModel = m_tableView->model();
|
|
m_tableView->setModel(newTableView->model());
|
|
|
|
// Удаляем старую модель только после успешной установки новой
|
|
if (oldModel && oldModel != newTableView->model()) {
|
|
oldModel->deleteLater();
|
|
}
|
|
|
|
// Удаляем временную таблицу, но не её модель
|
|
delete newTableView;
|
|
|
|
// Применяем настройки растягивания столбцов к основной таблице
|
|
applyColumnStretching();
|
|
|
|
// Устанавливаем соединение для сигнала selectionChanged после установки модели
|
|
setupSelectionConnection();
|
|
|
|
qDebug() << "DocumentEditWidget::updateView: Таблица обновлена успешно";
|
|
}
|
|
|
|
TitleInscriptionsModel* DocumentEditWidget::getTitleInscriptionsModel() const
|
|
{
|
|
// Возвращаем модель надписей из MainController
|
|
if (m_controller) {
|
|
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
|
|
qDebug() << "DocumentEditWidget::getTitleInscriptionsModel: Возвращаем модель надписей из MainController:" << (titleModel ? "доступна" : "nullptr");
|
|
return titleModel;
|
|
}
|
|
qDebug() << "DocumentEditWidget::getTitleInscriptionsModel: Контроллер недоступен, возвращаем nullptr";
|
|
return nullptr;
|
|
}
|
|
|
|
PerechenTableModel* DocumentEditWidget::getPerechenTableModel() const
|
|
{
|
|
qDebug() << "DocumentEditWidget::getPerechenTableModel: Проверяем доступность PerechenProcessor";
|
|
|
|
// Проверяем, является ли текущий процессор PerechenProcessor
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor) {
|
|
if (m_controller && m_controller->perechenTableModel()) {
|
|
qDebug() << "DocumentEditWidget::getPerechenTableModel: Возвращаем модель перечня:" << (m_controller->perechenTableModel() ? "доступна" : "nullptr");
|
|
return m_controller->perechenTableModel();
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::getPerechenTableModel: PerechenProcessor недоступен, возвращаем nullptr";
|
|
return nullptr;
|
|
}
|
|
|
|
SpecificationPCBTableModel* DocumentEditWidget::getSpecificationPCBTableModel() const
|
|
{
|
|
qDebug() << "DocumentEditWidget::getSpecificationPCBTableModel: Проверяем доступность SpecificationPCBProcessor";
|
|
|
|
// Проверяем, является ли текущий процессор SpecificationPCBProcessor
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor) {
|
|
if (m_controller && m_controller->specificationPCBTableModel()) {
|
|
qDebug() << "DocumentEditWidget::getSpecificationPCBTableModel: Возвращаем модель спецификации платы:" << (m_controller->specificationPCBTableModel() ? "доступна" : "nullptr");
|
|
return m_controller->specificationPCBTableModel();
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::getSpecificationPCBTableModel: SpecificationPCBProcessor недоступен, возвращаем nullptr";
|
|
return nullptr;
|
|
}
|
|
|
|
SpecificationTableModel* DocumentEditWidget::getSpecificationTableModel() const
|
|
{
|
|
qDebug() << "DocumentEditWidget::getSpecificationTableModel: Проверяем доступность SpecificationProcessor";
|
|
|
|
// Проверяем, является ли текущий процессор SpecificationProcessor
|
|
SpecificationProcessor *specProcessor = qobject_cast<SpecificationProcessor*>(m_processor);
|
|
if (specProcessor) {
|
|
if (m_controller && m_controller->specificationTableModel()) {
|
|
qDebug() << "DocumentEditWidget::getSpecificationTableModel: Возвращаем модель спецификации:" << (m_controller->specificationTableModel() ? "доступна" : "nullptr");
|
|
return m_controller->specificationTableModel();
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::getSpecificationTableModel: SpecificationProcessor недоступен, возвращаем nullptr";
|
|
return nullptr;
|
|
}
|
|
|
|
VedomostTableModel* DocumentEditWidget::getVedomostTableModel() const
|
|
{
|
|
qDebug() << "DocumentEditWidget::getVedomostTableModel: Проверяем доступность VedomostProcessor";
|
|
|
|
// Проверяем, является ли текущий процессор VedomostProcessor
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor) {
|
|
if (m_controller && m_controller->vedomostTableModel()) {
|
|
qDebug() << "DocumentEditWidget::getVedomostTableModel: Возвращаем модель ведомости:" << (m_controller->vedomostTableModel() ? "доступна" : "nullptr");
|
|
return m_controller->vedomostTableModel();
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::getVedomostTableModel: VedomostProcessor недоступен, возвращаем nullptr";
|
|
return nullptr;
|
|
}
|
|
|
|
// Новые слоты для управления строками
|
|
void DocumentEditWidget::onAddRow()
|
|
{
|
|
qDebug() << "DocumentEditWidget::onAddRow: Нажата кнопка добавления строки";
|
|
|
|
// Проверяем, является ли процессор PerechenProcessor
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor) {
|
|
if (m_controller && m_controller->perechenTableController()) {
|
|
m_controller->perechenTableController()->addEmptyRow();
|
|
qDebug() << "DocumentEditWidget::onAddRow: Пустая строка добавлена через PerechenTableController";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onAddRow: PerechenTableController недоступен";
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор SpecificationPCBProcessor
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor) {
|
|
if (m_controller && m_controller->specificationPCBController()) {
|
|
m_controller->specificationPCBController()->addEmptyRow();
|
|
qDebug() << "DocumentEditWidget::onAddRow: Пустая строка добавлена через SpecificationPCBController";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onAddRow: SpecificationPCBController недоступен";
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор VedomostProcessor
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor) {
|
|
if (m_controller && m_controller->vedomostController()) {
|
|
m_controller->vedomostController()->addEmptyRow();
|
|
qDebug() << "DocumentEditWidget::onAddRow: Пустая строка добавлена через VedomostController";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onAddRow: VedomostController недоступен";
|
|
}
|
|
return;
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onAddRow: Процессор не поддерживает добавление строк";
|
|
}
|
|
|
|
void DocumentEditWidget::onInsertRow()
|
|
{
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Нажата кнопка вставки строки";
|
|
|
|
// Получаем текущую выбранную строку
|
|
int selectedRow = getCurrentSelectedRow();
|
|
if (selectedRow == -1) {
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Нет выбранной строки";
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор PerechenProcessor
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor) {
|
|
// Проверяем, можно ли вставить строку в эту позицию
|
|
if (m_controller && m_controller->perechenTableModel()) {
|
|
if (!m_controller->perechenTableModel()->canEditRow(selectedRow)) {
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Нельзя вставить строку перед строкой" << selectedRow << "(заголовок или автоматически сгенерированная)";
|
|
return;
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Вставляем строку перед строкой" << selectedRow;
|
|
|
|
// Получаем контроллер и вставляем пустую строку перед текущей
|
|
if (m_controller && m_controller->perechenTableController()) {
|
|
m_controller->perechenTableController()->insertEmptyRowAt(selectedRow);
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Пустая строка вставлена через PerechenTableController";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onInsertRow: PerechenTableController недоступен";
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор SpecificationPCBProcessor
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor) {
|
|
// Проверяем, можно ли вставить строку в эту позицию
|
|
if (m_controller && m_controller->specificationPCBTableModel()) {
|
|
if (!m_controller->specificationPCBTableModel()->canEditRow(selectedRow)) {
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Нельзя вставить строку перед строкой" << selectedRow << "(заголовок или автоматически сгенерированная)";
|
|
return;
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Вставляем строку перед строкой" << selectedRow;
|
|
|
|
// Получаем контроллер и вставляем пустую строку перед текущей
|
|
if (m_controller && m_controller->specificationPCBController()) {
|
|
m_controller->specificationPCBController()->insertEmptyRowAt(selectedRow);
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Пустая строка вставлена через SpecificationPCBController";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onInsertRow: SpecificationPCBController недоступен";
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор VedomostProcessor
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor) {
|
|
// Проверяем, можно ли вставить строку в эту позицию
|
|
if (m_controller && m_controller->vedomostTableModel()) {
|
|
if (!m_controller->vedomostTableModel()->canEditRow(selectedRow)) {
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Нельзя вставить строку перед строкой" << selectedRow << "(заголовок или автоматически сгенерированная)";
|
|
return;
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Вставляем строку перед строкой" << selectedRow;
|
|
|
|
// Получаем контроллер и вставляем пустую строку перед текущей
|
|
if (m_controller && m_controller->vedomostController()) {
|
|
m_controller->vedomostController()->insertEmptyRowAt(selectedRow);
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Пустая строка вставлена через VedomostController";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onInsertRow: VedomostController недоступен";
|
|
}
|
|
return;
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onInsertRow: Процессор не поддерживает вставку строк";
|
|
}
|
|
|
|
void DocumentEditWidget::onRemoveRow()
|
|
{
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Нажата кнопка удаления строки";
|
|
|
|
// Получаем текущую выбранную строку
|
|
int row = getCurrentSelectedRow();
|
|
if (row == -1) {
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Нет выбранной строки";
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор PerechenProcessor
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor) {
|
|
// Проверяем, можно ли удалить эту строку
|
|
if (m_controller && m_controller->perechenTableModel()) {
|
|
if (!m_controller->perechenTableModel()->canEditRow(row)) {
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Строка" << row << "не может быть удалена (заголовок или автоматически сгенерированная)";
|
|
return;
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Удаляем строку" << row;
|
|
|
|
// Получаем контроллер и удаляем строку
|
|
if (m_controller && m_controller->perechenTableController()) {
|
|
m_controller->perechenTableController()->removeRow(row);
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Строка удалена через PerechenTableController";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: PerechenTableController недоступен";
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор SpecificationPCBProcessor
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor) {
|
|
// Проверяем, можно ли удалить эту строку
|
|
if (m_controller && m_controller->specificationPCBTableModel()) {
|
|
if (!m_controller->specificationPCBTableModel()->canEditRow(row)) {
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Строка" << row << "не может быть удалена (заголовок или автоматически сгенерированная)";
|
|
return;
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Удаляем строку" << row;
|
|
|
|
// Получаем контроллер и удаляем строку
|
|
if (m_controller && m_controller->specificationPCBController()) {
|
|
m_controller->specificationPCBController()->removeRow(row);
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Строка удалена через SpecificationPCBController";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: SpecificationPCBController недоступен";
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли процессор VedomostProcessor
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor) {
|
|
// Проверяем, можно ли удалить эту строку
|
|
if (m_controller && m_controller->vedomostTableModel()) {
|
|
if (!m_controller->vedomostTableModel()->canEditRow(row)) {
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Строка" << row << "не может быть удалена (заголовок или автоматически сгенерированная)";
|
|
return;
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Удаляем строку" << row;
|
|
|
|
// Получаем контроллер и удаляем строку
|
|
if (m_controller && m_controller->vedomostController()) {
|
|
m_controller->vedomostController()->removeRow(row);
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Строка удалена через VedomostController";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: VedomostController недоступен";
|
|
}
|
|
return;
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onRemoveRow: Процессор не поддерживает удаление строк";
|
|
}
|
|
|
|
// Слот для обновления состояния кнопок
|
|
void DocumentEditWidget::onSelectionChanged()
|
|
{
|
|
int selectedRow = getCurrentSelectedRow();
|
|
bool hasSelection = selectedRow != -1;
|
|
|
|
// Кнопки активны только когда есть выбранная строка
|
|
m_insertRowButton->setEnabled(hasSelection);
|
|
m_removeRowButton->setEnabled(hasSelection);
|
|
|
|
qDebug() << "DocumentEditWidget::onSelectionChanged: Выбрана строка" << selectedRow
|
|
<< "кнопки вставки и удаления" << (hasSelection ? "активны" : "неактивны");
|
|
}
|
|
|
|
// Вспомогательные методы
|
|
int DocumentEditWidget::getCurrentSelectedRow() const
|
|
{
|
|
QModelIndex currentIndex = m_tableView->currentIndex();
|
|
if (currentIndex.isValid()) {
|
|
return currentIndex.row();
|
|
}
|
|
return -1; // Нет выбранной строки
|
|
}
|
|
|
|
void DocumentEditWidget::setupSelectionConnection()
|
|
{
|
|
// Отключаем предыдущее соединение, если оно есть
|
|
disconnect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
|
this, &DocumentEditWidget::onSelectionChanged);
|
|
|
|
// Устанавливаем новое соединение
|
|
if (m_tableView->selectionModel()) {
|
|
connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
|
this, &DocumentEditWidget::onSelectionChanged);
|
|
qDebug() << "DocumentEditWidget::setupSelectionConnection: Соединение selectionChanged установлено";
|
|
|
|
// Обновляем состояние кнопок сразу после установки соединения
|
|
onSelectionChanged();
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::setupSelectionConnection: selectionModel недоступен";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void DocumentEditWidget::applyColumnStretching()
|
|
{
|
|
qDebug() << "DocumentEditWidget::applyColumnStretching: Применяем настройки растягивания столбцов";
|
|
|
|
if (!m_tableView || !m_tableView->model()) {
|
|
qDebug() << "DocumentEditWidget::applyColumnStretching: Таблица или модель недоступны";
|
|
return;
|
|
}
|
|
|
|
// Проверяем тип процессора и применяем соответствующие настройки
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor) {
|
|
// Настройки для Perechen (Перечень элементов)
|
|
QHeaderView *horizontalHeader = m_tableView->horizontalHeader();
|
|
|
|
// Отключаем автоматическое изменение размера по содержимому
|
|
horizontalHeader->setStretchLastSection(false);
|
|
|
|
// Устанавливаем режимы для каждого столбца - все интерактивные (изменяемые по ширине)
|
|
horizontalHeader->setSectionResizeMode(0, QHeaderView::Interactive); // Поз.обозначение
|
|
horizontalHeader->setSectionResizeMode(1, QHeaderView::Interactive); // Наименование
|
|
horizontalHeader->setSectionResizeMode(2, QHeaderView::Interactive); // Кол.
|
|
horizontalHeader->setSectionResizeMode(3, QHeaderView::Interactive); // Примечание
|
|
|
|
// Устанавливаем начальные размеры для столбцов
|
|
horizontalHeader->resizeSection(0, 100); // Поз.обозначение - 100px
|
|
horizontalHeader->resizeSection(1, 200); // Наименование - 200px
|
|
horizontalHeader->resizeSection(2, 60); // Кол. - 60px
|
|
horizontalHeader->resizeSection(3, 150); // Примечание - 150px
|
|
|
|
// Принудительно обновляем размеры столбцов
|
|
//horizontalHeader->resizeSections();
|
|
|
|
qDebug() << "DocumentEditWidget::applyColumnStretching: Настройки для Perechen применены";
|
|
return;
|
|
}
|
|
|
|
SpecificationProcessor *specProcessor = qobject_cast<SpecificationProcessor*>(m_processor);
|
|
if (specProcessor) {
|
|
// Настройки для Specification (Спецификация)
|
|
QHeaderView *horizontalHeader = m_tableView->horizontalHeader();
|
|
|
|
horizontalHeader->setStretchLastSection(false);
|
|
|
|
horizontalHeader->setSectionResizeMode(0, QHeaderView::Interactive); // Формат
|
|
horizontalHeader->setSectionResizeMode(1, QHeaderView::Interactive); // Зона
|
|
horizontalHeader->setSectionResizeMode(2, QHeaderView::Interactive); // Поз.
|
|
horizontalHeader->setSectionResizeMode(3, QHeaderView::Interactive); // Обозначение
|
|
horizontalHeader->setSectionResizeMode(4, QHeaderView::Interactive); // Наименование
|
|
horizontalHeader->setSectionResizeMode(5, QHeaderView::Interactive); // Количество
|
|
horizontalHeader->setSectionResizeMode(6, QHeaderView::Interactive); // Примечание
|
|
|
|
horizontalHeader->resizeSection(0, 60); // Формат - 60px
|
|
horizontalHeader->resizeSection(1, 50); // Зона - 50px
|
|
horizontalHeader->resizeSection(2, 80); // Поз. - 80px
|
|
horizontalHeader->resizeSection(3, 150); // Обозначение - 150px
|
|
horizontalHeader->resizeSection(4, 200); // Наименование - 200px
|
|
horizontalHeader->resizeSection(5, 60); // Количество - 60px
|
|
horizontalHeader->resizeSection(6, 150); // Примечание - 150px
|
|
|
|
// horizontalHeader->resizeSections();
|
|
|
|
qDebug() << "DocumentEditWidget::applyColumnStretching: Настройки для Specification применены";
|
|
return;
|
|
}
|
|
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor) {
|
|
// Настройки для SpecificationPCB (Спецификация ПП)
|
|
QHeaderView *horizontalHeader = m_tableView->horizontalHeader();
|
|
|
|
horizontalHeader->setStretchLastSection(false);
|
|
|
|
horizontalHeader->setSectionResizeMode(0, QHeaderView::Interactive); // Формат
|
|
horizontalHeader->setSectionResizeMode(1, QHeaderView::Interactive); // Зона
|
|
horizontalHeader->setSectionResizeMode(2, QHeaderView::Interactive); // Поз.
|
|
horizontalHeader->setSectionResizeMode(3, QHeaderView::Interactive); // Обозначение
|
|
horizontalHeader->setSectionResizeMode(4, QHeaderView::Interactive); // Наименование
|
|
horizontalHeader->setSectionResizeMode(5, QHeaderView::Interactive); // Количество
|
|
horizontalHeader->setSectionResizeMode(6, QHeaderView::Interactive); // Примечание
|
|
|
|
horizontalHeader->resizeSection(0, 60); // Формат - 60px
|
|
horizontalHeader->resizeSection(1, 50); // Зона - 50px
|
|
horizontalHeader->resizeSection(2, 80); // Поз. - 80px
|
|
horizontalHeader->resizeSection(3, 150); // Обозначение - 150px
|
|
horizontalHeader->resizeSection(4, 200); // Наименование - 200px
|
|
horizontalHeader->resizeSection(5, 60); // Количество - 60px
|
|
horizontalHeader->resizeSection(6, 150); // Примечание - 150px
|
|
|
|
//horizontalHeader->resizeSections();
|
|
|
|
qDebug() << "DocumentEditWidget::applyColumnStretching: Настройки для SpecificationPCB применены";
|
|
return;
|
|
}
|
|
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor) {
|
|
// Настройки для Vedomost (Ведомость покупных изделий) - 10 колонок
|
|
QHeaderView *horizontalHeader = m_tableView->horizontalHeader();
|
|
|
|
horizontalHeader->setStretchLastSection(false);
|
|
|
|
horizontalHeader->setSectionResizeMode(0, QHeaderView::Interactive); // Наименование
|
|
horizontalHeader->setSectionResizeMode(1, QHeaderView::Interactive); // Код продукции
|
|
horizontalHeader->setSectionResizeMode(2, QHeaderView::Interactive); // Обозначение документа на поставку
|
|
horizontalHeader->setSectionResizeMode(3, QHeaderView::Interactive); // Поставщик
|
|
horizontalHeader->setSectionResizeMode(4, QHeaderView::Interactive); // Куда входит (обозначение)
|
|
horizontalHeader->setSectionResizeMode(5, QHeaderView::Interactive); // Количество на изделие
|
|
horizontalHeader->setSectionResizeMode(6, QHeaderView::Interactive); // Количество в комплекте
|
|
horizontalHeader->setSectionResizeMode(7, QHeaderView::Interactive); // Количество на регулир
|
|
horizontalHeader->setSectionResizeMode(8, QHeaderView::Interactive); // Количество всего
|
|
horizontalHeader->setSectionResizeMode(9, QHeaderView::Interactive); // Примечание
|
|
|
|
horizontalHeader->resizeSection(0, 200); // Наименование - 200px
|
|
horizontalHeader->resizeSection(1, 120); // Код продукции - 120px
|
|
horizontalHeader->resizeSection(2, 150); // Обозначение документа на поставку - 150px
|
|
horizontalHeader->resizeSection(3, 100); // Поставщик - 100px
|
|
horizontalHeader->resizeSection(4, 120); // Куда входит (обозначение) - 120px
|
|
horizontalHeader->resizeSection(5, 100); // Количество на изделие - 100px
|
|
horizontalHeader->resizeSection(6, 100); // Количество в комплекте - 100px
|
|
horizontalHeader->resizeSection(7, 100); // Количество на регулир - 100px
|
|
horizontalHeader->resizeSection(8, 100); // Количество всего - 100px
|
|
horizontalHeader->resizeSection(9, 150); // Примечание - 150px
|
|
|
|
qDebug() << "DocumentEditWidget::applyColumnStretching: Настройки для Vedomost применены";
|
|
return;
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::applyColumnStretching: Неизвестный тип процессора";
|
|
}
|
|
|
|
void DocumentEditWidget::onContextMenuRequested(const QPoint &pos)
|
|
{
|
|
QModelIndex index = m_tableView->indexAt(pos);
|
|
if (!index.isValid()) {
|
|
return;
|
|
}
|
|
|
|
int row = index.row();
|
|
|
|
// Получаем выделенные строки
|
|
QItemSelectionModel *selectionModel = m_tableView->selectionModel();
|
|
QModelIndexList selectedRows = selectionModel->selectedRows();
|
|
int selectedCount = selectedRows.size();
|
|
|
|
QMenu contextMenu(this);
|
|
|
|
QAction *addRowAction = contextMenu.addAction("Добавить пустую строку");
|
|
connect(addRowAction, &QAction::triggered, this, &DocumentEditWidget::onContextMenuAddRow);
|
|
|
|
// Показываем либо "Удалить строку", либо "Удалить n строк" в зависимости от количества выделенных
|
|
QAction *removeRowAction;
|
|
if (selectedCount > 1) {
|
|
removeRowAction = contextMenu.addAction(QString("Удалить %1 строк").arg(selectedCount));
|
|
connect(removeRowAction, &QAction::triggered, this, &DocumentEditWidget::onContextMenuRemoveSelectedRows);
|
|
} else {
|
|
removeRowAction = contextMenu.addAction("Удалить строку");
|
|
connect(removeRowAction, &QAction::triggered, this, &DocumentEditWidget::onContextMenuRemoveRow);
|
|
}
|
|
|
|
// Добавляем подменю "Объединить" если выбрано несколько строк
|
|
if (selectedCount > 1) {
|
|
contextMenu.addSeparator();
|
|
QMenu *mergeMenu = contextMenu.addMenu(QString("Объединить %1 строк").arg(selectedCount));
|
|
|
|
QAction *mergeAllAction = mergeMenu->addAction("Объединить все");
|
|
connect(mergeAllAction, &QAction::triggered, this, &DocumentEditWidget::onContextMenuMergeRows);
|
|
|
|
// Получаем столбец, на котором был клик
|
|
int clickedColumn = index.column();
|
|
QString columnName = m_tableView->model()->headerData(clickedColumn, Qt::Horizontal, Qt::DisplayRole).toString();
|
|
if (columnName.isEmpty()) {
|
|
columnName = QString("Столбец %1").arg(clickedColumn + 1);
|
|
}
|
|
|
|
QAction *mergeColumnAction = mergeMenu->addAction(QString("Объединить только \"%1\"").arg(columnName));
|
|
// Сохраняем номер столбца в данных действия для использования в слоте
|
|
mergeColumnAction->setData(clickedColumn);
|
|
connect(mergeColumnAction, &QAction::triggered, this, &DocumentEditWidget::onContextMenuMergeColumn);
|
|
}
|
|
|
|
contextMenu.addSeparator();
|
|
|
|
QAction *cellSettingsAction = contextMenu.addAction("Настройка ячейки...");
|
|
connect(cellSettingsAction, &QAction::triggered, this, &DocumentEditWidget::onContextMenuCellSettings);
|
|
|
|
contextMenu.exec(m_tableView->viewport()->mapToGlobal(pos));
|
|
}
|
|
|
|
void DocumentEditWidget::onContextMenuAddRow()
|
|
{
|
|
QModelIndex index = m_tableView->currentIndex();
|
|
if (!index.isValid()) {
|
|
return;
|
|
}
|
|
|
|
int row = index.row();
|
|
|
|
// Добавляем пустую строку после текущей
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor && m_controller && m_controller->perechenTableController()) {
|
|
m_controller->perechenTableController()->addEmptyRowAt(row + 1);
|
|
}
|
|
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor && m_controller && m_controller->specificationPCBController()) {
|
|
m_controller->specificationPCBController()->addEmptyRowAt(row + 1);
|
|
}
|
|
|
|
SpecificationProcessor *specProcessor = qobject_cast<SpecificationProcessor*>(m_processor);
|
|
if (specProcessor && m_controller && m_controller->specificationController()) {
|
|
m_controller->specificationController()->addEmptyRowAt(row + 1);
|
|
}
|
|
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor && m_controller && m_controller->vedomostController()) {
|
|
m_controller->vedomostController()->addEmptyRowAt(row + 1);
|
|
}
|
|
}
|
|
|
|
void DocumentEditWidget::onContextMenuRemoveRow()
|
|
{
|
|
QModelIndex index = m_tableView->currentIndex();
|
|
if (!index.isValid()) {
|
|
return;
|
|
}
|
|
|
|
int row = index.row();
|
|
onRemoveRow();
|
|
}
|
|
|
|
void DocumentEditWidget::onContextMenuRemoveSelectedRows()
|
|
{
|
|
// Получаем выделенные строки
|
|
QItemSelectionModel *selectionModel = m_tableView->selectionModel();
|
|
QModelIndexList selectedRows = selectionModel->selectedRows();
|
|
|
|
if (selectedRows.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
// Собираем номера строк и сортируем в обратном порядке (для корректного удаления)
|
|
QList<int> rowsToDelete;
|
|
for (const QModelIndex &index : selectedRows) {
|
|
if (index.isValid()) {
|
|
rowsToDelete.append(index.row());
|
|
}
|
|
}
|
|
|
|
// Удаляем дубликаты и сортируем в обратном порядке
|
|
std::sort(rowsToDelete.begin(), rowsToDelete.end());
|
|
rowsToDelete.erase(std::unique(rowsToDelete.begin(), rowsToDelete.end()), rowsToDelete.end());
|
|
std::reverse(rowsToDelete.begin(), rowsToDelete.end());
|
|
|
|
int count = rowsToDelete.size();
|
|
|
|
// Запрашиваем подтверждение
|
|
QMessageBox::StandardButton reply = QMessageBox::question(
|
|
this,
|
|
tr("Подтверждение удаления"),
|
|
tr("Вы уверены, что хотите удалить %1 строк?").arg(count),
|
|
QMessageBox::Yes | QMessageBox::No
|
|
);
|
|
|
|
if (reply != QMessageBox::Yes) {
|
|
return;
|
|
}
|
|
|
|
// Удаляем строки в обратном порядке (чтобы индексы не сбивались)
|
|
for (int row : rowsToDelete) {
|
|
// Проверяем, можно ли удалить эту строку
|
|
bool canDelete = true;
|
|
|
|
// Проверяем для каждого типа процессора
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor && m_controller && m_controller->perechenTableModel()) {
|
|
canDelete = m_controller->perechenTableModel()->canEditRow(row);
|
|
}
|
|
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor && m_controller && m_controller->specificationPCBTableModel()) {
|
|
canDelete = m_controller->specificationPCBTableModel()->canEditRow(row);
|
|
}
|
|
|
|
SpecificationProcessor *specProcessor = qobject_cast<SpecificationProcessor*>(m_processor);
|
|
if (specProcessor && m_controller && m_controller->specificationTableModel()) {
|
|
canDelete = m_controller->specificationTableModel()->canEditRow(row);
|
|
}
|
|
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor && m_controller && m_controller->vedomostTableModel()) {
|
|
canDelete = m_controller->vedomostTableModel()->canEditRow(row);
|
|
}
|
|
|
|
if (!canDelete) {
|
|
qDebug() << "DocumentEditWidget::onContextMenuRemoveSelectedRows: Строка" << row << "не может быть удалена (заголовок или автоматически сгенерированная)";
|
|
continue;
|
|
}
|
|
|
|
// Удаляем строку через соответствующий контроллер
|
|
if (perechenProcessor && m_controller && m_controller->perechenTableController()) {
|
|
m_controller->perechenTableController()->removeRow(row);
|
|
} else if (specPCBProcessor && m_controller && m_controller->specificationPCBController()) {
|
|
m_controller->specificationPCBController()->removeRow(row);
|
|
} else if (specProcessor && m_controller && m_controller->specificationController()) {
|
|
m_controller->specificationController()->removeRow(row);
|
|
} else if (vedomostProcessor && m_controller && m_controller->vedomostController()) {
|
|
m_controller->vedomostController()->removeRow(row);
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onContextMenuRemoveSelectedRows: Удалено строк:" << count;
|
|
}
|
|
|
|
void DocumentEditWidget::onContextMenuMergeRows()
|
|
{
|
|
// Получаем выделенные строки
|
|
QItemSelectionModel *selectionModel = m_tableView->selectionModel();
|
|
QModelIndexList selectedRows = selectionModel->selectedRows();
|
|
|
|
if (selectedRows.size() < 2) {
|
|
return; // Нужно минимум 2 строки для объединения
|
|
}
|
|
|
|
// Собираем номера строк и сортируем
|
|
QList<int> rowsToMerge;
|
|
for (const QModelIndex &index : selectedRows) {
|
|
if (index.isValid()) {
|
|
rowsToMerge.append(index.row());
|
|
}
|
|
}
|
|
|
|
// Удаляем дубликаты и сортируем
|
|
std::sort(rowsToMerge.begin(), rowsToMerge.end());
|
|
rowsToMerge.erase(std::unique(rowsToMerge.begin(), rowsToMerge.end()), rowsToMerge.end());
|
|
|
|
if (rowsToMerge.size() < 2) {
|
|
return;
|
|
}
|
|
|
|
int firstRow = rowsToMerge.first();
|
|
int columnCount = m_tableView->model()->columnCount();
|
|
|
|
// Объединяем содержимое ячеек для каждой колонки
|
|
for (int col = 0; col < columnCount; ++col) {
|
|
QStringList mergedValues;
|
|
|
|
// Собираем значения из всех выбранных строк
|
|
for (int row : rowsToMerge) {
|
|
QModelIndex cellIndex = m_tableView->model()->index(row, col);
|
|
if (cellIndex.isValid()) {
|
|
QString cellValue = m_tableView->model()->data(cellIndex, Qt::DisplayRole).toString().trimmed();
|
|
if (!cellValue.isEmpty()) {
|
|
mergedValues.append(cellValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Объединяем значения через пробел
|
|
QString mergedValue = mergedValues.join(" ");
|
|
|
|
// Записываем объединенное значение в первую строку
|
|
QModelIndex firstCellIndex = m_tableView->model()->index(firstRow, col);
|
|
if (firstCellIndex.isValid()) {
|
|
// Сохраняем CellData из первой строки (если есть)
|
|
QVariant originalCellData = m_tableView->model()->data(firstCellIndex, Qt::UserRole);
|
|
|
|
// Устанавливаем новое значение
|
|
m_tableView->model()->setData(firstCellIndex, mergedValue, Qt::EditRole);
|
|
|
|
// Если была структура CellData, обновляем значение в ней
|
|
if (originalCellData.isValid()) {
|
|
if (originalCellData.canConvert<PerechenCellData>()) {
|
|
PerechenCellData cell = originalCellData.value<PerechenCellData>();
|
|
cell.value = mergedValue;
|
|
m_tableView->model()->setData(firstCellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
} else if (originalCellData.canConvert<SpecificationPCBCellData>()) {
|
|
SpecificationPCBCellData cell = originalCellData.value<SpecificationPCBCellData>();
|
|
cell.value = mergedValue;
|
|
m_tableView->model()->setData(firstCellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
} else if (originalCellData.canConvert<SpecificationCellData>()) {
|
|
SpecificationCellData cell = originalCellData.value<SpecificationCellData>();
|
|
cell.value = mergedValue;
|
|
m_tableView->model()->setData(firstCellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
} else if (originalCellData.canConvert<VedomostCellData>()) {
|
|
VedomostCellData cell = originalCellData.value<VedomostCellData>();
|
|
cell.value = mergedValue;
|
|
m_tableView->model()->setData(firstCellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Удаляем остальные строки в обратном порядке (чтобы индексы не сбивались)
|
|
QList<int> rowsToDelete = rowsToMerge;
|
|
rowsToDelete.removeFirst(); // Не удаляем первую строку
|
|
std::reverse(rowsToDelete.begin(), rowsToDelete.end());
|
|
|
|
// Удаляем строки через соответствующий контроллер
|
|
for (int row : rowsToDelete) {
|
|
// Проверяем, можно ли удалить эту строку
|
|
bool canDelete = true;
|
|
|
|
PerechenProcessor *perechenProcessor = qobject_cast<PerechenProcessor*>(m_processor);
|
|
if (perechenProcessor && m_controller && m_controller->perechenTableModel()) {
|
|
canDelete = m_controller->perechenTableModel()->canEditRow(row);
|
|
}
|
|
|
|
SpecificationPCBProcessor *specPCBProcessor = qobject_cast<SpecificationPCBProcessor*>(m_processor);
|
|
if (specPCBProcessor && m_controller && m_controller->specificationPCBTableModel()) {
|
|
canDelete = m_controller->specificationPCBTableModel()->canEditRow(row);
|
|
}
|
|
|
|
SpecificationProcessor *specProcessor = qobject_cast<SpecificationProcessor*>(m_processor);
|
|
if (specProcessor && m_controller && m_controller->specificationTableModel()) {
|
|
canDelete = m_controller->specificationTableModel()->canEditRow(row);
|
|
}
|
|
|
|
VedomostProcessor *vedomostProcessor = qobject_cast<VedomostProcessor*>(m_processor);
|
|
if (vedomostProcessor && m_controller && m_controller->vedomostTableModel()) {
|
|
canDelete = m_controller->vedomostTableModel()->canEditRow(row);
|
|
}
|
|
|
|
if (!canDelete) {
|
|
qDebug() << "DocumentEditWidget::onContextMenuMergeRows: Строка" << row << "не может быть удалена (заголовок или автоматически сгенерированная)";
|
|
continue;
|
|
}
|
|
|
|
// Удаляем строку через соответствующий контроллер
|
|
if (perechenProcessor && m_controller && m_controller->perechenTableController()) {
|
|
m_controller->perechenTableController()->removeRow(row);
|
|
} else if (specPCBProcessor && m_controller && m_controller->specificationPCBController()) {
|
|
m_controller->specificationPCBController()->removeRow(row);
|
|
} else if (specProcessor && m_controller && m_controller->specificationController()) {
|
|
m_controller->specificationController()->removeRow(row);
|
|
} else if (vedomostProcessor && m_controller && m_controller->vedomostController()) {
|
|
m_controller->vedomostController()->removeRow(row);
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onContextMenuMergeRows: Объединено строк:" << rowsToMerge.size() << "в строку" << firstRow;
|
|
}
|
|
|
|
void DocumentEditWidget::onContextMenuMergeColumn()
|
|
{
|
|
// Получаем выделенные строки
|
|
QItemSelectionModel *selectionModel = m_tableView->selectionModel();
|
|
QModelIndexList selectedRows = selectionModel->selectedRows();
|
|
|
|
if (selectedRows.size() < 2) {
|
|
return; // Нужно минимум 2 строки для объединения
|
|
}
|
|
|
|
// Получаем столбец из действия, которое вызвало слот
|
|
QAction *action = qobject_cast<QAction*>(sender());
|
|
if (!action) {
|
|
return;
|
|
}
|
|
|
|
int targetColumn = action->data().toInt();
|
|
if (targetColumn < 0) {
|
|
return;
|
|
}
|
|
|
|
// Собираем номера строк и сортируем
|
|
QList<int> rowsToMerge;
|
|
for (const QModelIndex &index : selectedRows) {
|
|
if (index.isValid()) {
|
|
rowsToMerge.append(index.row());
|
|
}
|
|
}
|
|
|
|
// Удаляем дубликаты и сортируем
|
|
std::sort(rowsToMerge.begin(), rowsToMerge.end());
|
|
rowsToMerge.erase(std::unique(rowsToMerge.begin(), rowsToMerge.end()), rowsToMerge.end());
|
|
|
|
if (rowsToMerge.size() < 2) {
|
|
return;
|
|
}
|
|
|
|
int firstRow = rowsToMerge.first();
|
|
|
|
// Объединяем содержимое ячеек только для выбранного столбца
|
|
QStringList mergedValues;
|
|
|
|
// Собираем значения из всех выбранных строк для выбранного столбца
|
|
for (int row : rowsToMerge) {
|
|
QModelIndex cellIndex = m_tableView->model()->index(row, targetColumn);
|
|
if (cellIndex.isValid()) {
|
|
QString cellValue = m_tableView->model()->data(cellIndex, Qt::DisplayRole).toString().trimmed();
|
|
if (!cellValue.isEmpty()) {
|
|
mergedValues.append(cellValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Объединяем значения через пробел
|
|
QString mergedValue = mergedValues.join(" ");
|
|
|
|
// Записываем объединенное значение в первую строку
|
|
QModelIndex firstCellIndex = m_tableView->model()->index(firstRow, targetColumn);
|
|
if (firstCellIndex.isValid()) {
|
|
// Сохраняем CellData из первой строки (если есть)
|
|
QVariant originalCellData = m_tableView->model()->data(firstCellIndex, Qt::UserRole);
|
|
|
|
// Устанавливаем новое значение
|
|
m_tableView->model()->setData(firstCellIndex, mergedValue, Qt::EditRole);
|
|
|
|
// Если была структура CellData, обновляем значение в ней
|
|
if (originalCellData.isValid()) {
|
|
if (originalCellData.canConvert<PerechenCellData>()) {
|
|
PerechenCellData cell = originalCellData.value<PerechenCellData>();
|
|
cell.value = mergedValue;
|
|
m_tableView->model()->setData(firstCellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
} else if (originalCellData.canConvert<SpecificationPCBCellData>()) {
|
|
SpecificationPCBCellData cell = originalCellData.value<SpecificationPCBCellData>();
|
|
cell.value = mergedValue;
|
|
m_tableView->model()->setData(firstCellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
} else if (originalCellData.canConvert<SpecificationCellData>()) {
|
|
SpecificationCellData cell = originalCellData.value<SpecificationCellData>();
|
|
cell.value = mergedValue;
|
|
m_tableView->model()->setData(firstCellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
} else if (originalCellData.canConvert<VedomostCellData>()) {
|
|
VedomostCellData cell = originalCellData.value<VedomostCellData>();
|
|
cell.value = mergedValue;
|
|
m_tableView->model()->setData(firstCellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Очищаем значения в остальных строках для выбранного столбца
|
|
QList<int> rowsToClear = rowsToMerge;
|
|
rowsToClear.removeFirst(); // Не очищаем первую строку
|
|
|
|
for (int row : rowsToClear) {
|
|
QModelIndex cellIndex = m_tableView->model()->index(row, targetColumn);
|
|
if (cellIndex.isValid()) {
|
|
// Очищаем значение, но сохраняем структуру CellData
|
|
QVariant originalCellData = m_tableView->model()->data(cellIndex, Qt::UserRole);
|
|
|
|
m_tableView->model()->setData(cellIndex, "", Qt::EditRole);
|
|
|
|
// Обновляем значение в CellData, если оно есть
|
|
if (originalCellData.isValid()) {
|
|
if (originalCellData.canConvert<PerechenCellData>()) {
|
|
PerechenCellData cell = originalCellData.value<PerechenCellData>();
|
|
cell.value = "";
|
|
m_tableView->model()->setData(cellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
} else if (originalCellData.canConvert<SpecificationPCBCellData>()) {
|
|
SpecificationPCBCellData cell = originalCellData.value<SpecificationPCBCellData>();
|
|
cell.value = "";
|
|
m_tableView->model()->setData(cellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
} else if (originalCellData.canConvert<SpecificationCellData>()) {
|
|
SpecificationCellData cell = originalCellData.value<SpecificationCellData>();
|
|
cell.value = "";
|
|
m_tableView->model()->setData(cellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
} else if (originalCellData.canConvert<VedomostCellData>()) {
|
|
VedomostCellData cell = originalCellData.value<VedomostCellData>();
|
|
cell.value = "";
|
|
m_tableView->model()->setData(cellIndex, QVariant::fromValue(cell), Qt::UserRole);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
qDebug() << "DocumentEditWidget::onContextMenuMergeColumn: Объединен столбец" << targetColumn
|
|
<< "для строк:" << rowsToMerge.size() << "в строку" << firstRow;
|
|
}
|
|
|
|
void DocumentEditWidget::onContextMenuCellSettings()
|
|
{
|
|
QModelIndex index = m_tableView->currentIndex();
|
|
if (!index.isValid()) {
|
|
return;
|
|
}
|
|
|
|
int row = index.row();
|
|
int column = index.column();
|
|
|
|
// Получаем название ячейки из заголовка
|
|
QString cellName = m_tableView->model()->headerData(column, Qt::Horizontal, Qt::DisplayRole).toString();
|
|
if (cellName.isEmpty()) {
|
|
cellName = QString("Колонка %1").arg(column + 1);
|
|
}
|
|
|
|
// Получаем текущие значения из модели
|
|
int currentStretch = 100;
|
|
bool currentIsHeader = false;
|
|
bool currentIsUnderline = true;
|
|
QVariant cellData = m_tableView->model()->data(index, Qt::UserRole);
|
|
if (cellData.isValid()) {
|
|
// Извлекаем значения из CellData
|
|
if (cellData.canConvert<PerechenCellData>()) {
|
|
PerechenCellData cell = cellData.value<PerechenCellData>();
|
|
currentStretch = cell.stretch;
|
|
currentIsHeader = cell.isHeader;
|
|
currentIsUnderline = cell.isUnderline;
|
|
} else if (cellData.canConvert<SpecificationPCBCellData>()) {
|
|
SpecificationPCBCellData cell = cellData.value<SpecificationPCBCellData>();
|
|
currentStretch = cell.stretch;
|
|
currentIsHeader = cell.isHeader;
|
|
currentIsUnderline = cell.isUnderline;
|
|
} else if (cellData.canConvert<SpecificationCellData>()) {
|
|
SpecificationCellData cell = cellData.value<SpecificationCellData>();
|
|
currentStretch = cell.stretch;
|
|
currentIsHeader = cell.isHeader;
|
|
currentIsUnderline = cell.isUnderline;
|
|
} else if (cellData.canConvert<VedomostCellData>()) {
|
|
VedomostCellData cell = cellData.value<VedomostCellData>();
|
|
currentStretch = cell.stretch;
|
|
currentIsHeader = cell.isHeader;
|
|
currentIsUnderline = cell.isUnderline;
|
|
}
|
|
}
|
|
|
|
// Создаем диалог настройки ячейки
|
|
CellSettingsDialog dialog(row, column, cellName, currentStretch, currentIsHeader, currentIsUnderline, this);
|
|
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
int newStretch = dialog.getStretch();
|
|
bool newIsHeader = dialog.isHeader();
|
|
bool newIsUnderline = dialog.isUnderline();
|
|
qDebug() << "DocumentEditWidget::onContextMenuCellSettings: Установлены настройки для ячейки row=" << row << "column=" << column
|
|
<< "stretch=" << newStretch << "isHeader=" << newIsHeader << "isUnderline=" << newIsUnderline;
|
|
|
|
// Обновляем настройки в соответствующей модели
|
|
bool success = false;
|
|
PerechenTableModel *perechenModel = getPerechenTableModel();
|
|
if (perechenModel) {
|
|
// Вызываем все три метода независимо - они вернут true, если значение изменилось
|
|
perechenModel->setCellStretch(row, column, newStretch);
|
|
perechenModel->setCellHeader(row, column, newIsHeader);
|
|
perechenModel->setCellUnderline(row, column, newIsUnderline);
|
|
success = true; // Всегда успех, если модель доступна
|
|
} else {
|
|
SpecificationPCBTableModel *specPCBModel = getSpecificationPCBTableModel();
|
|
if (specPCBModel) {
|
|
// Вызываем все три метода независимо - они вернут true, если значение изменилось
|
|
specPCBModel->setCellStretch(row, column, newStretch);
|
|
specPCBModel->setCellHeader(row, column, newIsHeader);
|
|
specPCBModel->setCellUnderline(row, column, newIsUnderline);
|
|
success = true; // Всегда успех, если модель доступна
|
|
} else {
|
|
SpecificationTableModel *specModel = getSpecificationTableModel();
|
|
if (specModel) {
|
|
// Вызываем все три метода независимо - они вернут true, если значение изменилось
|
|
specModel->setCellStretch(row, column, newStretch);
|
|
specModel->setCellHeader(row, column, newIsHeader);
|
|
specModel->setCellUnderline(row, column, newIsUnderline);
|
|
success = true; // Всегда успех, если модель доступна
|
|
} else {
|
|
VedomostTableModel *vedomostModel = getVedomostTableModel();
|
|
if (vedomostModel) {
|
|
// Вызываем все три метода независимо - они вернут true, если значение изменилось
|
|
vedomostModel->setCellStretch(row, column, newStretch);
|
|
vedomostModel->setCellHeader(row, column, newIsHeader);
|
|
vedomostModel->setCellUnderline(row, column, newIsUnderline);
|
|
success = true; // Всегда успех, если модель доступна
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (success) {
|
|
qDebug() << "DocumentEditWidget::onContextMenuCellSettings: Настройки успешно сохранены в модель";
|
|
} else {
|
|
qDebug() << "DocumentEditWidget::onContextMenuCellSettings: Ошибка при сохранении настроек в модель - модель не найдена";
|
|
}
|
|
}
|
|
} |