Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 21 additions & 29 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,42 +94,34 @@ int showErrorUpdatingTheDB()

void loadTranslations(QApplication &app, QTranslator &myappTranslator)
{
// Detect UI language.
// On macOS, QLocale::system().name() returns the regional-format locale
// (e.g. "en_US") which may differ from the display language set in
// System Preferences. uiLanguages() reads AppleLanguages and is
// reliable on all platforms.
QString language;
QStringList uiLangs = QLocale::system().uiLanguages();
if (!uiLangs.isEmpty())
language = uiLangs.first().left(2).toLower();
else
language = QLocale::system().name().left(2).toLower();
Utilities util(Q_FUNC_INFO);

// The user may have selected a fixed language in the Language menu.
// "auto" (the default) follows the operating system language.
QSettings settings(util.getCfgFile(), QSettings::IniFormat);
QString language = settings.value("Language", "auto").toString().toLower();

if ((language == "auto") || language.isEmpty())
{
// Detect UI language.
// On macOS, QLocale::system().name() returns the regional-format locale
// (e.g. "en_US") which may differ from the display language set in
// System Preferences. uiLanguages() reads AppleLanguages and is
// reliable on all platforms.
QStringList uiLangs = QLocale::system().uiLanguages();
if (!uiLangs.isEmpty())
language = uiLangs.first().left(2).toLower();
else
language = QLocale::system().name().left(2).toLower();
}

//qDebug() << Q_FUNC_INFO << "Language:" << language;

if (language == "en")
return; // English is built-in; no translation file needed.

QString fileName = "klog_" + language + ".qm";
QStringList searchPaths;

#if defined(Q_OS_MACOS)
// .app bundle: KLog.app/Contents/Resources/translations/
// (CMakeLists: MACOSX_PACKAGE_LOCATION Resources/translations)
searchPaths << QCoreApplication::applicationDirPath() + "/../Resources/translations";
#elif defined(Q_OS_WIN)
// Alongside the .exe (CMakeLists: DESTINATION translations)
searchPaths << QCoreApplication::applicationDirPath() + "/translations";
#else
// Linux FHS (CMakeLists: DESTINATION ${CMAKE_INSTALL_DATADIR}/klog/translations)
searchPaths << QCoreApplication::applicationDirPath() + "/../share/klog/translations";
searchPaths << "/usr/share/klog/translations";
searchPaths << "/usr/local/share/klog/translations";
#endif
// Fallback for development builds on every platform
searchPaths << QCoreApplication::applicationDirPath() + "/translations";
searchPaths << QCoreApplication::applicationDirPath() + "/../src/translations";
const QStringList searchPaths = util.getTranslationSearchPaths();

for (const QString &dir : searchPaths)
{
Expand Down
32 changes: 32 additions & 0 deletions src/setuppages/setuppageuserdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,22 @@
provinceLineEdit = new QLineEdit;
countryLineEdit = new QLineEdit;

languageComboBox = new QComboBox;

Check failure on line 70 in src/setuppages/setuppageuserdata.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace the use of "new" with an operation that automatically manages the memory.

See more on https://sonarcloud.io/project/issues?id=ea4k_klog&issues=AZ7AJFLSGmv_3eIbQ6X_&open=AZ7AJFLSGmv_3eIbQ6X_&pullRequest=1032

Check warning on line 70 in src/setuppages/setuppageuserdata.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not assign data members in a constructor. Initialize member "languageComboBox" in an initialization list.

See more on https://sonarcloud.io/project/issues?id=ea4k_klog&issues=AZ7AJFLSGmv_3eIbQ6X9&open=AZ7AJFLSGmv_3eIbQ6X9&pullRequest=1032
languageComboBox->addItem(tr("System default"), "auto");
const QStringList languages = util->getAvailableLanguages();
for (const QString &code : languages)
{
QLocale langLocale(code);
QString langName = langLocale.nativeLanguageName();
if (langName.isEmpty())
langName = code;
else
langName[0] = langName.at(0).toUpper();
languageComboBox->addItem(langName, code);
}

nameLineEdit->setToolTip(tr("Enter your name."));
languageComboBox->setToolTip(tr("Select the language of the KLog user interface. 'System default' uses the language of the operating system."));
address1LineEdit->setToolTip(tr("Enter your address - 1st line."));
address2LineEdit->setToolTip(tr("Enter your address - 2nd line."));
address3LineEdit->setToolTip(tr("Enter your address - 3rd line."));
Expand All @@ -78,13 +93,15 @@
countryLineEdit->setToolTip(tr("Enter your country."));

QLabel *nameLabel = new QLabel(tr("&Name"));
QLabel *languageLabel = new QLabel(tr("Lang&uage"));

Check warning on line 96 in src/setuppages/setuppageuserdata.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace the redundant type with "auto".

See more on https://sonarcloud.io/project/issues?id=ea4k_klog&issues=AZ7AJFLSGmv_3eIbQ6X-&open=AZ7AJFLSGmv_3eIbQ6X-&pullRequest=1032

Check failure on line 96 in src/setuppages/setuppageuserdata.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace the use of "new" with an operation that automatically manages the memory.

See more on https://sonarcloud.io/project/issues?id=ea4k_klog&issues=AZ7AJFLSGmv_3eIbQ6YA&open=AZ7AJFLSGmv_3eIbQ6YA&pullRequest=1032
QLabel *addressLabel = new QLabel(tr("&Address"));
QLabel *cityLabel = new QLabel(tr("Cit&y"));
QLabel *zipLabel = new QLabel(tr("&Zip Code"));
QLabel *provLabel = new QLabel(tr("Pro&v/State"));
QLabel *countryLabel = new QLabel(tr("Countr&y"));

nameLabel->setBuddy(nameLineEdit);
languageLabel->setBuddy(languageComboBox);
addressLabel->setBuddy(address1LineEdit);
cityLabel->setBuddy(cityLineEdit);
zipLabel->setBuddy(zipLineEdit);
Expand All @@ -98,6 +115,8 @@

personalLayout->addWidget(nameLabel, 0, 0);
personalLayout->addWidget(nameLineEdit, 1, 0);
personalLayout->addWidget(languageLabel, 0, 2);
personalLayout->addWidget(languageComboBox, 1, 2);
personalLayout->addWidget(addressLabel, 2, 0);
personalLayout->addWidget(address1LineEdit, 3, 0, 1, 2);
personalLayout->addWidget(address2LineEdit, 4, 0, 1, 2);
Expand Down Expand Up @@ -717,6 +736,15 @@
settings.setValue ("Antenna3",getAntenna3());
settings.setValue ("Power", getPower ());
settings.endGroup ();

// The language is a top level setting as it is read in main.cpp before the UI exists.
QString newLanguage = languageComboBox->currentData().toString();
if (settings.value("Language", "auto").toString().toLower() != newLanguage)
{
settings.setValue("Language", newLanguage);
QMessageBox::information(this, tr("KLog - Language"),
tr("The language change will take effect the next time you start KLog."));
}
//qDebug() << Q_FUNC_INFO << " - END";
}

Expand Down Expand Up @@ -748,4 +776,8 @@
ant3LineEdit->setText (settings.value ("Antenna3").toString ());
myPowerSpinBox->setValue(settings.value ("Power").toDouble ());
settings.endGroup ();

// The language is a top level setting as it is read in main.cpp before the UI exists.
int langIndex = languageComboBox->findData(settings.value("Language", "auto").toString().toLower());
languageComboBox->setCurrentIndex(qMax(0, langIndex));
}
1 change: 1 addition & 0 deletions src/setuppages/setuppageuserdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ private slots:

