/* *openPilotLog - A FOSS Pilot Logbook Application *Copyright (C) 2020-2023 Felix Turowsky * *This program 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. * *This program 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 this program. If not, see . */ #ifndef OPLCONSTANTS_H #define OPLCONSTANTS_H #include #include #include #define APPNAME QStringLiteral("openPilotLog") #define ORGNAME QStringLiteral("opl") #define ORGDOMAIN QStringLiteral("https://github.com/fiffty-50/openpilotlog") #define OPL_VERSION 0 #define OPL_SUBVERSION 1 #if OPL_VERSION < 1 #define OPL_VERSION_STRING QString(QString::number(OPL_VERSION) + "." + QString::number(OPL_SUBVERSION)) + "-alpha" #else #define OPL_VERSION_STRING QString(QString::number(OPL_VERSION) + "." + QString::number(OPL_SUBVERSION)) #endif /*! * \brief A namespace to collect constants and enums used throughout the application. * * \details The opl namespace collects enums and constants that are used throughout * the application and provide uniform access. * * The date, time and datetime namespaces include enums used to differentiate * date and time formats for QDate, QTime and QDateTime that deviate from standard values * included in the Qt Framework like Qt::ISODate and are to be used in conjunction with the * .toString() members of these classes. * * The db namespace contains constants for programatically accessing the database in a fast * and uniform manner. */ namespace OPL { #if defined(__GNUC__) || defined(__clang__) #define FUNC_IDENT __PRETTY_FUNCTION__ #elif defined(_MSC_VER) #define FUNC_IDENT __FUNCSIG__ #else #define FUNC_IDENT __func__ #endif #define DEB qDebug() // Use for debugging #define LOG qInfo() // Use for logging milestones (silently, will be written to log file and console out only) #define TODO qCritical() << "TO DO:\t" #define INFO(msg) OPL::ANotificationHandler::info(msg, this) // Use for messages of interest to the user (will be displayed in GUI) #define WARN(msg) OPL::ANotificationHandler::warn(msg, this) // Use for warnings (will be displayed in GUI) #define CRIT(msg) OPL::ANotificationHandler::crit(msg, this) // Use for critical warnings (will be displayed in GUI) /** * @brief Defines the row ID for non-user entries in the database; */ constexpr static int STUB_ROW_ID = -1; /** * @brief Defines a four-letter code for a non-extistent (dummy) airport: "XXXX" */ constexpr static auto STUB_AIRPORT_CODE = QLatin1String("XXXX"); /** * @brief Defines a registration for a non-existent (dummy) aircraft: "XX-XXX" */ constexpr static auto STUB_AIRCRAFT_REG = QLatin1String("XX-XXX"); /*! * \brief The decimal seperator used internally */ constexpr static char DECIMAL_SEPERATOR = '.'; /*! * \brief The ANotificationHandler class handles displaying of user-directed messages. It displays * information to the user in a QMessageBox and forwards the displayed message to ALog so it is written * to the console and log files. The INFO, WARN and CRIT makros provide convenient access. */ class ANotificationHandler { public: static inline void info(const QString msg, QWidget *parent = nullptr){ qInfo() << msg; auto mb = QMessageBox(QMessageBox::Information, QStringLiteral("Info"), msg, QMessageBox::StandardButton::Ok, parent); mb.exec(); }; static inline void warn(const QString msg, QWidget *parent = nullptr){ qWarning() << msg; auto mb = QMessageBox(QMessageBox::Warning, QStringLiteral("Warning"), msg, QMessageBox::StandardButton::Ok, parent); mb.exec(); }; static inline void crit(const QString msg, QWidget *parent = nullptr){ qCritical() << msg; auto mb = QMessageBox(QMessageBox::Critical, QStringLiteral("Warning"), msg, QMessageBox::StandardButton::Ok, parent); mb.exec(); }; }; // class ANotificationHandler using RowData_T = QHash; struct ToLdgCount_T { int toDay; int toNight; int ldgDay; int ldgNight; ToLdgCount_T(int toDay, int toNight, int ldgDay, int ldgNight) : toDay(toDay), toNight(toNight), ldgDay(ldgDay), ldgNight(ldgNight) {} }; /*! * \brief The DateFormat struct encapsulates how date and time values are displayed. * \details Stores how the user wishes to display and enter Date and Time Entries. * These are stored numerically in the database and thus need to be converted to * human-readably form. */ struct DateTimeFormat { /*! * \brief Enumerates how dates can be formatted to a localised format. * \value Default - The Application standard, Equivalent to Qt::ISODate * \value SystemLocale - The current system locale date format */ enum class DateFormat { Default, SystemLocale, Custom }; /*! * \brief Enumerates how time values can be formatted * \value Default - The application default is 'hh:mm' * \value Decimal - Time as Decmial hours (01:30 == 1.5) * \value Custom - A user-provided custom format string */ enum class TimeFormat { Default, Decimal, Custom }; /*! * \brief Initialise a DateTimeFormat instance with default values */ DateTimeFormat() : m_dateFormat(DateFormat::Default), m_dateFormatString(QStringLiteral("yyyy-MM-dd")), m_timeFormat(TimeFormat::Default), m_timeFormatString(QStringLiteral("hh:mm")) {} DateTimeFormat(DateFormat dateFormat_, const QString &dateFormatString_, TimeFormat timeFormat_, const QString &timeFormatString_) : m_dateFormat(dateFormat_), m_dateFormatString(dateFormatString_), m_timeFormat(timeFormat_), m_timeFormatString(timeFormatString_) {} public: DateFormat dateFormat() const { return m_dateFormat; } TimeFormat timeFormat() const { return m_timeFormat; } const QString &dateFormatString() const { return m_dateFormatString; } const QString &timeFormatString() const { return m_timeFormatString; } private: DateFormat m_dateFormat; TimeFormat m_timeFormat; QString m_dateFormatString; QString m_timeFormatString; }; /*! * \brief ADateFormats enumerates the accepted date formats for QDateEdits * \todo At the moment, only ISODate is accepet as a valid date format. */ enum class DateFormat {ISODate, DE, EN }; enum class FlightTimeFormat {Default, Decimal}; enum class DateTimeFormat_deprecated {Default, Backup}; /*! * \brief PilotFunction * Pilot in Command, Pilot in Command under Supervision, Second in Command (Co-Pilot), Dual, Flight Instructor */ enum class PilotFunction {PIC = 0, PICUS = 1, SIC = 2, DUAL = 3, FI = 4}; /*! * \brief Enumerates the available translations */ enum class Translation {English, German, Spanish}; /*! * \brief Enumerates the available SQL views in the database */ enum class LogbookView {Default, DefaultWithSim, Easa, EasaWithSim, SimulatorOnly}; /*! * \brief Enumerates the Simulator Types: Flight and Navigation Procedures Trainer 1/2, Flight Simulation Training Device */ enum class SimulatorType {FNPTI = 0, FNPTII = 1, FSTD = 2}; /*! * \brief Enumerates the tables in the database */ enum class DbTable {Any, Flights, Simulators, Pilots, Tails, Aircraft, Airports, Currencies, Changelog, PreviousExperience}; /*! * \brief Enumerates the currency names */ enum class CurrencyName {Licence = 1, TypeRating = 2, LineCheck = 3, Medical = 4, Custom1 = 5, Custom2 = 6}; /*! * \brief The OplGlobals class encapsulates non-POD globals to avoid making them static. It is available * as a global static object via the OPL::GLOBAL makro and may be used as if it were a pointer, guaranteed to be initialized exactly once. * For more information, see (Q_GLOBAL_STATIC)[https://doc.qt.io/qt-5/qglobalstatic.html#details] */ class OplGlobals : public QObject { public: OplGlobals() = default; void fillLanguageComboBox(QComboBox *combo_box) const; void fillViewNamesComboBox(QComboBox *combo_box) const; void loadPilotFunctios(QComboBox *combo_box) const; void loadSimulatorTypes(QComboBox *combo_box) const; void loadApproachTypes(QComboBox *combo_box) const; inline const QStringList &getApproachTypes() const {return APPROACH_TYPES;} inline const QString getLanguageFilePath(Translation language) const {return L10N_FilePaths.value(language);} inline const QString getViewIdentifier(LogbookView view_name) const {return DATABASE_VIEWS.value(view_name);} inline const QString getDbTableName(DbTable table_name) const {return DB_TABLES.value(table_name);} private: Q_OBJECT const static inline QMap L10N_FilePaths { {Translation::English, QStringLiteral("l10n/openpilotlog_en")}, {Translation::German, QStringLiteral("l10n/openpilotlog_de")}, {Translation::Spanish, QStringLiteral("l10n/openpilotlog_es")}, }; const static inline QMap L10N_DisplayNames { {Translation::English, QStringLiteral("English")}, {Translation::German, QStringLiteral("Deutsch")}, {Translation::Spanish, QStringLiteral("Español")}, }; const static inline QMap DATABASE_VIEWS = { {LogbookView::Default, QStringLiteral("viewDefault")}, {LogbookView::DefaultWithSim, QStringLiteral("viewDefaultSim")}, {LogbookView::Easa, QStringLiteral("viewEasa")}, {LogbookView::EasaWithSim, QStringLiteral("viewEasaSim")}, {LogbookView::SimulatorOnly, QStringLiteral("viewSimulators")}, }; const QMap DATABASE_VIEW_DISPLAY_NAMES = { {LogbookView::Default, tr("Default")}, {LogbookView::DefaultWithSim, tr("Default with Simulator")}, {LogbookView::Easa, tr("EASA-FCL")}, {LogbookView::EasaWithSim, tr("EASA-FCL with Simulator")}, {LogbookView::SimulatorOnly, tr("Simulator Sessions Only")}, }; const static inline QMap PILOT_FUNCTIONS = { {PilotFunction::PIC, QStringLiteral("PIC")}, {PilotFunction::PICUS, QStringLiteral("PICUS")}, {PilotFunction::SIC, QStringLiteral("SIC")}, {PilotFunction::DUAL, QStringLiteral("DUAL")}, {PilotFunction::FI, QStringLiteral("FI")}, }; const static inline QMap SIMULATOR_TYPES = { {SimulatorType::FNPTI, QStringLiteral("FNPT I")}, {SimulatorType::FNPTII, QStringLiteral("FNPT II")}, {SimulatorType::FSTD, QStringLiteral("FSTD")}, }; const static inline QMap DB_TABLES = { {DbTable::Flights, QStringLiteral("flights")}, {DbTable::Simulators, QStringLiteral("simulators")}, {DbTable::Pilots, QStringLiteral("pilots")}, {DbTable::Tails, QStringLiteral("tails")}, {DbTable::Aircraft, QStringLiteral("aircraft")}, {DbTable::Airports, QStringLiteral("airports")}, {DbTable::Currencies, QStringLiteral("currencies")}, {DbTable::Changelog, QStringLiteral("changelog")}, {DbTable::PreviousExperience, QStringLiteral("previousExperience")}, }; const static inline QStringList APPROACH_TYPES = { QStringLiteral("VISUAL"), QStringLiteral("ILS CAT I"), QStringLiteral("ILS CAT II"), QStringLiteral("ILS CAT III"), QStringLiteral("GLS"), QStringLiteral("MLS"), QStringLiteral("LOC"), QStringLiteral("LOC/DME"), QStringLiteral("RNAV"), QStringLiteral("RNAV (LNAV)"), QStringLiteral("RNAV (LNAV/VNAV)"), QStringLiteral("RNAV (LPV)"), QStringLiteral("RNAV (RNP)"), QStringLiteral("RNAV (RNP-AR)"), QStringLiteral("VOR"), QStringLiteral("VOR/DME"), QStringLiteral("NDB"), QStringLiteral("NDB/DME"), QStringLiteral("TACAN"), QStringLiteral("SRA"), QStringLiteral("PAR"), QStringLiteral("OTHER") }; }; //Make available as a global static Q_GLOBAL_STATIC(OplGlobals, GLOBALS) namespace Assets { const inline auto DATABASE_SCHEMA = QStringLiteral(":/database/database_schema.sql"); const inline auto DATABASE_TEMPLATE_AIRCRAFT = QStringLiteral(":/database/templates/aircraft.json"); const inline auto DATABASE_TEMPLATE_AIRPORT = QStringLiteral(":/database/templates/airports.json"); const inline auto DATABASE_TEMPLATE_CHANGELOG = QStringLiteral(":/database/templates/changelog.json"); const inline auto LOGO = QStringLiteral(":/icons/opl-icons/logos/logo_text.png"); const inline auto ICON_MAIN = QStringLiteral(":/icons/opl-icons/app/icon_main.png"); const inline auto ICON_APPICON_LINUX = QStringLiteral(":/icons/opl-icons/app/icon_linux.svg"); const inline auto ICON_APPICON_IOS = QStringLiteral(":/icons/opl-icons/app/icon_ios.icns"); const inline auto ICON_APPICON_WIN = QStringLiteral(":/icons/opl-icons/app/icon_windows.ico"); const inline auto ICON_TOOLBAR_HOME = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_home.svg"); const inline auto ICON_TOOLBAR_NEW_FLIGHT = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_new_flight.svg"); const inline auto ICON_TOOLBAR_LOGBOOK = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_logbook.svg"); const inline auto ICON_TOOLBAR_AIRCRAFT = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_airplane.svg"); const inline auto ICON_TOOLBAR_PILOT = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_pilot.svg"); const inline auto ICON_TOOLBAR_SETTINGS = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_settings.svg"); const inline auto ICON_TOOLBAR_QUIT = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_exit.svg"); const inline auto ICON_TOOLBAR_BACKUP = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_backup.svg"); const inline auto ICON_TOOLBAR_HOME_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_home_dm.svg"); const inline auto ICON_TOOLBAR_NEW_FLIGHT_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_new_flight_dm.svg"); const inline auto ICON_TOOLBAR_LOGBOOK_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_logbook_dm.svg"); const inline auto ICON_TOOLBAR_AIRCRAFT_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_airplane_dm.svg"); const inline auto ICON_TOOLBAR_PILOT_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_pilot_dm.svg"); const inline auto ICON_TOOLBAR_SETTINGS_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_settings_dm.svg"); const inline auto ICON_TOOLBAR_QUIT_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_exit_dm.svg"); const inline auto ICON_TOOLBAR_BACKUP_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_backup_dm.svg"); } namespace CssStyles { const inline auto RED_BORDER = QStringLiteral("border: 1px solid red"); } // namespace Styles //namespace Format { //const inline auto TIME_FORMAT = QStringLiteral("hh:mm"); //} // namespace Format namespace RegEx { const inline auto RX_PHONE_NUMBER = QRegularExpression(QStringLiteral("^[+]{0,1}[0-9\\-\\s]+")); const inline auto RX_TIME_ENTRY = QRegularExpression(QStringLiteral("^(?:(?:([01]?\\d|2[0-3])(?::?)([0-5]\\d))|(?:([01]?\\d|2[0-3])([0-5]\\d))|(?:([1-9]|[1-9]\\d)\\:([0-5]\\d)?)|(?:([01]?\\d|2[0-3])\\.([0-5]?\\d)))$")); const inline auto RX_AIRPORT_CODE = QRegularExpression(QStringLiteral("[a-zA-Z0-9]{1,4}")); } // namespace RegEx } // namespace opl #endif // OPLCONSTANTS_H