comparison src/gui/pages/anime_list.cpp @ 47:d8eb763e6661

information.cpp: add widgets to the list tab, and add an "optional date" widget like taiga has so users can specify whether to set the date or not
author Paper <mrpapersonic@gmail.com>
date Mon, 25 Sep 2023 00:43:38 -0400
parents d0adc4aedfc8
children 75c804f713b2
comparison
equal deleted inserted replaced
46:d0adc4aedfc8 47:d8eb763e6661
9 * like a native tabbed widget. 9 * like a native tabbed widget.
10 **/ 10 **/
11 #include "gui/pages/anime_list.h" 11 #include "gui/pages/anime_list.h"
12 #include "core/anime.h" 12 #include "core/anime.h"
13 #include "core/anime_db.h" 13 #include "core/anime_db.h"
14 #include "core/array.h"
14 #include "core/session.h" 15 #include "core/session.h"
15 #include "core/time.h" 16 #include "core/time.h"
16 #include "core/array.h"
17 #include "gui/dialog/information.h" 17 #include "gui/dialog/information.h"
18 #include "gui/translate/anime.h" 18 #include "gui/translate/anime.h"
19 #include "services/anilist.h" 19 #include "services/anilist.h"
20 #include <QDebug> 20 #include <QDebug>
21 #include <QHBoxLayout> 21 #include <QHBoxLayout>
97 } 97 }
98 98
99 QVariant AnimeListWidgetModel::headerData(const int section, const Qt::Orientation orientation, const int role) const { 99 QVariant AnimeListWidgetModel::headerData(const int section, const Qt::Orientation orientation, const int role) const {
100 if (role == Qt::DisplayRole) { 100 if (role == Qt::DisplayRole) {
101 switch (section) { 101 switch (section) {
102 case AL_TITLE: return tr("Anime title"); 102 case AL_TITLE: return tr("Anime title");
103 case AL_PROGRESS: return tr("Progress"); 103 case AL_PROGRESS: return tr("Progress");
104 case AL_EPISODES: return tr("Episodes"); 104 case AL_EPISODES: return tr("Episodes");
105 case AL_TYPE: return tr("Type"); 105 case AL_TYPE: return tr("Type");
106 case AL_SCORE: return tr("Score"); 106 case AL_SCORE: return tr("Score");
107 case AL_SEASON: return tr("Season"); 107 case AL_SEASON: return tr("Season");
108 case AL_STARTED: return tr("Date started"); 108 case AL_STARTED: return tr("Date started");
109 case AL_COMPLETED: return tr("Date completed"); 109 case AL_COMPLETED: return tr("Date completed");
110 case AL_NOTES: return tr("Notes"); 110 case AL_NOTES: return tr("Notes");
111 case AL_AVG_SCORE: return tr("Average score"); 111 case AL_AVG_SCORE: return tr("Average score");
112 case AL_UPDATED: return tr("Last updated"); 112 case AL_UPDATED: return tr("Last updated");
113 default: return {}; 113 default: return {};
114 } 114 }
115 } else if (role == Qt::TextAlignmentRole) { 115 } else if (role == Qt::TextAlignmentRole) {
116 switch (section) { 116 switch (section) {
117 case AL_TITLE: 117 case AL_TITLE:
118 case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); 118 case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
119 case AL_PROGRESS: 119 case AL_PROGRESS:
120 case AL_EPISODES: 120 case AL_EPISODES:
121 case AL_TYPE: 121 case AL_TYPE:
122 case AL_SCORE: 122 case AL_SCORE:
123 case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter); 123 case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
124 case AL_SEASON: 124 case AL_SEASON:
125 case AL_STARTED: 125 case AL_STARTED:
126 case AL_COMPLETED: 126 case AL_COMPLETED:
127 case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter); 127 case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter);
128 default: return QAbstractListModel::headerData(section, orientation, role); 128 default: return QAbstractListModel::headerData(section, orientation, role);
129 } 129 }
130 } 130 }
131 return QAbstractListModel::headerData(section, orientation, role); 131 return QAbstractListModel::headerData(section, orientation, role);
132 } 132 }
133 133
134 QVariant AnimeListWidgetModel::data(const QModelIndex& index, int role) const { 134 QVariant AnimeListWidgetModel::data(const QModelIndex& index, int role) const {
135 if (!index.isValid()) 135 if (!index.isValid())
136 return QVariant(); 136 return QVariant();
137 switch (role) { 137 switch (role) {
138 case Qt::DisplayRole: 138 case Qt::DisplayRole:
139 switch (index.column()) { 139 switch (index.column()) {
140 case AL_TITLE: return QString::fromUtf8(list[index.row()].GetUserPreferredTitle().c_str()); 140 case AL_TITLE: return QString::fromUtf8(list[index.row()].GetUserPreferredTitle().c_str());
141 case AL_PROGRESS: 141 case AL_PROGRESS:
142 return QString::number(list[index.row()].GetUserProgress()) + "/" + 142 return QString::number(list[index.row()].GetUserProgress()) + "/" +
143 QString::number(list[index.row()].GetEpisodes()); 143 QString::number(list[index.row()].GetEpisodes());
144 case AL_EPISODES: return list[index.row()].GetEpisodes(); 144 case AL_EPISODES: return list[index.row()].GetEpisodes();
145 case AL_SCORE: return list[index.row()].GetUserScore(); 145 case AL_SCORE: return list[index.row()].GetUserScore();
146 case AL_TYPE: return QString::fromStdString(Translate::ToString(list[index.row()].GetFormat())); 146 case AL_TYPE: return QString::fromStdString(Translate::ToString(list[index.row()].GetFormat()));
147 case AL_SEASON: 147 case AL_SEASON:
148 return QString::fromStdString(Translate::ToString(list[index.row()].GetSeason())) + " " + 148 return QString::fromStdString(Translate::ToString(list[index.row()].GetSeason())) + " " +
149 QString::number(list[index.row()].GetAirDate().GetYear()); 149 QString::number(list[index.row()].GetAirDate().GetYear());
150 case AL_AVG_SCORE: return QString::number(list[index.row()].GetAudienceScore()) + "%"; 150 case AL_AVG_SCORE: return QString::number(list[index.row()].GetAudienceScore()) + "%";
151 case AL_STARTED: return list[index.row()].GetUserDateStarted().GetAsQDate(); 151 case AL_STARTED: return list[index.row()].GetUserDateStarted().GetAsQDate();
152 case AL_COMPLETED: return list[index.row()].GetUserDateCompleted().GetAsQDate(); 152 case AL_COMPLETED: return list[index.row()].GetUserDateCompleted().GetAsQDate();
153 case AL_UPDATED: { 153 case AL_UPDATED: {
154 if (list[index.row()].GetUserTimeUpdated() == 0) 154 if (list[index.row()].GetUserTimeUpdated() == 0)
155 return QString("-"); 155 return QString("-");
156 Time::Duration duration(Time::GetSystemTime() - list[index.row()].GetUserTimeUpdated()); 156 Time::Duration duration(Time::GetSystemTime() - list[index.row()].GetUserTimeUpdated());
157 return QString::fromUtf8(duration.AsRelativeString().c_str()); 157 return QString::fromUtf8(duration.AsRelativeString().c_str());
158 } 158 }
159 case AL_NOTES: return QString::fromUtf8(list[index.row()].GetUserNotes().c_str()); 159 case AL_NOTES: return QString::fromUtf8(list[index.row()].GetUserNotes().c_str());
160 default: return ""; 160 default: return "";
161 } 161 }
162 break; 162 break;
163 case Qt::UserRole: 163 case Qt::UserRole:
164 switch (index.column()) { 164 switch (index.column()) {
165 case AL_PROGRESS: return list[index.row()].GetUserProgress(); 165 case AL_PROGRESS: return list[index.row()].GetUserProgress();
166 case AL_TYPE: return static_cast<int>(list[index.row()].GetFormat()); 166 case AL_TYPE: return static_cast<int>(list[index.row()].GetFormat());
167 case AL_SEASON: return list[index.row()].GetAirDate().GetAsQDate(); 167 case AL_SEASON: return list[index.row()].GetAirDate().GetAsQDate();
168 case AL_AVG_SCORE: return list[index.row()].GetAudienceScore(); 168 case AL_AVG_SCORE: return list[index.row()].GetAudienceScore();
169 case AL_UPDATED: return QVariant::fromValue(list[index.row()].GetUserTimeUpdated()); 169 case AL_UPDATED: return QVariant::fromValue(list[index.row()].GetUserTimeUpdated());
170 default: return data(index, Qt::DisplayRole); 170 default: return data(index, Qt::DisplayRole);
171 } 171 }
172 break; 172 break;
173 case Qt::TextAlignmentRole: 173 case Qt::TextAlignmentRole:
174 switch (index.column()) { 174 switch (index.column()) {
175 case AL_TITLE: 175 case AL_TITLE:
176 case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); 176 case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
177 case AL_PROGRESS: 177 case AL_PROGRESS:
178 case AL_EPISODES: 178 case AL_EPISODES:
179 case AL_TYPE: 179 case AL_TYPE:
180 case AL_SCORE: 180 case AL_SCORE:
181 case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter); 181 case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
182 case AL_SEASON: 182 case AL_SEASON:
183 case AL_STARTED: 183 case AL_STARTED:
184 case AL_COMPLETED: 184 case AL_COMPLETED:
185 case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter); 185 case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter);
186 default: break; 186 default: break;
187 } 187 }
188 break; 188 break;
189 } 189 }
190 return QVariant(); 190 return QVariant();
191 } 191 }
192 192
193 void AnimeListWidgetModel::UpdateAnime(int id) { 193 void AnimeListWidgetModel::UpdateAnime(int id) {
194 /* meh... it might be better to just reinit the entire list */ 194 /* meh... it might be better to just reinit the entire list */
195 int i = 0; 195 int i = 0;
196 for (const auto& a : Anime::db.items) { 196 for (const auto& a : Anime::db.items) {
197 if (a.second.IsInUserList() && a.first == id && a.second.GetUserStatus() == status) { 197 if (a.second.IsInUserList() && a.first == id && a.second.GetUserStatus() == status) {
198 emit dataChanged(index(i), index(i)); 198 emit dataChanged(index(i), index(i));
199 } 199 }
200 i++; 200 i++;
201 } 201 }
202 } 202 }
203 203
210 if (has_children) 210 if (has_children)
211 beginResetModel(); 211 beginResetModel();
212 else { 212 else {
213 int count = 0; 213 int count = 0;
214 for (const auto& a : Anime::db.items) 214 for (const auto& a : Anime::db.items)
215 if (a.second.IsInUserList() && a.second.GetUserStatus() == status) 215 if (a.second.IsInUserList() && a.second.GetUserStatus() == status)
216 count++; 216 count++;
217 beginInsertRows(index(0), 0, count - 1); 217 beginInsertRows(index(0), 0, count - 1);
218 } 218 }
219 219
220 list.clear(); 220 list.clear();
221 221
222 for (const auto& a : Anime::db.items) { 222 for (const auto& a : Anime::db.items) {
223 if (a.second.IsInUserList() && a.second.GetUserStatus() == status) { 223 if (a.second.IsInUserList() && a.second.GetUserStatus() == status) {
224 list.push_back(a.second); 224 list.push_back(a.second);
225 } 225 }
226 } 226 }
227 227
228 if (has_children) 228 if (has_children)
229 endResetModel(); 229 endResetModel();
234 int AnimeListWidget::VisibleColumnsCount() const { 234 int AnimeListWidget::VisibleColumnsCount() const {
235 int count = 0; 235 int count = 0;
236 236
237 for (int i = 0, end = tree_view->header()->count(); i < end; i++) { 237 for (int i = 0, end = tree_view->header()->count(); i < end; i++) {
238 if (!tree_view->isColumnHidden(i)) 238 if (!tree_view->isColumnHidden(i))
239 count++; 239 count++;
240 } 240 }
241 241
242 return count; 242 return count;
243 } 243 }
244 244
263 menu->setTitle(tr("Column visibility")); 263 menu->setTitle(tr("Column visibility"));
264 menu->setToolTipsVisible(true); 264 menu->setToolTipsVisible(true);
265 265
266 for (int i = 0; i < AnimeListWidgetModel::NB_COLUMNS; i++) { 266 for (int i = 0; i < AnimeListWidgetModel::NB_COLUMNS; i++) {
267 if (i == AnimeListWidgetModel::AL_TITLE) 267 if (i == AnimeListWidgetModel::AL_TITLE)
268 continue; 268 continue;
269 const auto column_name = 269 const auto column_name =
270 sort_models[tab_bar->currentIndex()]->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); 270 sort_models[tab_bar->currentIndex()]->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString();
271 QAction* action = menu->addAction(column_name, this, [this, i](const bool checked) { 271 QAction* action = menu->addAction(column_name, this, [this, i](const bool checked) {
272 if (!checked && (VisibleColumnsCount() <= 1)) 272 if (!checked && (VisibleColumnsCount() <= 1))
273 return; 273 return;