Skip to content

Commit 39f010c

Browse files
feat: integrate keyboard layout module and enhance configuration
- Added KeyboardController to manage keyboard layout settings - Updated CMakeLists.txt to include necessary files and dependencies - Introduced new KeyboardLayoutModule in QML for advanced settings Log: integrate keyboard layout management into the configuration tool https://pms.uniontech.com/story-view-39439
1 parent 7572915 commit 39f010c

30 files changed

Lines changed: 4283 additions & 0 deletions

src/dcc-fcitx5configtool/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,24 @@ find_package(Qt${QT_DESIRED_VERSION} COMPONENTS Core Gui DBus LinguistTools Qml
1717
find_package(DdeControlCenter REQUIRED)
1818
find_package(Dtk${DTK_VERSION_MAJOR} COMPONENTS Core REQUIRED)
1919
find_package(PkgConfig REQUIRED)
20+
find_package(PolkitQt6-1 REQUIRED)
21+
find_package(PkgConfig REQUIRED)
22+
pkg_check_modules(ICU REQUIRED icu-uc icu-i18n)
2023

2124

2225
set(DccFcitx5configtool_Name fcitx5configtool)
2326
file(GLOB_RECURSE DccFcitx5configtool_SRCS
2427
"operation/qrc/*.qrc"
28+
"keyboard-layout/operation/qrc/*.qrc"
2529
"*.cpp"
2630
"*.h"
31+
"*.qml"
2732
"private/*.h"
2833
"operation/*.cpp"
2934
"operation/*.h"
35+
"keyboard-layout/operation/*.cpp"
36+
"keyboard-layout/operation/*.h"
37+
"keyboard-layout/qml/*.qml"
3038
)
3139

3240
add_library(${DccFcitx5configtool_Name} MODULE
@@ -37,6 +45,8 @@ target_include_directories(${DccFcitx5configtool_Name} PUBLIC
3745
Dde::Control-Center
3846
configlib${QT_DESIRED_VERSION}
3947
configwidgetslib${QT_DESIRED_VERSION}
48+
keyboard-layout/operation
49+
${ICU_INCLUDE_DIRS}
4050
)
4151

4252
set(DccFcitx5configtool_Libraries
@@ -45,6 +55,8 @@ set(DccFcitx5configtool_Libraries
4555
Qt${QT_DESIRED_VERSION}::Qml
4656
Dtk${DTK_VERSION_MAJOR}::Core
4757
Dde::Control-Center
58+
PolkitQt6-1::Agent
59+
${ICU_LIBRARIES}
4860
)
4961

5062
target_link_libraries(${DccFcitx5configtool_Name} PRIVATE
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// SPDX-FileCopyrightText: 2024 - 2027 UnionTech Software Technology Co., Ltd.
2+
//
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
#ifndef DCCFACTORY_H
5+
#define DCCFACTORY_H
6+
7+
#include <QObject>
8+
9+
namespace dccV25 {
10+
#define DccFactory_iid "org.deepin.dde.dcc-factory/v1.0"
11+
class DccObject;
12+
13+
class DccFactory : public QObject
14+
{
15+
Q_OBJECT
16+
public:
17+
using QObject::QObject;
18+
19+
// 作为数据返回,会导出为dccData供main.qml使用
20+
virtual QObject *create(QObject * = nullptr) { return nullptr; }
21+
22+
// 未提供qml的,可在此自己加载qml返回DccObject对象
23+
virtual DccObject *dccObject(QObject * = nullptr) { return nullptr; }
24+
};
25+
} // namespace dccV25
26+
Q_DECLARE_INTERFACE(dccV25::DccFactory, DccFactory_iid)
27+
28+
#define DCC_FACTORY_CLASS(classname) \
29+
namespace { \
30+
class Q_DECL_EXPORT classname##DccFactory : public dccV25::DccFactory \
31+
{ \
32+
Q_OBJECT \
33+
Q_PLUGIN_METADATA(IID DccFactory_iid) \
34+
Q_INTERFACES(dccV25::DccFactory) \
35+
public: \
36+
using dccV25::DccFactory::DccFactory; \
37+
QObject *create(QObject *parent = nullptr) override \
38+
{ \
39+
return new classname(parent); \
40+
} \
41+
}; \
42+
}
43+
#endif // DCCFACTORY_H
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
2+
//
3+
//SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
#include "dcclocale.h"
6+
7+
#include <QCoreApplication>
8+
#include <QGlobalStatic>
9+
#include <QLocale>
10+
#include <memory>
11+
12+
#include <unicode/locdspnm.h>
13+
14+
using namespace icu;
15+
using namespace Qt::Literals::StringLiterals;
16+
17+
namespace {
18+
// Cache LocaleDisplayNames instance
19+
struct DisplayNamesHolder {
20+
DisplayNamesHolder()
21+
: displayNames(icu::LocaleDisplayNames::createInstance(
22+
icu::Locale::getDefault(), ULDN_DIALECT_NAMES)) {}
23+
24+
std::unique_ptr<icu::LocaleDisplayNames> displayNames;
25+
};
26+
27+
Q_GLOBAL_STATIC(DisplayNamesHolder, globalDisplayNames);
28+
29+
icu::LocaleDisplayNames* getDisplayNames() {
30+
return globalDisplayNames()->displayNames.get();
31+
}
32+
33+
[[maybe_unused]] icu::UnicodeString fromQString(const QString& qstr) {
34+
return icu::UnicodeString(qstr.utf16(), qstr.length());
35+
}
36+
37+
QString toQString(const icu::UnicodeString& icuString) {
38+
// Get a pointer to the internal UTF-16 buffer of the icu::UnicodeString.
39+
// The buffer is not necessarily null-terminated, so we also need the length.
40+
const UChar* ucharData = icuString.getBuffer();
41+
int32_t length = icuString.length();
42+
43+
// QString has a constructor that takes a const QChar* and a length.
44+
// UChar is typically a 16-bit unsigned integer, which is compatible with QChar.
45+
// Static_cast is used here for explicit type conversion, though often
46+
// UChar and QChar are typedefs to the same underlying type (e.g., unsigned short).
47+
return QString(reinterpret_cast<const QChar*>(ucharData), length);
48+
}
49+
}
50+
51+
QStringList DCCLocale::dialectNames(const QStringList &localeCodes)
52+
{
53+
QStringList results;
54+
results.reserve(localeCodes.size()); // 预分配空间
55+
56+
icu::LocaleDisplayNames* displayNames = getDisplayNames();
57+
58+
for (const QString &localeCode : std::as_const(localeCodes)) {
59+
// locale code might contain something like @latin, we need to remove such suffix
60+
QString localeCodeWithoutSuffix = localeCode.split("@").first();
61+
if (localeCode.startsWith("zh_HK")) {
62+
results.append(QCoreApplication::translate("dcc::Locale::dialectNames", "Traditional Chinese (Chinese Hong Kong)"));
63+
continue;
64+
} else if (localeCode.startsWith("zh_TW")) {
65+
results.append(QCoreApplication::translate("dcc::Locale::dialectNames", "Traditional Chinese (Chinese Taiwan)"));
66+
continue;
67+
}
68+
69+
icu::UnicodeString dialectName;
70+
displayNames->localeDisplayName(localeCodeWithoutSuffix.toLatin1().constData(), dialectName);
71+
results.append(toQString(dialectName));
72+
}
73+
return results;
74+
}
75+
76+
QPair<QString, QString> DCCLocale::languageAndRegionName(const QString &localeCode)
77+
{
78+
const icu::Locale& systemLocale = icu::Locale::getDefault();
79+
icu::UnicodeString localeUString;
80+
icu::Locale icuLocale(localeCode.toLatin1().constData());
81+
auto regionCode = QString(icuLocale.getCountry());
82+
QString displayLanguage = toQString(icuLocale.getDisplayLanguage(systemLocale, localeUString));
83+
QString displayCountry = toQString(icuLocale.getDisplayCountry(systemLocale, localeUString));
84+
85+
if (regionCode == u"TW"_s) {
86+
displayCountry = QCoreApplication::translate("dcc::Locale::regionNames", "Taiwan China");
87+
}
88+
89+
return { displayLanguage, displayCountry };
90+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
2+
//
3+
//SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
#pragma once
6+
7+
#include <QString>
8+
#include <QStringList>
9+
#include <QTranslator>
10+
11+
class DCCLocale
12+
{
13+
public:
14+
//! Get the dialect names of the given \a languageCodes in current system locale.
15+
static QStringList dialectNames(const QStringList &localeCodes);
16+
static QPair<QString, QString> languageAndRegionName(const QString &localeName);
17+
};

0 commit comments

Comments
 (0)