diff options
author | Axel Spoerl <axel.spoerl@qt.io> | 2023-05-09 09:53:54 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-06-04 01:21:45 +0000 |
commit | 920997ab0843bc20b3a27821bdda75cbda77ea07 (patch) | |
tree | ce79b4b64941f53332639eb8ae566a820dd16500 /tests | |
parent | 6f8c0a09ad881d5f58ff8e9cb3f904f88863eeaf (diff) |
Move widgets Application example to manual tests
With 6e77da640aa84c1efe330d4a5224c9c7425ece57, the documentviewer
demo's TxtViewer plugin has been fully documented in order to replace
the Application example.
This patch moves the application example to manual tests.
Change-Id: I67d975e478c7bc840613c8af1301a4eafe8f1a42
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit eda71105ff9a516059c6dd6643ff446a82edac81)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/manual/examples/widgets/application/CMakeLists.txt | 54 | ||||
-rw-r--r-- | tests/manual/examples/widgets/application/application.pro | 13 | ||||
-rw-r--r-- | tests/manual/examples/widgets/application/application.qrc | 10 | ||||
-rw-r--r-- | tests/manual/examples/widgets/application/images/copy.png | bin | 0 -> 1338 bytes | |||
-rw-r--r-- | tests/manual/examples/widgets/application/images/cut.png | bin | 0 -> 1323 bytes | |||
-rw-r--r-- | tests/manual/examples/widgets/application/images/new.png | bin | 0 -> 852 bytes | |||
-rw-r--r-- | tests/manual/examples/widgets/application/images/open.png | bin | 0 -> 2073 bytes | |||
-rw-r--r-- | tests/manual/examples/widgets/application/images/paste.png | bin | 0 -> 1645 bytes | |||
-rw-r--r-- | tests/manual/examples/widgets/application/images/save.png | bin | 0 -> 2699 bytes | |||
-rw-r--r-- | tests/manual/examples/widgets/application/main.cpp | 30 | ||||
-rw-r--r-- | tests/manual/examples/widgets/application/mainwindow.cpp | 306 | ||||
-rw-r--r-- | tests/manual/examples/widgets/application/mainwindow.h | 53 |
12 files changed, 466 insertions, 0 deletions
diff --git a/tests/manual/examples/widgets/application/CMakeLists.txt b/tests/manual/examples/widgets/application/CMakeLists.txt new file mode 100644 index 0000000000..545d1cfca0 --- /dev/null +++ b/tests/manual/examples/widgets/application/CMakeLists.txt @@ -0,0 +1,54 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(application LANGUAGES CXX) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/mainwindows/application") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) + +qt_standard_project_setup() + +qt_add_executable(application + main.cpp + mainwindow.cpp mainwindow.h +) + +set_target_properties(application PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(application PRIVATE + Qt6::Core + Qt6::Gui + Qt6::Widgets +) + +# Resources: +set(application_resource_files + "images/copy.png" + "images/cut.png" + "images/new.png" + "images/open.png" + "images/paste.png" + "images/save.png" +) + +qt_add_resources(application "application" + PREFIX + "/" + FILES + ${application_resource_files} +) + +install(TARGETS application + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/tests/manual/examples/widgets/application/application.pro b/tests/manual/examples/widgets/application/application.pro new file mode 100644 index 0000000000..e55655a934 --- /dev/null +++ b/tests/manual/examples/widgets/application/application.pro @@ -0,0 +1,13 @@ +QT += widgets +requires(qtConfig(filedialog)) + +HEADERS = mainwindow.h +SOURCES = main.cpp \ + mainwindow.cpp +#! [0] +RESOURCES = application.qrc +#! [0] + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mainwindows/application +INSTALLS += target diff --git a/tests/manual/examples/widgets/application/application.qrc b/tests/manual/examples/widgets/application/application.qrc new file mode 100644 index 0000000000..0a776fab4d --- /dev/null +++ b/tests/manual/examples/widgets/application/application.qrc @@ -0,0 +1,10 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>images/copy.png</file> + <file>images/cut.png</file> + <file>images/new.png</file> + <file>images/open.png</file> + <file>images/paste.png</file> + <file>images/save.png</file> +</qresource> +</RCC> diff --git a/tests/manual/examples/widgets/application/images/copy.png b/tests/manual/examples/widgets/application/images/copy.png Binary files differnew file mode 100644 index 0000000000..2aeb28288f --- /dev/null +++ b/tests/manual/examples/widgets/application/images/copy.png diff --git a/tests/manual/examples/widgets/application/images/cut.png b/tests/manual/examples/widgets/application/images/cut.png Binary files differnew file mode 100644 index 0000000000..54638e9386 --- /dev/null +++ b/tests/manual/examples/widgets/application/images/cut.png diff --git a/tests/manual/examples/widgets/application/images/new.png b/tests/manual/examples/widgets/application/images/new.png Binary files differnew file mode 100644 index 0000000000..12131b0100 --- /dev/null +++ b/tests/manual/examples/widgets/application/images/new.png diff --git a/tests/manual/examples/widgets/application/images/open.png b/tests/manual/examples/widgets/application/images/open.png Binary files differnew file mode 100644 index 0000000000..45fa2883a7 --- /dev/null +++ b/tests/manual/examples/widgets/application/images/open.png diff --git a/tests/manual/examples/widgets/application/images/paste.png b/tests/manual/examples/widgets/application/images/paste.png Binary files differnew file mode 100644 index 0000000000..c14425cad1 --- /dev/null +++ b/tests/manual/examples/widgets/application/images/paste.png diff --git a/tests/manual/examples/widgets/application/images/save.png b/tests/manual/examples/widgets/application/images/save.png Binary files differnew file mode 100644 index 0000000000..e65a29d5f1 --- /dev/null +++ b/tests/manual/examples/widgets/application/images/save.png diff --git a/tests/manual/examples/widgets/application/main.cpp b/tests/manual/examples/widgets/application/main.cpp new file mode 100644 index 0000000000..903150c1c4 --- /dev/null +++ b/tests/manual/examples/widgets/application/main.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QApplication> +#include <QCommandLineParser> +#include <QCommandLineOption> + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + Q_INIT_RESOURCE(application); + + QApplication app(argc, argv); + QCoreApplication::setOrganizationName("QtProject"); + QCoreApplication::setApplicationName("Application Example"); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::applicationName()); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("file", "The file to open."); + parser.process(app); + + MainWindow mainWin; + if (!parser.positionalArguments().isEmpty()) + mainWin.loadFile(parser.positionalArguments().first()); + mainWin.show(); + return app.exec(); +} diff --git a/tests/manual/examples/widgets/application/mainwindow.cpp b/tests/manual/examples/widgets/application/mainwindow.cpp new file mode 100644 index 0000000000..fcb5590751 --- /dev/null +++ b/tests/manual/examples/widgets/application/mainwindow.cpp @@ -0,0 +1,306 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QtWidgets> + +#include "mainwindow.h" + +MainWindow::MainWindow() + : textEdit(new QPlainTextEdit) +{ + setCentralWidget(textEdit); + + createActions(); + createStatusBar(); + + readSettings(); + + connect(textEdit->document(), &QTextDocument::contentsChanged, + this, &MainWindow::documentWasModified); + +#ifndef QT_NO_SESSIONMANAGER + connect(qApp, &QGuiApplication::commitDataRequest, + this, &MainWindow::commitData); +#endif + + setCurrentFile(QString()); + setUnifiedTitleAndToolBarOnMac(true); +} + +void MainWindow::closeEvent(QCloseEvent *event) +{ + if (maybeSave()) { + writeSettings(); + event->accept(); + } else { + event->ignore(); + } +} + +void MainWindow::newFile() +{ + if (maybeSave()) { + textEdit->clear(); + setCurrentFile(QString()); + } +} + +void MainWindow::open() +{ + if (maybeSave()) { + QString fileName = QFileDialog::getOpenFileName(this); + if (!fileName.isEmpty()) + loadFile(fileName); + } +} + +bool MainWindow::save() +{ + if (curFile.isEmpty()) { + return saveAs(); + } else { + return saveFile(curFile); + } +} + +bool MainWindow::saveAs() +{ + QFileDialog dialog(this); + dialog.setWindowModality(Qt::WindowModal); + dialog.setAcceptMode(QFileDialog::AcceptSave); + if (dialog.exec() != QDialog::Accepted) + return false; + return saveFile(dialog.selectedFiles().first()); +} + +void MainWindow::about() +{ + QMessageBox::about(this, tr("About Application"), + tr("The <b>Application</b> example demonstrates how to " + "write modern GUI applications using Qt, with a menu bar, " + "toolbars, and a status bar.")); +} + +void MainWindow::documentWasModified() +{ + setWindowModified(textEdit->document()->isModified()); +} + +void MainWindow::createActions() +{ + + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + QToolBar *fileToolBar = addToolBar(tr("File")); + const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png")); + QAction *newAct = new QAction(newIcon, tr("&New"), this); + newAct->setShortcuts(QKeySequence::New); + newAct->setStatusTip(tr("Create a new file")); + connect(newAct, &QAction::triggered, this, &MainWindow::newFile); + fileMenu->addAction(newAct); + fileToolBar->addAction(newAct); + + const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png")); + QAction *openAct = new QAction(openIcon, tr("&Open..."), this); + openAct->setShortcuts(QKeySequence::Open); + openAct->setStatusTip(tr("Open an existing file")); + connect(openAct, &QAction::triggered, this, &MainWindow::open); + fileMenu->addAction(openAct); + fileToolBar->addAction(openAct); + + const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png")); + QAction *saveAct = new QAction(saveIcon, tr("&Save"), this); + saveAct->setShortcuts(QKeySequence::Save); + saveAct->setStatusTip(tr("Save the document to disk")); + connect(saveAct, &QAction::triggered, this, &MainWindow::save); + fileMenu->addAction(saveAct); + fileToolBar->addAction(saveAct); + + const QIcon saveAsIcon = QIcon::fromTheme("document-save-as"); + QAction *saveAsAct = fileMenu->addAction(saveAsIcon, tr("Save &As..."), this, &MainWindow::saveAs); + saveAsAct->setShortcuts(QKeySequence::SaveAs); + saveAsAct->setStatusTip(tr("Save the document under a new name")); + + fileMenu->addSeparator(); + + const QIcon exitIcon = QIcon::fromTheme("application-exit"); + QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), this, &QWidget::close); + exitAct->setShortcuts(QKeySequence::Quit); + exitAct->setStatusTip(tr("Exit the application")); + + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + QToolBar *editToolBar = addToolBar(tr("Edit")); + +#ifndef QT_NO_CLIPBOARD + const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")); + QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this); + cutAct->setShortcuts(QKeySequence::Cut); + cutAct->setStatusTip(tr("Cut the current selection's contents to the " + "clipboard")); + connect(cutAct, &QAction::triggered, textEdit, &QPlainTextEdit::cut); + editMenu->addAction(cutAct); + editToolBar->addAction(cutAct); + + const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")); + QAction *copyAct = new QAction(copyIcon, tr("&Copy"), this); + copyAct->setShortcuts(QKeySequence::Copy); + copyAct->setStatusTip(tr("Copy the current selection's contents to the " + "clipboard")); + connect(copyAct, &QAction::triggered, textEdit, &QPlainTextEdit::copy); + editMenu->addAction(copyAct); + editToolBar->addAction(copyAct); + + const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")); + QAction *pasteAct = new QAction(pasteIcon, tr("&Paste"), this); + pasteAct->setShortcuts(QKeySequence::Paste); + pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " + "selection")); + connect(pasteAct, &QAction::triggered, textEdit, &QPlainTextEdit::paste); + editMenu->addAction(pasteAct); + editToolBar->addAction(pasteAct); + + menuBar()->addSeparator(); + +#endif // !QT_NO_CLIPBOARD + + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about); + aboutAct->setStatusTip(tr("Show the application's About box")); + + QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); + aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); + +#ifndef QT_NO_CLIPBOARD + cutAct->setEnabled(false); + copyAct->setEnabled(false); + connect(textEdit, &QPlainTextEdit::copyAvailable, cutAct, &QAction::setEnabled); + connect(textEdit, &QPlainTextEdit::copyAvailable, copyAct, &QAction::setEnabled); +#endif // !QT_NO_CLIPBOARD +} + +void MainWindow::createStatusBar() +{ + statusBar()->showMessage(tr("Ready")); +} + +void MainWindow::readSettings() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray(); + if (geometry.isEmpty()) { + const QRect availableGeometry = screen()->availableGeometry(); + resize(availableGeometry.width() / 3, availableGeometry.height() / 2); + move((availableGeometry.width() - width()) / 2, + (availableGeometry.height() - height()) / 2); + } else { + restoreGeometry(geometry); + } +} + +void MainWindow::writeSettings() +{ + QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue("geometry", saveGeometry()); +} + +bool MainWindow::maybeSave() +{ + if (!textEdit->document()->isModified()) + return true; + const QMessageBox::StandardButton ret + = QMessageBox::warning(this, tr("Application"), + tr("The document has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + switch (ret) { + case QMessageBox::Save: + return save(); + case QMessageBox::Cancel: + return false; + default: + break; + } + return true; +} + +void MainWindow::loadFile(const QString &fileName) +{ + QFile file(fileName); + if (!file.open(QFile::ReadOnly | QFile::Text)) { + QMessageBox::warning(this, tr("Application"), + tr("Cannot read file %1:\n%2.") + .arg(QDir::toNativeSeparators(fileName), file.errorString())); + return; + } + + QTextStream in(&file); +#ifndef QT_NO_CURSOR + QGuiApplication::setOverrideCursor(Qt::WaitCursor); +#endif + textEdit->setPlainText(in.readAll()); +#ifndef QT_NO_CURSOR + QGuiApplication::restoreOverrideCursor(); +#endif + + setCurrentFile(fileName); + statusBar()->showMessage(tr("File loaded"), 2000); +} + +bool MainWindow::saveFile(const QString &fileName) +{ + QString errorMessage; + + QGuiApplication::setOverrideCursor(Qt::WaitCursor); + QSaveFile file(fileName); + if (file.open(QFile::WriteOnly | QFile::Text)) { + QTextStream out(&file); + out << textEdit->toPlainText(); + if (!file.commit()) { + errorMessage = tr("Cannot write file %1:\n%2.") + .arg(QDir::toNativeSeparators(fileName), file.errorString()); + } + } else { + errorMessage = tr("Cannot open file %1 for writing:\n%2.") + .arg(QDir::toNativeSeparators(fileName), file.errorString()); + } + QGuiApplication::restoreOverrideCursor(); + + if (!errorMessage.isEmpty()) { + QMessageBox::warning(this, tr("Application"), errorMessage); + return false; + } + + setCurrentFile(fileName); + statusBar()->showMessage(tr("File saved"), 2000); + return true; +} + +void MainWindow::setCurrentFile(const QString &fileName) +{ + curFile = fileName; + textEdit->document()->setModified(false); + setWindowModified(false); + + QString shownName = curFile; + if (curFile.isEmpty()) + shownName = "untitled.txt"; + setWindowFilePath(shownName); +} + +QString MainWindow::strippedName(const QString &fullFileName) +{ + return QFileInfo(fullFileName).fileName(); +} + +#ifndef QT_NO_SESSIONMANAGER +void MainWindow::commitData(QSessionManager &manager) +{ + if (manager.allowsInteraction()) { + if (!maybeSave()) + manager.cancel(); + } else { + // Non-interactive: save without asking + if (textEdit->document()->isModified()) + save(); + } +} +#endif diff --git a/tests/manual/examples/widgets/application/mainwindow.h b/tests/manual/examples/widgets/application/mainwindow.h new file mode 100644 index 0000000000..f1a4e2ac4f --- /dev/null +++ b/tests/manual/examples/widgets/application/mainwindow.h @@ -0,0 +1,53 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> + +QT_BEGIN_NAMESPACE +class QAction; +class QMenu; +class QPlainTextEdit; +class QSessionManager; +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + + void loadFile(const QString &fileName); + +protected: + void closeEvent(QCloseEvent *event) override; + +private slots: + void newFile(); + void open(); + bool save(); + bool saveAs(); + void about(); + void documentWasModified(); +#ifndef QT_NO_SESSIONMANAGER + void commitData(QSessionManager &); +#endif + +private: + void createActions(); + void createStatusBar(); + void readSettings(); + void writeSettings(); + bool maybeSave(); + bool saveFile(const QString &fileName); + void setCurrentFile(const QString &fileName); + QString strippedName(const QString &fullFileName); + + QPlainTextEdit *textEdit; + QString curFile; +}; + +#endif |