homewidget.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. #include "homewidget.h"
  19. #include "src/functions/statistics.h"
  20. #include "src/gui/widgets/totalswidget.h"
  21. #include "ui_homewidget.h"
  22. #include "src/database/database.h"
  23. #include "src/classes/time.h"
  24. #include "src/classes/settings.h"
  25. #include "src/database/row.h"
  26. // EASA FTL Limitations in minutes
  27. // 100 hours per 28 days
  28. static const int ROLLING_28_DAYS = 6000;
  29. // 900 hours per calendar year
  30. static const int CALENDAR_YEAR = 54000;
  31. // 1000 hours per rolling 12 months
  32. static const int ROLLING_12_MONTHS = 60000;
  33. // Todo: Encapsulate and plan to also use non-EASA (FAA,...) options
  34. HomeWidget::HomeWidget(QWidget *parent) :
  35. QWidget(parent),
  36. ui(new Ui::HomeWidget)
  37. {
  38. ui->setupUi(this);
  39. today = QDate::currentDate();
  40. ftlWarningThreshold = Settings::getFtlWarningThreshold();
  41. currWarningThreshold = Settings::getCurrencyWarningThreshold();
  42. auto logo = QPixmap(OPL::Assets::LOGO);
  43. ui->logoLabel->setPixmap(logo);
  44. ui->welcomeLabel->setText(tr("Welcome to openPilotLog, %1!").arg(getLogbookOwnerName()));
  45. limitationDisplayLabels = {
  46. ui->TakeOffDisplayLabel, ui->LandingsDisplayLabel,
  47. ui->FlightTime28dDisplayLabel, ui->FlightTimeCalYearDisplayLabel,
  48. ui->FlightTime12mDisplayLabel
  49. };
  50. fillTotals();
  51. fillSelectedCurrencies();
  52. fillLimitations();
  53. QObject::connect(DB, &OPL::Database::dataBaseUpdated,
  54. this, &HomeWidget::onPilotsDatabaseChanged);
  55. }
  56. HomeWidget::~HomeWidget()
  57. {
  58. delete ui;
  59. }
  60. void HomeWidget::refresh()
  61. {
  62. const auto label_list = this->findChildren<QLabel *>();
  63. for (const auto label : label_list)
  64. label->setVisible(true);
  65. for (const auto &label : qAsConst(limitationDisplayLabels))
  66. label->setStyleSheet(QString());
  67. fillTotals();
  68. fillSelectedCurrencies();
  69. fillLimitations();
  70. }
  71. void HomeWidget::onPilotsDatabaseChanged(const OPL::DbTable table)
  72. {
  73. // maybe logbook owner name has changed, redraw
  74. if (table == OPL::DbTable::Pilots)
  75. ui->welcomeLabel->setText(tr("Welcome to openPilotLog, %1!").arg(getLogbookOwnerName()));
  76. }
  77. void HomeWidget::changeEvent(QEvent *event)
  78. {
  79. if (event != nullptr)
  80. if(event->type() == QEvent::LanguageChange)
  81. ui->retranslateUi(this);
  82. }
  83. /*!
  84. * \brief HomeWidget::fillTotals Retreives a Database Summary of Total Flight Time via the OPL::Statistics::totals
  85. * function and parses the return to fill out the QLineEdits.
  86. */
  87. void HomeWidget::fillTotals()
  88. {
  89. auto tw = new TotalsWidget(TotalsWidget::TotalTimeWidget, this);
  90. ui->totalsStackedWidget->addWidget(tw);
  91. ui->totalsStackedWidget->setCurrentWidget(tw);
  92. }
  93. void HomeWidget::fillCurrency(OPL::CurrencyEntry::Currency currency, QLabel* display_label)
  94. {
  95. const auto currency_entry = DB->getCurrencyEntry(currency);
  96. if (currency_entry.isValid()) {
  97. // set label for custom currencies
  98. if (currency == OPL::CurrencyEntry::Custom1) {
  99. ui->currCustom1Label->setText(currency_entry.getDisplayName());
  100. } else if (currency == OPL::CurrencyEntry::Custom2) {
  101. ui->currCustom2Label->setText(currency_entry.getDisplayName());
  102. }
  103. // get date and set visible
  104. const QDate date = currency_entry.getExpiryDate();
  105. display_label->setText(date.toString(Qt::ISODate));
  106. setLabelColour(display_label, Colour::None);
  107. if (today >= date) {
  108. // currency is expired
  109. setLabelColour(display_label, Colour::Red);
  110. return;
  111. } else if (today.addDays(currWarningThreshold) >= date) {
  112. // currency expires less than <currWarningThreshold> days from current Date
  113. setLabelColour(display_label, Colour::Orange);
  114. }
  115. } else {
  116. display_label->setText(tr("Invalid Date"));
  117. }
  118. }
  119. /*!
  120. * \brief HomeWidget::fillSelectedCurrencies Checks whether a currency is selected and
  121. * retreives and displays relevant data.
  122. */
  123. void HomeWidget::fillSelectedCurrencies()
  124. {
  125. fillCurrencyTakeOffLanding();
  126. Settings::getShowCurrency(OPL::CurrencyEntry::Licence) ?
  127. fillCurrency(OPL::CurrencyEntry::Licence, ui->currLicDisplayLabel)
  128. : hideLabels(ui->currLicLabel, ui->currLicDisplayLabel);
  129. Settings::getShowCurrency(OPL::CurrencyEntry::TypeRating) ?
  130. fillCurrency(OPL::CurrencyEntry::TypeRating, ui->currTrDisplayLabel)
  131. : hideLabels(ui->currTrLabel, ui->currTrDisplayLabel);
  132. Settings::getShowCurrency(OPL::CurrencyEntry::LineCheck) ?
  133. fillCurrency(OPL::CurrencyEntry::LineCheck, ui->currLckDisplayLabel)
  134. : hideLabels(ui->currLckLabel, ui->currLckDisplayLabel);
  135. Settings::getShowCurrency(OPL::CurrencyEntry::Medical) ?
  136. fillCurrency(OPL::CurrencyEntry::Medical, ui->currMedDisplayLabel)
  137. : hideLabels(ui->currMedLabel, ui->currMedDisplayLabel);
  138. Settings::getShowCurrency(OPL::CurrencyEntry::Custom1) ?
  139. fillCurrency(OPL::CurrencyEntry::Custom1, ui->currCustom1DisplayLabel)
  140. : hideLabels(ui->currCustom1Label, ui->currCustom1DisplayLabel);
  141. Settings::getShowCurrency(OPL::CurrencyEntry::Custom2) ?
  142. fillCurrency(OPL::CurrencyEntry::Custom2, ui->currCustom2DisplayLabel)
  143. : hideLabels(ui->currCustom2Label, ui->currCustom2DisplayLabel);
  144. }
  145. /*!
  146. * \brief HomeWidget::fillCurrencyTakeOffLanding Uses OPL::Statistics::countTakeOffLandings to determine
  147. * the amount of Take-Offs and Landings in the last 90 days and displays data and notifications
  148. * as required.
  149. */
  150. void HomeWidget::fillCurrencyTakeOffLanding()
  151. {
  152. const auto takeoff_landings = OPL::Statistics::countTakeOffLanding();
  153. if(takeoff_landings.isEmpty())
  154. return;
  155. ui->TakeOffDisplayLabel->setText(takeoff_landings[0].toString());
  156. if (takeoff_landings[0].toUInt() < 3)
  157. setLabelColour(ui->TakeOffDisplayLabel, Colour::Red);
  158. ui->LandingsDisplayLabel->setText(takeoff_landings[1].toString());
  159. if (takeoff_landings[1].toUInt() < 3)
  160. setLabelColour(ui->LandingsDisplayLabel, Colour::Red);
  161. if (Settings::getShowCurrency(OPL::CurrencyEntry::TakeOffLanding)) {
  162. QDate expiration_date = OPL::Statistics::currencyTakeOffLandingExpiry();
  163. if (expiration_date <= QDate::currentDate())
  164. setLabelColour(ui->currToLdgDisplayLabel, Colour::Red);
  165. ui->currToLdgDisplayLabel->setText(expiration_date.toString(Qt::TextDate));
  166. } else {
  167. ui->currToLdgLabel->hide();
  168. ui->currToLdgDisplayLabel->hide();
  169. }
  170. }
  171. /*!
  172. * \brief HomeWidget::fillLimitations Queries OPL::Statistics to obtain information regarding cumulative
  173. * Flight Times and Calculates and Notifies about approaching Flight Time Limitations
  174. */
  175. void HomeWidget::fillLimitations()
  176. {
  177. int minutes = OPL::Statistics::totalTime(OPL::Statistics::TimeFrame::Rolling28Days);
  178. ui->FlightTime28dDisplayLabel->setText(OPL::Time(minutes).toString());
  179. if (minutes >= ROLLING_28_DAYS) {
  180. setLabelColour(ui->FlightTime28dDisplayLabel, Colour::Red);
  181. } else if (minutes >= ROLLING_28_DAYS * ftlWarningThreshold) {
  182. setLabelColour(ui->FlightTime28dDisplayLabel, Colour::Orange);
  183. }
  184. minutes = OPL::Statistics::totalTime(OPL::Statistics::TimeFrame::Rolling12Months);
  185. ui->FlightTime12mDisplayLabel->setText(OPL::Time(minutes).toString());
  186. if (minutes >= ROLLING_12_MONTHS) {
  187. setLabelColour(ui->FlightTime12mDisplayLabel, Colour::Red);
  188. } else if (minutes >= ROLLING_12_MONTHS * ftlWarningThreshold) {
  189. setLabelColour(ui->FlightTime12mDisplayLabel, Colour::Orange);
  190. }
  191. minutes = OPL::Statistics::totalTime(OPL::Statistics::TimeFrame::CalendarYear);
  192. ui->FlightTimeCalYearDisplayLabel->setText(OPL::Time(minutes).toString());
  193. if (minutes >= CALENDAR_YEAR) {
  194. setLabelColour(ui->FlightTimeCalYearDisplayLabel, Colour::Red);
  195. } else if (minutes >= CALENDAR_YEAR * ftlWarningThreshold) {
  196. setLabelColour(ui->FlightTimeCalYearDisplayLabel, Colour::Orange);
  197. }
  198. }
  199. const QString HomeWidget::getLogbookOwnerName()
  200. {
  201. OPL::PilotEntry owner = DB->getLogbookOwner();
  202. QString name = owner.getFirstName();
  203. if(name.isEmpty()) {
  204. name = owner.getLastName();
  205. }
  206. return name;
  207. }