OSDN Git Service

revise amulet search to consider of seed1 value,
[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._init_notebook_seed1()
51         self._init_notebook_seed2()
52         self._init_notebook_skill2()
53         self._init_notebook_setting()
54         self._init_notebook_amulet()
55
56         self.frame_view.EnableNoteBook()
57         return True
58
59     def _init_events(self):
60         u"""イベント登録"""
61         frame = self.frame_view.frame
62
63         # menu event
64         frame.Bind(wx.EVT_MENU, self.OnClose, id=self.frame_view.ID_MENU_ITEM_EXIT)
65         frame.Bind(wx.EVT_MENU, self.OnAboutBox, id=self.frame_view.ID_MENU_ITEM_ABOUT)
66         frame.Bind(wx.EVT_CLOSE, self.CloseHandler)
67
68         # button event
69
70     def _init_database(self):
71         u""" DBの初期設定 """
72
73         if not os.path.exists(model.DB_FILE_NAME):
74             u""" DBが存在しない時は再生成する """
75             frame = self.frame_view.frame
76             try:
77                 generator = model.DataBaseGenerator(model.DB_FILE_NAME)
78                 #generator = model.DataBaseGenerator()
79
80                 dlg_view = view.GaugeDialogView(os.path.join(_get_base_dir(), u"view", view.XRC_GAUGE_DIALOG))
81                 def _loop():
82                     while t1.is_alive():
83                         dlg_view.gauge.Pulse()
84                         time.sleep(0.2)
85                     dlg_view.finish_generation()
86
87                 t1 = threading.Thread(target=generator.generate_db)
88                 t2 = threading.Thread(target=_loop)
89                 t1.start()
90                 t2.start()
91
92                 dlg_view.ShowModal()
93                 t1.join()
94                 t2.join()
95                 dlg_view.Destroy()
96             except sqlite3.Error as e:
97                 self._show_error_dialog(u"データベース生成中にエラーが発生しました")
98
99         # access to db
100         try:
101             self.db_accessor = model.DataBaseAccessor(model.DB_FILE_NAME)
102         except sqlite3.Error as e:
103             self._show_error_dialog(u"データベースが壊れています")
104
105         # get dictionaries
106         (self._skill_id2name_dict, 
107             self._skill_name2id_dict,
108             self._amulet_id2name_dict, 
109             self._amulet_name2id_dict,
110             self._amulet_id2skill1_id_dict,
111             self._amulet_id2skill2_id_dict) = self.db_accessor.get_dicts()
112
113     def _init_notebook_seed1(self):
114         u""" Seed1特定タブのviewの初期化 """
115         self.notebook_seed1_view = self.frame_view.notebook_seed1_view
116         self.notebook_seed1_view.bind_button_search(self.OnClickSeed1Search)
117         self.notebook_seed1_view.bind_button_clear(self.OnClickSeed1Clear)
118
119         u" 各種お守りの第1スキル選択のセット "
120         amu_names, name2skill1s = [], {}
121         for amu_id in sorted(self._amulet_id2name_dict.keys()):
122             name = self._amulet_id2name_dict[amu_id]
123             amu_names.append(name)
124             name2skill1s[name] = [self._skill_id2name_dict[skill_id]
125                     for skill_id in self._amulet_id2skill1_id_dict[amu_id]]
126         self.notebook_seed1_view.set_amuletname_skillnames_dict(amu_names, name2skill1s)
127
128     def _init_notebook_seed2(self):
129         u""" Seed2特定タブのviewの初期化 """
130         self.notebook_seed2_view = self.frame_view.notebook_seed2_view
131         self.notebook_seed2_view.bind_button_search(self.OnClickSeed2Search)
132         self.notebook_seed2_view.bind_button_clear(self.OnClickSeed2Clear)
133         self.notebook_seed2_view.bind_button_skill2(self.OnClickSkill2SearchFromSeed2)
134
135         u" 各種お守りの第2スキル選択 "
136         for amu_key, amu_name in zip([view.KEY_AMULET1, view.KEY_AMULET2, view.KEY_AMULET3], 
137                 [view.NAME_AMULET1, view.NAME_AMULET2, view.NAME_AMULET3]):
138             amu_id = self._amulet_name2id_dict[amu_name]
139             skill_ids = self._amulet_id2skill2_id_dict[amu_id]
140             skill_names = [view.VAL_NO_SKILL] + [self._skill_id2name_dict[x] for x in skill_ids]
141             self.notebook_seed2_view.set_skill_names(amu_key, skill_names)
142         self.notebook_seed2_view.set_skill_selected_idx(0)
143
144     def _init_notebook_skill2(self):
145         u""" Seed2によるSkill2一覧タブのviewの初期化 """
146         self.notebook_skill2_view = self.frame_view.notebook_skill2_view
147         self.notebook_skill2_view.bind_button_search(self.OnClickSkillSearch)
148         self.notebook_skill2_view.bind_button_clear(self.OnClickSkillClear)
149
150     def _update_notebook_amulet(self, amulet_id=None):
151         u""" お守り検索タブのviewの更新
152         amulet_id が Noneでない場合、お守りの種類に応じてComboboxを再設定する
153         また、選択中のスキルに応じて最大最小を設定する"""
154         #min1, max1, min2, max2 = self.db_accessor.get_skill_minmax()
155         #self.notebook_amulet_view.set_skill_minmax(min1, max1, min2, max2)
156
157         if amulet_id is not None:
158             for i, skill_dict in enumerate([self._amulet_id2skill1_id_dict, self._amulet_id2skill2_id_dict]):
159                 skill_ids = skill_dict[amulet_id]
160                 skill_names = [self._skill_id2name_dict[_id] for _id in skill_ids]
161                 if i == 0:
162                     self.notebook_amulet_view.set_items_skill1_combobox(skill_names)
163                     skill1_selected = skill_ids[0]
164                     self.notebook_amulet_view.set_selection_skill1_combobox(0)
165                 elif i == 1:
166                     self.notebook_amulet_view.set_items_skill2_combobox([view.VAL_NO_SKILL] + skill_names)
167                     self.notebook_amulet_view.set_selection_skill2_combobox(0)  # select No Skill
168         else:
169             amulet_name = self.notebook_amulet_view.get_selected_amulet()
170             amulet_id = self._amulet_name2id_dict[amulet_name]
171
172         # settting min max
173         skill1_str = self.notebook_amulet_view.get_string_selection_skill1_combobox()
174         skill2_str = self.notebook_amulet_view.get_string_selection_skill2_combobox()
175         skill1_id = self._skill_name2id_dict[skill1_str] if skill1_str in self._skill_name2id_dict else None
176         skill2_id = self._skill_name2id_dict[skill2_str] if skill2_str in self._skill_name2id_dict else None
177
178         if skill2_id is None:
179             minmax_dict = self.db_accessor.select_minmax_from_skill_ids(amulet_id, [skill1_id])
180             min1, max1 = minmax_dict[skill1_id][0], minmax_dict[skill1_id][1]
181             min2, max2 = 0, 0
182         else:
183             minmax_dict = self.db_accessor.select_minmax_from_skill_ids(amulet_id, [skill1_id, skill2_id])
184             min1, max1 = minmax_dict[skill1_id][0], minmax_dict[skill1_id][1]
185             min2, max2 = minmax_dict[skill2_id][2], minmax_dict[skill2_id][3]
186         self.notebook_amulet_view.set_skill_minmax(min1, max1, min2, max2)
187
188     def _update_notebook_amulet_seed2s(self):
189         u"""お守り検索タブのSeed2リストを更新する"""
190         threshold_type = self.notebook_amulet_view.get_selected_threshold_type()
191         if threshold_type == view.THRESHOLD_TYPE_ALL:
192             include_th1, include_th2, include_ini = True, True, True
193         elif threshold_type == view.THRESHOLD_TYPE_THRESHOLD1:
194             include_th1, include_th2, include_ini = True, False, False
195         elif threshold_type == view.THRESHOLD_TYPE_THRESHOLD2:
196             include_th1, include_th2, include_ini = False, True, False
197         elif threshold_type == view.THRESHOLD_TYPE_INISHIE:
198             include_th1, include_th2, include_ini = False, False, True
199
200         set_items_dict = {}
201         seed2_set = self.threshold1_seed2_set | self.threshold2_seed2_set | self.threshold_inishie_set
202         for seed2 in seed2_set:
203             type_set, include = [], False
204             if seed2 in self.threshold1_seed2_set:
205                 type_set.append(u"判定値1")
206                 if include_th1:
207                     include = True
208             if seed2 in self.threshold2_seed2_set:
209                 type_set.append(u"判定値2")
210                 if include_th2:
211                     include = True
212             if seed2 in self.threshold_inishie_set: # seed in inishie_set
213                 type_set.append(u"いにしえ")
214                 if include_ini:
215                     include = True
216             if include:
217                 if seed2 in self.seed2_tenun_num_dict:
218                     tenun555_num, tenun888_num = self.seed2_tenun_num_dict[seed2]
219                 else:
220                     tenun555_num, tenun888_num = 0, 0
221                 set_items_dict[seed2] = (u",".join(type_set), tenun555_num, tenun888_num)
222
223         self.notebook_amulet_view.set_grid_seed2s_items(set_items_dict)
224         if len(set_items_dict) > 0:
225             self.notebook_amulet_view.set_grid_seed2s_selected_idx(0)
226             self.notebook_amulet_view.set_skill_button_enable(True)
227         else:
228             self.notebook_amulet_view.set_skill_button_enable(False)
229
230     def _init_notebook_amulet(self):
231         u""" お守り検索タブの初期設定 """
232         self.notebook_amulet_view = self.frame_view.notebook_amulet_view
233         self.notebook_amulet_view.bind_radiobox_amulet(self.OnClickAmuletRadioAmulet)
234         self.notebook_amulet_view.bind_radiobox_threshold_type(self.OnClickAmuletRadioThresholdType)
235         self.notebook_amulet_view.bind_combobox(self.OnClickAmuletCombo)
236         self.notebook_amulet_view.bind_button_search(self.OnClickAmuletSearch)
237         self.notebook_amulet_view.bind_button_clear(self.OnClickAmuletClear)
238         self.notebook_amulet_view.bind_button_skill(self.OnClickSkillSearchFromAmulet)
239
240         amu_id = self._amulet_name2id_dict[view.NAME_AMULET1]
241         self.notebook_amulet_view.set_radio_value(True, view.NAME_AMULET1)
242         self._update_notebook_amulet(amu_id)
243
244         self.threshold1_seed2_set, self.threshold2_seed2_set, self.threshold_inishie_set = set(), set(), set()
245         self.seed2_tenun_num_dict = {}
246         self._amulet_values = None
247
248     def _init_notebook_setting(self):
249         u""" 設定タブの初期設定 """
250         self.notebook_setting_view = self.frame_view.notebook_setting_view
251         self.notebook_setting_view.bind_button_ok(self.OnClickSettingOK)
252         self.notebook_setting_view.bind_button_clear(self.OnClickSettingClear)
253         self.notebook_setting_view.set_skill_strings(self._skill_name2id_dict.keys())
254         self._update_notebook_setting()
255
256     def _update_notebook_setting(self):
257         u"""設定タブの値更新"""
258         self.notebook_setting_view.set_threshold(self._highlight_threshold1, 
259                 self._highlight_threshold2)
260         self.notebook_setting_view.set_checked_strings([self._skill_id2name_dict[x] for x in self._highlight_skills])
261
262     def _update_highlight(self):
263         u""" update highlight cells """
264         skill_names = [self._skill_id2name_dict[x] for x in self._highlight_skills]
265         self.notebook_skill2_view.set_skill2_highlight(
266                 skill_names, self._highlight_threshold1, self._highlight_threshold2)
267         self.notebook_seed1_view.update_highlight(skill_names)
268
269     u""" Seed1 view's event"""
270     def OnClickSeed1Search(self, evt):
271         u""" search seed1s from selected skill1s """
272         tenun_key = self.notebook_seed1_view.get_tenun_radio_key()
273         amu_skill_name_list = self.notebook_seed1_view.get_selected_amulets_and_names()
274         if tenun_key == view.KEY_TENUN555:
275             tenun_key = model.KEY_TENUN555
276         elif tenun_key == view.KEY_TENUN888:
277             tenun_key = model.KEY_TENUN888
278         else:
279             raise KeyError(u"key '{0}' not found in TENUN KEYS".format(tenun_key))
280         amu_skill_id_list = [(self._amulet_name2id_dict[x], self._skill_name2id_dict[y]) for x, y in amu_skill_name_list]
281         seed1s = self.db_accessor.select_seed1s_tenun(amu_skill_id_list, tenun_key)
282         if len(seed1s) == 0:
283             self.notebook_seed1_view.set_text_result(u"条件に一致するSeed1は見つかりません")
284             self.notebook_seed1_view.clear_seed1_grid()
285         elif len(seed1s) == 1:
286             seed1 = [x for x in seed1s][0]
287             table_no, no = self.db_accessor.select_table_nos_from_seed1(seed1s, tenun_key)[seed1]
288             self.notebook_seed1_view.set_text_result(
289                     u"Seed1: {0}, テーブルNo: {1}, 通し番号: {2}".format(seed1, table_no, no))
290             # list of (no, seed1)
291             near_num = view.NEAR_SEED1_NUMBERS
292             no_seed1_list = self.db_accessor.select_near_seed1s_from_seed1(
293                     seed1, near_num, near_num, tenun_key)
294             seed1_list = [x[1] for x in no_seed1_list]
295
296             # seed1 -> (no, table_no, result_num, amu_ids, skill_id2)
297             result_dict = self.db_accessor.select_all_from_seed1s(seed1_list, tenun_key)
298             for key, val in result_dict.items():
299                 _no, _table_no, _result_num, _amu_ids, _skill_ids = val
300                 _amu_names = [self._amulet_id2name_dict[x] 
301                         if x in self._amulet_id2name_dict else None for x in _amu_ids]
302                 _skill_names = [self._skill_id2name_dict[x] 
303                         if x in self._skill_id2name_dict else None for x in _skill_ids]
304                 result_dict[key] = (_no, _table_no, _result_num, _amu_names, _skill_names)
305             self.notebook_seed1_view.set_seed1_dict(result_dict, seed1)
306             skill_names = [self._skill_id2name_dict[x] for x in self._highlight_skills]
307             self.notebook_seed1_view.update_highlight(skill_names)
308         else:
309             self.notebook_seed1_view.set_text_result(
310                     u"Seed1は{0}件あります。条件を絞ってください".format(len(seed1s)))
311             self.notebook_seed1_view.clear_seed1_grid()
312
313     def OnClickSeed1Clear(self, evt):
314         u""" clear seed1s from selected skill1s """
315         self.notebook_seed1_view.clear_combobox()
316         self.notebook_seed1_view.clear_seed1_grid()
317         self.notebook_seed1_view.clear_text_result()
318
319     u""" Seed2 view's event """
320     def OnClickSeed2Search(self, evt):
321         u""" search seed2s from selected skill2s """
322         amu_id2skill_id_list_dict = {}
323         for amu_key, amu_name in zip([view.KEY_AMULET1, view.KEY_AMULET2, view.KEY_AMULET3], 
324                 [view.NAME_AMULET1, view.NAME_AMULET2, view.NAME_AMULET3]):
325             amu_id = self._amulet_name2id_dict[amu_name]
326             names = self.notebook_seed2_view.get_selected_skill_names(amu_key)
327             ls = [self._skill_name2id_dict[name] if name in self._skill_name2id_dict else None 
328                     for name in names]
329             amu_id2skill_id_list_dict[amu_id] = ls
330         seed_sets = self.db_accessor.select_seed2s(amu_id2skill_id_list_dict)
331         self.notebook_seed2_view.set_result_text(u"""Seedの候補は{0}個です。""".format(len(seed_sets)))
332
333         if len(seed_sets) > 0:
334             self.notebook_seed2_view.set_seed_lists([u"{0:06d}".format(seed) for seed in seed_sets])
335             self.notebook_seed2_view.set_skill2_button_enable(True)
336         else:
337             self.notebook_seed2_view.clear_seed_list()
338             self.notebook_seed2_view.set_skill2_button_enable(False)
339
340     def OnClickSeed2Clear(self, evt):
341         u""" reset seed2 search settings of combo box"""
342         self.notebook_seed2_view.set_skill_selected_idx(0)
343         self.notebook_seed2_view.clear_seed_list()
344         self.notebook_seed2_view.set_result_text(u"")
345         self.notebook_seed2_view.set_skill2_button_enable(False)
346
347     def OnClickSkill2SearchFromSeed2(self, evt):
348         u""" change page to skill2 search from seed2"""
349         seed2 = self.notebook_seed2_view.get_selected_seed2()
350         if seed2 is not None:
351             self.notebook_skill2_view.set_seed2_value(seed2)
352             self.frame_view.note_book.SetSelection(view.SKILL_SEARCH_PAGE)
353             self.OnClickSkillSearch(evt)
354
355     u""" Skill2 search from Seed2's event """
356     def OnClickSkillSearch(self, evt):
357         u""" skill search from seed2"""
358         seed2 = self.notebook_skill2_view.get_seed2_value()
359         if seed2 is not None:
360             skill_dict, threshold1_dict, threshold2_dict = self.db_accessor.select_skill2s_from_seed2s([seed2])
361             try:
362                 for amu_key, amu_name in zip([view.KEY_AMULET1, view.KEY_AMULET2, view.KEY_AMULET3], 
363                         [view.NAME_AMULET1, view.NAME_AMULET2, view.NAME_AMULET3]):
364                     amu_id = self._amulet_name2id_dict[amu_name]
365                     skill_names = [self._skill_id2name_dict[x] for x in skill_dict[amu_id][seed2]]
366                     self.notebook_skill2_view.set_skill2_by_col_key(amu_key, skill_names)
367                 th_vals = [u"{0}".format(x) for x in threshold1_dict[seed2]]
368                 self.notebook_skill2_view.set_skill2_by_col_key(view.KEY_THRESHOLD1, th_vals)
369                 th_vals = [u"{0}".format(x) for x in threshold2_dict[seed2]]
370                 self.notebook_skill2_view.set_skill2_by_col_key(view.KEY_THRESHOLD2, th_vals)
371                 #inishie
372                 skill_id, th1, th2 = self.db_accessor.select_inishie_skill2_from_seed2([seed2])[seed2]
373                 self.notebook_skill2_view.set_inishie(self._skill_id2name_dict[skill_id], th1, th2)
374                 # explanation
375                 table_no, no = self.db_accessor.select_table_nos_from_seed2([seed2])[seed2]
376                 self.notebook_skill2_view.set_result_text(
377                         u"SEED2:{2}は通し番号{1}、テーブルNo{0}です".format(table_no, no, seed2))
378             except KeyError, e:
379                 self._show_message_dialog(message=u"指定されたSeed値は存在しません")
380             finally:
381                 self._update_highlight()
382
383         else:
384             self._show_message_dialog(message=u"Seed値には数字を入力してください")
385
386     def OnClickSkillClear(self, evt):
387         u""" clear skills from seed """
388         self.notebook_skill2_view.clear_skill2_grid()
389         self.notebook_skill2_view.clear_skill2_highlight()
390         self.notebook_skill2_view.clear_items_amulet_prospects()
391         self.notebook_skill2_view.clear_result_text()
392         self.notebook_skill2_view.clear_inishie()
393
394     u""" amulet search event """
395     def OnClickAmuletRadioAmulet(self, evt):
396         u""" switch skill lists by amulet id """
397         #btn_id = evt.GetId()
398         amulet_name = self.notebook_amulet_view.get_selected_amulet()
399         amu_id = self._amulet_name2id_dict[amulet_name]
400         self._update_notebook_amulet(amu_id)
401         self.notebook_amulet_view.set_result_text_ctrl_value(u"")
402         self.notebook_amulet_view.set_skill_button_enable(False)
403         self.notebook_amulet_view.clear_grid()
404
405     def OnClickAmuletRadioThresholdType(self, evt):
406         u""" switch seed lists by threshold_type """
407         self._update_notebook_amulet_seed2s()
408
409     def OnClickAmuletCombo(self, evt):
410         u""" switch skill minmax by amulet id and skill_id"""
411         self._update_notebook_amulet()
412
413     def OnClickAmuletSearch(self, evt):
414         u""" search seeds from amulet condition """
415         skill1_name, skill2_name = self.notebook_amulet_view.get_string_selection_skill_names()
416         skill1_val, skill2_val = self.notebook_amulet_view.get_skill_values()
417         slot_val = self.notebook_amulet_view.get_slot_value()
418         amulet_name = self.notebook_amulet_view.get_selected_amulet()
419         amu_id = self._amulet_name2id_dict[amulet_name]
420
421         if skill1_name == skill2_name:
422             self._show_message_dialog(message=u"異なるスキルを選択してください")
423         elif skill1_val == 0:
424             self._show_message_dialog(message=u"第1スキルの値には0以外を指定してください")
425         else:
426             skill1_id = self._skill_name2id_dict[skill1_name]
427             if skill2_name in self._skill_name2id_dict:
428                 skill2_id = self._skill_name2id_dict[skill2_name]
429             else:
430                 skill2_id = None # for skill2 is 0
431             suff_dict = {}
432             tup = self.db_accessor.get_sufficient_value(
433                 amu_id, skill1_id, skill2_id, skill1_val, skill2_val)
434             if tup is not None:
435                 suff_val = tup[0]
436                 (threshold, self.threshold1_seed2_set, self.threshold2_seed2_set, 
437                     self.threshold_inishie_set) = self.db_accessor.select_seed2s_from_sufficient_val(
438                         amu_id, suff_val, slot_val, skill2_id)
439                 seed2_set = self.threshold1_seed2_set | self.threshold2_seed2_set
440
441                 # filter seed2s by skill1_id
442                 filtered_seed2_dict = {} # seeds -> (num555, num888)
443                 for seed2 in seed2_set:
444                     places = self.db_accessor.select_skill2_place(amu_id, seed2, skill2_id)
445                     num_555, num_888 = self.db_accessor.count_seed1s_from_skill_place(skill1_id, places, amu_id)
446                     if num_555 > 0 or num_888 > 0:
447                         filtered_seed2_dict[seed2] = (num_555, num_888)
448                 seed2_set = set(filtered_seed2_dict.keys())
449                 self.seed2_tenun_num_dict = filtered_seed2_dict
450                 self.threshold1_seed2_set = seed2_set & self.threshold1_seed2_set
451                 self.threshold2_seed2_set = seed2_set & self.threshold2_seed2_set
452                 u""" self.threshold_inishie_set についてはSeed1との対応が不明なのでそのまま使用する"""
453
454                 self._amulet_values = (skill1_id, skill2_id, skill1_val, skill2_val)
455                 self._update_notebook_amulet_seed2s()
456                 if len(seed2_set) > 0:
457                     self.notebook_amulet_view.set_result_text_ctrl_value(
458 u"""指定されたお守りの充足値:\t{0}
459 必要な判定値:\t{1}\n判定値1:\t{2}個のSeed2で出現\n判定値2:\t{3}個のSeed2で出現\nいにしえ:\t{4}個のSeed2で出現
460 判定値1,2:\t{5}個のSeed2で出現""".format(
461                             suff_val, threshold, len(self.threshold1_seed2_set), len(self.threshold2_seed2_set), len(self.threshold_inishie_set), len(seed2_set)))
462                 else:
463                     self.threshold1_seed2_set, self.threshold2_seed2_set, self.threshold_inishie_set = set(), set(), set()
464                     self.notebook_amulet_view.set_result_text_ctrl_value(
465 u"""指定されたお守りの充足値:\t{0}\n必要な判定値:\t{1}
466 指定されたお守りは見つかりませんでした""".format(suff_val, threshold))
467                     self.notebook_amulet_view.set_skill_button_enable(False)
468                     self.notebook_amulet_view.clear_grid()
469                     self._amulet_values = None
470                     self.seed2_tenun_num_dict = {}
471             else:
472                 self.threshold1_seed2_set, self.threshold2_seed2_set, self.threshold_inishie_set = set(), set(), set()
473                 self.notebook_amulet_view.set_result_text_ctrl_value(
474                     u"エラー。充足値が計算できません")
475                 self.notebook_amulet_view.set_skill_button_enable(False)
476                 self.notebook_amulet_view.clear_grid()
477                 self._amulet_values = None
478                 self.seed2_tenun_num_dict = {}
479
480     def OnClickAmuletClear(self, evt):
481         u""" clear amulet conditions """
482         self.threshold1_seed2_set, self.threshold2_seed2_set, self.threshold_inishie_set = set(), set(), set()
483         self._amulet_values = None
484         self.seed2_tenun_num_dict = {}
485         self.notebook_amulet_view.set_radio_value(True, view.NAME_AMULET1)
486         amu_id = self._amulet_name2id_dict[view.NAME_AMULET1]
487         self._update_notebook_amulet(amu_id)
488         self.notebook_amulet_view.set_skill_button_enable(False)
489         self.notebook_amulet_view.set_result_text_ctrl_value(u"")
490         self.notebook_amulet_view.clear_grid()
491
492     def OnClickSkillSearchFromAmulet(self, evt):
493         u""" change page to skill search from amulet"""
494         seed = self.notebook_amulet_view.get_grid_selected_seed2()
495         if seed is not None:
496             self.notebook_skill2_view.set_seed2_value(seed)
497             self.frame_view.note_book.SetSelection(view.SKILL_SEARCH_PAGE)
498             self.OnClickSkillSearch(evt)
499
500     u""" settings' event """
501     def OnClickSettingOK(self, evt):
502         u""" get settings of setting tab """
503         (self._highlight_threshold1, 
504                 self._highlight_threshold2) = self.frame_view.notebook_setting_view.get_threshold()
505         self._highlight_skills = set([self._skill_name2id_dict[x] for x in 
506                 self.frame_view.notebook_setting_view.get_checked_strings()
507                 if x in self._skill_name2id_dict])
508         self._update_highlight()
509
510     def OnClickSettingClear(self, evt):
511         u""" reset settings of setting tab """
512         self._highlight_threshold1 = view.HIGHLIGHT_THRESHOLD1
513         self._highlight_threshold2 = view.HIGHLIGHT_THRESHOLD2
514         self._highlight_skills = set()
515         self._update_notebook_setting()
516         self._update_highlight()
517
518
519     def _show_error_dialog(self, message=u"予期せぬエラーが発生しました", caption=u"エラー"):
520         u""" エラーダイアログを表示し、
521         OKボタンが押されたらアプリケーションを終了する
522         """
523         dlg = wx.MessageDialog(self.frame_view.frame, 
524             message,
525             caption, wx.OK | wx.ICON_ERROR)
526         dlg.ShowModal()
527         dlg.Destroy()
528         wx.Exit()
529     
530     def _show_message_dialog(self, message, caption=u"メッセージ"):
531         u""" メッセージダイアログを表示する
532         """
533         dlg = wx.MessageDialog(self.frame_view.frame, 
534             message,
535             caption, wx.OK | wx.ICON_INFORMATION)
536         dlg.ShowModal()
537         dlg.Destroy()
538
539     def CloseHandler(self, evt):
540         dlg = wx.MessageDialog(parent = self.frame_view.frame,
541                 message = u"終了します。よろしいですか?", 
542                 caption = u"終了確認", 
543                 style = wx.YES_NO)
544         result = dlg.ShowModal()
545         dlg.Destroy()
546         if result == wx.ID_YES:
547             self._write_settings()
548             wx.Exit()
549
550     def OnClose(self, evt):
551         self.frame_view.Close()
552
553     def OnAboutBox(self, evt):
554         info = self.frame_view.GetAboutInfo()
555         wx.AboutBox(info)
556
557     def _write_settings(self):
558         with open(SETTING_FILE, mode="w") as f:
559             data = {SETTING_THRESHOLD1:self._highlight_threshold1, 
560                     SETTING_THRESHOLD2:self._highlight_threshold2, 
561                     SETTING_SKILLS:self._highlight_skills}
562             pickle.dump(data, f)
563
564     def _read_settings(self):
565         if os.path.exists(SETTING_FILE):
566             with open(SETTING_FILE, mode="r") as f:
567                 try:
568                     data = pickle.load(f)
569                     self._highlight_threshold1 = data[SETTING_THRESHOLD1] 
570                     self._highlight_threshold2 = data[SETTING_THRESHOLD2] 
571                     self._highlight_skills = data[SETTING_SKILLS]
572                 except EOFError, e:
573                     self._highlight_threshold1 = view.HIGHLIGHT_THRESHOLD1
574                     self._highlight_threshold2 = view.HIGHLIGHT_THRESHOLD2
575                     self._highlight_skills = set()
576         else:
577             self._highlight_threshold1 = view.HIGHLIGHT_THRESHOLD1
578             self._highlight_threshold2 = view.HIGHLIGHT_THRESHOLD2
579             self._highlight_skills = set()
580
581 if __name__ == "__main__":
582     app = AmuletToolController(False)
583     app.MainLoop()
584