2023-01-26 17:31:16 +00:00
|
|
|
// Copyright (C) 2023 The Qt Company Ltd.
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
2023-03-23 15:25:43 +00:00
|
|
|
|
2023-01-26 17:31:16 +00:00
|
|
|
#include "mainwindow.h"
|
|
|
|
#include "ui_mainwindow.h"
|
|
|
|
#include "viewerfactory.h"
|
2023-03-23 15:25:43 +00:00
|
|
|
#include "abstractviewer.h"
|
|
|
|
#include "recentfiles.h"
|
|
|
|
#include "recentfilemenu.h"
|
2023-06-20 11:39:08 +00:00
|
|
|
|
2023-01-26 17:31:16 +00:00
|
|
|
#include <QFileDialog>
|
|
|
|
#include <QToolButton>
|
|
|
|
#include <QMessageBox>
|
2023-06-20 11:39:08 +00:00
|
|
|
|
2023-06-20 11:22:02 +00:00
|
|
|
#include <QDir>
|
2023-06-20 11:39:08 +00:00
|
|
|
#include <QSettings>
|
2023-01-26 17:31:16 +00:00
|
|
|
|
2023-06-20 11:22:02 +00:00
|
|
|
using namespace Qt::StringLiterals;
|
|
|
|
|
2023-01-26 17:31:16 +00:00
|
|
|
MainWindow::MainWindow(QWidget *parent) :
|
|
|
|
QMainWindow(parent),
|
|
|
|
ui(new Ui::MainWindow)
|
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
2023-06-20 13:23:45 +00:00
|
|
|
connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::onActionOpenTriggered);
|
|
|
|
connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::onActionAboutTriggered);
|
|
|
|
connect(ui->actionAboutQt, &QAction::triggered, this, &MainWindow::onActionAboutQtTriggered);
|
2023-03-23 15:25:43 +00:00
|
|
|
|
|
|
|
m_recentFiles.reset(new RecentFiles(ui->actionRecent));
|
|
|
|
connect(m_recentFiles.get(), &RecentFiles::countChanged, this, [&](int count){
|
2023-06-20 11:22:02 +00:00
|
|
|
ui->actionRecent->setText(tr("%n recent files", nullptr, count));
|
2023-03-23 15:25:43 +00:00
|
|
|
});
|
|
|
|
|
2023-01-26 17:31:16 +00:00
|
|
|
readSettings();
|
2023-03-23 15:25:43 +00:00
|
|
|
m_factory.reset(new ViewerFactory(ui->viewArea, this));
|
|
|
|
const QStringList &viewers = m_factory->viewerNames();
|
2023-06-20 11:22:02 +00:00
|
|
|
|
|
|
|
const QString msg = tr("Available viewers: %1").arg(viewers.join(", "_L1));
|
2023-03-23 15:25:43 +00:00
|
|
|
statusBar()->showMessage(msg);
|
|
|
|
|
|
|
|
auto *menu = new RecentFileMenu(this, m_recentFiles.get());
|
|
|
|
ui->actionRecent->setMenu(menu);
|
|
|
|
connect(menu, &RecentFileMenu::fileOpened, this, &MainWindow::openFile);
|
|
|
|
QWidget *w = ui->mainToolBar->widgetForAction(ui->actionRecent);
|
|
|
|
auto *button = qobject_cast<QToolButton *>(w);
|
|
|
|
if (button)
|
|
|
|
connect(ui->actionRecent, &QAction::triggered, button, &QToolButton::showMenu);
|
2023-01-26 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2024-02-26 10:36:25 +00:00
|
|
|
bool MainWindow::hasPlugins() const
|
|
|
|
{
|
|
|
|
return m_factory ? !m_factory->viewers().isEmpty() : false;
|
|
|
|
}
|
|
|
|
|
2023-01-26 17:31:16 +00:00
|
|
|
MainWindow::~MainWindow()
|
|
|
|
{
|
|
|
|
saveSettings();
|
|
|
|
}
|
|
|
|
|
2023-06-20 13:23:45 +00:00
|
|
|
void MainWindow::onActionOpenTriggered()
|
2023-01-26 17:31:16 +00:00
|
|
|
{
|
2023-06-20 12:35:36 +00:00
|
|
|
QFileDialog fileDialog(this, tr("Open Document"), m_currentDir.absolutePath());
|
|
|
|
while (fileDialog.exec() == QDialog::Accepted
|
|
|
|
&& !openFile(fileDialog.selectedFiles().constFirst())) {
|
|
|
|
}
|
2023-01-26 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2023-06-20 12:35:36 +00:00
|
|
|
bool MainWindow::openFile(const QString &fileName)
|
2023-01-26 17:31:16 +00:00
|
|
|
{
|
|
|
|
QFile *file = new QFile(fileName);
|
|
|
|
if (!file->exists()) {
|
2023-06-20 11:22:02 +00:00
|
|
|
statusBar()->showMessage(tr("File %1 could not be opened")
|
|
|
|
.arg(QDir::toNativeSeparators(fileName)));
|
2023-01-26 17:31:16 +00:00
|
|
|
delete file;
|
2023-06-20 12:35:36 +00:00
|
|
|
return false;
|
2023-01-26 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QFileInfo fileInfo(*file);
|
|
|
|
m_currentDir = fileInfo.dir();
|
2023-03-23 15:25:43 +00:00
|
|
|
m_recentFiles->addFile(fileInfo.absoluteFilePath());
|
2023-01-26 17:31:16 +00:00
|
|
|
|
2023-06-17 18:04:55 +00:00
|
|
|
// If a viewer is already open, clean it up and save its settings
|
|
|
|
resetViewer();
|
2023-03-23 15:25:43 +00:00
|
|
|
m_viewer = m_factory->viewer(file);
|
|
|
|
if (!m_viewer) {
|
2023-06-20 11:22:02 +00:00
|
|
|
statusBar()->showMessage(tr("File %1 can't be opened.")
|
|
|
|
.arg(QDir::toNativeSeparators(fileName)));
|
2023-06-20 12:35:36 +00:00
|
|
|
return false;
|
2023-03-23 15:25:43 +00:00
|
|
|
}
|
2023-01-26 17:31:16 +00:00
|
|
|
|
2024-02-15 08:09:56 +00:00
|
|
|
for (const QMetaObject::Connection &connection : m_viewerConnections)
|
|
|
|
disconnect(connection);
|
|
|
|
|
|
|
|
m_viewerConnections = {
|
|
|
|
connect(m_viewer, &AbstractViewer::printingEnabledChanged, ui->actionPrint,
|
|
|
|
&QAction::setEnabled),
|
|
|
|
connect(ui->actionPrint, &QAction::triggered, m_viewer, &AbstractViewer::print),
|
|
|
|
connect(m_viewer, &AbstractViewer::showMessage, statusBar(), &QStatusBar::showMessage)
|
|
|
|
};
|
2023-01-26 17:31:16 +00:00
|
|
|
|
|
|
|
m_viewer->initViewer(ui->actionBack, ui->actionForward, ui->menuHelp->menuAction(), ui->tabWidget);
|
2023-03-23 15:25:43 +00:00
|
|
|
restoreViewerSettings();
|
2023-01-26 17:31:16 +00:00
|
|
|
ui->scrollArea->setWidget(m_viewer->widget());
|
2023-06-20 12:35:36 +00:00
|
|
|
return true;
|
2023-01-26 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2023-06-20 13:23:45 +00:00
|
|
|
void MainWindow::onActionAboutTriggered()
|
2023-01-26 17:31:16 +00:00
|
|
|
{
|
2023-06-20 11:22:02 +00:00
|
|
|
const QString viewerNames = m_factory->viewerNames().join(", "_L1);
|
|
|
|
const QString mimeTypes = m_factory->supportedMimeTypes().join(u'\n');
|
|
|
|
QString text = tr("A Widgets application to display and print JSON, "
|
|
|
|
"text and PDF files. Demonstrates various features to use "
|
|
|
|
"in widget applications: Using QSettings, query and save "
|
|
|
|
"user preferences, manage file histories and control cursor "
|
|
|
|
"behavior when hovering over widgets.\n\n"
|
|
|
|
"This version has loaded the following plugins:\n%1\n"
|
|
|
|
"\n\nIt supports the following mime types:\n%2")
|
|
|
|
.arg(viewerNames, mimeTypes);
|
|
|
|
|
|
|
|
if (auto *def = m_factory->defaultViewer())
|
|
|
|
text += tr("\n\nOther mime types will be displayed with %1.").arg(def->viewerName());
|
2023-03-23 15:25:43 +00:00
|
|
|
|
|
|
|
QMessageBox::about(this, tr("About Document Viewer Demo"), text);
|
2023-01-26 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2023-06-20 13:23:45 +00:00
|
|
|
void MainWindow::onActionAboutQtTriggered()
|
2023-01-26 17:31:16 +00:00
|
|
|
{
|
|
|
|
QMessageBox::aboutQt(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::readSettings()
|
|
|
|
{
|
2023-07-03 14:49:06 +00:00
|
|
|
QSettings settings;
|
2023-01-26 17:31:16 +00:00
|
|
|
|
|
|
|
// Restore working directory
|
|
|
|
if (settings.contains(settingsDir))
|
|
|
|
m_currentDir = QDir(settings.value(settingsDir).toString());
|
|
|
|
else
|
|
|
|
m_currentDir = QDir::current();
|
|
|
|
|
|
|
|
// Restore QMainWindow state
|
|
|
|
if (settings.contains(settingsMainWindow)) {
|
|
|
|
QByteArray mainWindowState = settings.value(settingsMainWindow).toByteArray();
|
|
|
|
restoreState(mainWindowState);
|
|
|
|
}
|
2023-03-23 15:25:43 +00:00
|
|
|
|
|
|
|
// Restore recent files
|
|
|
|
m_recentFiles->restoreFromSettings(settings, settingsFiles);
|
2023-01-26 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::saveSettings() const
|
|
|
|
{
|
2023-07-03 14:49:06 +00:00
|
|
|
QSettings settings;
|
2023-01-26 17:31:16 +00:00
|
|
|
|
|
|
|
// Save working directory
|
|
|
|
settings.setValue(settingsDir, m_currentDir.absolutePath());
|
|
|
|
|
|
|
|
// Save QMainWindow state
|
|
|
|
settings.setValue(settingsMainWindow, saveState());
|
|
|
|
|
2023-03-23 15:25:43 +00:00
|
|
|
// Save recent files
|
|
|
|
m_recentFiles->saveSettings(settings, settingsFiles);
|
|
|
|
|
2023-01-26 17:31:16 +00:00
|
|
|
settings.sync();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::saveViewerSettings() const
|
|
|
|
{
|
|
|
|
if (!m_viewer)
|
|
|
|
return;
|
|
|
|
|
2023-07-03 14:49:06 +00:00
|
|
|
QSettings settings;
|
2023-01-26 17:31:16 +00:00
|
|
|
settings.beginGroup(settingsViewers);
|
|
|
|
settings.setValue(m_viewer->viewerName(), m_viewer->saveState());
|
|
|
|
settings.endGroup();
|
|
|
|
settings.sync();
|
|
|
|
}
|
|
|
|
|
2023-06-17 18:04:55 +00:00
|
|
|
void MainWindow::resetViewer() const
|
|
|
|
{
|
|
|
|
if (!m_viewer)
|
|
|
|
return;
|
|
|
|
|
|
|
|
saveViewerSettings();
|
|
|
|
m_viewer->cleanup();
|
|
|
|
}
|
|
|
|
|
2023-01-26 17:31:16 +00:00
|
|
|
void MainWindow::restoreViewerSettings()
|
|
|
|
{
|
|
|
|
if (!m_viewer)
|
|
|
|
return;
|
|
|
|
|
2023-07-03 14:49:06 +00:00
|
|
|
QSettings settings;
|
2023-01-26 17:31:16 +00:00
|
|
|
settings.beginGroup(settingsViewers);
|
|
|
|
QByteArray viewerSettings = settings.value(m_viewer->viewerName(), QByteArray()).toByteArray();
|
|
|
|
settings.endGroup();
|
|
|
|
if (!viewerSettings.isEmpty())
|
|
|
|
m_viewer->restoreState(viewerSettings);
|
|
|
|
}
|
|
|
|
|