From dc68e630fe207f2d69b22fb202790e64b0292504 Mon Sep 17 00:00:00 2001 From: alanwang Date: Thu, 30 Oct 2025 04:12:35 +0800 Subject: [PATCH 1/6] Fix macOS locale detection for Chinese language support This commit resolves the issue where the Qt application would default to English instead of Chinese when launched from Finder on macOS, even when the system language is set to Chinese. Key changes: - Added macOS-specific locale detection when environment variables are empty - Implemented fallback to Chinese locale when launched from Finder - Added support for user locale preference file (~/.android-file-transfer-locale-prefs) - Enhanced translation loading with multiple format support (zh_CN, zh-CN, zh) - Added proper locale format handling for macOS vs translation file naming Technical details: - Uses #ifdef Q_OS_MACOS to ensure Linux compatibility - Detects when LANG/LC_ALL environment variables are empty (Finder launch) - Auto-detects Chinese locale if zh_CN translation is available - Supports user preference override via preference file - Implements fallback: localeName -> hyphen format -> language code Testing: - Verified Chinese language loads correctly from Finder - Confirmed existing command-line behavior is preserved - Tested preference file functionality - Ensured Linux systems are unaffected by macOS-specific changes --- .gitignore | 4 + qt/main.cpp | 79 ++++++++++++++++++- .../android-file-transfer-linux_zh-CN.ts | 2 +- 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 007b02d8..f998d2dd 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,7 @@ build *.user doc .vscode + +# AI doc +GEMINI.md +IFLOW.md \ No newline at end of file diff --git a/qt/main.cpp b/qt/main.cpp index 4a70feb2..e847284c 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #include #if QT_VERSION >= 0x050000 # include @@ -54,6 +57,30 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); Q_INIT_RESOURCE(android_file_transfer); + +#ifdef Q_OS_MACOS + // On macOS, when launched from Finder, environment variables are often not set + // This causes QLocale::system() to default to en_US even if system language is Chinese + if (qgetenv("LANG").isEmpty() && qgetenv("LC_ALL").isEmpty()) { + // Check if user has a locale preference file, otherwise default to detecting from available translations + QFile prefsFile(QDir::home().filePath(".android-file-transfer-locale-prefs")); + if (prefsFile.exists() && prefsFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&prefsFile); + QString preferredLocale = in.readLine().trimmed(); + if (!preferredLocale.isEmpty()) { + qputenv("LANG", preferredLocale.toUtf8()); + qputenv("LC_ALL", preferredLocale.toUtf8()); + } + prefsFile.close(); + } else { + // Auto-detect Chinese locale if available - this is the most common case for Chinese users + if (QFile::exists(":/android-file-transfer-linux_zh_CN")) { + qputenv("LANG", "zh_CN.UTF-8"); + qputenv("LC_ALL", "zh_CN.UTF-8"); + } + } + } +#endif QCoreApplication::setApplicationName("aft-linux-qt"); QCoreApplication::setOrganizationDomain("whoozle.github.io"); @@ -64,14 +91,60 @@ int main(int argc, char *argv[]) #endif QTranslator qtTranslator; + QString localeName = QLocale::system().name(); + +#ifdef Q_OS_MACOS + // On macOS, check for user preference file first + QFile prefsFile(QDir::home().filePath(".android-file-transfer-locale-prefs")); + if (prefsFile.exists() && prefsFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&prefsFile); + QString preferredLocale = in.readLine().trimmed(); + if (!preferredLocale.isEmpty()) { + // Extract just the locale part (e.g., "zh_CN.UTF-8" -> "zh_CN") + localeName = preferredLocale.split(".").first(); + } + prefsFile.close(); + } else if (qgetenv("LANG").isEmpty() && qgetenv("LC_ALL").isEmpty()) { + // When launched from Finder with no preference file, auto-detect Chinese + if (QFile::exists(":/android-file-transfer-linux_zh_CN")) { + localeName = "zh_CN"; + } + } +#endif - qtTranslator.load("qt_" + QLocale::system().name(), + qtTranslator.load("qt_" + localeName, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); app.installTranslator(&qtTranslator); QTranslator aTranslator; - aTranslator.load(":/android-file-transfer-linux_" + QLocale::system().name()); - app.installTranslator(&aTranslator); + + // Try to load translation with multiple fallback strategies + bool translationLoaded = false; + QStringList localeAttempts; + + // Add all possible locale formats to try + localeAttempts << localeName; // Original: "zh_CN" + localeAttempts << localeName.replace("_", "-"); // Hyphen: "zh-CN" + localeAttempts << localeName.split("-").first().split("_").first(); // Language only: "zh" + + // Also try some common variations for Chinese + if (localeName.startsWith("zh")) { + localeAttempts << "zh-CN"; // Simplified Chinese + localeAttempts << "zh-TW"; // Traditional Chinese + localeAttempts << "zh_CN"; // Underscore variant + } + + for (const QString& attempt : localeAttempts) { + QString resourcePath = ":/android-file-transfer-linux_" + attempt; + if (aTranslator.load(resourcePath)) { + translationLoaded = true; + break; + } + } + + if (translationLoaded) { + app.installTranslator(&aTranslator); + } MainWindow w; diff --git a/qt/translations/android-file-transfer-linux_zh-CN.ts b/qt/translations/android-file-transfer-linux_zh-CN.ts index 9453253a..9dbed3cc 100644 --- a/qt/translations/android-file-transfer-linux_zh-CN.ts +++ b/qt/translations/android-file-transfer-linux_zh-CN.ts @@ -1,4 +1,4 @@ - + From 0c70f632ef8909a854594ed32750b97c65cca367 Mon Sep 17 00:00:00 2001 From: alanwang Date: Thu, 30 Oct 2025 04:23:39 +0800 Subject: [PATCH 2/6] fix not in chinese environment --- qt/main.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/qt/main.cpp b/qt/main.cpp index e847284c..868879a5 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) // On macOS, when launched from Finder, environment variables are often not set // This causes QLocale::system() to default to en_US even if system language is Chinese if (qgetenv("LANG").isEmpty() && qgetenv("LC_ALL").isEmpty()) { - // Check if user has a locale preference file, otherwise default to detecting from available translations + // Check if user has a locale preference file first QFile prefsFile(QDir::home().filePath(".android-file-transfer-locale-prefs")); if (prefsFile.exists() && prefsFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&prefsFile); @@ -72,13 +72,9 @@ int main(int argc, char *argv[]) qputenv("LC_ALL", preferredLocale.toUtf8()); } prefsFile.close(); - } else { - // Auto-detect Chinese locale if available - this is the most common case for Chinese users - if (QFile::exists(":/android-file-transfer-linux_zh_CN")) { - qputenv("LANG", "zh_CN.UTF-8"); - qputenv("LC_ALL", "zh_CN.UTF-8"); - } } + // If no preference file, let Qt detect system locale naturally + // Don't force any specific language - let the fallback mechanism handle it } #endif @@ -104,12 +100,9 @@ int main(int argc, char *argv[]) localeName = preferredLocale.split(".").first(); } prefsFile.close(); - } else if (qgetenv("LANG").isEmpty() && qgetenv("LC_ALL").isEmpty()) { - // When launched from Finder with no preference file, auto-detect Chinese - if (QFile::exists(":/android-file-transfer-linux_zh_CN")) { - localeName = "zh_CN"; - } } + // Note: When launched from Finder with no preference file, we let Qt detect system locale naturally + // The fallback mechanism in translation loading will handle unknown languages #endif qtTranslator.load("qt_" + localeName, From 100a5b7c78417be6176f168a795c8ac1728318e4 Mon Sep 17 00:00:00 2001 From: iFlow CLI Date: Tue, 4 Nov 2025 03:35:28 +0800 Subject: [PATCH 3/6] Replace locale preference file with system language detection on macOS --- qt/main.cpp | 70 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/qt/main.cpp b/qt/main.cpp index 868879a5..cc7cf221 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #if QT_VERSION >= 0x050000 # include @@ -58,25 +60,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); Q_INIT_RESOURCE(android_file_transfer); -#ifdef Q_OS_MACOS - // On macOS, when launched from Finder, environment variables are often not set - // This causes QLocale::system() to default to en_US even if system language is Chinese - if (qgetenv("LANG").isEmpty() && qgetenv("LC_ALL").isEmpty()) { - // Check if user has a locale preference file first - QFile prefsFile(QDir::home().filePath(".android-file-transfer-locale-prefs")); - if (prefsFile.exists() && prefsFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - QTextStream in(&prefsFile); - QString preferredLocale = in.readLine().trimmed(); - if (!preferredLocale.isEmpty()) { - qputenv("LANG", preferredLocale.toUtf8()); - qputenv("LC_ALL", preferredLocale.toUtf8()); - } - prefsFile.close(); - } - // If no preference file, let Qt detect system locale naturally - // Don't force any specific language - let the fallback mechanism handle it - } -#endif + QCoreApplication::setApplicationName("aft-linux-qt"); QCoreApplication::setOrganizationDomain("whoozle.github.io"); @@ -90,20 +74,46 @@ int main(int argc, char *argv[]) QString localeName = QLocale::system().name(); #ifdef Q_OS_MACOS - // On macOS, check for user preference file first - QFile prefsFile(QDir::home().filePath(".android-file-transfer-locale-prefs")); - if (prefsFile.exists() && prefsFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - QTextStream in(&prefsFile); - QString preferredLocale = in.readLine().trimmed(); - if (!preferredLocale.isEmpty()) { - // Extract just the locale part (e.g., "zh_CN.UTF-8" -> "zh_CN") - localeName = preferredLocale.split(".").first(); + // On macOS, when launched from Finder, environment variables are often not set + // This causes QLocale::system() to default to en_US even if system language is Chinese + // Try to detect the actual system language using multiple methods + if (qgetenv("LANG").isEmpty() && qgetenv("LC_ALL").isEmpty()) { + // Method 1: Try to get system language using macOS-specific commands + QProcess process; + process.start("defaults", QStringList() << "read" << "NSGlobalDomain" << "AppleLocale"); + process.waitForFinished(1000); + QString output = process.readAllStandardOutput().trimmed(); + if (!output.isEmpty() && output != "\"en_US\"") { + // Remove quotes and convert to Qt locale format + output = output.remove("\""); + localeName = output; + } else { + // Method 2: Try to get language from system preferences + process.start("defaults", QStringList() << "read" << "NSGlobalDomain" << "AppleLanguages"); + process.waitForFinished(1000); + output = process.readAllStandardOutput().trimmed(); + if (!output.isEmpty()) { + // Parse array format like ( "zh-Hans-CN", "en" ) + QRegularExpression re("\"([^\"]+)\""); + QRegularExpressionMatch match = re.match(output); + if (match.hasMatch()) { + QString lang = match.captured(1); + // Convert macOS format to Qt format + if (lang.startsWith("zh-Hans")) { + localeName = "zh_CN"; + } else if (lang.startsWith("zh-Hant")) { + localeName = "zh_TW"; + } else { + // Extract first two characters for language code + localeName = lang.left(2); + } + } + } } - prefsFile.close(); } - // Note: When launched from Finder with no preference file, we let Qt detect system locale naturally - // The fallback mechanism in translation loading will handle unknown languages #endif + + qtTranslator.load("qt_" + localeName, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); From e127b11720be23c744cd5febc54ff845759a3e23 Mon Sep 17 00:00:00 2001 From: iFlow CLI Date: Tue, 4 Nov 2025 03:37:48 +0800 Subject: [PATCH 4/6] Revert gitignore changes --- .gitignore | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index f998d2dd..31f9282b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,4 @@ nbproject build *.user doc -.vscode - -# AI doc -GEMINI.md -IFLOW.md \ No newline at end of file +.vscode \ No newline at end of file From 6d4be048b31f9f853cb7f63769a474c4878fc005 Mon Sep 17 00:00:00 2001 From: iFlow CLI Date: Tue, 4 Nov 2025 03:47:00 +0800 Subject: [PATCH 5/6] Revert encoding format change in zh-CN.ts file --- qt/translations/android-file-transfer-linux_zh-CN.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/translations/android-file-transfer-linux_zh-CN.ts b/qt/translations/android-file-transfer-linux_zh-CN.ts index 9dbed3cc..9453253a 100644 --- a/qt/translations/android-file-transfer-linux_zh-CN.ts +++ b/qt/translations/android-file-transfer-linux_zh-CN.ts @@ -1,4 +1,4 @@ - + From 69f8545a94c788713eab9e08c54968774a5506be Mon Sep 17 00:00:00 2001 From: iFlow CLI Date: Tue, 4 Nov 2025 03:50:31 +0800 Subject: [PATCH 6/6] Revert AI doc entries from .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 31f9282b..007b02d8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ nbproject build *.user doc -.vscode \ No newline at end of file +.vscode