瀏覽代碼

Moved language handling code to Languages.h/cpp

Ivan Savenko 2 年之前
父節點
當前提交
70bdb3aeaf

+ 2 - 0
launcher/CMakeLists.txt

@@ -10,6 +10,7 @@ set(launcher_SRCS
 		firstLaunch/firstlaunch_moc.cpp
 		main.cpp
 		mainwindow_moc.cpp
+		languages.cpp
 		launcherdirs.cpp
 		jsonutils.cpp
 		updatedialog_moc.cpp
@@ -29,6 +30,7 @@ set(launcher_HEADERS
 		settingsView/csettingsview_moc.h
 		firstLaunch/firstlaunch_moc.h
 		mainwindow_moc.h
+		languages.h
 		launcherdirs.h
 		jsonutils.h
 		updatedialog_moc.h

+ 1 - 1
launcher/firstLaunch/firstlaunch_moc.ui

@@ -140,7 +140,7 @@
    <item>
     <widget class="QStackedWidget" name="installerTabs">
      <property name="currentIndex">
-      <number>3</number>
+      <number>0</number>
      </property>
      <widget class="QWidget" name="pageLanguageSelect">
       <layout class="QGridLayout" name="gridLayout_3">

+ 94 - 0
launcher/languages.cpp

@@ -0,0 +1,94 @@
+/*
+ * languages.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#include "StdInc.h"
+#include "languages.h"
+
+#include "../lib/CConfigHandler.h"
+#include "../lib/Languages.h"
+
+#include <QComboBox>
+#include <QListWidget>
+
+// list of language names, for generation of translations. Do not use directly, use Languages namespace instead
+static const std::array<std::string, 11> languageTranslatedNamesGenerator = {
+	{
+		QT_TRANSLATE_NOOP("Language", "Chinese"),
+		QT_TRANSLATE_NOOP("Language", "English"),
+		QT_TRANSLATE_NOOP("Language", "French"),
+		QT_TRANSLATE_NOOP("Language", "German"),
+		QT_TRANSLATE_NOOP("Language", "Korean"),
+		QT_TRANSLATE_NOOP("Language", "Polish"),
+		QT_TRANSLATE_NOOP("Language", "Russian"),
+		QT_TRANSLATE_NOOP("Language", "Ukrainian"),
+		QT_TRANSLATE_NOOP("Language", "Other (East European)"),
+		QT_TRANSLATE_NOOP("Language", "Other (Cyrillic Script)"),
+		QT_TRANSLATE_NOOP("Language", "Other (West European)"),
+	 }
+};
+
+static_assert(languageTranslatedNamesGenerator.size() == static_cast<size_t>(Languages::ELanguages::COUNT), "Languages array is missing a value!");
+
+QString Languages::generateLanguageName(const Languages::Options & language)
+{
+	std::string activeLanguage = settings["general"]["language"].String();
+
+	QString localizedName = QApplication::translate("Language", language.nameEnglish.c_str());
+	QString nativeName = language.nameNative.c_str();
+
+	if(activeLanguage == language.identifier)
+		return nativeName;
+
+	if(!language.hasTranslation)
+		return localizedName;
+
+	QString displayName = QString("%1 (%2)").arg(localizedName, nativeName);
+
+	return displayName;
+}
+
+void Languages::fillLanguages(QComboBox * widget)
+{
+	widget->blockSignals(true); // we do not want calls caused by initialization
+	widget->clear();
+
+	std::string activeLanguage = settings["general"]["language"].String();
+
+	for(const auto & language : Languages::getLanguageList())
+	{
+		QString displayName = generateLanguageName(language);
+		QVariant userData = QString::fromStdString(language.identifier);
+
+		widget->addItem(displayName, userData);
+		if(activeLanguage == language.identifier)
+			widget->setCurrentIndex(widget->count() - 1);
+	}
+
+	widget->blockSignals(false);
+}
+
+void Languages::fillLanguages(QListWidget * widget)
+{
+	widget->blockSignals(true); // we do not want calls caused by initialization
+	widget->clear();
+
+	std::string activeLanguage = settings["general"]["language"].String();
+
+	for(const auto & language : Languages::getLanguageList())
+	{
+		QString displayName = generateLanguageName(language);
+		QVariant userData = QString::fromStdString(language.identifier);
+
+		widget->addItem(displayName);
+		widget->item(widget->count() - 1)->setData(Qt::UserRole, userData);
+		if(activeLanguage == language.identifier)
+			widget->setCurrentRow(widget->count() - 1);
+	}
+	widget->blockSignals(false);
+}

+ 28 - 0
launcher/languages.h

@@ -0,0 +1,28 @@
+/*
+ * languages.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#pragma once
+
+class QString;
+class QComboBox;
+class QListWidget;
+
+VCMI_LIB_NAMESPACE_BEGIN
+
+namespace Languages
+{
+	struct Options;
+
+	QString generateLanguageName(const Languages::Options & identifier);
+
+	void fillLanguages(QComboBox * widget);
+	void fillLanguages(QListWidget * widget);
+}
+
+VCMI_LIB_NAMESPACE_END

+ 2 - 2
launcher/mainwindow_moc.h

@@ -44,8 +44,8 @@ private:
 
 	void changeEvent(QEvent *event) override;
 public:
-	explicit MainWindow(QWidget * parent = 0);
-	~MainWindow();
+	explicit MainWindow(QWidget * parent = nullptr);
+	~MainWindow() override;
 
 	const CModList & getModList() const;
 

+ 8 - 20
launcher/settingsView/csettingsview_moc.cpp

@@ -14,6 +14,7 @@
 #include "mainwindow_moc.h"
 
 #include "../jsonutils.h"
+#include "../languages.h"
 #include "../launcherdirs.h"
 #include "../updatedialog_moc.h"
 
@@ -29,18 +30,6 @@ QString resolutionToString(const QSize & resolution)
 {
 	return QString{"%1x%2"}.arg(resolution.width()).arg(resolution.height());
 }
-}
-
-/// List of tags of languages that can be selected from Launcher (and have translation for Launcher)
-static const std::string languageTagList[] =
-{
-	"chinese",
-	"english",
-	"german",
-	"polish",
-	"russian",
-	"ukrainian",
-};
 
 static const std::string cursorTypesList[] =
 {
@@ -49,6 +38,8 @@ static const std::string cursorTypesList[] =
 	"software"
 };
 
+}
+
 void CSettingsView::setDisplayList()
 {
 	QStringList list;
@@ -105,10 +96,7 @@ void CSettingsView::loadSettings()
 
 	ui->comboBoxAutoSave->setCurrentIndex(settings["general"]["saveFrequency"].Integer() > 0 ? 1 : 0);
 
-	std::string language = settings["general"]["language"].String();
-	size_t languageIndex = boost::range::find(languageTagList, language) - languageTagList;
-	if(languageIndex < ui->comboBoxLanguage->count())
-		ui->comboBoxLanguage->setCurrentIndex((int)languageIndex);
+	Languages::fillLanguages(ui->comboBoxLanguage);
 
 	std::string cursorType = settings["video"]["cursor"].String();
 	size_t cursorTypeIndex = boost::range::find(cursorTypesList, cursorType) - cursorTypesList;
@@ -308,13 +296,13 @@ void CSettingsView::on_updatesButton_clicked()
 	UpdateDialog::showUpdateDialog(true);
 }
 
-
 void CSettingsView::on_comboBoxLanguage_currentIndexChanged(int index)
 {
 	Settings node = settings.write["general"]["language"];
-	node->String() = languageTagList[index];
+	QString selectedLanguage = ui->comboBoxLanguage->itemData(index).toString();
+	node->String() = selectedLanguage.toStdString();
 
-	if ( auto mainWindow = dynamic_cast<MainWindow*>(qApp->activeWindow()) )
+	if(auto * mainWindow = dynamic_cast<MainWindow *>(qApp->activeWindow()))
 		mainWindow->updateTranslation();
 }
 
@@ -323,6 +311,7 @@ void CSettingsView::changeEvent(QEvent *event)
 	if(event->type() == QEvent::LanguageChange)
 	{
 		ui->retranslateUi(this);
+		Languages::fillLanguages(ui->comboBoxLanguage);
 	}
 	QWidget::changeEvent(event);
 }
@@ -333,7 +322,6 @@ void CSettingsView::on_comboBoxCursorType_currentIndexChanged(int index)
 	node->String() = cursorTypesList[index];
 }
 
-
 void CSettingsView::on_listWidgetSettings_currentRowChanged(int currentRow)
 {
 	QVector<QWidget*> targetWidgets = {

+ 1 - 32
launcher/settingsView/csettingsview_moc.ui

@@ -509,38 +509,7 @@
         </widget>
        </item>
        <item row="1" column="1" colspan="3">
-        <widget class="QComboBox" name="comboBoxLanguage">
-         <item>
-          <property name="text">
-           <string>English</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>简体中文 (Simplified Chinese)</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>Deutsch (German)</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>Polska (Polish)</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>Русский (Russian)</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>Українська (Ukrainian)</string>
-          </property>
-         </item>
-        </widget>
+        <widget class="QComboBox" name="comboBoxLanguage"/>
        </item>
        <item row="16" column="0">
         <widget class="QLabel" name="labelDataDirs">

+ 20 - 10
lib/Languages.h

@@ -18,10 +18,16 @@ enum class ELanguages
 	ENGLISH,
 	FRENCH,
 	GERMAN,
+	KOREAN,
 	POLISH,
 	RUSSIAN,
 	UKRAINIAN,
 
+	// Pseudo-languages, that have no translations but can define H3 encoding to use
+	OTHER_CP1250,
+	OTHER_CP1251,
+	OTHER_CP1252,
+
 	COUNT
 };
 
@@ -46,34 +52,38 @@ struct Options
 	bool hasTranslation = false;
 };
 
-inline auto const & getLanguageList( )
+inline const auto & getLanguageList()
 {
-	static const std::array<Options, 7> languages
+	static const std::array<Options, 11> languages
 	{ {
-		{ "chinese",   "Chinese",   "简体中文",       "GBK",    true, true },
+		{ "chinese",   "Chinese",   "简体中文",       "GBK",    true,  true },
 		{ "english",   "English",   "English",    "CP1252", true,  true },
 		{ "french",    "French",    "Français",   "CP1252", true,  true },
 		{ "german",    "German",    "Deutsch",    "CP1252", true,  true },
-			//TODO: korean - CP949 encoding
+		{ "korean",    "Korean",    "한국어",        "CP949",  false, true },
 		{ "polish",    "Polish",    "Polski",     "CP1250", true,  true },
 		{ "russian",   "Russian",   "Русский",    "CP1251", true,  true },
-		{ "ukrainian", "Ukrainian", "Українська", "CP1251", true,  true }
+		{ "ukrainian", "Ukrainian", "Українська", "CP1251", true,  true },
+
+		{ "other_cp1250", "Other (East European)",   "", "CP1251", false, false },
+		{ "other_cp1251", "Other (Cyrillic Script)", "", "CP1250", false, false },
+		{ "other_cp1250", "Other (West European)",   "", "CP1252", false, false }
 	} };
-	static_assert (languages.size() == static_cast<size_t>(ELanguages::COUNT), "Languages array is missing a value!" );
+	static_assert(languages.size() == static_cast<size_t>(ELanguages::COUNT), "Languages array is missing a value!");
 
 	return languages;
 }
 
-inline const Options & getLanguageOptions( ELanguages language )
+inline const Options & getLanguageOptions(ELanguages language)
 {
 	assert(language < ELanguages::COUNT);
 	return getLanguageList()[static_cast<size_t>(language)];
 }
 
-inline const Options & getLanguageOptions( std::string language )
+inline const Options & getLanguageOptions(const std::string & language)
 {
-	for (auto const & entry : getLanguageList())
-		if (entry.identifier == language)
+	for(const auto & entry : getLanguageList())
+		if(entry.identifier == language)
 			return entry;
 
 	static const Options emptyValue;