Commit 04cc37d2 authored by Weng Xuetian's avatar Weng Xuetian

[keyboard] use json file from iso codes

parent 9e150864
Pipeline #29012293 passed with stage
in 0 seconds
......@@ -60,9 +60,10 @@ endif ()
find_package(XCB COMPONENTS XCB AUX XKB XFIXES ICCCM XINERAMA RANDR EWMH KEYSYMS)
find_package(XKBCommon COMPONENTS XKBCommon X11)
find_package(XCBImdkit)
find_package(IsoCodes)
find_package(Expat)
find_package(IsoCodes REQUIRED)
find_package(Expat REQUIRED)
find_package(XKeyboardConfig)
pkg_check_modules(JsonC REQUIRED IMPORTED_TARGET "json-c")
pkg_check_modules(XkbFile REQUIRED IMPORTED_TARGET "xkbfile")
pkg_check_modules(Cairo IMPORTED_TARGET cairo)
pkg_check_modules(CairoXCB IMPORTED_TARGET cairo-xcb)
......
......@@ -18,15 +18,15 @@ endif(ISOCODES_INCLUDE_DIR AND ISOCODES_LIBRARIES)
find_package(PkgConfig)
pkg_check_modules(PC_ISOCODES iso-codes)
find_file(ISOCODES_ISO639_XML iso_639.xml
HINTS "${PC_ISOCODES_PREFIX}/share/xml/iso-codes/"
find_file(ISOCODES_ISO639_JSON iso_639-3.json
HINTS "${PC_ISOCODES_PREFIX}/share/iso-codes/json/"
)
find_file(ISOCODES_ISO3166_XML iso_3166.xml
HINTS "${PC_ISOCODES_PREFIX}/share/xml/iso-codes/"
find_file(ISOCODES_ISO3166_JSON iso_3166-1.json
HINTS "${PC_ISOCODES_PREFIX}/share/iso-codes/json/"
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(IsoCodes DEFAULT_MSG ISOCODES_ISO639_XML ISOCODES_ISO3166_XML)
find_package_handle_standard_args(IsoCodes DEFAULT_MSG ISOCODES_ISO639_JSON ISOCODES_ISO3166_JSON)
mark_as_advanced(ISOCODES_ISO639_XML ISOCODES_ISO3166_XML)
mark_as_advanced(ISOCODES_ISO639_JSON ISOCODES_ISO3166_JSON)
......@@ -29,8 +29,8 @@
#define FCITX_LIBRARY_SUFFIX "@FCITX_LIBRARY_SUFFIX@"
#define FCITX_VERSION_STRING "@FCITX_VERSION@"
#define ISOCODES_ISO639_XML "@ISOCODES_ISO639_XML@"
#define ISOCODES_ISO3166_XML "@ISOCODES_ISO3166_XML@"
#define ISOCODES_ISO639_JSON "@ISOCODES_ISO639_JSON@"
#define ISOCODES_ISO3166_JSON "@ISOCODES_ISO3166_JSON@"
#define XKEYBOARDCONFIG_XKBBASE "@XKEYBOARDCONFIG_XKBBASE@"
#define DEFAULT_XKB_RULES "@DEFAULT_XKB_RULES@"
#cmakedefine EXECINFO_FOUND
......
add_library(keyboard STATIC keyboard.cpp isocodes.cpp xkbrules.cpp xmlparser.cpp)
target_link_libraries(keyboard Fcitx5::Core Expat::Expat LibIntl::LibIntl XKBCommon::XKBCommon Fcitx5::Module::XCB Fcitx5::Module::Spell Fcitx5::Module::Notifications ${FMT_TARGET})
target_link_libraries(keyboard Fcitx5::Core Expat::Expat LibIntl::LibIntl XKBCommon::XKBCommon Fcitx5::Module::XCB Fcitx5::Module::Spell Fcitx5::Module::Notifications PkgConfig::JsonC ${FMT_TARGET})
target_include_directories(keyboard PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
fcitx5_translate_desktop_file(keyboard.conf.in keyboard.conf)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/keyboard.conf" DESTINATION "${FCITX_INSTALL_PKGDATADIR}/addon")
......
......@@ -18,42 +18,94 @@
//
#include "isocodes.h"
#include "fcitx-utils/metastring.h"
#include "xmlparser.h"
#include <cstring>
#include <fcitx-utils/log.h>
#include <json-c/json.h>
#include <memory>
namespace fcitx {
class IsoCodes639Parser : public XMLParser {
template <typename RootString>
class IsoCodesJsonParser {
public:
virtual void handle(json_object *entry) = 0;
void parse(const std::string &filename) {
std::unique_ptr<json_object, decltype(&json_object_put)> obj(
nullptr, json_object_put);
obj.reset(json_object_from_file(filename.data()));
if (!obj) {
return;
}
FCITX_INFO() << RootString::data();
json_object *root =
json_object_object_get(obj.get(), RootString::data());
if (!root || json_object_get_type(root) != json_type_array) {
return;
}
for (size_t i = 0, e = json_object_array_length(root); i < e; i++) {
json_object *entry = json_object_array_get_idx(root, i);
handle(entry);
}
}
};
class IsoCodes639Parser
: public IsoCodesJsonParser<fcitxMakeMetaString("639-3")> {
public:
IsoCodes639Parser(IsoCodes *that) : that_(that) {}
void startElement(const XML_Char *name, const XML_Char **atts) override {
if (strcmp(name, "iso_639_entry") == 0) {
IsoCodes639Entry entry;
int i = 0;
while (atts && atts[i * 2] != 0) {
if (strcmp(atts[i * 2], "iso_639_2B_code") == 0)
entry.iso_639_2B_code = atts[i * 2 + 1];
else if (strcmp(atts[i * 2], "iso_639_2T_code") == 0)
entry.iso_639_2T_code = atts[i * 2 + 1];
else if (strcmp(atts[i * 2], "iso_639_1_code") == 0)
entry.iso_639_1_code = atts[i * 2 + 1];
else if (strcmp(atts[i * 2], "name") == 0)
entry.name = atts[i * 2 + 1];
i++;
void handle(json_object *entry) override {
json_object *alpha2 = json_object_object_get(entry, "alpha_2");
json_object *alpha3 = json_object_object_get(entry, "alpha_3");
json_object *bibliographic =
json_object_object_get(entry, "bibliographic");
json_object *name = json_object_object_get(entry, "name");
if (!name || json_object_get_type(name) != json_type_string) {
return;
}
// there must be alpha3
if (!alpha3 || json_object_get_type(alpha3) != json_type_string) {
return;
}
// alpha2 is optional
if (alpha2 && json_object_get_type(alpha2) != json_type_string) {
return;
}
// bibliographic is optional
if (bibliographic &&
json_object_get_type(bibliographic) != json_type_string) {
return;
}
if (!bibliographic) {
bibliographic = alpha3;
}
IsoCodes639Entry e;
e.name.assign(json_object_get_string(name),
json_object_get_string_len(name));
if (alpha2) {
e.iso_639_1_code.assign(json_object_get_string(alpha2),
json_object_get_string_len(alpha2));
}
e.iso_639_2B_code.assign(json_object_get_string(bibliographic),
json_object_get_string_len(bibliographic));
e.iso_639_2T_code.assign(json_object_get_string(alpha3),
json_object_get_string_len(alpha3));
if ((!e.iso_639_2B_code.empty() || !e.iso_639_2T_code.empty()) &&
!e.name.empty()) {
that_->iso639entires.emplace_back(e);
if (!e.iso_639_2B_code.empty()) {
that_->iso6392B.emplace(e.iso_639_2B_code,
that_->iso639entires.size() - 1);
}
if ((!entry.iso_639_2B_code.empty() ||
!entry.iso_639_2T_code.empty()) &&
!entry.name.empty()) {
that_->iso639entires.emplace_back(entry);
if (!entry.iso_639_2B_code.empty()) {
that_->iso6392B.emplace(entry.iso_639_2B_code,
that_->iso639entires.size() - 1);
}
if (!entry.iso_639_2T_code.empty()) {
that_->iso6392T.emplace(entry.iso_639_2T_code,
that_->iso639entires.size() - 1);
}
if (!e.iso_639_2T_code.empty()) {
that_->iso6392T.emplace(e.iso_639_2T_code,
that_->iso639entires.size() - 1);
}
}
}
......@@ -62,24 +114,28 @@ private:
IsoCodes *that_;
};
class IsoCodes3166Parser : public XMLParser {
class IsoCodes3166Parser
: public IsoCodesJsonParser<fcitxMakeMetaString("3166-1")> {
public:
IsoCodes3166Parser(IsoCodes *that) : that_(that) {}
void startElement(const XML_Char *name, const XML_Char **atts) override {
if (strcmp(name, "iso_3166_entry") == 0) {
std::string alpha_2_code, name;
int i = 0;
while (atts && atts[i * 2] != 0) {
if (strcmp(atts[i * 2], "alpha_2_code") == 0)
alpha_2_code = atts[i * 2 + 1];
else if (strcmp(atts[i * 2], "name") == 0)
name = atts[i * 2 + 1];
i++;
}
if (!name.empty() && !alpha_2_code.empty()) {
that_->iso3166.emplace(alpha_2_code, name);
}
void handle(json_object *entry) override {
json_object *alpha2 = json_object_object_get(entry, "alpha_2");
json_object *nameObj = json_object_object_get(entry, "name");
if (!nameObj || json_object_get_type(nameObj) != json_type_string) {
return;
}
// there must be alpha3
if (!alpha2 || json_object_get_type(alpha2) != json_type_string) {
return;
}
std::string alpha_2_code, name;
name.assign(json_object_get_string(nameObj),
json_object_get_string_len(nameObj));
alpha_2_code.assign(json_object_get_string(alpha2),
json_object_get_string_len(alpha2));
if (!name.empty() && !alpha_2_code.empty()) {
that_->iso3166.emplace(alpha_2_code, name);
}
}
......
......@@ -162,7 +162,7 @@ static std::string findBestLanguage(const IsoCodes &isocodes,
KeyboardEngine::KeyboardEngine(Instance *instance) : instance_(instance) {
registerDomain("xkeyboard-config", XKEYBOARDCONFIG_DATADIR "/locale");
isoCodes_.read(ISOCODES_ISO639_XML, ISOCODES_ISO3166_XML);
isoCodes_.read(ISOCODES_ISO639_JSON, ISOCODES_ISO3166_JSON);
auto xcb = instance_->addonManager().addon("xcb");
std::string rule;
if (xcb) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment