mirror of
				https://github.com/RetroDECK/Duckstation.git
				synced 2025-04-10 19:15:14 +00:00 
			
		
		
		
	Qt: Add translation support and language setting
This commit is contained in:
		
							parent
							
								
									bb56b169fc
								
							
						
					
					
						commit
						3edb255eca
					
				|  | @ -463,6 +463,31 @@ void MainWindow::setupAdditionalUi() | |||
|     }); | ||||
|   } | ||||
|   updateDebugMenuGPURenderer(); | ||||
| 
 | ||||
|   const QString current_language( | ||||
|     QString::fromStdString(m_host_interface->GetStringSettingValue("Main", "Language", ""))); | ||||
|   for (const std::pair<QString, QString>& it : m_host_interface->getAvailableLanguageList()) | ||||
|   { | ||||
|     QAction* action = m_ui.menuSettingsLanguage->addAction(it.first); | ||||
|     action->setCheckable(true); | ||||
|     action->setChecked(it.second == current_language); | ||||
|     action->setData(it.second); | ||||
|     connect(action, &QAction::triggered, [this, action]() { | ||||
|       const QString new_language = action->data().toString(); | ||||
|       m_host_interface->SetStringSettingValue("Main", "Language", new_language.toUtf8().constData()); | ||||
|       QMessageBox::information(this, tr("DuckStation"), | ||||
|                                tr("Language changed. Please restart the application to apply.")); | ||||
|       for (QObject* obj : m_ui.menuSettingsLanguage->children()) | ||||
|       { | ||||
|         QAction* other_action = qobject_cast<QAction*>(obj); | ||||
|         if (other_action) | ||||
|         { | ||||
|           QSignalBlocker blocker(other_action); | ||||
|           action->setChecked(other_action == action); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void MainWindow::updateEmulationActions(bool starting, bool running) | ||||
|  |  | |||
|  | @ -90,6 +90,11 @@ | |||
|       <string>Theme</string> | ||||
|      </property> | ||||
|     </widget> | ||||
|     <widget class="QMenu" name="menuSettingsLanguage"> | ||||
|      <property name="title"> | ||||
|       <string>Language</string> | ||||
|      </property> | ||||
|     </widget> | ||||
|     <addaction name="actionFullscreen"/> | ||||
|     <addaction name="separator"/> | ||||
|     <addaction name="actionGeneralSettings"/> | ||||
|  | @ -106,6 +111,7 @@ | |||
|     <addaction name="actionScanForNewGames"/> | ||||
|     <addaction name="actionRescanAllGames"/> | ||||
|     <addaction name="separator"/> | ||||
|     <addaction name="menuSettingsLanguage"/> | ||||
|     <addaction name="menuSettingsTheme"/> | ||||
|    </widget> | ||||
|    <widget class="QMenu" name="menuHelp"> | ||||
|  |  | |||
|  | @ -23,7 +23,9 @@ | |||
| #include <QtCore/QDateTime> | ||||
| #include <QtCore/QDebug> | ||||
| #include <QtCore/QEventLoop> | ||||
| #include <QtCore/QFile> | ||||
| #include <QtCore/QTimer> | ||||
| #include <QtCore/QTranslator> | ||||
| #include <QtWidgets/QMenu> | ||||
| #include <QtWidgets/QMessageBox> | ||||
| #include <algorithm> | ||||
|  | @ -49,10 +51,19 @@ const char* QtHostInterface::GetFrontendName() const | |||
|   return "DuckStation Qt Frontend"; | ||||
| } | ||||
| 
 | ||||
| std::vector<std::pair<QString, QString>> QtHostInterface::getAvailableLanguageList() | ||||
| { | ||||
|   return {{QStringLiteral("English"), QStringLiteral("")}}; | ||||
| } | ||||
| 
 | ||||
| bool QtHostInterface::Initialize() | ||||
| { | ||||
|   createThread(); | ||||
|   return m_worker_thread->waitForInit(); | ||||
|   if (!m_worker_thread->waitForInit()) | ||||
|     return false; | ||||
| 
 | ||||
|   installTranslator(); | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void QtHostInterface::Shutdown() | ||||
|  | @ -82,6 +93,36 @@ void QtHostInterface::shutdownOnThread() | |||
|   CommonHostInterface::Shutdown(); | ||||
| } | ||||
| 
 | ||||
| void QtHostInterface::installTranslator() | ||||
| { | ||||
|   m_translator = std::make_unique<QTranslator>(); | ||||
| 
 | ||||
|   std::string language = GetStringSettingValue("Main", "Language", ""); | ||||
|   if (language.empty()) | ||||
|     return; | ||||
| 
 | ||||
|   const QString path = | ||||
|     QStringLiteral("%1/translations/duckstation-qt_%3.qm").arg(qApp->applicationDirPath()).arg(language.c_str()); | ||||
|   if (!QFile::exists(path)) | ||||
|   { | ||||
|     QMessageBox::warning( | ||||
|       nullptr, QStringLiteral("Translation Error"), | ||||
|       QStringLiteral("Failed to find translation file for language '%1':\n%2").arg(language.c_str()).arg(path)); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   if (!m_translator->load(path)) | ||||
|   { | ||||
|     QMessageBox::warning( | ||||
|       nullptr, QStringLiteral("Translation Error"), | ||||
|       QStringLiteral("Failed to load translation file for language '%1':\n%2").arg(language.c_str()).arg(path)); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   Log_InfoPrintf("Loaded translation file for language '%s'", language.c_str()); | ||||
|   qApp->installTranslator(m_translator.get()); | ||||
| } | ||||
| 
 | ||||
| void QtHostInterface::ReportError(const char* message) | ||||
| { | ||||
|   HostInterface::ReportError(message); | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ class QEventLoop; | |||
| class QMenu; | ||||
| class QWidget; | ||||
| class QTimer; | ||||
| class QTranslator; | ||||
| 
 | ||||
| class GameList; | ||||
| class INISettingsInterface; | ||||
|  | @ -95,6 +96,9 @@ public: | |||
|   /// Returns a path relative to the application directory (for system files).
 | ||||
|   QString getProgramDirectoryRelativePath(const QString& arg) const; | ||||
| 
 | ||||
|   /// Returns a list of supported languages and codes (suffixes for translation files).
 | ||||
|   static std::vector<std::pair<QString, QString>> getAvailableLanguageList(); | ||||
| 
 | ||||
| Q_SIGNALS: | ||||
|   void errorReported(const QString& message); | ||||
|   void messageReported(const QString& message); | ||||
|  | @ -213,6 +217,7 @@ private: | |||
|   void threadEntryPoint(); | ||||
|   bool initializeOnThread(); | ||||
|   void shutdownOnThread(); | ||||
|   void installTranslator(); | ||||
|   void renderDisplay(); | ||||
|   void connectDisplaySignals(QtDisplayWidget* widget); | ||||
|   void updateDisplayState(); | ||||
|  | @ -222,6 +227,8 @@ private: | |||
|   std::unique_ptr<INISettingsInterface> m_settings_interface; | ||||
|   std::recursive_mutex m_settings_mutex; | ||||
| 
 | ||||
|   std::unique_ptr<QTranslator> m_translator; | ||||
| 
 | ||||
|   MainWindow* m_main_window = nullptr; | ||||
|   QThread* m_original_thread = nullptr; | ||||
|   Thread* m_worker_thread = nullptr; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Connor McLaughlin
						Connor McLaughlin