1 //
2 // Copyright RIME Developers
3 // Distributed under the BSD License
4 //
5 // 2012-02-18 GONG Chen <chen.sst@gmail.com>
6 //
7 #include <utility>
8 #include <boost/algorithm/string.hpp>
9 #include <boost/filesystem.hpp>
10 #include <rime/config.h>
11 #include <rime/deployer.h>
12 #include <rime/lever/switcher_settings.h>
13
14 namespace fs = boost::filesystem;
15
16 namespace rime {
17
SwitcherSettings(Deployer * deployer)18 SwitcherSettings::SwitcherSettings(Deployer* deployer)
19 : CustomSettings(deployer, "default", "Rime::SwitcherSettings") {
20 }
21
Load()22 bool SwitcherSettings::Load() {
23 if (!CustomSettings::Load())
24 return false;
25 available_.clear();
26 selection_.clear();
27 hotkeys_.clear();
28 GetAvailableSchemasFromDirectory(deployer_->shared_data_dir);
29 GetAvailableSchemasFromDirectory(deployer_->user_data_dir);
30 GetSelectedSchemasFromConfig();
31 GetHotkeysFromConfig();
32 return true;
33 }
34
Select(Selection selection)35 bool SwitcherSettings::Select(Selection selection) {
36 selection_ = std::move(selection);
37 auto schema_list = New<ConfigList>();
38 for (const string& schema_id : selection_) {
39 auto item = New<ConfigMap>();
40 item->Set("schema", New<ConfigValue>(schema_id));
41 schema_list->Append(item);
42 }
43 return Customize("schema_list", schema_list);
44 }
45
SetHotkeys(const string & hotkeys)46 bool SwitcherSettings::SetHotkeys(const string& hotkeys) {
47 // TODO: not implemented; validation required
48 return false;
49 }
50
GetAvailableSchemasFromDirectory(const fs::path & dir)51 void SwitcherSettings::GetAvailableSchemasFromDirectory(const fs::path& dir) {
52 if (!fs::exists(dir) || !fs::is_directory(dir)) {
53 LOG(INFO) << "directory '" << dir.string() << "' does not exist.";
54 return;
55 }
56 for (fs::directory_iterator it(dir), end;
57 it != end; ++it) {
58 string file_path(it->path().string());
59 if (boost::ends_with(file_path, ".schema.yaml")) {
60 Config config;
61 if (config.LoadFromFile(file_path)) {
62 SchemaInfo info;
63 // required properties
64 if (!config.GetString("schema/schema_id", &info.schema_id))
65 continue;
66 if (!config.GetString("schema/name", &info.name))
67 continue;
68 // check for duplicates
69 bool duplicated = false;
70 for (const SchemaInfo& other : available_) {
71 if (other.schema_id == info.schema_id) {
72 duplicated = true;
73 break;
74 }
75 }
76 if (duplicated)
77 continue;
78 // details
79 config.GetString("schema/version", &info.version);
80 if (auto authors = config.GetList("schema/author")) {
81 for (size_t i = 0; i < authors->size(); ++i) {
82 auto author = authors->GetValueAt(i);
83 if (author && !author->str().empty()) {
84 if (!info.author.empty())
85 info.author += "\n";
86 info.author += author->str();
87 }
88 }
89 }
90 config.GetString("schema/description", &info.description);
91 info.file_path = file_path;
92 available_.push_back(info);
93 }
94 }
95 }
96 }
97
GetSelectedSchemasFromConfig()98 void SwitcherSettings::GetSelectedSchemasFromConfig() {
99 auto schema_list = config_.GetList("schema_list");
100 if (!schema_list) {
101 LOG(WARNING) << "schema list not defined.";
102 return;
103 }
104 for (auto it = schema_list->begin(); it != schema_list->end(); ++it) {
105 auto item = As<ConfigMap>(*it);
106 if (!item)
107 continue;
108 auto schema_property = item->GetValue("schema");
109 if (!schema_property)
110 continue;
111 const string& schema_id(schema_property->str());
112 selection_.push_back(schema_id);
113 }
114 }
115
GetHotkeysFromConfig()116 void SwitcherSettings::GetHotkeysFromConfig() {
117 auto hotkeys = config_.GetList("switcher/hotkeys");
118 if (!hotkeys) {
119 LOG(WARNING) << "hotkeys not defined.";
120 return;
121 }
122 for (auto it = hotkeys->begin(); it != hotkeys->end(); ++it) {
123 auto item = As<ConfigValue>(*it);
124 if (!item)
125 continue;
126 const string& hotkey(item->str());
127 if (hotkey.empty())
128 continue;
129 if (!hotkeys_.empty())
130 hotkeys_ += ", ";
131 hotkeys_ += hotkey;
132 }
133 }
134
135 } // namespace rime
136