Mercurial > minori
diff src/gui/pages/statistics.cc @ 250:c130f47f6f48
*: many many changes
e.g. the search page is actually implemented now!
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Sun, 04 Feb 2024 21:17:17 -0500 |
parents | 4d461ef7d424 |
children | d14f8e0e40c3 |
line wrap: on
line diff
--- a/src/gui/pages/statistics.cc Wed Jan 24 20:18:59 2024 -0500 +++ b/src/gui/pages/statistics.cc Sun Feb 04 21:17:17 2024 -0500 @@ -14,6 +14,12 @@ #include <QWidget> #include <sstream> +#include <cmath> + +enum class TimeUnits { + SECONDS, + MINUTES +}; StatisticsPage::StatisticsPage(QWidget* parent) : QFrame(parent) { QVBoxLayout* layout = new QVBoxLayout(this); @@ -74,47 +80,49 @@ UpdateStatistics(); } -/* me abusing macros :) */ -static void add_time_segment(std::ostringstream& str, int x, const std::string_view& s, const std::string_view& p) { - if (x > 0) - str << x << ((x == 1) ? s : p); -} +/* [in] enum TimeUnits unit: + * which unit to stop on + * [in] int amount: + * amount of units to parse + * [in, defaults to 1.0] double unit_in_seconds: + * equivalent of one of 'amount' in seconds, e.g. minutes would be 60.0 +*/ +static std::string TimeToDateString(TimeUnits unit, int amount, double unit_in_seconds = 1.0) { + /* avoid calculating this twice */ + const double years_conv = (31556952.0 / unit_in_seconds); + const double months_conv = (2629746.0 / unit_in_seconds); + const double days_conv = (86400.0 / unit_in_seconds); + const double hours_conv = (3600.0 / unit_in_seconds); + const double minutes_conv = (60.0 / unit_in_seconds); + const double seconds_conv = (1.0 / unit_in_seconds); -std::string StatisticsPage::MinutesToDateString(const int minutes) { - /* ew */ - int years = (minutes * (1 / 525949.2F)); - int months = (minutes * (1 / 43829.1F)) - (years * 12); - int days = (minutes * (1 / 1440.0F)) - (years * 365.2425F) - (months * 30.436875F); - int hours = (minutes * (1 / 60.0F)) - (years * 8765.82F) - (months * 730.485F) - (days * 24); - int rest_minutes = (minutes) - (years * 525949.2F) - (months * 43829.1F) - (days * 1440) - (hours * 60); - std::ostringstream return_stream; - add_time_segment(return_stream, years, " year ", " years "); - add_time_segment(return_stream, months, " month ", " months "); - add_time_segment(return_stream, days, " day ", " days "); - add_time_segment(return_stream, hours, " hour ", " hours "); - if (rest_minutes > 0 || return_stream.str().size() == 0) - return_stream << rest_minutes << ((rest_minutes == 1) ? " minute" : " minutes"); - return return_stream.str(); -} + const int years = amount / years_conv; + const int months = std::fmod(amount, years_conv) / months_conv; + const int days = std::fmod(amount, months_conv) / days_conv; + const int hours = std::fmod(amount, days_conv) / hours_conv; + const int minutes = std::fmod(amount, hours_conv) / minutes_conv; + const int seconds = std::fmod(amount, minutes_conv) / seconds_conv; + + const auto add_time_segment = [](std::ostringstream& str, int amount, const std::string_view& singular, const std::string_view& plural, bool always = false) { + if (amount > 0 || always) + str << amount << ((amount == 1) ? singular : plural); + }; -std::string StatisticsPage::SecondsToDateString(const int sec) { - /* this is all fairly unnecessary, but works:tm: */ - int years = sec * (1 / 31556952.0F); - int months = sec * (1 / 2629746.0F) - (years * 12); - int days = sec * (1 / 86400.0F) - (years * 365.2425F) - (months * 30.436875F); - int hours = sec * (1 / 3600.0F) - (years * 8765.82F) - (months * 730.485F) - (days * 24); - int minutes = (sec) * (1 / 60.0F) - (years * 525949.2F) - (months * 43829.1F) - (days * 1440.0F) - (hours * 60.0F); - int seconds = - sec - (years * 31556952.0F) - (months * 2629746.0F) - (days * 86400.0F) - (hours * 3600.0F) - (minutes * 60.0F); - std::ostringstream return_stream; - add_time_segment(return_stream, years, " year ", " years "); - add_time_segment(return_stream, months, " month ", " months "); - add_time_segment(return_stream, days, " day ", " days "); - add_time_segment(return_stream, hours, " hour ", " hours "); - add_time_segment(return_stream, minutes, " minute ", " minutes "); - if (seconds > 0 || return_stream.str().size() == 0) - return_stream << seconds << ((seconds == 1) ? " second" : " seconds"); - return return_stream.str(); + std::ostringstream string; + add_time_segment(string, years, " year ", " years "); + add_time_segment(string, months, " month ", " months "); + add_time_segment(string, days, " day ", " days "); + add_time_segment(string, hours, " hour ", " hours "); + + if (unit == TimeUnits::MINUTES) { + add_time_segment(string, minutes, " minute", " minutes", true); + return string.str(); + } else { + add_time_segment(string, minutes, " minute ", " minutes "); + } + + add_time_segment(string, seconds, " second", " seconds", true); + return string.str(); } inline int GetTotalWithScore(const int score) { @@ -131,8 +139,8 @@ QTextStream ts(&string); ts << Anime::db.GetTotalAnimeAmount() << '\n'; ts << Anime::db.GetTotalEpisodeAmount() << '\n'; - ts << MinutesToDateString(Anime::db.GetTotalWatchedAmount()).c_str() << '\n'; - ts << MinutesToDateString(Anime::db.GetTotalPlannedAmount()).c_str() << '\n'; + ts << Strings::ToQString(TimeToDateString(TimeUnits::MINUTES, Anime::db.GetTotalWatchedAmount(), 60.0)) << '\n'; + ts << Strings::ToQString(TimeToDateString(TimeUnits::MINUTES, Anime::db.GetTotalPlannedAmount(), 60.0)) << '\n'; ts << Anime::db.GetAverageScore() << '\n'; ts << Anime::db.GetScoreDeviation(); _anime_list->GetParagraph()->SetText(string); @@ -142,7 +150,7 @@ _score_distribution_graph->AddItem(i, GetTotalWithScore(i)); string = ""; - ts << Strings::ToQString(SecondsToDateString(session.uptime() / 1000)) << '\n'; + ts << Strings::ToQString(TimeToDateString(TimeUnits::SECONDS, session.uptime() / 1000)) << '\n'; ts << session.GetRequests(); /* Application */ // UiUtils::SetPlainTextEditData(application_data, QString::number(session.uptime() / 1000));