155
|
1 # Copyright (C) 2000-2001 The OpenRPG Project
|
|
2 #
|
|
3 # openrpg-dev@lists.sourceforge.net
|
|
4 #
|
|
5 # This program is free software; you can redistribute it and/or modify
|
|
6 # it under the terms of the GNU General Public License as published by
|
|
7 # the Free Software Foundation; either version 2 of the License, or
|
|
8 # (at your option) any later version.
|
|
9 #
|
|
10 # This program is distributed in the hope that it will be useful,
|
|
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 # GNU General Public License for more details.
|
|
14 #
|
|
15 # You should have received a copy of the GNU General Public License
|
|
16 # along with this program; if not, write to the Free Software
|
|
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
18 # --
|
|
19 #
|
|
20 # File: gametree.py
|
|
21 # Author: Chris Davis
|
|
22 # Maintainer:
|
|
23 # Version:
|
|
24 # $Id: gametree.py,v 1.68 2007/12/07 20:39:48 digitalxero Exp $
|
|
25 #
|
|
26 # Description: The file contains code fore the game tree shell
|
|
27 #
|
173
|
28 # Traipse EZ_Tree Reference System (TaS - Prof.Ebral):
|
|
29 #
|
|
30 # The new EZ_Tree Reference System being implemented takes full advantage of
|
|
31 # Python's OOP Language. The entire tree code is being reused, but a new ID is
|
|
32 # being created which 'shuts off' some of the features of the tree and adds new ones.
|
|
33 # This new feature will allow users to quickly add a Reference button to new node
|
|
34 # handlers. The button will show a faximile of the tree and users can then create a
|
|
35 # node reference with ease!
|
|
36 #
|
155
|
37
|
|
38 from __future__ import with_statement
|
|
39
|
|
40 __version__ = "$Id: gametree.py,v 1.68 2007/12/07 20:39:48 digitalxero Exp $"
|
|
41
|
|
42 from orpg.orpg_wx import *
|
|
43 from orpg.orpg_windows import *
|
|
44 from orpg.orpgCore import component
|
|
45 from orpg.dirpath import dir_struct
|
|
46 from nodehandlers import core
|
|
47 import string, urllib, time, os
|
|
48
|
|
49 from orpg.orpg_xml import xml
|
|
50 from orpg.tools.validate import validate
|
|
51 from orpg.tools.orpg_log import logger, debug
|
|
52 from orpg.tools.orpg_settings import settings
|
|
53 from orpg.gametree.nodehandlers import containers, forms, dnd3e, dnd35, chatmacro
|
|
54 from orpg.gametree.nodehandlers import map_miniature_nodehandler
|
|
55 from orpg.gametree.nodehandlers import minilib, rpg_grid, d20, StarWarsd20, voxchat
|
|
56
|
|
57 from gametree_version import GAMETREE_VERSION
|
|
58
|
|
59 from xml.etree.ElementTree import ElementTree, Element, parse
|
|
60 from xml.etree.ElementTree import fromstring, tostring, XML, iselement
|
|
61 from xml.parsers.expat import ExpatError
|
|
62
|
|
63 STD_MENU_DELETE = wx.NewId()
|
|
64 STD_MENU_DESIGN = wx.NewId()
|
|
65 STD_MENU_USE = wx.NewId()
|
|
66 STD_MENU_PP = wx.NewId()
|
|
67 STD_MENU_RENAME = wx.NewId()
|
|
68 STD_MENU_SEND = wx.NewId()
|
|
69 STD_MENU_SAVE = wx.NewId()
|
|
70 STD_MENU_ICON = wx.NewId()
|
|
71 STD_MENU_CLONE = wx.NewId()
|
|
72 STD_MENU_ABOUT = wx.NewId()
|
|
73 STD_MENU_HTML = wx.NewId()
|
|
74 STD_MENU_EMAIL = wx.NewId()
|
|
75 STD_MENU_CHAT = wx.NewId()
|
|
76 STD_MENU_WHISPER = wx.NewId()
|
|
77 STD_MENU_WIZARD = wx.NewId()
|
|
78 STD_MENU_NODE_SUBMENU = wx.NewId()
|
|
79 STD_MENU_NODE_USEFUL = wx.NewId()
|
|
80 STD_MENU_NODE_USELESS = wx.NewId()
|
|
81 STD_MENU_NODE_INDIFFERENT = wx.NewId()
|
|
82 STD_MENU_MAP = wx.NewId()
|
|
83 TOP_IFILE = wx.NewId()
|
|
84 TOP_INSERT_URL = wx.NewId()
|
|
85 TOP_NEW_TREE = wx.NewId()
|
|
86 TOP_SAVE_TREE = wx.NewId()
|
|
87 TOP_SAVE_TREE_AS = wx.NewId()
|
|
88 TOP_TREE_PROP = wx.NewId()
|
|
89 TOP_FEATURES = wx.NewId()
|
173
|
90 EZ_REF = wx.NewId()
|
155
|
91
|
|
92 class game_tree(wx.TreeCtrl):
|
|
93
|
|
94 def __init__(self, parent, id):
|
173
|
95 wx.TreeCtrl.__init__(self,parent,id, wx.DefaultPosition,
|
155
|
96 wx.DefaultSize,style=wx.TR_EDIT_LABELS | wx.TR_HAS_BUTTONS)
|
153
|
97 self.chat = component.get('chat')
|
155
|
98 self.session = component.get('session')
|
|
99 self.mainframe = component.get('frame')
|
173
|
100 self.ez_ref = True if id == EZ_REF else False
|
155
|
101 self.build_img_list()
|
173
|
102 if not self.ez_ref: self.build_std_menu()
|
155
|
103 self.nodehandlers = {}
|
|
104 self.nodes = {}
|
|
105 self.init_nodehandlers()
|
173
|
106 if not self.ez_ref:
|
|
107 self.Bind(wx.EVT_LEFT_DCLICK, self.on_ldclick)
|
|
108 self.Bind(wx.EVT_RIGHT_DOWN, self.on_rclick)
|
|
109 self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.on_drag, id=id)
|
|
110 self.Bind(wx.EVT_LEFT_UP, self.on_left_up)
|
|
111 self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
|
|
112 self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.on_label_change, id=self.GetId())
|
|
113 self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.on_label_begin, id=self.GetId())
|
|
114 self.Bind(wx.EVT_CHAR, self.on_char)
|
|
115 self.Bind(wx.EVT_KEY_UP, self.on_key_up)
|
155
|
116 self.id = 1
|
|
117 self.dragging = False
|
|
118 self.last_save_dir = dir_struct["user"]
|
|
119 self.tree_map = {}
|
|
120
|
|
121 #Create tree from default if it does not exist
|
|
122 validate.config_file("tree.xml","default_tree.xml")
|
173
|
123
|
|
124 ## The EZ_Tree Reference creates a duplicate component called tree_back. This is because the
|
|
125 ## tree wont parse fully without adding the component, and when a dupplicate component is created
|
|
126 ## the older one is deleted. If there are an C++ errors the tree_back can be used as a failsafe
|
|
127
|
178
|
128 if not self.ez_ref: component.add("tree", self); component.add('tree_fs', self) ## Fail Safe
|
173
|
129 component.add('tree', self)
|
155
|
130
|
|
131 #build tree
|
|
132 self.root = self.AddRoot("Game Tree", self.icons['gear'])
|
|
133 self.was_labeling = 0
|
|
134 self.rename_flag = 0
|
|
135 self.image_cache = {}
|
|
136 logger.debug("Exit game_tree")
|
|
137
|
|
138 def add_nodehandler(self, nodehandler, nodeclass):
|
|
139 if not self.nodehandlers.has_key(nodehandler): self.nodehandlers[nodehandler] = nodeclass
|
|
140 else: logger.debug("Nodehandler for " + nodehandler + " already exists!")
|
|
141
|
|
142 def remove_nodehandler(self, nodehandler):
|
|
143 if self.nodehandlers.has_key(nodehandler): del self.nodehandlers[nodehandler]
|
|
144 else: logger.debug("No nodehandler for " + nodehandler + " exists!")
|
|
145
|
|
146 def init_nodehandlers(self):
|
|
147 self.add_nodehandler('group_handler', containers.group_handler)
|
|
148 self.add_nodehandler('tabber_handler', containers.tabber_handler)
|
|
149 self.add_nodehandler('splitter_handler', containers.splitter_handler)
|
|
150 self.add_nodehandler('form_handler', forms.form_handler)
|
|
151 self.add_nodehandler('textctrl_handler', forms.textctrl_handler)
|
|
152 self.add_nodehandler('listbox_handler', forms.listbox_handler)
|
|
153 self.add_nodehandler('link_handler', forms.link_handler)
|
|
154 self.add_nodehandler('webimg_handler', forms.webimg_handler)
|
|
155 self.add_nodehandler('dnd3echar_handler', dnd3e.dnd3echar_handler)
|
|
156 self.add_nodehandler('dnd35char_handler', dnd35.dnd35char_handler)
|
|
157 self.add_nodehandler('macro_handler', chatmacro.macro_handler)
|
|
158 self.add_nodehandler('map_miniature_handler', map_miniature_nodehandler.map_miniature_handler)
|
|
159 self.add_nodehandler('minilib_handler', minilib.minilib_handler)
|
|
160 self.add_nodehandler('mini_handler', minilib.mini_handler)
|
|
161 self.add_nodehandler('rpg_grid_handler', rpg_grid.rpg_grid_handler)
|
|
162 self.add_nodehandler('d20char_handler', d20.d20char_handler)
|
|
163 self.add_nodehandler('SWd20char_handler', StarWarsd20.SWd20char_handler)
|
|
164 self.add_nodehandler('voxchat_handler', voxchat.voxchat_handler)
|
|
165 self.add_nodehandler('file_loader', core.file_loader)
|
|
166 self.add_nodehandler('node_loader', core.node_loader)
|
|
167 self.add_nodehandler('url_loader', core.url_loader)
|
|
168 self.add_nodehandler('min_map', core.min_map)
|
|
169
|
|
170 def on_key_up(self, evt):
|
|
171 key_code = evt.GetKeyCode()
|
|
172 if self.dragging and (key_code == wx.WXK_SHIFT):
|
|
173 curSelection = self.GetSelection()
|
|
174 cur = wx.StockCursor(wx.CURSOR_ARROW)
|
|
175 self.SetCursor(cur)
|
|
176 self.dragging = False
|
|
177 obj = self.GetPyData(curSelection)
|
|
178 self.SelectItem(curSelection)
|
|
179 if(isinstance(obj,core.node_handler)):
|
|
180 obj.on_drop(evt)
|
|
181 self.drag_obj = None
|
|
182 evt.Skip()
|
|
183
|
|
184 def on_char(self, evt):
|
|
185 key_code = evt.GetKeyCode()
|
|
186 curSelection = self.GetSelection() # Get the current selection
|
|
187 if evt.ShiftDown() and ((key_code == wx.WXK_UP) or (key_code == wx.WXK_DOWN)) and not self.dragging:
|
|
188 curSelection = self.GetSelection()
|
|
189 obj = self.GetPyData(curSelection)
|
|
190 self.SelectItem(curSelection)
|
|
191 if(isinstance(obj,core.node_handler)):
|
|
192 self.dragging = True
|
|
193 cur = wx.StockCursor(wx.CURSOR_HAND)
|
|
194 self.SetCursor(cur)
|
|
195 self.drag_obj = obj
|
|
196 elif key_code == wx.WXK_LEFT: self.Collapse(curSelection)
|
|
197 elif key_code == wx.WXK_DELETE: # Handle the delete key
|
|
198 if curSelection:
|
|
199 nextSelect = self.GetItemParent(curSelection)
|
|
200 self.on_del(evt)
|
151
|
201 try:
|
155
|
202 if self.GetItemText(nextSelect) != "": self.SelectItem(nextSelect)
|
|
203 except: pass
|
|
204 elif key_code == wx.WXK_F2:
|
|
205 self.rename_flag = 1
|
|
206 self.EditLabel(curSelection)
|
|
207 evt.Skip()
|
|
208
|
|
209 def locate_valid_tree(self, error, msg): ## --Snowdog 3/05
|
|
210 """prompts the user to locate a new tree file or create a new one"""
|
|
211 response = wx.MessageDialog(self, msg, error, wx.YES|wx.NO|wx.ICON_ERROR)
|
|
212 if response == wx.YES:
|
|
213 file = None
|
|
214 dlg = wx.FileDialog(self, "Locate Gametree file", dir_struct["user"],
|
|
215 filename[ ((filename.rfind(os.sep))+len(os.sep)):],
|
|
216 "Gametree (*.xml)|*.xml|All files (*.*)|*.*",
|
|
217 wx.OPEN | wx.CHANGE_DIR)
|
|
218 if dlg.ShowModal() == wx.ID_OK: file = dlg.GetPath()
|
|
219 dlg.Destroy()
|
|
220 if not file: self.load_tree(error=1)
|
|
221 else: self.load_tree(file)
|
|
222 return
|
|
223 else:
|
|
224 validate.config_file("tree.xml","default_tree.xml")
|
|
225 self.load_tree(error=1)
|
|
226 return
|
|
227
|
|
228 def load_tree(self, filename=dir_struct["user"]+'tree.xml', error=0):
|
|
229 settings.change("gametree", filename)
|
|
230 if not os.path.exists(filename):
|
|
231 emsg = "Gametree Missing!\n"+filename+" cannot be found.\n\n"\
|
|
232 "Would you like to locate it?\n"\
|
|
233 "(Selecting 'No' will cause a new default gametree to be generated)"
|
|
234 self.locate_valid_tree("Gametree Error", emsg)
|
|
235 return
|
|
236 try:
|
|
237 tree = parse(filename)
|
|
238 self.xml_root = tree.getroot()
|
|
239 except:
|
|
240 self.xml_root = None
|
|
241
|
|
242 if not self.xml_root:
|
|
243 os.rename(filename,filename+".corrupt")
|
|
244 emsg = "Your gametree is being regenerated.\n\n"\
|
|
245 "To salvage a recent version of your gametree\n"\
|
|
246 "exit OpenRPG and copy the lastgood.xml file in\n"\
|
|
247 "your myfiles directory to "+filename+ "\n"\
|
|
248 "in your myfiles directory.\n\n"\
|
|
249 "lastgood.xml WILL BE OVERWRITTEN NEXT TIME YOU RUN OPENRPG.\n\n"\
|
|
250 "Would you like to select a different gametree file to use?\n"\
|
|
251 "(Selecting 'No' will cause a new default gametree to be generated)"
|
|
252 self.locate_valid_tree("Corrupt Gametree!", emsg)
|
|
253 return
|
|
254
|
|
255 if self.xml_root.tag != "gametree":
|
|
256 emsg = filename+" does not appear to be a valid gametree file.\n\n"\
|
|
257 "Would you like to select a different gametree file to use?\n"\
|
|
258 "(Selecting 'No' will cause a new default gametree to be generated)"
|
|
259 self.locate_valid_tree("Invalid Gametree!", emsg)
|
|
260 return
|
|
261 try:
|
|
262 # version = self.xml_root.get("version")
|
|
263 # see if we should load the gametree
|
|
264 loadfeatures = int(settings.get_setting("LoadGameTreeFeatures"))
|
|
265 if loadfeatures:
|
|
266 features_tree = parse(orpg.dirpath.dir_struct["template"]+"feature.xml")
|
|
267 self.xml_root.append(features_tree.getroot())
|
|
268 settings.change("LoadGameTreeFeatures","0")
|
|
269
|
|
270 ## load tree
|
|
271 logger.debug("Features loaded (if required)")
|
|
272 self.CollapseAndReset(self.root)
|
|
273 logger.note("Parsing Gametree Nodes ", True)
|
|
274 for xml_child in self.xml_root:
|
|
275 logger.note('.', True)
|
|
276 self.load_xml(xml_child,self.root)
|
|
277 logger.note("done", True)
|
|
278
|
|
279 self.Expand(self.root)
|
|
280 self.SetPyData(self.root,self.xml_root)
|
|
281 if error != 1:
|
|
282 with open(filename, "rb") as infile:
|
|
283 with open(dir_struct["user"]+"lastgood.xml", "wb") as outfile:
|
|
284 outfile.write(infile.read())
|
|
285 else: logger.info("Not overwriting lastgood.xml file.", True)
|
|
286
|
|
287 except Exception, e:
|
|
288 logger.exception(traceback.format_exc())
|
|
289 wx.MessageBox("Corrupt Tree!\nYour game tree is being regenerated. To\nsalvage a recent version of your gametree\nexit OpenRPG and copy the lastgood.xml\nfile in your myfiles directory\nto "+filename+ "\nin your myfiles directory.\nlastgood.xml WILL BE OVERWRITTEN NEXT TIME YOU RUN OPENRPG.")
|
|
290 os.rename(filename,filename+".corrupt")
|
|
291 validate.config_file("tree.xml","default_tree.xml")
|
|
292 self.load_tree(error=1)
|
|
293
|
|
294 def build_std_menu(self, obj=None):
|
|
295 # build useful menu
|
|
296 useful_menu = wx.Menu()
|
|
297 useful_menu.Append(STD_MENU_NODE_USEFUL,"Use&ful")
|
|
298 useful_menu.Append(STD_MENU_NODE_USELESS,"Use&less")
|
|
299 useful_menu.Append(STD_MENU_NODE_INDIFFERENT,"&Indifferent")
|
|
300
|
|
301 # build standard menu
|
|
302 self.std_menu = wx.Menu()
|
|
303 self.std_menu.SetTitle("game tree")
|
|
304 self.std_menu.Append(STD_MENU_USE,"&Use")
|
|
305 self.std_menu.Append(STD_MENU_DESIGN,"&Design")
|
|
306 self.std_menu.Append(STD_MENU_PP,"&Pretty Print")
|
|
307 self.std_menu.AppendSeparator()
|
|
308 self.std_menu.Append(STD_MENU_SEND,"Send To Player")
|
|
309 self.std_menu.Append(STD_MENU_MAP,"Send To Map")
|
|
310 self.std_menu.Append(STD_MENU_CHAT,"Send To Chat")
|
|
311 self.std_menu.Append(STD_MENU_WHISPER,"Whisper To Player")
|
|
312 self.std_menu.AppendSeparator()
|
|
313 self.std_menu.Append(STD_MENU_ICON,"Change &Icon")
|
|
314 self.std_menu.Append(STD_MENU_DELETE,"D&elete")
|
|
315 self.std_menu.Append(STD_MENU_CLONE,"&Clone")
|
|
316 self.std_menu.AppendMenu(STD_MENU_NODE_SUBMENU,"Node &Usefulness",useful_menu)
|
|
317 self.std_menu.AppendSeparator()
|
|
318 self.std_menu.Append(STD_MENU_SAVE,"&Save Node")
|
|
319 self.std_menu.Append(STD_MENU_HTML,"E&xport as HTML")
|
|
320 self.std_menu.AppendSeparator()
|
|
321 self.std_menu.Append(STD_MENU_ABOUT,"&About")
|
|
322 self.Bind(wx.EVT_MENU, self.on_send_to, id=STD_MENU_SEND)
|
|
323 self.Bind(wx.EVT_MENU, self.indifferent, id=STD_MENU_NODE_INDIFFERENT)
|
|
324 self.Bind(wx.EVT_MENU, self.useful, id=STD_MENU_NODE_USEFUL)
|
|
325 self.Bind(wx.EVT_MENU, self.useless, id=STD_MENU_NODE_USELESS)
|
|
326 self.Bind(wx.EVT_MENU, self.on_del, id=STD_MENU_DELETE)
|
|
327 self.Bind(wx.EVT_MENU, self.on_send_to_map, id=STD_MENU_MAP)
|
|
328 self.Bind(wx.EVT_MENU, self.on_node_design, id=STD_MENU_DESIGN)
|
|
329 self.Bind(wx.EVT_MENU, self.on_node_use, id=STD_MENU_USE)
|
|
330 self.Bind(wx.EVT_MENU, self.on_node_pp, id=STD_MENU_PP)
|
|
331 self.Bind(wx.EVT_MENU, self.on_save, id=STD_MENU_SAVE)
|
|
332 self.Bind(wx.EVT_MENU, self.on_icon, id=STD_MENU_ICON)
|
|
333 self.Bind(wx.EVT_MENU, self.on_clone, id=STD_MENU_CLONE)
|
|
334 self.Bind(wx.EVT_MENU, self.on_about, id=STD_MENU_ABOUT)
|
|
335 self.Bind(wx.EVT_MENU, self.on_send_to_chat, id=STD_MENU_CHAT)
|
|
336 self.Bind(wx.EVT_MENU, self.on_whisper_to, id=STD_MENU_WHISPER)
|
|
337 self.Bind(wx.EVT_MENU, self.on_export_html, id=STD_MENU_HTML)
|
|
338 self.top_menu = wx.Menu()
|
|
339 self.top_menu.SetTitle("game tree")
|
178
|
340 self.top_menu.Append(TOP_IFILE,"&Insert Node File")
|
|
341 self.top_menu.Append(TOP_INSERT_URL,"Insert Node &URL")
|
155
|
342 self.top_menu.Append(TOP_FEATURES, "Insert &Features Node")
|
|
343 self.top_menu.Append(TOP_NEW_TREE, "&Load New Tree")
|
|
344 self.top_menu.Append(TOP_SAVE_TREE,"&Save Tree")
|
|
345 self.top_menu.Append(TOP_SAVE_TREE_AS,"Save Tree &As...")
|
|
346 self.top_menu.Append(TOP_TREE_PROP,"&Tree Properties")
|
|
347 self.Bind(wx.EVT_MENU, self.on_insert_file, id=TOP_IFILE)
|
|
348 self.Bind(wx.EVT_MENU, self.on_insert_url, id=TOP_INSERT_URL)
|
|
349 self.Bind(wx.EVT_MENU, self.on_save_tree_as, id=TOP_SAVE_TREE_AS)
|
|
350 self.Bind(wx.EVT_MENU, self.on_save_tree, id=TOP_SAVE_TREE)
|
|
351 self.Bind(wx.EVT_MENU, self.on_load_new_tree, id=TOP_NEW_TREE)
|
|
352 self.Bind(wx.EVT_MENU, self.on_tree_prop, id=TOP_TREE_PROP)
|
|
353 self.Bind(wx.EVT_MENU, self.on_insert_features, id=TOP_FEATURES)
|
|
354
|
|
355 def do_std_menu(self, evt, obj):
|
|
356 try: self.std_menu.Enable(STD_MENU_MAP, obj.checkToMapMenu())
|
|
357 except: self.std_menu.Enable(STD_MENU_MAP, obj.map_aware())
|
|
358 self.std_menu.Enable(STD_MENU_CLONE, obj.can_clone())
|
|
359 self.PopupMenu(self.std_menu)
|
|
360
|
|
361 def strip_html(self, player):
|
|
362 ret_string = ""
|
|
363 x = 0
|
|
364 in_tag = 0
|
|
365 for x in xrange(len(player[0])) :
|
|
366 if player[0][x] == "<" or player[0][x] == ">" or in_tag == 1 :
|
|
367 if player[0][x] == "<" : in_tag = 1
|
|
368 elif player[0][x] == ">" : in_tag = 0
|
|
369 else: pass
|
|
370 else: ret_string = ret_string + player[0][x]
|
|
371 logger.debug(ret_string)
|
|
372 return ret_string
|
|
373
|
133
|
374 def on_receive_data(self, data):
|
155
|
375 self.insert_xml(data)
|
|
376
|
|
377 def on_send_to_chat(self, evt):
|
|
378 item = self.GetSelection()
|
|
379 obj = self.GetPyData(item)
|
|
380 obj.on_send_to_chat(evt)
|
|
381
|
|
382 def on_whisper_to(self, evt):
|
|
383 players = self.session.get_players()
|
|
384 opts = []
|
|
385 myid = self.session.get_id()
|
|
386 me = None
|
|
387 for p in players:
|
|
388 if p[2] != myid: opts.append("("+p[2]+") " + self.strip_html(p))
|
|
389 else: me = p
|
|
390 if len(opts): players.remove(me)
|
|
391 if len(opts):
|
|
392 dlg = orpgMultiCheckBoxDlg( self.GetParent(),opts,"Select Players:","Whisper To",[] )
|
|
393 if dlg.ShowModal() == wx.ID_OK:
|
|
394 item = self.GetSelection()
|
|
395 obj = self.GetPyData(item)
|
|
396 selections = dlg.get_selections()
|
|
397 if len(selections) == len(opts): self.chat.ParsePost(obj.tohtml(),True,True)
|
|
398 else:
|
|
399 player_ids = []
|
|
400 for s in selections: player_ids.append(players[s][2])
|
|
401 self.chat.whisper_to_players(obj.tohtml(),player_ids)
|
|
402
|
|
403 def on_export_html(self, evt):
|
|
404 f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","HTML (*.html)|*.html",wx.SAVE)
|
|
405 if f.ShowModal() == wx.ID_OK:
|
|
406 item = self.GetSelection()
|
|
407 obj = self.GetPyData(item)
|
|
408 type = f.GetFilterIndex()
|
|
409 with open(f.GetPath(),"w") as f:
|
|
410 data = "<html><head><title>"+obj.xml.get("name")+"</title></head>"
|
|
411 data += "<body bgcolor='#FFFFFF' >"+obj.tohtml()+"</body></html>"
|
|
412 for tag in ("</tr>","</td>","</th>","</table>","</html>","</body>"): data = data.replace(tag,tag+"\n")
|
|
413 f.write(data)
|
|
414 self.last_save_dir, throwaway = os.path.split( f.GetPath() )
|
|
415 f.Destroy()
|
|
416 os.chdir(dir_struct["home"])
|
|
417
|
|
418 def indifferent(self, evt):
|
|
419 item = self.GetSelection()
|
|
420 obj = self.GetPyData(item)
|
|
421 obj.usefulness("indifferent")
|
|
422
|
|
423 def useful(self, evt):
|
|
424 item = self.GetSelection()
|
|
425 obj = self.GetPyData(item)
|
|
426 obj.usefulness("useful")
|
|
427
|
|
428 def useless(self, evt):
|
|
429 item = self.GetSelection()
|
|
430 obj = self.GetPyData(item)
|
|
431 obj.usefulness("useless")
|
|
432
|
|
433 def on_email(self,evt):
|
|
434 pass
|
|
435
|
|
436 def on_send_to(self, evt):
|
|
437 players = self.session.get_players()
|
|
438 opts = []
|
|
439 myid = self.session.get_id()
|
|
440 me = None
|
|
441 for p in players:
|
|
442 if p[2] != myid: opts.append("("+p[2]+") " + self.strip_html(p))
|
|
443 else: me = p
|
|
444 if len(opts):
|
|
445 players.remove(me)
|
|
446 dlg = orpgMultiCheckBoxDlg( None, opts, "Select Players:", "Send To", [] )
|
|
447 if dlg.ShowModal() == wx.ID_OK:
|
|
448 item = self.GetSelection()
|
|
449 obj = self.GetPyData(item)
|
|
450 xmldata = "<tree>" + tostring(obj.xml) + "</tree>"
|
|
451 selections = dlg.get_selections()
|
|
452 if len(selections) == len(opts): self.session.send(xmldata)
|
|
453 else:
|
|
454 for s in selections: self.session.send(xmldata,players[s][2])
|
|
455 dlg.Destroy()
|
|
456
|
|
457 def on_icon(self, evt):
|
|
458 icons = self.icons.keys()
|
|
459 icons.sort()
|
|
460 dlg = wx.SingleChoiceDialog(self,"Choose Icon?","Change Icon",icons)
|
|
461 if dlg.ShowModal() == wx.ID_OK:
|
|
462 key = dlg.GetStringSelection()
|
|
463 item = self.GetSelection()
|
|
464 obj = self.GetPyData(item)
|
|
465 obj.change_icon(key)
|
|
466 dlg.Destroy()
|
|
467
|
|
468 def on_wizard(self, evt):
|
|
469 item = self.GetSelection()
|
|
470 obj = self.GetPyData(item)
|
|
471 name = "New " + obj.xml_root.get("name")
|
|
472 icon = obj.xml_root.get("icon")
|
|
473 xml_data = "<nodehandler name='"+name+"' icon='" + icon + "' module='core' class='node_loader' >"
|
|
474 xml_data += xml.toxml(obj)
|
|
475 xml_data += "</nodehandler>"
|
|
476 self.insert_xml(xml_data)
|
|
477 logger.debug(xml_data)
|
|
478
|
|
479 def on_clone(self, evt):
|
|
480 item = self.GetSelection()
|
|
481 obj = self.GetPyData(item)
|
|
482 if obj.can_clone():
|
|
483 parent_node = self.GetItemParent(item)
|
|
484 prev_sib = self.GetPrevSibling(item)
|
|
485 if not prev_sib.IsOk(): prev_sib = parent_node
|
|
486 clone_xml = XML(tostring(obj.xml))
|
|
487 if parent_node == self.root: parent_xml = self.GetPyData(parent_node)
|
|
488 else: parent_xml = self.GetPyData(parent_node).xml
|
|
489 for i in range(len(parent_xml)):
|
151
|
490 if parent_xml[i] is obj.xml:
|
|
491 name = self.clone_renaming(parent_xml, parent_xml[i].get('name'))
|
|
492 clone_xml.set('name', name)
|
155
|
493 parent_xml.insert(i, clone_xml)
|
|
494 break
|
151
|
495 self.load_xml(clone_xml, parent_node, prev_sib)
|
|
496
|
|
497 def clone_renaming(self, node, name):
|
|
498 node_list = node.getchildren()
|
|
499 parent = node
|
|
500 append = name.split('_')
|
|
501 try: append_d = int(append[len(append)-1]); del append[len(append)-1]
|
|
502 except: append_d = False
|
|
503 if append_d:
|
|
504 append_d += 1; name = ''
|
|
505 for a in append: name += a+'_'
|
|
506 name = name+str(append_d)
|
|
507 if not append_d:
|
|
508 append_d = 1; name = ''
|
|
509 for a in append: name += a+'_'
|
|
510 name = name+str(append_d)
|
|
511 for n in node_list:
|
|
512 if n.get('name') == name: name = self.clone_renaming(parent, name)
|
155
|
513 return name
|
|
514
|
|
515 def on_save(self, evt):
|
|
516 """save node to a xml file"""
|
|
517 item = self.GetSelection()
|
|
518 obj = self.GetPyData(item)
|
|
519 obj.on_save(evt)
|
|
520 os.chdir(dir_struct["home"])
|
|
521
|
|
522 def on_save_tree_as(self, evt):
|
|
523 f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","*.xml",wx.SAVE)
|
|
524 if f.ShowModal() == wx.ID_OK:
|
|
525 self.save_tree(f.GetPath())
|
|
526 self.last_save_dir, throwaway = os.path.split( f.GetPath() )
|
|
527 f.Destroy()
|
|
528 os.chdir(dir_struct["home"])
|
|
529
|
|
530 def on_save_tree(self, evt=None):
|
|
531 filename = settings.get_setting("gametree")
|
|
532 self.save_tree(filename)
|
|
533
|
|
534 def save_tree(self, filename=dir_struct["user"]+'tree.xml'):
|
|
535 self.xml_root.set("version", GAMETREE_VERSION)
|
133
|
536 settings.change("gametree", filename)
|
155
|
537 ElementTree(self.xml_root).write(filename)
|
|
538
|
|
539 def on_load_new_tree(self, evt):
|
|
540 f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","*.xml",wx.OPEN)
|
|
541 if f.ShowModal() == wx.ID_OK:
|
|
542 self.load_tree(f.GetPath())
|
|
543 self.last_save_dir, throwaway = os.path.split( f.GetPath() )
|
|
544 f.Destroy()
|
|
545 os.chdir(dir_struct["home"])
|
|
546
|
|
547 def on_insert_file(self, evt):
|
|
548 """loads xml file into the tree"""
|
|
549 if self.last_save_dir == ".":
|
|
550 self.last_save_dir = dir_struct["user"]
|
|
551 f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","*.xml",wx.OPEN)
|
|
552 if f.ShowModal() == wx.ID_OK:
|
|
553 self.insert_xml(open(f.GetPath(),"r").read())
|
|
554 self.last_save_dir, throwaway = os.path.split( f.GetPath() )
|
|
555 f.Destroy()
|
|
556 os.chdir(dir_struct["home"])
|
|
557
|
|
558 def on_insert_url(self, evt):
|
|
559 """loads xml url into the tree"""
|
|
560 dlg = wx.TextEntryDialog(self,"URL?","Insert URL", "http://")
|
|
561 if dlg.ShowModal() == wx.ID_OK:
|
|
562 path = dlg.GetValue()
|
|
563 file = urllib.urlopen(path)
|
|
564 self.insert_xml(file.read())
|
|
565 dlg.Destroy()
|
|
566
|
|
567 def on_insert_features(self, evt):
|
|
568 self.insert_xml(open(dir_struct["template"]+"feature.xml","r").read())
|
|
569
|
|
570 def on_tree_prop(self, evt):
|
|
571 dlg = gametree_prop_dlg(self, settings)
|
|
572 if dlg.ShowModal() == wx.ID_OK: pass
|
|
573 dlg.Destroy()
|
|
574
|
|
575 def on_node_design(self, evt):
|
|
576 item = self.GetSelection()
|
|
577 obj = self.GetPyData(item)
|
|
578 obj.on_design(evt)
|
|
579
|
|
580 def on_node_use(self, evt):
|
|
581 item = self.GetSelection()
|
|
582 obj = self.GetPyData(item)
|
|
583 obj.on_use(evt)
|
|
584
|
|
585 def on_node_pp(self, evt):
|
|
586 item = self.GetSelection()
|
151
|
587 obj = self.GetPyData(item)
|
155
|
588 obj.on_html_view(evt)
|
|
589
|
|
590 def on_del(self, evt):
|
|
591 status_value = "none"
|
|
592 try:
|
|
593 item = self.GetSelection()
|
|
594 if item:
|
|
595 handler = self.GetPyData(item)
|
|
596 status_value = handler.xml.get('status')
|
|
597 name = handler.xml.get('name')
|
|
598 parent_item = self.GetItemParent(item)
|
|
599 while parent_item.IsOk() and status_value!="useful" and status_value!="useless":
|
|
600 try:
|
|
601 parent_handler = self.GetPyData(parent_item)
|
|
602 status_value = parent_handler.get('status')
|
|
603 name = parent_handler.get('name')
|
|
604 if status_value == "useless": break
|
|
605 elif status_value == "useful": break
|
|
606 except: status_value = "none"
|
|
607 parent_item = self.GetItemParent(parent_item)
|
|
608 if status_value == "useful":
|
|
609 dlg = wx.MessageDialog(self, `name` + " And everything beneath it are considered useful. \n\nAre you sure you want to delete this item?",'Important Item',wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
|
|
610 if dlg.ShowModal() == wx.ID_YES: handler.delete()
|
|
611 else: handler.delete()
|
|
612 except:
|
|
613 if self.GetSelection() == self.GetRootItem(): msg = wx.MessageDialog(None,"You can't delete the root item.","Delete Error",wx.OK)
|
|
614 else: msg = wx.MessageDialog(None,"Unknown error deleting node.","Delete Error",wx.OK)
|
|
615 msg.ShowModal()
|
|
616 msg.Destroy()
|
|
617
|
|
618 def on_about(self, evt):
|
|
619 item = self.GetSelection()
|
|
620 obj = self.GetPyData(item)
|
|
621 text = str(obj.about())
|
151
|
622 #about = MyAboutBox(self, obj.about())
|
155
|
623 wx.MessageBox(text, 'About')#.ShowModal()
|
|
624 #about.ShowModal()
|
|
625 #about.Destroy()
|
|
626
|
|
627 def on_send_to_map(self, evt):
|
|
628 item = self.GetSelection()
|
|
629 obj = self.GetPyData(item)
|
|
630 if hasattr(obj,"on_send_to_map"): obj.on_send_to_map(evt)
|
|
631
|
|
632 def insert_xml(self, txt):
|
|
633 #Updated to allow safe merging of gametree files
|
|
634 #without leaving an unusable and undeletable node.
|
|
635 # -- Snowdog 8/03
|
|
636 if not txt:
|
|
637 wx.MessageBox("Import Failed: Invalid or missing node data")
|
|
638 logger.general("Import Failed: Invalid or missing node data")
|
133
|
639 return
|
155
|
640 try: new_xml = XML(txt)
|
|
641 except ExpatError:
|
|
642 wx.MessageBox("Error Importing Node or Tree")
|
|
643 logger.general("Error Importing Node or Tree")
|
|
644 return
|
|
645 if new_xml.tag == "gametree":
|
|
646 for xml_child in new_xml: self.load_xml(xml_child, self.root)
|
|
647 return
|
133
|
648 if new_xml.tag == "tree":
|
155
|
649 self.xml_root.append(new_xml.find('nodehandler'))
|
|
650 for xml_child in new_xml: self.load_xml(xml_child, self.root)
|
133
|
651 return
|
155
|
652 self.xml_root.append(new_xml)
|
|
653 self.load_xml(new_xml, self.root, self.root)
|
|
654
|
|
655 def build_img_list(self):
|
|
656 """make image list"""
|
|
657 helper = img_helper()
|
|
658 self.icons = { }
|
|
659 self._imageList= wx.ImageList(16,16,False)
|
|
660 icons_xml = parse(orpg.dirpath.dir_struct["icon"]+"icons.xml")
|
|
661 for icon in icons_xml.getroot():
|
|
662 key = icon.get("name")
|
|
663 path = orpg.dirpath.dir_struct["icon"] + icon.get("file")
|
|
664 img = helper.load_file(path)
|
|
665 self.icons[key] = self._imageList.Add(img)
|
|
666 self.SetImageList(self._imageList)
|
|
667
|
|
668 def get_tree_map(self, parent):
|
|
669 ## Could be a little cleaner ##
|
|
670 family_tree = []
|
|
671 test = parent
|
|
672 while test != self.root:
|
|
673 parent = self.GetItemText(test)
|
|
674 test = self.GetItemParent(test)
|
|
675 family_tree.append(parent)
|
|
676 return family_tree
|
|
677
|
133
|
678 def load_xml(self, xml_element, parent_node, prev_node=None):
|
136
|
679 if parent_node == self.root:
|
|
680 self.tree_map[xml_element.get('name')] = {}
|
|
681 self.tree_map[xml_element.get('name')]['node'] = xml_element
|
173
|
682 xml_element.set('map', '')
|
155
|
683 if parent_node != self.root:
|
|
684 ## Loading XML seems to lag on Grids and Images need a cache for load speed ##
|
|
685 family_tree = self.get_tree_map(parent_node)
|
|
686 family_tree.reverse()
|
|
687 map_str = '' #'!@'
|
|
688 for member in family_tree: map_str += member +'::'
|
|
689 map_str = map_str[:len(map_str)-2] #+'@!'
|
|
690 xml_element.set('map', map_str)
|
|
691
|
|
692 #add the first tree node
|
|
693 i = 0
|
|
694 name = xml_element.get("name")
|
|
695 icon = xml_element.get("icon")
|
|
696 if self.icons.has_key(icon): i = self.icons[icon]
|
|
697
|
|
698 if prev_node:
|
|
699 if prev_node == parent_node: new_tree_node = self.PrependItem(parent_node, name, i, i)
|
|
700 else: new_tree_node = self.InsertItem(parent_node, prev_node, name, i, i)
|
|
701 else: new_tree_node = self.AppendItem(parent_node, name, i, i)
|
|
702
|
|
703 logger.debug("Node Added to tree")
|
|
704 #create a nodehandler or continue loading xml into tree
|
|
705 if xml_element.tag == "nodehandler":
|
|
706 try:
|
|
707 py_class = xml_element.get("class")
|
|
708 logger.debug("nodehandler class: " + py_class)
|
|
709 if not self.nodehandlers.has_key(py_class): raise Exception("Unknown Nodehandler for " + py_class)
|
|
710 self.nodes[self.id] = self.nodehandlers[py_class](xml_element, new_tree_node)
|
|
711 self.SetPyData(new_tree_node, self.nodes[self.id])
|
|
712 logger.debug("Node Data set")
|
|
713 bmp = self.nodes[self.id].get_scaled_bitmap(16,16)
|
|
714 if bmp: self.cached_load_of_image(bmp,new_tree_node,)
|
|
715 logger.debug("Node Icon loaded")
|
|
716 self.id = self.id + 1
|
|
717 except Exception, er:
|
|
718 logger.exception(traceback.format_exc())
|
|
719 # was deleted -- should we delete non-nodehandler nodes then?
|
|
720 #self.Delete(new_tree_node)
|
|
721 #parent = xml_dom._get_parentNode()
|
|
722 #parent.removeChild(xml_dom)
|
|
723 return new_tree_node
|
|
724
|
|
725 def cached_load_of_image(self, bmp_in, new_tree_node):
|
|
726 image_list = self.GetImageList()
|
|
727 img = wx.ImageFromBitmap(bmp_in)
|
|
728 img_data = img.GetData()
|
|
729 image_index = None
|
|
730 for key in self.image_cache.keys():
|
|
731 if self.image_cache[key] == str(img_data):
|
|
732 image_index = key
|
|
733 break
|
|
734 if image_index is None:
|
|
735 image_index = image_list.Add(bmp_in)
|
|
736 self.image_cache[image_index] = img_data
|
|
737 self.SetItemImage(new_tree_node,image_index)
|
|
738 self.SetItemImage(new_tree_node,image_index, wx.TreeItemIcon_Selected)
|
|
739 return image_index
|
|
740
|
|
741 def on_rclick(self, evt):
|
|
742 pt = evt.GetPosition()
|
|
743 (item, flag) = self.HitTest(pt)
|
|
744 if item.IsOk():
|
|
745 obj = self.GetPyData(item)
|
|
746 self.SelectItem(item)
|
|
747 if(isinstance(obj,core.node_handler)): obj.on_rclick(evt)
|
|
748 else: self.PopupMenu(self.top_menu)
|
|
749 else: self.PopupMenu(self.top_menu,pt)
|
|
750
|
|
751 def on_ldclick(self, evt):
|
|
752 self.rename_flag = 0
|
|
753 pt = evt.GetPosition()
|
|
754 (item, flag) = self.HitTest(pt)
|
|
755 if item.IsOk():
|
|
756 obj = self.GetPyData(item)
|
|
757 self.SelectItem(item)
|
|
758 if(isinstance(obj,core.node_handler)):
|
|
759 if not obj.on_ldclick(evt):
|
|
760 action = settings.get_setting("treedclick")
|
|
761 if action == "use": obj.on_use(evt)
|
|
762 elif action == "design": obj.on_design(evt)
|
|
763 elif action == "print": obj.on_html_view(evt)
|
|
764 elif action == "chat": self.on_send_to_chat(evt)
|
|
765
|
|
766 def on_left_down(self, evt):
|
|
767 pt = evt.GetPosition()
|
|
768 (item, flag) = self.HitTest(pt)
|
|
769 if item.IsOk() and self.was_labeling:
|
|
770 self.SelectItem(item)
|
|
771 self.rename_flag = 0
|
|
772 self.was_labeling = 0
|
|
773 elif (flag & wx.TREE_HITTEST_ONITEMLABEL) == wx.TREE_HITTEST_ONITEMLABEL and self.IsSelected(item):
|
|
774 # this next if tests to ensure that the mouse up occurred over a label, and not the icon
|
|
775 self.rename_flag = 1
|
|
776 else: self.SelectItem(item)
|
|
777 evt.Skip()
|
|
778
|
|
779 def on_left_up(self, evt):
|
|
780 if self.dragging:
|
|
781 cur = wx.StockCursor(wx.CURSOR_ARROW)
|
|
782 self.SetCursor(cur)
|
|
783 self.dragging = False
|
|
784 pt = evt.GetPosition()
|
|
785 (item, flag) = self.HitTest(pt)
|
|
786 if item.IsOk():
|
|
787 obj = self.GetPyData(item)
|
|
788 self.SelectItem(item)
|
|
789 if(isinstance(obj,core.node_handler)):
|
|
790 obj.on_drop(evt)
|
|
791 self.drag_obj = None
|
|
792
|
|
793 def traverse(self, root, function, data=None, recurse=True):
|
|
794 child, cookie = self.GetFirstChild(root)
|
|
795 while child.IsOk():
|
|
796 function(child, data)
|
|
797 if recurse: self.traverse(child, function, data)
|
|
798 child, cookie = self.GetNextChild(root, cookie)
|
|
799
|
|
800 def on_label_change(self, evt):
|
|
801 item = evt.GetItem()
|
|
802 txt = evt.GetLabel()
|
|
803 self.was_labeling = 0
|
|
804 self.rename_flag = 0
|
|
805 if txt != "":
|
|
806 obj = self.GetPyData(item)
|
196
|
807 obj.xml_root.set('name',txt)
|
155
|
808 else: evt.Veto()
|
|
809
|
|
810 def on_label_begin(self, evt):
|
|
811 if not self.rename_flag: evt.Veto()
|
|
812 else:
|
|
813 self.was_labeling = 1
|
|
814 item = evt.GetItem()
|
|
815 if item == self.GetRootItem(): evt.Veto()
|
|
816
|
|
817 def on_drag(self, evt):
|
|
818 self.rename_flag = 0
|
|
819 item = self.GetSelection()
|
|
820 obj = self.GetPyData(item)
|
|
821 self.SelectItem(item)
|
|
822 if(isinstance(obj,core.node_handler) and obj.drag):
|
|
823 self.dragging = True
|
|
824 cur = wx.StockCursor(wx.CURSOR_HAND)
|
|
825 self.SetCursor(cur)
|
|
826 self.drag_obj = obj
|
|
827
|
|
828 def is_parent_node(self, node, compare_node):
|
|
829 parent_node = self.GetItemParent(node)
|
|
830 if compare_node == parent_node:
|
|
831 logger.debug("parent node")
|
|
832 return 1
|
|
833 elif parent_node == self.root:
|
|
834 logger.debug("not parent")
|
|
835 return 0
|
|
836 else: return self.is_parent_node(parent_node, compare_node)
|
|
837
|
|
838 CTRL_TREE_FILE = wx.NewId()
|
|
839 CTRL_YES = wx.NewId()
|
|
840 CTRL_NO = wx.NewId()
|
|
841 CTRL_USE = wx.NewId()
|
|
842 CTRL_DESIGN = wx.NewId()
|
|
843 CTRL_CHAT = wx.NewId()
|
|
844 CTRL_PRINT = wx.NewId()
|
|
845
|
|
846 class gametree_prop_dlg(wx.Dialog):
|
|
847
|
|
848 def __init__(self, parent, settings):
|
|
849 wx.Dialog.__init__(self, parent, wx.ID_ANY, "Game Tree Properties")
|
|
850
|
|
851 #sizers
|
|
852 sizers = {}
|
|
853 sizers['but'] = wx.BoxSizer(wx.HORIZONTAL)
|
|
854 sizers['main'] = wx.BoxSizer(wx.VERTICAL)
|
|
855
|
|
856 #box sizers
|
|
857 box_sizers = {}
|
|
858 box_sizers["save"] = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Save On Exit"), wx.HORIZONTAL)
|
|
859 box_sizers["file"] = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Tree File"), wx.HORIZONTAL)
|
|
860 box_sizers["dclick"] = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Double Click Action"), wx.HORIZONTAL)
|
|
861 self.ctrls = { CTRL_TREE_FILE : FileBrowseButtonWithHistory(self, wx.ID_ANY, labelText="" ) ,
|
|
862 CTRL_YES : wx.RadioButton(self, CTRL_YES, "Yes", style=wx.RB_GROUP),
|
|
863 CTRL_NO : wx.RadioButton(self, CTRL_NO, "No"),
|
|
864 CTRL_USE : wx.RadioButton(self, CTRL_USE, "Use", style=wx.RB_GROUP),
|
|
865 CTRL_DESIGN : wx.RadioButton(self, CTRL_DESIGN, "Desgin"),
|
|
866 CTRL_CHAT : wx.RadioButton(self, CTRL_CHAT, "Chat"),
|
|
867 CTRL_PRINT : wx.RadioButton(self, CTRL_PRINT, "Pretty Print")
|
|
868 }
|
|
869 self.ctrls[CTRL_TREE_FILE].SetValue(settings.get_setting("gametree"))
|
|
870 opt = settings.get_setting("SaveGameTreeOnExit")
|
|
871 self.ctrls[CTRL_YES].SetValue(opt=="1")
|
|
872 self.ctrls[CTRL_NO].SetValue(opt=="0")
|
|
873 opt = settings.get_setting("treedclick")
|
|
874 self.ctrls[CTRL_DESIGN].SetValue(opt=="design")
|
|
875 self.ctrls[CTRL_USE].SetValue(opt=="use")
|
|
876 self.ctrls[CTRL_CHAT].SetValue(opt=="chat")
|
|
877 self.ctrls[CTRL_PRINT].SetValue(opt=="print")
|
|
878 box_sizers['save'].Add(self.ctrls[CTRL_YES],0, wx.EXPAND)
|
|
879 box_sizers['save'].Add(wx.Size(10,10))
|
|
880 box_sizers['save'].Add(self.ctrls[CTRL_NO],0, wx.EXPAND)
|
|
881 box_sizers['file'].Add(self.ctrls[CTRL_TREE_FILE], 0, wx.EXPAND)
|
|
882 box_sizers['dclick'].Add(self.ctrls[CTRL_USE],0, wx.EXPAND)
|
|
883 box_sizers['dclick'].Add(wx.Size(10,10))
|
|
884 box_sizers['dclick'].Add(self.ctrls[CTRL_DESIGN],0, wx.EXPAND)
|
|
885 box_sizers['dclick'].Add(wx.Size(10,10))
|
|
886 box_sizers['dclick'].Add(self.ctrls[CTRL_CHAT],0, wx.EXPAND)
|
|
887 box_sizers['dclick'].Add(wx.Size(10,10))
|
|
888 box_sizers['dclick'].Add(self.ctrls[CTRL_PRINT],0, wx.EXPAND)
|
|
889
|
|
890 # buttons
|
|
891 sizers['but'].Add(wx.Button(self, wx.ID_OK, "Apply"), 1, wx.EXPAND)
|
|
892 sizers['but'].Add(wx.Size(10,10))
|
|
893 sizers['but'].Add(wx.Button(self, wx.ID_CANCEL, "Cancel"), 1, wx.EXPAND)
|
|
894 sizers['main'].Add(box_sizers['save'], 1, wx.EXPAND)
|
|
895 sizers['main'].Add(box_sizers['file'], 1, wx.EXPAND)
|
|
896 sizers['main'].Add(box_sizers['dclick'], 1, wx.EXPAND)
|
|
897 sizers['main'].Add(sizers['but'], 0, wx.EXPAND|wx.ALIGN_BOTTOM )
|
|
898
|
|
899 #sizers['main'].SetDimension(10,10,csize[0]-20,csize[1]-20)
|
|
900 self.SetSizer(sizers['main'])
|
|
901 self.SetAutoLayout(True)
|
|
902 self.Fit()
|
|
903 self.Bind(wx.EVT_BUTTON, self.on_ok, id=wx.ID_OK)
|
|
904
|
|
905
|
|
906 def on_ok(self,evt):
|
|
907 settings.change("gametree",self.ctrls[CTRL_TREE_FILE].GetValue())
|
|
908 settings.change("SaveGameTreeOnExit",str(self.ctrls[CTRL_YES].GetValue()))
|
|
909 if self.ctrls[CTRL_USE].GetValue(): settings.change("treedclick","use")
|
|
910 elif self.ctrls[CTRL_DESIGN].GetValue(): settings.change("treedclick","design")
|
|
911 elif self.ctrls[CTRL_PRINT].GetValue(): settings.change("treedclick","print")
|
|
912 elif self.ctrls[CTRL_CHAT].GetValue(): settings.change("treedclick","chat")
|
|
913 self.EndModal(wx.ID_OK)
|