opl.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /*
  2. *openPilotLog - A FOSS Pilot Logbook Application
  3. *Copyright (C) 2020-2023 Felix Turowsky
  4. *
  5. *This program is free software: you can redistribute it and/or modify
  6. *it under the terms of the GNU General Public License as published by
  7. *the Free Software Foundation, either version 3 of the License, or
  8. *(at your option) any later version.
  9. *
  10. *This program is distributed in the hope that it will be useful,
  11. *but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. *GNU General Public License for more details.
  14. *
  15. *You should have received a copy of the GNU General Public License
  16. *along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. #ifndef OPLCONSTANTS_H
  19. #define OPLCONSTANTS_H
  20. #include <QtCore>
  21. #include <QMessageBox>
  22. #include <QComboBox>
  23. #define APPNAME QStringLiteral("openPilotLog")
  24. #define ORGNAME QStringLiteral("opl")
  25. #define ORGDOMAIN QStringLiteral("https://github.com/fiffty-50/openpilotlog")
  26. #define OPL_VERSION 0
  27. #define OPL_SUBVERSION 1
  28. #if OPL_VERSION < 1
  29. #define OPL_VERSION_STRING QString(QString::number(OPL_VERSION) + "." + QString::number(OPL_SUBVERSION)) + "-alpha"
  30. #else
  31. #define OPL_VERSION_STRING QString(QString::number(OPL_VERSION) + "." + QString::number(OPL_SUBVERSION))
  32. #endif
  33. /*!
  34. * \brief A namespace to collect constants and enums used throughout the application.
  35. *
  36. * \details The opl namespace collects enums and constants that are used throughout
  37. * the application and provide uniform access.
  38. *
  39. * The date, time and datetime namespaces include enums used to differentiate
  40. * date and time formats for QDate, QTime and QDateTime that deviate from standard values
  41. * included in the Qt Framework like Qt::ISODate and are to be used in conjunction with the
  42. * .toString() members of these classes.
  43. *
  44. * The db namespace contains constants for programatically accessing the database in a fast
  45. * and uniform manner.
  46. */
  47. namespace OPL {
  48. #if defined(__GNUC__) || defined(__clang__)
  49. #define FUNC_IDENT __PRETTY_FUNCTION__
  50. #elif defined(_MSC_VER)
  51. #define FUNC_IDENT __FUNCSIG__
  52. #else
  53. #define FUNC_IDENT __func__
  54. #endif
  55. #define DEB qDebug() // Use for debugging
  56. #define LOG qInfo() // Use for logging milestones (silently, will be written to log file and console out only)
  57. #define TODO qCritical() << "TO DO:\t"
  58. #define INFO(msg) OPL::ANotificationHandler::info(msg, this) // Use for messages of interest to the user (will be displayed in GUI)
  59. #define WARN(msg) OPL::ANotificationHandler::warn(msg, this) // Use for warnings (will be displayed in GUI)
  60. #define CRIT(msg) OPL::ANotificationHandler::crit(msg, this) // Use for critical warnings (will be displayed in GUI)
  61. /**
  62. * @brief Defines the row ID for non-user entries in the database;
  63. */
  64. constexpr static int STUB_ROW_ID = -1;
  65. /**
  66. * @brief Defines a four-letter code for a non-extistent (dummy) airport: "XXXX"
  67. */
  68. constexpr static auto STUB_AIRPORT_CODE = QLatin1String("XXXX");
  69. /**
  70. * @brief Defines a registration for a non-existent (dummy) aircraft: "XX-XXX"
  71. */
  72. constexpr static auto STUB_AIRCRAFT_REG = QLatin1String("XX-XXX");
  73. /*!
  74. * \brief The decimal seperator used internally
  75. */
  76. constexpr static char DECIMAL_SEPERATOR = '.';
  77. /*!
  78. * \brief The ANotificationHandler class handles displaying of user-directed messages. It displays
  79. * information to the user in a QMessageBox and forwards the displayed message to ALog so it is written
  80. * to the console and log files. The INFO, WARN and CRIT makros provide convenient access.
  81. */
  82. class ANotificationHandler {
  83. public:
  84. static inline void info(const QString msg, QWidget *parent = nullptr){
  85. qInfo() << msg;
  86. auto mb = QMessageBox(QMessageBox::Information, QStringLiteral("Info"), msg, QMessageBox::StandardButton::Ok, parent);
  87. mb.exec();
  88. };
  89. static inline void warn(const QString msg, QWidget *parent = nullptr){
  90. qWarning() << msg;
  91. auto mb = QMessageBox(QMessageBox::Warning, QStringLiteral("Warning"), msg, QMessageBox::StandardButton::Ok, parent);
  92. mb.exec();
  93. };
  94. static inline void crit(const QString msg, QWidget *parent = nullptr){
  95. qCritical() << msg;
  96. auto mb = QMessageBox(QMessageBox::Critical, QStringLiteral("Warning"), msg, QMessageBox::StandardButton::Ok, parent);
  97. mb.exec();
  98. };
  99. }; // class ANotificationHandler
  100. using RowData_T = QHash<QString, QVariant>;
  101. struct ToLdgCount_T {
  102. int toDay;
  103. int toNight;
  104. int ldgDay;
  105. int ldgNight;
  106. ToLdgCount_T(int toDay, int toNight, int ldgDay, int ldgNight)
  107. : toDay(toDay), toNight(toNight), ldgDay(ldgDay), ldgNight(ldgNight) {}
  108. };
  109. /*!
  110. * \brief The DateFormat struct encapsulates how date and time values are displayed.
  111. * \details Stores how the user wishes to display and enter Date and Time Entries.
  112. * These are stored numerically in the database and thus need to be converted to
  113. * human-readably form.
  114. */
  115. struct DateTimeFormat {
  116. /*!
  117. * \brief Enumerates how dates can be formatted to a localised format.
  118. * \value Default - The Application standard, Equivalent to Qt::ISODate
  119. * \value SystemLocale - The current system locale date format
  120. */
  121. enum class DateFormat { Default, SystemLocale, Custom };
  122. /*!
  123. * \brief Enumerates how time values can be formatted
  124. * \value Default - The application default is 'hh:mm'
  125. * \value Decimal - Time as Decmial hours (01:30 == 1.5)
  126. * \value Custom - A user-provided custom format string
  127. */
  128. enum class TimeFormat { Default, Decimal, Custom };
  129. /*!
  130. * \brief Initialise a DateTimeFormat instance with default values
  131. */
  132. DateTimeFormat()
  133. : m_dateFormat(DateFormat::Default),
  134. m_dateFormatString(QStringLiteral("yyyy-MM-dd")),
  135. m_timeFormat(TimeFormat::Default),
  136. m_timeFormatString(QStringLiteral("hh:mm"))
  137. {}
  138. DateTimeFormat(DateFormat dateFormat_,
  139. const QString &dateFormatString_,
  140. TimeFormat timeFormat_,
  141. const QString &timeFormatString_)
  142. :
  143. m_dateFormat(dateFormat_),
  144. m_dateFormatString(dateFormatString_),
  145. m_timeFormat(timeFormat_),
  146. m_timeFormatString(timeFormatString_)
  147. {}
  148. public:
  149. DateFormat dateFormat() const { return m_dateFormat; }
  150. TimeFormat timeFormat() const { return m_timeFormat; }
  151. const QString &dateFormatString() const { return m_dateFormatString; }
  152. const QString &timeFormatString() const { return m_timeFormatString; }
  153. private:
  154. DateFormat m_dateFormat;
  155. TimeFormat m_timeFormat;
  156. QString m_dateFormatString;
  157. QString m_timeFormatString;
  158. };
  159. /*!
  160. * \brief ADateFormats enumerates the accepted date formats for QDateEdits
  161. * \todo At the moment, only ISODate is accepet as a valid date format.
  162. */
  163. enum class DateFormat {ISODate, DE, EN };
  164. enum class FlightTimeFormat {Default, Decimal};
  165. enum class DateTimeFormat_deprecated {Default, Backup};
  166. /*!
  167. * \brief PilotFunction
  168. * Pilot in Command, Pilot in Command under Supervision, Second in Command (Co-Pilot), Dual, Flight Instructor
  169. */
  170. enum class PilotFunction {PIC = 0, PICUS = 1, SIC = 2, DUAL = 3, FI = 4};
  171. /*!
  172. * \brief Enumerates the available translations
  173. */
  174. enum class Translation {English, German, Spanish};
  175. /*!
  176. * \brief Enumerates the available SQL views in the database
  177. */
  178. enum class LogbookView {Default, DefaultWithSim, Easa, EasaWithSim, SimulatorOnly};
  179. /*!
  180. * \brief Enumerates the Simulator Types: Flight and Navigation Procedures Trainer 1/2, Flight Simulation Training Device
  181. */
  182. enum class SimulatorType {FNPTI = 0, FNPTII = 1, FSTD = 2};
  183. /*!
  184. * \brief Enumerates the tables in the database
  185. */
  186. enum class DbTable {Any, Flights, Simulators, Pilots, Tails, Aircraft, Airports, Currencies, Changelog, PreviousExperience};
  187. /*!
  188. * \brief Enumerates the currency names
  189. */
  190. enum class CurrencyName {Licence = 1, TypeRating = 2, LineCheck = 3, Medical = 4, Custom1 = 5, Custom2 = 6};
  191. /*!
  192. * \brief The OplGlobals class encapsulates non-POD globals to avoid making them static. It is available
  193. * 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.
  194. * For more information, see (Q_GLOBAL_STATIC)[https://doc.qt.io/qt-5/qglobalstatic.html#details]
  195. */
  196. class OplGlobals : public QObject {
  197. public:
  198. OplGlobals() = default;
  199. void fillLanguageComboBox(QComboBox *combo_box) const;
  200. void fillViewNamesComboBox(QComboBox *combo_box) const;
  201. void loadPilotFunctios(QComboBox *combo_box) const;
  202. void loadSimulatorTypes(QComboBox *combo_box) const;
  203. void loadApproachTypes(QComboBox *combo_box) const;
  204. inline const QStringList &getApproachTypes() const {return APPROACH_TYPES;}
  205. inline const QString getLanguageFilePath(Translation language) const {return L10N_FilePaths.value(language);}
  206. inline const QString getViewIdentifier(LogbookView view_name) const {return DATABASE_VIEWS.value(view_name);}
  207. inline const QString getDbTableName(DbTable table_name) const {return DB_TABLES.value(table_name);}
  208. private:
  209. Q_OBJECT
  210. const static inline QMap<Translation, QString> L10N_FilePaths {
  211. {Translation::English, QStringLiteral("l10n/openpilotlog_en")},
  212. {Translation::German, QStringLiteral("l10n/openpilotlog_de")},
  213. {Translation::Spanish, QStringLiteral("l10n/openpilotlog_es")},
  214. };
  215. const static inline QMap<Translation, QString> L10N_DisplayNames {
  216. {Translation::English, QStringLiteral("English")},
  217. {Translation::German, QStringLiteral("Deutsch")},
  218. {Translation::Spanish, QStringLiteral("Español")},
  219. };
  220. const static inline QMap<LogbookView, QString> DATABASE_VIEWS = {
  221. {LogbookView::Default, QStringLiteral("viewDefault")},
  222. {LogbookView::DefaultWithSim, QStringLiteral("viewDefaultSim")},
  223. {LogbookView::Easa, QStringLiteral("viewEasa")},
  224. {LogbookView::EasaWithSim, QStringLiteral("viewEasaSim")},
  225. {LogbookView::SimulatorOnly, QStringLiteral("viewSimulators")},
  226. };
  227. const QMap<LogbookView, QString> DATABASE_VIEW_DISPLAY_NAMES = {
  228. {LogbookView::Default, tr("Default")},
  229. {LogbookView::DefaultWithSim, tr("Default with Simulator")},
  230. {LogbookView::Easa, tr("EASA-FCL")},
  231. {LogbookView::EasaWithSim, tr("EASA-FCL with Simulator")},
  232. {LogbookView::SimulatorOnly, tr("Simulator Sessions Only")},
  233. };
  234. const static inline QMap<PilotFunction, QString> PILOT_FUNCTIONS = {
  235. {PilotFunction::PIC, QStringLiteral("PIC")},
  236. {PilotFunction::PICUS, QStringLiteral("PICUS")},
  237. {PilotFunction::SIC, QStringLiteral("SIC")},
  238. {PilotFunction::DUAL, QStringLiteral("DUAL")},
  239. {PilotFunction::FI, QStringLiteral("FI")},
  240. };
  241. const static inline QMap<SimulatorType, QString> SIMULATOR_TYPES = {
  242. {SimulatorType::FNPTI, QStringLiteral("FNPT I")},
  243. {SimulatorType::FNPTII, QStringLiteral("FNPT II")},
  244. {SimulatorType::FSTD, QStringLiteral("FSTD")},
  245. };
  246. const static inline QMap<DbTable, QString> DB_TABLES = {
  247. {DbTable::Flights, QStringLiteral("flights")},
  248. {DbTable::Simulators, QStringLiteral("simulators")},
  249. {DbTable::Pilots, QStringLiteral("pilots")},
  250. {DbTable::Tails, QStringLiteral("tails")},
  251. {DbTable::Aircraft, QStringLiteral("aircraft")},
  252. {DbTable::Airports, QStringLiteral("airports")},
  253. {DbTable::Currencies, QStringLiteral("currencies")},
  254. {DbTable::Changelog, QStringLiteral("changelog")},
  255. {DbTable::PreviousExperience, QStringLiteral("previousExperience")},
  256. };
  257. const static inline QStringList APPROACH_TYPES = {
  258. QStringLiteral("VISUAL"),
  259. QStringLiteral("ILS CAT I"),
  260. QStringLiteral("ILS CAT II"),
  261. QStringLiteral("ILS CAT III"),
  262. QStringLiteral("GLS"),
  263. QStringLiteral("MLS"),
  264. QStringLiteral("LOC"),
  265. QStringLiteral("LOC/DME"),
  266. QStringLiteral("RNAV"),
  267. QStringLiteral("RNAV (LNAV)"),
  268. QStringLiteral("RNAV (LNAV/VNAV)"),
  269. QStringLiteral("RNAV (LPV)"),
  270. QStringLiteral("RNAV (RNP)"),
  271. QStringLiteral("RNAV (RNP-AR)"),
  272. QStringLiteral("VOR"),
  273. QStringLiteral("VOR/DME"),
  274. QStringLiteral("NDB"),
  275. QStringLiteral("NDB/DME"),
  276. QStringLiteral("TACAN"),
  277. QStringLiteral("SRA"),
  278. QStringLiteral("PAR"),
  279. QStringLiteral("OTHER")
  280. };
  281. };
  282. //Make available as a global static
  283. Q_GLOBAL_STATIC(OplGlobals, GLOBALS)
  284. namespace Assets {
  285. const inline auto DATABASE_SCHEMA = QStringLiteral(":/database/database_schema.sql");
  286. const inline auto DATABASE_TEMPLATE_AIRCRAFT = QStringLiteral(":/database/templates/aircraft.json");
  287. const inline auto DATABASE_TEMPLATE_AIRPORT = QStringLiteral(":/database/templates/airports.json");
  288. const inline auto DATABASE_TEMPLATE_CHANGELOG = QStringLiteral(":/database/templates/changelog.json");
  289. const inline auto LOGO = QStringLiteral(":/icons/opl-icons/logos/logo_text.png");
  290. const inline auto ICON_MAIN = QStringLiteral(":/icons/opl-icons/app/icon_main.png");
  291. const inline auto ICON_APPICON_LINUX = QStringLiteral(":/icons/opl-icons/app/icon_linux.svg");
  292. const inline auto ICON_APPICON_IOS = QStringLiteral(":/icons/opl-icons/app/icon_ios.icns");
  293. const inline auto ICON_APPICON_WIN = QStringLiteral(":/icons/opl-icons/app/icon_windows.ico");
  294. const inline auto ICON_TOOLBAR_HOME = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_home.svg");
  295. const inline auto ICON_TOOLBAR_NEW_FLIGHT = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_new_flight.svg");
  296. const inline auto ICON_TOOLBAR_LOGBOOK = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_logbook.svg");
  297. const inline auto ICON_TOOLBAR_AIRCRAFT = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_airplane.svg");
  298. const inline auto ICON_TOOLBAR_PILOT = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_pilot.svg");
  299. const inline auto ICON_TOOLBAR_SETTINGS = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_settings.svg");
  300. const inline auto ICON_TOOLBAR_QUIT = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_exit.svg");
  301. const inline auto ICON_TOOLBAR_BACKUP = QStringLiteral(":/icons/opl-icons/toolbar/thick/light/icon_backup.svg");
  302. const inline auto ICON_TOOLBAR_HOME_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_home_dm.svg");
  303. const inline auto ICON_TOOLBAR_NEW_FLIGHT_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_new_flight_dm.svg");
  304. const inline auto ICON_TOOLBAR_LOGBOOK_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_logbook_dm.svg");
  305. const inline auto ICON_TOOLBAR_AIRCRAFT_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_airplane_dm.svg");
  306. const inline auto ICON_TOOLBAR_PILOT_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_pilot_dm.svg");
  307. const inline auto ICON_TOOLBAR_SETTINGS_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_settings_dm.svg");
  308. const inline auto ICON_TOOLBAR_QUIT_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_exit_dm.svg");
  309. const inline auto ICON_TOOLBAR_BACKUP_DARK = QStringLiteral(":/icons/opl-icons/toolbar/thick/dark/icon_backup_dm.svg");
  310. }
  311. namespace CssStyles {
  312. const inline auto RED_BORDER = QStringLiteral("border: 1px solid red");
  313. } // namespace Styles
  314. //namespace Format {
  315. //const inline auto TIME_FORMAT = QStringLiteral("hh:mm");
  316. //} // namespace Format
  317. namespace RegEx {
  318. const inline auto RX_PHONE_NUMBER = QRegularExpression(QStringLiteral("^[+]{0,1}[0-9\\-\\s]+"));
  319. 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)))$"));
  320. const inline auto RX_AIRPORT_CODE = QRegularExpression(QStringLiteral("[a-zA-Z0-9]{1,4}"));
  321. } // namespace RegEx
  322. } // namespace opl
  323. #endif // OPLCONSTANTS_H