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