comparison src/gui/window.cc @ 250:c130f47f6f48

*: many many changes e.g. the search page is actually implemented now!
author Paper <paper@paper.us.eu.org>
date Sun, 04 Feb 2024 21:17:17 -0500
parents 06d6c351925c
children fe702c8f161f
comparison
equal deleted inserted replaced
249:6b2441c776dd 250:c130f47f6f48
46 # include "sys/osx/permissions.h" 46 # include "sys/osx/permissions.h"
47 #elif defined(WIN32) 47 #elif defined(WIN32)
48 # include "sys/win32/dark_theme.h" 48 # include "sys/win32/dark_theme.h"
49 #endif 49 #endif
50 50
51 enum class Pages {
52 NOW_PLAYING,
53
54 ANIME_LIST,
55 HISTORY,
56 STATISTICS,
57
58 SEARCH,
59 SEASONS,
60 TORRENTS
61 };
62
63 void PlayingThread::run() { 51 void PlayingThread::run() {
64 std::vector<std::string> files; 52 std::vector<std::string> files;
65 Track::Media::GetCurrentlyPlaying(files); 53 Track::Media::GetCurrentlyPlaying(files);
66 emit Done(files); 54 emit Done(files);
67 } 55 }
122 timer->start(5000); 110 timer->start(5000);
123 } 111 }
124 112
125 void MainWindow::AddMainWidgets() { 113 void MainWindow::AddMainWidgets() {
126 int page = static_cast<int>(Pages::ANIME_LIST); 114 int page = static_cast<int>(Pages::ANIME_LIST);
115
127 if (sidebar.get()) { 116 if (sidebar.get()) {
128 main_widget->layout()->removeWidget(sidebar.get()); 117 main_widget->layout()->removeWidget(sidebar.get());
129 sidebar.reset(); 118 sidebar.reset();
130 } 119 }
131 120
147 sidebar->AddItem(tr("Search"), SideBar::CreateIcon(":/icons/16x16/magnifier.png")); 136 sidebar->AddItem(tr("Search"), SideBar::CreateIcon(":/icons/16x16/magnifier.png"));
148 sidebar->AddItem(tr("Seasons"), SideBar::CreateIcon(":/icons/16x16/calendar.png")); 137 sidebar->AddItem(tr("Seasons"), SideBar::CreateIcon(":/icons/16x16/calendar.png"));
149 sidebar->AddItem(tr("Torrents"), SideBar::CreateIcon(":/icons/16x16/feed.png")); 138 sidebar->AddItem(tr("Torrents"), SideBar::CreateIcon(":/icons/16x16/feed.png"));
150 139
151 stack.reset(new QStackedWidget(main_widget.get())); 140 stack.reset(new QStackedWidget(main_widget.get()));
141
152 stack->addWidget(new NowPlayingPage(main_widget.get())); 142 stack->addWidget(new NowPlayingPage(main_widget.get()));
143 /* ---- */
153 stack->addWidget(new AnimeListPage(main_widget.get())); 144 stack->addWidget(new AnimeListPage(main_widget.get()));
154 stack->addWidget(new HistoryPage(main_widget.get())); 145 stack->addWidget(new HistoryPage(main_widget.get()));
155 stack->addWidget(new StatisticsPage(main_widget.get())); 146 stack->addWidget(new StatisticsPage(main_widget.get()));
147 /* ---- */
156 stack->addWidget(new SearchPage(main_widget.get())); 148 stack->addWidget(new SearchPage(main_widget.get()));
157 stack->addWidget(new SeasonsPage(main_widget.get())); 149 stack->addWidget(new SeasonsPage(main_widget.get()));
158 stack->addWidget(new TorrentsPage(main_widget.get())); 150 stack->addWidget(new TorrentsPage(main_widget.get()));
159 151
160 connect(sidebar.get(), &SideBar::CurrentItemChanged, stack.get(), &QStackedWidget::setCurrentIndex); 152 connect(sidebar.get(), &SideBar::CurrentItemChanged, stack.get(), &QStackedWidget::setCurrentIndex);
164 main_widget->layout()->addWidget(stack.get()); 156 main_widget->layout()->addWidget(stack.get());
165 } 157 }
166 158
167 void MainWindow::CreateBars() { 159 void MainWindow::CreateBars() {
168 QMenuBar* menubar = new QMenuBar(this); 160 QMenuBar* menubar = new QMenuBar(this);
169 QMenu* folder_menu; /* this is used twice, so we declare it here */
170 QAction* sync_action; 161 QAction* sync_action;
171 162
172 { 163 {
173 /* File */ 164 /* File */
174 QMenu* menu = menubar->addMenu(tr("&File")); 165 QMenu* menu = menubar->addMenu(tr("&File"));
175 166
176 { 167 {
177 folder_menu = menu->addMenu(tr("&Library folders")); 168 folder_menu = menu->addMenu(tr("&Library folders"));
178 169
179 /* add in all of our existing folders... */ 170 UpdateFolderMenu();
180 std::size_t i = 0;
181 for (const auto& path : session.config.library.paths) {
182 const QString folder = Strings::ToQString(path);
183 QAction* action = folder_menu->addAction(folder, [folder]{
184 QDesktopServices::openUrl(QUrl::fromLocalFile(folder));
185 });
186 if (i < 9)
187 action->setShortcut(QKeySequence(Qt::ALT | static_cast<Qt::Modifier>(Qt::Key_1 + i)));
188 else if (i == 9)
189 action->setShortcut(QKeySequence(Qt::ALT | Qt::Key_0));
190 /* don't bother with a shortcut in case of more... */
191 i++;
192 }
193
194 folder_menu->addSeparator();
195
196 {
197 folder_menu->addAction(tr("&Add new folder..."), [this]{
198 const QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
199 QDir::homePath(),
200 QFileDialog::ShowDirsOnly
201 | QFileDialog::DontResolveSymlinks);
202 if (dir.isEmpty())
203 return;
204 session.config.library.paths.insert(Strings::ToUtf8String(dir));
205 /* we have to recreate the menu bar to add the new folder */
206 CreateBars();
207 });
208 }
209 } 171 }
210 172
211 { 173 {
212 menu->addAction(tr("&Scan available episodes"), []{ 174 menu->addAction(tr("&Scan available episodes"), []{
213 Library::SearchLibraryFolders(); 175 Library::SearchLibraryFolders();
227 // } 189 // }
228 190
229 menu->addSeparator(); 191 menu->addSeparator();
230 192
231 { 193 {
232 QAction* action = menu->addAction(tr("E&xit"), qApp, &QApplication::quit); 194 QAction* action = menu->addAction(tr("E&xit"), this, &MainWindow::close);
233 action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q)); 195 action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
234 } 196 }
235 } 197 }
236 198
237 { 199 {
312 274
313 { 275 {
314 QAction* action = menu->addAction(tr("&Settings"), [this] { 276 QAction* action = menu->addAction(tr("&Settings"), [this] {
315 SettingsDialog dialog(this); 277 SettingsDialog dialog(this);
316 dialog.exec(); 278 dialog.exec();
317 CreateBars(); 279 UpdateFolderMenu();
318 }); 280 });
319 action->setMenuRole(QAction::PreferencesRole); 281 action->setMenuRole(QAction::PreferencesRole);
320 } 282 }
321 } 283 }
322 284
324 /* View */ 286 /* View */
325 QMenu* menu = menubar->addMenu(tr("&View")); 287 QMenu* menu = menubar->addMenu(tr("&View"));
326 288
327 { 289 {
328 /* Pages... */ 290 /* Pages... */
329 std::map<QAction*, int> page_to_index_map = {}; 291 QActionGroup* pages_group = new QActionGroup(menu);
330
331 QActionGroup* pages_group = new QActionGroup(this);
332 pages_group->setExclusive(true); 292 pages_group->setExclusive(true);
333 293
334 { 294 {
335 QAction* action = pages_group->addAction(menu->addAction(tr("&Now Playing"))); 295 QAction* action = pages_group->addAction(menu->addAction(tr("&Now Playing")));
336 action->setCheckable(true); 296 action->setCheckable(true);
337 page_to_index_map[action] = 0; 297 connect(action, &QAction::toggled, this, [this] {
298 sidebar->SetCurrentItem(0);
299 });
338 } 300 }
339 301
340 { 302 {
341 QAction* action = pages_group->addAction(menu->addAction(tr("&Anime List"))); 303 QAction* action = pages_group->addAction(menu->addAction(tr("&Anime List")));
342 action->setCheckable(true); 304 action->setCheckable(true);
343 action->setChecked(true); 305 action->setChecked(true);
344 page_to_index_map[action] = 1; 306 connect(action, &QAction::toggled, this, [this] {
307 sidebar->SetCurrentItem(1);
308 });
345 } 309 }
346 310
347 { 311 {
348 QAction* action = pages_group->addAction(menu->addAction(tr("&History"))); 312 QAction* action = pages_group->addAction(menu->addAction(tr("&History")));
349 action->setCheckable(true); 313 action->setCheckable(true);
350 page_to_index_map[action] = 2; 314 connect(action, &QAction::toggled, this, [this] {
315 sidebar->SetCurrentItem(2);
316 });
351 } 317 }
352 318
353 { 319 {
354 QAction* action = pages_group->addAction(menu->addAction(tr("&Statistics"))); 320 QAction* action = pages_group->addAction(menu->addAction(tr("&Statistics")));
355 action->setCheckable(true); 321 action->setCheckable(true);
356 page_to_index_map[action] = 3; 322 connect(action, &QAction::toggled, this, [this] {
323 sidebar->SetCurrentItem(3);
324 });
357 } 325 }
358 326
359 { 327 {
360 QAction* action = pages_group->addAction(menu->addAction(tr("S&earch"))); 328 QAction* action = pages_group->addAction(menu->addAction(tr("S&earch")));
361 action->setCheckable(true); 329 action->setCheckable(true);
362 page_to_index_map[action] = 4; 330 connect(action, &QAction::toggled, this, [this] {
331 sidebar->SetCurrentItem(4);
332 });
363 } 333 }
364 334
365 { 335 {
366 QAction* action = pages_group->addAction(menu->addAction(tr("Se&asons"))); 336 QAction* action = pages_group->addAction(menu->addAction(tr("Se&asons")));
367 action->setCheckable(true); 337 action->setCheckable(true);
368 page_to_index_map[action] = 5; 338 connect(action, &QAction::toggled, this, [this] {
339 sidebar->SetCurrentItem(5);
340 });
369 } 341 }
370 342
371 { 343 {
372 QAction* action = pages_group->addAction(menu->addAction(tr("&Torrents"))); 344 QAction* action = pages_group->addAction(menu->addAction(tr("&Torrents")));
373 action->setCheckable(true); 345 action->setCheckable(true);
374 page_to_index_map[action] = 6; 346 connect(action, &QAction::toggled, this, [this] {
347 sidebar->SetCurrentItem(6);
348 });
375 } 349 }
376 350
377 /* pain in my ass */ 351 /* pain in my ass */
378 connect(sidebar.get(), &SideBar::CurrentItemChanged, this, 352 connect(sidebar.get(), &SideBar::CurrentItemChanged, this, [pages_group](int index) {
379 [pages_group](int index) { pages_group->actions()[index]->setChecked(true); }); 353 QAction* checked = pages_group->checkedAction();
380 354
381 connect(pages_group, &QActionGroup::triggered, this, 355 const QList<QAction*>& actions = pages_group->actions();
382 [this, page_to_index_map](QAction* action) { sidebar->SetCurrentItem(page_to_index_map.at(action)); }); 356 if (index > actions.size())
357 return;
358
359 if (checked)
360 checked->setChecked(false);
361 actions[index]->setChecked(true);
362 });
383 } 363 }
384 364
385 menu->addSeparator(); 365 menu->addSeparator();
386 366
387 // { 367 // {
477 457
478 toolbar->addSeparator(); 458 toolbar->addSeparator();
479 toolbar->addAction(QIcon(":/icons/24x24/gear.png"), tr("S&ettings"), [this] { 459 toolbar->addAction(QIcon(":/icons/24x24/gear.png"), tr("S&ettings"), [this] {
480 SettingsDialog dialog(this); 460 SettingsDialog dialog(this);
481 dialog.exec(); 461 dialog.exec();
482 CreateBars(); 462 /* library folders might have changed! */
463 UpdateFolderMenu();
483 }); 464 });
484 addToolBar(toolbar); 465 addToolBar(toolbar);
466 }
467 }
468
469 void MainWindow::UpdateFolderMenu() {
470 if (!folder_menu)
471 return;
472
473 folder_menu->clear();
474
475 /* add in all of our existing folders... */
476 std::size_t i = 0;
477 for (const auto& path : session.config.library.paths) {
478 const QString folder = Strings::ToQString(path);
479 QAction* action = folder_menu->addAction(folder, [folder]{
480 QDesktopServices::openUrl(QUrl::fromLocalFile(folder));
481 });
482
483 if (i < 9) {
484 /* Qt::Key_1 is equivalent to 1 in ASCII, so we can use the same
485 * stupid `'0' + i` trick here
486 */
487 action->setShortcut(QKeySequence(Qt::ALT | static_cast<Qt::Modifier>(Qt::Key_1 + i)));
488 } else if (i == 9) {
489 action->setShortcut(QKeySequence(Qt::ALT | Qt::Key_0));
490 }
491 /* don't bother with a shortcut in case of more... */
492 i++;
493 }
494
495 folder_menu->addSeparator();
496
497 {
498 folder_menu->addAction(tr("&Add new folder..."), [this]{
499 const QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
500 QDir::homePath(),
501 QFileDialog::ShowDirsOnly
502 | QFileDialog::DontResolveSymlinks);
503 if (dir.isEmpty())
504 return;
505 session.config.library.paths.insert(Strings::ToUtf8String(dir));
506 UpdateFolderMenu();
507 });
485 } 508 }
486 } 509 }
487 510
488 void MainWindow::SetActivePage(QWidget* page) { 511 void MainWindow::SetActivePage(QWidget* page) {
489 this->setCentralWidget(page); 512 this->setCentralWidget(page);