Mercurial > minori
comparison 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 |
comparison
equal
deleted
inserted
replaced
249:6b2441c776dd | 250:c130f47f6f48 |
---|---|
12 #include <QTimer> | 12 #include <QTimer> |
13 #include <QVBoxLayout> | 13 #include <QVBoxLayout> |
14 #include <QWidget> | 14 #include <QWidget> |
15 | 15 |
16 #include <sstream> | 16 #include <sstream> |
17 #include <cmath> | |
18 | |
19 enum class TimeUnits { | |
20 SECONDS, | |
21 MINUTES | |
22 }; | |
17 | 23 |
18 StatisticsPage::StatisticsPage(QWidget* parent) : QFrame(parent) { | 24 StatisticsPage::StatisticsPage(QWidget* parent) : QFrame(parent) { |
19 QVBoxLayout* layout = new QVBoxLayout(this); | 25 QVBoxLayout* layout = new QVBoxLayout(this); |
20 | 26 |
21 setFrameShape(QFrame::Box); | 27 setFrameShape(QFrame::Box); |
72 | 78 |
73 void StatisticsPage::showEvent(QShowEvent*) { | 79 void StatisticsPage::showEvent(QShowEvent*) { |
74 UpdateStatistics(); | 80 UpdateStatistics(); |
75 } | 81 } |
76 | 82 |
77 /* me abusing macros :) */ | 83 /* [in] enum TimeUnits unit: |
78 static void add_time_segment(std::ostringstream& str, int x, const std::string_view& s, const std::string_view& p) { | 84 * which unit to stop on |
79 if (x > 0) | 85 * [in] int amount: |
80 str << x << ((x == 1) ? s : p); | 86 * amount of units to parse |
81 } | 87 * [in, defaults to 1.0] double unit_in_seconds: |
88 * equivalent of one of 'amount' in seconds, e.g. minutes would be 60.0 | |
89 */ | |
90 static std::string TimeToDateString(TimeUnits unit, int amount, double unit_in_seconds = 1.0) { | |
91 /* avoid calculating this twice */ | |
92 const double years_conv = (31556952.0 / unit_in_seconds); | |
93 const double months_conv = (2629746.0 / unit_in_seconds); | |
94 const double days_conv = (86400.0 / unit_in_seconds); | |
95 const double hours_conv = (3600.0 / unit_in_seconds); | |
96 const double minutes_conv = (60.0 / unit_in_seconds); | |
97 const double seconds_conv = (1.0 / unit_in_seconds); | |
82 | 98 |
83 std::string StatisticsPage::MinutesToDateString(const int minutes) { | 99 const int years = amount / years_conv; |
84 /* ew */ | 100 const int months = std::fmod(amount, years_conv) / months_conv; |
85 int years = (minutes * (1 / 525949.2F)); | 101 const int days = std::fmod(amount, months_conv) / days_conv; |
86 int months = (minutes * (1 / 43829.1F)) - (years * 12); | 102 const int hours = std::fmod(amount, days_conv) / hours_conv; |
87 int days = (minutes * (1 / 1440.0F)) - (years * 365.2425F) - (months * 30.436875F); | 103 const int minutes = std::fmod(amount, hours_conv) / minutes_conv; |
88 int hours = (minutes * (1 / 60.0F)) - (years * 8765.82F) - (months * 730.485F) - (days * 24); | 104 const int seconds = std::fmod(amount, minutes_conv) / seconds_conv; |
89 int rest_minutes = (minutes) - (years * 525949.2F) - (months * 43829.1F) - (days * 1440) - (hours * 60); | |
90 std::ostringstream return_stream; | |
91 add_time_segment(return_stream, years, " year ", " years "); | |
92 add_time_segment(return_stream, months, " month ", " months "); | |
93 add_time_segment(return_stream, days, " day ", " days "); | |
94 add_time_segment(return_stream, hours, " hour ", " hours "); | |
95 if (rest_minutes > 0 || return_stream.str().size() == 0) | |
96 return_stream << rest_minutes << ((rest_minutes == 1) ? " minute" : " minutes"); | |
97 return return_stream.str(); | |
98 } | |
99 | 105 |
100 std::string StatisticsPage::SecondsToDateString(const int sec) { | 106 const auto add_time_segment = [](std::ostringstream& str, int amount, const std::string_view& singular, const std::string_view& plural, bool always = false) { |
101 /* this is all fairly unnecessary, but works:tm: */ | 107 if (amount > 0 || always) |
102 int years = sec * (1 / 31556952.0F); | 108 str << amount << ((amount == 1) ? singular : plural); |
103 int months = sec * (1 / 2629746.0F) - (years * 12); | 109 }; |
104 int days = sec * (1 / 86400.0F) - (years * 365.2425F) - (months * 30.436875F); | 110 |
105 int hours = sec * (1 / 3600.0F) - (years * 8765.82F) - (months * 730.485F) - (days * 24); | 111 std::ostringstream string; |
106 int minutes = (sec) * (1 / 60.0F) - (years * 525949.2F) - (months * 43829.1F) - (days * 1440.0F) - (hours * 60.0F); | 112 add_time_segment(string, years, " year ", " years "); |
107 int seconds = | 113 add_time_segment(string, months, " month ", " months "); |
108 sec - (years * 31556952.0F) - (months * 2629746.0F) - (days * 86400.0F) - (hours * 3600.0F) - (minutes * 60.0F); | 114 add_time_segment(string, days, " day ", " days "); |
109 std::ostringstream return_stream; | 115 add_time_segment(string, hours, " hour ", " hours "); |
110 add_time_segment(return_stream, years, " year ", " years "); | 116 |
111 add_time_segment(return_stream, months, " month ", " months "); | 117 if (unit == TimeUnits::MINUTES) { |
112 add_time_segment(return_stream, days, " day ", " days "); | 118 add_time_segment(string, minutes, " minute", " minutes", true); |
113 add_time_segment(return_stream, hours, " hour ", " hours "); | 119 return string.str(); |
114 add_time_segment(return_stream, minutes, " minute ", " minutes "); | 120 } else { |
115 if (seconds > 0 || return_stream.str().size() == 0) | 121 add_time_segment(string, minutes, " minute ", " minutes "); |
116 return_stream << seconds << ((seconds == 1) ? " second" : " seconds"); | 122 } |
117 return return_stream.str(); | 123 |
124 add_time_segment(string, seconds, " second", " seconds", true); | |
125 return string.str(); | |
118 } | 126 } |
119 | 127 |
120 inline int GetTotalWithScore(const int score) { | 128 inline int GetTotalWithScore(const int score) { |
121 int count = 0; | 129 int count = 0; |
122 for (const auto& item : Anime::db.items) | 130 for (const auto& item : Anime::db.items) |
129 /* Anime list */ | 137 /* Anime list */ |
130 QString string = ""; | 138 QString string = ""; |
131 QTextStream ts(&string); | 139 QTextStream ts(&string); |
132 ts << Anime::db.GetTotalAnimeAmount() << '\n'; | 140 ts << Anime::db.GetTotalAnimeAmount() << '\n'; |
133 ts << Anime::db.GetTotalEpisodeAmount() << '\n'; | 141 ts << Anime::db.GetTotalEpisodeAmount() << '\n'; |
134 ts << MinutesToDateString(Anime::db.GetTotalWatchedAmount()).c_str() << '\n'; | 142 ts << Strings::ToQString(TimeToDateString(TimeUnits::MINUTES, Anime::db.GetTotalWatchedAmount(), 60.0)) << '\n'; |
135 ts << MinutesToDateString(Anime::db.GetTotalPlannedAmount()).c_str() << '\n'; | 143 ts << Strings::ToQString(TimeToDateString(TimeUnits::MINUTES, Anime::db.GetTotalPlannedAmount(), 60.0)) << '\n'; |
136 ts << Anime::db.GetAverageScore() << '\n'; | 144 ts << Anime::db.GetAverageScore() << '\n'; |
137 ts << Anime::db.GetScoreDeviation(); | 145 ts << Anime::db.GetScoreDeviation(); |
138 _anime_list->GetParagraph()->SetText(string); | 146 _anime_list->GetParagraph()->SetText(string); |
139 | 147 |
140 _score_distribution_graph->Clear(); | 148 _score_distribution_graph->Clear(); |
141 for (int i = 10; i <= 100; i += 10) | 149 for (int i = 10; i <= 100; i += 10) |
142 _score_distribution_graph->AddItem(i, GetTotalWithScore(i)); | 150 _score_distribution_graph->AddItem(i, GetTotalWithScore(i)); |
143 | 151 |
144 string = ""; | 152 string = ""; |
145 ts << Strings::ToQString(SecondsToDateString(session.uptime() / 1000)) << '\n'; | 153 ts << Strings::ToQString(TimeToDateString(TimeUnits::SECONDS, session.uptime() / 1000)) << '\n'; |
146 ts << session.GetRequests(); | 154 ts << session.GetRequests(); |
147 /* Application */ | 155 /* Application */ |
148 // UiUtils::SetPlainTextEditData(application_data, QString::number(session.uptime() / 1000)); | 156 // UiUtils::SetPlainTextEditData(application_data, QString::number(session.uptime() / 1000)); |
149 _application->GetParagraph()->SetText(string); | 157 _application->GetParagraph()->SetText(string); |
150 } | 158 } |