# HG changeset patch # User Paper # Date 1699296090 18000 # Node ID 80f49f623d303101b23ae1cdb82c7b51ead6ecf8 # Parent fcae8bece0ec4fd65b54b581aa99a6ff37a182df locale: allow switching locales without restarting diff -r fcae8bece0ec -r 80f49f623d30 CMakeLists.txt --- a/CMakeLists.txt Mon Nov 06 02:03:55 2023 -0500 +++ b/CMakeLists.txt Mon Nov 06 13:41:30 2023 -0500 @@ -135,7 +135,7 @@ cmake_language(CALL qt${QT_VERSION_MAJOR}_create_translation ${SRC_FILES} ${TS_FILES} OPTIONS "-I${CMAKE_CURRENT_SOURCE_DIR}/include") endif() cmake_language(CALL qt${QT_VERSION_MAJOR}_add_translation QM_FILES ${TS_FILES}) -add_custom_target(translation SOURCES ${QM_FILES} DEPENDS ${TS_FILES}) +list(APPEND SRC_FILES ${QM_FILES}) function(qt_create_resource_file outfile) set(QRC "\n\t\n") @@ -149,7 +149,7 @@ endfunction() qt_create_resource_file("${CMAKE_CURRENT_BINARY_DIR}/rc/locale.qrc" ${QM_FILES}) -add_custom_target(resources DEPENDS translation SOURCES "${CMAKE_CURRENT_BINARY_DIR}/rc/locale.qrc") +list(APPEND SRC_FILES "${CMAKE_CURRENT_BINARY_DIR}/rc/locale.qrc") # This is also used in the Win32 rc file set(RC_INFO_STRING "A lightweight anime tracker built with Qt.") @@ -183,7 +183,6 @@ endif() add_executable(minori WIN32 MACOSX_BUNDLE ${SRC_FILES}) -add_dependencies(minori resources) set_property(TARGET minori PROPERTY CXX_STANDARD 11) set_property(TARGET minori PROPERTY AUTOMOC ON) set_property(TARGET minori PROPERTY AUTORCC ON) diff -r fcae8bece0ec -r 80f49f623d30 include/gui/widgets/sidebar.h --- a/include/gui/widgets/sidebar.h Mon Nov 06 02:03:55 2023 -0500 +++ b/include/gui/widgets/sidebar.h Mon Nov 06 13:41:30 2023 -0500 @@ -13,6 +13,7 @@ SideBar(QWidget* parent = nullptr); QListWidgetItem* AddItem(QString name, QIcon icon = QIcon()); QListWidgetItem* AddSeparator(); + int GetCurrentItem(); bool IndexIsSeparator(QModelIndex index) const; static QIcon CreateIcon(const char* file); void SetBackgroundColor(QColor color); diff -r fcae8bece0ec -r 80f49f623d30 include/gui/window.h --- a/include/gui/window.h Mon Nov 06 02:03:55 2023 -0500 +++ b/include/gui/window.h Mon Nov 06 13:41:30 2023 -0500 @@ -15,13 +15,17 @@ MainWindow(QWidget* parent = nullptr); void SetActivePage(QWidget* page); void CreateBars(); + void AddMainWidgets(); + void RetranslateUI(); + void AsyncSynchronize(QStackedWidget* stack); + void changeEvent(QEvent* event) override; void showEvent(QShowEvent* event) override; void closeEvent(QCloseEvent* event) override; private: - QWidget* main_widget; - QStackedWidget* stack; - SideBar* sidebar; + QWidget* main_widget = nullptr; + QStackedWidget* stack = nullptr; + SideBar* sidebar = nullptr; }; #endif // __window_h diff -r fcae8bece0ec -r 80f49f623d30 rc/locale/en_GB.ts --- a/rc/locale/en_GB.ts Mon Nov 06 02:03:55 2023 -0500 +++ b/rc/locale/en_GB.ts Mon Nov 06 13:41:30 2023 -0500 @@ -185,252 +185,267 @@ MainWindow - + Now Playing - + Anime List - + History - + Statistics - + Search - + Seasons - + Torrents - + &File - + &Library folders - + &Add new folder... - + &Scan available episodes - + Play &next episode - + Play &random episode - + E&xit - + &Services - + Synchronize &list Synchronise &list - + &AniList - - - + + + Go to my &profile - + Go to my &stats - + &Kitsu - + Go to my &feed - + Go to my &library - + &MyAnimeList - + Go to my p&anel - + Go to my &history - + &Tools - + &Export anime list - + Export as &Markdown... - + Export as MyAnimeList &XML... - + Enable anime &recognition - + Enable auto &sharing - + Enable &auto synchronization Enable &auto synchronisation - + &Settings - - &View - - - - - &Now Playing - - - - - &Anime List - - - + &View + + + + + &Now Playing + + + + + &Anime List + + + + &History - + &Statistics - + S&earch - + Se&asons - + &Torrents - + Show sidebar - + &Help - - &About Minori - - - - - About &Qt - - - + &About Minori + + + + + About &Qt + + + + &Synchronize &Synchronise - + Add new folder... - + Placeholder - + S&ettings + + + Error synchronizing with service! + + + + + It seems you haven't yet selected a service to use. + + + + + Would you like to select one now? + + NowPlayingPages::Default @@ -716,6 +731,11 @@ + + Set application locale: + + + Highlight anime if next episode is available in library folders @@ -726,11 +746,6 @@ - - Set application locale (requires restart): - - - Progress diff -r fcae8bece0ec -r 80f49f623d30 rc/locale/es.ts --- a/rc/locale/es.ts Mon Nov 06 02:03:55 2023 -0500 +++ b/rc/locale/es.ts Mon Nov 06 13:41:30 2023 -0500 @@ -190,252 +190,267 @@ MainWindow - + Now Playing Jugando ahora - + Anime List Lista de anime - + History Historia - + Statistics Estadísticas - + Search Buscar - + Seasons Temporadas - + Torrents - + &File &Fichero - + &Library folders Directorios de la biblioteca (&L) - + &Add new folder... &Añadir una nueva directorios... - + &Scan available episodes E&scanear episodios disponibles - + Play &next episode Ver el próximo episodio (&N) - + Play &random episode Ver episodio aleato&rio - + E&xit Salida (&X) - + &Services &Servicios - + Synchronize &list Sincronizar &lista - + &AniList &AniList - - - + + + Go to my &profile Ir a mi &perfil - + Go to my &stats Ir a mis e&stadísticas - + &Kitsu &Kitsu - + Go to my &feed Ir a mi &feed - + Go to my &library Ir a mi biblioteca (&L) - + &MyAnimeList &MyAnimeList - + Go to my p&anel Ir a mi p&anel - + Go to my &history Ir a mi &historia - + &Tools Ins&trumentos - + &Export anime list &Exportar lista de anime - + Export as &Markdown... Exportar como &Markdown... - + Export as MyAnimeList &XML... Exportar como &XML de MyAnimeList - + Enable anime &recognition Activar el &reconocimiento de anime - + Enable auto &sharing Activar el uso compartido automático (&S) - + Enable &auto synchronization Activar la sincronización &automática - + &Settings Configuración (&S) - + &View &Ver - + &Now Playing Jugando ahora (&N) - + &Anime List Lista de &anime - + &History &Historia - + &Statistics E&stadísticas - + S&earch Buscar (&S) - + Se&asons Tempor&adas - + &Torrents - + Show sidebar Mostrar barra lateral - + &Help Ayuda (&H) - + &About Minori &Acerca de Minori - + About &Qt Acerca de &Qt - + &Synchronize &Sincronice - + Add new folder... Añadir una nueva carpeta... - + Placeholder Marcador de posición - + S&ettings Configuración (&S) + + + Error synchronizing with service! + Error al sincronizar con el servicio! + + + + It seems you haven't yet selected a service to use. + Parece que aún no has seleccionado un servicio para usar. + + + + Would you like to select one now? + ¿Quieres seleccionar uno ahora? + NowPlayingPages::Default @@ -722,8 +737,8 @@ - Set application locale (requires restart): - Establecer la configuración regional de la aplicación (requiere reinicio): + Set application locale: + Establecer la configuración regional de la aplicación: diff -r fcae8bece0ec -r 80f49f623d30 src/gui/dialog/settings/application.cc --- a/src/gui/dialog/settings/application.cc Mon Nov 06 02:03:55 2023 -0500 +++ b/src/gui/dialog/settings/application.cc Mon Nov 06 13:41:30 2023 -0500 @@ -107,7 +107,7 @@ { /* Application locale */ { - QLabel* locale_combo_box_label = new QLabel(tr("Set application locale (requires restart):"), appearance_group_box); + QLabel* locale_combo_box_label = new QLabel(tr("Set application locale:"), appearance_group_box); appearance_layout->addWidget(locale_combo_box_label); } diff -r fcae8bece0ec -r 80f49f623d30 src/gui/pages/anime_list.cc --- a/src/gui/pages/anime_list.cc Mon Nov 06 02:03:55 2023 -0500 +++ b/src/gui/pages/anime_list.cc Mon Nov 06 13:41:30 2023 -0500 @@ -434,6 +434,8 @@ SetColumnDefaults(); setFocusPolicy(Qt::TabFocus); setFocusProxy(tab_bar); + + Refresh(); } void AnimeListPage::RefreshList() { diff -r fcae8bece0ec -r 80f49f623d30 src/gui/widgets/anime_info.cc --- a/src/gui/widgets/anime_info.cc Mon Nov 06 02:03:55 2023 -0500 +++ b/src/gui/widgets/anime_info.cc Mon Nov 06 13:41:30 2023 -0500 @@ -31,11 +31,15 @@ /* details */ QString details_data; QTextStream details_data_s(&details_data); - details_data_s << Translate::ToString(anime.GetFormat()).c_str() << "\n" + /* we have to convert ALL of these strings to + QString because QTextStream sucks and assumes + Latin1 (on Windows?) */ + details_data_s << Strings::ToQString(Translate::ToString(anime.GetFormat())) << "\n" << anime.GetEpisodes() << "\n" - << Translate::ToString(anime.GetUserStatus()).c_str() << "\n" - << Translate::ToString(anime.GetSeason()).c_str() << " " << anime.GetAirDate().GetYear() << "\n" - << Strings::Implode(anime.GetGenres(), ", ").c_str() << "\n" + << Strings::ToQString(Translate::ToString(anime.GetUserStatus())) << "\n" + << Strings::ToQString(Translate::ToString(anime.GetSeason())) << " " + << anime.GetAirDate().GetYear() << "\n" + << Strings::ToQString(Strings::Implode(anime.GetGenres(), ", ")) << "\n" << anime.GetAudienceScore() << "%"; _details->GetParagraph()->SetText(details_data); diff -r fcae8bece0ec -r 80f49f623d30 src/gui/widgets/sidebar.cc --- a/src/gui/widgets/sidebar.cc Mon Nov 06 02:03:55 2023 -0500 +++ b/src/gui/widgets/sidebar.cc Mon Nov 06 13:41:30 2023 -0500 @@ -24,6 +24,10 @@ setCurrentRow(AddSeparatorsToIndex(index)); } +int SideBar::GetCurrentItem() { + return RemoveSeparatorsFromIndex(currentRow()); +} + void SideBar::SetBackgroundColor(QColor color) { viewport()->setAutoFillBackground(color != Qt::transparent); QPalette pal(palette()); diff -r fcae8bece0ec -r 80f49f623d30 src/gui/window.cc --- a/src/gui/window.cc Mon Nov 06 02:03:55 2023 -0500 +++ b/src/gui/window.cc Mon Nov 06 13:41:30 2023 -0500 @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef MACOSX # include "sys/osx/dark_theme.h" #elif defined(WIN32) @@ -49,46 +50,14 @@ TORRENTS }; -static void AsyncSynchronize(QStackedWidget* stack) { - QThreadPool::globalInstance()->start([stack] { - Services::Synchronize(); - reinterpret_cast(stack->widget(static_cast(Pages::ANIME_LIST)))->Refresh(); - }); -} - MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { setWindowIcon(QIcon(":/favicon.png")); - main_widget = new QWidget(parent); - - sidebar = new SideBar(main_widget); - sidebar->AddItem(tr("Now Playing"), SideBar::CreateIcon(":/icons/16x16/film.png")); - sidebar->AddSeparator(); - sidebar->AddItem(tr("Anime List"), SideBar::CreateIcon(":/icons/16x16/document-list.png")); - sidebar->AddItem(tr("History"), SideBar::CreateIcon(":/icons/16x16/clock-history-frame.png")); - sidebar->AddItem(tr("Statistics"), SideBar::CreateIcon(":/icons/16x16/chart.png")); - sidebar->AddSeparator(); - sidebar->AddItem(tr("Search"), SideBar::CreateIcon(":/icons/16x16/magnifier.png")); - sidebar->AddItem(tr("Seasons"), SideBar::CreateIcon(":/icons/16x16/calendar.png")); - sidebar->AddItem(tr("Torrents"), SideBar::CreateIcon(":/icons/16x16/feed.png")); - sidebar->setFixedWidth(128); - sidebar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + main_widget = new QWidget(this); + /*QHBoxLayout* layout = */new QHBoxLayout(main_widget); - stack = new QStackedWidget(main_widget); - stack->addWidget(new NowPlayingPage(main_widget)); - stack->addWidget(new AnimeListPage(main_widget)); - stack->addWidget(new HistoryPage(main_widget)); - stack->addWidget(new StatisticsPage(main_widget)); - stack->addWidget(new SearchPage(main_widget)); - stack->addWidget(new SeasonsPage(main_widget)); - stack->addWidget(new TorrentsPage(main_widget)); + AddMainWidgets(); - connect(sidebar, &SideBar::CurrentItemChanged, stack, &QStackedWidget::setCurrentIndex); - sidebar->SetCurrentItem(static_cast(Pages::ANIME_LIST)); - - QHBoxLayout* layout = new QHBoxLayout(main_widget); - layout->addWidget(sidebar); - layout->addWidget(stack); setCentralWidget(main_widget); CreateBars(); @@ -110,6 +79,53 @@ timer->start(5000); } +void MainWindow::AddMainWidgets() { + int page = static_cast(Pages::ANIME_LIST); + if (sidebar) { + main_widget->layout()->removeWidget(sidebar); + delete sidebar; + } + + if (stack) { + page = stack->currentIndex(); + main_widget->layout()->removeWidget(stack); + delete stack; + } + + sidebar = new SideBar(main_widget); + sidebar->setFixedWidth(128); + sidebar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + + sidebar->AddItem(tr("Now Playing"), SideBar::CreateIcon(":/icons/16x16/film.png")); + sidebar->AddSeparator(); + sidebar->AddItem(tr("Anime List"), SideBar::CreateIcon(":/icons/16x16/document-list.png")); + sidebar->AddItem(tr("History"), SideBar::CreateIcon(":/icons/16x16/clock-history-frame.png")); + sidebar->AddItem(tr("Statistics"), SideBar::CreateIcon(":/icons/16x16/chart.png")); + sidebar->AddSeparator(); + sidebar->AddItem(tr("Search"), SideBar::CreateIcon(":/icons/16x16/magnifier.png")); + sidebar->AddItem(tr("Seasons"), SideBar::CreateIcon(":/icons/16x16/calendar.png")); + sidebar->AddItem(tr("Torrents"), SideBar::CreateIcon(":/icons/16x16/feed.png")); + + stack = new QStackedWidget(main_widget); + stack->addWidget(new NowPlayingPage(main_widget)); + stack->addWidget(new AnimeListPage(main_widget)); + stack->addWidget(new HistoryPage(main_widget)); + stack->addWidget(new StatisticsPage(main_widget)); + stack->addWidget(new SearchPage(main_widget)); + stack->addWidget(new SeasonsPage(main_widget)); + stack->addWidget(new TorrentsPage(main_widget)); + + connect(sidebar, &SideBar::CurrentItemChanged, this, [](int index){ + std::cout << index << std::endl; + }); + + connect(sidebar, &SideBar::CurrentItemChanged, stack, &QStackedWidget::setCurrentIndex); + sidebar->SetCurrentItem(page); + + main_widget->layout()->addWidget(sidebar); + main_widget->layout()->addWidget(stack); +} + void MainWindow::CreateBars() { /* Menu Bar */ QAction* action; @@ -227,13 +243,17 @@ action = menu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); action->setMenuRole(QAction::AboutQtRole); + /* QMainWindow will delete the old one for us, + according to the docs */ setMenuBar(menubar); /* Toolbar */ /* remove old toolbar(s) */ QList toolbars = findChildren(); - for (auto& t : toolbars) + for (auto& t : toolbars) { removeToolBar(t); + delete t; + } QToolBar* toolbar = new QToolBar(this); toolbar->addAction(QIcon(":/icons/24x24/arrow-circle-double-135.png"), tr("&Synchronize"), @@ -272,9 +292,56 @@ this->setCentralWidget(page); } +void MainWindow::AsyncSynchronize(QStackedWidget* stack) { + if (session.config.service == Anime::Services::NONE) { + QMessageBox msg; + msg.setWindowTitle(tr("Error synchronizing with service!")); + msg.setText(tr("It seems you haven't yet selected a service to use.")); + msg.setInformativeText(tr("Would you like to select one now?")); + msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msg.setDefaultButton(QMessageBox::Yes); + int ret = msg.exec(); + if (ret == QMessageBox::Yes) { + SettingsDialog dialog; + dialog.exec(); + } + } + QThreadPool::globalInstance()->start([stack] { + Services::Synchronize(); + reinterpret_cast(stack->widget(static_cast(Pages::ANIME_LIST)))->Refresh(); + }); +} + +void MainWindow::RetranslateUI() { + /* Temporarily disable UI updates so we don't flash the screen */ + setUpdatesEnabled(false); + AddMainWidgets(); + CreateBars(); + setUpdatesEnabled(true); +} + +void MainWindow::changeEvent(QEvent* event) { + if (event) { /* is this really necessary */ + switch (event->type()) { + // this event is send if a translator is loaded + case QEvent::LanguageChange: + RetranslateUI(); + break; + + default: + break; + } + } + QMainWindow::changeEvent(event); +} + void MainWindow::showEvent(QShowEvent* event) { QMainWindow::showEvent(event); #ifdef WIN32 + /* Technically this *should* be + session.config.theme.IsInDarkTheme() && win32::IsInDarkTheme() + but I prefer the title bar being black even when light mode + is enabled :/ */ win32::SetTitleBarsToBlack(session.config.theme.IsInDarkTheme()); #endif } diff -r fcae8bece0ec -r 80f49f623d30 src/services/services.cc --- a/src/services/services.cc Mon Nov 06 02:03:55 2023 -0500 +++ b/src/services/services.cc Mon Nov 06 13:41:30 2023 -0500 @@ -9,19 +9,7 @@ void Synchronize() { switch (session.config.service) { case Anime::Services::ANILIST: AniList::GetAnimeList(); break; - default: { - QMessageBox msg; - msg.setInformativeText("It seems you haven't yet selected a service to use."); - msg.setText("Would you like to select one now?"); - msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msg.setDefaultButton(QMessageBox::Yes); - int ret = msg.exec(); - if (ret == QMessageBox::Yes) { - SettingsDialog dialog; - dialog.exec(); - } - break; - } + default: break; } }