182 lines
5.6 KiB
C++
182 lines
5.6 KiB
C++
// 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 <QCloseEvent>
|
|
#include <QFileSystemWatcher>
|
|
#include <QLayout>
|
|
#include <QMenuBar>
|
|
#include <QMessageBox>
|
|
|
|
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 <i>%1</i> 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();
|
|
}
|