Skip to content
Pokered Save Editor 2
Pokemon Red & Blue save file editor - Qt 6 C++/QML
Loading...
Searching...
No Matches
boot.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2019 Twilight
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15*/
16
23
24#include <QApplication>
25#include <QIcon>
26#include <QElapsedTimer>
27#include <QDebug>
28#include <QTranslator>
29#include <QLocale>
30#include <QSettings>
31#include <QLibraryInfo>
32
34#include "../bridge/router.h"
35
36// Generated by CMake from the repo-root VERSION; provides PSE_VERSION_FULL
37// (e.g. "0.7.0-alpha+g1a2b3c4d"). See notes/reference/versioning.md.
38#include "pse_version.h"
39
40extern void bootDatabase();
41extern void bootQmlLinkage();
42extern void applyDebugLaunch(QApplication* app); // DEBUG-only launch flags (no-op in release)
43extern void startDebugServer(); // DEBUG-only live control channel (no-op in release)
44
45// There is only ever one main window.
47
48// Installs the UI translators, before any QML is instantiated, so qsTr()/tr()
49// resolve to the chosen language at load time.
50//
51// Language preference resolves as: an explicit "ui/language" setting (a locale
52// name like "fr" or "de"), else the system locale. English is the source
53// language, so when no .qm matches — or a particular string is untranslated —
54// the UI simply falls back to the source text. That graceful degradation is by
55// design (see notes/context/principles.md): a missing translation never blanks
56// a label or blocks the user. See notes/reference/i18n.md for the pipeline.
57static void installTranslators(QApplication* app)
58{
59 QSettings settings; // uses the org/app names set in createApp()
60 const QString pref = settings.value(QStringLiteral("ui/language")).toString();
61 const QLocale locale = pref.isEmpty() ? QLocale::system() : QLocale(pref);
62
63 // The app's own strings (translations/pse_<locale>.ts → :/i18n/pse_<locale>.qm).
64 auto* appTr = new QTranslator(app);
65 if (appTr->load(locale, QStringLiteral("pse"), QStringLiteral("_"),
66 QStringLiteral(":/i18n")))
67 app->installTranslator(appTr);
68 else
69 delete appTr; // no catalog for this locale — stay on the en_US source strings
70
71 // Qt's own built-in strings (standard dialog buttons, etc.), best-effort.
72 auto* qtTr = new QTranslator(app);
73 if (qtTr->load(locale, QStringLiteral("qtbase"), QStringLiteral("_"),
74 QLibraryInfo::path(QLibraryInfo::TranslationsPath)))
75 app->installTranslator(qtTr);
76 else
77 delete qtTr;
78}
79
80// Sets critical Qt options that must be configured before QApplication is created.
81static void preBootAttributes()
82{
83 // Qt 6: High-DPI scaling is enabled automatically — no setAttribute needed.
84 // Qt 6: AA_CompressHighFrequencyEvents and AA_CompressTabletEvents are on by default.
85 // Qt 6: AA_DisableWindowContextHelpButton is the default on all platforms.
86 // Nothing to set here — kept as a hook for future platform-specific tweaks.
87}
88
89// Creates and configures the QApplication instance.
90[[nodiscard]] static QApplication* createApp(int argc, char* argv[])
91{
93
94 QApplication::setApplicationName("Pokered Save Editor");
95 QApplication::setOrganizationName("Twilight");
96 QApplication::setApplicationVersion(QStringLiteral(PSE_VERSION_FULL));
97 QApplication::setOrganizationDomain("pokeredsaveeditor.twilight.app");
98
99 // Note: Do NOT set a custom QSurfaceFormat with MSAA here.
100 // QQuickWidget renders into an offscreen FBO; requesting MSAA via
101 // setDefaultFormat() causes the scene graph to hang on context creation
102 // on many Windows drivers. Qt Quick handles its own antialiasing internally.
103
104 auto* app = new QApplication(argc, argv);
105
106 // Install translators right after the app exists and before the MainWindow
107 // (and thus any QML) is created, so qsTr()/tr() resolve at load time.
109
110 qSetMessagePattern("[%{type}]: %{message} ~ %{time} %{file} %{function} %{line}");
111
112 app->setWindowIcon(QIcon("qrc:/assets/icons/app/512x512.png"));
113
114 // Qt 6 uses QRandomGenerator internally; no manual seeding required.
115
116 mainWindow = new MainWindow();
117
118 // DEBUG: --minimized starts the window minimized (background) so automation can
119 // open + drive + screenshot the app without it popping up / stealing focus. The
120 // QQuickWidget framebuffer grab still works while minimized, so --shot is unaffected.
121#ifdef QT_DEBUG
122 if(app->arguments().contains(QStringLiteral("--minimized")))
123 mainWindow->showMinimized();
124 else
125 mainWindow->show();
126#else
127 mainWindow->show();
128#endif
129
130 return app;
131}
132
133// Performs full program bootstrapping and returns a ready-to-exec QApplication.
134extern QApplication* boot(int argc, char* argv[])
135{
136 QElapsedTimer t;
137 t.start();
138
139 qDebug() << "[boot] bootDatabase() start";
140 bootDatabase();
141 qDebug() << "[boot] bootDatabase() done —" << t.elapsed() << "ms";
142
143 qDebug() << "[boot] bootQmlLinkage() start";
145 qDebug() << "[boot] bootQmlLinkage() done —" << t.elapsed() << "ms";
146
147 qDebug() << "[boot] loadScreens() start";
149 qDebug() << "[boot] loadScreens() done —" << t.elapsed() << "ms";
150
151 qDebug() << "[boot] createApp() start";
152 auto* app = createApp(argc, argv);
153 qDebug() << "[boot] createApp() done (window visible) —" << t.elapsed() << "ms";
154
155 // DEBUG-only: honour --sav/--screen/--select launch flags (no-op in release).
156 applyDebugLaunch(app);
157
158 // DEBUG-only: start the live control channel on 127.0.0.1:8766 (no-op in release).
160
161 return app;
162}
163
void bootQmlLinkage()
void startDebugServer()
static void installTranslators(QApplication *app)
Definition boot.cpp:57
static QApplication * createApp(int argc, char *argv[])
Definition boot.cpp:90
void bootDatabase()
void applyDebugLaunch(QApplication *app)
static void preBootAttributes()
Definition boot.cpp:81
MainWindow * mainWindow
Definition boot.cpp:46
QApplication * boot(int argc, char *argv[])
Definition boot.cpp:134
The top-level window – a QMainWindow hosting the QML UI in a QQuickWidget.
Definition mainwindow.h:52
static void loadScreens()
Register the app's screen set (called at boot).
Definition router.cpp:139