/* *openPilotLog - A FOSS Pilot Logbook Application *Copyright (C) 2020-2021 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 . */ #include "homewidget.h" #include "ui_homewidget.h" #include "src/functions/alog.h" #include "src/database/adatabase.h" #include "src/functions/atime.h" #include "src/classes/asettings.h" // EASA FTL Limitations in minutes // 100 hours per 28 days static const int ROLLING_28_DAYS = 6000; // 900 hours per calendar year static const int CALENDAR_YEAR = 54000; // 1000 hours per rolling 12 months static const int ROLLING_12_MONTHS = 60000; // Todo: Encapsulate and plan to also use non-EASA (FAA,...) options HomeWidget::HomeWidget(QWidget *parent) : QWidget(parent), ui(new Ui::HomeWidget) { ui->setupUi(this); today = QDate::currentDate(); ftlWarningThreshold = ASettings::read(ASettings::UserData::FtlWarningThreshold).toDouble(); currWarningThreshold = ASettings::read(ASettings::UserData::CurrWarningThreshold).toInt(); auto logo = QPixmap(OPL::Assets::LOGO); ui->logoLabel->setPixmap(logo); ui->welcomeLabel->setText(tr("Welcome to openPilotLog, %1!").arg(userName())); limitationDisplayLabels = { ui->TakeOffDisplayLabel, ui->LandingsDisplayLabel, ui->FlightTime28dDisplayLabel, ui->FlightTimeCalYearDisplayLabel, ui->FlightTime12mDisplayLabel }; LOG << "Filling Home Widget..."; fillTotals(); fillSelectedCurrencies(); fillLimitations(); } HomeWidget::~HomeWidget() { delete ui; } void HomeWidget::refresh() { LOG << "Updating HomeWidget..."; const auto label_list = this->findChildren(); for (const auto label : label_list) label->setVisible(true); for (const auto &label : qAsConst(limitationDisplayLabels)) label->setStyleSheet(QString()); fillTotals(); fillSelectedCurrencies(); fillLimitations(); } void HomeWidget::changeEvent(QEvent *event) { if (event != nullptr) if(event->type() == QEvent::LanguageChange) ui->retranslateUi(this); } /*! * \brief HomeWidget::fillTotals Retreives a Database Summary of Total Flight Time via the AStat::totals * function and parses the return to fill out the QLineEdits. */ void HomeWidget::fillTotals() { const auto data = AStat::totals(); for (const auto &field : data) { auto line_edit = this->findChild(field.first + QLatin1String("LineEdit")); line_edit->setText(field.second); } } void HomeWidget::fillCurrency(ACurrencyEntry::CurrencyName currency_name, QLabel* display_label) { auto currency_entry = aDB->getCurrencyEntry(currency_name); if (currency_entry.isValid()) { auto currency_date = QDate::fromString(currency_entry.tableData.value( OPL::Db::CURRENCIES_EXPIRYDATE).toString(), Qt::ISODate); display_label->setText(currency_date.toString(Qt::TextDate)); setLabelColour(display_label, Colour::None); if (today >= currency_date) { // is expired setLabelColour(display_label, Colour::Red); return; } else if (today.addDays(currWarningThreshold) >=currency_date) { // expires less than days from current Date setLabelColour(display_label, Colour::Orange); } } else { display_label->setText(tr("Invalid Date")); } } /*! * \brief HomeWidget::fillSelectedCurrencies Checks whether a currency is selected and * retreives and displays relevant data. */ void HomeWidget::fillSelectedCurrencies() { fillCurrencyTakeOffLanding(); ASettings::read(ASettings::UserData::ShowLicCurrency).toBool() ? fillCurrency(ACurrencyEntry::CurrencyName::Licence, ui->currLicDisplayLabel) : hideLabels(ui->currLicLabel, ui->currLicDisplayLabel); ASettings::read(ASettings::UserData::ShowTrCurrency).toBool() ? fillCurrency(ACurrencyEntry::CurrencyName::TypeRating, ui->currTrDisplayLabel) : hideLabels(ui->currTrLabel, ui->currTrDisplayLabel); ASettings::read(ASettings::UserData::ShowLckCurrency).toBool() ? fillCurrency(ACurrencyEntry::CurrencyName::LineCheck, ui->currLckDisplayLabel) : hideLabels(ui->currLckLabel, ui->currLckDisplayLabel); ASettings::read(ASettings::UserData::ShowMedCurrency).toBool() ? fillCurrency(ACurrencyEntry::CurrencyName::Medical, ui->currMedDisplayLabel) : hideLabels(ui->currMedLabel, ui->currMedDisplayLabel); ASettings::read(ASettings::UserData::ShowCustom1Currency).toBool() ? fillCurrency(ACurrencyEntry::CurrencyName::Custom1, ui->currCustom1DisplayLabel) : hideLabels(ui->currCustom1Label, ui->currCustom1DisplayLabel); const QString custom1_text = ASettings::read(ASettings::UserData::Custom1CurrencyName).toString(); if (!custom1_text.isEmpty()) ui->currCustom1Label->setText(custom1_text); ASettings::read(ASettings::UserData::ShowCustom2Currency).toBool() ? fillCurrency(ACurrencyEntry::CurrencyName::Custom2, ui->currCustom2DisplayLabel) : hideLabels(ui->currCustom2Label, ui->currCustom2DisplayLabel); const QString custom2_text = ASettings::read(ASettings::UserData::Custom2CurrencyName).toString(); if (!custom2_text.isEmpty()) ui->currCustom2Label->setText(custom2_text); } /*! * \brief HomeWidget::fillCurrencyTakeOffLanding Uses AStat::countTakeOffLandings to determine * the amount of Take-Offs and Landings in the last 90 days and displays data and notifications * as required. */ void HomeWidget::fillCurrencyTakeOffLanding() { const auto takeoff_landings = AStat::countTakeOffLanding(); if(takeoff_landings.isEmpty()) return; ui->TakeOffDisplayLabel->setText(takeoff_landings[0].toString()); if (takeoff_landings[0].toUInt() < 3) setLabelColour(ui->TakeOffDisplayLabel, Colour::Red); ui->LandingsDisplayLabel->setText(takeoff_landings[1].toString()); if (takeoff_landings[1].toUInt() < 3) setLabelColour(ui->LandingsDisplayLabel, Colour::Red); if (ASettings::read(ASettings::UserData::ShowToLgdCurrency).toBool()) { QDate expiration_date = AStat::currencyTakeOffLandingExpiry(); if (expiration_date <= QDate::currentDate()) setLabelColour(ui->currToLdgDisplayLabel, Colour::Red); ui->currToLdgDisplayLabel->setText(expiration_date.toString(Qt::TextDate)); } else { ui->currToLdgLabel->hide(); ui->currToLdgDisplayLabel->hide(); } } /*! * \brief HomeWidget::fillLimitations Queries AStat to obtain information regarding cumulative * Flight Times and Calculates and Notifies about approaching Flight Time Limitations */ void HomeWidget::fillLimitations() { int minutes = AStat::totalTime(AStat::TimeFrame::Rolling28Days); ui->FlightTime28dDisplayLabel->setText(ATime::toString(minutes)); if (minutes >= ROLLING_28_DAYS) { setLabelColour(ui->FlightTime28dDisplayLabel, Colour::Red); } else if (minutes >= ROLLING_28_DAYS * ftlWarningThreshold) { setLabelColour(ui->FlightTime28dDisplayLabel, Colour::Orange); } minutes = AStat::totalTime(AStat::TimeFrame::Rolling12Months); ui->FlightTime12mDisplayLabel->setText(ATime::toString(minutes)); if (minutes >= ROLLING_12_MONTHS) { setLabelColour(ui->FlightTime12mDisplayLabel, Colour::Red); } else if (minutes >= ROLLING_12_MONTHS * ftlWarningThreshold) { setLabelColour(ui->FlightTime12mDisplayLabel, Colour::Orange); } minutes = AStat::totalTime(AStat::TimeFrame::CalendarYear); ui->FlightTimeCalYearDisplayLabel->setText(ATime::toString(minutes)); if (minutes >= CALENDAR_YEAR) { setLabelColour(ui->FlightTimeCalYearDisplayLabel, Colour::Red); } else if (minutes >= CALENDAR_YEAR * ftlWarningThreshold) { setLabelColour(ui->FlightTimeCalYearDisplayLabel, Colour::Orange); } } const QString HomeWidget::userName() { const auto statement = QStringLiteral("SELECT firstname FROM pilots WHERE ROWID=1"); const auto name = aDB->customQuery(statement, 1); if (!name.isEmpty()) return name.first().toString(); return QString(); }