comparison src/gui/pages/statistics.cc @ 202:71832ffe425a

animia: re-add kvm fd source this is all being merged from my wildly out-of-date laptop. SORRY! in other news, I edited the CI file to install the wayland client as well, so the linux CI build might finally get wayland stuff.
author Paper <paper@paper.us.eu.org>
date Tue, 02 Jan 2024 06:05:06 -0500
parents 649786bae914
children 4d461ef7d424
comparison
equal deleted inserted replaced
201:8f6f8dd2eb23 202:71832ffe425a
1 #include "gui/pages/statistics.h" 1 #include "gui/pages/statistics.h"
2 #include "core/anime_db.h" 2 #include "core/anime_db.h"
3 #include "core/strings.h"
3 #include "core/session.h" 4 #include "core/session.h"
4 #include "gui/pages/anime_list.h" 5 #include "gui/pages/anime_list.h"
5 #include "gui/widgets/text.h" 6 #include "gui/widgets/text.h"
6 #include "gui/widgets/graph.h" 7 #include "gui/widgets/graph.h"
8
7 #include <QString> 9 #include <QString>
8 #include <QTextDocument> 10 #include <QTextDocument>
9 #include <QTextStream> 11 #include <QTextStream>
10 #include <QTimer> 12 #include <QTimer>
11 #include <QVBoxLayout> 13 #include <QVBoxLayout>
12 #include <QWidget> 14 #include <QWidget>
15
13 #include <sstream> 16 #include <sstream>
14 17
15 StatisticsPage::StatisticsPage(QWidget* parent) : QFrame(parent) { 18 StatisticsPage::StatisticsPage(QWidget* parent) : QFrame(parent) {
16 QVBoxLayout* layout = new QVBoxLayout(this); 19 QVBoxLayout* layout = new QVBoxLayout(this);
17 20
22 25
23 _anime_list.reset(new TextWidgets::LabelledSection( 26 _anime_list.reset(new TextWidgets::LabelledSection(
24 tr("Anime list"), 27 tr("Anime list"),
25 tr("Anime count:\nEpisode count:\nTime spent watching:\nTime to complete:\nAverage score:\nScore deviation:"), 28 tr("Anime count:\nEpisode count:\nTime spent watching:\nTime to complete:\nAverage score:\nScore deviation:"),
26 "", this)); 29 "", this));
30 layout->addWidget(_anime_list.get());
27 31
28 QWidget* score_dist_widget = new QWidget(this); 32 {
29 QVBoxLayout* score_dist_layout = new QVBoxLayout(score_dist_widget); 33 QWidget* score_dist_widget = new QWidget(this);
34 QVBoxLayout* score_dist_layout = new QVBoxLayout(score_dist_widget);
30 35
31 score_dist_layout->addWidget(new TextWidgets::Header(tr("Score distribution"), score_dist_widget)); 36 score_dist_layout->addWidget(new TextWidgets::Header(tr("Score distribution"), score_dist_widget));
32 37
33 /* I have to explain myself here: I hate this :). This makes a widget as a layer to create a margin, 38 /* Ew */
34 similar to what I do in text.cc with sections. I hate it and it should really be put into a separate 39 {
35 class, but whatever. */ 40 QWidget* score_graph_parent = new QWidget(score_dist_widget);
36 QWidget* content = new QWidget(score_dist_widget); 41 QVBoxLayout* score_parent_layout = new QVBoxLayout(score_graph_parent);
37 QVBoxLayout* content_layout = new QVBoxLayout(content);
38 _score_distribution_graph.reset(new Graph<int>(content));
39 content_layout->addWidget(_score_distribution_graph.get());
40 content_layout->setSpacing(0);
41 /* For some reason, when we set the margin to 12 on any paragraphs it
42 actually doesn't draw them 12 pixels away. It draws them ~15 pixels
43 away! I'm assuming this is just Qt's widgets being weird (they usually are)
44 and I hope it's nothing I *really* have to worry about... */
45 content_layout->setContentsMargins(15, 0, 0, 0);
46 content->setContentsMargins(0, 0, 0, 0);
47 42
48 score_dist_layout->addWidget(content); 43 _score_distribution_graph.reset(new Graph<int>(score_graph_parent));
49 score_dist_layout->setContentsMargins(0, 0, 0, 0); 44 score_parent_layout->addWidget(_score_distribution_graph.get());
45
46 score_parent_layout->setSpacing(0);
47 score_parent_layout->setContentsMargins(12, 0, 0, 0);
48
49 score_graph_parent->setContentsMargins(3, 0, 0, 0);
50
51 score_dist_layout->addWidget(score_graph_parent);
52 }
53
54 score_dist_layout->setContentsMargins(0, 0, 0, 0);
55
56 layout->addWidget(score_dist_widget);
57 }
58
50 59
51 _application.reset(new TextWidgets::LabelledSection(tr("Minori"), tr("Uptime:\nRequests made:"), "\n\n", this)); 60 _application.reset(new TextWidgets::LabelledSection(tr("Minori"), tr("Uptime:\nRequests made:"), "\n\n", this));
61 layout->addWidget(_application.get());
52 62
53 layout->addWidget(_anime_list.get());
54 layout->addWidget(score_dist_widget);
55 layout->addWidget(_application.get());
56 layout->addStretch(); 63 layout->addStretch();
57 64
58 QTimer* timer = new QTimer(this); 65 QTimer* timer = new QTimer(this);
59 connect(timer, &QTimer::timeout, this, [this] { 66 connect(timer, &QTimer::timeout, this, [this] {
60 if (isVisible()) 67 if (isVisible())
66 void StatisticsPage::showEvent(QShowEvent*) { 73 void StatisticsPage::showEvent(QShowEvent*) {
67 UpdateStatistics(); 74 UpdateStatistics();
68 } 75 }
69 76
70 /* me abusing macros :) */ 77 /* me abusing macros :) */
71 #define ADD_TIME_SEGMENT(r, x, s, p) \ 78 static void add_time_segment(std::ostringstream& str, int x, const std::string_view& s, const std::string_view& p) {
72 if (x > 0) \ 79 if (x > 0)
73 r << x << ((x == 1) ? s : p) 80 str << x << ((x == 1) ? s : p);
81 }
82
74 std::string StatisticsPage::MinutesToDateString(const int minutes) { 83 std::string StatisticsPage::MinutesToDateString(const int minutes) {
75 /* ew */ 84 /* ew */
76 int years = (minutes * (1 / 525949.2F)); 85 int years = (minutes * (1 / 525949.2F));
77 int months = (minutes * (1 / 43829.1F)) - (years * 12); 86 int months = (minutes * (1 / 43829.1F)) - (years * 12);
78 int days = (minutes * (1 / 1440.0F)) - (years * 365.2425F) - (months * 30.436875F); 87 int days = (minutes * (1 / 1440.0F)) - (years * 365.2425F) - (months * 30.436875F);
79 int hours = (minutes * (1 / 60.0F)) - (years * 8765.82F) - (months * 730.485F) - (days * 24); 88 int hours = (minutes * (1 / 60.0F)) - (years * 8765.82F) - (months * 730.485F) - (days * 24);
80 int rest_minutes = (minutes) - (years * 525949.2F) - (months * 43829.1F) - (days * 1440) - (hours * 60); 89 int rest_minutes = (minutes) - (years * 525949.2F) - (months * 43829.1F) - (days * 1440) - (hours * 60);
81 std::ostringstream return_stream; 90 std::ostringstream return_stream;
82 ADD_TIME_SEGMENT(return_stream, years, " year ", " years "); 91 add_time_segment(return_stream, years, " year ", " years ");
83 ADD_TIME_SEGMENT(return_stream, months, " month ", " months "); 92 add_time_segment(return_stream, months, " month ", " months ");
84 ADD_TIME_SEGMENT(return_stream, days, " day ", " days "); 93 add_time_segment(return_stream, days, " day ", " days ");
85 ADD_TIME_SEGMENT(return_stream, hours, " hour ", " hours "); 94 add_time_segment(return_stream, hours, " hour ", " hours ");
86 if (rest_minutes > 0 || return_stream.str().size() == 0) 95 if (rest_minutes > 0 || return_stream.str().size() == 0)
87 return_stream << rest_minutes << ((rest_minutes == 1) ? " minute" : " minutes"); 96 return_stream << rest_minutes << ((rest_minutes == 1) ? " minute" : " minutes");
88 return return_stream.str(); 97 return return_stream.str();
89 } 98 }
90 99
96 int hours = sec * (1 / 3600.0F) - (years * 8765.82F) - (months * 730.485F) - (days * 24); 105 int hours = sec * (1 / 3600.0F) - (years * 8765.82F) - (months * 730.485F) - (days * 24);
97 int minutes = (sec) * (1 / 60.0F) - (years * 525949.2F) - (months * 43829.1F) - (days * 1440.0F) - (hours * 60.0F); 106 int minutes = (sec) * (1 / 60.0F) - (years * 525949.2F) - (months * 43829.1F) - (days * 1440.0F) - (hours * 60.0F);
98 int seconds = 107 int seconds =
99 sec - (years * 31556952.0F) - (months * 2629746.0F) - (days * 86400.0F) - (hours * 3600.0F) - (minutes * 60.0F); 108 sec - (years * 31556952.0F) - (months * 2629746.0F) - (days * 86400.0F) - (hours * 3600.0F) - (minutes * 60.0F);
100 std::ostringstream return_stream; 109 std::ostringstream return_stream;
101 ADD_TIME_SEGMENT(return_stream, years, " year ", " years "); 110 add_time_segment(return_stream, years, " year ", " years ");
102 ADD_TIME_SEGMENT(return_stream, months, " month ", " months "); 111 add_time_segment(return_stream, months, " month ", " months ");
103 ADD_TIME_SEGMENT(return_stream, days, " day ", " days "); 112 add_time_segment(return_stream, days, " day ", " days ");
104 ADD_TIME_SEGMENT(return_stream, hours, " hour ", " hours "); 113 add_time_segment(return_stream, hours, " hour ", " hours ");
105 ADD_TIME_SEGMENT(return_stream, minutes, " minute ", " minutes "); 114 add_time_segment(return_stream, minutes, " minute ", " minutes ");
106 if (seconds > 0 || return_stream.str().size() == 0) 115 if (seconds > 0 || return_stream.str().size() == 0)
107 return_stream << seconds << ((seconds == 1) ? " second" : " seconds"); 116 return_stream << seconds << ((seconds == 1) ? " second" : " seconds");
108 return return_stream.str(); 117 return return_stream.str();
109 } 118 }
110 #undef ADD_TIME_SEGMENT
111 119
112 inline int GetTotalWithScore(const int score) { 120 inline int GetTotalWithScore(const int score) {
113 int count = 0; 121 int count = 0;
114 for (const auto& item : Anime::db.items) 122 for (const auto& item : Anime::db.items)
115 if (item.second.IsInUserList() && item.second.GetUserScore() == score) 123 if (item.second.IsInUserList() && item.second.GetUserScore() == score)
132 _score_distribution_graph->Clear(); 140 _score_distribution_graph->Clear();
133 for (int i = 10; i <= 100; i += 10) 141 for (int i = 10; i <= 100; i += 10)
134 _score_distribution_graph->AddItem(i, GetTotalWithScore(i)); 142 _score_distribution_graph->AddItem(i, GetTotalWithScore(i));
135 143
136 string = ""; 144 string = "";
137 ts << QString::fromUtf8(SecondsToDateString(session.uptime() / 1000).c_str()) << '\n'; 145 ts << Strings::ToQString(SecondsToDateString(session.uptime() / 1000)) << '\n';
138 ts << session.GetRequests(); 146 ts << session.GetRequests();
139 /* Application */ 147 /* Application */
140 // UiUtils::SetPlainTextEditData(application_data, QString::number(session.uptime() / 1000)); 148 // UiUtils::SetPlainTextEditData(application_data, QString::number(session.uptime() / 1000));
141 _application->GetParagraph()->SetText(string); 149 _application->GetParagraph()->SetText(string);
142 } 150 }