Font selection added. Preference saving/loading improved.
[jben2_gui.git] / preferences.py
blob3d5609863389f2483a189e6e3ae88134d4960dec
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 # Project: J-Ben, Python front-end
5 # File: preferences.py
6 # Author: Paul Goins
7 # Created on: 20 December 2008
9 from jben_global import *
10 import re
12 options = {}
13 """Maps preference key strings to stored option values."""
15 original_save_target = None
16 """This variable will be set to the contents of options["config_save_target"]
17 when a config file is loaded, in order to track runtime changes.
18 """
20 __CURRENT_CONFIG_VERSION = "2.0"
21 """The current version of the config file."""
23 def load(filename=None):
24 """Load preferences from a config file.
26 If filename is None (default), then J-Ben will search for a config
27 file in the program's parent directory (important for self-contained
28 "mobile" installs), followed by the user's home directory.
30 """
31 loaded = False
33 if filename:
34 try:
35 f = open(filename)
36 print "Reading from file:", filename
37 lines = f.readlines()
38 f.close()
40 for line in lines:
41 line = line.strip()
42 # Treat # and ; as comment markers, and ignore empty lines.
43 if len(line) == 0 or line[0] == "#" or line[0] == ";":
44 continue
46 try:
47 k, v = re.split("[ \t=:]+", line, 1)
48 if k and v:
49 v2 = v.lower().strip()
50 if v2 in ("true", "false"):
51 options[k] = (v2 == "true")
52 else:
53 options[k] = v
54 except ValueError:
55 print _("Warning: unable to split line: %s" % line)
56 except IOError, e:
57 if e.args[0] == 2: # Error 2 == File not found
58 print "Could not find file:", filename
59 else:
60 raise
61 else:
62 loaded = load("../" + CFG_FILE)
63 if not loaded or options["config_save_target"] == "home":
64 env_path = os.getenv(HOME_ENV)
65 if env_path:
66 loaded2 = load("%s/%s" % (env_path, CFG_FILE))
67 if loaded2:
68 loaded = True
70 return loaded
72 def save(filename=None):
73 """Save preferences to a config file.
75 If filename is None (default), then J-Ben will save the file based
76 on the current install type (standard or mobile).
78 Important: If filename is None, and the installation type was
79 changed during runtime, then this function will save to both files.
80 This is necessary in case two config files are located on a
81 system (both standard and mobile), in which case J-Ben will look at
82 both files and decide which one to use.
84 """
85 save_data = __create_config_file_string()
86 #print "save_data = [%s]" % save_data
88 files = []
89 if filename is None:
90 if (options["config_save_target"] == "mobile"
91 or original_save_target == "mobile"):
92 files.append("../" + CFG_FILE)
93 else: # Default: save to home folder
94 env_path = os.getenv(HOME_ENV)
95 if env_path:
96 files.append("%s/%s" % (env_path, CFG_FILE))
97 else:
98 files.append("../" + CFG_FILE)
99 else:
100 files.append(filename)
102 for f in files:
103 if f:
104 try:
105 fo = open(f, "w")
106 print "Writing to file:", f
107 fo.write(save_data)
108 fo.close()
109 except:
110 # We can add error handlers later...
111 raise
113 def set_default_prefs():
114 """Default preferences are defined here.
116 These settings are loaded prior to loading any config file. Any
117 new default settings should be defined here.
120 # Changes in Python version
121 # 1. JB_DATADIR is now configured in jben_global.py.
122 # 2. DSSTR is removed; we will now simply specify "/" as a
123 # directory separator.
124 # 3. kanjidicOptions and kanjidicDictionaries have been obsoleted and
125 # replaced with explicit "kdict.render" values.
127 options.clear()
128 options["config_version"] = __CURRENT_CONFIG_VERSION
129 options["config_save_target"] = "unset"
131 # Obsoleted options
132 # kanjidicOptions = KDO_READINGS | KDO_MEANINGS
133 # | KDO_HIGHIMPORTANCE | KDO_VOCABCROSSREF;
134 # kanjidicDictionaries = 0;
136 # Replaced by the following, more explicit options:
138 # KDO_READINGS:
139 options["kdict.render.onyomi"] = "true"
140 options["kdict.render.kunyomi"] = "true"
141 options["kdict.render.nanori"] = "true"
142 options["kdict.render.radical_name"] = "true"
144 # KDO_MEANINGS:
145 options["kdict.render.meaning"] = "true" # ENGLISH
146 #options["kdict.render.meaning.fr"] = "true" # Example for French
148 # KDO_HIGHIMPORTANCE:
149 options["kdict.render.stroke_count"] = "true"
150 options["kdict.render.jouyou_grade"] = "true"
151 options["kdict.render.jlpt_level"] = "true"
152 options["kdict.render.frequency"] = "true"
154 # KDO_MULTIRAD:
155 options["kdict.render.radical_list"] = "false"
157 # KDO_VOCABCROSSREF:
158 options["kdict.render.vocab_cross_ref"] = "true"
160 # KDO_DICTIONARIES:
161 options["kdict.render.dictionaries"] = "false"
162 # Additional keys for specific dictionaries are boolean flags tagged onto
163 # the end of the above key.
164 # Example: kdict.render.dictionaries.kld = "true"
165 # (kld = Kanji Learners' Dictionary)
167 # KDO_LOWIMPORTANCE:
168 options["kdict.render.jis-208"] = "false"
169 options["kdict.render.jis-212"] = "false"
170 options["kdict.render.jis-213"] = "false"
171 options["kdict.render.unicode"] = "false"
172 options["kdict.render.kangxi_radical"] = "false"
173 options["kdict.render.nelson_radical"] = "false"
174 options["kdict.render.pinyin_roman"] = "false"
175 options["kdict.render.korean"] = "false"
176 options["kdict.render.korean_roman"] = "false"
177 options["kdict.render.cross_ref"] = "false"
179 # KDO_SOD_*:
180 options["kdict.render.kanjicafe_sods"] = "true"
181 options["kdict.render.kanjicafe_sodas"] = "true"
183 # Define default paths to supported (and future supported) dicts.
184 # J-Ben will automatically append ".gz" and load compressed dictionaries
185 # if found.
186 # Identifiers are of the form "jben_obj.dict_type.file[#]". Dicts with the
187 # same format should share the same dict_type and add a file number.
189 options["kdict.kanjidic2.file"] = JB_DATADIR + "/dicts/kanjidic2.xml"
190 options["kdict.kanjidic.file"] = JB_DATADIR + "/dicts/kanjidic"
191 options["kdict.kanjidic.file2"] = JB_DATADIR + "/dicts/kanjd212"
192 options["kdict.kradfile.file"] = JB_DATADIR + "/dicts/kradfile"
193 options["kdict.radkfile.file"] = JB_DATADIR + "/dicts/radkfile"
194 options["wdict.edict.file"] = JB_DATADIR + "/dicts/edict"
195 options["wdict.edict2.file"] = JB_DATADIR + "/dicts/edict2"
197 # J-Ben's internal encoding is UTF-8, however most of Jim Breen's non-XML
198 # dict files are in EUC-JP. We should allow the program to support
199 # these files.
200 options["wdict.edict.file.encoding"] = "euc-jp"
201 options["wdict.edict2.file.encoding"] = "euc-jp"
202 options["kdict.kanjidic.file.encoding"] = "euc-jp"
203 options["kdict.kanjidic.file2.encoding"] = "euc-jp"
204 options["kdict.kradfile.file.encoding"] = "euc-jp"
205 options["kdict.radkfile.file.encoding"] = "euc-jp"
206 # Specify JIS encoding for kanjidic files (jis-208 or jis-212)
207 # jis-208 is assumed, so this just means to set it only for kanjd212.
208 options["kdict.kanjidic.file2.jispage"] = "jis212"
210 options["sod_dir"] = JB_DATADIR + "/sods"
212 options["kanjitest.writing.showonyomi"]="true"
213 options["kanjitest.writing.showkunyomi"]="true"
214 options["kanjitest.writing.showenglish"]="true"
215 options["kanjitest.reading.showonyomi"]="false"
216 options["kanjitest.reading.showkunyomi"]="false"
217 options["kanjitest.reading.showenglish"]="false"
218 options["kanjitest.showanswer"]="1"
219 options["kanjitest.correctanswer"]="2"
220 options["kanjitest.wronganswer"]="3"
221 options["kanjitest.stopdrill"]="4"
223 def upgrade_config_file():
224 """Brings settings loaded from previous config file versions up-to-date.
226 Generally speaking, this should not need to be edited. Only when
227 an option string has been renamed, or the config file itself changed,
228 should this really need to be touched.
231 version = options["config_version"]
233 # Iterate through the version-wise changes
235 if version == "1":
236 el.Push(EL_Silent, "Upgrading config file from version 1 to 1.1.")
237 # 1 to 1.1:
238 # - Add config_save_target setting
239 # - Add KANJIDIC2 and KANJD212 default settings
240 options["config_save_target"] = "home"
241 options["kdict_kanjidic2"] = JB_DATADIR + "/dicts/kanjidic2.xml"
242 options["kdict_kanjd212"] = JB_DATADIR + "/dicts/kanjd212"
243 version = "1.1"
245 if version == "1.1":
246 # 1.1 to 1.2:
247 # - Convert xdict_filename to xdict.dicttype_file# format */
248 map = {"kdict_kanjidic": "kdict.kanjidic.file",
249 "kdict_kanjd212": "kdict.kanjidic.file2",
250 "kdict_kanjidic2": "kdict.kanjidic2.file",
251 "kdict_kradfile": "kdict.kradfile.file",
252 "kdict_radkfile": "kdict.radkfile.file",
253 "wdict_edict2": "wdict.edict2.file"}
254 for old_key, new_key in map.items():
255 val = options.get(old_key)
256 if val:
257 options[new_key] = val
258 del val[old_key]
259 if "kdict.kanjidic.file2" in options.keys():
260 options["kdict.kanjidic.file2.jispage"] = "jis212"
261 version = "1.2"
263 if version == "1.2":
264 # This version change doesn't really change anything, but is left in
265 # so we don't break anything.
266 version = "1.2.1"
268 if version == "1.2.1":
269 # Updates for J-Ben 2.0
270 # 1. Convert kanjidic options/dictionaries int values to normal
271 # options.
272 # 2. Rename KanjiList and VocabList to list.kanji and list.vocab
273 # respectively.
274 pass
275 version = "2.0"
277 version = __CURRENT_CONFIG_VERSION
279 def __create_config_file_string():
280 """Creates a complete config file data string for saving to disk."""
282 # Format: tab-delimited
283 # Example: key value
284 # Notes: First key MUST be "config_version".
286 header = "config_version\t%s" % options["config_version"]
287 config_strs = []
289 # These values are handled specially, so we don't auto-include them.
290 excludes = ["config_version", "kanji_list", "vocab_list"]
291 other_opts = [(k, v) for k, v in options.items() if k not in excludes]
292 for k, v in other_opts:
293 if v != '':
294 config_strs.append("%s\t%s" % (k, str(v)))
295 else:
296 print _('Warning: dropping empty setting "%s"!' % k)
298 # Append kanji and vocab lists
299 # ...
301 config_strs.sort()
302 config_strs.insert(0, header)
303 return "\n".join(config_strs) + "\n"