15.1.231. tablet_qt/main.cpp

/*
    Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
    Created by Rudolf Cardinal (rnc1001@cam.ac.uk).

    This file is part of CamCOPS.

    CamCOPS 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.

    CamCOPS 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 CamCOPS. If not, see <https://www.gnu.org/licenses/>.
*/

// #define DEBUG_TEST_BASIC_QT_ONLY  // Disables CamCOPS! Just says hello.

#define FULL_LOG_FORMAT  // Include time and thread ID.
// #define DISABLE_ANDROID_NATIVE_DIALOGS  // For a bug fixed in Qt 5.2.1.
// #define QT_OPENGL_IN_SOFTWARE  // Unnecessary once proper OpenGL detection added.
// #define DEBUG_WITH_DIAGNOSTIC_STYLE


#include <QApplication>
#include <QDebug>
#include <QPushButton>
#include <QStyleFactory>
#include "common/preprocessor_aid.h"  // IWYU pragma: keep
#include "core/camcopsapp.h"
#ifdef OPENSSL_VIA_QLIBRARY
#include "crypto/cryptofunc.h"
#endif
#ifdef DEBUG_WITH_DIAGNOSTIC_STYLE
#include "lib/diagnosticstyle.h"
#endif

#ifdef FULL_LOG_FORMAT
    #ifdef QT_DEBUG
        const QString message_pattern(
            "camcops[%{threadid}]: %{time yyyy-MM-ddTHH:mm:ss.zzz}"
            ": %{type}: %{file}(%{line}): %{message}");
    #else
        const QString message_pattern(
            "camcops[%{threadid}]: %{time yyyy-MM-ddTHH:mm:ss.zzz}"
            ": %{type}: %{message}");
    #endif
#else
    const QString message_pattern("camcops: %{type}: %{message}");
#endif


#ifdef DEBUG_TEST_BASIC_QT_ONLY
int runMinimalQtApp(int& argc, char* argv[])
{
    QApplication app(argc, argv);
    QPushButton button("Hello, world!");
    button.show();
    return app.exec();
}
#endif


VISIBLE_SYMBOL int main(int argc, char* argv[])
{
    /*
    NOTE: argc must be passed to the QApplication as a REFERENCE to int, or the
    app will crash. See
    - https://bugreports.qt.io/browse/QTBUG-5637
    - https://doc.qt.io/qt-6.5/qapplication.html
    */

#ifdef DEBUG_TEST_BASIC_QT_ONLY
    // For when it all breaks!
    return runMinimalQtApp(argc, argv);
#else

    // ========================================================================
    // Qt environment variables
    // ========================================================================

    // Can switch media backend here from default ("ffmpeg" on most platforms)
    // https://doc.qt.io/qt-6.5/qtmultimedia-index.html#changing-backends
    // qputenv("QT_MEDIA_BACKEND", "android");

#ifdef DISABLE_ANDROID_NATIVE_DIALOGS
    // To fix a message box bug: https://bugreports.qt.io/browse/QTBUG-35313
    qputenv("QT_USE_ANDROID_NATIVE_DIALOGS", "0");
    // ... read by QAndroidPlatformTheme::usePlatformNativeDialog in qandroidplatformtheme.cpp
#endif

#ifdef QT_OPENGL_IN_SOFTWARE
    // To fix a crash when opening the camera system of
    // "fatal: unknown(0): Failed to create OpenGL context for format QSurfaceFormat"
    // ... see https://bugreports.qt.io/browse/QTBUG-47540

    // Set OpenGL to use software rendering:
    // qputenv("QT_OPENGL", "software");  // doesn't fix it

    // Show Qt scenegraph information:
    // qputenv("QSG_INFO", "1");  // doesn't seem to do much

    // Also try:
    // $ ~/dev/qt_local_build/qt_linux_x86_64_install/bin/qtdiag
    // ... which might say "Unable to create an Open GL context."

    // See also:
    // - https://stackoverflow.com/questions/41021681/qt-how-to-detect-which-version-of-opengl-is-being-used
    // - https://blog.qt.io/blog/2017/01/18/opengl-implementation-qt-quick-app-using-today/

    // THE UPSHOT: I needed (1) to reboot my computer, and (2) to make CamCOPS
    // check for OpenGL, rather than just crashing if it wasn't present.
    // See QuPhoto.
#endif

    // ========================================================================
    // Qt style preamble
    // ========================================================================

    /*
    -   Almost the VERY FIRST THING we do is to create a QApplication, and that
        requires one bit of preamble.
        http://stackoverflow.com/questions/27963697
    -   Prevent native styling, which makes (for example) QListWidget colours
        not work from the stylsheet. This must be done before the app is
        created. See https://bugreports.qt.io/browse/QTBUG-45517
    */

#ifdef DEBUG_WITH_DIAGNOSTIC_STYLE
    // Overlay widgets with bounding box and class name
    auto style = new DiagnosticStyle();
#else
    QStyle* style = QStyleFactory::create("Fusion");
#endif

    // QProxyStyle* proxy_style = new TreeViewProxyStyle(style);

    QApplication::setStyle(style);
    // ... https://stackoverflow.com/questions/41184723/i-want-qt-app-to-look-like-qt-app-rather-than-android-native

    // ========================================================================
    // Set up log format
    // ========================================================================

    qSetMessagePattern(message_pattern);
    // See also http://stackoverflow.com/questions/4954140/how-to-redirect-qdebug-qwarning-qcritical-etc-output

    // ========================================================================
    // Create and run QApplication
    // ========================================================================

    CamcopsApp app(argc, argv);
#ifdef OPENSSL_VIA_QLIBRARY
    cryptofunc::ensureAllCryptoFunctionsLoaded();
#endif
    return app.run();

#endif
}