4 Website: http://www.vultaire.net/software/jben/
5 License: GNU General Public License (GPL) version 2
6 (http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt)
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>
25 # define JB_DATADIR "."
29 # define CFGFILE "jben.cfg"
30 # define HOMEENV "APPDATA"
32 # define CFGFILE ".jben"
33 # define HOMEENV "HOME"
36 #define CURRENT_CONFIG_VERSION "1.1"
38 #include "preferences.h"
40 #include "file_utils.h"
41 #include "encoding_convert.h"
42 #include "string_utils.h"
51 Preferences
* Preferences::prefsSingleton
= NULL
;
53 Preferences
*Preferences::Get() {
55 prefsSingleton
= new Preferences
;
56 /* Load with default preferences, and overwrite with any stored
58 prefsSingleton
->SetDefaultPrefs();
60 /* Check for the config file in the user's home directory. */
61 string homedir
= getenv(HOMEENV
);
62 homedir
.append(1, DSCHAR
);
63 bool OK
= (prefsSingleton
64 ->LoadFile(string(homedir
).append(CFGFILE
).c_str())
67 /* If the config file could not be loaded from the home directory,
68 fall back and check the current directory. */
70 prefsSingleton
->LoadFile(CFGFILE
);
72 return prefsSingleton
;
75 Preferences::Preferences() {
76 /* Nothing to be done */
79 void Preferences::Destroy() {
81 delete prefsSingleton
;
82 prefsSingleton
= NULL
;
86 void Preferences::SetDefaultPrefs() {
88 KDO_READINGS
| KDO_MEANINGS
| KDO_HIGHIMPORTANCE
| KDO_VOCABCROSSREF
;
89 kanjidicDictionaries
= 0;
90 stringOpts
["config_version"] = CURRENT_CONFIG_VERSION
;
91 stringOpts
["config_save_target"] = "home";
92 stringOpts
["kdict_kanjidic2"]
93 = JB_DATADIR DSSTR
"dicts" DSSTR
"kanjidic2.xml";
94 stringOpts
["kdict_kanjidic"] = JB_DATADIR DSSTR
"dicts" DSSTR
"kanjidic";
95 stringOpts
["kdict_kanjd212"] = JB_DATADIR DSSTR
"dicts" DSSTR
"kanjd212";
96 stringOpts
["kdict_kradfile"] = JB_DATADIR DSSTR
"dicts" DSSTR
"kradfile";
97 stringOpts
["kdict_radkfile"] = JB_DATADIR DSSTR
"dicts" DSSTR
"radkfile";
98 stringOpts
["wdict_edict2"] = JB_DATADIR DSSTR
"dicts" DSSTR
"edict2";
99 stringOpts
["sod_dir"] = JB_DATADIR DSSTR
"sods";
102 int Preferences::LoadFile(const char *filename
) {
104 kanjidicOptions
= KDO_ALL
| KDO_UNHANDLED
;
105 kanjidicDictionaries
= 0; /* KDD_ALL */
107 int e
= ReadEncodedFile(filename
, s
);
110 oss
<< "Preferences file \"" << filename
111 << "\" loaded successfully.";
112 el
.Push(EL_Silent
, oss
.str());
114 /* Split into strings for each line */
115 list
<wstring
> tokenList
= StrTokenize
<wchar_t>(s
, L
"\n");
116 wstring token
, subToken
;
118 while(tokenList
.size()>0) {
119 token
= tokenList
.front();
120 tokenList
.pop_front();
121 if( (token
.length()>0) && (token
[0]!=L
'#') ) {
122 /* We only want to split the string into two subtokens, so we'll
124 index
= token
.find_first_of(_T(" \t"));
125 if(index
!=wstring::npos
) {
126 subToken
= token
.substr(0, index
);
127 subToken
= ToLower(subToken
);
129 if(subToken
==L
"kanjidicoptionmask") {
130 subToken
= token
.substr(index
+1);
131 subToken
= Trim(subToken
);
132 /* We know the subtoken starts with 0x, so skip the
133 first two characters. */
134 wistringstream(subToken
.substr(2))
135 >> hex
>> kanjidicOptions
;
137 } else if(subToken
==L
"kanjidicdictionarymask") {
138 subToken
= token
.substr(index
+1);
139 subToken
= Trim(subToken
);
140 wistringstream(subToken
.substr(2))
141 >> hex
>> kanjidicDictionaries
;
143 } else if(subToken
==L
"vocablist") {
144 subToken
= token
.substr(index
+1);
145 subToken
= Trim(subToken
);
147 = StrTokenize
<wchar_t>(subToken
, L
";");
148 while(tSub
.size()>0) {
149 subToken
= tSub
.front();
151 if(subToken
.length()>0) {
152 string
*temp
= &stringOpts
["vocablist"];
154 temp
->append(1, '\n');
155 temp
->append(utfconv_wm(subToken
));
160 /* Default handling for any
161 other string-based entries */
162 string key
= utfconv_wm(subToken
);
163 subToken
= token
.substr(index
+1);
164 stringOpts
[key
] = utfconv_wm(Trim(subToken
));
167 /* No space/tab was found. Check no-arg options, if any.
168 (Currently there are none.) */
170 } /* if(tokenlen>0, token[0]!=# */
171 } /* while(hasmoretokens) */
172 } /* if(file opened) */
175 oss
<< "Preferences file \"" << filename
176 << "\" could NOT be loaded." << endl
;
177 el
.Push(EL_Silent
, oss
.str());
180 /* The file is now loaded.
181 Upgrade it to the latest version, if necessary. */
182 if(stringOpts
["config_version"] != CURRENT_CONFIG_VERSION
)
188 void Preferences::UpgradeConfigFile() {
189 string version
= stringOpts
["config_version"];
190 /* Iterate through the version-wise changes */
192 el
.Push(EL_Silent
, "Upgrading config file from version 1 to 1.1.");
194 - Add config_save_target setting
195 - Add KANJIDIC2 and KANJD212 default settings */
196 stringOpts
["config_save_target"] = "home";
197 stringOpts
["kdict_kanjidic2"]
198 = JB_DATADIR DSSTR
"dicts" DSSTR
"kanjidic2.xml";
199 stringOpts
["kdict_kanjd212"]
200 = JB_DATADIR DSSTR
"dicts" DSSTR
"kanjd212";
203 stringOpts
["config_version"] = CURRENT_CONFIG_VERSION
;
206 Preferences::~Preferences() {
207 string prefs
= GetPrefsStr();
210 if(ToLower(stringOpts
["config_save_target"]) == "home") {
211 filename
= string(getenv(HOMEENV
)).append(1, DSCHAR
).append(CFGFILE
);
212 ofile
.open(filename
.c_str(), ios::out
| ios::binary
);
214 if(!ofile
.is_open()) {
216 ofile
.open(filename
.c_str(), ios::out
| ios::binary
);
220 if(ofile
.is_open()) {
222 oss
<< "Preferences file \"" << filename
223 << "\" saved successfully.";
224 el
.Push(EL_Silent
, oss
.str());
227 oss
<< "Unable to save preferences to file \"" << CFGFILE
229 el
.Push(EL_Error
, oss
.str());
235 string
Preferences::GetPrefsStr() {
237 string kanjiList
, vocabList
;
239 /* Output config version first */
240 prefs
<< "config_version\t" << stringOpts
["config_version"] << '\n';
242 /* Get kanji and vocab lists in UTF-8 encoded strings */
243 kanjiList
= utfconv_wm(jben
->kanjiList
->ToString());
244 vocabList
= utfconv_wm(jben
->vocabList
->ToString(';'));
246 prefs
<< "KanjidicOptionMask\t0x"
247 << uppercase
<< hex
<< setw(8) << setfill('0')
248 << kanjidicOptions
<< '\n';
249 prefs
<< "KanjidicDictionaryMask\t0x"
250 << uppercase
<< hex
<< setw(8) << setfill('0')
251 << kanjidicDictionaries
<< '\n';
252 prefs
<< "KanjiList\t"
253 << utfconv_wm(jben
->kanjiList
->ToString()) << '\n';
254 prefs
<< "VocabList\t"
255 << utfconv_wm(jben
->vocabList
->ToString(';')) << '\n';
257 /* Append any other variables stored */
258 for(map
<string
, string
>::iterator mi
= stringOpts
.begin();
259 mi
!= stringOpts
.end(); mi
++) {
260 if(mi
->first
!="kanjilist" &&
261 mi
->first
!="vocablist" &&
262 mi
->first
!="config_version") {
263 prefs
<< mi
->first
<< '\t' << mi
->second
<< '\n';
270 string
& Preferences::GetSetting(string key
) {
271 return stringOpts
[ToLower(key
)];