Files
GostGenerator/view/mainwindow.cpp
T

1640 lines
80 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "mainwindow.h"
#include "../model/componentmodel.h"
#include "../model/perechentablemodel.h"
#include "../model/specificationpcbtablemodel.h"
#include "../model/specificationtablemodel.h"
#include "../model/vedomosttablemodel.h"
#include "../model/titleinscriptionsmodel.h"
#include "../model/projectparamtablemodel.h"
#include "../controller/altiumparser.h"
#include "../controller/maincontroller.h"
#include "../controller/pdfcontroller.h"
#include "projectsettingsdialog.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QCloseEvent>
#include <QFileInfo>
#include <QDebug> // Added for qDebug
#include <QMap>
#include <QDesktopServices>
#include <QUrl>
#include <QCoreApplication>
#include <QIcon>
MainWindow::MainWindow(MainController *controller, QWidget *parent): QMainWindow(parent), m_controller(controller), m_isParsing(false){
setUp();
updateWindowTitle();
// Устанавливаем иконку окна
setWindowIcon(QIcon(":/assets/icon2.png"));
// Отключаем все элементы интерфейса кроме создания/открытия проекта
disableInterfaceExceptProjectActions();
show();
}
MainWindow::~MainWindow() {}
void MainWindow::setUp(){
setWidgets();
setUpLayout();
setUpConnections();
}
void MainWindow::setWidgets(){
m_editWidget = new EditPDFWidget(m_controller, this);
m_pdfWidget = new PreviewPdfWidget(this);
m_dataView = new ImportedDataView(m_controller->componentTableModel(), m_controller->projectParamTableModel(), m_controller->pcbMaterialModel(), this);
// Передаем MainController в PreviewPdfWidget
m_pdfWidget->setMainController(m_controller);
// Подключаем сигнал изменения типа документа от EditPDFWidget к PreviewPdfWidget
connect(m_editWidget, &EditPDFWidget::documentTypeChanged,
m_pdfWidget, &PreviewPdfWidget::onDocumentTypeChanged);
// Передаем данные в EditPDFWidget
qDebug() << "MainWindow::setWidgets: Передаем ComponentTableModel:" << m_controller->componentTableModel();
qDebug() << "MainWindow::setWidgets: Компонентов в модели:" << m_controller->componentTableModel()->getComponents().size();
m_editWidget->setData(m_controller->componentTableModel(), m_controller->projectParamTableModel());
// Подключаем сигнал изменения варианта от ComponentsPreview после создания m_dataView
if (m_dataView && m_dataView->getComponentsPreview()) {
connect(m_dataView->getComponentsPreview(), &ComponentsPreview::variantChanged,
[this](const QString &variant) {
qDebug() << "MainWindow: Получен сигнал variantChanged:" << variant;
// Обновляем вариант в настройках проекта
m_controller->projectSettingsModel()->setCurrentVariant(variant);
// Обновляем текущий вариант в контроллере
m_controller->setCurrentVariant(variant);
// Перезагружаем компоненты с новым вариантом
m_controller->loadComponentsFromDatabase();
// Сохраняем настройки в базу данных
m_controller->saveProjectSettingsToDatabase();
});
}
// Инициализация элементов для асинхронного парсинга
m_progressBar = new QProgressBar(this);
m_progressBar->setVisible(false);
m_progressBar->setRange(0, 100);
m_progressBar->setValue(0);
m_cancelParsingAction = new QAction(tr("Отменить парсинг"), this);
m_cancelParsingAction->setVisible(false);
}
void MainWindow::setUpLayout(){
//Меню
m_centralWidget = new QWidget(this);
QHBoxLayout* mainLayout = new QHBoxLayout(m_centralWidget);
mainLayout->addWidget(m_editWidget);
setCentralWidget(m_centralWidget);
// Устанавливаем менюбар
m_menuBar = new QMenuBar(this);
setMenuBar(m_menuBar);
m_fileMenu = m_menuBar->addMenu(tr("&Файл"));
QAction* undoAction = m_fileMenu->addAction("Отменить", this, &MainWindow::onUndo, QKeySequence::Undo);
QAction* redoAction = m_fileMenu->addAction("Повторить", this, &MainWindow::onRedo, QKeySequence::Redo);
undoAction->setEnabled(false);
redoAction->setEnabled(false);
m_fileMenu->addSeparator();
m_fileMenu->addAction("&Новый проект", this, &MainWindow::onFileNew, QKeySequence::New);
m_fileMenu->addAction("&Открыть проект", this, &MainWindow::onFileOpen, QKeySequence::Open);
m_fileMenu->addAction("&Сохранить проект", this, &MainWindow::onFileSave, QKeySequence::Save);
m_fileMenu->addAction("Сохранить &как...", this, &MainWindow::onFileSaveAs, QKeySequence::SaveAs);
m_fileMenu->addSeparator();
m_fileMenu->addAction("&Импорт Altium файла", this, &MainWindow::onFileImportAltium);
m_fileMenu->addSeparator();
m_fileMenu->addAction("&Настройки проекта", this, &MainWindow::onProjectSettings);
m_fileMenu->addSeparator();
m_fileMenu->addAction("&Выход", this, &MainWindow::onFileExit, QKeySequence::Quit);
m_exportMenu = m_menuBar->addMenu(tr("&Экспорт"));
// Подменю для экспорта в PDF
QMenu* pdfMenu = m_exportMenu->addMenu(tr("Экспорт в &PDF"));
pdfMenu->addAction("&Спецификация (PDF)", this, &MainWindow::onExportSpecification);
pdfMenu->addAction("&Перечень элементов (PDF)", this, &MainWindow::onExportPerechen);
pdfMenu->addAction("&Ведомость покупных изделий (PDF)", this, &MainWindow::onExportPurchaseList);
pdfMenu->addAction("Спецификация &PCB (PDF)", this, &MainWindow::onExportSpecificationPcb);
pdfMenu->addSeparator();
pdfMenu->addAction("Экспорт &всех в PDF", this, &MainWindow::onExportAll);
// Подменю для экспорта в CSV
QMenu* csvMenu = m_exportMenu->addMenu(tr("Экспорт в &CSV"));
csvMenu->addAction("&Спецификация (CSV)", this, &MainWindow::onExportSpecificationToCsv);
csvMenu->addAction("&Перечень элементов (CSV)", this, &MainWindow::onExportPerechenToCsv);
csvMenu->addAction("&Ведомость покупных изделий (CSV)", this, &MainWindow::onExportPurchaseListToCsv);
csvMenu->addAction("Спецификация &PCB (CSV)", this, &MainWindow::onExportSpecificationPcbToCsv);
m_viewMenu = m_menuBar->addMenu(tr("&Вид"));
QAction* dataPanelAction = m_viewMenu->addAction(tr("&Панель данных"), this, &MainWindow::onViewDataPanel);
dataPanelAction->setCheckable(true);
dataPanelAction->setChecked(true);
QAction* pdfPreviewAction = m_viewMenu->addAction(tr("&PDF Превью"), this, &MainWindow::onViewPdfPreview);
pdfPreviewAction->setCheckable(true);
pdfPreviewAction->setChecked(true);
m_viewMenu->addSeparator();
m_viewMenu->addAction(tr("&Сбросить расположение"), this, &MainWindow::onViewResetLayout);
m_helpMenu = m_menuBar->addMenu(tr("&Справка"));
m_helpMenu->addAction("&О программе", this, &MainWindow::onHelpAbout);
m_helpMenu->addAction("&Руководство", this, &MainWindow::onHelpManual);
//панель инструментов - первая строка
m_toolBar = new QToolBar(this);
addToolBar(m_toolBar);
m_toolBar->setMovable(false);
m_toolBar->addAction(tr("&Новый проект"), this, &MainWindow::onFileNew);
m_toolBar->addAction(tr("&Открыть проект"), this, &MainWindow::onFileOpen);
m_toolBar->addAction(tr("&Сохранить проект"), this, &MainWindow::onFileSave);
m_toolBar->addAction(tr("Сохранить &как..."), this, &MainWindow::onFileSaveAs);
m_toolBar->addSeparator();
m_toolBar->addAction(tr("&Настройки проекта"), this, &MainWindow::onProjectSettings);
m_toolBar->addAction(tr("&Импорт Altium файла"), this, &MainWindow::onFileImportAltium);
m_toolBar->addSeparator();
// Экспорт в PDF
m_toolBar->addAction(tr("Экспорт всех (PDF)"), this, &MainWindow::onExportAll);
m_toolBar->addAction(tr("Спецификация (PDF)"), this, &MainWindow::onExportSpecification);
m_toolBar->addAction(tr("Перечень (PDF)"), this, &MainWindow::onExportPerechen);
m_toolBar->addAction(tr("Ведомость (PDF)"), this, &MainWindow::onExportPurchaseList);
m_toolBar->addAction(tr("Спецификация PCB (PDF)"), this, &MainWindow::onExportSpecificationPcb);
//панель инструментов - вторая строка
m_toolBar2 = new QToolBar(this);
addToolBar(m_toolBar2);
m_toolBar2->setMovable(false);
// Экспорт в CSV
m_toolBar2->addAction(tr("Спецификация (CSV)"), this, &MainWindow::onExportSpecificationToCsv);
m_toolBar2->addAction(tr("Перечень (CSV)"), this, &MainWindow::onExportPerechenToCsv);
m_toolBar2->addAction(tr("Ведомость (CSV)"), this, &MainWindow::onExportPurchaseListToCsv);
m_toolBar2->addAction(tr("Спецификация PCB (CSV)"), this, &MainWindow::onExportSpecificationPcbToCsv);
m_toolBar2->addSeparator();
QAction* undoToolAction = m_toolBar2->addAction(tr("&Отменить"), this, &MainWindow::onUndo);
QAction* redoToolAction = m_toolBar2->addAction(tr("&Повторить"), this, &MainWindow::onRedo);
undoToolAction->setEnabled(false);
redoToolAction->setEnabled(false);
m_toolBar2->addSeparator();
// Добавляем кнопку отмены парсинга во второй тулбар
m_toolBar2->addAction(m_cancelParsingAction);
//Статусбар
m_statusBar = new QStatusBar(this);
setStatusBar(m_statusBar);
// Добавляем прогресс-бар в статус-бар
m_statusBar->addPermanentWidget(m_progressBar);
//Панель данных
m_dataPanelDockWidget = new QDockWidget(tr("Панель данных"), this);
m_dataPanelDockWidget->setWidget(m_dataView);
//ПДФ Превью
m_pdfPanelDockWidget = new QDockWidget(tr("PDF Превью"), this);
m_pdfPanelDockWidget->setWidget(m_pdfWidget);
//Добавляем панели в главное окно
addDockWidget(Qt::RightDockWidgetArea, m_dataPanelDockWidget);
addDockWidget(Qt::RightDockWidgetArea, m_pdfPanelDockWidget);
// Накладываем панели друг на друга в виде табов
tabifyDockWidget(m_dataPanelDockWidget, m_pdfPanelDockWidget);
// Показываем первую панель по умолчанию
m_dataPanelDockWidget->raise();
// Обновляем состояние меню "Вид"
updateViewMenuState();
}
void MainWindow::setUpConnections(){
// Подключаем сигналы для асинхронного парсинга
connect(m_cancelParsingAction, &QAction::triggered, this, [this]() {
if (m_controller && m_controller->isParsingAsync()) {
qDebug() << "MainWindow: Отмена парсинга по запросу пользователя";
m_controller->cancelParsing();
m_statusBar->showMessage(tr("Парсинг отменен"));
}
});
// Подключаем сигналы закрытия док-виджетов для обновления меню
if (m_dataPanelDockWidget) {
connect(m_dataPanelDockWidget, &QDockWidget::visibilityChanged, this, &MainWindow::updateViewMenuState);
}
if (m_pdfPanelDockWidget) {
connect(m_pdfPanelDockWidget, &QDockWidget::visibilityChanged, this, &MainWindow::updateViewMenuState);
}
// Подключаем сигнал изменения варианта от ComponentsPreview
if (m_dataView && m_dataView->getComponentsPreview()) {
connect(m_dataView->getComponentsPreview(), &ComponentsPreview::variantChanged,
[this](const QString &variant) {
qDebug() << "MainWindow: Получен сигнал variantChanged:" << variant;
// Обновляем вариант в настройках проекта
m_controller->projectSettingsModel()->setCurrentVariant(variant);
// Обновляем текущий вариант в контроллере
m_controller->setCurrentVariant(variant);
// Перезагружаем компоненты с новым вариантом
m_controller->loadComponentsFromDatabase();
// Сохраняем настройки в базу данных
m_controller->saveProjectSettingsToDatabase();
});
}
}
void MainWindow::onHelpAbout()
{
QMessageBox::about(this, "О программе",
"PDF Генератор и Парсер Altium\n"
"Версия 1.0.0\n\n"
"Программа для работы с проектами Altium Designer\n"
"и генерации PDF документов.");
}
void MainWindow::onHelpManual()
{
QMessageBox::information(this, "Руководство",
"Руководство пользователя будет доступно в следующей версии.");
}
void MainWindow::onFileNew(){
// Проверяем, нужно ли сохранить текущий проект
if (!askForSave()) {
return; // Пользователь отменил создание нового проекта
}
// Открываем диалог сохранения файла проекта
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Создать новый проект"),
QString(),
tr("PDF Проекты (*.pdfprj);;База данных (*.db);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Создание нового проекта: %1").arg(fileName));
// Сначала инициализируем глобальную БД для настроек
if (!m_controller->initializeGlobalDatabase()) {
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось инициализировать глобальную базу данных: %1")
.arg(QString(m_controller->lastError())));
return;
}
// Очищаем все данные перед созданием нового проекта
m_controller->clearAllData();
// Сбрасываем текущий вариант
m_controller->setCurrentVariant("No Variations");
// Инициализируем базу данных проекта
if (m_controller->initializeDatabase(fileName)) {
m_currentProjectPath = fileName;
updateWindowTitle();
m_dataView->updateView();
updateStatusBar();
enableInterface();
m_statusBar->showMessage(tr("Новый проект создан: %1").arg(fileName));
} else {
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось создать проект: %1")
.arg(QString(m_controller->lastError())));
}
}
}
void MainWindow::onFileOpen(){
// Проверяем, нужно ли сохранить текущий проект
if (!askForSave()) {
return; // Пользователь отменил открытие проекта
}
// Открываем диалог выбора файла проекта
QString fileName = QFileDialog::getOpenFileName(
this,
tr("Открыть проект"),
QString(),
tr("PDF Проекты (*.pdfprj);;База данных (*.db);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
openProjectFile(fileName);
}
}
void MainWindow::openProjectFile(const QString &fileName) {
if (fileName.isEmpty()) {
return;
}
// Проверяем существование файла
QFileInfo fileInfo(fileName);
if (!fileInfo.exists()) {
QMessageBox::critical(this, tr("Ошибка"),
tr("Файл не найден: %1").arg(fileName));
return;
}
// Проверяем расширение файла
QString extension = fileInfo.suffix().toLower();
if (extension != "pdfprj" && extension != "db") {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Неизвестный тип файла: %1\nОжидается файл проекта (.pdfprj)").arg(extension));
return;
}
m_statusBar->showMessage(tr("Открытие проекта: %1").arg(fileName));
// Глобальная БД уже должна быть инициализирована в main.cpp
// Если по какой-то причине она не инициализирована, попробуем инициализировать
// Но сначала проверим, не открыта ли она уже
// (повторная инициализация может вызвать ошибку, поэтому пропускаем, если уже открыта)
// Инициализируем базу данных проекта с выбранным файлом
if (m_controller->initializeDatabase(fileName)) {
// Сначала загружаем настройки проекта, чтобы установить правильный текущий вариант
m_controller->loadProjectSettingsFromDatabase();
// Затем загружаем компоненты с правильным текущим вариантом
if (m_controller->loadComponentsFromDatabase()) {
// Загружаем параметры проекта
m_controller->loadProjectParamsFromDatabase();
// Загружаем перечень элементов напрямую в модель MainController
QByteArray tableData = m_controller->loadPerechenTableFromDatabase();
if (!tableData.isEmpty()) {
PerechenTableModel *perechenModel = m_controller->perechenTableModel();
if (perechenModel) {
perechenModel->loadFromDatabase(tableData);
qDebug() << "MainWindow::onFileOpen: Таблица перечня загружена из БД в MainController";
} else {
qDebug() << "MainWindow::onFileOpen: PerechenTableModel недоступен в MainController";
}
} else {
qDebug() << "MainWindow::onFileOpen: Данные таблицы перечня не найдены в БД";
}
// Загружаем спецификацию ПП напрямую в модель MainController
QByteArray specPCBTableData = m_controller->loadSpecificationPCBTableFromDatabase();
if (!specPCBTableData.isEmpty()) {
SpecificationPCBTableModel *specPCBModel = m_controller->specificationPCBTableModel();
if (specPCBModel) {
specPCBModel->loadFromDatabase(specPCBTableData);
qDebug() << "MainWindow::onFileOpen: Таблица спецификации ПП загружена из БД в MainController";
} else {
qDebug() << "MainWindow::onFileOpen: SpecificationPCBTableModel недоступен в MainController";
}
} else {
qDebug() << "MainWindow::onFileOpen: Данные таблицы спецификации ПП не найдены в БД";
}
// Загружаем спецификацию материалов напрямую в модель MainController
QByteArray specTableData = m_controller->loadSpecificationTableFromDatabase();
if (!specTableData.isEmpty()) {
SpecificationTableModel *specModel = m_controller->specificationTableModel();
if (specModel) {
specModel->loadFromDatabase(specTableData);
qDebug() << "MainWindow::onFileOpen: Таблица спецификации материалов загружена из БД в MainController";
} else {
qDebug() << "MainWindow::onFileOpen: SpecificationTableModel недоступен в MainController";
}
} else {
qDebug() << "MainWindow::onFileOpen: Данные таблицы спецификации материалов не найдены в БД";
}
// Загружаем ведомость покупных изделий напрямую в модель MainController
QByteArray vedomostTableData = m_controller->loadVedomostTableFromDatabase();
if (!vedomostTableData.isEmpty()) {
VedomostTableModel *vedomostModel = m_controller->vedomostTableModel();
if (vedomostModel) {
vedomostModel->loadFromDatabase(vedomostTableData);
qDebug() << "MainWindow::onFileOpen: Таблица ведомости покупных изделий загружена из БД в MainController";
} else {
qDebug() << "MainWindow::onFileOpen: VedomostTableModel недоступен в MainController";
}
} else {
qDebug() << "MainWindow::onFileOpen: Данные таблицы ведомости покупных изделий не найдены в БД";
}
// Загружаем надписи титульного листа в MainController
QMap<int, QString> inscriptions;
if (m_controller->loadTitleInscriptionsFromDatabase(inscriptions)) {
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
if (titleModel) {
titleModel->setAllInscriptions(inscriptions);
qDebug() << "MainWindow::onFileOpen: Надписи титульного листа загружены в MainController";
} else {
qDebug() << "MainWindow::onFileOpen: TitleInscriptionsModel недоступен в MainController";
}
} else {
qDebug() << "MainWindow::onFileOpen: Надписи титульного листа не найдены в БД";
}
m_currentProjectPath = fileName;
updateWindowTitle();
updateStatusBar();
enableInterface();
m_statusBar->showMessage(tr("Проект успешно загружен: %1").arg(fileName));
// Обновляем все представления документов, включая таблицу перечня
m_editWidget->updateAllViews();
// Обновляем представление компонентов
m_dataView->updateView();
// Принудительно обновляем ComponentsPreview с правильным вариантом
if (m_dataView && m_dataView->getComponentsPreview()) {
QString currentVariant = m_controller->projectSettingsModel()->currentVariant();
qDebug() << "MainWindow: Устанавливаем текущий вариант в ComponentsPreview:" << currentVariant;
// Используем QTimer::singleShot для обеспечения полной загрузки модели
QTimer::singleShot(100, [this, currentVariant]() {
if (m_dataView && m_dataView->getComponentsPreview()) {
m_dataView->getComponentsPreview()->setCurrentVariant(currentVariant);
}
});
}
} else {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Проект загружен, но данные не найдены"));
}
} else {
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось открыть проект: %1")
.arg(QString(m_controller->lastError())));
}
}
bool MainWindow::onFileSave(){
// Сохраняем текущий проект
if (m_currentProjectPath.isEmpty()) {
// Если путь не установлен, вызываем "Сохранить как"
onFileSaveAs();
return !m_currentProjectPath.isEmpty(); // Возвращаем true если файл был сохранен
} else {
// Сохраняем основные данные в текущую БД (без свойств и вариантов)
bool success = true;
success &= m_controller->saveComponentsToDatabase();
success &= m_controller->saveProjectParamsToDatabase();
success &= m_controller->saveProjectSettingsToDatabase();
// Сохраняем надписи титульного листа из MainController
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
if (titleModel) {
QMap<int, QString> inscriptions = titleModel->getAllInscriptions();
success &= m_controller->saveTitleInscriptionsToDatabase(inscriptions);
qDebug() << "MainWindow::onFileSave: Надписи титульного листа сохранены из MainController";
} else {
qDebug() << "MainWindow::onFileSave: TitleInscriptionsModel недоступен в MainController";
}
// Сохраняем перечень элементов из модели MainController
PerechenTableModel *perechenModel = m_controller->perechenTableModel();
if (perechenModel) {
QByteArray tableData = perechenModel->saveToDatabase();
if (!tableData.isEmpty()) {
success &= m_controller->savePerechenTableToDatabase(tableData);
qDebug() << "MainWindow::onFileSave: Таблица перечня сохранена из MainController";
} else {
qDebug() << "MainWindow::onFileSave: Данные таблицы перечня пусты";
}
} else {
qDebug() << "MainWindow::onFileSave: PerechenTableModel недоступен в MainController";
}
// Сохраняем спецификацию ПП из модели MainController
SpecificationPCBTableModel *specPCBModel = m_controller->specificationPCBTableModel();
if (specPCBModel) {
QByteArray tableData = specPCBModel->saveToDatabase();
if (!tableData.isEmpty()) {
success &= m_controller->saveSpecificationPCBTableToDatabase(tableData);
qDebug() << "MainWindow::onFileSave: Таблица спецификации ПП сохранена из MainController";
} else {
qDebug() << "MainWindow::onFileSave: Данные таблицы спецификации ПП пусты";
}
} else {
qDebug() << "MainWindow::onFileSave: SpecificationPCBTableModel недоступен в MainController";
}
// Сохраняем спецификацию материалов из модели MainController
SpecificationTableModel *specModel = m_controller->specificationTableModel();
if (specModel) {
QByteArray tableData = specModel->saveToDatabase();
if (!tableData.isEmpty()) {
success &= m_controller->saveSpecificationTableToDatabase(tableData);
qDebug() << "MainWindow::onFileSave: Таблица спецификации материалов сохранена из MainController";
} else {
qDebug() << "MainWindow::onFileSave: Данные таблицы спецификации материалов пусты";
}
} else {
qDebug() << "MainWindow::onFileSave: SpecificationTableModel недоступен в MainController";
}
// Сохраняем ведомость покупных изделий из модели MainController
VedomostTableModel *vedomostModel = m_controller->vedomostTableModel();
if (vedomostModel) {
QByteArray tableData = vedomostModel->saveToDatabase();
if (!tableData.isEmpty()) {
success &= m_controller->saveVedomostTableToDatabase(tableData);
qDebug() << "MainWindow::onFileSave: Таблица ведомости покупных изделий сохранена из MainController";
} else {
qDebug() << "MainWindow::onFileSave: Данные таблицы ведомости покупных изделий пусты";
}
} else {
qDebug() << "MainWindow::onFileSave: VedomostTableModel недоступен в MainController";
}
if (success) {
m_statusBar->showMessage(tr("Проект сохранен: %1").arg(m_currentProjectPath));
return true;
} else {
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось сохранить проект: %1")
.arg(QString(m_controller->lastError())));
return false;
}
}
}
void MainWindow::onFileSaveAs(){
// Открываем диалог сохранения файла проекта
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Сохранить проект как"),
QString(),
tr("PDF Проекты (*.pdfprj);;База данных (*.db);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Сохранение проекта: %1").arg(fileName));
// Инициализируем новую базу данных
if (m_controller->initializeDatabase(fileName)) {
// Сохраняем основные данные в новую БД (без свойств и вариантов)
bool success = true;
success &= m_controller->saveComponentsToDatabase();
success &= m_controller->saveProjectParamsToDatabase();
success &= m_controller->saveProjectSettingsToDatabase();
// Сохраняем надписи титульного листа из MainController
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
if (titleModel) {
QMap<int, QString> inscriptions = titleModel->getAllInscriptions();
success &= m_controller->saveTitleInscriptionsToDatabase(inscriptions);
qDebug() << "MainWindow::onFileSaveAs: Надписи титульного листа сохранены из MainController";
} else {
qDebug() << "MainWindow::onFileSaveAs: TitleInscriptionsModel недоступен в MainController";
}
// Сохраняем перечень элементов из модели MainController
PerechenTableModel *perechenModel = m_controller->perechenTableModel();
if (perechenModel) {
QByteArray tableData = perechenModel->saveToDatabase();
if (!tableData.isEmpty()) {
success &= m_controller->savePerechenTableToDatabase(tableData);
qDebug() << "MainWindow::onFileSaveAs: Таблица перечня сохранена из MainController";
} else {
qDebug() << "MainWindow::onFileSaveAs: Данные таблицы перечня пусты";
}
} else {
qDebug() << "MainWindow::onFileSaveAs: PerechenTableModel недоступен в MainController";
}
// Сохраняем спецификацию ПП из модели MainController
SpecificationPCBTableModel *specPCBModel = m_controller->specificationPCBTableModel();
if (specPCBModel) {
QByteArray tableData = specPCBModel->saveToDatabase();
if (!tableData.isEmpty()) {
success &= m_controller->saveSpecificationPCBTableToDatabase(tableData);
qDebug() << "MainWindow::onFileSaveAs: Таблица спецификации ПП сохранена из MainController";
} else {
qDebug() << "MainWindow::onFileSaveAs: Данные таблицы спецификации ПП пусты";
}
} else {
qDebug() << "MainWindow::onFileSaveAs: SpecificationPCBTableModel недоступен в MainController";
}
// Сохраняем спецификацию материалов из модели MainController
SpecificationTableModel *specModel = m_controller->specificationTableModel();
if (specModel) {
QByteArray tableData = specModel->saveToDatabase();
if (!tableData.isEmpty()) {
success &= m_controller->saveSpecificationTableToDatabase(tableData);
qDebug() << "MainWindow::onFileSaveAs: Таблица спецификации материалов сохранена из MainController";
} else {
qDebug() << "MainWindow::onFileSaveAs: Данные таблицы спецификации материалов пусты";
}
} else {
qDebug() << "MainWindow::onFileSaveAs: SpecificationTableModel недоступен в MainController";
}
// Сохраняем ведомость покупных изделий из модели MainController
VedomostTableModel *vedomostModel = m_controller->vedomostTableModel();
if (vedomostModel) {
QByteArray tableData = vedomostModel->saveToDatabase();
if (!tableData.isEmpty()) {
success &= m_controller->saveVedomostTableToDatabase(tableData);
qDebug() << "MainWindow::onFileSaveAs: Таблица ведомости покупных изделий сохранена из MainController";
} else {
qDebug() << "MainWindow::onFileSaveAs: Данные таблицы ведомости покупных изделий пусты";
}
} else {
qDebug() << "MainWindow::onFileSaveAs: VedomostTableModel недоступен в MainController";
}
if (success) {
m_currentProjectPath = fileName;
updateWindowTitle();
updateStatusBar();
enableInterface();
m_statusBar->showMessage(tr("Проект сохранен: %1").arg(fileName));
} else {
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось сохранить проект: %1")
.arg(QString(m_controller->lastError())));
}
} else {
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось создать файл проекта: %1")
.arg(QString(m_controller->lastError())));
}
}
}
void MainWindow::onFileImportAltium(){
// Проверяем, есть ли открытый проект
if (m_currentProjectPath.isEmpty() ||
!m_controller || !m_controller->isDatabaseOpen()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Для импорта Altium файла необходимо сначала создать или открыть проект.\n\n"
"Пожалуйста, создайте новый проект или откройте существующий."));
return;
}
// Открываем диалог выбора файла
QString fileName = QFileDialog::getOpenFileName(
this,
tr("Выберите Altium файл"),
QString(),
tr("Altium проекты (*.PrjPCB);;Altium файлы (*.prjpcb *.sch *.schdoc *.pcb *.pcbdoc);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Импорт файла: %1").arg(fileName));
// Парсинг теперь выполняется через MainController
if (m_controller) {
// Отключаем старые соединения
disconnect(m_controller, nullptr, this, nullptr);
// Подключаем сигналы через MainController
connect(m_controller, &MainController::parsingStarted, this, &MainWindow::onParsingStarted);
connect(m_controller, &MainController::parsingProgress, this, &MainWindow::onParsingProgress);
connect(m_controller, &MainController::parsingFinished, this, &MainWindow::onParsingFinished);
connect(m_controller, &MainController::error, this, &MainWindow::onParsingError);
// Запускаем парсинг через MainController
m_controller->parseFileAsync(fileName);
} else {
QMessageBox::critical(this, tr("Ошибка"), tr("Контроллер не инициализирован"));
}
}
}
void MainWindow::onFileExit(){
if (askForSave()) {
close();
}
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if (askForSave()) {
event->accept();
} else {
event->ignore();
}
}
void MainWindow::onExportSpecification(){
qDebug() << "MainWindow::onExportSpecification: Начинаем экспорт спецификации материалов";
// Проверяем, открыт ли проект
if (m_currentProjectPath.isEmpty()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Сначала создайте или откройте проект"));
return;
}
// Проверяем, есть ли данные для экспорта
if (!m_controller->specificationTableModel() ||
m_controller->specificationTableModel()->rowCount() == 0) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Нет данных для экспорта. Сначала сгенерируйте таблицу спецификации."));
return;
}
// Формируем имя файла: поле 2 из TitleInscription + " Спецификация"
QString fileNameBase = "Спецификация";
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
ProjectParamTableModel *projectParamModel = m_controller->projectParamTableModel();
if (titleModel && projectParamModel) {
QString field2Value = PDFController::getInscriptionValueWithProjectParams(titleModel, projectParamModel, 2);
if (!field2Value.isEmpty() && field2Value != "-- Не выбрано --") {
fileNameBase = field2Value + " Спецификация";
}
}
// Запрашиваем путь для сохранения файла
QString defaultPath = QCoreApplication::applicationDirPath() + "/" + fileNameBase + ".pdf";
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Экспорт спецификации"),
defaultPath,
tr("PDF файлы (*.pdf)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Экспорт спецификации: %1").arg(fileName));
// Экспортируем в PDF через MainController
if (m_controller->exportSpecificationToPdf(fileName)) {
m_statusBar->showMessage(tr("Спецификация успешно экспортирована: %1").arg(fileName));
// Автоматически открываем созданный PDF файл
QUrl fileUrl = QUrl::fromLocalFile(fileName);
QDesktopServices::openUrl(fileUrl);
} else {
m_statusBar->showMessage(tr("Ошибка экспорта спецификации"));
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось экспортировать спецификацию"));
}
}
}
void MainWindow::onExportPerechen(){
qDebug() << "MainWindow::onExportPerechen: Начинаем экспорт перечня элементов";
// Проверяем, открыт ли проект
if (m_currentProjectPath.isEmpty()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Сначала создайте или откройте проект"));
return;
}
// Получаем модель перечня из MainController
PerechenTableModel *perechenModel = m_controller->perechenTableModel();
if (!perechenModel) {
QMessageBox::critical(this, tr("Ошибка"),
tr("Модель перечня элементов недоступна"));
return;
}
// Проверяем, есть ли данные в модели
if (perechenModel->rowCount() == 0) {
QMessageBox::information(this, tr("Информация"),
tr("Таблица перечня элементов пуста. Сначала сгенерируйте таблицу."));
return;
}
// Формируем имя файла: поле 2 из TitleInscription + " ПЭ3"
QString fileNameBase = "ПЭ3";
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
ProjectParamTableModel *projectParamModel = m_controller->projectParamTableModel();
if (titleModel && projectParamModel) {
QString field2Value = PDFController::getInscriptionValueWithProjectParams(titleModel, projectParamModel, 2);
if (!field2Value.isEmpty() && field2Value != "-- Не выбрано --") {
fileNameBase = field2Value + " ПЭ3";
}
}
// Открываем диалог сохранения файла
QString defaultPath = QCoreApplication::applicationDirPath() + "/" + fileNameBase + ".pdf";
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Экспорт перечня элементов"),
defaultPath,
tr("PDF файлы (*.pdf);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Экспорт перечня элементов: %1").arg(fileName));
// Экспортируем в PDF через MainController
if (m_controller->exportPerechenToPdf(fileName)) {
m_statusBar->showMessage(tr("Перечень элементов успешно экспортирован: %1").arg(fileName));
// Автоматически открываем созданный PDF файл
QUrl fileUrl = QUrl::fromLocalFile(fileName);
QDesktopServices::openUrl(fileUrl);
} else {
m_statusBar->showMessage(tr("Ошибка экспорта перечня элементов"));
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось экспортировать перечень элементов"));
}
}
}
void MainWindow::onExportSpecificationPcb(){
qDebug() << "MainWindow::onExportSpecificationPcb: Начинаем экспорт спецификации PCB";
// Проверяем, открыт ли проект
if (m_currentProjectPath.isEmpty()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Сначала создайте или откройте проект"));
return;
}
// Получаем модель спецификации PCB из MainController
SpecificationPCBTableModel *specificationModel = m_controller->specificationPCBTableModel();
if (!specificationModel) {
QMessageBox::critical(this, tr("Ошибка"),
tr("Модель спецификации PCB недоступна"));
return;
}
// Проверяем, есть ли данные в модели
if (specificationModel->rowCount() == 0) {
QMessageBox::information(this, tr("Информация"),
tr("Таблица спецификации PCB пуста. Сначала сгенерируйте таблицу."));
return;
}
// Формируем имя файла: поле 2 из TitleInscription + " Спецификация ПП"
QString fileNameBase = "Спецификация ПП";
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
ProjectParamTableModel *projectParamModel = m_controller->projectParamTableModel();
if (titleModel && projectParamModel) {
QString field2Value = PDFController::getInscriptionValueWithProjectParams(titleModel, projectParamModel, 2);
if (!field2Value.isEmpty() && field2Value != "-- Не выбрано --") {
fileNameBase = field2Value + " Спецификация ПП";
}
}
// Открываем диалог сохранения файла
QString defaultPath = QCoreApplication::applicationDirPath() + "/" + fileNameBase + ".pdf";
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Экспорт спецификации PCB"),
defaultPath,
tr("PDF файлы (*.pdf);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Экспорт спецификации PCB: %1").arg(fileName));
// Экспортируем в PDF через MainController
if (m_controller->exportSpecificationPcbToPdf(fileName)) {
m_statusBar->showMessage(tr("Спецификация PCB успешно экспортирована: %1").arg(fileName));
// Автоматически открываем созданный PDF файл
QUrl fileUrl = QUrl::fromLocalFile(fileName);
QDesktopServices::openUrl(fileUrl);
} else {
m_statusBar->showMessage(tr("Ошибка экспорта спецификации PCB"));
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось экспортировать спецификацию PCB"));
}
}
}
void MainWindow::onExportPurchaseList()
{
qDebug() << "MainWindow::onExportPurchaseList: Экспорт ведомости покупных изделий";
// Проверяем, открыт ли проект
if (m_currentProjectPath.isEmpty()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Сначала создайте или откройте проект"));
return;
}
// Проверяем, есть ли данные в модели ведомости
VedomostTableModel *vedomostModel = m_controller->vedomostTableModel();
if (!vedomostModel || vedomostModel->rowCount() == 0) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Ведомость покупных изделий пуста. Сначала сгенерируйте таблицу."));
return;
}
// Формируем имя файла: поле 2 из TitleInscription + " ВП"
QString fileNameBase = "ВП";
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
ProjectParamTableModel *projectParamModel = m_controller->projectParamTableModel();
if (titleModel && projectParamModel) {
QString field2Value = PDFController::getInscriptionValueWithProjectParams(titleModel, projectParamModel, 2);
if (!field2Value.isEmpty() && field2Value != "-- Не выбрано --") {
fileNameBase = field2Value + " ВП";
}
}
// Открываем диалог сохранения файла
QString defaultPath = QCoreApplication::applicationDirPath() + "/" + fileNameBase + ".pdf";
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Экспорт ведомости покупных изделий"),
defaultPath,
tr("PDF файлы (*.pdf);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Экспорт ведомости покупных изделий: %1").arg(fileName));
// Экспортируем ведомость в PDF
if (m_controller->exportVedomostToPdf(fileName)) {
m_statusBar->showMessage(tr("Ведомость покупных изделий успешно экспортирована: %1").arg(fileName));
QMessageBox::information(this, tr("Успех"),
tr("Ведомость покупных изделий успешно экспортирована:\n%1").arg(fileName));
} else {
m_statusBar->showMessage(tr("Ошибка экспорта ведомости покупных изделий"));
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось экспортировать ведомость покупных изделий:\n%1")
.arg(m_controller->lastError()));
}
}
}
void MainWindow::onExportSpecificationToCsv()
{
qDebug() << "MainWindow::onExportSpecificationToCsv: Начинаем экспорт спецификации материалов в CSV";
// Проверяем, открыт ли проект
if (m_currentProjectPath.isEmpty()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Сначала создайте или откройте проект"));
return;
}
// Проверяем, есть ли данные для экспорта
if (!m_controller->specificationTableModel() ||
m_controller->specificationTableModel()->rowCount() == 0) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Нет данных для экспорта. Сначала сгенерируйте таблицу спецификации."));
return;
}
// Запрашиваем путь для сохранения файла
QString defaultPath = QCoreApplication::applicationDirPath() + "/Спецификация.csv";
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Экспорт спецификации в CSV"),
defaultPath,
tr("CSV файлы (*.csv);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Экспорт спецификации в CSV: %1").arg(fileName));
// Экспортируем в CSV через MainController
if (m_controller->exportSpecificationToCsv(fileName)) {
m_statusBar->showMessage(tr("Спецификация успешно экспортирована в CSV: %1").arg(fileName));
QMessageBox::information(this, tr("Успех"),
tr("Спецификация успешно экспортирована в CSV:\n%1").arg(fileName));
} else {
m_statusBar->showMessage(tr("Ошибка экспорта спецификации в CSV"));
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось экспортировать спецификацию в CSV"));
}
}
}
void MainWindow::onExportPerechenToCsv()
{
qDebug() << "MainWindow::onExportPerechenToCsv: Начинаем экспорт перечня элементов в CSV";
// Проверяем, открыт ли проект
if (m_currentProjectPath.isEmpty()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Сначала создайте или откройте проект"));
return;
}
// Получаем модель перечня из MainController
PerechenTableModel *perechenModel = m_controller->perechenTableModel();
if (!perechenModel) {
QMessageBox::critical(this, tr("Ошибка"),
tr("Модель перечня элементов недоступна"));
return;
}
// Проверяем, есть ли данные в модели
if (perechenModel->rowCount() == 0) {
QMessageBox::information(this, tr("Информация"),
tr("Таблица перечня элементов пуста. Сначала сгенерируйте таблицу."));
return;
}
// Открываем диалог сохранения файла
QString defaultPath = QCoreApplication::applicationDirPath() + "/ПереченьЭлементов.csv";
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Экспорт перечня элементов в CSV"),
defaultPath,
tr("CSV файлы (*.csv);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Экспорт перечня элементов в CSV: %1").arg(fileName));
// Экспортируем в CSV через MainController
if (m_controller->exportPerechenToCsv(fileName)) {
m_statusBar->showMessage(tr("Перечень элементов успешно экспортирован в CSV: %1").arg(fileName));
QMessageBox::information(this, tr("Успех"),
tr("Перечень элементов успешно экспортирован в CSV:\n%1").arg(fileName));
} else {
m_statusBar->showMessage(tr("Ошибка экспорта перечня элементов в CSV"));
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось экспортировать перечень элементов в CSV"));
}
}
}
void MainWindow::onExportSpecificationPcbToCsv()
{
qDebug() << "MainWindow::onExportSpecificationPcbToCsv: Начинаем экспорт спецификации PCB в CSV";
// Проверяем, открыт ли проект
if (m_currentProjectPath.isEmpty()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Сначала создайте или откройте проект"));
return;
}
// Получаем модель спецификации PCB из MainController
SpecificationPCBTableModel *specificationModel = m_controller->specificationPCBTableModel();
if (!specificationModel) {
QMessageBox::critical(this, tr("Ошибка"),
tr("Модель спецификации PCB недоступна"));
return;
}
// Проверяем, есть ли данные в модели
if (specificationModel->rowCount() == 0) {
QMessageBox::information(this, tr("Информация"),
tr("Таблица спецификации PCB пуста. Сначала сгенерируйте таблицу."));
return;
}
// Открываем диалог сохранения файла
QString defaultPath = QCoreApplication::applicationDirPath() + "/СпецификацияПП.csv";
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Экспорт спецификации PCB в CSV"),
defaultPath,
tr("CSV файлы (*.csv);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Экспорт спецификации PCB в CSV: %1").arg(fileName));
// Экспортируем в CSV через MainController
if (m_controller->exportSpecificationPcbToCsv(fileName)) {
m_statusBar->showMessage(tr("Спецификация PCB успешно экспортирована в CSV: %1").arg(fileName));
QMessageBox::information(this, tr("Успех"),
tr("Спецификация PCB успешно экспортирована в CSV:\n%1").arg(fileName));
} else {
m_statusBar->showMessage(tr("Ошибка экспорта спецификации PCB в CSV"));
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось экспортировать спецификацию PCB в CSV"));
}
}
}
void MainWindow::onExportPurchaseListToCsv()
{
qDebug() << "MainWindow::onExportPurchaseListToCsv: Экспорт ведомости покупных изделий в CSV";
// Проверяем, открыт ли проект
if (m_currentProjectPath.isEmpty()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Сначала создайте или откройте проект"));
return;
}
// Проверяем, есть ли данные в модели ведомости
VedomostTableModel *vedomostModel = m_controller->vedomostTableModel();
if (!vedomostModel || vedomostModel->rowCount() == 0) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Ведомость покупных изделий пуста. Сначала сгенерируйте таблицу."));
return;
}
// Открываем диалог сохранения файла
QString defaultPath = QCoreApplication::applicationDirPath() + "/ВедомостьПокупныхИзделий.csv";
QString fileName = QFileDialog::getSaveFileName(
this,
tr("Экспорт ведомости покупных изделий в CSV"),
defaultPath,
tr("CSV файлы (*.csv);;Все файлы (*)")
);
if (!fileName.isEmpty()) {
m_statusBar->showMessage(tr("Экспорт ведомости покупных изделий в CSV: %1").arg(fileName));
// Экспортируем ведомость в CSV
if (m_controller->exportVedomostToCsv(fileName)) {
m_statusBar->showMessage(tr("Ведомость покупных изделий успешно экспортирована в CSV: %1").arg(fileName));
QMessageBox::information(this, tr("Успех"),
tr("Ведомость покупных изделий успешно экспортирована в CSV:\n%1").arg(fileName));
} else {
m_statusBar->showMessage(tr("Ошибка экспорта ведомости покупных изделий в CSV"));
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось экспортировать ведомость покупных изделий в CSV:\n%1")
.arg(m_controller->lastError()));
}
}
}
void MainWindow::onUndo(){}
void MainWindow::onRedo(){}
// Слоты для управления видом
void MainWindow::onViewDataPanel()
{
if (m_dataPanelDockWidget) {
if (m_dataPanelDockWidget->isVisible()) {
m_dataPanelDockWidget->hide();
} else {
m_dataPanelDockWidget->show();
m_dataPanelDockWidget->raise();
}
updateViewMenuState();
}
}
void MainWindow::onViewPdfPreview()
{
if (m_pdfPanelDockWidget) {
if (m_pdfPanelDockWidget->isVisible()) {
m_pdfPanelDockWidget->hide();
} else {
m_pdfPanelDockWidget->show();
m_pdfPanelDockWidget->raise();
}
updateViewMenuState();
}
}
void MainWindow::onProjectSettings()
{
qDebug() << "MainWindow: Открытие диалога настроек проекта";
// Проверяем, открыт ли проект
if (m_currentProjectPath.isEmpty()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Сначала создайте или откройте проект"));
return;
}
// Загружаем текущие настройки
m_controller->loadProjectSettingsFromDatabase();
// Обновляем доступные варианты из модели компонентов ПЕРЕД созданием диалога
QStringList variants = m_controller->componentTableModel()->variants();
qDebug() << "MainWindow: Доступные варианты из модели компонентов:" << variants;
m_controller->projectSettingsModel()->setAvailableVariants(variants);
// Создаем диалог настроек
ProjectSettingsDialog dialog(m_controller->projectSettingsModel(),
m_controller->designatorMappingModel(), this);
if (dialog.exec() == QDialog::Accepted) {
// Сохраняем настройки в базу данных
if (m_controller->saveProjectSettingsToDatabase()) {
m_statusBar->showMessage(tr("Настройки проекта сохранены"));
// Обновляем текущий вариант в компонентах
QString newVariant = dialog.getCurrentVariant();
m_controller->setCurrentVariant(newVariant);
// Перезагружаем компоненты с новым вариантом
m_controller->loadComponentsFromDatabase();
// Синхронизируем выбор варианта в ComponentsPreview
if (m_dataView && m_dataView->getComponentsPreview()) {
m_dataView->getComponentsPreview()->setCurrentVariant(newVariant);
}
} else {
QMessageBox::critical(this, tr("Ошибка"),
tr("Не удалось сохранить настройки проекта"));
}
}
}
void MainWindow::onViewResetLayout()
{
// Сбрасываем расположение док-виджетов к исходному состоянию
if (m_dataPanelDockWidget) {
m_dataPanelDockWidget->setVisible(true);
addDockWidget(Qt::RightDockWidgetArea, m_dataPanelDockWidget);
}
if (m_pdfPanelDockWidget) {
m_pdfPanelDockWidget->setVisible(true);
addDockWidget(Qt::RightDockWidgetArea, m_pdfPanelDockWidget);
}
// Накладываем панели друг на друга в виде табов
tabifyDockWidget(m_dataPanelDockWidget, m_pdfPanelDockWidget);
// Показываем первую панель по умолчанию
m_dataPanelDockWidget->raise();
updateViewMenuState();
m_statusBar->showMessage(tr("Расположение панелей сброшено"));
}
void MainWindow::updateViewMenuState()
{
if (m_viewMenu) {
QList<QAction*> actions = m_viewMenu->actions();
for (QAction* action : actions) {
if (action->text().contains("Панель данных")) {
action->setChecked(m_dataPanelDockWidget && m_dataPanelDockWidget->isVisible());
} else if (action->text().contains("PDF Превью")) {
action->setChecked(m_pdfPanelDockWidget && m_pdfPanelDockWidget->isVisible());
}
}
}
}
void MainWindow::updateWindowTitle()
{
QString title = "GostGenerator";
if (!m_currentProjectPath.isEmpty()) {
QFileInfo fileInfo(m_currentProjectPath);
title += " - " + fileInfo.fileName();
} else {
title += " - Новый проект";
}
setWindowTitle(title);
}
void MainWindow::disableInterfaceExceptProjectActions()
{
// Отключаем все элементы интерфейса кроме создания/открытия проекта
// Отключаем действия в меню
if (m_fileMenu) {
QList<QAction*> actions = m_fileMenu->actions();
for (QAction* action : actions) {
if (action->text().contains("Новый проект") || action->text().contains("Открыть проект")) {
action->setEnabled(true);
} else {
action->setEnabled(false);
}
}
}
// Отключаем действия в тулбаре
if (m_toolBar) {
QList<QAction*> actions = m_toolBar->actions();
for (QAction* action : actions) {
if (action->text().contains("Новый проект") || action->text().contains("Открыть проект")) {
action->setEnabled(true);
} else if (action->text().contains("Отменить") || action->text().contains("Повторить")) {
// Кнопки отмены и повтора всегда отключены
action->setEnabled(false);
} else {
action->setEnabled(false);
}
}
}
// Отключаем действия во втором тулбаре
if (m_toolBar2) {
QList<QAction*> actions = m_toolBar2->actions();
for (QAction* action : actions) {
if (action->text().contains("Отменить") || action->text().contains("Повторить")) {
// Кнопки отмены и повтора всегда отключены
action->setEnabled(false);
} else {
action->setEnabled(false);
}
}
}
// Отключаем панели данных
if (m_dataPanelDockWidget) {
m_dataPanelDockWidget->setEnabled(false);
}
if (m_pdfPanelDockWidget) {
m_pdfPanelDockWidget->setEnabled(false);
}
// Отключаем центральный виджет
if (m_centralWidget) {
m_centralWidget->setEnabled(false);
}
updateStatusBar();
}
void MainWindow::enableInterface()
{
// Включаем все элементы интерфейса
// Включаем действия в меню
if (m_fileMenu) {
QList<QAction*> actions = m_fileMenu->actions();
for (QAction* action : actions) {
action->setEnabled(true);
}
}
// Включаем действия в тулбаре
if (m_toolBar) {
QList<QAction*> actions = m_toolBar->actions();
for (QAction* action : actions) {
if (action->text().contains("Отменить") || action->text().contains("Повторить")) {
// Кнопки отмены и повтора всегда отключены
action->setEnabled(false);
} else {
action->setEnabled(true);
}
}
}
// Включаем действия во втором тулбаре
if (m_toolBar2) {
QList<QAction*> actions = m_toolBar2->actions();
for (QAction* action : actions) {
if (action->text().contains("Отменить") || action->text().contains("Повторить")) {
// Кнопки отмены и повтора всегда отключены
action->setEnabled(false);
} else {
action->setEnabled(true);
}
}
}
// Включаем панели данных
if (m_dataPanelDockWidget) {
m_dataPanelDockWidget->setEnabled(true);
}
if (m_pdfPanelDockWidget) {
m_pdfPanelDockWidget->setEnabled(true);
}
// Включаем центральный виджет
if (m_centralWidget) {
m_centralWidget->setEnabled(true);
}
updateStatusBar();
}
void MainWindow::updateStatusBar()
{
if (!m_currentProjectPath.isEmpty()) {
QFileInfo fileInfo(m_currentProjectPath);
QString statusText = tr("Проект: %1").arg(fileInfo.fileName());
// Добавляем информацию о количестве компонентов
if (m_controller && m_controller->componentTableModel()) {
int componentCount = m_controller->componentTableModel()->getComponents().size();
statusText += tr(" | Компонентов: %1").arg(componentCount);
}
m_statusBar->showMessage(statusText);
} else {
m_statusBar->showMessage(tr("Проект не открыт. Создайте новый проект или откройте существующий для начала работы."));
}
}
bool MainWindow::askForSave()
{
// Проверяем, есть ли несохраненные изменения
bool hasChanges = false;
if (m_controller && m_controller->componentTableModel()) {
// Проверяем наличие компонентов
if (m_controller->componentTableModel()->getComponents().size() > 0) {
hasChanges = true;
}
// Проверяем наличие параметров проекта
if (m_controller->projectParamTableModel() &&
m_controller->projectParamTableModel()->rowCount() > 0) {
hasChanges = true;
}
}
if (hasChanges) {
QMessageBox::StandardButton reply = QMessageBox::question(
this,
tr("Сохранение проекта"),
tr("Сохранить изменения в проекте?"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel
);
if (reply == QMessageBox::Save) {
return onFileSave();
} else if (reply == QMessageBox::Cancel) {
return false; // Отмена выхода
}
}
return true; // Можно выходить
}
// Слоты для асинхронного парсинга
void MainWindow::onParsingStarted()
{
m_isParsing = true;
m_progressBar->setVisible(true);
m_progressBar->setValue(0);
m_cancelParsingAction->setVisible(true);
m_statusBar->showMessage(tr("Начало парсинга файла..."));
}
void MainWindow::onParsingFinished(bool success)
{
m_isParsing = false;
m_progressBar->setVisible(false);
m_cancelParsingAction->setVisible(false);
if (success) {
m_statusBar->showMessage(tr("Парсинг завершен успешно"));
// Загружаем данные из базы в модели
if (m_controller) {
qDebug() << "MainWindow: Загружаем данные из базы после парсинга";
// Загружаем компоненты из базы
bool componentsLoaded = m_controller->loadComponentsFromDatabase();
qDebug() << "MainWindow: Компоненты загружены:" << componentsLoaded;
// Загружаем параметры проекта из базы
bool paramsLoaded = m_controller->loadProjectParamsFromDatabase();
qDebug() << "MainWindow: Параметры проекта загружены:" << paramsLoaded;
}
// Обновляем отображение данных
m_dataView->updateView();
updateStatusBar();
QMessageBox::information(this, tr("Успех"),
tr("Файл успешно импортирован!\n"
"Найдено компонентов: %1\n\n"
"Не забудьте сохранить проект!")
.arg(m_controller->componentTableModel()->getComponents().size()));
} else {
m_statusBar->showMessage(tr("Ошибка парсинга файла"));
QString errorMessage = m_controller->lastError();
if (errorMessage.isEmpty()) {
errorMessage = tr("Неизвестная ошибка при парсинге файла");
}
QMessageBox::critical(this, tr("Ошибка импорта"),
tr("Не удалось импортировать файл:\n%1").arg(errorMessage));
}
}
void MainWindow::onParsingProgress(int percentage)
{
m_progressBar->setValue(percentage);
m_statusBar->showMessage(tr("Парсинг файла... %1%").arg(percentage));
}
void MainWindow::onParsingError(const QString &error)
{
m_statusBar->showMessage(tr("Ошибка парсинга: %1").arg(error));
}
PerechenTableModel* MainWindow::getPerechenTableModel() const
{
// Теперь получаем модель напрямую из MainController
if (m_controller) {
return m_controller->perechenTableModel();
}
return nullptr;
}
void MainWindow::onExportAll()
{
qDebug() << "MainWindow::onExportAll: Начинаем экспорт всех документов";
// Проверяем, открыт ли проект
if (m_currentProjectPath.isEmpty()) {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Сначала создайте или откройте проект"));
return;
}
// Получаем путь к папке, где находится файл проекта (.pdfprj)
QFileInfo projectFileInfo(m_currentProjectPath);
QString projectDir = projectFileInfo.absolutePath();
qDebug() << "MainWindow::onExportAll: Папка проекта:" << projectDir;
// Проверяем, есть ли данные для экспорта
bool hasData = false;
QStringList exportedFiles;
// Экспорт спецификации материалов
if (m_controller->specificationTableModel() &&
m_controller->specificationTableModel()->rowCount() > 0) {
// Формируем имя файла: поле 2 из TitleInscription + " Спецификация"
QString fileNameBase = "Спецификация";
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
ProjectParamTableModel *projectParamModel = m_controller->projectParamTableModel();
if (titleModel && projectParamModel) {
QString field2Value = PDFController::getInscriptionValueWithProjectParams(titleModel, projectParamModel, 2);
if (!field2Value.isEmpty() && field2Value != "-- Не выбрано --") {
fileNameBase = field2Value + " Спецификация";
}
}
QString fileName = projectDir + "/" + fileNameBase + ".pdf";
if (m_controller->exportSpecificationToPdf(fileName)) {
exportedFiles << fileName;
hasData = true;
}
}
// Экспорт спецификации PCB
if (m_controller->specificationPCBTableModel() &&
m_controller->specificationPCBTableModel()->rowCount() > 0) {
// Формируем имя файла: поле 2 из TitleInscription + " Спецификация ПП"
QString fileNameBase = "Спецификация ПП";
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
ProjectParamTableModel *projectParamModel = m_controller->projectParamTableModel();
if (titleModel && projectParamModel) {
QString field2Value = PDFController::getInscriptionValueWithProjectParams(titleModel, projectParamModel, 2);
if (!field2Value.isEmpty() && field2Value != "-- Не выбрано --") {
fileNameBase = field2Value + " Спецификация ПП";
}
}
QString fileName = projectDir + "/" + fileNameBase + ".pdf";
if (m_controller->exportSpecificationPcbToPdf(fileName)) {
exportedFiles << fileName;
hasData = true;
}
}
// Экспорт ведомости покупных изделий
if (m_controller->vedomostTableModel() &&
m_controller->vedomostTableModel()->rowCount() > 0) {
// Формируем имя файла: поле 2 из TitleInscription + " ВП"
QString fileNameBase = "ВП";
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
ProjectParamTableModel *projectParamModel = m_controller->projectParamTableModel();
if (titleModel && projectParamModel) {
QString field2Value = PDFController::getInscriptionValueWithProjectParams(titleModel, projectParamModel, 2);
if (!field2Value.isEmpty() && field2Value != "-- Не выбрано --") {
fileNameBase = field2Value + " ВП";
}
}
QString fileName = projectDir + "/" + fileNameBase + ".pdf";
if (m_controller->exportVedomostToPdf(fileName)) {
exportedFiles << fileName;
hasData = true;
}
}
// Экспорт перечня элементов
if (m_controller->perechenTableModel() &&
m_controller->perechenTableModel()->rowCount() > 0) {
// Формируем имя файла: поле 2 из TitleInscription + " ПЭ3"
QString fileNameBase = "ПЭ3";
TitleInscriptionsModel *titleModel = m_controller->titleInscriptionsModel();
ProjectParamTableModel *projectParamModel = m_controller->projectParamTableModel();
if (titleModel && projectParamModel) {
QString field2Value = PDFController::getInscriptionValueWithProjectParams(titleModel, projectParamModel, 2);
if (!field2Value.isEmpty() && field2Value != "-- Не выбрано --") {
fileNameBase = field2Value + " ПЭ3";
}
}
QString fileName = projectDir + "/" + fileNameBase + ".pdf";
if (m_controller->exportPerechenToPdf(fileName)) {
exportedFiles << fileName;
hasData = true;
}
}
if (hasData) {
QString message = tr("Экспорт завершен успешно!\n\nЭкспортированные файлы:\n");
for (const QString& file : exportedFiles) {
message += file + "\n";
}
message += tr("\nФайлы сохранены в папке проекта.");
QMessageBox::information(this, tr("Успех"), message);
m_statusBar->showMessage(tr("Экспорт всех документов завершен"));
// Открываем папку с экспортированными файлами
QUrl folderUrl = QUrl::fromLocalFile(projectDir);
QDesktopServices::openUrl(folderUrl);
} else {
QMessageBox::warning(this, tr("Предупреждение"),
tr("Нет данных для экспорта. Сначала сгенерируйте таблицы документов."));
}
}