comparison src/gui/pages/anime_list.cpp @ 15:cde8f67a7c7d

*: update, megacommit :)
author Paper <mrpapersonic@gmail.com>
date Tue, 19 Sep 2023 22:36:08 -0400
parents fc1bf97c528b
children d05b1be2f3a6
comparison
equal deleted inserted replaced
14:a29c9402faf0 15:cde8f67a7c7d
14 #include "core/session.h" 14 #include "core/session.h"
15 #include "core/time.h" 15 #include "core/time.h"
16 #include "gui/dialog/information.h" 16 #include "gui/dialog/information.h"
17 #include "gui/translate/anime.h" 17 #include "gui/translate/anime.h"
18 #include "services/anilist.h" 18 #include "services/anilist.h"
19 #include <QDebug>
19 #include <QHBoxLayout> 20 #include <QHBoxLayout>
20 #include <QHeaderView> 21 #include <QHeaderView>
21 #include <QMenu> 22 #include <QMenu>
22 #include <QProgressBar> 23 #include <QProgressBar>
23 #include <QDebug>
24 #include <QShortcut> 24 #include <QShortcut>
25 #include <QStylePainter> 25 #include <QStylePainter>
26 #include <QStyledItemDelegate> 26 #include <QStyledItemDelegate>
27 #include <QAbstractItemModelTester>
28 #include <cmath> 27 #include <cmath>
29 28
30 AnimeListWidgetDelegate::AnimeListWidgetDelegate(QObject* parent) : QStyledItemDelegate(parent) { 29 AnimeListWidgetDelegate::AnimeListWidgetDelegate(QObject* parent) : QStyledItemDelegate(parent) {
31 } 30 }
32 31
34 // no edit 4 u 33 // no edit 4 u
35 return nullptr; 34 return nullptr;
36 } 35 }
37 36
38 void AnimeListWidgetDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, 37 void AnimeListWidgetDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
39 const QModelIndex& index) const { 38 const QModelIndex& index) const {
40 switch (index.column()) { 39 switch (index.column()) {
41 /* 40 #if 0
42 case AnimeListWidgetModel::AL_PROGRESS: { 41 case AnimeListWidgetModel::AL_PROGRESS: {
43 const int progress = static_cast<int>(index.data(Qt::UserRole).toReal()); 42 const int progress = static_cast<int>(index.data(Qt::UserRole).toReal());
44 const int episodes = 43 const int episodes =
45 static_cast<int>(index.siblingAtColumn(AnimeListWidgetModel::AL_EPISODES).data(Qt::UserRole).toReal()); 44 static_cast<int>(index.siblingAtColumn(AnimeListWidgetModel::AL_EPISODES).data(Qt::UserRole).toReal());
46 45
47 int text_width = 59; 46 int text_width = 59;
48 QRectF text_rect(option.rect.x() + text_width, option.rect.y(), text_width, option.decorationSize.height()); 47 QRectF text_rect(option.rect.x() + text_width, option.rect.y(), text_width, option.decorationSize.height());
49 painter->save(); 48 painter->save();
50 painter->drawText(text_rect, "/", QTextOption(Qt::AlignCenter | Qt::AlignVCenter)); 49 painter->drawText(text_rect, "/", QTextOption(Qt::AlignCenter | Qt::AlignVCenter));
51 // drawText(const QRectF &rectangle, const QString &text, const QTextOption &option = QTextOption()) 50 // drawText(const QRectF &rectangle, const QString &text, const QTextOption &option =
52 painter->drawText(QRectF(text_rect.x(), text_rect.y(), text_width / 2 - 2, text_rect.height()), 51 QTextOption()) painter->drawText(QRectF(text_rect.x(), text_rect.y(), text_width / 2 - 2,
53 QString::number(progress), QTextOption(Qt::AlignRight | Qt::AlignVCenter)); 52 text_rect.height()), QString::number(progress), QTextOption(Qt::AlignRight | Qt::AlignVCenter));
54 painter->drawText( 53 painter->drawText(
55 QRectF(text_rect.x() + text_width / 2 + 2, text_rect.y(), text_width / 2 - 2, text_rect.height()), 54 QRectF(text_rect.x() + text_width / 2 + 2, text_rect.y(), text_width / 2 - 2, text_rect.height()),
56 QString::number(episodes), QTextOption(Qt::AlignLeft | Qt::AlignVCenter)); 55 QString::number(episodes), QTextOption(Qt::AlignLeft | Qt::AlignVCenter));
57 painter->restore(); 56 painter->restore();
58 QStyledItemDelegate::paint(painter, option, index); 57 QStyledItemDelegate::paint(painter, option, index);
59 break; 58 break;
60 } 59 }
61 */ 60 #endif
62 default: QStyledItemDelegate::paint(painter, option, index); break; 61 default: QStyledItemDelegate::paint(painter, option, index); break;
63 } 62 }
64 } 63 }
65 64
66 AnimeListWidgetSortFilter::AnimeListWidgetSortFilter(QObject* parent) : QSortFilterProxyModel(parent) { 65 AnimeListWidgetSortFilter::AnimeListWidgetSortFilter(QObject* parent) : QSortFilterProxyModel(parent) {
97 } 96 }
98 97
99 QVariant AnimeListWidgetModel::headerData(const int section, const Qt::Orientation orientation, const int role) const { 98 QVariant AnimeListWidgetModel::headerData(const int section, const Qt::Orientation orientation, const int role) const {
100 if (role == Qt::DisplayRole) { 99 if (role == Qt::DisplayRole) {
101 switch (section) { 100 switch (section) {
102 case AL_TITLE: return tr("Anime title"); 101 case AL_TITLE: return tr("Anime title");
103 case AL_PROGRESS: return tr("Progress"); 102 case AL_PROGRESS: return tr("Progress");
104 case AL_EPISODES: return tr("Episodes"); 103 case AL_EPISODES: return tr("Episodes");
105 case AL_TYPE: return tr("Type"); 104 case AL_TYPE: return tr("Type");
106 case AL_SCORE: return tr("Score"); 105 case AL_SCORE: return tr("Score");
107 case AL_SEASON: return tr("Season"); 106 case AL_SEASON: return tr("Season");
108 case AL_STARTED: return tr("Date started"); 107 case AL_STARTED: return tr("Date started");
109 case AL_COMPLETED: return tr("Date completed"); 108 case AL_COMPLETED: return tr("Date completed");
110 case AL_NOTES: return tr("Notes"); 109 case AL_NOTES: return tr("Notes");
111 case AL_AVG_SCORE: return tr("Average score"); 110 case AL_AVG_SCORE: return tr("Average score");
112 case AL_UPDATED: return tr("Last updated"); 111 case AL_UPDATED: return tr("Last updated");
113 default: return {}; 112 default: return {};
114 } 113 }
115 } else if (role == Qt::TextAlignmentRole) { 114 } else if (role == Qt::TextAlignmentRole) {
116 switch (section) { 115 switch (section) {
117 case AL_TITLE: 116 case AL_TITLE:
118 case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); 117 case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
119 case AL_PROGRESS: 118 case AL_PROGRESS:
120 case AL_EPISODES: 119 case AL_EPISODES:
121 case AL_TYPE: 120 case AL_TYPE:
122 case AL_SCORE: 121 case AL_SCORE:
123 case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter); 122 case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
124 case AL_SEASON: 123 case AL_SEASON:
125 case AL_STARTED: 124 case AL_STARTED:
126 case AL_COMPLETED: 125 case AL_COMPLETED:
127 case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter); 126 case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter);
128 default: return QAbstractListModel::headerData(section, orientation, role); 127 default: return QAbstractListModel::headerData(section, orientation, role);
129 } 128 }
130 } 129 }
131 return QAbstractListModel::headerData(section, orientation, role); 130 return QAbstractListModel::headerData(section, orientation, role);
132 } 131 }
133 132
134 QVariant AnimeListWidgetModel::data(const QModelIndex& index, int role) const { 133 QVariant AnimeListWidgetModel::data(const QModelIndex& index, int role) const {
135 if (!index.isValid()) 134 if (!index.isValid())
136 return QVariant(); 135 return QVariant();
137 switch (role) { 136 switch (role) {
138 case Qt::DisplayRole: 137 case Qt::DisplayRole:
139 switch (index.column()) { 138 switch (index.column()) {
140 case AL_TITLE: return QString::fromUtf8(list[index.row()].GetUserPreferredTitle().c_str()); 139 case AL_TITLE: return QString::fromUtf8(list[index.row()].GetUserPreferredTitle().c_str());
141 case AL_PROGRESS: 140 case AL_PROGRESS:
142 return QString::number(list[index.row()].GetUserProgress()) + "/" + QString::number(list[index.row()].GetEpisodes()); 141 return QString::number(list[index.row()].GetUserProgress()) + "/" +
143 case AL_EPISODES: return list[index.row()].GetEpisodes(); 142 QString::number(list[index.row()].GetEpisodes());
144 case AL_SCORE: return list[index.row()].GetUserScore(); 143 case AL_EPISODES: return list[index.row()].GetEpisodes();
145 case AL_TYPE: return QString::fromStdString(Translate::TranslateSeriesFormat(list[index.row()].GetFormat())); 144 case AL_SCORE: return list[index.row()].GetUserScore();
146 case AL_SEASON: 145 case AL_TYPE: return QString::fromStdString(Translate::ToString(list[index.row()].GetFormat()));
147 return QString::fromStdString(Translate::TranslateSeriesSeason(list[index.row()].GetSeason())) + " " + 146 case AL_SEASON:
148 QString::number(list[index.row()].GetAirDate().GetYear()); 147 return QString::fromStdString(Translate::ToString(list[index.row()].GetSeason())) + " " +
149 case AL_AVG_SCORE: return QString::number(list[index.row()].GetAudienceScore()) + "%"; 148 QString::number(list[index.row()].GetAirDate().GetYear());
150 case AL_STARTED: return list[index.row()].GetUserDateStarted().GetAsQDate(); 149 case AL_AVG_SCORE: return QString::number(list[index.row()].GetAudienceScore()) + "%";
151 case AL_COMPLETED: return list[index.row()].GetUserDateCompleted().GetAsQDate(); 150 case AL_STARTED: return list[index.row()].GetUserDateStarted().GetAsQDate();
152 case AL_UPDATED: { 151 case AL_COMPLETED: return list[index.row()].GetUserDateCompleted().GetAsQDate();
153 if (list[index.row()].GetUserTimeUpdated() == 0) 152 case AL_UPDATED: {
154 return QString("-"); 153 if (list[index.row()].GetUserTimeUpdated() == 0)
155 Time::Duration duration(Time::GetSystemTime() - list[index.row()].GetUserTimeUpdated()); 154 return QString("-");
156 return QString::fromUtf8(duration.AsRelativeString().c_str()); 155 Time::Duration duration(Time::GetSystemTime() - list[index.row()].GetUserTimeUpdated());
157 } 156 return QString::fromUtf8(duration.AsRelativeString().c_str());
158 case AL_NOTES: return QString::fromUtf8(list[index.row()].GetUserNotes().c_str()); 157 }
159 default: return ""; 158 case AL_NOTES: return QString::fromUtf8(list[index.row()].GetUserNotes().c_str());
160 } 159 default: return "";
161 break; 160 }
161 break;
162 case Qt::UserRole: 162 case Qt::UserRole:
163 switch (index.column()) { 163 switch (index.column()) {
164 case AL_ID: return list[index.row()].GetId(); 164 case AL_PROGRESS: return list[index.row()].GetUserProgress();
165 case AL_PROGRESS: return list[index.row()].GetUserProgress(); 165 case AL_TYPE: return static_cast<int>(list[index.row()].GetFormat());
166 case AL_TYPE: return static_cast<int>(list[index.row()].GetFormat()); 166 case AL_SEASON: return list[index.row()].GetAirDate().GetAsQDate();
167 case AL_SEASON: return list[index.row()].GetAirDate().GetAsQDate(); 167 case AL_AVG_SCORE: return list[index.row()].GetAudienceScore();
168 case AL_AVG_SCORE: return list[index.row()].GetAudienceScore(); 168 case AL_UPDATED: return list[index.row()].GetUserTimeUpdated();
169 case AL_UPDATED: return list[index.row()].GetUserTimeUpdated(); 169 default: return data(index, Qt::DisplayRole);
170 default: return data(index, Qt::DisplayRole); 170 }
171 } 171 break;
172 break;
173 case Qt::TextAlignmentRole: 172 case Qt::TextAlignmentRole:
174 switch (index.column()) { 173 switch (index.column()) {
175 case AL_TITLE: 174 case AL_TITLE:
176 case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); 175 case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
177 case AL_PROGRESS: 176 case AL_PROGRESS:
178 case AL_EPISODES: 177 case AL_EPISODES:
179 case AL_TYPE: 178 case AL_TYPE:
180 case AL_SCORE: 179 case AL_SCORE:
181 case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter); 180 case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
182 case AL_SEASON: 181 case AL_SEASON:
183 case AL_STARTED: 182 case AL_STARTED:
184 case AL_COMPLETED: 183 case AL_COMPLETED:
185 case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter); 184 case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter);
186 default: break; 185 default: break;
187 } 186 }
188 break; 187 break;
189 } 188 }
190 return QVariant(); 189 return QVariant();
191 } 190 }
192 191
193 void AnimeListWidgetModel::UpdateAnime(int id) { 192 void AnimeListWidgetModel::UpdateAnime(int id) {
194 /* meh... it might be better to just reinit the entire list */ 193 /* meh... it might be better to just reinit the entire list */
195 int i = 0; 194 int i = 0;
196 for (const auto& a : Anime::db.items) { 195 for (const auto& a : Anime::db.items) {
197 if (a.second.IsInUserList() && a.first == id && a.second.GetUserStatus() == status) { 196 if (a.second.IsInUserList() && a.first == id && a.second.GetUserStatus() == status) {
198 emit dataChanged(index(i), index(i)); 197 emit dataChanged(index(i), index(i));
199 } 198 }
200 i++; 199 i++;
201 } 200 }
202 } 201 }
203 202
205 return &list.at(index.row()); 204 return &list.at(index.row());
206 } 205 }
207 206
208 void AnimeListWidgetModel::RefreshList() { 207 void AnimeListWidgetModel::RefreshList() {
209 bool has_children = !!rowCount(index(0)); 208 bool has_children = !!rowCount(index(0));
210 if (has_children) beginResetModel(); 209 if (has_children)
210 beginResetModel();
211 else {
212 int count = 0;
213 for (const auto& a : Anime::db.items)
214 if (a.second.IsInUserList() && a.second.GetUserStatus() == status)
215 count++;
216 beginInsertRows(index(0), 0, count - 1);
217 }
218
211 list.clear(); 219 list.clear();
212 220
213 for (const auto& a : Anime::db.items) { 221 for (const auto& a : Anime::db.items) {
214 if (a.second.IsInUserList() && a.second.GetUserStatus() == status) { 222 if (a.second.IsInUserList() && a.second.GetUserStatus() == status) {
215 list.push_back(a.second); 223 list.push_back(a.second);
216 } 224 }
217 } 225 }
218 if (has_children) endResetModel(); 226
227 if (has_children)
228 endResetModel();
229 else
230 endInsertRows();
219 } 231 }
220 232
221 int AnimeListWidget::VisibleColumnsCount() const { 233 int AnimeListWidget::VisibleColumnsCount() const {
222 int count = 0; 234 int count = 0;
223 235
224 for (int i = 0, end = tree_view->header()->count(); i < end; i++) { 236 for (int i = 0, end = tree_view->header()->count(); i < end; i++) {
225 if (!tree_view->isColumnHidden(i)) 237 if (!tree_view->isColumnHidden(i))
226 count++; 238 count++;
227 } 239 }
228 240
229 return count; 241 return count;
230 } 242 }
231 243
240 tree_view->setColumnHidden(AnimeListWidgetModel::AL_AVG_SCORE, true); 252 tree_view->setColumnHidden(AnimeListWidgetModel::AL_AVG_SCORE, true);
241 tree_view->setColumnHidden(AnimeListWidgetModel::AL_STARTED, true); 253 tree_view->setColumnHidden(AnimeListWidgetModel::AL_STARTED, true);
242 tree_view->setColumnHidden(AnimeListWidgetModel::AL_COMPLETED, true); 254 tree_view->setColumnHidden(AnimeListWidgetModel::AL_COMPLETED, true);
243 tree_view->setColumnHidden(AnimeListWidgetModel::AL_UPDATED, true); 255 tree_view->setColumnHidden(AnimeListWidgetModel::AL_UPDATED, true);
244 tree_view->setColumnHidden(AnimeListWidgetModel::AL_NOTES, true); 256 tree_view->setColumnHidden(AnimeListWidgetModel::AL_NOTES, true);
245 tree_view->setColumnHidden(AnimeListWidgetModel::AL_ID, true);
246 } 257 }
247 258
248 void AnimeListWidget::DisplayColumnHeaderMenu() { 259 void AnimeListWidget::DisplayColumnHeaderMenu() {
249 QMenu* menu = new QMenu(this); 260 QMenu* menu = new QMenu(this);
250 menu->setAttribute(Qt::WA_DeleteOnClose); 261 menu->setAttribute(Qt::WA_DeleteOnClose);
251 menu->setTitle(tr("Column visibility")); 262 menu->setTitle(tr("Column visibility"));
252 menu->setToolTipsVisible(true); 263 menu->setToolTipsVisible(true);
253 264
254 for (int i = 0; i < AnimeListWidgetModel::NB_COLUMNS; i++) { 265 for (int i = 0; i < AnimeListWidgetModel::NB_COLUMNS; i++) {
255 if (i == AnimeListWidgetModel::AL_TITLE || i == AnimeListWidgetModel::AL_ID) 266 if (i == AnimeListWidgetModel::AL_TITLE)
256 continue; 267 continue;
257 const auto column_name = 268 const auto column_name =
258 sort_models[tab_bar->currentIndex()]->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); 269 sort_models[tab_bar->currentIndex()]->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString();
259 QAction* action = menu->addAction(column_name, this, [this, i](const bool checked) { 270 QAction* action = menu->addAction(column_name, this, [this, i](const bool checked) {
260 if (!checked && (VisibleColumnsCount() <= 1)) 271 if (!checked && (VisibleColumnsCount() <= 1))
261 return; 272 return;
262 273
263 tree_view->setColumnHidden(i, !checked); 274 tree_view->setColumnHidden(i, !checked);
286 QMenu* menu = new QMenu(this); 297 QMenu* menu = new QMenu(this);
287 menu->setAttribute(Qt::WA_DeleteOnClose); 298 menu->setAttribute(Qt::WA_DeleteOnClose);
288 menu->setTitle(tr("Column visibility")); 299 menu->setTitle(tr("Column visibility"));
289 menu->setToolTipsVisible(true); 300 menu->setToolTipsVisible(true);
290 301
291 const QItemSelection selection = sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); 302 const QItemSelection selection =
303 sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection());
292 if (!selection.indexes().first().isValid()) { 304 if (!selection.indexes().first().isValid()) {
293 return; 305 return;
294 } 306 }
295 307
296 QAction* action = menu->addAction("Information", [this, selection] { 308 QAction* action = menu->addAction("Information", [this, selection] {
297 const QModelIndex index = ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel()) 309 const QModelIndex index = ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel())
298 ->index(selection.indexes().first().row()); 310 ->index(selection.indexes().first().row());
299 Anime::Anime* anime = 311 Anime::Anime* anime =
300 ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel())->GetAnimeFromIndex(index); 312 ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel())->GetAnimeFromIndex(index);
301 if (!anime) { 313 if (!anime) {
302 return; 314 return;
303 } 315 }
304 316
305 InformationDialog* dialog = new InformationDialog( 317 InformationDialog* dialog = new InformationDialog(
306 *anime, 318 *anime,
307 [this, anime] { 319 [this, anime] {
308 ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel())->UpdateAnime(anime->GetId()); 320 ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel())
309 }, 321 ->UpdateAnime(anime->GetId());
310 this); 322 },
323 this);
311 324
312 dialog->show(); 325 dialog->show();
313 dialog->raise(); 326 dialog->raise();
314 dialog->activateWindow(); 327 dialog->activateWindow();
315 }); 328 });
317 } 330 }
318 331
319 void AnimeListWidget::ItemDoubleClicked() { 332 void AnimeListWidget::ItemDoubleClicked() {
320 /* throw out any other garbage */ 333 /* throw out any other garbage */
321 const QItemSelection selection = 334 const QItemSelection selection =
322 sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); 335 sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection());
323 if (!selection.indexes().first().isValid()) { 336 if (!selection.indexes().first().isValid()) {
324 return; 337 return;
325 } 338 }
326 339
327 const QModelIndex index = ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel()) 340 const QModelIndex index = ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel())
328 ->index(selection.indexes().first().row()); 341 ->index(selection.indexes().first().row());
329 Anime::Anime* anime = 342 Anime::Anime* anime =
330 ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel())->GetAnimeFromIndex(index); 343 ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel())->GetAnimeFromIndex(index);
331 344
332 InformationDialog* dialog = new InformationDialog( 345 InformationDialog* dialog = new InformationDialog(
333 *anime, 346 *anime,
334 [this, anime] { 347 [this, anime] {
335 ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel())->UpdateAnime(anime->GetId()); 348 ((AnimeListWidgetModel*)sort_models[tab_bar->currentIndex()]->sourceModel())->UpdateAnime(anime->GetId());
336 }, 349 },
337 this); 350 this);
338 351
339 dialog->show(); 352 dialog->show();
340 dialog->raise(); 353 dialog->raise();
341 dialog->activateWindow(); 354 dialog->activateWindow();
342 } 355 }
422 tree_view->setRootIsDecorated(false); 435 tree_view->setRootIsDecorated(false);
423 tree_view->setContextMenuPolicy(Qt::CustomContextMenu); 436 tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
424 tree_view->setFrameShape(QFrame::NoFrame); 437 tree_view->setFrameShape(QFrame::NoFrame);
425 438
426 for (unsigned int i = 0; i < ARRAYSIZE(sort_models); i++) { 439 for (unsigned int i = 0; i < ARRAYSIZE(sort_models); i++) {
427 tab_bar->addTab(QString::fromStdString(Translate::TranslateListStatus(Anime::ListStatuses[i])) + " (" + QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")"); 440 tab_bar->addTab(QString::fromStdString(Translate::ToString(Anime::ListStatuses[i])) + " (" +
441 QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")");
428 sort_models[i] = new AnimeListWidgetSortFilter(tree_view); 442 sort_models[i] = new AnimeListWidgetSortFilter(tree_view);
429 AnimeListWidgetModel* model = new AnimeListWidgetModel(this, Anime::ListStatuses[i]); 443 sort_models[i]->setSourceModel(new AnimeListWidgetModel(this, Anime::ListStatuses[i]));
430 new QAbstractItemModelTester(model, QAbstractItemModelTester::FailureReportingMode::Fatal, this);
431 sort_models[i]->setSourceModel(model);
432 sort_models[i]->setSortRole(Qt::UserRole); 444 sort_models[i]->setSortRole(Qt::UserRole);
433 sort_models[i]->setSortCaseSensitivity(Qt::CaseInsensitive); 445 sort_models[i]->setSortCaseSensitivity(Qt::CaseInsensitive);
434 } 446 }
447 tree_view->setModel(sort_models[0]);
435 448
436 QHBoxLayout* layout = new QHBoxLayout; 449 QHBoxLayout* layout = new QHBoxLayout;
437 layout->addWidget(tree_view); 450 layout->addWidget(tree_view);
438 layout->setMargin(0); 451 layout->setMargin(0);
439 tree_widget->setLayout(layout); 452 tree_widget->setLayout(layout);
441 /* Double click stuff */ 454 /* Double click stuff */
442 connect(tree_view, &QAbstractItemView::doubleClicked, this, &AnimeListWidget::ItemDoubleClicked); 455 connect(tree_view, &QAbstractItemView::doubleClicked, this, &AnimeListWidget::ItemDoubleClicked);
443 connect(tree_view, &QWidget::customContextMenuRequested, this, &AnimeListWidget::DisplayListMenu); 456 connect(tree_view, &QWidget::customContextMenuRequested, this, &AnimeListWidget::DisplayListMenu);
444 457
445 /* Enter & return keys */ 458 /* Enter & return keys */
446 connect(new QShortcut(Qt::Key_Return, tree_view, nullptr, nullptr, Qt::WidgetShortcut), &QShortcut::activated, 459 connect(new QShortcut(Qt::Key_Return, tree_view, nullptr, nullptr, Qt::WidgetShortcut), &QShortcut::activated, this,
447 this, &AnimeListWidget::ItemDoubleClicked); 460 &AnimeListWidget::ItemDoubleClicked);
448 461
449 connect(new QShortcut(Qt::Key_Enter, tree_view, nullptr, nullptr, Qt::WidgetShortcut), &QShortcut::activated, 462 connect(new QShortcut(Qt::Key_Enter, tree_view, nullptr, nullptr, Qt::WidgetShortcut), &QShortcut::activated, this,
450 this, &AnimeListWidget::ItemDoubleClicked); 463 &AnimeListWidget::ItemDoubleClicked);
451 464
452 tree_view->header()->setStretchLastSection(false); 465 tree_view->header()->setStretchLastSection(false);
453 tree_view->header()->setContextMenuPolicy(Qt::CustomContextMenu); 466 tree_view->header()->setContextMenuPolicy(Qt::CustomContextMenu);
454 connect(tree_view->header(), &QWidget::customContextMenuRequested, this, 467 connect(tree_view->header(), &QWidget::customContextMenuRequested, this, &AnimeListWidget::DisplayColumnHeaderMenu);
455 &AnimeListWidget::DisplayColumnHeaderMenu);
456 468
457 connect(tab_bar, &QTabBar::currentChanged, this, [this](int index) { 469 connect(tab_bar, &QTabBar::currentChanged, this, [this](int index) {
458 if (sort_models[index]) 470 if (sort_models[index])
459 tree_view->setModel(sort_models[index]); 471 tree_view->setModel(sort_models[index]);
460 }); 472 });
462 setFocusPolicy(Qt::TabFocus); 474 setFocusPolicy(Qt::TabFocus);
463 setFocusProxy(tab_bar); 475 setFocusProxy(tab_bar);
464 } 476 }
465 477
466 void AnimeListWidget::RefreshList() { 478 void AnimeListWidget::RefreshList() {
467 for (unsigned int i = 0; i < ARRAYSIZE(sort_models); i++) { 479 for (unsigned int i = 0; i < ARRAYSIZE(sort_models); i++)
468 ((AnimeListWidgetModel*)sort_models[i]->sourceModel())->RefreshList(); 480 ((AnimeListWidgetModel*)sort_models[i]->sourceModel())->RefreshList();
469 } 481 }
470 } 482
471 483 void AnimeListWidget::RefreshTabs() {
484 for (unsigned int i = 0; i < ARRAYSIZE(sort_models); i++)
485 tab_bar->setTabText(i, QString::fromStdString(Translate::ToString(Anime::ListStatuses[i])) + " (" +
486 QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")");
487 }
488
489 void AnimeListWidget::Refresh() {
490 RefreshList();
491 RefreshTabs();
492 }
493
494 /* This function, really, really should not be called.
495 Ever. Why would you ever need to clear the anime list?
496 Also, this sucks. */
472 void AnimeListWidget::Reset() { 497 void AnimeListWidget::Reset() {
473 while (tab_bar->count()) 498 while (tab_bar->count())
474 tab_bar->removeTab(0); 499 tab_bar->removeTab(0);
475 for (unsigned int i = 0; i < ARRAYSIZE(sort_models); i++) 500 for (unsigned int i = 0; i < ARRAYSIZE(sort_models); i++)
476 delete sort_models[i]; 501 delete sort_models[i];