#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/simplelisttablemodel.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 #include #include #include #include // Added for qDebug #include #include #include #include #include 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); csvMenu->addAction("&Бланк заказа (CSV)", this, &MainWindow::onExportSimpleListToCsv); 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->addAction(tr("Бланк заказа (CSV)"), this, &MainWindow::onExportSimpleListToCsv); 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 QByteArray simpleListTableData = m_controller->loadSimpleListTableFromDatabase(); if (!simpleListTableData.isEmpty()) { SimpleListTableModel *simpleListModel = m_controller->simpleListTableModel(); if (simpleListModel) { simpleListModel->loadFromDatabase(simpleListTableData); qDebug() << "MainWindow::onFileOpen: Таблица бланка заказа загружена из БД в MainController"; } else { qDebug() << "MainWindow::onFileOpen: SimpleListTableModel недоступен в MainController"; } } else { qDebug() << "MainWindow::onFileOpen: Данные таблицы бланка заказа не найдены в БД"; } // Загружаем надписи титульного листа в MainController QMap 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 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"; } // Сохраняем бланк заказа из модели MainController SimpleListTableModel *simpleListModel = m_controller->simpleListTableModel(); if (simpleListModel) { QByteArray tableData = simpleListModel->saveToDatabase(); if (!tableData.isEmpty()) { success &= m_controller->saveSimpleListTableToDatabase(tableData); qDebug() << "MainWindow::onFileSave: Таблица бланка заказа сохранена из MainController"; } else { qDebug() << "MainWindow::onFileSave: Данные таблицы бланка заказа пусты"; } } else { qDebug() << "MainWindow::onFileSave: SimpleListTableModel недоступен в 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 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"; } // Сохраняем бланк заказа из модели MainController SimpleListTableModel *simpleListModel = m_controller->simpleListTableModel(); if (simpleListModel) { QByteArray tableData = simpleListModel->saveToDatabase(); if (!tableData.isEmpty()) { success &= m_controller->saveSimpleListTableToDatabase(tableData); qDebug() << "MainWindow::onFileSaveAs: Таблица бланка заказа сохранена из MainController"; } else { qDebug() << "MainWindow::onFileSaveAs: Данные таблицы бланка заказа пусты"; } } else { qDebug() << "MainWindow::onFileSaveAs: SimpleListTableModel недоступен в 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::onExportSimpleListToCsv() { qDebug() << "MainWindow::onExportSimpleListToCsv: Экспорт бланка заказа в CSV"; // Проверяем, открыт ли проект if (m_currentProjectPath.isEmpty()) { QMessageBox::warning(this, tr("Предупреждение"), tr("Сначала создайте или откройте проект")); return; } // Проверяем, есть ли данные в модели бланка заказа SimpleListTableModel *simpleListModel = m_controller->simpleListTableModel(); if (!simpleListModel || simpleListModel->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->exportSimpleListToCsv(fileName)) { QMessageBox::information(this, tr("Успех"), tr("Бланк заказа успешно экспортирован в CSV:\n%1").arg(fileName)); m_statusBar->showMessage(tr("Экспорт бланка заказа в CSV завершен")); } else { QMessageBox::critical(this, tr("Ошибка"), tr("Не удалось экспортировать бланк заказа в CSV:\n%1").arg(m_controller->lastError())); m_statusBar->showMessage(tr("Ошибка экспорта бланка заказа в CSV")); } } } 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 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 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 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 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 actions = m_fileMenu->actions(); for (QAction* action : actions) { action->setEnabled(true); } } // Включаем действия в тулбаре if (m_toolBar) { QList 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 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("Нет данных для экспорта. Сначала сгенерируйте таблицы документов.")); } }