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