OSDN Git Service

b95ae2cfe169c88c6af8a6d2f8cf1cdfc684304c
[amulettoolsmh4/main.git] / amulettool.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 # お守りスキルのSeed特定ツールのコントロールクラス
5 # 2013/12/04 written by kei9
6
7 import threading
8 import time
9 import os.path
10 import sys
11 import pickle
12 import sqlite3
13
14 import wx
15
16 import view
17 import model
18 import convertcoding
19
20 SETTING_FILE = u"settings"
21 SETTING_THRESHOLD1 = u"threshold1"
22 SETTING_THRESHOLD2 = u"threshold2"
23 SETTING_SKILLS = u"skills"
24
25 def _get_base_dir():
26     u""" for pyinstaller 2.1 """
27     if getattr(sys, 'frozen', False):
28         # we are running in a |PyInstaller| bundle
29         basedir = sys._MEIPASS
30     else:
31         # we are running in a normal Python environment
32         #1basedir = os.path.dirname(__file__)
33         basedir = os.path.dirname(os.path.abspath(__file__))
34     return convertcoding.convert_unicode(basedir)
35
36
37 class AmuletToolController(wx.App):
38     u""" アプリケーションの制御クラス """
39     def OnInit(self):
40         self._read_settings()
41         self.frame_view = view.MainFrameView(os.path.join(_get_base_dir(), u"view", view.XRC_MAIN_FRAME))
42
43         self._init_events()
44
45         self.frame_view.Show()
46
47         self.frame_view.DisableNoteBook()
48
49         self._init_database()
50         self._set_views()
51
52         self.frame_view.EnableNoteBook()
53         return True
54
55     def _init_events(self):
56         u"""イベント登録"""
57         frame = self.frame_view.frame
58
59         # menu event
60         frame.Bind(wx.EVT_MENU, self.OnClose, id=self.frame_view.ID_MENU_ITEM_EXIT)
61         frame.Bind(wx.EVT_MENU, self.OnAboutBox, id=self.frame_view.ID_MENU_ITEM_ABOUT)
62         frame.Bind(wx.EVT_CLOSE, self.CloseHandler)
63
64         # button event
65         frame.Bind(wx.EVT_BUTTON, self.OnClickSeedSearch, id=self.frame_view.ID_BUTTON_SEED_SEARCH)
66         frame.Bind(wx.EVT_BUTTON, self.OnClickSeedClear, id=self.frame_view.ID_BUTTON_SEED_CLEAR)
67         frame.Bind(wx.EVT_BUTTON, self.OnClickSkillSearchFromSeed, id=self.frame_view.ID_BUTTON_SKILL_FROM_SEED_SEARCH)
68         frame.Bind(wx.EVT_BUTTON, self.OnClickSkillSearch, id=self.frame_view.ID_BUTTON_SKILL_SEARCH)
69         frame.Bind(wx.EVT_BUTTON, self.OnClickSkillClear, id=self.frame_view.ID_BUTTON_SKILL_CLEAR)
70         frame.Bind(wx.EVT_BUTTON, self.OnClickAmuletSearch, id=self.frame_view.ID_BUTTON_AMULET_SEARCH_SEARCH)
71         frame.Bind(wx.EVT_BUTTON, self.OnClickAmuletClear, id=self.frame_view.ID_BUTTON_AMULET_SEARCH_CLEAR)
72         frame.Bind(wx.EVT_BUTTON, self.OnClickSkillSearchFromAmulet, id=self.frame_view.ID_BUTTON_AMULET_SEARCH_SKILL)
73         frame.Bind(wx.EVT_BUTTON, self.OnClickSettingOK, id=self.frame_view.ID_BUTTON_SETTING_OK)
74         frame.Bind(wx.EVT_BUTTON, self.OnClickSettingClear, id=self.frame_view.ID_BUTTON_SETTING_CLEAR)
75
76         # radio button event
77         frame.Bind(wx.EVT_RADIOBUTTON, self.OnClickAmuletRadio, id=self.frame_view.ID_RADIO_BUTTON_AMULET1)
78         frame.Bind(wx.EVT_RADIOBUTTON, self.OnClickAmuletRadio, id=self.frame_view.ID_RADIO_BUTTON_AMULET2)
79         frame.Bind(wx.EVT_RADIOBUTTON, self.OnClickAmuletRadio, id=self.frame_view.ID_RADIO_BUTTON_AMULET3)
80
81         # combo box event
82         frame.Bind(wx.EVT_COMBOBOX, self.OnClickAmuletCombo, id=self.frame_view.ID_COMBO_BOX_AMULET_SEARCH_SKILL1)
83         frame.Bind(wx.EVT_COMBOBOX, self.OnClickAmuletCombo, id=self.frame_view.ID_COMBO_BOX_AMULET_SEARCH_SKILL2)
84
85     def _init_database(self):
86         u""" DBの初期設定 """
87
88         if not os.path.exists(model.DB_FILE_NAME):
89             u""" DBが存在しない時は再生成する """
90             frame = self.frame_view.frame
91             try:
92                 generator = model.DataBaseGenerator(model.DB_FILE_NAME)
93                 #generator = model.DataBaseGenerator()
94
95                 dlg_view = view.GaugeDialogView(os.path.join(_get_base_dir(), u"view", view.XRC_GAUGE_DIALOG))
96                 def _loop():
97                     while t1.is_alive():
98                         dlg_view.gauge.Pulse()
99                         time.sleep(0.2)
100                     dlg_view.finish_generation()
101
102                 t1 = threading.Thread(target=generator.generate_db)
103                 t2 = threading.Thread(target=_loop)
104                 t1.start()
105                 t2.start()
106
107                 dlg_view.ShowModal()
108                 t1.join()
109                 t2.join()
110                 dlg_view.Destroy()
111             except sqlite3.Error as e:
112                 self._show_error_dialog(u"データベース生成中にエラーが発生しました")
113
114         # access to db
115         try:
116             self.db_accessor = model.DataBaseAccessor(model.DB_FILE_NAME)
117         except sqlite3.Error as e:
118             self._show_error_dialog(u"データベースが壊れています")
119
120         # get dictionaries
121         (self._skill_id2name_dict, 
122             self._skill_name2id_dict,
123             self._amulet_id2name_dict, 
124             self._amulet_name2id_dict,
125             self._amulet_id2skill1_id_dict,
126             self._amulet_id2skill2_id_dict) = self.db_accessor.get_dicts()
127
128
129     def _set_views(self):
130         u""" GUIにDBの各種値をセットする """
131         self._set_combo_views()
132         self._set_spin_views()
133         self._set_check_list_views()
134
135     def _set_combo_views(self):
136         u""" ComboBoxの値をセットする """
137         combo_dict = self.frame_view.combo_box_skill_dict
138
139         u" 各種お守りの第2スキル選択 "
140         for amu_key, amu_name in zip([view.KEY_AMULET1, view.KEY_AMULET2, view.KEY_AMULET3], 
141                 [view.NAME_AMULET1, view.NAME_AMULET2, view.NAME_AMULET3]):
142             amu_id = self._amulet_name2id_dict[amu_name]
143             skill_ids = self._amulet_id2skill2_id_dict[amu_id]
144             skill_names = [view.VAL_NO_SKILL] + [self._skill_id2name_dict[x] for x in skill_ids]
145             for combo in combo_dict[amu_key]:
146                combo.SetItems(skill_names)
147                combo.SetSelection(0)
148
149         # amulet search
150         amu_id = self._amulet_name2id_dict[view.NAME_AMULET1]
151         self._set_skill_list_from_amulet(amu_id)
152         self.frame_view.amulet2radio_button_dict[view.NAME_AMULET1].SetValue(True)
153
154     def _set_skill_list_from_amulet(self, amulet_id):
155         u""" お守り種類の選択が変わった時の動作 """
156
157         for i, (combo, skill_dict) in enumerate(zip(
158                 [self.frame_view.combo_box_amulet_search_skill1, 
159                     self.frame_view.combo_box_amulet_search_skill2], 
160                 [self._amulet_id2skill1_id_dict, self._amulet_id2skill2_id_dict]
161                 )):
162             skill_ids = skill_dict[amulet_id]
163             skill_names = [self._skill_id2name_dict[_id] for _id in skill_ids]
164             if i == 0:
165                 combo.SetItems(skill_names)
166                 skill1_selected = skill_ids[0]
167             elif i == 1:
168                 combo.SetItems([view.VAL_NO_SKILL] + skill_names)
169             else:
170                 raise NotImplementedError(u"this iteration must be conducted only twice!")
171             combo.SetSelection(0)   # combo1 = skill1, combo2 = No Skill
172         self._set_spin_range(amulet_id, skill1_selected, None)
173
174     def _set_spin_views(self):
175         u""" Spin Ctrlの最大最小をセット"""
176         min1, max1, min2, max2 = self.db_accessor.get_skill_minmax()
177         self.frame_view.spin_ctrl_amulet_search_slot_num.SetRange(view.SLOT_MIN, view.SLOT_MAX)
178         self.frame_view.spin_ctrl_highlight1.SetRange(view.THRESHOLD1_MIN, view.THRESHOLD1_MAX)
179         self.frame_view.spin_ctrl_highlight2.SetRange(view.THRESHOLD2_MIN, view.THRESHOLD2_MAX)
180         self.frame_view.spin_ctrl_highlight1.SetValue(self._highlight_threshold1)
181         self.frame_view.spin_ctrl_highlight2.SetValue(self._highlight_threshold2)
182
183     def _set_check_list_views(self):
184         u""" CheckListBoxの値のセット """
185         checklist = self.frame_view.check_list_box_highlight_skill
186         checklist.SetItems(self._skill_name2id_dict.keys())
187         checklist.SetCheckedStrings([self._skill_id2name_dict[x] for x in self._highlight_skills])
188
189     def _set_spin_range(self, amulet_id, skill1_id, skill2_id):
190         u""" スキルに応じてSpinCtrlの最大最小をセットする """
191         if skill2_id is None:
192             minmax_dict = self.db_accessor.select_minmax_from_skill_ids(amulet_id, [skill1_id])
193             min1, max1 = minmax_dict[skill1_id][0], minmax_dict[skill1_id][1]
194             min2, max2 = 0, 0
195         else:
196             minmax_dict = self.db_accessor.select_minmax_from_skill_ids(amulet_id, [skill1_id, skill2_id])
197             min1, max1 = minmax_dict[skill1_id][0], minmax_dict[skill1_id][1]
198             min2, max2 = minmax_dict[skill2_id][2], minmax_dict[skill2_id][3]
199         self.frame_view.spin_ctrl_amulet_search_skill1_val.SetRange(min1, max1)
200         self.frame_view.spin_ctrl_amulet_search_skill2_val.SetRange(min2, max2)
201
202     def OnClickSeedSearch(self, evt):
203         u""" search seeds from selected skills """
204         amu_id2skill_id_list_dict = {}
205         for amu_key, amu_name in zip([view.KEY_AMULET1, view.KEY_AMULET2, view.KEY_AMULET3], 
206                 [view.NAME_AMULET1, view.NAME_AMULET2, view.NAME_AMULET3]):
207             amu_id = self._amulet_name2id_dict[amu_name]
208             ls = []
209             for combo in self.frame_view.combo_box_skill_dict[amu_key]:
210                 name = combo.GetStringSelection()
211                 if name not in self._skill_name2id_dict:
212                     ls.append(None)
213                 else:
214                     ls.append(self._skill_name2id_dict[name])
215             amu_id2skill_id_list_dict[amu_id] = ls
216         seed_sets = self.db_accessor.select_seeds(amu_id2skill_id_list_dict)
217         self.frame_view.text_ctrl_seed_result.SetValue(u"""Seedの候補は{0}個です。""".format(len(seed_sets)))
218
219         if len(seed_sets) > 0:
220             self.frame_view.list_box_seed.SetItems([u"{0}".format(seed) for seed in seed_sets])
221             self.frame_view.list_box_seed.SetSelection(0)
222             self.frame_view.button_skill_from_seed_search.Enable()
223         else:
224             self.frame_view.list_box_seed.Clear()
225
226
227     def OnClickSeedClear(self, evt):
228         u""" reset seed search settings of combo box"""
229         combo_dict = self.frame_view.combo_box_skill_dict
230         for amu_key in [view.KEY_AMULET1, view.KEY_AMULET2, view.KEY_AMULET3]:
231             for combo in combo_dict[amu_key]:
232                 combo.SetSelection(0)
233         self.frame_view.text_ctrl_seed_result.SetValue(u"")
234         self.frame_view.button_skill_from_seed_search.Disable()
235         self.frame_view.list_box_seed.Clear()
236
237     def OnClickSkillSearchFromSeed(self, evt):
238         u""" change page to skill search from seed"""
239         seed = self.frame_view.list_box_seed.GetStringSelection()
240         if seed.isdigit():
241             self.frame_view.text_ctrl_seed_select.SetValue(seed)
242             self.frame_view.note_book.SetSelection(view.SKILL_SEARCH_PAGE)
243             self.OnClickSkillSearch(evt)
244
245     def OnClickSkillSearch(self, evt):
246         u""" skill search from seed"""
247         seed = self.frame_view.text_ctrl_seed_select.GetValue()
248         if seed.isdigit():
249             seed = int(seed)
250             skill_dict, threshold1_dict = self.db_accessor.select_skills_from_seeds([seed])
251             grid = self.frame_view.skill2_grid
252             try:
253                 for amu_key, amu_name in zip([view.KEY_AMULET1, view.KEY_AMULET2, view.KEY_AMULET3], 
254                     [view.NAME_AMULET1, view.NAME_AMULET2, view.NAME_AMULET3]):
255                     amu_id = self._amulet_name2id_dict[amu_name]
256                     amu_col = view.DICT_SKILL2_GRID_COL[amu_key]
257                     for row, skill_id in enumerate(skill_dict[amu_id][seed]):
258                         grid.SetCellValue(row, amu_col, self._skill_id2name_dict[skill_id])
259                 th1_col = view.DICT_SKILL2_GRID_COL[view.KEY_THRESHOLD1]
260                 for row, threshold1 in enumerate(threshold1_dict[seed]):
261                     grid.SetCellValue(row, th1_col, u"{0}".format(threshold1))
262                 self._update_highlight()
263
264             except KeyError, e:
265                 self._show_message_dialog(message=u"指定されたSeed値は存在しません")
266         else:
267             self._show_message_dialog(message=u"Seed値には数字を入力してください")
268
269     def OnClickSkillClear(self, evt):
270         u""" clear skills from seed """
271
272         grid = self.frame_view.skill2_grid
273         for row in range(view.NUM_SKILL2_GRID_ROW):
274             for col in range(view.NUM_SKILL2_GRID_COL):
275                 grid.SetCellValue(row, col, "")
276         self.frame_view.list_box_seed_skill_amulet_prospect.Clear() 
277         self._update_highlight()
278
279     def OnClickAmuletRadio(self, evt):
280         u""" switch skill lists by amulet id """
281         btn_id = evt.GetId()
282         if btn_id == self.frame_view.ID_RADIO_BUTTON_AMULET1:
283             amu_id = self._amulet_name2id_dict[view.NAME_AMULET1]
284         elif btn_id == self.frame_view.ID_RADIO_BUTTON_AMULET2:
285             amu_id = self._amulet_name2id_dict[view.NAME_AMULET2]
286         elif btn_id == self.frame_view.ID_RADIO_BUTTON_AMULET3:
287             amu_id = self._amulet_name2id_dict[view.NAME_AMULET3]
288         else:
289             return
290         self._set_skill_list_from_amulet(amu_id)
291
292     def OnClickAmuletCombo(self, evt):
293         u""" switch skill minmax by amulet id and skill_id"""
294         skill1_name = self.frame_view.combo_box_amulet_search_skill1.GetStringSelection()
295         skill2_name = self.frame_view.combo_box_amulet_search_skill2.GetStringSelection()
296         skill1_id = self._skill_name2id_dict[skill1_name]
297         if skill2_name in self._skill_name2id_dict:
298             skill2_id = self._skill_name2id_dict[skill2_name]
299         else:
300             skill2_id = None
301         if self.frame_view.amulet2radio_button_dict[view.NAME_AMULET1].GetValue():
302             amu_id = self._amulet_name2id_dict[view.NAME_AMULET1]
303         elif self.frame_view.amulet2radio_button_dict[view.NAME_AMULET2].GetValue():
304             amu_id = self._amulet_name2id_dict[view.NAME_AMULET2]
305         elif self.frame_view.amulet2radio_button_dict[view.NAME_AMULET3].GetValue():
306             amu_id = self._amulet_name2id_dict[view.NAME_AMULET3]
307         else:
308             raise IndexError(u"amulet id is unknown")
309         self._set_spin_range(amu_id, skill1_id, skill2_id)
310
311     def OnClickAmuletSearch(self, evt):
312         u""" search seeds from amulet condition """
313         skill1_name = self.frame_view.combo_box_amulet_search_skill1.GetStringSelection()
314         skill2_name = self.frame_view.combo_box_amulet_search_skill2.GetStringSelection()
315         skill1_val = self.frame_view.spin_ctrl_amulet_search_skill1_val.GetValue()
316         skill2_val = self.frame_view.spin_ctrl_amulet_search_skill2_val.GetValue()
317         slot_val = self.frame_view.spin_ctrl_amulet_search_slot_num.GetValue()
318         if self.frame_view.amulet2radio_button_dict[view.NAME_AMULET1].GetValue():
319             amu_id = self._amulet_name2id_dict[view.NAME_AMULET1]
320         elif self.frame_view.amulet2radio_button_dict[view.NAME_AMULET2].GetValue():
321             amu_id = self._amulet_name2id_dict[view.NAME_AMULET2]
322         elif self.frame_view.amulet2radio_button_dict[view.NAME_AMULET3].GetValue():
323             amu_id = self._amulet_name2id_dict[view.NAME_AMULET3]
324         else:
325             raise IndexError(u"amulet id is unknown")
326
327         list_box = self.frame_view.list_box_amulet_search_seeds
328         if skill1_name == skill2_name:
329             self._show_message_dialog(message=u"異なるスキルを選択してください")
330         elif skill1_val == 0:
331             self._show_message_dialog(message=u"第1スキルの値には0以外を指定してください")
332         else:
333             skill1_id = self._skill_name2id_dict[skill1_name]
334             if skill2_name in self._skill_name2id_dict:
335                 skill2_id = self._skill_name2id_dict[skill2_name]
336             else:
337                 skill2_id = None # for skill2 is 0
338             suff_dict = {}
339             tup = self.db_accessor.get_sufficient_value(
340                 amu_id, skill1_id, skill2_id, skill1_val, skill2_val)
341             if tup is not None:
342                 suff_val = tup[0]
343                 seeds_set = self.db_accessor.select_seeds_from_sufficient_val(amu_id, suff_val, slot_val, skill2_id)
344                 if len(seeds_set) > 0:
345                     self.frame_view.text_ctrl_amulet_search_result.SetValue(
346                         u"{0}個のSeedで出現するお守りです".format(len(seeds_set)))
347                     list_box.SetItems([u"{0}".format(seed) for seed in seeds_set])
348                     list_box.SetSelection(0)
349                     self.frame_view.button_amulet_search_skill.Enable()
350                 else:
351                     self.frame_view.text_ctrl_amulet_search_result.SetValue(
352                         u"指定されたお守りは見つかりませんでした")
353                     self.frame_view.button_amulet_search_skill.Disable()
354                     list_box.Clear()
355             else:
356                 self.frame_view.text_ctrl_amulet_search_result.SetValue(
357                     u"エラー。充足値が計算できません")
358                 self.frame_view.button_amulet_search_skill.Disable()
359                 list_box.Clear()
360
361     def OnClickAmuletClear(self, evt):
362         u""" clear amulet conditions """
363         amu_id = self._amulet_name2id_dict[view.NAME_AMULET1]
364         self._set_skill_list_from_amulet(amu_id)
365         self.frame_view.amulet2radio_button_dict[view.NAME_AMULET1].SetValue(True)
366         self.frame_view.button_amulet_search_skill.Disable()
367         self.frame_view.text_ctrl_amulet_search_result.SetValue(u"")
368         self.frame_view.list_box_amulet_search_seeds.Clear()
369
370     def OnClickSkillSearchFromAmulet(self, evt):
371         u""" change page to skill search from amulet"""
372         seed = self.frame_view.list_box_amulet_search_seeds.GetStringSelection()
373         if seed.isdigit():
374             self.frame_view.text_ctrl_seed_select.SetValue(seed)
375             self.frame_view.note_book.SetSelection(view.SKILL_SEARCH_PAGE)
376             self.OnClickSkillSearch(evt)
377
378     def OnClickSettingOK(self, evt):
379         u""" get settings of setting tab """
380         self._highlight_threshold1 = self.frame_view.spin_ctrl_highlight1.GetValue()
381         self._highlight_threshold2 = self.frame_view.spin_ctrl_highlight2.GetValue()
382         self._highlight_skills = set([self._skill_name2id_dict[x] for x in 
383                 self.frame_view.check_list_box_highlight_skill.GetCheckedStrings()
384                 if x in self._skill_name2id_dict])
385         self._update_highlight()
386
387     def OnClickSettingClear(self, evt):
388         u""" reset settings of setting tab """
389         self._highlight_threshold1 = view.HIGHLIGHT_THRESHOLD1
390         self._highlight_threshold2 = view.HIGHLIGHT_THRESHOLD2
391         self.frame_view.spin_ctrl_highlight1.SetValue(view.HIGHLIGHT_THRESHOLD1)
392         self.frame_view.spin_ctrl_highlight2.SetValue(view.HIGHLIGHT_THRESHOLD2)
393         self._highlight_skills = set()
394         for idx in self.frame_view.check_list_box_highlight_skill.GetChecked():
395             self.frame_view.check_list_box_highlight_skill.Check(idx, False)
396         self._update_highlight()
397
398     def _update_highlight(self):
399         u""" update highlight cells """
400         grid = self.frame_view.skill2_grid
401         for key in [view.KEY_AMULET1, view.KEY_AMULET2, view.KEY_AMULET3]:
402             col = view.DICT_SKILL2_GRID_COL[key]
403             for row in range(view.NUM_SKILL2_GRID_ROW):
404                 val = grid.GetCellValue(row, col)
405                 if (val in self._skill_name2id_dict and
406                         self._skill_name2id_dict[val] in self._highlight_skills):
407                     grid.SetCellBackgroundColour(row, col, "Yellow")
408                 else:
409                     grid.SetCellBackgroundColour(row, col, wx.NullColor)
410         col = view.DICT_SKILL2_GRID_COL[view.KEY_THRESHOLD1]
411         for row in range(view.NUM_SKILL2_GRID_ROW):
412             val = grid.GetCellValue(row, col)
413             if val.isdigit() and int(val) >= self._highlight_threshold1:
414                 grid.SetCellBackgroundColour(row, col, "Yellow")
415             else:
416                 grid.SetCellBackgroundColour(row, col, wx.NullColor)
417
418
419     def _show_error_dialog(self, message=u"予期せぬエラーが発生しました", caption=u"エラー"):
420         u""" エラーダイアログを表示し、
421         OKボタンが押されたらアプリケーションを終了する
422         """
423         dlg = wx.MessageDialog(self.frame_view.frame, 
424             message,
425             caption, wx.OK | wx.ICON_ERROR)
426         dlg.ShowModal()
427         dlg.Destroy()
428         wx.Exit()
429     
430     def _show_message_dialog(self, message, caption=u"メッセージ"):
431         u""" メッセージダイアログを表示する
432         """
433         dlg = wx.MessageDialog(self.frame_view.frame, 
434             message,
435             caption, wx.OK | wx.ICON_INFORMATION)
436         dlg.ShowModal()
437         dlg.Destroy()
438
439     def CloseHandler(self, evt):
440         dlg = wx.MessageDialog(parent = self.frame_view.frame,
441                 message = u"終了します。よろしいですか?", 
442                 caption = u"終了確認", 
443                 style = wx.YES_NO)
444         result = dlg.ShowModal()
445         dlg.Destroy()
446         if result == wx.ID_YES:
447             self._write_settings()
448             wx.Exit()
449
450     def OnClose(self, evt):
451         self.frame_view.Close()
452
453     def OnAboutBox(self, evt):
454         info = self.frame_view.GetAboutInfo()
455         wx.AboutBox(info)
456
457     def _write_settings(self):
458         with open(SETTING_FILE, mode="w") as f:
459             data = {SETTING_THRESHOLD1:self._highlight_threshold1, 
460                     SETTING_THRESHOLD2:self._highlight_threshold2, 
461                     SETTING_SKILLS:self._highlight_skills}
462             pickle.dump(data, f)
463
464     def _read_settings(self):
465         if os.path.exists(SETTING_FILE):
466             with open(SETTING_FILE, mode="r") as f:
467                 try:
468                     data = pickle.load(f)
469                     self._highlight_threshold1 = data[SETTING_THRESHOLD1] 
470                     self._highlight_threshold2 = data[SETTING_THRESHOLD2] 
471                     self._highlight_skills = data[SETTING_SKILLS]
472                 except EOFError, e:
473                     self._highlight_threshold1 = view.HIGHLIGHT_THRESHOLD1
474                     self._highlight_threshold2 = view.HIGHLIGHT_THRESHOLD2
475                     self._highlight_skills = set()
476         else:
477             self._highlight_threshold1 = view.HIGHLIGHT_THRESHOLD1
478             self._highlight_threshold2 = view.HIGHLIGHT_THRESHOLD2
479             self._highlight_skills = set()
480
481 if __name__ == "__main__":
482     app = AmuletToolController(False)
483     app.MainLoop()
484