comparison src/gui/pages/search.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
1 #include "gui/pages/search.h" 1 #include "gui/pages/search.h"
2 #include "core/anime.h" 2 #include "core/anime.h"
3 #include "core/anime_db.h" 3 #include "core/anime_db.h"
4 #include "core/strings.h" 4 #include "core/filesystem.h"
5 #include "core/http.h" 5 #include "core/http.h"
6 #include "core/session.h" 6 #include "core/session.h"
7 #include "core/filesystem.h" 7 #include "core/strings.h"
8 #include "gui/dialog/information.h"
9 #include "gui/translate/anime.h"
8 #include "gui/widgets/text.h" 10 #include "gui/widgets/text.h"
9 #include "gui/dialog/information.h" 11 #include "services/services.h"
10 #include "track/media.h" 12 #include "track/media.h"
11 #include "gui/translate/anime.h" 13
12 #include "services/services.h" 14 #include <QDate>
13
14 #include <QHeaderView> 15 #include <QHeaderView>
15 #include <QVBoxLayout> 16 #include <QMenu>
16 #include <QToolBar> 17 #include <QToolBar>
17 #include <QTreeView> 18 #include <QTreeView>
18 #include <QDate> 19 #include <QVBoxLayout>
19 #include <QMenu> 20
20 21 #include <algorithm>
22 #include <fstream>
21 #include <iostream> 23 #include <iostream>
22 #include <sstream> 24 #include <sstream>
23 #include <fstream> 25
24 #include <algorithm> 26 #include "anitomy/anitomy.h"
25
26 #include "pugixml.hpp" 27 #include "pugixml.hpp"
27 #include "anitomy/anitomy.h"
28 28
29 SearchPageListSortFilter::SearchPageListSortFilter(QObject* parent) : QSortFilterProxyModel(parent) { 29 SearchPageListSortFilter::SearchPageListSortFilter(QObject* parent) : QSortFilterProxyModel(parent) {
30 } 30 }
31 31
32 bool SearchPageListSortFilter::lessThan(const QModelIndex& l, const QModelIndex& r) const { 32 bool SearchPageListSortFilter::lessThan(const QModelIndex& l, const QModelIndex& r) const {
35 35
36 switch (left.userType()) { 36 switch (left.userType()) {
37 case QMetaType::Int: 37 case QMetaType::Int:
38 case QMetaType::UInt: 38 case QMetaType::UInt:
39 case QMetaType::LongLong: 39 case QMetaType::LongLong:
40 case QMetaType::ULongLong: 40 case QMetaType::ULongLong: return left.toInt() < right.toInt();
41 return left.toInt() < right.toInt(); 41 case QMetaType::QDate: return left.toDate() < right.toDate();
42 case QMetaType::QDate:
43 return left.toDate() < right.toDate();
44 case QMetaType::QString: 42 case QMetaType::QString:
45 default: // meh 43 default: // meh
46 return QString::compare(left.toString(), right.toString(), Qt::CaseInsensitive) < 0; 44 return QString::compare(left.toString(), right.toString(), Qt::CaseInsensitive) < 0;
47 } 45 }
48 } 46 }
115 switch (index.column()) { 113 switch (index.column()) {
116 case SR_TITLE: return Strings::ToQString(anime.GetUserPreferredTitle()); 114 case SR_TITLE: return Strings::ToQString(anime.GetUserPreferredTitle());
117 case SR_TYPE: return Strings::ToQString(Translate::ToLocalString(anime.GetFormat())); 115 case SR_TYPE: return Strings::ToQString(Translate::ToLocalString(anime.GetFormat()));
118 case SR_EPISODES: return anime.GetEpisodes(); 116 case SR_EPISODES: return anime.GetEpisodes();
119 case SR_SCORE: return QString::number(anime.GetAudienceScore()) + "%"; 117 case SR_SCORE: return QString::number(anime.GetAudienceScore()) + "%";
120 case SR_SEASON: return Strings::ToQString(Translate::ToLocalString(anime.GetSeason())) + " " + QString::number(anime.GetAirDate().GetYear().value_or(2000)); 118 case SR_SEASON:
119 return Strings::ToQString(Translate::ToLocalString(anime.GetSeason())) + " " +
120 QString::number(anime.GetAirDate().GetYear().value_or(2000));
121 default: return {}; 121 default: return {};
122 } 122 }
123 break; 123 break;
124 case Qt::UserRole: 124 case Qt::UserRole:
125 switch (index.column()) { 125 switch (index.column()) {
126 case SR_SCORE: return anime.GetAudienceScore(); 126 case SR_SCORE: return anime.GetAudienceScore();
127 case SR_EPISODES: return anime.GetEpisodes(); 127 case SR_EPISODES: return anime.GetEpisodes();
128 case SR_SEASON: return anime.GetAirDate().GetAsQDate(); 128 case SR_SEASON: return anime.GetAirDate().GetAsQDate();
129 /* We have to use this to work around some stupid 129 /* We have to use this to work around some stupid
130 * "conversion ambiguous" error on Linux 130 * "conversion ambiguous" error on Linux
131 */ 131 */
132 default: return data(index, Qt::DisplayRole); 132 default: return data(index, Qt::DisplayRole);
133 } 133 }
134 break; 134 break;
135 case Qt::SizeHintRole: { 135 case Qt::SizeHintRole: {
136 switch (index.column()) { 136 switch (index.column()) {
142 return QSize(std::max(metric.horizontalAdvance(d), 100), metric.height()); 142 return QSize(std::max(metric.horizontalAdvance(d), 100), metric.height());
143 } 143 }
144 } 144 }
145 break; 145 break;
146 } 146 }
147 case Qt::TextAlignmentRole: 147 case Qt::TextAlignmentRole: return headerData(index.column(), Qt::Horizontal, Qt::TextAlignmentRole);
148 return headerData(index.column(), Qt::Horizontal, Qt::TextAlignmentRole);
149 } 148 }
150 return QVariant(); 149 return QVariant();
151 } 150 }
152 151
153 Qt::ItemFlags SearchPageListModel::flags(const QModelIndex& index) const { 152 Qt::ItemFlags SearchPageListModel::flags(const QModelIndex& index) const {
183 } 182 }
184 } 183 }
185 184
186 menu->addAction(tr("Information"), [this, animes] { 185 menu->addAction(tr("Information"), [this, animes] {
187 for (auto& anime : animes) { 186 for (auto& anime : animes) {
188 InformationDialog* dialog = new InformationDialog(*anime, [this, anime] { 187 InformationDialog* dialog = new InformationDialog(
189 //UpdateAnime(anime->GetId()); 188 *anime,
190 }, InformationDialog::PAGE_MAIN_INFO, this); 189 [this, anime] {
190 // UpdateAnime(anime->GetId());
191 },
192 InformationDialog::PAGE_MAIN_INFO, this);
191 193
192 dialog->show(); 194 dialog->show();
193 dialog->raise(); 195 dialog->raise();
194 dialog->activateWindow(); 196 dialog->activateWindow();
195 } 197 }
196 }); 198 });
197 menu->addSeparator(); 199 menu->addSeparator();
198 { 200 {
199 QMenu* submenu = menu->addMenu(tr("Add to list...")); 201 QMenu* submenu = menu->addMenu(tr("Add to list..."));
200 submenu->addAction(tr("Currently watching"), [animes]{ 202 submenu->addAction(tr("Currently watching"), [animes] {
201 for (auto& anime : animes) { 203 for (auto& anime : animes) {
202 if (!anime->IsInUserList()) 204 if (!anime->IsInUserList())
203 anime->AddToUserList(); 205 anime->AddToUserList();
204 anime->SetUserStatus(Anime::ListStatus::CURRENT); 206 anime->SetUserStatus(Anime::ListStatus::CURRENT);
205 Services::UpdateAnimeEntry(anime->GetId()); 207 Services::UpdateAnimeEntry(anime->GetId());
206 } 208 }
207 }); 209 });
208 submenu->addAction(tr("Completed"), [animes]{ 210 submenu->addAction(tr("Completed"), [animes] {
209 for (auto& anime : animes) { 211 for (auto& anime : animes) {
210 if (!anime->IsInUserList()) 212 if (!anime->IsInUserList())
211 anime->AddToUserList(); 213 anime->AddToUserList();
212 anime->SetUserStatus(Anime::ListStatus::COMPLETED); 214 anime->SetUserStatus(Anime::ListStatus::COMPLETED);
213 Services::UpdateAnimeEntry(anime->GetId()); 215 Services::UpdateAnimeEntry(anime->GetId());
214 } 216 }
215 }); 217 });
216 submenu->addAction(tr("On hold"), [animes]{ 218 submenu->addAction(tr("On hold"), [animes] {
217 for (auto& anime : animes) { 219 for (auto& anime : animes) {
218 if (!anime->IsInUserList()) 220 if (!anime->IsInUserList())
219 anime->AddToUserList(); 221 anime->AddToUserList();
220 anime->SetUserStatus(Anime::ListStatus::PAUSED); 222 anime->SetUserStatus(Anime::ListStatus::PAUSED);
221 Services::UpdateAnimeEntry(anime->GetId()); 223 Services::UpdateAnimeEntry(anime->GetId());
222 } 224 }
223 }); 225 });
224 submenu->addAction(tr("Dropped"), [animes]{ 226 submenu->addAction(tr("Dropped"), [animes] {
225 for (auto& anime : animes) { 227 for (auto& anime : animes) {
226 if (!anime->IsInUserList()) 228 if (!anime->IsInUserList())
227 anime->AddToUserList(); 229 anime->AddToUserList();
228 anime->SetUserStatus(Anime::ListStatus::DROPPED); 230 anime->SetUserStatus(Anime::ListStatus::DROPPED);
229 Services::UpdateAnimeEntry(anime->GetId()); 231 Services::UpdateAnimeEntry(anime->GetId());
230 } 232 }
231 }); 233 });
232 submenu->addAction(tr("Plan to watch"), [animes]{ 234 submenu->addAction(tr("Plan to watch"), [animes] {
233 for (auto& anime : animes) { 235 for (auto& anime : animes) {
234 if (!anime->IsInUserList()) 236 if (!anime->IsInUserList())
235 anime->AddToUserList(); 237 anime->AddToUserList();
236 anime->SetUserStatus(Anime::ListStatus::PLANNING); 238 anime->SetUserStatus(Anime::ListStatus::PLANNING);
237 Services::UpdateAnimeEntry(anime->GetId()); 239 Services::UpdateAnimeEntry(anime->GetId());
249 return; 251 return;
250 252
251 const QModelIndex index = model->index(selection.indexes().first().row()); 253 const QModelIndex index = model->index(selection.indexes().first().row());
252 Anime::Anime* anime = model->GetAnimeFromIndex(index); 254 Anime::Anime* anime = model->GetAnimeFromIndex(index);
253 255
254 InformationDialog* dialog = new InformationDialog(*anime, [this, anime] { 256 InformationDialog* dialog = new InformationDialog(
255 //UpdateAnime(anime->GetId()); 257 *anime,
256 }, InformationDialog::PAGE_MAIN_INFO, this); 258 [this, anime] {
259 // UpdateAnime(anime->GetId());
260 },
261 InformationDialog::PAGE_MAIN_INFO, this);
257 262
258 dialog->show(); 263 dialog->show();
259 dialog->raise(); 264 dialog->raise();
260 dialog->activateWindow(); 265 dialog->activateWindow();
261 } 266 }
273 QToolBar* toolbar = new QToolBar(this); 278 QToolBar* toolbar = new QToolBar(this);
274 toolbar->setMovable(false); 279 toolbar->setMovable(false);
275 280
276 { 281 {
277 QLineEdit* line_edit = new QLineEdit("", toolbar); 282 QLineEdit* line_edit = new QLineEdit("", toolbar);
278 connect(line_edit, &QLineEdit::returnPressed, this, [this, line_edit]{ 283 connect(line_edit, &QLineEdit::returnPressed, this, [this, line_edit] {
279 /* static thread here. */ 284 /* static thread here. */
280 static QThread* thread = nullptr; 285 static QThread* thread = nullptr;
281 286
282 if (thread) 287 if (thread)
283 return; 288 return;
284 289
285 thread = QThread::create([this, line_edit]{ 290 thread = QThread::create([this, line_edit] {
286 model->ParseSearch(Services::Search(Strings::ToUtf8String(line_edit->text()))); 291 model->ParseSearch(Services::Search(Strings::ToUtf8String(line_edit->text())));
287 }); 292 });
288 293
289 connect(thread, &QThread::finished, this, []{ 294 connect(thread, &QThread::finished, this, [] {
290 thread->deleteLater(); 295 thread->deleteLater();
291 thread = nullptr; 296 thread = nullptr;
292 }); 297 });
293 298
294 thread->start(); 299 thread->start();
327 sort_model->setSortCaseSensitivity(Qt::CaseInsensitive); 332 sort_model->setSortCaseSensitivity(Qt::CaseInsensitive);
328 treeview->setModel(sort_model); 333 treeview->setModel(sort_model);
329 } 334 }
330 335
331 // set column sizes 336 // set column sizes
332 treeview->setColumnWidth(SearchPageListModel::SR_TITLE, 400); 337 treeview->setColumnWidth(SearchPageListModel::SR_TITLE, 400);
333 treeview->setColumnWidth(SearchPageListModel::SR_TYPE, 60); 338 treeview->setColumnWidth(SearchPageListModel::SR_TYPE, 60);
334 treeview->setColumnWidth(SearchPageListModel::SR_EPISODES, 60); 339 treeview->setColumnWidth(SearchPageListModel::SR_EPISODES, 60);
335 treeview->setColumnWidth(SearchPageListModel::SR_SCORE, 60); 340 treeview->setColumnWidth(SearchPageListModel::SR_SCORE, 60);
336 treeview->setColumnWidth(SearchPageListModel::SR_SEASON, 100); 341 treeview->setColumnWidth(SearchPageListModel::SR_SEASON, 100);
337 342
338 treeview->header()->setStretchLastSection(false); 343 treeview->header()->setStretchLastSection(false);
339 344
340 /* Double click stuff */ 345 /* Double click stuff */
341 connect(treeview, &QAbstractItemView::doubleClicked, this, &SearchPage::ItemDoubleClicked); 346 connect(treeview, &QAbstractItemView::doubleClicked, this, &SearchPage::ItemDoubleClicked);