// Copyright (c) 2022 Proton AG
//
// This file is part of Proton Mail Bridge.
//
// Proton Mail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Proton Mail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see .
#include "Pch.h"
#include "Exception.h"
#include "QMLBackend.h"
#include "Log.h"
#include "EventStreamWorker.h"
//****************************************************************************************************************************************************
/// // initialize the Qt application.
//****************************************************************************************************************************************************
std::shared_ptr initQtApplication(int argc, char *argv[])
{
// Note the two following attributes must be set before instantiating the QCoreApplication/QGuiApplication class.
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, false);
if (QSysInfo::productType() != "windows")
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
QString const qsgInfo = QProcessEnvironment::systemEnvironment().value("QSG_INFO");
if ((!qsgInfo.isEmpty()) && (qsgInfo != "0"))
QLoggingCategory::setFilterRules("qt.scenegraph.general=true");
auto app = std::make_shared(argc, argv);
/// \todo GODT-1670 Get version from go backend.
QGuiApplication::setApplicationName("Proton Mail Bridge");
QGuiApplication::setApplicationVersion("3.0");
QGuiApplication::setOrganizationName("Proton AG");
QGuiApplication::setOrganizationDomain("proton.ch");
QGuiApplication::setQuitOnLastWindowClosed(false);
return app;
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void initLog()
{
Log &log = app().log();
log.setEchoInConsole(true);
log.setLevel(Log::Level::Debug);
}
//****************************************************************************************************************************************************
/// \param[in] engine The QML engine.
//****************************************************************************************************************************************************
QQmlComponent *createRootQmlComponent(QQmlApplicationEngine &engine)
{
/// \todo GODT-1669 pack QML and resources in QRC resource file.
QDir qmlDir("qml");
qmlRegisterType("CppBackend", 1, 0, "QMLBackend");
qmlRegisterType("CppBackend", 1, 0, "UserList");
qmlRegisterType("CppBackend", 1, 0, "User");
auto rootComponent = new QQmlComponent(&engine, &engine);
engine.addImportPath(qmlDir.absolutePath());
engine.addPluginPath(qmlDir.absolutePath());
QQuickStyle::addStylePath(qmlDir.absolutePath());
QQuickStyle::setStyle("Proton");
rootComponent->loadUrl(qmlDir.absoluteFilePath("Bridge.qml"));
if (rootComponent->status() != QQmlComponent::Status::Ready)
throw Exception("Could not load QML component");
return rootComponent;
}
//****************************************************************************************************************************************************
/// \param[in] argc The number of command-line arguments.
/// \param[in] argv The list of command-line arguments.
/// \return The exit code for the application.
//****************************************************************************************************************************************************
int main(int argc, char *argv[])
{
try
{
std::shared_ptr guiApp = initQtApplication(argc, argv);
initLog();
/// \todo GODT-1667 Locate & Launch go backend (and wait for it).
app().backend().init();
QQmlApplicationEngine engine;
QQmlComponent *rootComponent = createRootQmlComponent(engine);
QObject *rootObject = rootComponent->beginCreate(engine.rootContext());
if (!rootObject)
throw Exception("Could not create root object.");
rootObject->setProperty("backend", QVariant::fromValue(&app().backend()));
rootComponent->completeCreate();
int result = QGuiApplication::exec();
app().log().info(QString("Exiting app with return code %1").arg(result));
app().grpc().stopEventStream();
app().backend().clearUserList();
/// \todo GODT-1667 shutdown go backend.
return result;
}
catch (Exception const &e)
{
app().log().error(e.qwhat());
return EXIT_FAILURE;
}
}