//Personal Tab
QLineEdit *nameLineEdit;
QComboBox *languageComboBox;
QTextEdit *addressTextEdit;
QLineEdit *address1LineEdit;
QLineEdit *address2LineEdit;
Expand Down
46 changes: 46 additions & 0 deletions src/utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include "utilities.h"
#include "callsign.h"
#include <QRegularExpression>
// Qt headers are not in cppcheck's include path on the CI; silence the false positive.
// cppcheck-suppress missingIncludeSystem
#include <QCoreApplication>
//bool c;
Utilities::Utilities(const QString &_parentName)
{
Expand Down Expand Up @@ -583,6 +586,49 @@ QString Utilities::getCfgFile()
#endif
}

QStringList Utilities::getTranslationSearchPaths()
{
QStringList searchPaths;
#if defined(Q_OS_MACOS)
// .app bundle: KLog.app/Contents/Resources/translations/
// (CMakeLists: MACOSX_PACKAGE_LOCATION Resources/translations)
searchPaths << QCoreApplication::applicationDirPath() + "/../Resources/translations";
#elif defined(Q_OS_WIN)
// Alongside the .exe (CMakeLists: DESTINATION translations)
searchPaths << QCoreApplication::applicationDirPath() + "/translations";
#else
// Linux FHS (CMakeLists: DESTINATION ${CMAKE_INSTALL_DATADIR}/klog/translations)
searchPaths << QCoreApplication::applicationDirPath() + "/../share/klog/translations";
searchPaths << "/usr/share/klog/translations";
searchPaths << "/usr/local/share/klog/translations";
#endif
// Fallback for development builds on every platform
searchPaths << QCoreApplication::applicationDirPath() + "/translations";
searchPaths << QCoreApplication::applicationDirPath() + "/../src/translations";
// qt_add_translations generates the .qm files in <build>/src in development builds
searchPaths << QCoreApplication::applicationDirPath() + "/../src";
return searchPaths;
}

QStringList Utilities::getAvailableLanguages()
{
QStringList languages;
languages << "en"; // English is built-in; no translation file needed.
const QStringList paths = getTranslationSearchPaths();
for (const QString &dir : paths)
{
const QStringList files = QDir(dir).entryList(QStringList("klog_*.qm"), QDir::Files);
for (const QString &file : files)
{ // klog_<code>.qm
QString code = file.mid(5, file.length() - 8).toLower();
if (!code.isEmpty() && !languages.contains(code))
languages << code;
}
}
languages.sort();
return languages;
}

QString Utilities::getDebugLogFile()
{
#if defined(Q_OS_WIN)
Expand Down
2 changes: 2 additions & 0 deletions src/utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class Utilities : public QObject {
QString getTQSLsPath(); // Depending on the OS where are usually installed the executables
QString getHomeDir();
QString getCfgFile();
QStringList getTranslationSearchPaths(); // Folders where the klog_*.qm files may be installed
QStringList getAvailableLanguages(); // 2-letter codes of the languages with a translation installed (plus built-in English)
QString getCTYFile();
QString getDebugLogFile();
QString getSaveSpotsLogFile();
Expand Down
Loading