Mercurial > traipse_dev
view orpg/gametree/gametree.py @ 48:0aeee1992423 traipse_dev
This updates fixes three things. Branch names are now current to your udpate
and updates take place before the program starts and minor error in update
code (unremarked, removed '.')
author | sirebral |
---|---|
date | Thu, 06 Aug 2009 04:26:02 -0500 |
parents | 4385a7d0efd1 |
children | c54768cffbd4 |
line wrap: on
line source
# Copyright (C) 2000-2001 The OpenRPG Project # # openrpg-dev@lists.sourceforge.net # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # -- # # File: gametree.py # Author: Chris Davis # Maintainer: # Version: # $Id: gametree.py,v 1.68 2007/12/07 20:39:48 digitalxero Exp $ # # Description: The file contains code fore the game tree shell # __version__ = "$Id: gametree.py,v 1.68 2007/12/07 20:39:48 digitalxero Exp $" from orpg.orpg_wx import * from orpg.orpg_windows import * from orpg.orpgCore import open_rpg import orpg.dirpath from nodehandlers import core import orpg.gametree.nodehandlers.containers import orpg.gametree.nodehandlers.forms import orpg.gametree.nodehandlers.dnd3e import orpg.gametree.nodehandlers.dnd35 import orpg.gametree.nodehandlers.chatmacro import orpg.gametree.nodehandlers.map_miniature_nodehandler import orpg.gametree.nodehandlers.minilib import orpg.gametree.nodehandlers.rpg_grid import orpg.gametree.nodehandlers.d20 import orpg.gametree.nodehandlers.StarWarsd20 import orpg.gametree.nodehandlers.voxchat from gametree_version import GAMETREE_VERSION import string import urllib import time import os STD_MENU_DELETE = wx.NewId() STD_MENU_DESIGN = wx.NewId() STD_MENU_USE = wx.NewId() STD_MENU_PP = wx.NewId() STD_MENU_RENAME = wx.NewId() STD_MENU_SEND = wx.NewId() STD_MENU_SAVE = wx.NewId() STD_MENU_ICON = wx.NewId() STD_MENU_CLONE = wx.NewId() STD_MENU_ABOUT = wx.NewId() STD_MENU_HTML = wx.NewId() STD_MENU_EMAIL = wx.NewId() STD_MENU_CHAT = wx.NewId() STD_MENU_WHISPER = wx.NewId() STD_MENU_WIZARD = wx.NewId() STD_MENU_NODE_SUBMENU = wx.NewId() STD_MENU_NODE_USEFUL = wx.NewId() STD_MENU_NODE_USELESS = wx.NewId() STD_MENU_NODE_INDIFFERENT = wx.NewId() STD_MENU_MAP = wx.NewId() TOP_IFILE = wx.NewId() TOP_INSERT_URL = wx.NewId() TOP_NEW_TREE = wx.NewId() TOP_SAVE_TREE = wx.NewId() TOP_SAVE_TREE_AS = wx.NewId() TOP_TREE_PROP = wx.NewId() TOP_FEATURES = wx.NewId() class game_tree(wx.TreeCtrl): def __init__(self, parent, id): wx.TreeCtrl.__init__(self,parent,id, wx.DefaultPosition, wx.DefaultSize,style=wx.TR_EDIT_LABELS | wx.TR_HAS_BUTTONS) self.log = open_rpg.get_component('log') self.log.log("Enter game_tree", ORPG_DEBUG) self.validate = open_rpg.get_component('validate') self.xml = open_rpg.get_component('xml') self.settings = open_rpg.get_component('settings') self.session = open_rpg.get_component('session') self.chat = open_rpg.get_component('chat') self.mainframe = open_rpg.get_component('frame') self.build_img_list() self.build_std_menu() self.nodehandlers = {} self.nodes = {} self.init_nodehandlers() self.Bind(wx.EVT_LEFT_DCLICK, self.on_ldclick) self.Bind(wx.EVT_RIGHT_DOWN, self.on_rclick) self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.on_drag, id=id) self.Bind(wx.EVT_LEFT_UP, self.on_left_up) self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down) self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.on_label_change, id=self.GetId()) self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.on_label_begin, id=self.GetId()) self.Bind(wx.EVT_CHAR, self.on_char) self.Bind(wx.EVT_KEY_UP, self.on_key_up) self.id = 1 self.dragging = False self.root_dir = orpg.dirpath.dir_struct["home"] self.last_save_dir = orpg.dirpath.dir_struct["user"] #Create tree from default if it does not exist self.validate.config_file("tree.xml","default_tree.xml") open_rpg.add_component("tree", self) #build tree self.root = self.AddRoot("Game Tree",self.icons['gear']) self.was_labeling = 0 self.rename_flag = 0 self.image_cache = {} self.log.log("Exit game_tree", ORPG_DEBUG) def add_nodehandler(self, nodehandler, nodeclass): self.log.log("Enter game_tree->add_nodehandler(self, nodehandler, nodeclass)", ORPG_DEBUG) if not self.nodehandlers.has_key(nodehandler): self.nodehandlers[nodehandler] = nodeclass else: self.log.log("Nodehandler for " + nodehandler + " already exists!", ORPG_DEBUG, True) self.log.log("Exit game_tree->add_nodehandler(self, nodehandler, nodeclass)", ORPG_DEBUG) def remove_nodehandler(self, nodehandler): self.log.log("Enter game_tree->remove_nodehandler(self, nodehandler)", ORPG_DEBUG) if self.nodehandlers.has_key(nodehandler): del self.nodehandlers[nodehandler] else: self.log.log("No nodehandler for " + nodehandler + " exists!", ORPG_DEBUG, True) self.log.log("Exit game_tree->remove_nodehandler(self, nodehandler)", ORPG_DEBUG) def init_nodehandlers(self): self.log.log("Enter game_tree->init_nodehandlers(self)", ORPG_DEBUG) self.add_nodehandler('group_handler', orpg.gametree.nodehandlers.containers.group_handler) self.add_nodehandler('tabber_handler', orpg.gametree.nodehandlers.containers.tabber_handler) self.add_nodehandler('splitter_handler', orpg.gametree.nodehandlers.containers.splitter_handler) self.add_nodehandler('form_handler', orpg.gametree.nodehandlers.forms.form_handler) self.add_nodehandler('textctrl_handler', orpg.gametree.nodehandlers.forms.textctrl_handler) self.add_nodehandler('listbox_handler', orpg.gametree.nodehandlers.forms.listbox_handler) self.add_nodehandler('link_handler', orpg.gametree.nodehandlers.forms.link_handler) self.add_nodehandler('webimg_handler', orpg.gametree.nodehandlers.forms.webimg_handler) self.add_nodehandler('dnd3echar_handler', orpg.gametree.nodehandlers.dnd3e.dnd3echar_handler) self.add_nodehandler('dnd35char_handler', orpg.gametree.nodehandlers.dnd35.dnd35char_handler) self.add_nodehandler('macro_handler', orpg.gametree.nodehandlers.chatmacro.macro_handler) self.add_nodehandler('map_miniature_handler', orpg.gametree.nodehandlers.map_miniature_nodehandler.map_miniature_handler) self.add_nodehandler('minilib_handler', orpg.gametree.nodehandlers.minilib.minilib_handler) self.add_nodehandler('mini_handler', orpg.gametree.nodehandlers.minilib.mini_handler) self.add_nodehandler('rpg_grid_handler', orpg.gametree.nodehandlers.rpg_grid.rpg_grid_handler) self.add_nodehandler('d20char_handler', orpg.gametree.nodehandlers.d20.d20char_handler) self.add_nodehandler('SWd20char_handler', orpg.gametree.nodehandlers.StarWarsd20.SWd20char_handler) self.add_nodehandler('voxchat_handler', orpg.gametree.nodehandlers.voxchat.voxchat_handler) self.add_nodehandler('file_loader', core.file_loader) self.add_nodehandler('node_loader', core.node_loader) self.add_nodehandler('url_loader', core.url_loader) self.add_nodehandler('min_map', core.min_map) self.log.log("Exit game_tree->init_nodehandlers(self)", ORPG_DEBUG) # event = wxKeyEvent # set to be called by wxWindows by EVT_CHAR macro in __init__ def on_key_up(self, evt): self.log.log("Enter game_tree->on_key_up(self, evt)", ORPG_DEBUG) key_code = evt.GetKeyCode() if self.dragging and (key_code == wx.WXK_SHIFT): curSelection = self.GetSelection() cur = wx.StockCursor(wx.CURSOR_ARROW) self.SetCursor(cur) self.dragging = False obj = self.GetPyData(curSelection) self.SelectItem(curSelection) if(isinstance(obj,core.node_handler)): obj.on_drop(evt) self.drag_obj = None evt.Skip() self.log.log("Exit game_tree->on_key_up(self, evt)", ORPG_DEBUG) def on_char(self, evt): self.log.log("Enter game_tree->on_char(self, evt)", ORPG_DEBUG) key_code = evt.GetKeyCode() curSelection = self.GetSelection() # Get the current selection if evt.ShiftDown() and ((key_code == wx.WXK_UP) or (key_code == wx.WXK_DOWN)) and not self.dragging: curSelection = self.GetSelection() obj = self.GetPyData(curSelection) self.SelectItem(curSelection) if(isinstance(obj,core.node_handler)): self.dragging = True cur = wx.StockCursor(wx.CURSOR_HAND) self.SetCursor(cur) self.drag_obj = obj elif key_code == wx.WXK_LEFT: self.Collapse(curSelection) elif key_code == wx.WXK_DELETE: # Handle the delete key if curSelection: nextSelect = self.GetItemParent(curSelection) self.on_del(evt) try: if self.GetItemText(nextSelect) != "": self.SelectItem(nextSelect) except: pass elif key_code == wx.WXK_F2: self.rename_flag = 1 self.EditLabel(curSelection) evt.Skip() self.log.log("Exit game_tree->on_char(self, evt)", ORPG_DEBUG) ## locate_valid_tree ## GUI based dialogs to locate/fix missing treefile issues --Snowdog 3/05 def locate_valid_tree(self, error, msg, dir, filename): """prompts the user to locate a new tree file or create a new one""" self.log.log("Enter game_tree->locate_valid_tree(self, error, msg, dir, filename)", ORPG_DEBUG) response = wx.MessageDialog(self, msg, error, wx.YES|wx.NO|wx.ICON_ERROR) if response == wx.YES: file = None filetypes = "Gametree (*.xml)|*.xml|All files (*.*)|*.*" dlg = wx.FileDialog(self, "Locate Gametree file", dir, filename, filetypes,wx.OPEN | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: file = dlg.GetPath() dlg.Destroy() if not file: self.load_tree(error=1) else: self.load_tree(file) self.log.log("Exit game_tree->locate_valid_tree(self, error, msg, dir, filename)", ORPG_DEBUG) return else: self.validate.config_file("tree.xml","default_tree.xml") self.load_tree(error=1) self.log.log("Exit game_tree->locate_valid_tree(self, error, msg, dir, filename)", ORPG_DEBUG) return def load_tree(self, filename=orpg.dirpath.dir_struct["user"]+'tree.xml', error=0): self.log.log("Enter game_tree->load_tree(self, filename, error)", ORPG_DEBUG) self.settings.set_setting("gametree", filename) tmp = None xml_dom = None xml_doc = None try: self.log.log("Reading Gametree file: " + filename + "...", ORPG_INFO, True) tmp = open(filename,"r") xml_doc = self.xml.parseXml(tmp.read()) tmp.close() if xml_doc == None: pass else: xml_dom = xml_doc._get_documentElement() self.log.log("done.", ORPG_INFO, True) except IOError: emsg = "Gametree Missing!\n"+filename+" cannot be found.\n\n"\ "Would you like to locate it?\n"\ "(Selecting 'No' will cause a new default gametree to be generated)" fn = filename[ ((filename.rfind(os.sep))+len(os.sep)):] self.locate_valid_tree("Gametree Error", emsg, orpg.dirpath.dir_struct["user"], fn) self.log.log(emsg, ORPG_GENERAL) self.log.log("Exit game_tree->load_tree(self, filename, error)", ORPG_DEBUG) return if not xml_dom: os.rename(filename,filename+".corrupt") fn = filename[ ((filename.rfind(os.sep))+len(os.sep)):] emsg = "Your gametree is being regenerated.\n\n"\ "To salvage a recent version of your gametree\n"\ "exit OpenRPG and copy the lastgood.xml file in\n"\ "your myfiles directory to "+fn+ "\n"\ "in your myfiles directory.\n\n"\ "lastgood.xml WILL BE OVERWRITTEN NEXT TIME YOU RUN OPENRPG.\n\n"\ "Would you like to select a different gametree file to use?\n"\ "(Selecting 'No' will cause a new default gametree to be generated)" self.locate_valid_tree("Corrupt Gametree!", emsg, orpg.dirpath.dir_struct["user"], fn) self.log.log(emsg, ORPG_GENERAL) self.log.log("Exit game_tree->load_tree(self, filename, error)", ORPG_DEBUG) return if xml_dom._get_tagName() != "gametree": fn = filename[ ((filename.rfind(os.sep))+len(os.sep)):] emsg = fn+" does not appear to be a valid gametree file.\n\n"\ "Would you like to select a different gametree file to use?\n"\ "(Selecting 'No' will cause a new default gametree to be generated)" self.locate_valid_tree("Invalid Gametree!", emsg, orpg.dirpath.dir_struct["user"], fn) self.log.log(emsg, ORPG_DEBUG) self.log.log("Exit game_tree->load_tree(self, filename, error)", ORPG_DEBUG) return # get gametree version - we could write conversion code here! self.master_dom = xml_dom self.log.log("Master Dom Set", ORPG_DEBUG) try: version = self.master_dom.getAttribute("version") # see if we should load the gametree loadfeatures = int(self.settings.get_setting("LoadGameTreeFeatures")) if loadfeatures: xml_dom = self.xml.parseXml(open(orpg.dirpath.dir_struct["template"]+"feature.xml","r").read()) xml_dom = xml_dom._get_documentElement() xml_dom = self.master_dom.appendChild(xml_dom) self.settings.set_setting("LoadGameTreeFeatures","0") ## load tree self.log.log("Features loaded (if required)", ORPG_DEBUG) self.CollapseAndReset(self.root) children = self.master_dom._get_childNodes() self.log.log("Parsing Gametree Nodes ", ORPG_INFO, True) for c in children: print '.', self.load_xml(c,self.root) self.log.log("done", ORPG_INFO, True) self.Expand(self.root) self.SetPyData(self.root,self.master_dom) if error != 1: infile = open(filename, "rb") outfile = open(orpg.dirpath.dir_struct["user"]+"lastgood.xml", "wb") outfile.write(infile.read()) else: self.log.log("Not overwriting lastgood.xml file.", ORPG_INFO, True) except Exception, e: self.log.log(traceback.format_exc(), ORPG_GENERAL) 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.") os.rename(filename,filename+".corrupt") self.validate.config_file("tree.xml","default_tree.xml") self.load_tree(error=1) self.log.log("Exit game_tree->load_tree(self, filename, error)", ORPG_DEBUG) def build_std_menu(self, obj=None): self.log.log("Enter game_tree->build_std_menu(self, obj)", ORPG_DEBUG) # build useful menu useful_menu = wx.Menu() useful_menu.Append(STD_MENU_NODE_USEFUL,"Use&ful") useful_menu.Append(STD_MENU_NODE_USELESS,"Use&less") useful_menu.Append(STD_MENU_NODE_INDIFFERENT,"&Indifferent") # build standard menu self.std_menu = wx.Menu() self.std_menu.SetTitle("game tree") self.std_menu.Append(STD_MENU_USE,"&Use") self.std_menu.Append(STD_MENU_DESIGN,"&Design") self.std_menu.Append(STD_MENU_PP,"&Pretty Print") self.std_menu.AppendSeparator() self.std_menu.Append(STD_MENU_SEND,"Send To Player") self.std_menu.Append(STD_MENU_MAP,"Send To Map") self.std_menu.Append(STD_MENU_CHAT,"Send To Chat") self.std_menu.Append(STD_MENU_WHISPER,"Whisper To Player") self.std_menu.AppendSeparator() self.std_menu.Append(STD_MENU_ICON,"Change &Icon") self.std_menu.Append(STD_MENU_DELETE,"D&elete") self.std_menu.Append(STD_MENU_CLONE,"&Clone") self.std_menu.AppendMenu(STD_MENU_NODE_SUBMENU,"Node &Usefulness",useful_menu) self.std_menu.AppendSeparator() self.std_menu.Append(STD_MENU_SAVE,"&Save Node") self.std_menu.Append(STD_MENU_HTML,"E&xport as HTML") self.std_menu.AppendSeparator() self.std_menu.Append(STD_MENU_ABOUT,"&About") self.Bind(wx.EVT_MENU, self.on_send_to, id=STD_MENU_SEND) self.Bind(wx.EVT_MENU, self.indifferent, id=STD_MENU_NODE_INDIFFERENT) self.Bind(wx.EVT_MENU, self.useful, id=STD_MENU_NODE_USEFUL) self.Bind(wx.EVT_MENU, self.useless, id=STD_MENU_NODE_USELESS) self.Bind(wx.EVT_MENU, self.on_del, id=STD_MENU_DELETE) self.Bind(wx.EVT_MENU, self.on_send_to_map, id=STD_MENU_MAP) self.Bind(wx.EVT_MENU, self.on_node_design, id=STD_MENU_DESIGN) self.Bind(wx.EVT_MENU, self.on_node_use, id=STD_MENU_USE) self.Bind(wx.EVT_MENU, self.on_node_pp, id=STD_MENU_PP) self.Bind(wx.EVT_MENU, self.on_save, id=STD_MENU_SAVE) self.Bind(wx.EVT_MENU, self.on_icon, id=STD_MENU_ICON) self.Bind(wx.EVT_MENU, self.on_clone, id=STD_MENU_CLONE) self.Bind(wx.EVT_MENU, self.on_about, id=STD_MENU_ABOUT) self.Bind(wx.EVT_MENU, self.on_send_to_chat, id=STD_MENU_CHAT) self.Bind(wx.EVT_MENU, self.on_whisper_to, id=STD_MENU_WHISPER) self.Bind(wx.EVT_MENU, self.on_export_html, id=STD_MENU_HTML) self.top_menu = wx.Menu() self.top_menu.SetTitle("game tree") self.top_menu.Append(TOP_IFILE,"&Insert File") self.top_menu.Append(TOP_INSERT_URL,"Insert &URL") self.top_menu.Append(TOP_FEATURES, "Insert &Features Node") self.top_menu.Append(TOP_NEW_TREE, "&Load New Tree") self.top_menu.Append(TOP_SAVE_TREE,"&Save Tree") self.top_menu.Append(TOP_SAVE_TREE_AS,"Save Tree &As...") self.top_menu.Append(TOP_TREE_PROP,"&Tree Properties") self.Bind(wx.EVT_MENU, self.on_insert_file, id=TOP_IFILE) self.Bind(wx.EVT_MENU, self.on_insert_url, id=TOP_INSERT_URL) self.Bind(wx.EVT_MENU, self.on_save_tree_as, id=TOP_SAVE_TREE_AS) self.Bind(wx.EVT_MENU, self.on_save_tree, id=TOP_SAVE_TREE) self.Bind(wx.EVT_MENU, self.on_load_new_tree, id=TOP_NEW_TREE) self.Bind(wx.EVT_MENU, self.on_tree_prop, id=TOP_TREE_PROP) self.Bind(wx.EVT_MENU, self.on_insert_features, id=TOP_FEATURES) self.log.log("Exit game_tree->build_std_menu(self, obj)", ORPG_DEBUG) def do_std_menu(self, evt, obj): self.log.log("Enter game_tree->do_std_menu(self, evt, obj)", ORPG_DEBUG) try: self.std_menu.Enable(STD_MENU_MAP, obj.checkToMapMenu()) except: self.std_menu.Enable(STD_MENU_MAP, obj.map_aware()) self.std_menu.Enable(STD_MENU_CLONE, obj.can_clone()) self.PopupMenu(self.std_menu) self.log.log("Exit game_tree->do_std_menu(self, evt, obj)", ORPG_DEBUG) def strip_html(self, player): self.log.log("Enter game_tree->strip_html(self, player)", ORPG_DEBUG) ret_string = "" x = 0 in_tag = 0 for x in xrange(len(player[0])) : if player[0][x] == "<" or player[0][x] == ">" or in_tag == 1 : if player[0][x] == "<" : in_tag = 1 elif player[0][x] == ">" : in_tag = 0 else : pass else : ret_string = ret_string + player[0][x] self.log.log(ret_string, ORPG_DEBUG) self.log.log("Exit game_tree->strip_html(self, player)", ORPG_DEBUG) return ret_string def on_receive_data(self, data, player): self.log.log("Enter game_tree->on_receive_data(self, data, player)", ORPG_DEBUG) beg = string.find(data,"<tree>") end = string.rfind(data,"</tree>") data = data[6:end] self.insert_xml(data) self.log.log("Exit game_tree->on_receive_data(self, data, player)", ORPG_DEBUG) def on_send_to_chat(self, evt): self.log.log("Enter game_tree->on_send_to_chat(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) obj.on_send_to_chat(evt) self.log.log("Exit game_tree->on_send_to_chat(self, evt)", ORPG_DEBUG) def on_whisper_to(self, evt): self.log.log("Enter game_tree->on_whisper_to(self, evt)", ORPG_DEBUG) players = self.session.get_players() opts = [] myid = self.session.get_id() me = None for p in players: if p[2] != myid: opts.append("("+p[2]+") " + self.strip_html(p)) else: me = p if len(opts): players.remove(me) if len(opts): dlg = orpgMultiCheckBoxDlg( self.GetParent(),opts,"Select Players:","Whisper To",[] ) if dlg.ShowModal() == wx.ID_OK: item = self.GetSelection() obj = self.GetPyData(item) selections = dlg.get_selections() if len(selections) == len(opts): self.chat.ParsePost(obj.tohtml(),True,True) else: player_ids = [] for s in selections: player_ids.append(players[s][2]) self.chat.whisper_to_players(obj.tohtml(),player_ids) self.log.log("Exit game_tree->on_whisper_to(self, evt)", ORPG_DEBUG) def on_export_html(self, evt): self.log.log("Enter game_tree->on_export_html(self, evt)", ORPG_DEBUG) f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","HTML (*.html)|*.html",wx.SAVE) if f.ShowModal() == wx.ID_OK: item = self.GetSelection() obj = self.GetPyData(item) type = f.GetFilterIndex() file = open(f.GetPath(),"w") data = "<html><head><title>"+obj.master_dom.getAttribute("name")+"</title></head>" data += "<body bgcolor=\"#FFFFFF\" >"+obj.tohtml()+"</body></html>" for tag in ("</tr>","</td>","</th>","</table>","</html>","</body>"): data = data.replace(tag,tag+"\n") file.write(data) file.close() self.last_save_dir, throwaway = os.path.split( f.GetPath() ) f.Destroy() os.chdir(self.root_dir) self.log.log("Exit game_tree->on_export_html(self, evt)", ORPG_DEBUG) def indifferent(self, evt): self.log.log("Enter game_tree->indifferent(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) obj.usefulness("indifferent") self.log.log("Exit game_tree->indifferent(self, evt)", ORPG_DEBUG) def useful(self, evt): self.log.log("Enter game_tree->useful(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) obj.usefulness("useful") self.log.log("Exit game_tree->useful(self, evt)", ORPG_DEBUG) def useless(self, evt): self.log.log("Enter game_tree->useless(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) obj.usefulness("useless") self.log.log("Exit game_tree->useless(self, evt)", ORPG_DEBUG) def on_email(self,evt): pass def on_send_to(self, evt): self.log.log("Enter game_tree->on_send_to(self, evt)", ORPG_DEBUG) players = self.session.get_players() opts = [] myid = self.session.get_id() me = None for p in players: if p[2] != myid: opts.append("("+p[2]+") " + self.strip_html(p)) else: me = p if len(opts): players.remove(me) dlg = orpgMultiCheckBoxDlg( None, opts, "Select Players:", "Send To", [] ) if dlg.ShowModal() == wx.ID_OK: item = self.GetSelection() obj = self.GetPyData(item) xmldata = "<tree>" + self.xml.toxml(obj) + "</tree>" selections = dlg.get_selections() if len(selections) == len(opts): self.session.send(xmldata) else: for s in selections: self.session.send(xmldata,players[s][2]) dlg.Destroy() self.log.log("Exit game_tree->on_send_to(self, evt)", ORPG_DEBUG) def on_icon(self, evt): self.log.log("Enter game_tree->on_icon(self, evt)", ORPG_DEBUG) icons = self.icons.keys() icons.sort() dlg = wx.SingleChoiceDialog(self,"Choose Icon?","Change Icon",icons) if dlg.ShowModal() == wx.ID_OK: key = dlg.GetStringSelection() item = self.GetSelection() obj = self.GetPyData(item) obj.change_icon(key) dlg.Destroy() self.log.log("Exit game_tree->on_icon(self, evt)", ORPG_DEBUG) def on_wizard(self, evt): self.log.log("Enter game_tree->on_wizard(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) name = "New " + obj.master_dom.getAttribute("name") icon = obj.master_dom.getAttribute("icon") xml_data = "<nodehandler name=\""+name+"\" icon=\"" + icon + "\" module=\"core\" class=\"node_loader\" >" xml_data += self.xml.toxml(obj) xml_data += "</nodehandler>" self.insert_xml(xml_data) self.log.log(xml_data, ORPG_DEBUG) self.log.log("Exit game_tree->on_wizard(self, evt)", ORPG_DEBUG) def on_clone(self, evt): self.log.log("Enter game_tree->on_clone(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) if obj.can_clone(): parent_node = self.GetItemParent(item) prev_sib = self.GetPrevSibling(item) if not prev_sib.IsOk(): prev_sib = parent_node xml_dom = self.xml.parseXml(self.xml.toxml(obj)) xml_dom = xml_dom._get_firstChild() parent = obj.master_dom._get_parentNode() xml_dom = parent.insertBefore(xml_dom, obj.master_dom) self.load_xml(xml_dom, parent_node, prev_sib) self.log.log("Exit game_tree->on_clone(self, evt)", ORPG_DEBUG) def on_save(self, evt): """save node to a xml file""" self.log.log("Enter game_tree->on_save(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) obj.on_save(evt) os.chdir(self.root_dir) self.log.log("Exit game_tree->on_save(self, evt)", ORPG_DEBUG) def on_save_tree_as(self, evt): self.log.log("Enter game_tree->on_save_tree_as(self, evt)", ORPG_DEBUG) f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","*.xml",wx.SAVE) if f.ShowModal() == wx.ID_OK: self.save_tree(f.GetPath()) self.last_save_dir, throwaway = os.path.split( f.GetPath() ) f.Destroy() os.chdir(self.root_dir) self.log.log("Exit game_tree->on_save_tree_as(self, evt)", ORPG_DEBUG) def on_save_tree(self, evt=None): self.log.log("Enter game_tree->on_save_tree(self, evt)", ORPG_DEBUG) filename = self.settings.get_setting("gametree") self.save_tree(filename) self.log.log("Exit game_tree->on_save_tree(self, evt)", ORPG_DEBUG) def save_tree(self, filename=orpg.dirpath.dir_struct["user"]+'tree.xml'): self.log.log("Enter game_tree->save_tree(self, filename)", ORPG_DEBUG) self.master_dom.setAttribute("version",GAMETREE_VERSION) self.settings.set_setting("gametree",filename) file = open(filename,"w") file.write(self.xml.toxml(self.master_dom,1)) file.close() self.log.log("Exit game_tree->save_tree(self, filename)", ORPG_DEBUG) def on_load_new_tree(self, evt): self.log.log("Enter game_tree->on_load_new_tree(self, evt)", ORPG_DEBUG) f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","*.xml",wx.OPEN) if f.ShowModal() == wx.ID_OK: self.load_tree(f.GetPath()) self.last_save_dir, throwaway = os.path.split( f.GetPath() ) f.Destroy() os.chdir(self.root_dir) self.log.log("Exit game_tree->on_load_new_tree(self, evt)", ORPG_DEBUG) def on_insert_file(self, evt): """loads xml file into the tree""" self.log.log("Enter game_tree->on_insert_file(self, evt)", ORPG_DEBUG) if self.last_save_dir == ".": self.last_save_dir = orpg.dirpath.dir_struct["user"] f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","*.xml",wx.OPEN) if f.ShowModal() == wx.ID_OK: self.insert_xml(open(f.GetPath(),"r").read()) self.last_save_dir, throwaway = os.path.split( f.GetPath() ) f.Destroy() os.chdir(self.root_dir) self.log.log("Exit game_tree->on_insert_file(self, evt)", ORPG_DEBUG) def on_insert_url(self, evt): """loads xml url into the tree""" self.log.log("Enter game_tree->on_insert_url(self, evt)", ORPG_DEBUG) dlg = wx.TextEntryDialog(self,"URL?","Insert URL", "http://") if dlg.ShowModal() == wx.ID_OK: path = dlg.GetValue() file = urllib.urlopen(path) self.insert_xml(file.read()) dlg.Destroy() self.log.log("Exit game_tree->on_insert_url(self, evt)", ORPG_DEBUG) def on_insert_features(self, evt): self.log.log("Enter game_tree->on_insert_features(self, evt)", ORPG_DEBUG) self.insert_xml(open(orpg.dirpath.dir_struct["template"]+"feature.xml","r").read()) self.log.log("Exit game_tree->on_insert_features(self, evt)", ORPG_DEBUG) def on_tree_prop(self, evt): self.log.log("Enter game_tree->on_tree_prop(self, evt)", ORPG_DEBUG) dlg = gametree_prop_dlg(self, self.settings) if dlg.ShowModal() == wx.ID_OK: pass dlg.Destroy() self.log.log("Exit game_tree->on_tree_prop(self, evt)", ORPG_DEBUG) def on_node_design(self, evt): self.log.log("Enter game_tree->on_node_design(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) obj.on_design(evt) self.log.log("Exit game_tree->on_node_design(self, evt)", ORPG_DEBUG) def on_node_use(self, evt): self.log.log("Enter game_tree->on_node_use(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) obj.on_use(evt) self.log.log("Exit game_tree->on_node_use(self, evt)", ORPG_DEBUG) def on_node_pp(self, evt): self.log.log("Enter game_tree->on_node_pp(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) obj.on_html_view(evt) self.log.log("Exit game_tree->on_node_pp(self, evt)", ORPG_DEBUG) def on_del(self, evt): self.log.log("Enter game_tree->on_del(self, evt)", ORPG_DEBUG) status_value = "none" try: item = self.GetSelection() if item: obj = self.GetPyData(item) parent_obj = obj try: status_value = parent_obj.master_dom.getAttribute('status') name = parent_obj.master_dom.getAttribute('name') except: status_value = "none" parent_obj = parent_obj.master_dom._get_parentNode() while status_value!="useful" and status_value!="useless": try: status_value = parent_obj.getAttribute('status') name = parent_obj.getAttribute('name') if status_value == "useless": break elif status_value == "useful": break except: status_value = "none" try: parent_obj = parent_obj._get_parentNode() except: break if status_value == "useful": 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) if dlg.ShowModal() == wx.ID_YES: obj.delete() else: obj.delete() except: if self.GetSelection() == self.GetRootItem(): msg = wx.MessageDialog(None,"You can't delete the root item.","Delete Error",wx.OK) else: msg = wx.MessageDialog(None,"Unknown error deleting node.","Delete Error",wx.OK) msg.ShowModal() msg.Destroy() self.log.log("Exit game_tree->on_del(self, evt)", ORPG_DEBUG) def on_about(self, evt): self.log.log("Enter game_tree->on_about(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) about = MyAboutBox(self,obj.about()) about.ShowModal() about.Destroy() self.log.log("Exit game_tree->on_about(self, evt)", ORPG_DEBUG) def on_send_to_map(self, evt): self.log.log("Enter game_tree->on_send_to_map(self, evt)", ORPG_DEBUG) item = self.GetSelection() obj = self.GetPyData(item) if hasattr(obj,"on_send_to_map"): obj.on_send_to_map(evt) self.log.log("Exit game_tree->on_send_to_map(self, evt)", ORPG_DEBUG) def insert_xml(self, txt): self.log.log("Enter game_tree->insert_xml(self, txt)", ORPG_DEBUG) #Updated to allow safe merging of gametree files #without leaving an unusable and undeletable node. # -- Snowdog 8/03 xml_dom = self.xml.parseXml(txt) if xml_dom == None: wx.MessageBox("Import Failed: Invalid or missing node data") self.log.log("Import Failed: Invalid or missing node data", ORPG_DEBUG) self.log.log("Exit game_tree->insert_xml(self, txt)", ORPG_DEBUG) return xml_temp = xml_dom._get_documentElement() if not xml_temp: wx.MessageBox("Error Importing Node or Tree") self.log.log("Error Importing Node or Tree", ORPG_DEBUG) self.log.log("Exit game_tree->insert_xml(self, txt)", ORPG_DEBUG) return if xml_temp._get_tagName() == "gametree": children = xml_temp._get_childNodes() for c in children: self.load_xml(c, self.root) self.log.log("Exit game_tree->insert_xml(self, txt)", ORPG_DEBUG) return if not xml_dom: wx.MessageBox("XML Error") self.log.log("XML Error", ORPG_DEBUG) self.log.log("Exit game_tree->insert_xml(self, txt)", ORPG_DEBUG) return xml_dom = xml_dom._get_firstChild() child = self.master_dom._get_firstChild() xml_dom = self.master_dom.insertBefore(xml_dom,child) self.load_xml(xml_dom,self.root,self.root) self.log.log("Exit game_tree->insert_xml(self, txt)", ORPG_DEBUG) def build_img_list(self): """make image list""" self.log.log("Enter game_tree->build_img_list(self)", ORPG_DEBUG) helper = img_helper() self.icons = { } self._imageList= wx.ImageList(16,16,False) man = open(orpg.dirpath.dir_struct["icon"]+"icons.xml","r") xml_dom = self.xml.parseXml(man.read()) man.close() xml_dom = xml_dom._get_documentElement() node_list = xml_dom._get_childNodes() for n in node_list: key = n.getAttribute("name") path = orpg.dirpath.dir_struct["icon"] + n.getAttribute("file") img = helper.load_file(path) self.icons[key] = self._imageList.Add(img) self.SetImageList(self._imageList) self.log.log("Exit game_tree->build_img_list(self)", ORPG_DEBUG) def load_xml(self, xml_dom, parent_node, prev_node=None): self.log.log("Enter game_tree->load_xml(self, xml_dom, parent_node, prev_node)", ORPG_DEBUG) #add the first tree node i = 0 text = xml_dom.getAttribute("name") icon = xml_dom.getAttribute("icon") if self.icons.has_key(icon): i = self.icons[icon] name = xml_dom._get_nodeName() self.log.log("Text, icon and name set\n" + text + "\n" + icon + "\n" + name, ORPG_DEBUG) if prev_node: if prev_node == parent_node: new_tree_node = self.PrependItem(parent_node, text, i, i) else: new_tree_node = self.InsertItem(parent_node,prev_node, text, i, i) else: new_tree_node = self.AppendItem(parent_node, text, i, i) self.log.log("Node Added to tree", ORPG_DEBUG) #create a nodehandler or continue loading xml into tree if name == "nodehandler": #wx.BeginBusyCursor() self.log.log("We have a Nodehandler", ORPG_DEBUG) try: py_class = xml_dom.getAttribute("class") self.log.log("nodehandler class: " + py_class, ORPG_DEBUG) if not self.nodehandlers.has_key(py_class): raise Exception, "Unknown Nodehandler for " + py_class self.nodes[self.id] = self.nodehandlers[py_class](xml_dom, new_tree_node) self.SetPyData(new_tree_node, self.nodes[self.id]) self.log.log("Node Data set", ORPG_DEBUG) bmp = self.nodes[self.id].get_scaled_bitmap(16,16) if bmp: self.cached_load_of_image(bmp,new_tree_node,) self.log.log("Node Icon loaded", ORPG_DEBUG) self.id = self.id + 1 except Exception, er: self.log.log(traceback.format_exc(), ORPG_GENERAL) #self.log.log("Error Info: " + xml_dom.getAttribute("class") + "\n" + str(er), "Tree Node Load Error", ORPG_GENERAL, True) # Arbitrary fix! TaS. (gametree should thread in the future.) self.log.log("Error Info: " + xml_dom.getAttribute("class") + "\n" + str(er), ORPG_GENERAL, True) self.Delete(new_tree_node) parent = xml_dom._get_parentNode() parent.removeChild(xml_dom) #wx.EndBusyCursor() self.log.log("Exit game_tree->load_xml(self, xml_dom, parent_node, prev_node)", ORPG_DEBUG) return new_tree_node def cached_load_of_image(self, bmp_in, new_tree_node): self.log.log("Enter game_tree->cached_load_of_image(self, bmp_in, new_tree_node)", ORPG_DEBUG) image_list = self.GetImageList() img = wx.ImageFromBitmap(bmp_in) img_data = img.GetData() image_index = None for key in self.image_cache.keys(): if self.image_cache[key] == str(img_data): image_index = key break if image_index is None: image_index = image_list.Add(bmp_in) self.image_cache[image_index] = img_data self.SetItemImage(new_tree_node,image_index) self.SetItemImage(new_tree_node,image_index, wx.TreeItemIcon_Selected) self.log.log("Exit game_tree->cached_load_of_image(self, bmp_in, new_tree_node)", ORPG_DEBUG) return image_index def on_rclick(self, evt): self.log.log("Enter game_tree->on_rclick(self, evt)", ORPG_DEBUG) pt = evt.GetPosition() (item, flag) = self.HitTest(pt) if item.IsOk(): obj = self.GetPyData(item) self.SelectItem(item) if(isinstance(obj,core.node_handler)): obj.on_rclick(evt) else: self.PopupMenu(self.top_menu) else: self.PopupMenu(self.top_menu,pt) self.log.log("Exit game_tree->on_rclick(self, evt)", ORPG_DEBUG) def on_ldclick(self, evt): self.log.log("Enter game_tree->on_ldclick(self, evt)", ORPG_DEBUG) self.rename_flag = 0 pt = evt.GetPosition() (item, flag) = self.HitTest(pt) if item.IsOk(): obj = self.GetPyData(item) self.SelectItem(item) if(isinstance(obj,core.node_handler)): if not obj.on_ldclick(evt): action = self.settings.get_setting("treedclick") if action == "use": obj.on_use(evt) elif action == "design": obj.on_design(evt) elif action == "print": obj.on_html_view(evt) elif action == "chat": self.on_send_to_chat(evt) self.log.log("Exit game_tree->on_ldclick(self, evt)", ORPG_DEBUG) def on_left_down(self, evt): self.log.log("Enter game_tree->on_left_down(self, evt)", ORPG_DEBUG) pt = evt.GetPosition() (item, flag) = self.HitTest(pt) if item.IsOk() and self.was_labeling: self.SelectItem(item) self.rename_flag = 0 self.was_labeling = 0 elif (flag & wx.TREE_HITTEST_ONITEMLABEL) == wx.TREE_HITTEST_ONITEMLABEL and self.IsSelected(item): # this next if tests to ensure that the mouse up occurred over a label, and not the icon self.rename_flag = 1 else: self.SelectItem(item) evt.Skip() self.log.log("Exit game_tree->on_left_down(self, evt)", ORPG_DEBUG) def on_left_up(self, evt): self.log.log("Enter game_tree->on_left_up(self, evt)", ORPG_DEBUG) if self.dragging: cur = wx.StockCursor(wx.CURSOR_ARROW) self.SetCursor(cur) self.dragging = False pt = evt.GetPosition() (item, flag) = self.HitTest(pt) if item.IsOk(): obj = self.GetPyData(item) self.SelectItem(item) if(isinstance(obj,core.node_handler)): obj.on_drop(evt) self.drag_obj = None self.log.log("Exit game_tree->on_left_up(self, evt)", ORPG_DEBUG) def on_label_change(self, evt): self.log.log("Enter game_tree->on_label_change(self, evt)", ORPG_DEBUG) item = evt.GetItem() txt = evt.GetLabel() self.was_labeling = 0 self.rename_flag = 0 if txt != "": obj = self.GetPyData(item) obj.master_dom.setAttribute('name',txt) else: evt.Veto() self.log.log("Exit game_tree->on_label_change(self, evt)", ORPG_DEBUG) def on_label_begin(self, evt): self.log.log("Enter game_tree->on_label_begin(self, evt)", ORPG_DEBUG) if not self.rename_flag: evt.Veto() else: self.was_labeling = 1 item = evt.GetItem() if item == self.GetRootItem(): evt.Veto() self.log.log("Exit game_tree->on_label_begin(self, evt)", ORPG_DEBUG) def on_drag(self, evt): self.log.log("Enter game_tree->on_drag(self, evt)", ORPG_DEBUG) self.rename_flag = 0 item = self.GetSelection() obj = self.GetPyData(item) self.SelectItem(item) if(isinstance(obj,core.node_handler) and obj.drag): self.dragging = True cur = wx.StockCursor(wx.CURSOR_HAND) self.SetCursor(cur) self.drag_obj = obj self.log.log("Exit game_tree->on_drag(self, evt)", ORPG_DEBUG) def is_parent_node(self, node, compare_node): self.log.log("Enter game_tree->is_parent_node(self, node, compare_node)", ORPG_DEBUG) parent_node = self.GetItemParent(node) if compare_node == parent_node: self.log.log("parent node", ORPG_DEBUG) self.log.log("Exit game_tree->is_parent_node(self, node, compare_node)", ORPG_DEBUG) return 1 elif parent_node == self.root: self.log.log("not parent", ORPG_DEBUG) self.log.log("Exit game_tree->is_parent_node(self, node, compare_node)", ORPG_DEBUG) return 0 else: self.log.log("Exit game_tree->is_parent_node(self, node, compare_node)", ORPG_DEBUG) return self.is_parent_node(parent_node, compare_node) CTRL_TREE_FILE = wx.NewId() CTRL_YES = wx.NewId() CTRL_NO = wx.NewId() CTRL_USE = wx.NewId() CTRL_DESIGN = wx.NewId() CTRL_CHAT = wx.NewId() CTRL_PRINT = wx.NewId() class gametree_prop_dlg(wx.Dialog): def __init__(self, parent, settings): wx.Dialog.__init__(self, parent, wx.ID_ANY, "Game Tree Properties") self.settings = settings #sizers sizers = {} sizers['but'] = wx.BoxSizer(wx.HORIZONTAL) sizers['main'] = wx.BoxSizer(wx.VERTICAL) #box sizers box_sizers = {} box_sizers["save"] = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Save On Exit"), wx.HORIZONTAL) box_sizers["file"] = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Tree File"), wx.HORIZONTAL) box_sizers["dclick"] = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, "Double Click Action"), wx.HORIZONTAL) self.ctrls = { CTRL_TREE_FILE : FileBrowseButtonWithHistory(self, wx.ID_ANY, labelText="" ) , CTRL_YES : wx.RadioButton(self, CTRL_YES, "Yes", style=wx.RB_GROUP), CTRL_NO : wx.RadioButton(self, CTRL_NO, "No"), CTRL_USE : wx.RadioButton(self, CTRL_USE, "Use", style=wx.RB_GROUP), CTRL_DESIGN : wx.RadioButton(self, CTRL_DESIGN, "Desgin"), CTRL_CHAT : wx.RadioButton(self, CTRL_CHAT, "Chat"), CTRL_PRINT : wx.RadioButton(self, CTRL_PRINT, "Pretty Print") } self.ctrls[CTRL_TREE_FILE].SetValue(settings.get_setting("gametree")) opt = settings.get_setting("SaveGameTreeOnExit") self.ctrls[CTRL_YES].SetValue(opt=="1") self.ctrls[CTRL_NO].SetValue(opt=="0") opt = settings.get_setting("treedclick") self.ctrls[CTRL_DESIGN].SetValue(opt=="design") self.ctrls[CTRL_USE].SetValue(opt=="use") self.ctrls[CTRL_CHAT].SetValue(opt=="chat") self.ctrls[CTRL_PRINT].SetValue(opt=="print") box_sizers['save'].Add(self.ctrls[CTRL_YES],0, wx.EXPAND) box_sizers['save'].Add(wx.Size(10,10)) box_sizers['save'].Add(self.ctrls[CTRL_NO],0, wx.EXPAND) box_sizers['file'].Add(self.ctrls[CTRL_TREE_FILE], 0, wx.EXPAND) box_sizers['dclick'].Add(self.ctrls[CTRL_USE],0, wx.EXPAND) box_sizers['dclick'].Add(wx.Size(10,10)) box_sizers['dclick'].Add(self.ctrls[CTRL_DESIGN],0, wx.EXPAND) box_sizers['dclick'].Add(wx.Size(10,10)) box_sizers['dclick'].Add(self.ctrls[CTRL_CHAT],0, wx.EXPAND) box_sizers['dclick'].Add(wx.Size(10,10)) box_sizers['dclick'].Add(self.ctrls[CTRL_PRINT],0, wx.EXPAND) # buttons sizers['but'].Add(wx.Button(self, wx.ID_OK, "Apply"), 1, wx.EXPAND) sizers['but'].Add(wx.Size(10,10)) sizers['but'].Add(wx.Button(self, wx.ID_CANCEL, "Cancel"), 1, wx.EXPAND) sizers['main'].Add(box_sizers['save'], 1, wx.EXPAND) sizers['main'].Add(box_sizers['file'], 1, wx.EXPAND) sizers['main'].Add(box_sizers['dclick'], 1, wx.EXPAND) sizers['main'].Add(sizers['but'], 0, wx.EXPAND|wx.ALIGN_BOTTOM ) #sizers['main'].SetDimension(10,10,csize[0]-20,csize[1]-20) self.SetSizer(sizers['main']) self.SetAutoLayout(True) self.Fit() self.Bind(wx.EVT_BUTTON, self.on_ok, id=wx.ID_OK) def on_ok(self,evt): self.settings.set_setting("gametree",self.ctrls[CTRL_TREE_FILE].GetValue()) self.settings.set_setting("SaveGameTreeOnExit",str(self.ctrls[CTRL_YES].GetValue())) if self.ctrls[CTRL_USE].GetValue(): self.settings.set_setting("treedclick","use") elif self.ctrls[CTRL_DESIGN].GetValue(): self.settings.set_setting("treedclick","design") elif self.ctrls[CTRL_PRINT].GetValue(): self.settings.set_setting("treedclick","print") elif self.ctrls[CTRL_CHAT].GetValue(): self.settings.set_setting("treedclick","chat") self.EndModal(wx.ID_OK)