// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "mainwindow.h" #include "editorwidget.h" #include "previewwidget.h" #include "../states/statecontroller.h" #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , m_editorWidget{new EditorWidget} , m_previewWidget{new PreviewWidget} , m_fileWatcher{new QFileSystemWatcher} { setWindowIcon(QIcon(":/resources/logo.png")); setWindowTitle(tr("QML Previewer")); resize(1400, 800); initUI(); initMenuBar(); setupConnections(); StateController::instance()->fileLoaded(":/resources/default.qml"); m_editorWidget->updateEditor(); } MainWindow::~MainWindow() {} void MainWindow::initUI() { QWidget *centralWidget = new QWidget; setCentralWidget(centralWidget); QHBoxLayout *horizontalLayout = new QHBoxLayout; centralWidget->setLayout(horizontalLayout); horizontalLayout->addWidget(m_editorWidget, 1); horizontalLayout->addWidget(m_previewWidget, 1); } void MainWindow::initMenuBar() { QMenu *fileMenu = menuBar()->addMenu(tr("&File")); m_openAction = fileMenu->addAction(tr("&Open")); m_saveAction = fileMenu->addAction(tr("&Save")); m_saveAction->setEnabled(false); m_closeAction = fileMenu->addAction(tr("&Close")); m_closeAction->setEnabled(false); m_reloadAction = fileMenu->addAction(tr("&Reload")); m_reloadAction->setEnabled(false); fileMenu->addSeparator(); m_quitAction = fileMenu->addAction(tr("&Quit")); #if QT_CONFIG(shortcut) m_openAction->setShortcut(QKeySequence::Open); m_saveAction->setShortcut(QKeySequence::Save); m_closeAction->setShortcut(QKeySequence::Close); m_reloadAction->setShortcut(Qt::CTRL | Qt::Key_R); m_quitAction->setShortcut(QKeySequence::Quit); #endif } void MainWindow::setupConnections() { connect(StateController::instance(), &StateController::stateChanged, this, &MainWindow::onAppStateChanged); connect(m_fileWatcher, &QFileSystemWatcher::fileChanged, this, &MainWindow::onFileChanged); connect(menuBar(), &QMenuBar::triggered, this, &MainWindow::onMenuBarTriggered); connect(m_previewWidget, &PreviewWidget::errorPositionSelected, m_editorWidget, &EditorWidget::moveCursorTo); } void MainWindow::closeEvent(QCloseEvent *event) { switch (StateController::instance()->currentState()) { case StateController::NewState: case StateController::DirtyState: { const QMessageBox::StandardButton answer = QMessageBox::question(this, tr("About to Close"), tr("You have unsaved changes. " "Are you sure you want to close without saving?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (answer == QMessageBox::Yes) event->accept(); else event->ignore(); } break; default: event->accept(); break; } } void MainWindow::onAppStateChanged(int oldState, int newState) { switch (newState) { case StateController::InitState: if (!m_previewWidget->sourcePath().isEmpty()) { if (const QStringList files = m_fileWatcher->files(); !files.isEmpty()) m_fileWatcher->removePaths(files); m_previewWidget->setSourcePath(QString{}); } m_saveAction->setEnabled(false); m_closeAction->setEnabled(false); m_reloadAction->setEnabled(false); break; case StateController::OpenState: if (const QStringList files = m_fileWatcher->files(); !files.isEmpty()) m_fileWatcher->removePaths(files); m_fileWatcher->addPath(StateController::instance()->filePath()); m_previewWidget->setSourcePath(StateController::instance()->filePath()); m_saveAction->setEnabled(false); m_closeAction->setEnabled(true); m_reloadAction->setEnabled(false); break; case StateController::NewState: m_saveAction->setEnabled(true); m_closeAction->setEnabled(false); m_reloadAction->setEnabled(false); break; case StateController::DirtyState: m_saveAction->setEnabled(true); m_closeAction->setEnabled(false); m_reloadAction->setEnabled(true); break; default: Q_UNREACHABLE(); break; } } void MainWindow::onFileChanged(const QString &path) { StateController* stateController = StateController::instance(); m_fileWatcher->addPath(path); if (stateController->currentState() == StateController::DirtyState) { const QMessageBox::StandardButton answer = QMessageBox::question(this, tr("Reload File"), tr("The file %1 has been changed on disk. " "Do you want to reload it?").arg(path), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (answer == QMessageBox::No) return; } m_editorWidget->updateEditor(); m_previewWidget->setSourcePath(path); stateController->setDirty(false); } void MainWindow::onMenuBarTriggered(QAction *action) { if (action == m_openAction) m_editorWidget->openFile(); else if (action == m_saveAction) m_editorWidget->saveFile(); else if (action == m_closeAction) m_editorWidget->closeFile(); else if (action == m_reloadAction) m_editorWidget->reloadFile(); else if (action == m_quitAction) QCoreApplication::quit(); }