moment/src/main.cpp
miruka 872ee49a79 Don't catch SIGQUIT and SIGTERM
Give a way to quickly force quit. Catching SIGTERM also causes problems
with the live-reload script.
2020-07-24 00:45:58 -04:00

189 lines
5.9 KiB
C++

// SPDX-License-Identifier: LGPL-3.0-or-later
// This file creates the application, registers custom objects for QML
// and launches Window.qml (the root component).
#include <QDataStream> // must be first include to avoid clipboard.h errors
#include <QApplication>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQmlComponent>
#include <QFileInfo>
#include <QQuickStyle>
#include <QFontDatabase>
#include <QDateTime>
#include <signal.h>
#ifdef Q_OS_UNIX
#include <unistd.h>
#endif
#include "utils.h"
#include "clipboard.h"
#include "clipboard_image_provider.h"
void loggingHandler(
QtMsgType type,
const QMessageLogContext &context,
const QString &msg
) {
// Override default QML logger to provide colorful logging with times
Q_UNUSED(context)
// Hide dumb warnings about thing we can't fix without breaking
// compatibilty with Qt < 5.14
if (msg.contains("QML Binding: Not restoring previous value because"))
return;
// Hide layout-related spam introduced in Qt 5.14
if (msg.contains("Qt Quick Layouts: Detected recursive rearrange."))
return;
const char* level =
type == QtDebugMsg ? "~" :
type == QtInfoMsg ? "i" :
type == QtWarningMsg ? "!" :
type == QtCriticalMsg ? "X" :
type == QtFatalMsg ? "F" :
"?";
QString boldColor = "", color = "", clearFormatting = "";
#ifdef Q_OS_UNIX
// Don't output escape codes if stderr is piped or redirected to a file
if (isatty(fileno(stderr))) {
const QString ansiColor =
type == QtInfoMsg ? "2" : // green
type == QtWarningMsg ? "3" : // yellow
type == QtCriticalMsg ? "1" : // red
type == QtFatalMsg ? "5" : // purple
"4"; // blue
boldColor = "\e[1;3" + ansiColor + "m";
color = "\e[3" + ansiColor + "m";
clearFormatting = "\e[0m";
}
#endif
fprintf(
stderr,
"%s%s%s %s%s |%s %s\n",
boldColor.toUtf8().constData(),
level,
clearFormatting.toUtf8().constData(),
color.toUtf8().constData(),
QDateTime::currentDateTime().toString("hh:mm:ss").toUtf8().constData(),
clearFormatting.toUtf8().constData(),
msg.toUtf8().constData()
);
}
void onExitSignal(int signum) {
QApplication::exit(128 + signum);
}
int main(int argc, char *argv[]) {
qInstallMessageHandler(loggingHandler);
// Define some basic info about the app before creating the QApplication
QApplication::setOrganizationName("mirage");
QApplication::setApplicationName("mirage");
QApplication::setApplicationDisplayName("Mirage");
QApplication::setApplicationVersion("0.6.0");
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
// Register handlers for quit signals, e.g. SIGINT/Ctrl-C in unix terminals
signal(SIGINT, onExitSignal);
#ifdef Q_OS_UNIX
signal(SIGHUP, onExitSignal);
#endif
// Force the default universal QML style, notably prevents
// KDE from hijacking base controls and messing up everything
QQuickStyle::setStyle("Fusion");
QQuickStyle::setFallbackStyle("Default");
// Register default theme fonts. Take the files from the
// Qt resource system if possible (resources stored in the app executable),
// else the local file system.
// The dev qmake flag disables the resource system for faster builds.
QFileInfo qrcPath(":src/gui/Window.qml");
QString src = qrcPath.exists() ? ":/src" : "src";
QList<QString> fontFamilies;
fontFamilies << "roboto" << "hack";
QList<QString> fontVariants;
fontVariants << "regular" << "italic" << "bold" << "bold-italic";
foreach (QString family, fontFamilies) {
foreach (QString var, fontVariants) {
QFontDatabase::addApplicationFont(
src + "/fonts/" + family + "/" + var + ".ttf"
);
}
}
// Create the QML engine and get the root context.
// We will add it some properties that will be available globally in QML.
QQmlEngine engine;
QQmlContext *objectContext = new QQmlContext(engine.rootContext());
// Set the debugMode properties depending of if we're running in debug mode
// or not (`qmake CONFIG+=dev ...`, default in live-reload.sh)
#ifdef QT_DEBUG
objectContext->setContextProperty("debugMode", true);
#else
objectContext->setContextProperty("debugMode", false);
#endif
// Register our custom non-visual QObject singletons,
// that will be importable anywhere in QML. Example:
// import Clipboard 0.1
// ...
// Component.onCompleted: print(Clipboard.text)
qmlRegisterSingletonType<Clipboard>(
"Clipboard", 0, 1, "Clipboard",
[](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
Q_UNUSED(scriptEngine)
Clipboard *clipboard = new Clipboard();
// Register out custom image providers.
// QML will be able to request an image from them by setting an
// `Image`'s `source` to `image://<providerId>/<id>`
engine->addImageProvider(
"clipboard", new ClipboardImageProvider(clipboard)
);
return clipboard;
}
);
qmlRegisterSingletonType<Utils>(
"CppUtils", 0, 1, "CppUtils",
[](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return new Utils();
}
);
// Create the QML root component by loading its file from the Qt Resource
// System or local file system if not possible.
QQmlComponent component(
&engine,
qrcPath.exists() ? "qrc:/src/gui/Window.qml" : "src/gui/Window.qml"
);
component.create(objectContext);
// Finally, execute the app. Return its system exit code when it exits.
return app.exec();
}