ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvTranslationManager.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <QActionGroup>
11 #include <QDebug>
12 #include <QDir>
13 #include <QGlobalStatic>
14 #include <QMessageBox>
15 #include <QRegularExpression>
16 #include <QSettings>
17 #include <QTranslator>
18 
19 #include "ecvApplicationBase.h"
20 
22 }; // trick for Q_GLOBAL_STATIC to access constructor
23 Q_GLOBAL_STATIC(_ccTranslationManager, sTranslationmanager)
24 
26  return *sTranslationmanager;
27 }
28 
30  const QString &path) {
31  mTranslatorFileInfo.append({prefix, path});
32 }
33 
35  const QLocale locale(languagePref());
36 
37  const auto &info = mTranslatorFileInfo;
38 
39  for (const auto &fileInfo : info) {
40  auto translator = new QTranslator(ecvApp);
41 
42  bool loaded = translator->load(locale, fileInfo.prefix,
43  QStringLiteral("_"), fileInfo.path);
44 
45  if (loaded) {
46  ecvApp->installTranslator(translator);
47  } else {
48  delete translator;
49  }
50  }
51 }
52 
53 void ccTranslationManager::loadTranslation(QString language) {
54  const QLocale locale(language);
55 
56  const auto &info = mTranslatorFileInfo;
57 
58  for (const auto &fileInfo : info) {
59  auto translator = new QTranslator(ecvApp);
60 
61  bool loaded = translator->load(locale, fileInfo.prefix,
62  QStringLiteral("_"), fileInfo.path);
63 
64  if (loaded) {
65  ecvApp->installTranslator(translator);
66  } else {
67  delete translator;
68  }
69  }
70 }
71 
73  const QString &pathToTranslationFiles) {
74  const LanguageList cList = availableLanguages(
75  QStringLiteral("ACloudViewer"), pathToTranslationFiles);
76 
77  QActionGroup *group = new QActionGroup(menu);
78 
79  group->setExclusive(true);
80 
81  QAction *action = group->addAction(tr("No Translation (English)"));
82 
83  action->setCheckable(true);
84  action->setChecked(true);
85 
86  connect(action, &QAction::triggered, this,
87  [this]() { setLanguagePref(QStringLiteral("en")); });
88 
89  QAction *separator = new QAction(group);
90  separator->setSeparator(true);
91 
92  const QString currentLanguage = languagePref();
93 
94  for (auto &langInfo : cList) {
95  action = group->addAction(langInfo.second);
96 
97  action->setCheckable(true);
98 
99  if (currentLanguage == langInfo.first) {
100  action->setChecked(true);
101  }
102 
103  connect(action, &QAction::triggered, this,
104  [=]() { setLanguagePref(langInfo.first); });
105  }
106 
107  menu->addActions(group->actions());
108 }
109 
110 const QString ccTranslationManager::languagePref() {
111  QSettings settings;
112 
113  settings.beginGroup("Translation");
114 
115  const QString langCode =
116  settings.value(QStringLiteral("Language")).toString();
117 
118  settings.endGroup();
119 
120  return langCode;
121 }
122 
123 ccTranslationManager::LanguageList ccTranslationManager::availableLanguages(
124  const QString &appName, const QString &pathToTranslationFiles) {
125  LanguageList theList;
126 
127  QDir dir(pathToTranslationFiles);
128 
129  const QString cFilter = QStringLiteral("%1_*.qm").arg(appName);
130  const QStringList cFileNames = dir.entryList({cFilter});
131 
132  QRegularExpression regExp(
133  QStringLiteral("%1_(?<langCode>.{2}).*.qm").arg(appName));
134 
135  regExp.optimize();
136 
137  for (const auto &cFileName : cFileNames) {
138  QRegularExpressionMatch match = regExp.match(cFileName);
139 
140  if (!match.hasMatch()) {
141  continue;
142  }
143 
144  const QString cLangCode(match.captured(QStringLiteral("langCode")));
145 
146  QString language(QLocale(cLangCode).nativeLanguageName());
147 
148  if (language.isEmpty()) {
149  qWarning() << "Language not found for translation file"
150  << cFileName;
151  continue;
152  }
153 
154  language = language.at(0).toUpper() + language.mid(1);
155 
156  theList += {cLangCode, language};
157  }
158 
159  return theList;
160 }
161 
162 void ccTranslationManager::setLanguagePref(const QString &languageCode) {
163  if (languageCode == languagePref()) {
164  return;
165  }
166 
167  QSettings settings;
168 
169  settings.beginGroup("Translation");
170 
171  settings.setValue(QStringLiteral("Language"), languageCode);
172 
173  settings.endGroup();
174 
175  QMessageBox::information(nullptr, tr("Language Change"),
176  tr("Language change will take effect when "
177  "ACloudViewer is restarted"));
178 }
void populateMenu(QMenu *menu, const QString &pathToTranslationFiles)
void loadTranslation(QString language)
void registerTranslatorFile(const QString &prefix, const QString &path)
#define ecvApp
Mimic Qt's qApp for easy access to the application instance.
Q_GLOBAL_STATIC(PrivatePluginManager, sPluginManager)
static const std::string path
Definition: PointCloud.cpp:59