Mercurial > minori
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); |