Mercurial > minori
comparison src/gui/pages/anime_list.cc @ 258:862d0d8619f6
*: HUUUGE changes
animia has been renamed to animone, so instead of thinking of a
health condition, you think of a beautiful flower :)
I've also edited some of the code for animone, but I have no idea
if it even works or not because I don't have a mac or windows
machine lying around. whoops!
... anyway, all of the changes divergent from Anisthesia are now
licensed under BSD. it's possible that I could even rewrite most
of the code to where I don't even have to keep the MIT license,
but that's thinking too far into the future
I've been slacking off on implementing the anime seasons page,
mostly out of laziness. I think I'd have to create another db file
specifically for the seasons
anyway, this code is being pushed *primarily* because the hard drive
it's on is failing! yay :)
| author | Paper <paper@paper.us.eu.org> |
|---|---|
| date | Mon, 01 Apr 2024 02:43:44 -0400 |
| parents | c130f47f6f48 |
| children | f31305b9f60a |
comparison
equal
deleted
inserted
replaced
| 257:699a20c57dc8 | 258:862d0d8619f6 |
|---|---|
| 23 #include <QHBoxLayout> | 23 #include <QHBoxLayout> |
| 24 #include <QHeaderView> | 24 #include <QHeaderView> |
| 25 #include <QMenu> | 25 #include <QMenu> |
| 26 #include <QProgressBar> | 26 #include <QProgressBar> |
| 27 #include <QShortcut> | 27 #include <QShortcut> |
| 28 #include <QTreeView> | |
| 29 #include <QStylePainter> | 28 #include <QStylePainter> |
| 30 #include <QStyledItemDelegate> | 29 #include <QStyledItemDelegate> |
| 31 #include <QThread> | 30 #include <QThread> |
| 31 #include <QTreeView> | |
| 32 | 32 |
| 33 #include <set> | 33 #include <set> |
| 34 | 34 |
| 35 AnimeListPageSortFilter::AnimeListPageSortFilter(QObject* parent) : QSortFilterProxyModel(parent) { | 35 AnimeListPageSortFilter::AnimeListPageSortFilter(QObject* parent) : QSortFilterProxyModel(parent) { |
| 36 } | 36 } |
| 109 case Qt::DisplayRole: | 109 case Qt::DisplayRole: |
| 110 switch (index.column()) { | 110 switch (index.column()) { |
| 111 case AL_TITLE: return Strings::ToQString(list[index.row()].GetUserPreferredTitle()); | 111 case AL_TITLE: return Strings::ToQString(list[index.row()].GetUserPreferredTitle()); |
| 112 case AL_PROGRESS: | 112 case AL_PROGRESS: |
| 113 return QString::number(list[index.row()].GetUserProgress()) + "/" + | 113 return QString::number(list[index.row()].GetUserProgress()) + "/" + |
| 114 QString::number(list[index.row()].GetEpisodes()); | 114 QString::number(list[index.row()].GetEpisodes()); |
| 115 case AL_EPISODES: return list[index.row()].GetEpisodes(); | 115 case AL_EPISODES: return list[index.row()].GetEpisodes(); |
| 116 case AL_SCORE: return Strings::ToQString(list[index.row()].GetUserPresentableScore()); | 116 case AL_SCORE: return Strings::ToQString(list[index.row()].GetUserPresentableScore()); |
| 117 case AL_TYPE: return Strings::ToQString(Translate::ToString(list[index.row()].GetFormat())); | 117 case AL_TYPE: return Strings::ToQString(Translate::ToString(list[index.row()].GetFormat())); |
| 118 case AL_SEASON: { | 118 case AL_SEASON: { |
| 119 std::optional<unsigned int> year = list[index.row()].GetAirDate().GetYear(); | 119 std::optional<unsigned int> year = list[index.row()].GetAirDate().GetYear(); |
| 120 if (!year) | 120 if (!year) |
| 121 return "Unknown Unknown"; | 121 return "Unknown Unknown"; |
| 122 return Strings::ToQString(Translate::ToLocalString(list[index.row()].GetSeason()) + " " + Strings::ToUtf8String(year.value())); | 122 return Strings::ToQString(Translate::ToLocalString(list[index.row()].GetSeason()) + " " + |
| 123 Strings::ToUtf8String(year.value())); | |
| 123 } | 124 } |
| 124 case AL_AVG_SCORE: return QString::number(list[index.row()].GetAudienceScore()) + "%"; | 125 case AL_AVG_SCORE: return QString::number(list[index.row()].GetAudienceScore()) + "%"; |
| 125 case AL_STARTED: return list[index.row()].GetUserDateStarted().GetAsQDate(); | 126 case AL_STARTED: return list[index.row()].GetUserDateStarted().GetAsQDate(); |
| 126 case AL_COMPLETED: return list[index.row()].GetUserDateCompleted().GetAsQDate(); | 127 case AL_COMPLETED: return list[index.row()].GetUserDateCompleted().GetAsQDate(); |
| 127 case AL_UPDATED: { | 128 case AL_UPDATED: { |
| 216 tree_view->setColumnHidden(AnimeListPageModel::AL_UPDATED, true); | 217 tree_view->setColumnHidden(AnimeListPageModel::AL_UPDATED, true); |
| 217 tree_view->setColumnHidden(AnimeListPageModel::AL_NOTES, true); | 218 tree_view->setColumnHidden(AnimeListPageModel::AL_NOTES, true); |
| 218 } | 219 } |
| 219 | 220 |
| 220 void AnimeListPage::UpdateAnime(int id) { | 221 void AnimeListPage::UpdateAnime(int id) { |
| 221 QThread* thread = QThread::create([this, id] { | 222 QThread* thread = QThread::create([this, id] { Services::UpdateAnimeEntry(id); }); |
| 222 Services::UpdateAnimeEntry(id); | |
| 223 }); | |
| 224 | 223 |
| 225 connect(thread, &QThread::finished, this, &AnimeListPage::Refresh); | 224 connect(thread, &QThread::finished, this, &AnimeListPage::Refresh); |
| 226 connect(thread, &QThread::finished, thread, &QThread::deleteLater); | 225 connect(thread, &QThread::finished, thread, &QThread::deleteLater); |
| 227 | 226 |
| 228 thread->start(); | 227 thread->start(); |
| 242 | 241 |
| 243 for (int i = 0; i < AnimeListPageModel::NB_COLUMNS; i++) { | 242 for (int i = 0; i < AnimeListPageModel::NB_COLUMNS; i++) { |
| 244 if (i == AnimeListPageModel::AL_TITLE) | 243 if (i == AnimeListPageModel::AL_TITLE) |
| 245 continue; | 244 continue; |
| 246 const auto column_name = | 245 const auto column_name = |
| 247 sort_models[tab_bar->currentIndex()]->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); | 246 sort_models[tab_bar->currentIndex()]->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); |
| 248 | 247 |
| 249 QAction* action = menu->addAction(column_name, this, [this, i](const bool checked) { | 248 QAction* action = menu->addAction(column_name, this, [this, i](const bool checked) { |
| 250 if (!checked && (VisibleColumnsCount() <= 1)) | 249 if (!checked && (VisibleColumnsCount() <= 1)) |
| 251 return; | 250 return; |
| 252 | 251 |
| 276 QMenu* menu = new QMenu(this); | 275 QMenu* menu = new QMenu(this); |
| 277 menu->setAttribute(Qt::WA_DeleteOnClose); | 276 menu->setAttribute(Qt::WA_DeleteOnClose); |
| 278 menu->setToolTipsVisible(true); | 277 menu->setToolTipsVisible(true); |
| 279 | 278 |
| 280 AnimeListPageModel* source_model = | 279 AnimeListPageModel* source_model = |
| 281 reinterpret_cast<AnimeListPageModel*>(sort_models[tab_bar->currentIndex()]->sourceModel()); | 280 reinterpret_cast<AnimeListPageModel*>(sort_models[tab_bar->currentIndex()]->sourceModel()); |
| 282 const QItemSelection selection = | 281 const QItemSelection selection = |
| 283 sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); | 282 sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); |
| 284 | 283 |
| 285 std::set<Anime::Anime*> animes; | 284 std::set<Anime::Anime*> animes; |
| 286 for (const auto& index : selection.indexes()) { | 285 for (const auto& index : selection.indexes()) { |
| 287 if (!index.isValid()) | 286 if (!index.isValid()) |
| 288 continue; | 287 continue; |
| 291 animes.insert(anime); | 290 animes.insert(anime); |
| 292 } | 291 } |
| 293 | 292 |
| 294 menu->addAction(tr("Information"), [this, animes] { | 293 menu->addAction(tr("Information"), [this, animes] { |
| 295 for (auto& anime : animes) { | 294 for (auto& anime : animes) { |
| 296 InformationDialog* dialog = new InformationDialog(*anime, [this, anime] { | 295 InformationDialog* dialog = new InformationDialog( |
| 297 UpdateAnime(anime->GetId()); | 296 *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); |
| 298 }, InformationDialog::PAGE_MAIN_INFO, this); | |
| 299 | 297 |
| 300 dialog->show(); | 298 dialog->show(); |
| 301 dialog->raise(); | 299 dialog->raise(); |
| 302 dialog->activateWindow(); | 300 dialog->activateWindow(); |
| 303 } | 301 } |
| 304 }); | 302 }); |
| 305 menu->addSeparator(); | 303 menu->addSeparator(); |
| 306 menu->addAction(tr("Edit"), [this, animes] { | 304 menu->addAction(tr("Edit"), [this, animes] { |
| 307 for (auto& anime : animes) { | 305 for (auto& anime : animes) { |
| 308 InformationDialog* dialog = new InformationDialog(*anime, [this, anime] { | 306 InformationDialog* dialog = new InformationDialog( |
| 309 UpdateAnime(anime->GetId()); | 307 *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MY_LIST, this); |
| 310 }, InformationDialog::PAGE_MY_LIST, this); | |
| 311 | 308 |
| 312 dialog->show(); | 309 dialog->show(); |
| 313 dialog->raise(); | 310 dialog->raise(); |
| 314 dialog->activateWindow(); | 311 dialog->activateWindow(); |
| 315 } | 312 } |
| 323 } | 320 } |
| 324 | 321 |
| 325 void AnimeListPage::ItemDoubleClicked() { | 322 void AnimeListPage::ItemDoubleClicked() { |
| 326 /* throw out any other garbage */ | 323 /* throw out any other garbage */ |
| 327 const QItemSelection selection = | 324 const QItemSelection selection = |
| 328 sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); | 325 sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); |
| 329 if (!selection.indexes().first().isValid()) { | 326 if (!selection.indexes().first().isValid()) { |
| 330 return; | 327 return; |
| 331 } | 328 } |
| 332 | 329 |
| 333 AnimeListPageModel* source_model = | 330 AnimeListPageModel* source_model = |
| 334 reinterpret_cast<AnimeListPageModel*>(sort_models[tab_bar->currentIndex()]->sourceModel()); | 331 reinterpret_cast<AnimeListPageModel*>(sort_models[tab_bar->currentIndex()]->sourceModel()); |
| 335 | 332 |
| 336 const QModelIndex index = source_model->index(selection.indexes().first().row()); | 333 const QModelIndex index = source_model->index(selection.indexes().first().row()); |
| 337 Anime::Anime* anime = source_model->GetAnimeFromIndex(index); | 334 Anime::Anime* anime = source_model->GetAnimeFromIndex(index); |
| 338 | 335 |
| 339 InformationDialog* dialog = new InformationDialog(*anime, [this, anime] { | 336 InformationDialog* dialog = new InformationDialog( |
| 340 UpdateAnime(anime->GetId()); | 337 *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); |
| 341 }, InformationDialog::PAGE_MAIN_INFO, this); | |
| 342 | 338 |
| 343 dialog->show(); | 339 dialog->show(); |
| 344 dialog->raise(); | 340 dialog->raise(); |
| 345 dialog->activateWindow(); | 341 dialog->activateWindow(); |
| 346 } | 342 } |
| 351 } | 347 } |
| 352 | 348 |
| 353 void AnimeListPage::RefreshTabs() { | 349 void AnimeListPage::RefreshTabs() { |
| 354 for (unsigned int i = 0; i < sort_models.size(); i++) | 350 for (unsigned int i = 0; i < sort_models.size(); i++) |
| 355 tab_bar->setTabText(i, Strings::ToQString(Translate::ToString(Anime::ListStatuses[i])) + " (" + | 351 tab_bar->setTabText(i, Strings::ToQString(Translate::ToString(Anime::ListStatuses[i])) + " (" + |
| 356 QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")"); | 352 QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")"); |
| 357 } | 353 } |
| 358 | 354 |
| 359 void AnimeListPage::Refresh() { | 355 void AnimeListPage::Refresh() { |
| 360 RefreshList(); | 356 RefreshList(); |
| 361 RefreshTabs(); | 357 RefreshTabs(); |
| 447 tree_view->setContextMenuPolicy(Qt::CustomContextMenu); | 443 tree_view->setContextMenuPolicy(Qt::CustomContextMenu); |
| 448 tree_view->setFrameShape(QFrame::NoFrame); | 444 tree_view->setFrameShape(QFrame::NoFrame); |
| 449 | 445 |
| 450 for (unsigned int i = 0; i < sort_models.size(); i++) { | 446 for (unsigned int i = 0; i < sort_models.size(); i++) { |
| 451 tab_bar->addTab(Strings::ToQString(Translate::ToString(Anime::ListStatuses[i])) + " (" + | 447 tab_bar->addTab(Strings::ToQString(Translate::ToString(Anime::ListStatuses[i])) + " (" + |
| 452 QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")"); | 448 QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")"); |
| 453 sort_models[i] = new AnimeListPageSortFilter(tree_view); | 449 sort_models[i] = new AnimeListPageSortFilter(tree_view); |
| 454 sort_models[i]->setSourceModel(new AnimeListPageModel(this, Anime::ListStatuses[i])); | 450 sort_models[i]->setSourceModel(new AnimeListPageModel(this, Anime::ListStatuses[i])); |
| 455 sort_models[i]->setSortRole(Qt::UserRole); | 451 sort_models[i]->setSortRole(Qt::UserRole); |
| 456 sort_models[i]->setSortCaseSensitivity(Qt::CaseInsensitive); | 452 sort_models[i]->setSortCaseSensitivity(Qt::CaseInsensitive); |
| 457 } | 453 } |
| 478 connect(tree_view, &QAbstractItemView::doubleClicked, this, &AnimeListPage::ItemDoubleClicked); | 474 connect(tree_view, &QAbstractItemView::doubleClicked, this, &AnimeListPage::ItemDoubleClicked); |
| 479 connect(tree_view, &QWidget::customContextMenuRequested, this, &AnimeListPage::DisplayListMenu); | 475 connect(tree_view, &QWidget::customContextMenuRequested, this, &AnimeListPage::DisplayListMenu); |
| 480 | 476 |
| 481 /* Enter & return keys */ | 477 /* Enter & return keys */ |
| 482 connect(new QShortcut(Qt::Key_Return, tree_view, nullptr, nullptr, Qt::WidgetShortcut), &QShortcut::activated, this, | 478 connect(new QShortcut(Qt::Key_Return, tree_view, nullptr, nullptr, Qt::WidgetShortcut), &QShortcut::activated, this, |
| 483 &AnimeListPage::ItemDoubleClicked); | 479 &AnimeListPage::ItemDoubleClicked); |
| 484 | 480 |
| 485 connect(new QShortcut(Qt::Key_Enter, tree_view, nullptr, nullptr, Qt::WidgetShortcut), &QShortcut::activated, this, | 481 connect(new QShortcut(Qt::Key_Enter, tree_view, nullptr, nullptr, Qt::WidgetShortcut), &QShortcut::activated, this, |
| 486 &AnimeListPage::ItemDoubleClicked); | 482 &AnimeListPage::ItemDoubleClicked); |
| 487 | 483 |
| 488 tree_view->header()->setStretchLastSection(false); | 484 tree_view->header()->setStretchLastSection(false); |
| 489 tree_view->header()->setContextMenuPolicy(Qt::CustomContextMenu); | 485 tree_view->header()->setContextMenuPolicy(Qt::CustomContextMenu); |
| 490 connect(tree_view->header(), &QWidget::customContextMenuRequested, this, &AnimeListPage::DisplayColumnHeaderMenu); | 486 connect(tree_view->header(), &QWidget::customContextMenuRequested, this, &AnimeListPage::DisplayColumnHeaderMenu); |
| 491 | 487 |
