Files
GostGenerator/view/documentprocessor.cpp
T

2106 lines
112 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> &params)
{
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> &params)
{
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> &params)
{
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> &params)
{
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;
}
// Проверяем, является ли процессор SpecificationProcessor
SpecificationProcessor *specProcessor = qobject_cast<SpecificationProcessor*>(m_processor);
if (specProcessor) {
// Проверяем, можно ли удалить эту строку
if (m_controller && m_controller->specificationTableModel()) {
if (!m_controller->specificationTableModel()->canEditRow(row)) {
qDebug() << "DocumentEditWidget::onRemoveRow: Строка" << row << "не может быть удалена (заголовок или автоматически сгенерированная)";
return;
}
}
qDebug() << "DocumentEditWidget::onRemoveRow: Удаляем строку" << row;
// Получаем контроллер и удаляем строку
if (m_controller && m_controller->specificationController()) {
m_controller->specificationController()->removeRow(row);
qDebug() << "DocumentEditWidget::onRemoveRow: Строка удалена через SpecificationController";
} else {
qDebug() << "DocumentEditWidget::onRemoveRow: SpecificationController недоступен";
}
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: Ошибка при сохранении настроек в модель - модель не найдена";
}
}
}