changeset 118:217fb049bd00 alpha

Traipse Alpha 'OpenRPG' {091028-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: Adds Bookmarks (Alpha) with cool Smiley Star and Plus Symbol images! Changes made to the map for increased portability. SnowDog has changes planned in Core, though. Added an initial push to the BCG. Not much to see, just shows off how it is re-writing Main code. Fix to remote admin commands Minor fix to texted based server, works in /System/ folder Some Core changes to gametree to correctly disply Pretty Print, thanks David! Fix to Splitter Nodes not being created. Added images to Plugin Control panel for Autostart feature Fix to massive amounts of images loading; from Core fix to gsclient so with_statement imports Added 'boot' command to remote admin Prep work in Pass tool for remote admin rankings and different passwords, ei, Server, Admin, Moderator, etc. Remote Admin Commands more organized, more prep work. Added Confirmation window for sent nodes. Minor changes to allow for portability to an OpenSUSE linux OS (hopefully without breaking) {091028} 00: Made changes to gametree to start working with Element Tree, mostly from Core Minor changes to Map to start working with Element Tree, from Core Preliminary changes to map efficiency, from FlexiRPG Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG Changes to main.py to start working with Element Tree
author sirebral
date Wed, 28 Oct 2009 14:24:54 -0500
parents 0f18d16f3fe7
children 9314d63c0941
files orpg/chat/chatwnd.py orpg/gametree/gametree.py orpg/gametree/nodehandlers/containers.py orpg/gametree/nodehandlers/core.py orpg/gametree/nodehandlers/d20.py orpg/gametree/nodehandlers/forms.py orpg/gametree/nodehandlers/map_miniature_nodehandler.py orpg/gametree/nodehandlers/minilib.py orpg/gametree/nodehandlers/rpg_grid.py orpg/main.py orpg/map/__init__.py orpg/map/_background.py orpg/map/_canvas.py orpg/map/_circles.py orpg/map/_fog.py orpg/map/_grid.py orpg/map/_lines.py orpg/map/_minis.py orpg/map/_object.py orpg/map/_text.py orpg/map/_tiles.py orpg/mapper/background.py orpg/mapper/base_msg.py orpg/mapper/fog.py orpg/mapper/images.py orpg/mapper/map.py orpg/mapper/miniatures.py orpg/mapper/miniatures_handler.py orpg/networking/gsclient.py orpg/networking/mplay_client.py orpg/orpg_version.py orpg/orpg_xml.py orpg/tools/pluginui.py
diffstat 30 files changed, 1702 insertions(+), 3912 deletions(-) [+]
line wrap: on
line diff
--- a/orpg/chat/chatwnd.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/chat/chatwnd.py	Wed Oct 28 14:24:54 2009 -0500
@@ -65,14 +65,14 @@
 import cStringIO # for reading inline imagedata as a stream
 from HTMLParser import HTMLParser
 import chat_util
-import traceback
-from wx.lib.expando import EVT_ETC_LAYOUT_NEEDED 
-
-from orpg.tools.validate import validate
-from orpg.tools.orpg_settings import settings
-from orpg.orpgCore import component
-from orpg.tools.orpg_log import logger
-from orpg.tools.decorators import debugging
+import traceback
+from wx.lib.expando import EVT_ETC_LAYOUT_NEEDED 
+
+from orpg.tools.validate import validate
+from orpg.tools.orpg_settings import settings
+from orpg.orpgCore import component
+from orpg.tools.orpg_log import logger
+from orpg.tools.decorators import debugging
 
 NEWCHAT = False
 try:
@@ -84,29 +84,29 @@
 # Global parser for stripping HTML tags:
 # The 'tag stripping' is implicit, because this parser echoes every
 # type of html data *except* the tags.
-class HTMLStripper(HTMLParser):
+class HTMLStripper(HTMLParser):
     @debugging
     def __init__(self):
         self.accum = ""
-        self.special_tags = ['hr', 'br', 'img']
+        self.special_tags = ['hr', 'br', 'img']
     @debugging
     def handle_data(self, data):  # quote cdata literally
-        self.accum += data
+        self.accum += data
     @debugging
     def handle_entityref(self, name): # entities must be preserved exactly
-        self.accum += "&" + name + ";"
+        self.accum += "&" + name + ";"
     @debugging
     def handle_starttag(self, tag, attrs):
         if tag in self.special_tags:
             self.accum += '<' + tag
             for attrib in attrs: self.accum += ' ' + attrib[0] + '="' + attrib[1] + '"'
-            self.accum += '>'
+            self.accum += '>'
     @debugging
     def handle_charref(self, name):  # charrefs too
         self.accum += "&#" + name + ";"
 htmlstripper = HTMLStripper()
 
-# utility function;  see Post().
+# utility function;  see Post().
 @debugging
 def strip_html(string):
     "Return string tripped of html tags."
@@ -114,7 +114,7 @@
     htmlstripper.accum = ""
     htmlstripper.feed(string)
     htmlstripper.close()
-    return htmlstripper.accum
+    return htmlstripper.accum
 
 @debugging
 def log( settings, c, text ):
@@ -150,7 +150,7 @@
     # !id :
     @debugging
     def __init__(self, parent, id):
-        wx.html.HtmlWindow.__init__(self, parent, id, 
+        wx.html.HtmlWindow.__init__(self, parent, id, 
                                     style=wx.SUNKEN_BORDER|wx.html.HW_SCROLLBAR_AUTO|wx.NO_FULL_REPAINT_ON_RESIZE)
         self.parent = parent
         self.build_menu()
@@ -176,11 +176,11 @@
         self.menu.AppendItem(item)
 
     @debugging
-    def OnM_EditCopy(self, evt):
-        wx.TheClipboard.UsePrimarySelection(False)
-        wx.TheClipboard.Open()
-        wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText()))
-        wx.TheClipboard.Close()
+    def OnM_EditCopy(self, evt):
+        wx.TheClipboard.UsePrimarySelection(False)
+        wx.TheClipboard.Open()
+        wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText()))
+        wx.TheClipboard.Close()
 
     @debugging
     def scroll_down(self):
@@ -233,7 +233,7 @@
            Returns current font settings in a (fontname, fontsize) tuple."""
         self.SetFonts(fontname, "", self.CalculateAllFonts(int(fontsize)))
         return (self.GetFont().GetFaceName(), self.GetFont().GetPointSize())
-
+
 # class chat_html_window - end
 if NEWCHAT:
     class ChatHtmlWindow(wx.webview.WebView):
@@ -266,8 +266,8 @@
 
         @debugging
         def SetDefaultFontAndSize(self, fontname, fontsize):
-            self.__font = wx.Font(int(fontsize), 
-                            wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, 
+            self.__font = wx.Font(int(fontsize), 
+                            wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, 
                             wx.FONTWEIGHT_NORMAL, faceName=fontname)
             try: self.SetPageSource(self.Header() + self.StripHeader())
             except Exception, e: print e
@@ -290,10 +290,10 @@
             wx.CallAfter(self.parent.set_chat_text_focus, None)
 
         @debugging
-        def OnM_EditCopy(self, evt):
-            wx.TheClipboard.UsePrimarySelection(False)
-            wx.TheClipboard.Open()
-            wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText()))
+        def OnM_EditCopy(self, evt):
+            wx.TheClipboard.UsePrimarySelection(False)
+            wx.TheClipboard.Open()
+            wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText()))
             wx.TheClipboard.Close()
 
         #Cutom Methods
@@ -353,10 +353,10 @@
 #   OnPageChanged(self, event)
 #   set_default_font(self, font, fontsize)
 
-class chat_notebook(orpgTabberWnd):
+class chat_notebook(orpgTabberWnd):
     @debugging
     def __init__(self, parent, size):
-        orpgTabberWnd.__init__(self, parent, True, size=size, 
+        orpgTabberWnd.__init__(self, parent, True, size=size, 
                 style=FNB.FNB_DROPDOWN_TABS_LIST|FNB.FNB_NO_NAV_BUTTONS|FNB.FNB_MOUSE_MIDDLE_CLOSES_TABS)
         self.settings = component.get("settings")
         self.whisper_tabs = []
@@ -385,7 +385,7 @@
         if self.settings.get_setting("GMWhisperTab") == '1':
             self.create_gm_tab()
         self.SetSelection(0)
-
+
     @debugging
     def get_tab_index(self, chatpanel):
         "Return the index of a chatpanel in the wxNotebook."
@@ -393,7 +393,7 @@
         for i in xrange(self.GetPageCount()):
             if (self.GetPage(i) == chatpanel):
                 return i
-
+
     @debugging
     def create_gm_tab(self):
         if self.GMChatPanel == None:
@@ -401,7 +401,7 @@
             self.AddPage(self.GMChatPanel, "GM", False)
             self.SetPageImage(self.GetPageCount()-1, 1)
             self.GMChatPanel.chatwnd.SetDefaultFontAndSize(self.font, self.fontsize)
-
+
     @debugging
     def create_whisper_tab(self, playerid):
         "Add a new chatpanel directly connected to integer 'playerid' via whispering."
@@ -414,7 +414,7 @@
         self.AliasLib = component.get('alias')
         wx.CallAfter(self.AliasLib.RefreshAliases)
         return private_tab
-
+
     @debugging
     def create_group_tab(self, group_name):
         "Add a new chatpanel directly connected to integer 'playerid' via whispering."
@@ -426,7 +426,7 @@
         self.AliasLib = component.get('alias')
         wx.CallAfter(self.AliasLib.RefreshAliases)
         return private_tab
-
+
     @debugging
     def create_null_tab(self, tab_name):
         "Add a new chatpanel directly connected to integer 'playerid' via whispering."
@@ -438,7 +438,7 @@
         self.AliasLib = component.get('alias')
         wx.CallAfter(self.AliasLib.RefreshAliases)
         return private_tab
-
+
     @debugging
     def onCloseTab(self, evt):
         try: tabid = evt.GetSelection()
@@ -467,16 +467,16 @@
         if panel in self.whisper_tabs: self.whisper_tabs.remove(panel)
         elif panel in self.group_tabs: self.group_tabs.remove(panel)
         elif panel in self.null_tabs: self.null_tabs.remove(panel)
-
+
     @debugging
     def newMsg(self, tabid):
         if tabid != self.GetSelection(): self.SetPageImage(tabid, 0)
-
+
     @debugging
     def onPageChanging(self, event):
         """When private chattabs are selected, set the bitmap back to 'normal'."""
         event.Skip()
-
+
     @debugging
     def onPageChanged(self, event):
         """When private chattabs are selected, set the bitmap back to 'normal'."""
@@ -485,7 +485,7 @@
         page = self.GetPage(selected_idx)
         #wx.CallAfter(page.set_chat_text_focus, 0)
         event.Skip()
-
+
 """
  This class defines and builds the Chat Frame for OpenRPG
 
@@ -512,11 +512,11 @@
    ParseNodes(self,s)
    get_sha_checksum(self)
    get_color(self)
-
+
 """
 
 class chat_panel(wx.Panel):
-
+
     """
     This is the initialization subroutine
     
@@ -524,13 +524,13 @@
     !parent : parent that defines the chatframe
     !id :
     !openrpg :
-    !sendtarget:  who gets outbound messages: either 'all' or a playerid
-    """
-
+    !sendtarget:  who gets outbound messages: either 'all' or a playerid
+    """
+
     @debugging
     def __init__(self, parent, id, tab_type, sendtarget):
-        wx.Panel.__init__(self, parent, id)
-        logger._set_log_to_console(False)
+        wx.Panel.__init__(self, parent, id)
+        logger._set_log_to_console(False)
         self.session = component.get('session')
         self.settings = component.get('settings')
         self.activeplugins = component.get('plugins')
@@ -562,8 +562,8 @@
         self.advancedFilter = False
         self.lastSend = 0         #  this is used to help implement the player typing indicator
         self.lastPress = 0        #  this is used to help implement the player typing indicator
-        self.Bind(wx.EVT_SIZE, self.OnSize)
-        self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnSize) #require to keep text at bottom of chat when text entry expands --SD
+        self.Bind(wx.EVT_SIZE, self.OnSize)
+        self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnSize) #require to keep text at bottom of chat when text entry expands --SD
         self.build_ctrls()
         StartupFont = self.settings.get_setting("defaultfont")
         StartupFontSize = self.settings.get_setting("defaultfontsize")
@@ -572,11 +572,11 @@
             except: pass
         self.font = self.chatwnd.GetFont().GetFaceName()
         self.fontsize = self.chatwnd.GetFont().GetPointSize()
-        self.scroll_down()
-
+        self.scroll_down()
+
     @debugging
     def set_default_font(self, fontname=None, fontsize=None):
-        """Set all chatpanels to new default fontname/fontsize. 
+        """Set all chatpanels to new default fontname/fontsize. 
         Returns current font settings in a (fontname, fontsize) tuple."""
         if (fontname is not None): newfont = fontname
         else: newfont = self.font
@@ -587,10 +587,10 @@
         self.font = newfont
         self.fontsize = newfontsize
         return (self.font, self.fontsize)
-
+
     @debugging
     def build_menu(self):
-        top_frame = component.get('frame')
+        top_frame = component.get('frame')
         menu = wx.Menu()
         item = wx.MenuItem(menu, wx.ID_ANY, "&Background color", "Background color")
         top_frame.Bind(wx.EVT_MENU, self.OnMB_BackgroundColor, item)
@@ -625,7 +625,7 @@
         tabmenu = wx.Menu()
         toolmenu = wx.Menu()
         item = wx.MenuItem(wndmenu, wx.ID_ANY, "Show Images", "Show Images", wx.ITEM_CHECK)
-        top_frame.Bind(wx.EVT_MENU, self.OnMB_ShowImages, item)
+        top_frame.Bind(wx.EVT_MENU, self.OnMB_ShowImages, item)
 
         wndmenu.AppendItem(item)
         if self.settings.get_setting("Show_Images_In_Chat") == '1': item.Check(True)
@@ -676,57 +676,57 @@
         toolmenu.AppendItem(item)
         if self.settings.get_setting("AliasTool_On") == '1': item.Check(True)
         settingmenu.AppendMenu(wx.ID_ANY, 'Chat Tool Bars', toolmenu)
-        menu.AppendMenu(wx.ID_ANY, 'Chat Settings', settingmenu)
+        menu.AppendMenu(wx.ID_ANY, 'Chat Settings', settingmenu)
         top_frame.mainmenu.Insert(2, menu, '&Chat')
 
-    ## Settings Menu Events
+    ## Settings Menu Events
     @debugging
     def OnMB_ShowImages(self, event):
         if event.IsChecked(): self.settings.set_setting("Show_Images_In_Chat", '1')
         else: self.settings.set_setting("Show_Images_In_Chat", '0')
-
+
     @debugging
     def OnMB_StripHTML(self, event):
         if event.IsChecked(): self.settings.set_setting("Sstriphtml", '1')
         else: self.settings.set_setting("striphtml", '0')
-
+
     @debugging
     def OnMB_ChatTimeIndex(self, event):
         if event.IsChecked(): self.settings.set_setting("Chat_Time_Indexing", '1')
         else: self.settings.set_setting("Chat_Time_Indexing", '0')
-
+
     @debugging
     def OnMB_ChatAutoComplete(self, event):
         if event.IsChecked(): self.settings.set_setting("SuppressChatAutoComplete", '0')
         else: self.settings.set_setting("SuppressChatAutoComplete", '1')
-
+
     @debugging
     def OnMB_ShowIDinChat(self, event):
         if event.IsChecked(): self.settings.set_setting("ShowIDInChat", '1')
         else: self.settings.set_setting("ShowIDInChat", '0')
-
+
     @debugging
     def OnMB_LogTimeIndex(self, event):
         if event.IsChecked(): self.settings.set_setting("TimeStampGameLog", '1')
         else: self.settings.set_setting("TimeStampGameLog", '0')
-
+
     @debugging
     def OnMB_TabbedWhispers(self, event):
         if event.IsChecked(): self.settings.set_setting("tabbedwhispers", '1')
         else: self.settings.set_setting("tabbedwhispers", '0')
-
+
     @debugging
     def OnMB_GMTab(self, event):
         if event.IsChecked():
             self.settings.set_setting("GMWhisperTab", '1')
             self.parent.create_gm_tab()
         else: self.settings.set_setting("GMWhisperTab", '0')
-
+
     @debugging
     def OnMB_GroupWhisperTabs(self, event):
         if event.IsChecked(): self.settings.set_setting("GroupWhisperTab", '1')
         else: self.settings.set_setting("GroupWhisperTab", '0')
-
+
     @debugging
     def OnMB_DiceBar(self, event):
         act = '0'
@@ -740,7 +740,7 @@
         for panel in self.parent.whisper_tabs: panel.toggle_dice(act)
         for panel in self.parent.group_tabs: panel.toggle_dice(act)
         for panel in self.parent.null_tabs: panel.toggle_dice(act)
-
+
     @debugging
     def OnMB_FormatButtons(self, event):
         act = '0'
@@ -755,7 +755,7 @@
         for panel in self.parent.whisper_tabs: panel.toggle_formating(act)
         for panel in self.parent.group_tabs: panel.toggle_formating(act)
         for panel in self.parent.null_tabs: panel.toggle_formating(act)
-
+
     @debugging
     def OnMB_AliasTool(self, event):
         act = '0'
@@ -769,7 +769,7 @@
         for panel in self.parent.whisper_tabs: panel.toggle_alias(act)
         for panel in self.parent.group_tabs: panel.toggle_alias(act)
         for panel in self.parent.null_tabs:panel.toggle_alias(act)
-
+
     @debugging
     def OnMB_BackgroundColor(self, event):
         top_frame = component.get('frame')
@@ -791,7 +791,7 @@
                 top_frame.players.SetForegroundColour('black')
                 top_frame.players.Refresh()
             self.chatwnd.scroll_down()
-
+
     @debugging
     def OnMB_TextColor(self, event):
         top_frame = component.get('frame')
@@ -813,7 +813,7 @@
                 top_frame.players.SetForegroundColour('black')
                 top_frame.players.Refresh()
             self.chatwnd.scroll_down()
-
+
     @debugging
     def get_hot_keys(self):
         # dummy menus for hotkeys
@@ -822,7 +822,7 @@
         entries.append((wx.ACCEL_CTRL, ord('H'), self.setChatFocusMenu.GetId()))
         #entries.append((wx.ACCEL_CTRL, wx.WXK_TAB, SWAP_TABS))
         return entries
-
+
     @debugging
     def forward_tabs(self, evt):
         self.parent.AdvanceSelection()
@@ -832,18 +832,18 @@
 
     # This subroutine builds the controls for the chat frame
     #
-    # !self : instance of self
+    # !self : instance of self
     @debugging
     def build_ctrls(self):
         self.chatwnd = chat_html_window(self,-1)
         self.set_colors()
         wx.CallAfter(self.chatwnd.SetPage, self.chatwnd.Header())
         if (self.sendtarget == "all"):
-            wx.CallAfter(self.Post, self.colorize(self.syscolor, 
+            wx.CallAfter(self.Post, self.colorize(self.syscolor, 
                 "<b>Welcome to <a href='http://www.openrpg.com'>OpenRPG</a> version " + self.version + "...  </b>"))
             #self.chat_cmds.on_help()
-        self.chattxt = orpg.tools.predTextCtrl.predTextCtrl(self, -1, "", 
-                        style=wx.TE_PROCESS_ENTER |wx.TE_PROCESS_TAB|wx.TE_LINEWRAP, 
+        self.chattxt = orpg.tools.predTextCtrl.predTextCtrl(self, -1, "", 
+                        style=wx.TE_PROCESS_ENTER |wx.TE_PROCESS_TAB|wx.TE_LINEWRAP, 
                         keyHook = self.myKeyHook, validator=None )
         self.build_bar()
         self.basesizer = wx.BoxSizer(wx.VERTICAL)
@@ -880,7 +880,7 @@
         self.chattxt.Bind(wx.EVT_CHAR, self.chattxt.OnChar)
         self.chattxt.Bind(wx.EVT_TEXT_COPY, self.chatwnd.OnM_EditCopy)
     # def build_ctrls - end
-
+
     @debugging
     def build_bar(self):
         self.toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL)
@@ -896,19 +896,19 @@
             self.toolbar_sizer.Add(self.scroll_lock,0,wx.EXPAND)
             self.build_formating()
             self.build_colorbutton()
-
+
     @debugging
     def build_scroll(self):
         self.scroll_lock = wx.Button( self, wx.ID_ANY, "Scroll ON",size= wx.Size(80,25))
-
+
     @debugging
     def build_alias(self):
         self.aliasList = wx.Choice(self, wx.ID_ANY, size=(100, 25), choices=[self.defaultAliasName])
-        self.aliasButton = createMaskedButton( self, dir_struct["icon"] + 'player.gif', 
+        self.aliasButton = createMaskedButton( self, dir_struct["icon"] + 'player.gif', 
                                             'Refresh list of aliases from Game Tree', wx.ID_ANY, '#bdbdbd' )
         self.aliasList.SetSelection(0)
         self.filterList = wx.Choice(self, wx.ID_ANY, size=(100, 25), choices=[self.defaultFilterName])
-        self.filterButton = createMaskedButton( self, dir_struct["icon"] + 'add_filter.gif', 
+        self.filterButton = createMaskedButton( self, dir_struct["icon"] + 'add_filter.gif', 
                                              'Refresh list of filters from Game Tree', wx.ID_ANY, '#bdbdbd' )
         self.filterList.SetSelection(0)
         self.toolbar_sizer.Add( self.aliasButton, 0, wx.EXPAND )
@@ -917,7 +917,7 @@
         self.toolbar_sizer.Add( self.filterList,0,wx.EXPAND)
         if self.settings.get_setting('AliasTool_On') == '0': self.toggle_alias('0')
         else: self.toggle_alias('1')
-
+
     @debugging
     def toggle_alias(self, act):
         if act == '0':
@@ -932,11 +932,11 @@
             self.toolbar_sizer.Show(self.aliasButton, True)
             self.toolbar_sizer.Show(self.filterButton, True)
             self.toolbar_sizer.Layout()
-
+
     @debugging
     def build_text(self):
         self.textpop_lock = createMaskedButton(self, dir_struct["icon"]+'note.gif', 'Open Text View Of Chat Session', wx.ID_ANY, '#bdbdbd')
-
+
     @debugging
     def build_dice(self):
         self.numDieText = wx.TextCtrl( self, wx.ID_ANY, "1", size= wx.Size(25, 25), validator=orpg.tools.inputValidator.MathOnlyValidator() )
@@ -959,7 +959,7 @@
         self.toolbar_sizer.Add( self.dieModText, 0, wx.ALIGN_CENTER, 5 )
         if self.settings.get_setting('DiceButtons_On') == '0': self.toggle_dice('0')
         else: self.toggle_dice('1')
-
+
     @debugging
     def toggle_dice(self, act):
         if act == '0':
@@ -984,21 +984,21 @@
             self.toolbar_sizer.Show(self.d100Button, True)
             self.toolbar_sizer.Show(self.dieModText, True)
             self.toolbar_sizer.Layout()
-
+
     @debugging
     def build_formating(self):
-        self.boldButton = createMaskedButton( self, dir_struct["icon"]+'bold.gif', 
+        self.boldButton = createMaskedButton( self, dir_struct["icon"]+'bold.gif', 
                                                             'Make the selected text Bold', wx.ID_ANY, '#bdbdbd')
-        self.italicButton = createMaskedButton( self, dir_struct["icon"]+'italic.gif', 
+        self.italicButton = createMaskedButton( self, dir_struct["icon"]+'italic.gif', 
                                                             'Italicize the selected text', wx.ID_ANY, '#bdbdbd' )
-        self.underlineButton = createMaskedButton( self, dir_struct["icon"]+'underlined.gif', 
+        self.underlineButton = createMaskedButton( self, dir_struct["icon"]+'underlined.gif', 
                                                             'Underline the selected text', wx.ID_ANY, '#bdbdbd' )
         self.toolbar_sizer.Add( self.boldButton, 0, wx.EXPAND )
         self.toolbar_sizer.Add( self.italicButton, 0, wx.EXPAND )
         self.toolbar_sizer.Add( self.underlineButton, 0, wx.EXPAND )
         if self.settings.get_setting('FormattingButtons_On') == '0': self.toggle_formating('0')
         else: self.toggle_formating('1')
-
+
     @debugging
     def toggle_formating(self, act):
         if act == '0':
@@ -1012,20 +1012,20 @@
             self.toolbar_sizer.Show(self.underlineButton, True)
             self.toolbar_sizer.Layout()
 
-    # Heroman - Ideally, we would use static labels...
+    # Heroman - Ideally, we would use static labels...
     @debugging
     def build_colorbutton(self):
-        self.color_button = createMaskedButton(self, dir_struct["icon"]+'textcolor.gif', 
-                                                    'Text Color', wx.ID_ANY, '#bdbdbd', 
-                                                    wx.BITMAP_TYPE_GIF)
+        self.color_button = createMaskedButton(self, dir_struct["icon"]+'textcolor.gif', 
+                                                    'Text Color', wx.ID_ANY, '#bdbdbd', 
+                                                    wx.BITMAP_TYPE_GIF)
 
-        self.saveButton = createMaskedButton(self, dir_struct["icon"]+'save.bmp', 
-                                                    'Save the chatbuffer', wx.ID_ANY, 
-                                                    '#c0c0c0', wx.BITMAP_TYPE_BMP )
+        self.saveButton = createMaskedButton(self, dir_struct["icon"]+'save.bmp', 
+                                                    'Save the chatbuffer', wx.ID_ANY, 
+                                                    '#c0c0c0', wx.BITMAP_TYPE_BMP )
         self.color_button.SetBackgroundColour(self.settings.get_setting('mytextcolor'))
         self.toolbar_sizer.Add(self.color_button, 0, wx.EXPAND)
-        self.toolbar_sizer.Add(self.saveButton, 0, wx.EXPAND)
-
+        self.toolbar_sizer.Add(self.saveButton, 0, wx.EXPAND)
+
     @debugging
     def OnMotion(self, evt):
         contain = self.chatwnd.GetInternalRepresentation()
@@ -1051,7 +1051,7 @@
 
     #
     #  self:  duh
-    #  event:  raw KeyEvent from OnChar()
+    #  event:  raw KeyEvent from OnChar()
     @debugging
     def myKeyHook(self, event):
         if self.session.get_status() == MPLAY_CONNECTED:   #  only do if we're connected
@@ -1071,7 +1071,7 @@
     #  This subroutine gets called once a second by the typing Timer
     #  It checks if we need to send a not_typing message
     #
-    #  self:  duh
+    #  self:  duh
     @debugging
     def typingTimerFunc(self, event):
         #following added by mDuo13
@@ -1093,8 +1093,8 @@
     #  This subroutine actually takes care of sending the messages for typing/not_typing events
     #
     #  self:  duh
-    #  typing:  boolean
-
+    #  typing:  boolean
+
     @debugging
     def sendTyping(self, typing):
         if typing:
@@ -1113,7 +1113,7 @@
     # This subroutine sets the colors of the chat based on the settings in the
     # self instance.
     #
-    # !self : instance of self
+    # !self : instance of self
     @debugging
     def set_colors(self):
         # chat window backround color
@@ -1135,19 +1135,19 @@
     # This subroutine will insert text into the chat window
     #
     # !self : instance of self
-    # !txt : text to be inserted into the chat window
+    # !txt : text to be inserted into the chat window
     @debugging
     def set_chat_text(self, txt):
         self.chattxt.SetValue(txt)
         self.chattxt.SetFocus()
         self.chattxt.SetInsertionPointEnd()
     # def set_chat_text - end
-
+
     @debugging
     def get_chat_text(self):
         return self.chattxt.GetValue()
 
-    # This subroutine sets the focus to the chat window
+    # This subroutine sets the focus to the chat window
     @debugging
     def set_chat_text_focus(self, event):
         wx.CallAfter(self.chattxt.SetFocus)
@@ -1160,7 +1160,7 @@
     # !event :
     #
     # Note:  self.chattxt now handles it's own Key events.  It does, however still
-    #        call it's parent's (self) OnChar to handle "default" behavior.
+    #        call it's parent's (self) OnChar to handle "default" behavior.
     @debugging
     def OnChar(self, event):
         s = self.chattxt.GetValue()
@@ -1174,18 +1174,18 @@
             if self.session.get_status() == MPLAY_CONNECTED:          #  only do if we're connected
                 self.sendTyping(0)                                    #  Send a "not_typing" event on enter key press
         macroText=""
-        recycle_bin = {wx.WXK_F1: 'event.GetKeyCode() == wx.WXK_F1', wx.WXK_F2: 'event.GetKeyCode() == wx.WXK_F2', 
-                    wx.WXK_F3: 'event.GetKeyCode() == wx.WXK_F3', wx.WXK_F4: 'event.GetKeyCode() == wx.WXK_F4', 
-                    wx.WXK_F5: 'event.GetKeyCode() == wx.WXK_F5', wx.WXK_F6: 'event.GetKeyCode() == wx.WXK_F6', 
-                    wx.WXK_F7: 'event.GetKeyCode() == wx.WXK_F7', wx.WXK_F8: 'event.GetKeyCode() == wx.WXK_F8', 
-                    wx.WXK_F9: 'event.GetKeyCode() == wx.WXK_F9', wx.WXK_F10: 'event.GetKeyCode() == wx.WXK_F10', 
-                    wx.WXK_F11: 'event.GetKeyCode() == wx.WXK_F11', wx.WXK_F12: 'event.GetKeyCode() == wx.WXK_F12'}
-
-        bin_event = event.GetKeyCode()
-	if recycle_bin.has_key(bin_event):
-	    logger.debug(lambda bin_event: recycle_bin[bin_event])
-	    macroText = self.settings.get_setting(recycle_bin[bin_event][29:])
-	    recycle_bin = {}; del bin_event
+        recycle_bin = {wx.WXK_F1: 'event.GetKeyCode() == wx.WXK_F1', wx.WXK_F2: 'event.GetKeyCode() == wx.WXK_F2', 
+                    wx.WXK_F3: 'event.GetKeyCode() == wx.WXK_F3', wx.WXK_F4: 'event.GetKeyCode() == wx.WXK_F4', 
+                    wx.WXK_F5: 'event.GetKeyCode() == wx.WXK_F5', wx.WXK_F6: 'event.GetKeyCode() == wx.WXK_F6', 
+                    wx.WXK_F7: 'event.GetKeyCode() == wx.WXK_F7', wx.WXK_F8: 'event.GetKeyCode() == wx.WXK_F8', 
+                    wx.WXK_F9: 'event.GetKeyCode() == wx.WXK_F9', wx.WXK_F10: 'event.GetKeyCode() == wx.WXK_F10', 
+                    wx.WXK_F11: 'event.GetKeyCode() == wx.WXK_F11', wx.WXK_F12: 'event.GetKeyCode() == wx.WXK_F12'}
+
+        bin_event = event.GetKeyCode()
+	if recycle_bin.has_key(bin_event):
+	    logger.debug(lambda bin_event: recycle_bin[bin_event])
+	    macroText = self.settings.get_setting(recycle_bin[bin_event][29:])
+	    recycle_bin = {}; del bin_event
 
         # Append to the existing typed text as needed and make sure the status doesn't change back.
         if len(macroText):
@@ -1301,7 +1301,7 @@
         else: event.Skip()
         logger.debug("Exit chat_panel->OnChar(self, event)")
     # def OnChar - end
-
+
     @debugging
     def onDieRoll(self, evt):
         """Roll the dice based on the button pressed and the die modifiers entered, if any."""
@@ -1322,7 +1322,7 @@
     # FileDialog.
     #
     # !self : instance of self
-    # !evt :
+    # !evt :
     @debugging
     def on_chat_save(self, evt):
         f = wx.FileDialog(self,"Save Chat Buffer",".","","HTM* (*.htm*)|*.htm*|HTML (*.html)|*.html|HTM (*.htm)|*.htm",wx.SAVE)
@@ -1333,19 +1333,19 @@
         f.Destroy()
         os.chdir(dir_struct["home"])
     # def on_chat_save - end
-
+
     @debugging
     def ResetPage(self):
         self.set_colors()
         buffertext = self.chatwnd.Header() + "\n"
-        buffertext += chat_util.strip_body_tags(self.chatwnd.StripHeader()).replace("<br>", 
-                                                                            "<br />").replace('</html>', 
-                                                                            '').replace("<br />", 
+        buffertext += chat_util.strip_body_tags(self.chatwnd.StripHeader()).replace("<br>", 
+                                                                            "<br />").replace('</html>', 
+                                                                            '').replace("<br />", 
                                                                             "<br />\n").replace("\n\n", '')
         return buffertext
 
     # This subroutine sets the color of selected text, or base text color if
-    # nothing is selected
+    # nothing is selected
     @debugging
     def on_text_color(self, event):
         hexcolor = self.r_h.do_hex_color_dlg(self)
@@ -1369,7 +1369,7 @@
     #
     # !self : instance of self
     # !color : color for the text to be set
-    # !text : text string to be included in the html.
+    # !text : text string to be included in the html.
     @debugging
     def colorize(self, color, text):
         """Puts font tags of 'color' around 'text' value, and returns the string"""
@@ -1380,7 +1380,7 @@
     # tags included.
     #
     # !self : instance of self
-    # !event :
+    # !event :
     @debugging
     def on_text_format(self, event):
         id = event.GetId()
@@ -1397,7 +1397,7 @@
         self.chattxt.SetInsertionPointEnd()
         self.chattxt.SetFocus()
     # def on_text_format - end
-
+
     @debugging
     def lock_scroll(self, event):
         if self.lockscroll:
@@ -1414,7 +1414,7 @@
     # This subroutine will popup a text window with the chatbuffer contents
     #
     # !self : instance of self
-    # !event :
+    # !event :
     @debugging
     def pop_textpop(self, event):
         """searchable popup text view of chatbuffer"""
@@ -1425,35 +1425,35 @@
     # This subroutine will change the dimension of the window
     #
     # !self : instance of self
-    # !event :
+    # !event :
     @debugging
     def OnSize(self, event=None):
         event.Skip()
         wx.CallAfter(self.scroll_down)
     # def OnSize - end
-
+
     @debugging
     def scroll_down(self):
         self.Freeze()
         self.chatwnd.scroll_down()
         self.Thaw()
 
-    ###### message helpers ######
+    ###### message helpers ######
     @debugging
     def PurgeChat(self):
         self.set_colors()
         self.chatwnd.SetPage(self.chatwnd.Header())
-
+
     @debugging
     def system_message(self, text):
         self.send_chat_message(text,chat_msg.SYSTEM_MESSAGE)
         self.SystemPost(text)
-
+
     @debugging
     def info_message(self, text):
         self.send_chat_message(text,chat_msg.INFO_MESSAGE)
         self.InfoPost(text)
-
+
     @debugging
     def get_gms(self):
         the_gms = []
@@ -1461,7 +1461,7 @@
             if len(self.session.players[playerid])>7:
                 if self.session.players[playerid][7]=="GM" and self.session.group_id != '0': the_gms += [playerid]
         return the_gms
-
+
     @debugging
     def GetName(self):
         self.AliasLib = component.get('alias')
@@ -1472,7 +1472,7 @@
                 logger.debug("Exit chat_panel->GetName(self)")
                 return [self.chat_display_name([self.AliasLib.alias[0], player[1], player[2]]), self.AliasLib.alias[1]]
         return [self.chat_display_name(player), "Default"]
-
+
     @debugging
     def GetFilteredText(self, text):
         advregex = re.compile('\"(.*?)\"', re.I)
@@ -1487,12 +1487,12 @@
                         newmatch = re.sub(rule[0], rule[1], match)
                         text = text.replace(match, newmatch)
         return text
-
+
     @debugging
     def emote_message(self, text):
         text = self.NormalizeParse(text)
         text = self.colorize(self.emotecolor, text)
-
+
         if self.type == MAIN_TAB and self.sendtarget == 'all': self.send_chat_message(text,chat_msg.EMOTE_MESSAGE)
         elif self.type == MAIN_TAB and self.sendtarget == "gm":
             msg_type = chat_msg.WHISPER_EMOTE_MESSAGE
@@ -1506,7 +1506,7 @@
         name = self.GetName()[0]
         text = "** " + name + " " + text + " **"
         self.EmotePost(text)
-
+
     @debugging
     def whisper_to_players(self, text, player_ids):
         tabbed_whispers_p = self.settings.get_setting("tabbedwhispers")
@@ -1533,7 +1533,7 @@
             id = id.strip()
             if self.session.is_valid_id(id): self.send_chat_message(text,chat_msg.WHISPER_MESSAGE,id)
             else: self.InfoPost(id + " Unknown!")
-
+
     @debugging
     def send_chat_message(self, text, type=chat_msg.CHAT_MESSAGE, player_id="all"):
         #########send_msg()#############
@@ -1558,8 +1558,8 @@
         msg.set_alias(playername)
         if send: self.session.send(msg.toxml(),player_id)
         del msg
-
-    #### incoming chat message handler #####
+
+    #### incoming chat message handler #####
     @debugging
     def post_incoming_msg(self, msg, player):
 
@@ -1683,20 +1683,20 @@
         if sound_file != '':
             component.get('sound').play(sound_file)
     #### Posting helpers #####
-
+
     @debugging
     def InfoPost(self, s):
         self.Post(self.colorize(self.infocolor, s), c='info')
-
+
     @debugging
     def SystemPost(self, s):
         self.Post(self.colorize(self.syscolor, s), c='system')
-
+
     @debugging
     def EmotePost(self, s):
         self.Post(self.colorize(self.emotecolor, s), c='emote')
 
-    #### Standard Post method #####
+    #### Standard Post method #####
     @debugging
     def Post(self, s="", send=False, myself=False, c='post'):
         strip_p = self.settings.get_setting("striphtml")
@@ -1707,7 +1707,7 @@
         s = chat_util.strip_script_tags(s)
         s = chat_util.strip_li_tags(s)
         s = chat_util.strip_body_tags(s) #7-27-05 mDuo13
-        s = chat_util.strip_misalignment_tags(s) #7-27-05 mDuo13
+        s = chat_util.strip_misalignment_tags(s) #7-27-05 mDuo13
         aliasInfo = self.GetName()
         display_name = aliasInfo[0]
         if aliasInfo[1] != 'Default':
@@ -1767,7 +1767,7 @@
                     newline = "<div class='"+c+"'> " + self.TimeIndexString() + name + s2 + "</div>"
                     log( self.settings, c, name+s2 )
             else:
-                newline = "<div class='"+c+"'> " + self.TimeIndexString() + name + s + "</div>"
+                newline = "<div class='"+c+"'> " + self.TimeIndexString() + name + s + "</div>"
                 log( self.settings, c, name+s )
         else: send = False
         newline = component.get('xml').strip_unicode(newline)
@@ -1775,7 +1775,7 @@
             self.chatwnd.AppendToPage(newline)
             self.scroll_down()
         else: self.storedata.append(newline)
-        if send:
+        if send:
             if self.type == MAIN_TAB and self.sendtarget == 'all': self.send_chat_message(s)
             elif self.type == MAIN_TAB and self.sendtarget == "gm":
                 the_gms = self.get_gms()
@@ -1793,7 +1793,7 @@
     # TimeIndexString()
     #
     # time indexing for chat display only (don't log time indexing)
-    # added by Snowdog 4/04
+    # added by Snowdog 4/04
     @debugging
     def TimeIndexString(self):
         try:
@@ -1807,15 +1807,15 @@
             logger.general("EXCEPTION: " + str(e))
             return "[ERROR]"
 
-    ####  Post with parsing dice ####
+    ####  Post with parsing dice ####
     @debugging
     def ParsePost(self, s, send=False, myself=False):
         s = self.NormalizeParse(s)
         self.set_colors()
         self.Post(s,send,myself)
-
+
     @debugging
-    def NormalizeParse(self, s):
+    def NormalizeParse(self, s):
         for plugin_fname in self.activeplugins.keys():
             plugin = self.activeplugins[plugin_fname]
             try: s = plugin.pre_parse(s)
@@ -1829,14 +1829,14 @@
             s = self.ParseFilter(s)
             self.parsed = 1
         return s
-
+
     @debugging
-    def ParseFilter(self, s):
+    def ParseFilter(self, s):
         s = self.GetFilteredText(s)
         return s
-
+
     @debugging
-    def ParseNode(self, s):
+    def ParseNode(self, s):
         """Parses player input for embedded nodes rolls"""
         cur_loc = 0
         #[a-zA-Z0-9 _\-\.]
@@ -1846,14 +1846,14 @@
             newstr = self.ParseNode(self.resolve_nodes(matches[i][1]))
             s = s.replace(matches[i][0], newstr, 1)
         return s
-
+
     @debugging
-    def ParseDice(self, s):
+    def ParseDice(self, s):
         """Parses player input for embedded dice rolls"""
         reg = re.compile("\[([^]]*?)\]")
         matches = reg.findall(s)
         for i in xrange(0,len(matches)):
-            newstr = self.PraseUnknowns(matches[i])
+            newstr = self.PraseUnknowns(matches[i])
             qmode = 0
             newstr1 = newstr
             if newstr[0].lower() == 'q':
@@ -1865,9 +1865,9 @@
                 s = s.replace("[" + matches[i] + "]", "<!-- Official Roll [" + newstr1 + "] => " + newstr + "-->" + newstr, 1)
             else: s = s.replace("[" + matches[i] + "]", "[" + newstr1 + "<!-- Official Roll -->] => " + newstr, 1)
         return s
-
+
     @debugging
-    def PraseUnknowns(self, s):
+    def PraseUnknowns(self, s):
 	# Uses a tuple. Usage: ?Label}dY. If no Label is assigned then use ?}DY
         newstr = "0"
         reg = re.compile("(\?\{*)([a-zA-Z ]*)(\}*)")
@@ -1884,22 +1884,22 @@
             if newstr == '': newstr = '0'
             s = s.replace(matches[i][0], newstr, 1).replace(matches[i][1], '', 1).replace(matches[i][2], '', 1)
             dlg.Destroy()
-        return s
+        return s
 
     # This subroutine builds a chat display name.
-    #
+    #
     @debugging
-    def chat_display_name(self, player):
+    def chat_display_name(self, player):
         if self.settings.get_setting("ShowIDInChat") == "0":
             display_name = player[0]
         else:
             display_name = "("+player[2]+") " + player[0]
         return display_name
-
+
     # This subroutine will get a hex color and return it, or return nothing
-    #
+    #
     @debugging
-    def get_color(self):
+    def get_color(self):
         data = wx.ColourData()
         data.SetChooseFull(True)
         dlg = wx.ColourDialog(self, data)
@@ -1913,7 +1913,7 @@
             dlg.Destroy()
             return None
     # def get_color - end
-
+
     @debugging
     def replace_quotes(self, s):
         in_tag = 0
@@ -1929,14 +1929,14 @@
                 if in_tag:
                     rs = rs[:i] + "'" + rs[i+1:]
             i += 1
-        return rs
+        return rs
 
     @debugging
-    def resolve_loop(self, dom, nodeName, doLoop = False):
-        for node in dom:
+    def resolve_loop(self, dom, nodeName, doLoop = False):
+        for node in dom:
             if node._get_tagName() != 'nodehandler':
                 continue
-            if doLoop and node.getAttribute('class') != 'textctrl_handler' and node.hasChildNodes():
+            if doLoop and node.getAttribute('class') != 'textctrl_handler' and node.hasChildNodes():
                 (found, node) = self.resolve_loop(node.getChildren(), nodeName, doLoop)
                 if not found:
                     continue
@@ -1944,10 +1944,10 @@
                     continue
             foundNode = node
             return (True, foundNode)
-        return (False, '')
+        return (False, '')
 
     @debugging
-    def resolve_nodes(self, s):
+    def resolve_nodes(self, s):
         value = ""
         node_path_list = s.split("::")
         gametree = component.get('tree')
@@ -1974,4 +1974,4 @@
             value = node._get_nodeValue()
         else:
             value = s
-        return value
+        return value
--- a/orpg/gametree/gametree.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/gametree/gametree.py	Wed Oct 28 14:24:54 2009 -0500
@@ -26,28 +26,35 @@
 # Description: The file contains code fore the game tree shell
 #
 
+from __future__ import with_statement
+
 __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 component
 from orpg.dirpath import dir_struct
-from nodehandlers import core
+from nodehandlers import core
 import string
 import urllib
 import time
-import os
-
-from orpg.orpg_xml import xml
-from orpg.tools.validate import validate
-from orpg.tools.orpg_log import logger
+import os
+
+from orpg.orpg_xml import xml
+from orpg.tools.validate import validate
+from orpg.tools.orpg_log import logger
 from orpg.tools.decorators import debugging
+from orpg.tools.orpg_settings import settings
 from orpg.gametree.nodehandlers import containers, forms, dnd3e, dnd35, chatmacro
 from orpg.gametree.nodehandlers import map_miniature_nodehandler
-from orpg.gametree.nodehandlers import minilib, rpg_grid, d20, StarWarsd20, voxchat
-
+from orpg.gametree.nodehandlers import minilib, rpg_grid, d20, StarWarsd20, voxchat
+
 from gametree_version import GAMETREE_VERSION
 
+from xml.etree.ElementTree import ElementTree, Element, parse
+from xml.etree.ElementTree import fromstring, tostring, XML, iselement
+from xml.parsers.expat import ExpatError
+
 STD_MENU_DELETE = wx.NewId()
 STD_MENU_DESIGN = wx.NewId()
 STD_MENU_USE = wx.NewId()
@@ -76,10 +83,10 @@
 TOP_TREE_PROP = wx.NewId()
 TOP_FEATURES = wx.NewId()
 
-class game_tree(wx.TreeCtrl):
+class game_tree(wx.TreeCtrl):
     @debugging
     def __init__(self, parent, id):
-        wx.TreeCtrl.__init__(self,parent,id,  wx.DefaultPosition, 
+        wx.TreeCtrl.__init__(self,parent,id,  wx.DefaultPosition, 
                 wx.DefaultSize,style=wx.TR_EDIT_LABELS | wx.TR_HAS_BUTTONS)
         #self.xml = component.get('xml') #
         self.settings = component.get('settings')
@@ -113,18 +120,18 @@
         self.rename_flag = 0
         self.image_cache = {}
         logger.debug("Exit game_tree")
-
+
     @debugging
     def add_nodehandler(self, nodehandler, nodeclass):
         if not self.nodehandlers.has_key(nodehandler): self.nodehandlers[nodehandler] = nodeclass
         else: logger.debug("Nodehandler for " + nodehandler + " already exists!")
-
+
     @debugging
     def remove_nodehandler(self, nodehandler):
         if self.nodehandlers.has_key(nodehandler):
             del self.nodehandlers[nodehandler]
         else: logger.debug("No nodehandler for " + nodehandler + " exists!")
-
+
     @debugging
     def init_nodehandlers(self):
         self.add_nodehandler('group_handler', containers.group_handler)
@@ -151,7 +158,7 @@
         self.add_nodehandler('min_map', core.min_map)
 
     #   event = wxKeyEvent
-    #   set to be called by wxWindows by EVT_CHAR macro in __init__
+    #   set to be called by wxWindows by EVT_CHAR macro in __init__
     @debugging
     def on_key_up(self, evt):
         key_code = evt.GetKeyCode()
@@ -166,7 +173,7 @@
                 obj.on_drop(evt)
                 self.drag_obj = None
         evt.Skip()
-
+
     @debugging
     def on_char(self, evt):
         key_code = evt.GetKeyCode()
@@ -192,15 +199,17 @@
             self.rename_flag = 1
             self.EditLabel(curSelection)
         evt.Skip()
-   
+   
     @debugging
-    def locate_valid_tree(self, error, msg, dir, filename): ## --Snowdog 3/05
+    def locate_valid_tree(self, error, msg): ## --Snowdog 3/05
         """prompts the user to locate a new tree file or create a new one"""
         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)
+            dlg = wx.FileDialog(self, "Locate Gametree file", dir_struct["user"],
+                                filename[ ((filename.rfind(os.sep))+len(os.sep)):],
+                                "Gametree (*.xml)|*.xml|All files (*.*)|*.*",
+                                wx.OPEN | wx.CHANGE_DIR)
             if dlg.ShowModal() == wx.ID_OK: file = dlg.GetPath()
             dlg.Destroy()
             if not file: self.load_tree(error=1)
@@ -210,100 +219,93 @@
             validate.config_file("tree.xml","default_tree.xml")
             self.load_tree(error=1)
             return
-
+
     @debugging
     def load_tree(self, filename=dir_struct["user"]+'tree.xml', error=0):
         self.settings.set_setting("gametree", filename)
-        tmp = None
-        xml_dom = None
-        xml_doc = None
+        #check file exists
+        if not os.path.exists(filename):
+            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)"
+            self.locate_valid_tree("Gametree Error", emsg)
+            return
+        try:
+            f = open(filename, "rb")
+            tree = parse(f)
+            self.xml_root = tree.getroot()
+        except:
+            f.close()
+            self.xml_root = None
+        ### Alpha  ### Doing some work on Gametree to add Element Tree, slowly at first. 
+        
         try:
             logger.info("Reading Gametree file: " + filename + "...", True)
-            tmp = open(filename,"r")
-            xml_doc = xml.parseXml(tmp.read())
-            tmp.close()
+            xml_doc = xml.parseXml(tostring(self.xml_root))
             if xml_doc == None: pass
             else: xml_dom = xml_doc._get_documentElement()
             logger.info("done.", True)
+        except: pass
 
-        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, dir_struct["user"], fn)
-            logger.general(emsg)
+        if not self.xml_root:
+            os.rename(filename,filename+".corrupt")
+            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 "+filename+ "\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)
             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, dir_struct["user"], fn)
-            logger.general(emsg)
+        if self.xml_root.tag != "gametree":
+            emsg = filename+" 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)
             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, dir_struct["user"], fn)
-            logger.debug(emsg)
-            return
-
-        # get gametree version - we could write conversion code here!
-        self.master_dom = xml_dom
-        logger.debug("Master Dom Set")
-
         try:
-            version = self.master_dom.getAttribute("version")
+            # version = self.xml_root.get("version")
             # see if we should load the gametree
-            loadfeatures = int(self.settings.get_setting("LoadGameTreeFeatures"))
+            loadfeatures = int(settings.get_setting("LoadGameTreeFeatures"))
             if loadfeatures:
-                xml_dom = xml.parseXml(open(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")
+                features_tree = ET.parse(orpg.dirpath.dir_struct["template"]+"feature.xml")
+                self.xml_root.append(features_tree.getroot())
+                settings.set("LoadGameTreeFeatures","0")
 
             ## load tree
             logger.debug("Features loaded (if required)")
             self.CollapseAndReset(self.root)
-            children = self.master_dom._get_childNodes()
-            logger.info("Parsing Gametree Nodes ", True)
-            for c in children:
-                print '.',
-                self.load_xml(c,self.root)
-            logger.info("done", True)
+            logger.note("Parsing Gametree Nodes ", True)
+            for xml_child in self.xml_root:
+                logger.note('.', True)
+                self.load_xml(xml_child,self.root)
+            logger.note("done", True)
+
             self.Expand(self.root)
-            self.SetPyData(self.root,self.master_dom)
+            self.SetPyData(self.root,self.xml_root)
             if error != 1:
-                infile = open(filename, "rb")
-                outfile = open(dir_struct["user"]+"lastgood.xml", "wb")
-                outfile.write(infile.read())
+                with open(filename, "rb") as infile:
+                    with open(dir_struct["user"]+"lastgood.xml", "wb") as outfile:
+                        outfile.write(infile.read())
             else: logger.info("Not overwriting lastgood.xml file.", True)
 
         except Exception, e:
-            logger.general(traceback.format_exc())
+            logger.exception(traceback.format_exc())
             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")
             validate.config_file("tree.xml","default_tree.xml")
             self.load_tree(error=1)
-
+
     @debugging
     def build_std_menu(self, obj=None):
         # 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")
+        useful_menu.Append(STD_MENU_NODE_INDIFFERENT,"&Indifferent")
 
         # build standard menu
         self.std_menu = wx.Menu()
@@ -358,14 +360,14 @@
         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)
-
+
     @debugging
     def do_std_menu(self, evt, obj):
         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)
-
+
     @debugging
     def strip_html(self, player):
         ret_string = ""
@@ -379,20 +381,22 @@
             else: ret_string = ret_string + player[0][x]
         logger.debug(ret_string)
         return ret_string
-
+
     @debugging
     def on_receive_data(self, data, player):
+        if iselement(data):
+            tostring(data)
         beg = string.find(data,"<tree>")
         end = string.rfind(data,"</tree>")
         data = data[6:end]
         self.insert_xml(data)
-
+
     @debugging
     def on_send_to_chat(self, evt):
         item = self.GetSelection()
         obj = self.GetPyData(item)
         obj.on_send_to_chat(evt)
-
+
     @debugging
     def on_whisper_to(self, evt):
         players = self.session.get_players()
@@ -415,7 +419,7 @@
                     for s in selections:
                         player_ids.append(players[s][2])
                     self.chat.whisper_to_players(obj.tohtml(),player_ids)
-
+
     @debugging
     def on_export_html(self, evt):
         f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","HTML (*.html)|*.html",wx.SAVE)
@@ -423,39 +427,38 @@
             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()
+            with open(f.GetPath(),"w") as f:
+                data = "<html><head><title>"+obj.xml.get("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")
+                f.write(data)
             self.last_save_dir, throwaway = os.path.split( f.GetPath() )
         f.Destroy()
         os.chdir(dir_struct["home"])
-
+
     @debugging
     def indifferent(self, evt):
         item = self.GetSelection()
         obj = self.GetPyData(item)
         obj.usefulness("indifferent")
-
+
     @debugging
     def useful(self, evt):
         item = self.GetSelection()
         obj = self.GetPyData(item)
         obj.usefulness("useful")
-
+
     @debugging
     def useless(self, evt):
         item = self.GetSelection()
         obj = self.GetPyData(item)
         obj.usefulness("useless")
-
+
     @debugging
     def on_email(self,evt):
         pass
-
+
     @debugging
     def on_send_to(self, evt):
         players = self.session.get_players()
@@ -471,13 +474,13 @@
             if dlg.ShowModal() == wx.ID_OK:
                 item = self.GetSelection()
                 obj = self.GetPyData(item)
-                xmldata = "<tree>" + xml.toxml(obj) + "</tree>"
+                xmldata = "<tree>" + tostring(obj.xml) + "</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()
-
+
     @debugging
     def on_icon(self, evt):
         icons = self.icons.keys()
@@ -489,7 +492,7 @@
             obj = self.GetPyData(item)
             obj.change_icon(key)
         dlg.Destroy()
-
+
     @debugging
     def on_wizard(self, evt):
         item = self.GetSelection()
@@ -501,7 +504,7 @@
         xml_data += "</nodehandler>"
         self.insert_xml(xml_data)
         logger.debug(xml_data)
-
+
     @debugging
     def on_clone(self, evt):
         item = self.GetSelection()
@@ -510,12 +513,15 @@
             parent_node = self.GetItemParent(item)
             prev_sib = self.GetPrevSibling(item)
             if not prev_sib.IsOk(): prev_sib = parent_node
-            xml_dom = xml.parseXml(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)
-
+            clone_xml = XML(tostring(obj.xml))
+            if parent_node == self.root: parent_xml = self.GetPyData(parent_node)
+            else: parent_xml = self.GetPyData(parent_node).xml
+            for i in range(len(parent_xml)):
+                if parent_xml[i] is obj.xml:
+                    parent_xml.insert(i, clone_xml)
+                    break
+            self.load_xml(clone_xml, parent_node, prev_sib)
+
     @debugging
     def on_save(self, evt):
         """save node to a xml file"""
@@ -523,7 +529,7 @@
         obj = self.GetPyData(item)
         obj.on_save(evt)
         os.chdir(dir_struct["home"])
-
+
     @debugging
     def on_save_tree_as(self, evt):
         f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","*.xml",wx.SAVE)
@@ -532,20 +538,18 @@
             self.last_save_dir, throwaway = os.path.split( f.GetPath() )
         f.Destroy()
         os.chdir(dir_struct["home"])
-
+
     @debugging
     def on_save_tree(self, evt=None):
         filename = self.settings.get_setting("gametree")
         self.save_tree(filename)
-
+
     @debugging
     def save_tree(self, filename=dir_struct["user"]+'tree.xml'):
-        self.master_dom.setAttribute("version",GAMETREE_VERSION)
-        self.settings.set_setting("gametree",filename)
-        file = open(filename,"w")
-        file.write(xml.toxml(self.master_dom,1))
-        file.close()
-
+        self.xml_root.set("version",GAMETREE_VERSION)
+        settings.set_setting("gametree",filename)
+        ElementTree(self.xml_root).write(filename)
+
     @debugging
     def on_load_new_tree(self, evt):
         f = wx.FileDialog(self,"Select a file", self.last_save_dir,"","*.xml",wx.OPEN)
@@ -554,7 +558,7 @@
             self.last_save_dir, throwaway = os.path.split( f.GetPath() )
         f.Destroy()
         os.chdir(dir_struct["home"])
-
+
     @debugging
     def on_insert_file(self, evt):
         """loads xml file into the tree"""
@@ -566,7 +570,7 @@
             self.last_save_dir, throwaway = os.path.split( f.GetPath() )
         f.Destroy()
         os.chdir(dir_struct["home"])
-
+
     @debugging
     def on_insert_url(self, evt):
         """loads xml url into the tree"""
@@ -576,68 +580,68 @@
             file = urllib.urlopen(path)
             self.insert_xml(file.read())
         dlg.Destroy()
-
+
     @debugging
     def on_insert_features(self, evt):
         self.insert_xml(open(dir_struct["template"]+"feature.xml","r").read())
-
+
     @debugging
     def on_tree_prop(self, evt):
         dlg = gametree_prop_dlg(self, self.settings)
         if dlg.ShowModal() == wx.ID_OK: pass
         dlg.Destroy()
-
+
     @debugging
     def on_node_design(self, evt):
         item = self.GetSelection()
         obj = self.GetPyData(item)
         obj.on_design(evt)
-
+
     @debugging
     def on_node_use(self, evt):
         item = self.GetSelection()
         obj = self.GetPyData(item)
         obj.on_use(evt)
-
+
     @debugging
     def on_node_pp(self, evt):
         item = self.GetSelection()
         obj = self.GetPyData(item)
         obj.on_html_view(evt)
-
+
     @debugging
     def on_del(self, evt):
         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":
+                handler = self.GetPyData(item)
+                status_value = handler.xml.get('status')
+                name = handler.xml.get('name')
+                parent_item = self.GetItemParent(item)
+                while parent_item.IsOk() and 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
+                        parent_handler = self.GetPyData(parent_item)
+                        status_value = parent_handler.get('status')
+                        name = parent_handler.get('name')
+                        if status_value == "useless":
+                            break
+                        elif status_value == "useful":
+                            break
+                    except:
+                        status_value = "none"
+                    parent_item = self.GetItemParent(parent_item)
                 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()
+                    if dlg.ShowModal() == wx.ID_YES: handler.delete()
+                else: handler.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()
-
+
     @debugging
     def on_about(self, evt):
         item = self.GetSelection()
@@ -645,92 +649,74 @@
         about = MyAboutBox(self,obj.about())
         about.ShowModal()
         about.Destroy()
-
+
     @debugging
     def on_send_to_map(self, evt):
         item = self.GetSelection()
         obj = self.GetPyData(item)
         if hasattr(obj,"on_send_to_map"): obj.on_send_to_map(evt)
-
+
     @debugging
     def insert_xml(self, txt):
         #Updated to allow safe merging of gametree files
         #without leaving an unusable and undeletable node.
         #                               -- Snowdog 8/03
-        xml_dom = xml.parseXml(txt)
-        if xml_dom == None:
+        if not txt:
             wx.MessageBox("Import Failed: Invalid or missing node data")
-            logger.debug("Import Failed: Invalid or missing node data")
-            logger.debug("Exit game_tree->insert_xml(self, txt)")
-            return
-        xml_temp = xml_dom._get_documentElement()
-
-        if not xml_temp:
-            wx.MessageBox("Error Importing Node or Tree")
-            logger.debug("Error Importing Node or Tree")
-            logger.debug("Exit game_tree->insert_xml(self, txt)")
-            return
-
-        if xml_temp._get_tagName() == "gametree":
-            children = xml_temp._get_childNodes()
-            for c in children: self.load_xml(c, self.root)
-            logger.debug("Exit game_tree->insert_xml(self, txt)")
+            logger.general("Import Failed: Invalid or missing node data")
             return
 
-        if not xml_dom:
-            wx.MessageBox("XML Error")
-            logger.debug("XML Error")
-            logger.debug("Exit game_tree->insert_xml(self, txt)")
+        try:
+            new_xml = XML(txt)
+        except ExpatError:
+            wx.MessageBox("Error Importing Node or Tree")
+            logger.general("Error Importing Node or Tree")
             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)
-
+        if new_xml.tag == "gametree":
+            for xml_child in new_xml:
+                self.load_xml(xml_child, self.root)
+            return
+
+        self.xml_root.append(new_xml)
+        self.load_xml(new_xml,self.root,self.root)
+
     @debugging
     def build_img_list(self):
         """make image list"""
         helper = img_helper()
         self.icons = { }
         self._imageList= wx.ImageList(16,16,False)
-        man = open(dir_struct["icon"]+"icons.xml","r")
-        xml_dom = 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 = dir_struct["icon"] + n.getAttribute("file")
+        icons_xml = parse(orpg.dirpath.dir_struct["icon"]+"icons.xml")
+        for icon in icons_xml.getroot():
+            key = icon.get("name")
+            path = orpg.dirpath.dir_struct["icon"] + icon.get("file")
             img = helper.load_file(path)
             self.icons[key] = self._imageList.Add(img)
         self.SetImageList(self._imageList)
-
+
     @debugging
-    def load_xml(self, xml_dom, parent_node, prev_node=None):
+    def load_xml(self, xml_element, parent_node, prev_node=None):
         #add the first tree node
         i = 0
-        text = xml_dom.getAttribute("name")
-        icon = xml_dom.getAttribute("icon")
+        name = xml_element.get("name")
+        icon = xml_element.get("icon")
         if self.icons.has_key(icon): i = self.icons[icon]
-        name = xml_dom._get_nodeName()
-        logger.debug("Text, icon and name set\n" + text + "\n" + icon + "\n" + name)
+
         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)
+            if prev_node == parent_node: new_tree_node = self.PrependItem(parent_node, name, i, i)
+            else: new_tree_node = self.InsertItem(parent_node,prev_node, name, i, i)
+        else: new_tree_node = self.AppendItem(parent_node, name, i, i)
 
         logger.debug("Node Added to tree")
         #create a nodehandler or continue loading xml into tree
-        if name == "nodehandler":
-            #wx.BeginBusyCursor()
-            logger.debug("We have a Nodehandler")
+        if xml_element.tag == "nodehandler":
             try:
-                py_class = xml_dom.getAttribute("class")
+                py_class = xml_element.get("class")
                 logger.debug("nodehandler class: " + py_class)
                 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)
+                    raise Exception("Unknown Nodehandler for " + py_class)
+                self.nodes[self.id] = self.nodehandlers[py_class](xml_element, new_tree_node)
                 self.SetPyData(new_tree_node, self.nodes[self.id])
                 logger.debug("Node Data set")
                 bmp = self.nodes[self.id].get_scaled_bitmap(16,16)
@@ -738,13 +724,15 @@
                 logger.debug("Node Icon loaded")
                 self.id = self.id + 1
             except Exception, er:
-                logger.general(traceback.format_exc())
- 		        #logger.debug("Error Info: " + xml_dom.getAttribute("class") + "\n" + str(er), True)?indent?
-                self.Delete(new_tree_node)
-                parent = xml_dom._get_parentNode()
-                parent.removeChild(xml_dom)
+                logger.exception(traceback.format_exc())
+
+                # was deleted -- should we delete non-nodehandler nodes then?
+                #self.Delete(new_tree_node)
+                #parent = xml_dom._get_parentNode()
+                #parent.removeChild(xml_dom)
+
         return new_tree_node
-
+
     @debugging
     def cached_load_of_image(self, bmp_in, new_tree_node):
         image_list = self.GetImageList()
@@ -762,7 +750,7 @@
         self.SetItemImage(new_tree_node,image_index)
         self.SetItemImage(new_tree_node,image_index, wx.TreeItemIcon_Selected)
         return image_index
-
+
     @debugging
     def on_rclick(self, evt):
         pt = evt.GetPosition()
@@ -773,7 +761,7 @@
             if(isinstance(obj,core.node_handler)): obj.on_rclick(evt)
             else: self.PopupMenu(self.top_menu)
         else: self.PopupMenu(self.top_menu,pt)
-
+
     @debugging
     def on_ldclick(self, evt):
         self.rename_flag = 0
@@ -789,7 +777,7 @@
                     elif action == "design": obj.on_design(evt)
                     elif action == "print": obj.on_html_view(evt)
                     elif action == "chat": self.on_send_to_chat(evt)
-
+
     @debugging
     def on_left_down(self, evt):
         pt = evt.GetPosition()
@@ -803,7 +791,7 @@
             self.rename_flag = 1
         else: self.SelectItem(item)
         evt.Skip()
-
+
     @debugging
     def on_left_up(self, evt):
         if self.dragging:
@@ -818,7 +806,15 @@
                 if(isinstance(obj,core.node_handler)):
                     obj.on_drop(evt)
                     self.drag_obj = None
-
+
+    def traverse(self, root, function, data=None, recurse=True):
+        child, cookie = self.GetFirstChild(root)
+        while child.IsOk():
+            function(child, data)
+            if recurse:
+                self.traverse(child, function, data)
+            child, cookie = self.GetNextChild(root, cookie)
+
     @debugging
     def on_label_change(self, evt):
         item = evt.GetItem()
@@ -829,7 +825,7 @@
             obj = self.GetPyData(item)
             obj.master_dom.setAttribute('name',txt)
         else: evt.Veto()
-
+
     @debugging
     def on_label_begin(self, evt):
         if not self.rename_flag: evt.Veto()
@@ -838,7 +834,7 @@
             item = evt.GetItem()
             if item == self.GetRootItem():
                 evt.Veto()
-
+
     @debugging
     def on_drag(self, evt):
         self.rename_flag = 0
@@ -850,7 +846,7 @@
             cur = wx.StockCursor(wx.CURSOR_HAND)
             self.SetCursor(cur)
             self.drag_obj = obj
-
+
     @debugging
     def is_parent_node(self, node, compare_node):
         parent_node = self.GetItemParent(node)
@@ -870,12 +866,12 @@
 CTRL_CHAT = wx.NewId()
 CTRL_PRINT = wx.NewId()
 
-class gametree_prop_dlg(wx.Dialog):
+class gametree_prop_dlg(wx.Dialog):
     @debugging
     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)
@@ -929,7 +925,7 @@
         self.SetAutoLayout(True)
         self.Fit()
         self.Bind(wx.EVT_BUTTON, self.on_ok, id=wx.ID_OK)
-
+
     @debugging
     def on_ok(self,evt):
         self.settings.set_setting("gametree",self.ctrls[CTRL_TREE_FILE].GetValue())
--- a/orpg/gametree/nodehandlers/containers.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/gametree/nodehandlers/containers.py	Wed Oct 28 14:24:54 2009 -0500
@@ -39,32 +39,30 @@
     """ should not be used! only a base class!
     <nodehandler name='?'  module='core' class='container_handler'  />
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self, xml, tree_node):
+        node_handler.__init__(self, xml, tree_node)
         self.load_children()
 
     def load_children(self):
-        children = self.master_dom._get_childNodes()
-        for c in children:
-            self.tree.load_xml(c,self.mytree_node)
+        for child_xml in self.xml:
+            self.tree.load_xml(child_xml,self.mytree_node)
 
-    def check_map_aware(self, obj, evt):
-        if hasattr(obj,"map_aware") and obj.map_aware():
-            obj.on_send_to_map(evt)
-
+    def check_map_aware(self, treenode, evt):
+        node = self.tree.GetPyData(treenode)
+        if hasattr(node,"map_aware") and node.map_aware():
+            node.on_send_to_map(evt)
 
     def on_send_to_map(self, evt):
-        self.traverse(self.mytree_node, self.check_map_aware, evt) 
-
+        self.tree.traverse(self.mytree_node, self.check_map_aware, evt) 
 
-    def checkChildToMap(self, obj, evt):
-        if hasattr(obj,"map_aware") and obj.map_aware():
+    def checkChildToMap(self, treenode, evt):
+        node = self.tree.GetPyData(treenode)
+        if hasattr(node,"map_aware") and node.map_aware():
             self.mapcheck = True
 
     def checkToMapMenu(self):
         self.mapcheck = False
-        self.traverse(self.mytree_node, self.checkChildToMap)
-
+        self.tree.traverse(self.mytree_node, self.checkChildToMap)
         return self.mapcheck
 
     def on_drop(self,evt):
@@ -73,23 +71,24 @@
             return
         opt = wx.MessageBox("Add node as child?","Container Node",wx.YES_NO|wx.CANCEL)
         if opt == wx.YES:
-            xml_dom = self.tree.drag_obj.delete()
-            xml_dom = self.master_dom.insertBefore(xml_dom,None)
-            self.tree.load_xml(xml_dom, self.mytree_node)
+            drop_xml = self.tree.drag_obj.delete()
+            self.xml.insert(0, drop_xml)
+            self.tree.load_xml(drop_xml, self.mytree_node)
             self.tree.Expand(self.mytree_node)
         elif opt == wx.NO:
             node_handler.on_drop(self,evt)
 
-    def gen_html(self, obj, evt):
-        self.html_str += "<p>" + obj.tohtml()
-
+    def gen_html(self, treenode, evt):
+        node = self.tree.GetPyData(treenode)
+        self.html_str += "<p>" + node.tohtml()
+        
     def tohtml(self):
         self.html_str = "<table border=\"1\" ><tr><td>"
-        self.html_str += "<b>"+self.master_dom.getAttribute("name") + "</b>"
+        self.html_str += "<b>"+self.xml.get("name") + "</b>"
         self.html_str += "</td></tr>\n"
         self.html_str += "<tr><td>"
 
-        self.traverse(self.mytree_node, self.gen_html, recurse=False)
+        self.tree.traverse(self.mytree_node, self.gen_html, recurse=False)
 
         self.html_str += "</td></tr></table>"
         return self.html_str
@@ -106,22 +105,21 @@
         This handler will continue parsing child xml data.
         <nodehandler name='?'  module='core' class='group_handler'  />
     """
-    def __init__(self,xml_dom,tree_node):
-        container_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self, xml, tree_node):
+        container_handler.__init__(self, xml, tree_node)
 
     def load_children(self):
         self.atts = None
-        children = self.master_dom._get_childNodes()
-        for c in children:
-            if c._get_tagName() == "group_atts":
-                self.atts = c
+        for child_xml in self.xml:
+            if child_xml.tag == "group_atts":
+                self.atts = child_xml
             else:
-                self.tree.load_xml(c,self.mytree_node)
+                self.tree.load_xml(child_xml,self.mytree_node)
         if not self.atts:
-            elem = self.xml.minidom.Element('group_atts')
-            elem.setAttribute("cols","1")
-            elem.setAttribute("border","1")
-            self.atts = self.master_dom.appendChild(elem)
+            self.atts = Element('group_atts')
+            self.atts.set("cols","1")
+            self.atts.set("border","1")
+            self.xml.append(self.atts)
 
     def get_design_panel(self,parent):
         return group_edit_panel(parent,self)
@@ -129,27 +127,25 @@
     def on_use(self,evt):
         return
 
-    def gen_html(self, obj, evt):
+    def gen_html(self, treenode, evt):
+        node = self.tree.GetPyData(treenode)
         if self.i  not in self.tdatas:
             self.tdatas[self.i] = ''
-        self.tdatas[self.i] += "<P>" + obj.tohtml()
+        self.tdatas[self.i] += "<P>" + node.tohtml()
         self.i += 1
         if self.i >= self.cols:
             self.i = 0
 
     def tohtml(self):
-        cols = self.atts.getAttribute("cols")
-        border = self.atts.getAttribute("border")
+        cols = self.atts.get("cols")
+        border = self.atts.get("border")
         self.html_str = "<table border=\""+border+"\" ><tr><td colspan=\""+cols+"\">"
-        self.html_str += "<font size=4>"+self.master_dom.getAttribute("name") + "</font>"
+        self.html_str += "<font size=4>"+self.xml.get("name") + "</font>"
         self.html_str += "</td></tr>\n<tr>"
-
         self.cols = int(cols)
         self.i = 0
         self.tdatas = {}
-
-        self.traverse(self.mytree_node, self.gen_html, recurse=False)
-
+        self.tree.traverse(self.mytree_node, self.gen_html, recurse=False)
         for td in self.tdatas:
             self.html_str += "<td valign=\"top\" >" + self.tdatas[td] + "</td>\n";
         self.html_str += "</tr></table>"
@@ -163,19 +159,19 @@
         wx.Panel.__init__(self, parent, -1)
         self.handler = handler
         sizer = wx.BoxSizer(wx.VERTICAL)
-        self.text = {   P_TITLE : wx.TextCtrl(self, P_TITLE, handler.master_dom.getAttribute('name'))
+        self.text = {   P_TITLE : wx.TextCtrl(self, P_TITLE, handler.xml.get('name'))
                       }
         sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND)
         sizer.Add(self.text[P_TITLE], 0, wx.EXPAND)
         sizer.Add(wx.Size(10,10))
 
         radio_c = wx.RadioBox(self, GROUP_COLS, "Columns", choices=["1","2","3","4"])
-        cols = handler.atts.getAttribute("cols")
+        cols = handler.atts.get("cols")
         if cols != "":
             radio_c.SetSelection(int(cols)-1)
 
         radio_b = wx.RadioBox(self, GROUP_BOR, "Border", choices=["no","yes"])
-        border = handler.atts.getAttribute("border")
+        border = handler.atts.get("border")
         if border != "":
             radio_b.SetSelection(int(border))
 
@@ -197,16 +193,16 @@
         id = evt.GetId()
         index = evt.GetInt()
         if id == GROUP_COLS:
-            self.handler.atts.setAttribute("cols",str(index+1))
+            self.handler.atts.set("cols",str(index+1))
         elif id == GROUP_BOR:
-            self.handler.atts.setAttribute("border",str(index))
+            self.handler.atts.set("border",str(index))
 
     def on_text(self,evt):
         id = evt.GetId()
         if id == P_TITLE:
             txt = self.text[id].GetValue()
             if txt != "":
-                self.handler.master_dom.setAttribute('name',txt)
+                self.handler.xml.set('name',txt)
                 self.handler.rename(txt)
 
 
@@ -217,8 +213,8 @@
 class tabber_handler(container_handler):
     """ <nodehandler name='?'  module='containers' class='tabber_handler'  />"""
 
-    def __init__(self,xml_dom,tree_node):
-        container_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self, xml, tree_node):
+        container_handler.__init__(self, xml, tree_node)
 
     def get_design_panel(self,parent):
         return tabbed_panel(parent,self,1)
@@ -232,20 +228,16 @@
         orpgTabberWnd.__init__(self, parent, style=FNB.FNB_NO_X_BUTTON)
         self.handler = handler
         self.parent = parent
-        handler.traverse(handler.mytree_node, self.pick_panel, mode, False)
+        handler.tree.traverse(handler.mytree_node, self.pick_panel, mode, False)
 
         parent.SetSize(self.GetBestSize())
 
-    def pick_panel(self, obj, mode):
-        if mode == 1:
-            panel = obj.get_design_panel(self)
-        else:
-            panel = obj.get_use_panel(self)
-
-        name = obj.master_dom.getAttribute("name");print 'here '+name
-
-        if panel:
-            self.AddPage(panel, name, False)
+    def pick_panel(self, treenode, mode):
+        node = self.handler.tree.GetPyData(treenode)
+        if mode == 1: panel = node.get_design_panel(self)
+        else: panel = node.get_use_panel(self)
+        name = node.xml.get("name")
+        if panel: self.AddPage(panel, name, False)
 
 #################################
 ## Splitter container
@@ -254,21 +246,18 @@
 class splitter_handler(container_handler):
     """ <nodehandler name='?'  module='containers' class='splitter_handler'  />"""
 
-    def __init__(self,xml_dom,tree_node):
-        container_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self,xml,tree_node):
+        container_handler.__init__(self,xml,tree_node)
 
     def load_children(self):
         self.atts = None
-        children = self.master_dom._get_childNodes()
-        for c in children:
-            if c._get_tagName() == "splitter_atts":
-                self.atts = c
-            else:
-                self.tree.load_xml(c,self.mytree_node)
+        for child_xml in self.xml:
+            if child_xml.tag == "splitter_atts": self.atts = child_xml
+            else: self.tree.load_xml(child_xml,self.mytree_node)
         if not self.atts:
-            elem = self.xml.minidom.Element('splitter_atts')
-            elem.setAttribute("horizontal","0")
-            self.atts = self.master_dom.appendChild(elem)
+            self.atts = Element('splitter_atts')
+            self.atts.set("horizontal","0")
+            self.xml.append(self.atts)
 
     def get_design_panel(self,parent):
         return self.build_splitter_wnd(parent, 1)
@@ -281,7 +270,7 @@
         container_handler.on_drop(self,evt)
 
     def build_splitter_wnd(self, parent, mode):
-        self.split = self.atts.getAttribute("horizontal")
+        self.split = self.atts.get("horizontal")
 
         self.pane = splitter_panel(parent, self)
 
@@ -295,7 +284,7 @@
         self.bestSizex = -1
         self.bestSizey = -1
 
-        self.traverse(self.mytree_node, self.doSplit, mode, False) 
+        self.tree.traverse(self.mytree_node, self.doSplit, mode, False) 
 
         self.pane.sizer.Add(self.splitter, 1, wx.EXPAND)
 
@@ -308,11 +297,10 @@
         parent.SetSize(self.pane.GetSize())
         return self.pane
 
-    def doSplit(self, obj, mode):
-        if mode == 1:
-            tmp = obj.get_design_panel(self.splitter)
-        else:
-            tmp = obj.get_use_panel(self.splitter)
+    def doSplit(self, treenode, mode):
+        node = self.tree.GetPyData(treenode)
+        if mode == 1: tmp = node.get_design_panel(self.splitter)
+        else: tmp = node.get_use_panel(self.splitter)
 
         if self.split == '1':
             sash = tmp.GetBestSize()[1]+1
@@ -337,7 +325,7 @@
         sizer = wx.BoxSizer(wx.VERTICAL)
 
         self.hozCheck = wx.CheckBox(self, -1, "Horizontal Split")
-        hoz = self.handler.atts.getAttribute("horizontal")
+        hoz = self.handler.atts.get("horizontal")
 
         if hoz == '1':
             self.hozCheck.SetValue(True)
@@ -359,6 +347,6 @@
     def on_check_box(self,evt):
         state = self.hozCheck.GetValue()
         if state:
-            self.handler.atts.setAttribute("horizontal", "1")
+            self.handler.atts.set("horizontal", "1")
         else:
-            self.handler.atts.setAttribute("horizontal", "0")
+            self.handler.atts.set("horizontal", "0")
--- a/orpg/gametree/nodehandlers/core.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/gametree/nodehandlers/core.py	Wed Oct 28 14:24:54 2009 -0500
@@ -29,6 +29,7 @@
 __version__ = "$Id: core.py,v 1.49 2007/12/07 20:39:48 digitalxero Exp $"
 
 from nodehandler_version import NODEHANDLER_VERSION
+
 try:
     from orpg.orpg_windows import *
     from orpg.dirpath import dir_struct
@@ -40,6 +41,7 @@
 except:
     import wx
 
+from xml.etree.ElementTree import ElementTree, Element, tostring, XML
 
 #html defaults
 TH_BG = "#E9E9E9"
@@ -48,22 +50,33 @@
 ##########################
 class node_handler:
     """ Base nodehandler with virtual functions and standard implmentations """
-    def __init__(self,xml_dom,tree_node):
-        self.master_dom = xml_dom
+    def __init__(self,xml,tree_node):
+        self.xml = xml
         self.mytree_node = tree_node
-        self.tree = component.get('tree')
-        self.frame = component.get('frame')
-        self.chat = component.get('chat')
-        self.xml = component.get('xml') #Not used?
+        self.tree = open_rpg.get_component('tree')
+        self.frame = open_rpg.get_component('frame')
+        self.chat = open_rpg.get_component('chat')
         self.drag = True
         self.myeditor = None # designing
-        self.myviewer = None # pretty print
+        self.myviewer = None # prett print
         self.mywindow = None # using
         # call version hook
-        self.on_version(self.master_dom.getAttribute("version"))
+        self.on_version(self.xml.get("version"))
         # set to current version
-        self.master_dom.setAttribute("version",NODEHANDLER_VERSION)
+        self.xml.set("version",NODEHANDLER_VERSION)
         # null events
+        self.frame_size = None
+        self.frame_pos  = None
+        try:
+            frame = self.xml.get("frame")
+            if len(frame):
+                (sx,sy,px,py) = [int(value) for value in frame.split(',')]
+                self.frame_size = (sx, sy)
+                (maxx, maxy) = DisplaySize()
+                if px < maxx-80 and py < maxy-50:#if it's off screen ignore the saved pos
+                    self.frame_pos  = (px, py) 
+        except:
+            pass
 
     def on_version(self,old_version):
         ## added version control code here or implement a new on_version in your derived class.
@@ -76,22 +89,13 @@
     def on_ldclick(self,evt):
         return 0
 
-    def traverse(self, root, function, data=None, recurse=True):
-        child, cookie = self.tree.GetFirstChild(root)
-        while child.IsOk(): 
-            function(self.tree.GetPyData(child), data) 
-            if recurse: 
-                self.traverse(child, function, data) 
-            child, cookie = self.tree.GetNextChild(root, cookie) 
-
-
     def usefulness(self,text):
         if text=="useful":
-            self.master_dom.setAttribute('status',"useful")
+            self.xml.set('status',"useful")
         elif text=="useless":
-            self.master_dom.setAttribute('status',"useless")
+            self.xml.set('status',"useless")
         elif text=="indifferent":
-            self.master_dom.setAttribute('status',"indifferent")
+            self.xml.set('status',"indifferent")
 
     def on_design(self,evt):
         try:
@@ -102,16 +106,17 @@
             if self.create_designframe():
                 self.myeditor.Show()
                 self.myeditor.Raise()
-            else: return
+            else:
+                return
         wx.CallAfter(self.myeditor.Layout)
 
 
     def create_designframe(self):
-        title = self.master_dom.getAttribute('name') + " Editor"
+        title = self.xml.get('name') + " Editor"
         self.myeditor = wx.Frame(None, -1, title)
         self.myeditor.Freeze()
         if wx.Platform == '__WXMSW__':
-            icon = wx.Icon(dir_struct["icon"] + 'grid.ico', wx.BITMAP_TYPE_ICO)
+            icon = wx.Icon(orpg.dirpath.dir_struct["icon"] + 'grid.ico', wx.BITMAP_TYPE_ICO)
             self.myeditor.SetIcon(icon)
             del icon
 
@@ -144,19 +149,23 @@
         except:
             del self.mywindow
             if self.create_useframe():
+                self.mywindow.SetSize(self.frame_size)
+                if self.frame_pos:
+                    self.mywindow.SetPosition(self.frame_pos)
                 self.mywindow.Show()
                 self.mywindow.Raise()
             else:
                 return
         wx.CallAfter(self.mywindow.Layout)
 
+
     def create_useframe(self):
-        caption = self.master_dom.getAttribute('name')
+        caption = self.xml.get('name', '')
         self.mywindow = wx.Frame(None, -1, caption)
         self.mywindow.Freeze()
 
         if wx.Platform == '__WXMSW__':
-            icon = wx.Icon(dir_struct["icon"] + 'note.ico', wx.BITMAP_TYPE_ICO)
+            icon = wx.Icon(orpg.dirpath.dir_struct["icon"] + 'note.ico', wx.BITMAP_TYPE_ICO)
             self.mywindow.SetIcon(icon)
             del icon
         self.mywindow.panel = self.get_use_panel(self.mywindow)
@@ -169,27 +178,36 @@
         self.mywindow.SetSizer(sizer)
         self.mywindow.SetAutoLayout(True)
 
-        (x, y) = self.mywindow.GetSize()
-        if x < 400:
-            x = 400
-        if y < 400:
-            y = 400
+        if self.frame_size is None:
+            self.frame_size = self.mywindow.GetSize()
+            if self.frame_size.x < 400:
+                self.frame_size.x = 400
+            if self.frame_size.y < 400:
+                self.frame_size.y = 400
 
-        self.mywindow.SetSize((x, y))
         self.mywindow.Layout()
         self.mywindow.Thaw()
 
+        self.mywindow.Bind(wx.EVT_CLOSE, self.close_useframe)
+
         return True
 
+    def close_useframe(self, evt):
+        self.frame_size = self.mywindow.GetSize()
+        self.frame_pos  = self.mywindow.GetPosition()
+        frame_values = str(self.frame_size.x)+','+str(self.frame_size.y)+','+str(self.frame_pos.x)+','+str(self.frame_pos.y)
+        self.xml.set("frame", frame_values)
+        self.mywindow.Destroy()
+
 
     def on_html_view(self,evt):
         try:
             self.myviewer.Raise()
         except:
-            caption = self.master_dom.getAttribute('name')
+            caption = self.xml.get('name')
             self.myviewer = wx.Frame(None, -1, caption)
             if wx.Platform == '__WXMSW__':
-                icon = wx.Icon(dir_struct["icon"] + 'grid.ico', wx.BITMAP_TYPE_ICO)
+                icon = wx.Icon(orpg.dirpath.dir_struct["icon"] + 'grid.ico', wx.BITMAP_TYPE_ICO)
                 self.myviewer.SetIcon(icon)
                 del icon
             self.myviewer.panel = self.get_html_panel(self.myviewer)
@@ -204,7 +222,7 @@
     def on_del(self,evt):
         print "on del"
 
-    def on_new_data(self,xml_dom):
+    def on_new_data(self,xml):
         pass
 
     def get_scaled_bitmap(self,x,y):
@@ -222,47 +240,53 @@
             return
         #if self.is_my_child(self.mytree_node,drag_obj.mytree_node):
         #    return
-        xml_dom = self.tree.drag_obj.delete()
-        parent = self.master_dom._get_parentNode()
-        xml_dom = parent.insertBefore(xml_dom,self.master_dom)
+        drop_xml = self.tree.drag_obj.delete()
         parent_node = self.tree.GetItemParent(self.mytree_node)
         prev_sib = self.tree.GetPrevSibling(self.mytree_node)
+        if parent_node == self.tree.root:
+            parent_xml = self.tree.GetPyData(parent_node)
+        else:
+            parent_xml = self.tree.GetPyData(parent_node).xml
+        for i in range(len(parent_xml)):
+            if parent_xml[i] is self.xml:
+                parent_xml.insert(i, drop_xml)
+                break
         if not prev_sib.IsOk():
             prev_sib = parent_node
-        self.tree.load_xml(xml_dom, parent_node, prev_sib)
+        self.tree.load_xml(drop_xml, parent_node, prev_sib)
 
     def toxml(self,pretty=0):
-        return component.get('xml').toxml(self.master_dom,pretty)
+        return tostring(self.xml) #toxml(self.master_dom,pretty)
 
     def tohtml(self):
-        return self.master_dom.getAttribute("name")
+        return self.xml.get("name")
 
     def delete(self):
         """ removes the tree_node and xml_node, and returns the removed xml_node """
-
+        parent_node = self.tree.GetItemParent(self.mytree_node)
+        if parent_node == self.tree.root:
+            parent_xml = self.tree.GetPyData(parent_node)
+        else:
+            parent_xml = self.tree.GetPyData(parent_node).xml
+        parent_xml.remove(self.xml)
         self.tree.Delete(self.mytree_node)
-        parent = self.master_dom._get_parentNode()
-        return parent.removeChild(self.master_dom)
+        return self.xml
 
     def rename(self,name):
         if len(name):
             self.tree.SetItemText(self.mytree_node,name)
-            self.master_dom.setAttribute('name', name)
+            self.xml.set('name', name)
 
     def change_icon(self,icon):
-        self.master_dom.setAttribute("icon",icon)
+        self.xml.set("icon",icon)
         self.tree.SetItemImage(self.mytree_node, self.tree.icons[icon])
         self.tree.SetItemImage(self.mytree_node, self.tree.icons[icon], wx.TreeItemIcon_Selected)
         self.tree.Refresh()
 
     def on_save(self,evt):
-        f = wx.FileDialog(self.tree,"Select a file", dir_struct["user"],"","XML files (*.xml)|*.xml",wx.SAVE)
+        f = wx.FileDialog(self.tree,"Select a file", orpg.dirpath.dir_struct["user"],"","XML files (*.xml)|*.xml",wx.SAVE)
         if f.ShowModal() == wx.ID_OK:
-            type = f.GetFilterIndex()
-            if f.GetPath()[:len(f.GetPath())-4] != '.xml': file = open(f.GetPath()+'.xml',"w")
-            else: file = open(f.GetPath(),"w")
-            file.write(self.toxml(1))
-            file.close()
+            ElementTree(self.xml).write(f.GetPath())
         f.Destroy()
 
     def get_design_panel(self,parent):
@@ -275,17 +299,44 @@
         html_str = "<html><body bgcolor=\"#FFFFFF\" >"+self.tohtml()+"</body></html>"
         wnd = wx.html.HtmlWindow(parent,-1)
         html_str = self.chat.ParseDice(html_str)
-	wnd.SetPage(html_str)
+        wnd.SetPage(html_str)
         return wnd
 
     def get_size_constraint(self):
         return 0
 
     def about(self):
-        html_str = "<b>"+ self.master_dom.getAttribute('class')
+        html_str = "<b>"+ self.xml.get('class')
         html_str += " Applet</b><br />by Chris Davis<br />chris@rpgarchive.com"
         return html_str
 
+    def set_referenceable(self, value):
+        if value:
+            self.xml.set('referenceable', '1')
+        else:
+            self.xml.set('referenceable', '0')
+
+    def get_referenceable(self):
+        if 'referenceable' in self.xml.attrib and self.xml.get('referenceable')=="0":
+            return False
+        return True
+
+    def set_namespace(self, value):
+        if value:
+            self.xml.set('namespace', '1')
+        else:
+            self.xml.set('namespace', '0')
+
+    def get_namespace(self):
+        if 'namespace' in self.xml.attrib and self.xml.get('namespace')=="1":
+            return True
+        return False
+
+    def get_value(self):
+        return None
+        
+
+
 P_TITLE = 10
 P_BODY = 20
 class text_edit_panel(wx.Panel):
@@ -293,10 +344,10 @@
         wx.Panel.__init__(self, parent, -1)
         self.handler = handler
         sizer = wx.BoxSizer(wx.VERTICAL)
-        self.text = {   P_TITLE : wx.TextCtrl(self, P_TITLE, handler.master_dom.getAttribute('name')),
-                        P_BODY : html_text_edit(self,P_BODY,handler.text._get_nodeValue(),self.on_text)
+        self.text = {   P_TITLE : wx.TextCtrl(self, P_TITLE, handler.xml.get('name')),
+                        P_BODY : html_text_edit(self,P_BODY,handler.text,self.on_text)
                       }
-        #P_BODY : wx.TextCtrl(self, P_BODY,handler.text._get_nodeValue(), style=wx.TE_MULTILINE)
+        #P_BODY : wx.TextCtrl(self, P_BODY,handler.text, style=wx.TE_MULTILINE)
 
         sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND)
         sizer.Add(self.text[P_TITLE], 0, wx.EXPAND)
@@ -322,7 +373,7 @@
                 wx.MessageBox("Some non 7-bit ASCII characters found and stripped","Warning!")
             txt = u_txt
             if txt != "":
-                self.handler.master_dom.setAttribute('name',txt)
+                self.handler.xml.set('name',txt)
                 self.handler.rename(txt)
         elif id == P_BODY:
             txt = self.text[id].get_text()
@@ -348,21 +399,19 @@
     """ clones childe node and insert it at top of tree
         <nodehandler name='?'  module='core' class='node_loader'  />
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
 
     def on_rclick(self,evt):
         pass
 
     def on_ldclick(self,evt):
-        title = self.master_dom.getAttribute('name')
-        new_node = self.master_dom._get_firstChild()
-        new_node = new_node.cloneNode(True)
-        child = self.tree.master_dom._get_firstChild()
-        new_node = self.tree.master_dom.insertBefore(new_node,child)
-        tree_node = self.tree.load_xml(new_node,self.tree.root,self.tree.root)
-        obj = self.tree.GetPyData(tree_node)
+        title = self.xml.get('name')
+        new_xml = XML(tostring(self.xml[0]))
+        self.tree.root_xml.insert(0, new_xml)
+        tree_node = self.tree.load_xml(new_xml,self.tree.root,self.tree.root)
         return 1
+        #obj = self.tree.GetPyData(tree_node)
         #obj.on_design(None)
 
 ##########################
@@ -375,25 +424,25 @@
         <file name="file_name.xml" />
         </nodehandler>
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
-        self.file_node = self.master_dom._get_firstChild()
-        self.frame = component.get('frame')
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
+        self.file_node = self.xml[0]
+        self.frame = open_rpg.get_component('frame')
 
     def on_ldclick(self,evt):
-        file_name = self.file_node.getAttribute("name")
-        self.tree.insert_xml(open(dir_struct["nodes"] + file_name,"r").read())
+        file_name = self.file_node.get("name")
+        self.tree.insert_xml(open(orpg.dirpath.dir_struct["nodes"] + file_name,"r").read())
         return 1
 
     def on_design(self,evt):
         tlist = ['Title','File Name']
-        vlist = [self.master_dom.getAttribute("name"),
-                  self.file_node.getAttribute("name")]
+        vlist = [self.xml.get("name"),
+                  self.file_node.get("name")]
         dlg = orpgMultiTextEntry(self.tree.GetParent(),tlist,vlist,"File Loader Edit")
         if dlg.ShowModal() == wx.ID_OK:
             vlist = dlg.get_values()
-            self.file_node.setAttribute('name', vlist[1])
-            self.master_dom.setAttribute('name', vlist[0])
+            self.file_node.set('name', vlist[1])
+            self.xml.set('name', vlist[0])
             self.tree.SetItemText(self.mytree_node,vlist[0])
         dlg.Destroy()
 
@@ -407,27 +456,27 @@
         <file name="http://file_name.xml" />
         </nodehandler>
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
-        self.file_node = self.master_dom._get_firstChild()
-        self.frame = component.get('frame')
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
+        self.file_node = self.xml[0]
+        self.frame = open_rpg.get_component('frame')
 
     def on_ldclick(self,evt):
-        file_name = self.file_node.getAttribute("url")
+        file_name = self.file_node.get("url")
         file = urllib.urlopen(file_name)
         self.tree.insert_xml(file.read())
         return 1
 
     def on_design(self,evt):
         tlist = ['Title','URL']
-        print "design filename",self.master_dom.getAttribute('name')
-        vlist = [self.master_dom.getAttribute("name"),
-                 self.file_node.getAttribute("url")]
+        print "design filename",self.xml.get('name')
+        vlist = [self.xml.get("name"),
+                 self.file_node.get("url")]
         dlg = orpgMultiTextEntry(self.tree.GetParent(),tlist,vlist,"File Loader Edit")
         if dlg.ShowModal() == wx.ID_OK:
             vlist = dlg.get_values()
-            self.file_node.setAttribute('url', vlist[1])
-            self.master_dom.setAttribute('name', vlist[0])
+            self.file_node.set('url', vlist[1])
+            self.xml.set('name', vlist[0])
             self.tree.SetItemText(self.mytree_node,vlist[0])
         dlg.Destroy()
 
@@ -439,11 +488,11 @@
     """ clones childe node and insert it at top of tree
         <nodehandler name='?'  module='core' class='min_map'  />
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
-        self.map = component.get('map')
-        self.mapdata = self.master_dom._get_firstChild()
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
+        self.map = open_rpg.get_component('map')
+        self.mapdata = self.xml[0]
 
     def on_ldclick(self,evt):
-        self.map.new_data(toxml(self.mapdata))
+        self.map.new_data(tostring(self.mapdata))
         return 1
--- a/orpg/gametree/nodehandlers/d20.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/gametree/nodehandlers/d20.py	Wed Oct 28 14:24:54 2009 -0500
@@ -30,6 +30,8 @@
 
 from core import *
 import re
+from xml.etree.ElementTree import ElementTree, Element, iselement
+from xml.etree.ElementTree import fromstring, tostring, parse, XML
 
 D20_EXPORT = wx.NewId()
 ############################
@@ -42,12 +44,12 @@
     """ should not be used! only a base class!
     <nodehandler name='?'  module='core' class='container_handler'  />
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
         self.load_children()
 
     def load_children(self):
-        children = self.master_dom._get_childNodes()
+        children = self.xml._get_childNodes()
         for c in children:
             self.tree.load_xml(c,self.mytree_node)
 
@@ -60,9 +62,9 @@
             return
         opt = wx.MessageBox("Add node as child?","Container Node",wx.YES_NO|wx.CANCEL)
         if opt == wx.YES:
-            xml_dom = self.tree.drag_obj.delete()
-            xml_dom = self.master_dom.insertBefore(xml_dom,None)
-            self.tree.load_xml(xml_dom, self.mytree_node)
+            xml = self.tree.drag_obj.delete()
+            xml = self.xml.insertBefore(xml,None)
+            self.tree.load_xml(xml, self.mytree_node)
             self.tree.Expand(self.mytree_node)
         elif opt == wx.NO:
             node_handler.on_drop(self,evt)
@@ -70,7 +72,7 @@
     def tohtml(self):
         cookie = 0
         html_str = "<table border=\"1\" ><tr><td>"
-        html_str += "<b>"+self.master_dom.getAttribute("name") + "</b>"
+        html_str += "<b>"+self.xml.get("name") + "</b>"
         html_str += "</td></tr>\n"
         html_str += "<tr><td>"
 
@@ -110,8 +112,8 @@
     """ Node handler for a d20 charactor
         <nodehandler name='?'  module='d20' class='d20char_handler2'  />
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
         self.frame = component.get('frame')
         self.child_handlers = {}
         self.new_child_handler('howtouse','HowTO use this tool',d20howto,'note')
@@ -136,38 +138,32 @@
     def on_version(self,old_version):
         node_handler.on_version(self,old_version)
         if old_version == "":
-            tmp = open(orpg.dirpath.dir_struct["nodes"]+"d20character.xml","r")
-            xml_dom = parseXml_with_dlg(self.tree,tmp.read())
-            xml_dom = xml_dom._get_firstChild()
-            tmp.close()
-            ## add new nodes
+            data = parse(orpg.dirpath.dir_struct["nodes"]+"d20character.xml").getroot()
             for tag in ("howtouse","inventory","powers","divine","pp"):
-                node_list = xml_dom.getElementsByTagName(tag)
-                self.master_dom.appendChild(node_list[0])
+                self.xml.append(data.find(tag))
 
             ## add new atts
-            melee_attack = self.master_dom.getElementsByTagName('melee')[0]
-            melee_attack.setAttribute("second","0")
-            melee_attack.setAttribute("third","0")
-            melee_attack.setAttribute("forth","0")
-            melee_attack.setAttribute("fifth","0")
-            melee_attack.setAttribute("sixth","0")
-            range_attack = self.master_dom.getElementsByTagName('ranged')[0]
-            range_attack.setAttribute("second","0")
-            range_attack.setAttribute("third","0")
-            range_attack.setAttribute("forth","0")
-            range_attack.setAttribute("fifth","0")
-            range_attack.setAttribute("sixth","0")
+            melee_attack = self.xml.find('melee')
+            melee_attack.set("second","0")
+            melee_attack.set("third","0")
+            melee_attack.set("forth","0")
+            melee_attack.set("fifth","0")
+            melee_attack.set("sixth","0")
+            range_attack = self.xml.find('ranged')
+            range_attack.set("second","0")
+            range_attack.set("third","0")
+            range_attack.set("forth","0")
+            range_attack.set("fifth","0")
+            range_attack.set("sixth","0")
 
-            gen_list = self.master_dom.getElementsByTagName('general')[0]
+            gen_list = self.xml.find('general')
 
             for tag in ("currentxp","xptolevel"):
-                node_list = xml_dom.getElementsByTagName(tag)
-                gen_list.appendChild(node_list[0])
+                gen_list.append(data.find(tag))
             ## temp fix
-            #parent = self.master_dom._get_parentNode()
-            #old_dom = parent.replaceChild(xml_dom,self.master_dom)
-            #self.master_dom = xml_dom
+            #parent = self.xml._get_parentNode()
+            #old_dom = parent.replaceChild(xml,self.xml)
+            #self.xml = xml
         print old_version
 
 
@@ -185,11 +181,10 @@
 
 
     def new_child_handler(self,tag,text,handler_class,icon='gear'):
-        node_list = self.master_dom.getElementsByTagName(tag)
         tree = self.tree
         i = self.tree.icons[icon]
         new_tree_node = tree.AppendItem(self.mytree_node,text,i,i)
-        handler = handler_class(node_list[0],new_tree_node,self)
+        handler = handler_class(self.xml.find(tag),new_tree_node,self)
         tree.SetPyData(new_tree_node,handler)
         self.child_handlers[tag] = handler
 
@@ -264,7 +259,7 @@
                 panel = obj.get_design_panel(self)
             else:
                 panel = obj.get_use_panel(self)
-            name = obj.master_dom.getAttribute("name")
+            name = obj.xml.get("name")
 
             if panel:
                 self.AddPage(panel,name)
@@ -297,14 +292,13 @@
     """ Node Handler for skill.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        node_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self,xml,tree_node,parent):
+        node_handler.__init__(self,xml,tree_node)
         self.char_hander = parent
         self.drag = False
         self.frame = component.get('frame')
         self.myeditor = None
 
-
     def on_drop(self,evt):
         pass
 
@@ -314,7 +308,7 @@
     def on_ldclick(self,evt):
         return
         if self.myeditor == None or self.myeditor.destroyed:
-            title = self.master_dom.getAttribute('name') + " Editor"
+            title = self.xml.get('name') + " Editor"
             self.myeditor = wx.Frame(self.frame, -1, title)
             if wx.Platform == '__WXMSW__':
                 icon = wx.Icon(orpg.dirpath.dir_struct["icon"]+'grid.ico', wx.BITMAP_TYPE_ICO)
@@ -330,7 +324,7 @@
     def on_html(self,evt):
         html_str = self.tohtml()
         wnd = http_html_window(self.frame.note,-1)
-        wnd.title = self.master_dom.getAttribute('name')
+        wnd.title = self.xml.get('name')
         self.frame.add_panel(wnd)
         wnd.SetPage(html_str)
 
@@ -348,27 +342,26 @@
     """ Node Handler for skill.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
         tree = self.tree
         icons = self.tree.icons
-        node_list = self.master_dom.getElementsByTagName('skill')
         self.skills={}
-        for n in node_list:
-            name = n.getAttribute('name')
+        for n in self.xml.findall('skill'):
+            name = n.get('name')
             self.skills[name] = n
             new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear'])
             tree.SetPyData(new_tree_node,self)
 
     def get_mod(self,name):
         skill = self.skills[name]
-        stat = skill.getAttribute('stat')
-        ac = int(skill.getAttribute('armorcheck'))
+        stat = skill.get('stat')
+        ac = int(skill.get('armorcheck'))
         if ac:
             ac = self.char_hander.child_handlers['ac'].get_check_pen()
         stat_mod = self.char_hander.child_handlers['abilities'].get_mod(stat)
-        rank = int(skill.getAttribute('rank'))
-        misc = int(skill.getAttribute('misc'))
+        rank = int(skill.get('rank'))
+        misc = int(skill.get('misc'))
         total = stat_mod + rank + misc + ac
         return total
 
@@ -382,8 +375,8 @@
             #self.frame.add_panel(wnd)
         else:
             skill = self.skills[name];
-            untrained = skill.getAttribute('untrained');
-            rank = skill.getAttribute('rank');
+            untrained = skill.get('untrained');
+            rank = skill.get('rank');
             if untrained == "0" and rank == "0":
                 txt = '%s Skill Check: Untrained' % (name)
             else:
@@ -404,14 +397,13 @@
     def tohtml(self):
         html_str = """<table border='1' width=100% ><tr BGCOLOR=#E9E9E9 ><th width='30%'>Skill</th><th>Key</th>
                     <th>Rank</th><th>Abil</th><th>Misc</th><th>Total</th></tr>"""
-        node_list = self.master_dom.getElementsByTagName('skill')
-        for n in node_list:
-            name = n.getAttribute('name')
-            stat = n.getAttribute('stat')
-            rank = n.getAttribute('rank')
+        for n in self.xml.findall('skill'):
+            name = n.get('name')
+            stat = n.get('stat')
+            rank = n.get('rank')
             html_str = html_str + "<tr ALIGN='center'><td>"+name+"</td><td>"+stat+"</td><td>"+rank+"</td>"
             stat_mod = str(self.char_hander.child_handlers['abilities'].get_mod(stat))
-            misc = n.getAttribute('misc')
+            misc = n.get('misc')
             mod = str(self.get_mod(name))
             if mod >= 0:
                 mod1 = "+"
@@ -426,14 +418,13 @@
     """ Node Handler for ability.   This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
         self.abilities = {}
-        node_list = self.master_dom.getElementsByTagName('stat')
         tree = self.tree
         icons = tree.icons
-        for n in node_list:
-            name = n.getAttribute('abbr')
+        for n in self.xml.findall('stat'):
+            name = n.get('abbr')
             self.abilities[name] = n
             new_tree_node = tree.AppendItem( self.mytree_node, name, icons['gear'], icons['gear'] )
             tree.SetPyData( new_tree_node, self )
@@ -454,13 +445,13 @@
             chat.ParsePost( txt, True, True )
 
     def get_mod(self,abbr):
-        score = int(self.abilities[abbr].getAttribute('base'))
+        score = int(self.abilities[abbr].get('base'))
         mod = (score - 10) / 2
         return mod
 
     def set_score(self,abbr,score):
         if score >= 0:
-            self.abilities[abbr].setAttribute("base",str(score))
+            self.abilities[abbr].set("base",str(score))
 
     def get_design_panel(self,parent):
         wnd = outline_panel(parent,self,abil_grid,"Abilities")
@@ -469,12 +460,11 @@
 
     def tohtml(self):
         html_str = """<table border='1' width=100%><tr BGCOLOR=#E9E9E9 ><th width='50%'>Ability</th>
-                    <th>Base</th><th>Modifier</th></tr>"""
-        node_list = self.master_dom.getElementsByTagName('stat')
-        for n in node_list:
-            name = n.getAttribute('name')
-            abbr = n.getAttribute('abbr')
-            base = n.getAttribute('base')
+                    <th>Base</th><th>Modifier</th></tr>""" 
+        for n in self.xml.findall('stat'):
+            name = n.get('name')
+            abbr = n.get('abbr')
+            base = n.get('base')
             mod = str(self.get_mod(abbr))
             if mod >= 0:
                 mod1 = "+"
@@ -484,29 +474,29 @@
         html_str = html_str + "</table>"
         return html_str
 
+
 class d20saves(d20_char_child):
     """ Node Handler for saves.   This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
         tree = self.tree
         icons = self.tree.icons
-        node_list = self.master_dom.getElementsByTagName('save')
         self.saves={}
-        for n in node_list:
-            name = n.getAttribute('name')
+        for n in self.xml.findall('save'):
+            name = n.get('name')
             self.saves[name] = n
             new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear'])
             tree.SetPyData(new_tree_node,self)
 
     def get_mod(self,name):
         save = self.saves[name]
-        stat = save.getAttribute('stat')
+        stat = save.get('stat')
         stat_mod = self.char_hander.child_handlers['abilities'].get_mod(stat)
-        base = int(save.getAttribute('base'))
-        miscmod = int(save.getAttribute('miscmod'))
-        magmod = int(save.getAttribute('magmod'))
+        base = int(save.get('base'))
+        miscmod = int(save.get('miscmod'))
+        magmod = int(save.get('magmod'))
         total = stat_mod + base + miscmod + magmod
         return total
 
@@ -537,15 +527,14 @@
         html_str = """<table border='1' width=100% ><tr BGCOLOR=#E9E9E9 ><th width='30%'>Save</th>
                     <th>Key</th><th>Base</th><th>Abil</th><th>Magic</th>
                     <th>Misc</th><th>Total</th></tr>"""
-        node_list = self.master_dom.getElementsByTagName('save')
-        for n in node_list:
-            name = n.getAttribute('name')
-            stat = n.getAttribute('stat')
-            base = n.getAttribute('base')
+        for n in self.xml.findall('save'):
+            name = n.get('name')
+            stat = n.get('stat')
+            base = n.get('base')
             html_str = html_str + "<tr ALIGN='center'><td>"+name+"</td><td>"+stat+"</td><td>"+base+"</td>"
             stat_mod = str(self.char_hander.child_handlers['abilities'].get_mod(stat))
-            mag = n.getAttribute('magmod')
-            misc = n.getAttribute('miscmod')
+            mag = n.get('magmod')
+            misc = n.get('miscmod')
             mod = str(self.get_mod(name))
             if mod >= 0:
                 mod1 = "+"
@@ -561,8 +550,8 @@
     """ Node Handler for general information.   This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
 
     def get_design_panel(self,parent):
         wnd = outline_panel(parent,self,gen_grid,"General Information")
@@ -570,12 +559,10 @@
         return wnd
 
     def tohtml(self):
-        n_list = self.master_dom._get_childNodes()
         html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>General Information</th></tr><tr><td>"
-        for n in n_list:
-            t_node = component.get('xml').safe_get_text_node(n)
-            html_str += "<B>"+n._get_tagName().capitalize() +":</B> "
-            html_str += t_node._get_nodeValue() + ", "
+        for n in self.xml:
+            html_str += "<B>"+n.tag.capitalize() +":</B> "
+            html_str += n.text + ", "
         html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
         return html_str
 
@@ -583,17 +570,15 @@
         self.char_hander.rename(name)
 
     def get_char_name( self ):
-        node = self.master_dom.getElementsByTagName( 'name' )[0]
-        t_node = component.get('xml').safe_get_text_node( node )
-        return t_node._get_nodeValue()
+        return self.xml.find( 'name' ).text
 
 
 class d20classes(d20_char_child):
     """ Node Handler for classes.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
 
     def get_design_panel(self,parent):
         wnd = outline_panel(parent,self,class_panel,"Classes")
@@ -602,17 +587,15 @@
 
     def tohtml(self):
         html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Classes</th></tr><tr><td>"
-        n_list = self.master_dom._get_childNodes()
-        for n in n_list:
-            html_str += n.getAttribute('name') + " ("+n.getAttribute('level')+"), "
+        for n in self.xml:
+            html_str += n.get('name') + " ("+n.get('level')+"), "
         html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
         return html_str
 
     def get_char_lvl( self, attr ):
-        node_list = self.master_dom.getElementsByTagName('class')
-        for n in node_list:
-            lvl = n.getAttribute('level')
-            type = n.getAttribute('name')
+        for n in self.xml.findall('class'):
+            lvl = n.get('level')
+            type = n.get('name')
             if attr == "level":
                 return lvl
             elif attr == "class":
@@ -623,8 +606,8 @@
     """ Node Handler for classes.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
 
     def get_design_panel(self,parent):
         wnd = outline_panel(parent,self,feat_panel,"Feats")
@@ -633,24 +616,23 @@
 
     def tohtml(self):
         html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Feats</th></tr><tr><td>"
-        n_list = self.master_dom._get_childNodes()
-        for n in n_list:
-            html_str += n.getAttribute('name')+ ", "
+        for n in self.xml:
+            html_str += n.get('name')+ ", "
         html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
         return html_str
 
+
 class d20spells(d20_char_child):
     """ Node Handler for classes.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
-        node_list = self.master_dom.getElementsByTagName( 'spell' )
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
         self.spells = {}
         tree = self.tree
         icons = self.tree.icons
-        for n in node_list:
-            name = n.getAttribute('name')
+        for n in self.xml.findall( 'spell' ):
+            name = n.get('name')
             self.spells[ name ] = n
             new_tree_node = tree.AppendItem( self.mytree_node, name, icons['gear'], icons['gear'] )
             tree.SetPyData( new_tree_node, self )
@@ -661,10 +643,10 @@
         if item == self.mytree_node:
             d20_char_child.on_ldclick( self, evt )
         else:
-            level = self.spells[ name ].getAttribute( 'level' )
-            descr = self.spells[ name ].getAttribute( 'desc' )
-            use = self.spells[ name ].getAttribute( 'used' )
-            memrz = self.spells[ name ].getAttribute( 'memrz' )
+            level = self.spells[ name ].get( 'level' )
+            descr = self.spells[ name ].get( 'desc' )
+            use = self.spells[ name ].get( 'used' )
+            memrz = self.spells[ name ].get( 'memrz' )
             cname = self.char_hander.get_char_name()
             use += '+1'
             left = eval( '%s - ( %s )' % ( memrz, use ) )
@@ -679,16 +661,15 @@
                     s = 's'
                 txt = '%s can cast %s %d more time%s' % ( cname, name, left, s )
                 self.chat.ParsePost( txt, False, False )
-                self.spells[ name ].setAttribute( 'used', `eval( use )` )
+                self.spells[ name ].set( 'used', `eval( use )` )
 
     def refresh_spells(self):
         self.spells = {}
         tree = self.tree
         icons = self.tree.icons
         tree.CollapseAndReset(self.mytree_node)
-        node_list = self.master_dom.getElementsByTagName('spell')
-        for n in node_list:
-            name = n.getAttribute('name')
+        for n in self.xml.findall('spell'):
+            name = n.get('name')
             new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear'])
             tree.SetPyData(new_tree_node,self)
             self.spells[name]=n
@@ -700,9 +681,8 @@
 
     def tohtml(self):
         html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Arcane Spells</th></tr><tr><td><br />"
-        n_list = self.master_dom._get_childNodes()
-        for n in n_list:
-            html_str += "(" + n.getAttribute('level') + ") " + n.getAttribute('name')+ ", "
+        for n in self.xml:
+            html_str += "(" + n.get('level') + ") " + n.get('name')+ ", "
         html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
         return html_str
 
@@ -713,14 +693,13 @@
     """ Node Handler for classes.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,component,parent)
-        node_list = self.master_dom.getElementsByTagName( 'gift' )
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
         self.spells = {}
         tree = self.tree
         icons = self.tree.icons
-        for n in node_list:
-            name = n.getAttribute('name')
+        for n in self.xml.findall( 'gift' ):
+            name = n.get('name')
             self.spells[ name ] = n
             new_tree_node = tree.AppendItem( self.mytree_node, name, icons['flask'], icons['flask'] )
             tree.SetPyData( new_tree_node, self )
@@ -731,10 +710,10 @@
         if item == self.mytree_node:
             d20_char_child.on_ldclick( self, evt )
         else:
-            level = self.spells[ name ].getAttribute( 'level' )
-            descr = self.spells[ name ].getAttribute( 'desc' )
-            use = self.spells[ name ].getAttribute( 'used' )
-            memrz = self.spells[ name ].getAttribute( 'memrz' )
+            level = self.spells[ name ].get( 'level' )
+            descr = self.spells[ name ].get( 'desc' )
+            use = self.spells[ name ].get( 'used' )
+            memrz = self.spells[ name ].get( 'memrz' )
             cname = self.char_hander.get_char_name()
             use += '+1'
             left = eval( '%s - ( %s )' % ( memrz, use ) )
@@ -749,20 +728,19 @@
                     s = 's'
                 txt = '%s can cast %s %d more time%s' % ( cname, name, left, s )
                 self.chat.ParsePost( txt, False, False )
-                self.spells[ name ].setAttribute( 'used', `eval( use )` )
+                self.spells[ name ].set( 'used', `eval( use )` )
 
     def refresh_spells(self):
         self.spells = {}
         tree = self.tree
         icons = self.tree.icons
         tree.CollapseAndReset(self.mytree_node)
-        node_list = self.master_dom.getElementsByTagName('gift')
-        for n in node_list:
-            name = n.getAttribute('name')
+        for n in self.xml.findall('gift'):
+            name = n.get('name')
             new_tree_node = tree.AppendItem(self.mytree_node,name,icons['flask'],icons['flask'])
             tree.SetPyData(new_tree_node,self)
             self.spells[name]=n
-
+            
     def get_design_panel(self,parent):
         wnd = outline_panel(parent,self,divine_panel,"Spells")
         wnd.title = "Spells"
@@ -770,9 +748,8 @@
 
     def tohtml(self):
         html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Divine Spells</th></tr><tr><td><br />"
-        n_list = self.master_dom._get_childNodes()
-        for n in n_list:
-            html_str += "(" + n.getAttribute('level') + ") " + n.getAttribute('name')+ ", "
+        for n in self.xml:
+            html_str += "(" + n.get('level') + ") " + n.get('name')+ ", "
         html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
         return html_str
 
@@ -783,15 +760,14 @@
     """ Node Handler for classes.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
-        node_list = self.master_dom.getElementsByTagName( 'power' )
-        #cpp = self.master_dom.getElementsByTagName( 'pp' ).getAttribute('current1')
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
+        #cpp = self.xml.findall( 'pp' ).get('current1')
         self.powers = {}
         tree = self.tree
         icons = self.tree.icons
-        for n in node_list:
-            name = n.getAttribute('name')
+        for n in self.xml.findall( 'power' ):
+            name = n.get('name')
             self.powers[ name ] = n
             new_tree_node = tree.AppendItem( self.mytree_node, name, icons['gear'], icons['gear'] )
             tree.SetPyData( new_tree_node, self )
@@ -802,10 +778,10 @@
         if item == self.mytree_node:
             d20_char_child.on_ldclick( self, evt )
         else:
-            level = self.powers[ name ].getAttribute( 'level' )
-            descr = self.powers[ name ].getAttribute( 'desc' )
-            use = self.powers[ name ].getAttribute( 'used' )
-            points = self.powers[ name ].getAttribute( 'point' )
+            level = self.powers[ name ].get( 'level' )
+            descr = self.powers[ name ].get( 'desc' )
+            use = self.powers[ name ].get( 'used' )
+            points = self.powers[ name ].get( 'point' )
             cpp = self.char_hander.get_char_pp('current1')
             fre = self.char_hander.get_char_pp('free')
             cname = self.char_hander.get_char_name()
@@ -837,7 +813,7 @@
                     if left != 1:
                         s = 's'
                     txt = '%s can use %s %d more time%s' % ( cname, name, numcast, s )
-                    txt += ' - And has %d more PowerpointsP left' % (left)
+                    txt += ' - And has %d more Powerpoints left' % (left)
                     self.chat.ParsePost( txt, False, False )
                     self.char_hander.set_char_pp('current1', left)
 
@@ -846,9 +822,8 @@
         tree = self.tree
         icons = self.tree.icons
         tree.CollapseAndReset(self.mytree_node)
-        node_list = self.master_dom.getElementsByTagName('power')
-        for n in node_list:
-            name = n.getAttribute('name')
+        for n in self.xml.findall('power'):
+            name = n.get('name')
             new_tree_node = tree.AppendItem(self.mytree_node,name,icons['questionhead'],icons['questionhead'])
             tree.SetPyData(new_tree_node,self)
             self.powers[name]=n
@@ -860,9 +835,8 @@
 
     def tohtml(self):
         html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>Powers</th></tr><tr><td><br />"
-        n_list = self.master_dom._get_childNodes()
-        for n in n_list:
-            html_str += "(" + n.getAttribute('level') + ") " + n.getAttribute('name')+ ", "
+        for n in self.xml:
+            html_str += "(" + n.get('level') + ") " + n.get('name')+ ", "
         html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
         return html_str
 
@@ -879,8 +853,8 @@
     """ Node Handler for hit points.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
 
     def get_design_panel(self,parent):
         wnd = outline_panel(parent,self,howto_panel,"How To")
@@ -891,8 +865,8 @@
     """ Node Handler for general information.   This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
 
     def get_design_panel(self,parent):
         wnd = outline_panel(parent,self,inventory_grid,"Inventory")
@@ -900,12 +874,10 @@
         return wnd
 
     def tohtml(self):
-        n_list = self.master_dom._get_childNodes()
         html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th>General Information</th></tr><tr><td>"
-        for n in n_list:
-            t_node = component.get('xml').safe_get_text_node(n)
-            html_str += "<B>"+n._get_tagName().capitalize() +":</B> "
-            html_str += t_node._get_nodeValue() + "<br />"
+        for n in self.xml:
+            html_str += "<B>"+n.tag.capitalize() +":</B> "
+            html_str += n.text + "<br />"
         html_str = html_str[:len(html_str)-2] + "</td></tr></table>"
         return html_str
 
@@ -913,16 +885,15 @@
         self.char_hander.rename(name)
 
     def get_char_name( self ):
-        node = self.master_dom.getElementsByTagName( 'name' )[0]
-        t_node = component.get('xml').safe_get_text_node( node )
-        return t_node._get_nodeValue()
+        return self.xml.find( 'name' ).text
+
 
 class d20hp(d20_char_child):
     """ Node Handler for hit points.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
 
     def get_design_panel(self,parent):
         wnd = outline_panel(parent,self,hp_panel,"Hit Points")
@@ -931,19 +902,19 @@
 
     def tohtml(self):
         html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th colspan=4>Hit Points</th></tr>"
-        html_str += "<tr><th>Max:</th><td>"+self.master_dom.getAttribute('max')+"</td>"
-        html_str += "<th>Current:</th><td>"+self.master_dom.getAttribute('current')+"</td>"
+        html_str += "<tr><th>Max:</th><td>"+self.xml.get('max')+"</td>"
+        html_str += "<th>Current:</th><td>"+self.xml.get('current')+"</td>"
         html_str += "</tr></table>"
         return html_str
 
     def get_max_hp( self ):
         try:
-            return eval( self.master_dom.getAttribute( 'max' ) )
+            return eval( self.xml.get( 'max' ) )
         except:
             return 0
     def get_current_hp( self ):
         try:
-            return eval( self.master_dom.getAttribute( 'current' ) )
+            return eval( self.xml.get( 'current' ) )
         except:
             return 0
 
@@ -951,8 +922,8 @@
     """ Node Handler for power points.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
 
     def get_design_panel(self,parent):
         wnd = outline_panel(parent,self,pp_panel,"Power Points")
@@ -961,30 +932,30 @@
 
     def tohtml(self):
         html_str = "<table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th colspan=8>Power Points</th></tr>"
-        html_str += "<tr><th>Max:</th><td>"+self.master_dom.getAttribute('max1')+"</td>"
-        html_str += "<th>Current:</th><td>"+self.master_dom.getAttribute('current1')+"</td>"
-        html_str += "<th>Current Talents/day:</th><td>"+self.master_dom.getAttribute('free')+"</td>"
-        html_str += "<th>Max Talents/day:</th><td>"+self.master_dom.getAttribute('maxfree')+"</td>"
+        html_str += "<tr><th>Max:</th><td>"+self.xml.get('max1')+"</td>"
+        html_str += "<th>Current:</th><td>"+self.xml.get('current1')+"</td>"
+        html_str += "<th>Current Talents/day:</th><td>"+self.xml.get('free')+"</td>"
+        html_str += "<th>Max Talents/day:</th><td>"+self.xml.get('maxfree')+"</td>"
         html_str += "</tr></table>"
         return html_str
 
     def get_char_pp( self, attr ):
-        pp = self.master_dom.getAttribute(attr)
+        pp = self.xml.get(attr)
         return pp
 
     def set_char_pp( self, attr, evl ):
-        pp = self.master_dom.setAttribute(attr, evl)
+        pp = self.xml.set(attr, evl)
         return pp
 
 class d20attacks(d20_char_child):
     """ Node Handler for attacks.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
-        node_list = self.master_dom.getElementsByTagName('melee')
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
+        node_list = self.xml.findall('melee')
         self.melee = node_list[0]
-        node_list = self.master_dom.getElementsByTagName('ranged')
+        node_list = self.xml.findall('ranged')
         self.ranged = node_list[0]
         self.refresh_weapons()
 
@@ -993,22 +964,22 @@
         tree = self.tree
         icons = self.tree.icons
         tree.CollapseAndReset(self.mytree_node)
-        node_list = self.master_dom.getElementsByTagName('weapon')
+        node_list = self.xml.findall('weapon')
         for n in node_list:
-            name = n.getAttribute('name')
+            name = n.get('name')
             new_tree_node = tree.AppendItem(self.mytree_node,name,icons['sword'],icons['sword'])
             tree.SetPyData(new_tree_node,self)
             self.weapons[name]=n
 
     def get_attack_data(self):
         temp = self.melee
-        base = int(temp.getAttribute('base'))
-        base2 = int(temp.getAttribute('second'))
-        base3 = int(temp.getAttribute('third'))
-        base4 = int(temp.getAttribute('forth'))
-        base5 = int(temp.getAttribute('fifth'))
-        base6 = int(temp.getAttribute('sixth'))
-        misc = int(temp.getAttribute('misc'))
+        base = int(temp.get('base'))
+        base2 = int(temp.get('second'))
+        base3 = int(temp.get('third'))
+        base4 = int(temp.get('forth'))
+        base5 = int(temp.get('fifth'))
+        base6 = int(temp.get('sixth'))
+        misc = int(temp.get('misc'))
         return (base, base2, base3, base4, base5, base6, misc)
 
     # Replace any 'S' and 'D' in an attack modifier and damage modifier with the
@@ -1038,10 +1009,10 @@
             #self.frame.add_panel(self.get_design_panel(self.frame.note))
         else:
             # Weapon/attack specific attack modifier (e.g. "S+1" for a longsword+1).
-            attack_mod_str = self.weapons[name].getAttribute('mod')
+            attack_mod_str = self.weapons[name].get('mod')
 
             # Weapon/attack specific damage (e.g. "1d8+S+1" for a longsword+1).
-            damage_str = self.weapons[name].getAttribute('damage')
+            damage_str = self.weapons[name].get('damage')
             (num_damage_dice, damage_die, damage_mods, extra_damage) = self.decompose_damage( damage_str )
 
             # Replace any 'S' and 'D' in attack_mod_str and damage_str with the
@@ -1052,10 +1023,10 @@
             bab_attributes = ['base', 'second', 'third', 'forth', 'fifth', 'sixth']
             bab = []
             for b in bab_attributes:
-                bab.append( int(self.melee.getAttribute( b )) )
+                bab.append( int(self.melee.get( b )) )
 
             # Misc. attack modifier to be applied to *all* attacks.
-            misc_mod = int(self.melee.getAttribute( 'misc' ));
+            misc_mod = int(self.melee.get( 'misc' ));
 
             # Attack modifier (except BAB)
             attack_mod = misc_mod + eval( attack_mod_str )
@@ -1067,7 +1038,7 @@
                 damage_mod = 0
 
             # Determine critical hit range and multiplier.
-            critical_str = self.weapons[name].getAttribute( 'critical' )
+            critical_str = self.weapons[name].get( 'critical' )
             m = re.match( r"(((?P<min>\d+)-)?\d+/)?x(?P<mult>\d+)", critical_str )
             crit_min = m.group( 'min' )
             crit_mult = m.group( 'mult' )
@@ -1120,32 +1091,32 @@
         html_str += "</td></tr><tr ALIGN='center' ><th BGCOLOR=#E9E9E9>Misc. Attack Bonus</th>"
         html_str += '<td>%+d</td></tr></table>' % babs[6]
 
-        n_list = self.master_dom.getElementsByTagName('weapon')
+        n_list = self.xml.findall('weapon')
         for n in n_list:
-            (attack_mod, damage_mod) = self.process_mod_codes( n.getAttribute( 'mod' ), \
-                                                               n.getAttribute( 'damage' ) )
+            (attack_mod, damage_mod) = self.process_mod_codes( n.get( 'mod' ), \
+                                                               n.get( 'damage' ) )
             attack_mod = eval( attack_mod )
             html_str += """<P><table width=100% border=1><tr BGCOLOR=#E9E9E9><th colspan=3>Weapon</th>
                     <th>Attack</th><th >Damage</th></tr>""" \
                       + "<tr ALIGN='center'><td colspan=3>" \
-                      + n.getAttribute('name') + "</td><td>"
+                      + n.get('name') + "</td><td>"
             html_str += '%+d</td><td>%s</td></tr>' % (attack_mod, damage_mod)
             html_str += """<tr BGCOLOR=#E9E9E9 ><th>Critical</th><th>Range</th><th>Weight</th>
                         <th>Type</th><th>Size</th></tr>""" \
                       + "<tr ALIGN='center'><td>" \
-                      + n.getAttribute( 'critical' ) + "</td><td>" \
-                      + n.getAttribute( 'range' ) + "</td><td>" \
-                      + n.getAttribute( 'weight' )+"</td><td>" \
-                      + n.getAttribute( 'type' ) + "</td><td>" \
-                      + n.getAttribute( 'size' ) + "</td></tr></table>"
+                      + n.get( 'critical' ) + "</td><td>" \
+                      + n.get( 'range' ) + "</td><td>" \
+                      + n.get( 'weight' )+"</td><td>" \
+                      + n.get( 'type' ) + "</td><td>" \
+                      + n.get( 'size' ) + "</td></tr></table>"
         return html_str
 
 class d20armor(d20_char_child):
     """ Node Handler for ac.  This handler will be
         created by d20char_handler.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        d20_char_child.__init__(self,xml_dom,tree_node,parent)
+    def __init__(self,xml,tree_node,parent):
+        d20_char_child.__init__(self,xml,tree_node,parent)
 
     def get_spell_failure(self):
         return self.get_total('spellfailure')
@@ -1168,19 +1139,19 @@
         return ac_total
 
     def get_max_dex(self):
-        armor_list = self.master_dom.getElementsByTagName('armor')
+        armor_list = self.xml.findall('armor')
         dex = 10
         for a in armor_list:
-            temp = int(a.getAttribute("maxdex"))
+            temp = int(a.get("maxdex"))
             if temp < dex:
                 dex = temp
         return dex
 
     def get_total(self,attr):
-        armor_list = self.master_dom.getElementsByTagName('armor')
+        armor_list = self.xml.findall('armor')
         total = 0
         for a in armor_list:
-            total += int(a.getAttribute(attr))
+            total += int(a.get(attr))
         return total
 
     def get_design_panel(self,parent):
@@ -1196,20 +1167,19 @@
         html_str += "<td>"+str(self.get_spell_failure())+"</td>"
         html_str += "<td>"+str(self.get_max_dex())+"</td>"
         html_str += "<td>"+str(self.get_total_weight())+"</td></tr></table>"
-        n_list = self.master_dom._get_childNodes()
-        for n in n_list:
+        for n in self.xml:
             html_str += """<P><table width=100% border=1 ><tr BGCOLOR=#E9E9E9 ><th colspan=3>Armor</th>
                     <th>Type</th><th >Bonus</th></tr>"""
-            html_str += "<tr ALIGN='center' ><td  colspan=3>"+n.getAttribute('name')+"</td>"
-            html_str += "<td>"+n.getAttribute('type')+"</td>"
-            html_str += "<td>"+n.getAttribute('bonus')+"</td></tr>"
+            html_str += "<tr ALIGN='center' ><td  colspan=3>"+n.get('name')+"</td>"
+            html_str += "<td>"+n.get('type')+"</td>"
+            html_str += "<td>"+n.get('bonus')+"</td></tr>"
             html_str += """<tr BGCOLOR=#E9E9E9 ><th>Check Penalty</th><th>Spell Failure</th>
                         <th>Max Dex</th><th>Speed</th><th>Weight</th></tr>"""
-            html_str += "<tr ALIGN='center'><td>"+n.getAttribute('checkpenalty')+"</td>"
-            html_str += "<td>"+n.getAttribute('spellfailure')+"</td>"
-            html_str += "<td>"+n.getAttribute('maxdex')+"</td>"
-            html_str += "<td>"+n.getAttribute('speed')+"</td>"
-            html_str += "<td>"+n.getAttribute('weight')+"</td></tr></table>"
+            html_str += "<tr ALIGN='center'><td>"+n.get('checkpenalty')+"</td>"
+            html_str += "<td>"+n.get('spellfailure')+"</td>"
+            html_str += "<td>"+n.get('maxdex')+"</td>"
+            html_str += "<td>"+n.get('speed')+"</td>"
+            html_str += "<td>"+n.get('weight')+"</td></tr></table>"
         return html_str
 
 
@@ -1242,7 +1212,7 @@
 
 class char_panel(wx.ScrolledWindow):
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'TWO')
+        pname = handler.xml.set("name", 'TWO')
         wx.ScrolledWindow.__init__(self, parent, -1,style=wx.VSCROLL | wx.SUNKEN_BORDER  )
         self.height = 1200
         self.SetScrollbars(10, 10,80, self.height/10)
@@ -1297,14 +1267,12 @@
 class howto_panel(wx.Panel):
     def __init__(self, parent, handler):
         wx.Panel.__init__(self, parent, -1)
-        pname = handler.master_dom.setAttribute("name", 'How To')
+        pname = handler.xml.set("name", 'How To')
         self.sizer = wx.FlexGridSizer(2, 4, 2, 2)  # rows, cols, hgap, vgap
-        self.master_dom = handler.master_dom
-        n_list = self.master_dom._get_childNodes()
-        for n in n_list:
-            t_node = component.get('xml').safe_get_text_node(n)
-        self.sizer.AddMany([ (wx.StaticText(self, -1, t_node._get_nodeValue()),   0, wx.ALIGN_CENTER_VERTICAL),
-                 ])
+        self.sizer.AddMany([ (wx.StaticText(self, -1, 
+                              handler.xml.find('howto').text), 
+                              0, wx.ALIGN_CENTER_VERTICAL),
+                            ])
         self.sizer.AddGrowableCol(1)
         self.SetSizer(self.sizer)
 
@@ -1315,13 +1283,13 @@
 class hp_panel(wx.Panel):
     def __init__(self, parent, handler):
         wx.Panel.__init__(self, parent, -1)
-        pname = handler.master_dom.setAttribute("name", 'HitPoints')
+        pname = handler.xml.set("name", 'HitPoints')
         self.sizer = wx.FlexGridSizer(2, 4, 2, 2)  # rows, cols, hgap, vgap
-        self.master_dom = handler.master_dom
+        self.xml = handler.xml
         self.sizer.AddMany([ (wx.StaticText(self, -1, "HP Current:"),   0, wx.ALIGN_CENTER_VERTICAL),
-                 (wx.TextCtrl(self, HP_CUR, self.master_dom.getAttribute('current')),   0, wx.EXPAND),
+                 (wx.TextCtrl(self, HP_CUR, self.xml.get('current')),   0, wx.EXPAND),
                  (wx.StaticText(self, -1, "HP Max:"), 0, wx.ALIGN_CENTER_VERTICAL),
-                 (wx.TextCtrl(self, HP_MAX, self.master_dom.getAttribute('max')),  0, wx.EXPAND),
+                 (wx.TextCtrl(self, HP_MAX, self.xml.get('max')),  0, wx.EXPAND),
                  ])
         self.sizer.AddGrowableCol(1)
         self.SetSizer(self.sizer)
@@ -1332,9 +1300,9 @@
     def on_text(self,evt):
         id = evt.GetId()
         if id == HP_CUR:
-            self.master_dom.setAttribute('current',evt.GetString())
+            self.xml.set('current',evt.GetString())
         elif id == HP_MAX:
-            self.master_dom.setAttribute('max',evt.GetString())
+            self.xml.set('max',evt.GetString())
 
     def on_size(self,evt):
         s = self.GetClientSizeTuple()
@@ -1348,18 +1316,18 @@
 class pp_panel(wx.Panel):
     def __init__(self, parent, handler):
         wx.Panel.__init__(self, parent, -1)
-        pname = handler.master_dom.setAttribute("name", 'PowerPoints')
+        pname = handler.xml.set("name", 'PowerPoints')
         self.sizer = wx.FlexGridSizer(2, 4, 2, 2)  # rows, cols, hgap, vgap
-        self.master_dom = handler.master_dom
+        self.xml = handler.xml
 
         self.sizer.AddMany([ (wx.StaticText(self, -1, "PP Current:"),   0, wx.ALIGN_CENTER_VERTICAL),
-                 (wx.TextCtrl(self, PP_CUR, self.master_dom.getAttribute('current1')),   0, wx.EXPAND),
+                 (wx.TextCtrl(self, PP_CUR, self.xml.get('current1')),   0, wx.EXPAND),
                  (wx.StaticText(self, -1, "PP Max:"), 0, wx.ALIGN_CENTER_VERTICAL),
-                 (wx.TextCtrl(self, PP_MAX, self.master_dom.getAttribute('max1')),  0, wx.EXPAND),
+                 (wx.TextCtrl(self, PP_MAX, self.xml.get('max1')),  0, wx.EXPAND),
                  (wx.StaticText(self, -1, "Current Free Talants per day:"), 0, wx.ALIGN_CENTER_VERTICAL),
-                 (wx.TextCtrl(self, PP_FRE, self.master_dom.getAttribute('free')),  0, wx.EXPAND),
+                 (wx.TextCtrl(self, PP_FRE, self.xml.get('free')),  0, wx.EXPAND),
                  (wx.StaticText(self, -1, "Max Free Talants per day:"), 0, wx.ALIGN_CENTER_VERTICAL),
-                 (wx.TextCtrl(self, PP_MFRE, self.master_dom.getAttribute('maxfree')),  0, wx.EXPAND),
+                 (wx.TextCtrl(self, PP_MFRE, self.xml.get('maxfree')),  0, wx.EXPAND),
                  ])
         self.sizer.AddGrowableCol(1)
         self.SetSizer(self.sizer)
@@ -1372,13 +1340,13 @@
     def on_text(self,evt):
         id = evt.GetId()
         if id == PP_CUR:
-            self.master_dom.setAttribute('current1',evt.GetString())
+            self.xml.set('current1',evt.GetString())
         elif id == PP_MAX:
-            self.master_dom.setAttribute('max1',evt.GetString())
+            self.xml.set('max1',evt.GetString())
         elif id == PP_FRE:
-            self.master_dom.setAttribute('free',evt.GetString())
+            self.xml.set('free',evt.GetString())
         elif id == PP_MFRE:
-            self.master_dom.setAttribute('maxfree',evt.GetString())
+            self.xml.set('maxfree',evt.GetString())
 
     def on_size(self,evt):
         s = self.GetClientSizeTuple()
@@ -1388,12 +1356,12 @@
 class gen_grid(wx.grid.Grid):
     """grid for gen info"""
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'General')
+        pname = handler.xml.set("name", 'General')
         wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         self.Bind(wx.EVT_SIZE, self.on_size)
         self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
         self.handler = handler
-        n_list = handler.master_dom._get_childNodes()
+        n_list = handler.xml[:]
         self.CreateGrid(len(n_list),2)
         self.SetRowLabelSize(0)
         self.SetColLabelSize(0)
@@ -1406,15 +1374,13 @@
         row = evt.GetRow()
         col = evt.GetCol()
         value = self.GetCellValue(row,col)
-        t_node = self.n_list[row]._get_firstChild()
-        t_node._set_nodeValue(value)
+        self.n_list[row].text = value
         if row==0: self.handler.on_name_change(value)
 
     def refresh_row(self,rowi):
-        t_node = component.get('xml').safe_get_text_node(self.n_list[rowi])
-        self.SetCellValue(rowi,0,self.n_list[rowi]._get_tagName())
+        self.SetCellValue(rowi,0,self.n_list[rowi].tag)
         self.SetReadOnly(rowi,0)
-        self.SetCellValue(rowi,1,t_node._get_nodeValue())
+        self.SetCellValue(rowi,1,self.n_list[rowi].text)
 
     def on_size(self,evt):
         (w,h) = self.GetClientSizeTuple()
@@ -1428,12 +1394,12 @@
 class inventory_grid(wx.grid.Grid):
     """grid for gen info"""
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Money and Inventory')
+        pname = handler.xml.set("name", 'Money and Inventory')
         wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         self.Bind(wx.EVT_SIZE, self.on_size)
         self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
         self.handler = handler
-        n_list = handler.master_dom._get_childNodes()
+        n_list = handler.xml[:]
         self.CreateGrid(len(n_list),2)
         self.SetRowLabelSize(0)
         self.SetColLabelSize(0)
@@ -1446,15 +1412,13 @@
         row = evt.GetRow()
         col = evt.GetCol()
         value = self.GetCellValue(row,col)
-        t_node = self.n_list[row]._get_firstChild()
-        t_node._set_nodeValue(value)
+        self.n_list[row].text = value
         if row==0: self.handler.on_name_change(value)
 
     def refresh_row(self,rowi):
-        t_node = component.get('xml').safe_get_text_node(self.n_list[rowi])
-        self.SetCellValue(rowi,0,self.n_list[rowi]._get_tagName())
+        self.SetCellValue(rowi,0,self.n_list[rowi].tag)
         self.SetReadOnly(rowi,0)
-        self.SetCellValue(rowi,1,t_node._get_nodeValue())
+        self.SetCellValue(rowi,1,self.n_list[rowi].text)
 
     def on_size(self,evt):
         (w,h) = self.GetClientSizeTuple()
@@ -1468,12 +1432,12 @@
 class abil_grid(wx.grid.Grid):
     """grid for abilities"""
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Stats')
+        pname = handler.xml.set("name", 'Stats')
         wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         self.Bind(wx.EVT_SIZE, self.on_size)
         self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
         self.handler = handler
-        stats = handler.master_dom.getElementsByTagName('stat')
+        stats = handler.xml.findall('stat')
         self.CreateGrid(len(stats),3)
         self.SetRowLabelSize(0)
         col_names = ['Ability','Score','Modifier']
@@ -1491,7 +1455,7 @@
         value = self.GetCellValue(row,col)
         try:
             int(value)
-            self.stats[row].setAttribute('base',value)
+            self.stats[row].set('base',value)
             self.refresh_row(row)
         except:
             self.SetCellValue(row,col,"0")
@@ -1500,11 +1464,11 @@
 
     def refresh_row(self,rowi):
         s = self.stats[rowi]
-        name = s.getAttribute('name')
-        abbr = s.getAttribute('abbr')
+        name = s.get('name')
+        abbr = s.get('abbr')
         self.SetCellValue(rowi,0,name)
         self.SetReadOnly(rowi,0)
-        self.SetCellValue(rowi,1,s.getAttribute('base'))
+        self.SetCellValue(rowi,1,s.get('base'))
         self.SetCellValue(rowi,2,str(self.handler.get_mod(abbr)))
         self.SetReadOnly(rowi,2)
 
@@ -1526,12 +1490,12 @@
 class save_grid(wx.grid.Grid):
     """grid for saves"""
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Saves')
+        pname = handler.xml.set("name", 'Saves')
         wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         self.Bind(wx.EVT_SIZE, self.on_size)
         self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
         self.handler = handler
-        saves = handler.master_dom.getElementsByTagName('save')
+        saves = handler.xml.findall('save')
         self.stats = handler.char_hander.child_handlers['abilities']
         self.CreateGrid(len(saves),7)
         self.SetRowLabelSize(0)
@@ -1550,28 +1514,28 @@
         try:
             int(value)
             if col == 2:
-                self.saves[row].setAttribute('base',value)
+                self.saves[row].set('base',value)
             elif col ==4:
-                self.saves[row].setAttribute('magmod',value)
+                self.saves[row].set('magmod',value)
             elif col ==4:
-                self.saves[row].setAttribute('miscmod',value)
+                self.saves[row].set('miscmod',value)
             self.refresh_row(row)
         except:
             self.SetCellValue(row,col,"0")
 
     def refresh_row(self,rowi):
         s = self.saves[rowi]
-        name = s.getAttribute('name')
+        name = s.get('name')
         self.SetCellValue(rowi,0,name)
         self.SetReadOnly(rowi,0)
-        stat = s.getAttribute('stat')
+        stat = s.get('stat')
         self.SetCellValue(rowi,1,stat)
         self.SetReadOnly(rowi,1)
-        self.SetCellValue(rowi,2,s.getAttribute('base'))
+        self.SetCellValue(rowi,2,s.get('base'))
         self.SetCellValue(rowi,3,str(self.stats.get_mod(stat)))
         self.SetReadOnly(rowi,3)
-        self.SetCellValue(rowi,4,s.getAttribute('magmod'))
-        self.SetCellValue(rowi,5,s.getAttribute('miscmod'))
+        self.SetCellValue(rowi,4,s.get('magmod'))
+        self.SetCellValue(rowi,5,s.get('miscmod'))
         mod = str(self.handler.get_mod(name))
         self.SetCellValue(rowi,6,mod)
         self.SetReadOnly(rowi,6)
@@ -1594,12 +1558,12 @@
 class skill_grid(wx.grid.Grid):
     """ panel for skills """
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Skills')
+        pname = handler.xml.set("name", 'Skills')
         wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         self.Bind(wx.EVT_SIZE, self.on_size)
         self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
         self.handler = handler
-        skills = handler.master_dom.getElementsByTagName('skill')
+        skills = handler.xml.findall('skill')
         self.stats = handler.char_hander.child_handlers['abilities']
         self.CreateGrid(len(skills),6)
         self.SetRowLabelSize(0)
@@ -1618,25 +1582,25 @@
         try:
             int(value)
             if col == 2:
-                self.skills[row].setAttribute('rank',value)
+                self.skills[row].set('rank',value)
             elif col ==4:
-                self.skills[row].setAttribute('misc',value)
+                self.skills[row].set('misc',value)
             self.refresh_row(row)
         except:
             self.SetCellValue(row,col,"0")
 
     def refresh_row(self,rowi):
         s = self.skills[rowi]
-        name = s.getAttribute('name')
+        name = s.get('name')
         self.SetCellValue(rowi,0,name)
         self.SetReadOnly(rowi,0)
-        stat = s.getAttribute('stat')
+        stat = s.get('stat')
         self.SetCellValue(rowi,1,stat)
         self.SetReadOnly(rowi,1)
-        self.SetCellValue(rowi,2,s.getAttribute('rank'))
+        self.SetCellValue(rowi,2,s.get('rank'))
         self.SetCellValue(rowi,3,str(self.stats.get_mod(stat)))
         self.SetReadOnly(rowi,3)
-        self.SetCellValue(rowi,4,s.getAttribute('misc'))
+        self.SetCellValue(rowi,4,s.get('misc'))
         mod = str(self.handler.get_mod(name))
         self.SetCellValue(rowi,5,mod)
         self.SetReadOnly(rowi,5)
@@ -1659,7 +1623,7 @@
 
 class feat_panel(wx.Panel):
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Feats')
+        pname = handler.xml.set("name", 'Feats')
         wx.Panel.__init__(self, parent, -1)
         self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         sizer = wx.BoxSizer(wx.HORIZONTAL)
@@ -1671,9 +1635,9 @@
         self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
         self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
 
-        n_list = handler.master_dom._get_childNodes()
+        n_list = handler.xml[:]
         self.n_list = n_list
-        self.master_dom = handler.master_dom
+        self.xml = handler.xml
         self.grid.CreateGrid(len(n_list),2,1)
         self.grid.SetRowLabelSize(0)
         self.grid.SetColLabelValue(0,"Feat")
@@ -1685,8 +1649,8 @@
 
     def refresh_row(self,i):
         feat = self.n_list[i]
-        name = feat.getAttribute('name')
-        type = feat.getAttribute('type')
+        name = feat.get('name')
+        type = feat.get('type')
         self.grid.SetCellValue(i,0,name)
         self.grid.SetReadOnly(i,0)
         self.grid.SetCellValue(i,1,type)
@@ -1697,28 +1661,25 @@
         for i in range(rows):
             if self.grid.IsInSelection(i,0):
                 self.grid.DeleteRows(i)
-                self.master_dom.removeChild(self.n_list[i])
+                self.xml.removeChild(self.n_list[i])
 
     def on_add(self,evt):
         if not self.temp_dom:
-            tmp = open(orpg.dirpath.dir_struct["d20"]+"d20feats.xml","r")
-            xml_dom = parseXml_with_dlg(self,tmp.read())
-            xml_dom = xml_dom._get_firstChild()
-            tmp.close()
-            self.temp_dom = xml_dom
-        f_list = self.temp_dom.getElementsByTagName('feat')
+            tree = parse(orpg.dirpath.dir_struct["d20"]+"d20feats.xml")
+            self.temp_dom = tree.getroot()
+        f_list = self.temp_dom.findall('feat')
         opts = []
         for f in f_list:
-            opts.append(f.getAttribute('name'))
+            opts.append(f.get('name'))
         dlg = wx.SingleChoiceDialog(self,'Choose Feat','Feats',opts)
         if dlg.ShowModal() == wx.ID_OK:
             i = dlg.GetSelection()
-            new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
+            new_node = self.xml.append(XML(tostring(f_list[i])))
             self.grid.AppendRows(1)
+            self.n_list = self.xml.findall('feat')
             self.refresh_row(self.grid.GetNumberRows()-1)
         dlg.Destroy()
 
-
     def on_size(self,event):
         s = self.GetClientSizeTuple()
         self.grid.SetDimensions(0,0,s[0],s[1]-25)
@@ -1731,7 +1692,7 @@
 
 class spell_panel(wx.Panel):
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Arcane Spells')
+        pname = handler.xml.set("name", 'Arcane Spells')
         wx.Panel.__init__(self, parent, -1)
         self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         self.handler = handler
@@ -1748,9 +1709,9 @@
         self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
         self.Bind(wx.EVT_BUTTON, self.on_refresh_spells, id=30)
         self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
-        n_list = handler.master_dom._get_childNodes()
+        n_list = handler.xml[:]
         self.n_list = n_list
-        self.master_dom = handler.master_dom
+        self.xml = handler.xml
         self.grid.CreateGrid(len(n_list),4,1)
         self.grid.SetRowLabelSize(0)
         self.grid.SetColLabelValue(0,"No.")
@@ -1766,15 +1727,14 @@
         col = evt.GetCol()
         value = self.grid.GetCellValue(row,col)
         if col == 0:
-            self.n_list[row].setAttribute('memrz',value)
-
+            self.n_list[row].set('memrz',value)
 
     def refresh_row(self,i):
         spell = self.n_list[i]
-        memrz = spell.getAttribute('memrz')
-        name = spell.getAttribute('name')
-        type = spell.getAttribute('desc')
-        level = spell.getAttribute('level')
+        memrz = spell.get('memrz')
+        name = spell.get('name')
+        type = spell.get('desc')
+        level = spell.get('level')
         self.grid.SetCellValue(i,0,memrz)
         self.grid.SetCellValue(i,2,name)
         self.grid.SetReadOnly(i,2)
@@ -1788,42 +1748,39 @@
         for i in range(rows):
             if self.grid.IsInSelection(i,0):
                 self.grid.DeleteRows(i)
-                self.master_dom.removeChild(self.n_list[i])
+                self.xml.removeChild(self.n_list[i])
                 self.handler.refresh_spells()
 
     def on_add(self,evt):
         if not self.temp_dom:
-            tmp = open(orpg.dirpath.dir_struct["d20"]+"d20spells.xml","r")
-            xml_dom = parseXml_with_dlg(self,tmp.read())
-            xml_dom = xml_dom._get_firstChild()
-            tmp.close()
-            self.temp_dom = xml_dom
-        f_list = self.temp_dom.getElementsByTagName('spell')
+            tree = parse(orpg.dirpath.dir_struct["d20"]+"d20spells.xml")
+            self.temp_dom = tree.getroot()
+        f_list = self.temp_dom.findall('spell')
         opts = []
         # lvl = int(self.handler.get_char_lvl('level'))
         # castlvl = lvl / 2
         for f in f_list:
-            opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
-            # spelllvl = f.getAttribute('level')
+            opts.append("(" + f.get('level') + ")" + f.get('name'))
+            # spelllvl = f.get('level')
             # if spelllvl <= "1":
-            #     opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
+            #     opts.append("(" + f.get('level') + ")" + f.get('name'))
             # else:
             #     if eval('%d >= %s' %(castlvl, spelllvl)):
-            #         opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
+            #         opts.append("(" + f.get('level') + ")" + f.get('name'))
         dlg = wx.SingleChoiceDialog(self,'Choose Spell','Spells',opts)
         if dlg.ShowModal() == wx.ID_OK:
             i = dlg.GetSelection()
-            new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
+            new_node = self.xml.append(XML(tostring(f_list[i])))
             self.grid.AppendRows(1)
-            self.n_list = self.master_dom.getElementsByTagName('spell')
+            self.n_list = self.xml.findall('spell')
             self.refresh_row(self.grid.GetNumberRows()-1)
             self.handler.refresh_spells()
         dlg.Destroy()
 
     def on_refresh_spells( self, evt ):
-        f_list = self.master_dom.getElementsByTagName('spell')
+        f_list = self.xml.findall('spell')
         for spell in f_list:
-            spell.setAttribute( 'used', '0' )
+            spell.set( 'used', '0' )
 
     def on_size(self,event):
         s = self.GetClientSizeTuple()
@@ -1845,7 +1802,7 @@
 
 class divine_panel(wx.Panel):
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Divine Spells')
+        pname = handler.xml.set("name", 'Divine Spells')
         wx.Panel.__init__(self, parent, -1)
         self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         self.handler = handler
@@ -1862,9 +1819,9 @@
         self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
         self.Bind(wx.EVT_BUTTON, self.on_refresh_spells, id=30)
         self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
-        n_list = handler.master_dom._get_childNodes()
+        n_list = handler.xml[:]
         self.n_list = n_list
-        self.master_dom = handler.master_dom
+        self.xml = handler.xml
         self.grid.CreateGrid(len(n_list),4,1)
         self.grid.SetRowLabelSize(0)
         self.grid.SetColLabelValue(0,"No.")
@@ -1880,15 +1837,15 @@
         col = evt.GetCol()
         value = self.grid.GetCellValue(row,col)
         if col == 0:
-            self.n_list[row].setAttribute('memrz',value)
+            self.n_list[row].set('memrz',value)
 
 
     def refresh_row(self,i):
         spell = self.n_list[i]
-        memrz = spell.getAttribute('memrz')
-        name = spell.getAttribute('name')
-        type = spell.getAttribute('desc')
-        level = spell.getAttribute('level')
+        memrz = spell.get('memrz')
+        name = spell.get('name')
+        type = spell.get('desc')
+        level = spell.get('level')
         self.grid.SetCellValue(i,0,memrz)
         self.grid.SetCellValue(i,2,name)
         self.grid.SetReadOnly(i,2)
@@ -1902,42 +1859,39 @@
         for i in range(rows):
             if self.grid.IsInSelection(i,0):
                 self.grid.DeleteRows(i)
-                self.master_dom.removeChild(self.n_list[i])
+                self.xml.remove(self.n_list[i])
                 self.handler.refresh_spells()
 
     def on_add(self,evt):
         if not self.temp_dom:
-            tmp = open(orpg.dirpath.dir_struct["d20"]+"d20divine.xml","r")
-            xml_dom = parseXml_with_dlg(self,tmp.read())
-            xml_dom = xml_dom._get_firstChild()
-            tmp.close()
-            self.temp_dom = xml_dom
-        f_list = self.temp_dom.getElementsByTagName('gift')
+            tree = parse(orpg.dirpath.dir_struct["d20"]+"d20divine.xml")
+            self.temp_dom = tree.getroot()
+        f_list = self.temp_dom.findall('gift')
         opts = []
         # lvl = int(self.handler.get_char_lvl('level'))
         # castlvl = lvl / 2
         for f in f_list:
-            opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
-            # spelllvl = f.getAttribute('level')
+            opts.append("(" + f.get('level') + ")" + f.get('name'))
+            # spelllvl = f.get('level')
             # if spelllvl <= "1":
-            #     opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
+            #     opts.append("(" + f.get('level') + ")" + f.get('name'))
             # else:
             #     if eval('%d >= %s' %(castlvl, spelllvl)):
-            #         opts.append("(" + f.getAttribute('level') + ")" + f.getAttribute('name'))
+            #         opts.append("(" + f.get('level') + ")" + f.get('name'))
         dlg = wx.SingleChoiceDialog(self,'Choose Spell','Spells',opts)
         if dlg.ShowModal() == wx.ID_OK:
             i = dlg.GetSelection()
-            new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
+            new_node = self.xml.append(XML(tostring(f_list[i])))
             self.grid.AppendRows(1)
-            self.n_list = self.master_dom.getElementsByTagName('gift')
+            self.n_list = self.xml.findall('gift')
             self.refresh_row(self.grid.GetNumberRows()-1)
             self.handler.refresh_spells()
         dlg.Destroy()
 
     def on_refresh_spells( self, evt ):
-        f_list = self.master_dom.getElementsByTagName('gift')
+        f_list = self.xml.findall('gift')
         for spell in f_list:
-            spell.setAttribute( 'used', '0' )
+            spell.set( 'used', '0' )
 
     def on_size(self,event):
         s = self.GetClientSizeTuple()
@@ -1960,7 +1914,7 @@
 
 class power_panel(wx.Panel):
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Pionic Powers')
+        pname = handler.xml.set("name", 'Pionic Powers')
         wx.Panel.__init__(self, parent, -1)
         self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         self.handler = handler
@@ -1976,9 +1930,9 @@
         self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
         self.Bind(wx.EVT_BUTTON, self.on_refresh_powers, id=30)
         self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
-        n_list = handler.master_dom._get_childNodes()
+        n_list = handler.xml[:]
         self.n_list = n_list
-        self.master_dom = handler.master_dom
+        self.xml = handler.xml
         self.grid.CreateGrid(len(n_list),5,1)
         self.grid.SetRowLabelSize(0)
         self.grid.SetColLabelValue(0,"PP")
@@ -1997,16 +1951,16 @@
         col = evt.GetCol()
         value = self.grid.GetCellValue(row,col)
         """if col == 0:
-            self.n_list[row].setAttribute('memrz',value)"""
+            self.n_list[row].set('memrz',value)"""
 
 
     def refresh_row(self,i):
         power = self.n_list[i]
-        point = power.getAttribute('point')
-        name = power.getAttribute('name')
-        type = power.getAttribute('desc')
-        test = power.getAttribute('test')
-        level = power.getAttribute('level')
+        point = power.get('point')
+        name = power.get('name')
+        type = power.get('desc')
+        test = power.get('test')
+        level = power.get('level')
         self.grid.SetCellValue(i,0,point)
         self.grid.SetReadOnly(i,0)
         self.grid.SetCellValue(i,1,level)
@@ -2023,34 +1977,31 @@
         for i in range(rows):
             if self.grid.IsInSelection(i,0):
                 self.grid.DeleteRows(i)
-                self.master_dom.removeChild(self.n_list[i])
+                self.xml.removeChild(self.n_list[i])
                 self.handler.refresh_powers()
 
     def on_add(self,evt):
         if not self.temp_dom:
-            tmp = open(orpg.dirpath.dir_struct["d20"]+"d20powers.xml","r")
-            xml_dom = parseXml_with_dlg(self,tmp.read())
-            xml_dom = xml_dom._get_firstChild()
-            tmp.close()
-            self.temp_dom = xml_dom
-        f_list = self.temp_dom.getElementsByTagName('power')
+            tree = parse(orpg.dirpath.dir_struct["d20"]+"d20powers.xml")
+            self.temp_dom = tree.getroot()
+        f_list = self.temp_dom.findall('power')
         opts = []
         # lvl = int(self.handler.get_char_lvl('level'))
         # castlvl = lvl / 2
         for f in f_list:
-            opts.append("(" + f.getAttribute('level') + ") - " + f.getAttribute('name') + " - " + f.getAttribute('test'))
-            # spelllvl = f.getAttribute('level')
+            opts.append("(" + f.get('level') + ") - " + f.get('name') + " - " + f.get('test'))
+            # spelllvl = f.get('level')
             # if spelllvl <= "1":
-            #     opts.append("(" + f.getAttribute('level') + ") - " + f.getAttribute('name') + " - " + f.getAttribute('test'))
+            #     opts.append("(" + f.get('level') + ") - " + f.get('name') + " - " + f.get('test'))
             # else:
             #     if eval('%d >= %s' %(castlvl, spelllvl)):
-            #         opts.append("(" + f.getAttribute('level') + ") - " + f.getAttribute('name') + " - " + f.getAttribute('test'))
+            #         opts.append("(" + f.get('level') + ") - " + f.get('name') + " - " + f.get('test'))
         dlg = wx.SingleChoiceDialog(self,'Choose Power','Powers',opts)
         if dlg.ShowModal() == wx.ID_OK:
             i = dlg.GetSelection()
-            new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
+            new_node = self.xml.append(XML(tostring(f_list[i])))
             self.grid.AppendRows(1)
-            self.n_list = self.master_dom.getElementsByTagName('power')
+            self.n_list = self.xml.findall('power')
             self.refresh_row(self.grid.GetNumberRows()-1)
             self.handler.refresh_powers()
         dlg.Destroy()
@@ -2060,8 +2011,8 @@
         for i in range(rows):
             if self.grid.IsInSelection(i,0):
                 self.grid.DeleteRows(i)
-                self.master_dom.removeChild(self.n_list[i])
-                self.n_list = self.master_dom.getElementsByTagName('weapon')
+                self.xml.remove(self.n_list[i])
+                self.n_list = self.xml.findall('weapon')
                 self.handler.refresh_weapons()
 
 
@@ -2093,7 +2044,7 @@
 class attack_grid(wx.grid.Grid):
     """grid for attacks"""
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Melee')
+        pname = handler.xml.set("name", 'Melee')
         wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         self.parent = parent
         self.handler = handler
@@ -2117,7 +2068,7 @@
             value = "0"
             self.SetCellValue( row, col, value )
         attribs = ['base','second','third','forth','fifth','sixth','misc']
-        self.babs.setAttribute( attribs[col], value )
+        self.babs.set( attribs[col], value )
         self.parent.refresh_data()
 
     def refresh_data(self):
@@ -2136,7 +2087,7 @@
 
 class weapon_panel(wx.Panel):
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Weapons')
+        pname = handler.xml.set("name", 'Weapons')
         wx.Panel.__init__(self, parent, -1)
         self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         sizer = wx.BoxSizer(wx.HORIZONTAL)
@@ -2148,9 +2099,9 @@
         self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
         self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
         self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
-        n_list = handler.master_dom.getElementsByTagName('weapon')
+        n_list = handler.xml.findall('weapon')
         self.n_list = n_list
-        self.master_dom = handler.master_dom
+        self.xml = handler.xml
         self.handler = handler
         self.grid.CreateGrid(len(n_list),8,1)
         self.grid.SetRowLabelSize(0)
@@ -2166,51 +2117,48 @@
         col = evt.GetCol()
         value = self.grid.GetCellValue(row,col)
         if col == 0:
-            self.n_list[row].setAttribute('name',value)
+            self.n_list[row].set('name',value)
             self.handler.refresh_weapons();
         else:
-            self.n_list[row].setAttribute(self.grid.GetColLabelValue(col),value)
+            self.n_list[row].set(self.grid.GetColLabelValue(col),value)
 
     def refresh_row(self,i):
         n = self.n_list[i]
-        name = n.getAttribute('name')
-        mod = n.getAttribute('mod')
-        ran = n.getAttribute('range')
+        name = n.get('name')
+        mod = n.get('mod')
+        ran = n.get('range')
         self.grid.SetCellValue(i,0,name)
-        self.grid.SetCellValue(i,1,n.getAttribute('damage'))
+        self.grid.SetCellValue(i,1,n.get('damage'))
         self.grid.SetCellValue(i,2,mod)
-        self.grid.SetCellValue(i,3,n.getAttribute('critical'))
-        self.grid.SetCellValue(i,4,n.getAttribute('type'))
-        self.grid.SetCellValue(i,5,n.getAttribute('weight'))
+        self.grid.SetCellValue(i,3,n.get('critical'))
+        self.grid.SetCellValue(i,4,n.get('type'))
+        self.grid.SetCellValue(i,5,n.get('weight'))
         self.grid.SetCellValue(i,6,ran)
-        self.grid.SetCellValue(i,7,n.getAttribute('size') )
+        self.grid.SetCellValue(i,7,n.get('size') )
 
     def on_remove(self,evt):
         rows = self.grid.GetNumberRows()
         for i in range(rows):
             if self.grid.IsInSelection(i,0):
                 self.grid.DeleteRows(i)
-                self.master_dom.removeChild(self.n_list[i])
-                self.n_list = self.master_dom.getElementsByTagName('weapon')
+                self.xml.remove(self.n_list[i])
+                self.n_list = self.xml.findall('weapon')
                 self.handler.refresh_weapons()
 
     def on_add(self,evt):
         if not self.temp_dom:
-            tmp = open(orpg.dirpath.dir_struct["d20"]+"d20weapons.xml","r")
-            xml_dom = parseXml_with_dlg(self,tmp.read())
-            xml_dom = xml_dom._get_firstChild()
-            tmp.close()
-            self.temp_dom = xml_dom
-        f_list = self.temp_dom.getElementsByTagName('weapon')
+            tree = parse(orpg.dirpath.dir_struct["d20"]+"d20weapons.xml")
+            self.temp_dom = tree.getroot()
+        f_list = self.temp_dom.findall('weapon')
         opts = []
         for f in f_list:
-            opts.append(f.getAttribute('name'))
+            opts.append(f.get('name'))
         dlg = wx.SingleChoiceDialog(self,'Choose Weapon','Weapon List',opts)
         if dlg.ShowModal() == wx.ID_OK:
             i = dlg.GetSelection()
-            new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
+            new_node = self.xml.append(XML(tostring(f_list[i])))
             self.grid.AppendRows(1)
-            self.n_list = self.master_dom.getElementsByTagName('weapon')
+            self.n_list = self.xml.findall('weapon')
             self.refresh_row(self.grid.GetNumberRows()-1)
             self.handler.refresh_weapons()
         dlg.Destroy()
@@ -2233,7 +2181,7 @@
 
 class attack_panel(wx.Panel):
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Melee')
+        pname = handler.xml.set("name", 'Melee')
         wx.Panel.__init__(self, parent, -1)
 
         self.a_grid = attack_grid(self, handler)
@@ -2255,7 +2203,7 @@
 
 class ac_panel(wx.Panel):
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Armor')
+        pname = handler.xml.set("name", 'Armor')
         wx.Panel.__init__(self, parent, -1)
         self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         sizer = wx.BoxSizer(wx.HORIZONTAL)
@@ -2267,8 +2215,8 @@
         self.Bind(wx.EVT_BUTTON, self.on_remove, id=10)
         self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
         self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
-        self.master_dom = handler.master_dom
-        n_list = handler.master_dom._get_childNodes()
+        self.xml = handler.xml
+        n_list = handler.xml[:]
         self.n_list = n_list
         col_names = ['Armor','bonus','maxdex','cp','sf','weight','speed','type']
         self.grid.CreateGrid(len(n_list),len(col_names),1)
@@ -2288,43 +2236,42 @@
         if col >= 1 and col <= 5:
             try:
                 int(value)
-                self.n_list[row].setAttribute(self.atts[col],value)
+                self.n_list[row].set(self.atts[col],value)
             except:
                 self.grid.SetCellValue(row,col,"0")
         else:
-            self.n_list[row].setAttribute(self.atts[col],value)
+            self.n_list[row].set(self.atts[col],value)
 
     def refresh_row(self,i):
         n = self.n_list[i]
         for y in range(len(self.atts)):
-            self.grid.SetCellValue(i,y,n.getAttribute(self.atts[y]))
+            self.grid.SetCellValue(i,y,n.get(self.atts[y]))
 
     def on_remove(self,evt):
         rows = self.grid.GetNumberRows()
         for i in range(rows):
             if self.grid.IsInSelection(i,0):
                 self.grid.DeleteRows(i)
-                self.master_dom.removeChild(self.n_list[i])
+                self.xml.remove(self.n_list[i])
 
     def on_add(self,evt):
         if not self.temp_dom:
-            tmp = open(orpg.dirpath.dir_struct["d20"]+"d20armor.xml","r")
-            xml_dom = parseXml_with_dlg(self,tmp.read())
-            xml_dom = xml_dom._get_firstChild()
-            tmp.close()
-            self.temp_dom = xml_dom
-        f_list = self.temp_dom.getElementsByTagName('armor')
+            tree = parse(orpg.dirpath.dir_struct["d20"]+"d20armor.xml")
+            self.temp_dom = tree.getroot()
+        f_list = self.temp_dom.findall('armor')
         opts = []
         for f in f_list:
-            opts.append(f.getAttribute('name'))
+            opts.append(f.get('name'))
         dlg = wx.SingleChoiceDialog(self,'Choose Armor:','Armor List',opts)
         if dlg.ShowModal() == wx.ID_OK:
             i = dlg.GetSelection()
-            new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
+            new_node = self.xml.append(XML(tostring(f_list[i])))
             self.grid.AppendRows(1)
+            self.n_list = self.xml.findall('armor')
             self.refresh_row(self.grid.GetNumberRows()-1)
         dlg.Destroy()
 
+
     def on_size(self,event):
         s = self.GetClientSizeTuple()
         self.grid.SetDimensions(0,0,s[0],s[1]-25)
@@ -2339,7 +2286,7 @@
 
 class class_panel(wx.Panel):
     def __init__(self, parent, handler):
-        pname = handler.master_dom.setAttribute("name", 'Class')
+        pname = handler.xml.set("name", 'Class')
         wx.Panel.__init__(self, parent, -1)
         self.grid =wx.grid.Grid(self, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
         sizer = wx.BoxSizer(wx.HORIZONTAL)
@@ -2353,9 +2300,9 @@
         self.Bind(wx.EVT_BUTTON, self.on_add, id=20)
         self.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
 
-        n_list = handler.master_dom._get_childNodes()
+        n_list = handler.xml[:]
         self.n_list = n_list
-        self.master_dom = handler.master_dom
+        self.xml = handler.xml
         self.grid.CreateGrid(len(n_list),2,1)
         self.grid.SetRowLabelSize(0)
         self.grid.SetColLabelValue(0,"Class")
@@ -2370,15 +2317,14 @@
         value = self.grid.GetCellValue(row,col)
         try:
             int(value)
-            self.n_list[row].setAttribute('level',value)
+            self.n_list[row].set('level',value)
         except:
             self.grid.SetCellValue(row,col,"1")
 
-
     def refresh_row(self,i):
         n = self.n_list[i]
-        name = n.getAttribute('name')
-        level = n.getAttribute('level')
+        name = n.get('name')
+        level = n.get('level')
         self.grid.SetCellValue(i,0,name)
         self.grid.SetReadOnly(i,0)
         self.grid.SetCellValue(i,1,level)
@@ -2389,28 +2335,25 @@
         for i in range(rows):
             if self.grid.IsInSelection(i,0):
                 self.grid.DeleteRows(i)
-                self.master_dom.removeChild(self.n_list[i])
+                self.xml.remove(self.n_list[i])
 
     def on_add(self,evt):
         if not self.temp_dom:
-            tmp = open(orpg.dirpath.dir_struct["d20"]+"d20classes.xml","r")
-            xml_dom = parseXml_with_dlg(self,tmp.read())
-            xml_dom = xml_dom._get_firstChild()
-            tmp.close()
-            self.temp_dom = xml_dom
-        f_list = self.temp_dom.getElementsByTagName('class')
+            tree = parse(orpg.dirpath.dir_struct["d20"]+"d20classes.xml")
+            self.temp_dom = tree.getroot()
+        f_list = self.temp_dom.findall('class')
         opts = []
         for f in f_list:
-            opts.append(f.getAttribute('name'))
+            opts.append(f.get('name'))
         dlg = wx.SingleChoiceDialog(self,'Choose Class','Classes',opts)
         if dlg.ShowModal() == wx.ID_OK:
             i = dlg.GetSelection()
-            new_node = self.master_dom.appendChild(f_list[i].cloneNode(False))
+            new_node = self.xml.append(XML(tostring(f_list[i])))
             self.grid.AppendRows(1)
+            self.n_list = self.xml.findall('class')
             self.refresh_row(self.grid.GetNumberRows()-1)
         dlg.Destroy()
 
-
     def on_size(self,event):
         s = self.GetClientSizeTuple()
         self.grid.SetDimensions(0,0,s[0],s[1]-25)
--- a/orpg/gametree/nodehandlers/forms.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/gametree/nodehandlers/forms.py	Wed Oct 28 14:24:54 2009 -0500
@@ -39,10 +39,8 @@
     #if it was an int already, nothing changes. The difference between 1.0
     #and 1, i.e. between ints and floats, is potentially dangerous when we
     #use str() on it, but it seems to work fine right now.
-    if b:
-        return 1
-    else:
-        return 0
+    if b: return 1
+    else: return 0
 
 #################################
 ## form container
@@ -54,23 +52,19 @@
             <form width='100' height='100' />
             </nodehandler>
     """
-
-    def __init__(self,xml_dom,tree_node):
-        container_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self,xml,tree_node):
+        container_handler.__init__(self,xml,tree_node)
 
     def load_children(self):
         self.atts = None
-        children = self.master_dom._get_childNodes()
-        for c in children:
-            if c._get_tagName() == "form":
-                self.atts = c
-            else:
-                self.tree.load_xml(c,self.mytree_node)
+        for child_xml in self.xml:
+            if child_xml.tag == "form": self.atts = child_xml
+            else: self.tree.load_xml(child_xml,self.mytree_node)
         if not self.atts:
-            elem = minidom.Element('form')
-            elem.setAttribute("width","400")
-            elem.setAttribute("height","600")
-            self.atts = self.master_dom.appendChild(elem)
+            self.atts = Element('form')
+            self.atts.set("width","400")
+            self.atts.set("height","600")
+            self.xml.append(self.atts)
 
     def get_design_panel(self,parent):
         return form_edit_panel(parent,self)
@@ -82,29 +76,22 @@
         # make sure its a contorl node
         container_handler.on_drop(self,evt)
 
-
 class form_panel(ScrolledPanel):
     def __init__(self, parent, handler):
         ScrolledPanel.__init__(self, parent, wx.ID_ANY, style=wx.NO_BORDER|wx.VSCROLL|wx.HSCROLL)
-        self.height = int(handler.atts.getAttribute("height"))
-        self.width = int(handler.atts.getAttribute("width"))
-        
+        self.height = int(handler.atts.get("height"))
+        self.width = int(handler.atts.get("width"))
         self.SetSize((0,0))
         self.handler = handler
         self.parent = parent
         self.main_sizer = wx.BoxSizer(wx.VERTICAL)
-        tree = self.handler.tree
-        handler.traverse(handler.mytree_node, self.create_child_wnd, None, False)
-
+        handler.tree.traverse(handler.mytree_node, self.create_child_wnd, None, False)
         self.SetSizer(self.main_sizer)
         self.SetAutoLayout(True)
-
         self.SetupScrolling()
-
         parent.SetSize(self.GetSize())
         self.Fit()
 
-
     def SetSize(self, xy):
         (x, y) = self.GetSize()
         (nx, ny) = xy
@@ -113,16 +100,14 @@
         y += ny+11
         ScrolledPanel.SetSize(self, (x, y))
 
-
-    def create_child_wnd(self, obj, evt):
-        panel = obj.get_use_panel(self)
-        size = obj.get_size_constraint()
+    def create_child_wnd(self, treenode, evt):
+        node = self.handler.tree.GetPyData(treenode)
+        panel = node.get_use_panel(self)
+        size = node.get_size_constraint()
         if panel:
             self.main_sizer.Add(panel, size, wx.EXPAND)
             self.main_sizer.Add(wx.Size(10,10))
 
-
-
 F_HEIGHT = wx.NewId()
 F_WIDTH = wx.NewId()
 class form_edit_panel(wx.Panel):
@@ -131,9 +116,9 @@
         self.handler = handler
         sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Form Properties"), wx.VERTICAL)
         wh_sizer = wx.BoxSizer(wx.HORIZONTAL)
-        self.text = {   P_TITLE : wx.TextCtrl(self, P_TITLE, handler.master_dom.getAttribute('name')),
-                        F_HEIGHT : wx.TextCtrl(self, F_HEIGHT, handler.atts.getAttribute('height')),
-                        F_WIDTH : wx.TextCtrl(self, F_WIDTH, handler.atts.getAttribute('width'))
+        self.text = {   P_TITLE : wx.TextCtrl(self, P_TITLE, handler.xml.get('name')),
+                        F_HEIGHT : wx.TextCtrl(self, F_HEIGHT, handler.atts.get('height')),
+                        F_WIDTH : wx.TextCtrl(self, F_WIDTH, handler.atts.get('width'))
                       }
 
         wh_sizer.Add(wx.StaticText(self, -1, "Width:"), 0, wx.ALIGN_CENTER)
@@ -163,21 +148,13 @@
         txt = self.text[id].GetValue()
         if not len(txt): return
         if id == P_TITLE:
-            self.handler.master_dom.setAttribute('name',txt)
+            self.handler.xml.set('name',txt)
             self.handler.rename(txt)
         elif id == F_HEIGHT or id == F_WIDTH:
-            try:
-                int(txt)
-            except:
-                return 0
-            if id == F_HEIGHT:
-                self.handler.atts.setAttribute("height",txt)
-            elif id == F_WIDTH:
-                self.handler.atts.setAttribute("width",txt)
-
-
-
-
+            try: int(txt)
+            except: return 0
+            if id == F_HEIGHT: self.handler.atts.set("height",txt)
+            elif id == F_WIDTH: self.handler.atts.set("width",txt)
 
 ##########################
 ## control handler
@@ -186,13 +163,12 @@
     """ A nodehandler for form controls.
         <nodehandler name='?' module='forms' class='control_handler' />
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self, xml, tree_node):
+        node_handler.__init__(self, xml, tree_node)
 
     def get_size_constraint(self):
         return 0
 
-
 ##########################
 ## textctrl handler
 ##########################
@@ -207,16 +183,15 @@
            <text multiline='0' send_button='0' raw_mode='0' hide_title='0'>Text In Node</text>
         </nodehandler>
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
-        self.text_elem = self.master_dom.getElementsByTagName('text')[0]
-        self.text = component.get('xml').safe_get_text_node(self.text_elem)
-        if self.text_elem.getAttribute("send_button") == "":
-            self.text_elem.setAttribute("send_button","0")
-        if self.text_elem.getAttribute("raw_mode") == "":
-            self.text_elem.setAttribute("raw_mode","0")
-        if self.text_elem.getAttribute("hide_title") == "":
-            self.text_elem.setAttribute("hide_title","0")
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
+        self.text_elem = self.xml.find('text')
+        if self.text_elem.get("send_button") == "":
+            self.text_elem.set("send_button","0")
+        if self.text_elem.get("raw_mode") == "":
+            self.text_elem.set("raw_mode","0")
+        if self.text_elem.get("hide_title") == "":
+            self.text_elem.set("hide_title","0")
 
     def get_design_panel(self,parent):
         return textctrl_edit_panel(parent,self)
@@ -225,28 +200,32 @@
         return text_panel(parent,self)
 
     def get_size_constraint(self):
-        return int(self.text_elem.getAttribute("multiline"))
+        return int(self.text_elem.get("multiline",0))
 
     def is_multi_line(self):
-        return int(self.text_elem.getAttribute("multiline"))
+        return int(self.text_elem.get("multiline",0))
 
     def is_raw_send(self):
-        return int(self.text_elem.getAttribute("raw_mode"))
+        return int(self.text_elem.get("raw_mode",0))
 
     def is_hide_title(self):
-        return int(self.text_elem.getAttribute("hide_title"))
+        return int(self.text_elem.get("hide_title",0))
 
     def has_send_button(self):
-        return int(self.text_elem.getAttribute("send_button"))
-
+        return int(self.text_elem.get("send_button",0))
 
     def tohtml(self):
-        txt = self.text._get_nodeValue()
+        txt = self.get_value()
         txt = string.replace(txt,'\n',"<br />")
         if not self.is_hide_title():
-            txt = "<b>"+self.master_dom.getAttribute("name")+":</b> "+txt
+            txt = "<b>"+self.xml.get("name")+":</b> "+txt
         return txt
 
+    def get_value(self):
+        return self.text_elem.text
+
+    def set_value(self, new_value):
+        self.text_elem.text = str(new_value)
 
 FORM_TEXT_CTRL = wx.NewId()
 FORM_SEND_BUTTON = wx.NewId()
@@ -265,9 +244,10 @@
             text_style = 0
             sizer = wx.BoxSizer(wx.HORIZONTAL)
 
-        txt = handler.text._get_nodeValue()
+        txt = handler.get_value()
+        if txt == None: txt = ''
         self.text = wx.TextCtrl(self, FORM_TEXT_CTRL, txt, style=text_style)
-        sizer.Add(wx.StaticText(self, -1, handler.master_dom.getAttribute('name')+": "), 0, sizer_style)
+        sizer.Add(wx.StaticText(self, -1, handler.xml.get('name')+": "), 0, sizer_style)
         sizer.Add(wx.Size(5,0))
         sizer.Add(self.text, 1, sizer_style)
 
@@ -284,8 +264,8 @@
 
     def on_text(self,evt):
         txt = self.text.GetValue()
-        txt = xml.strip_text(txt)
-        self.handler.text._set_nodeValue(txt)
+        txt = strip_text(txt)
+        self.handler.text_elem.text = txt
 
     def on_send(self,evt):
         txt = self.text.GetValue()
@@ -315,7 +295,7 @@
         self.handler = handler
         sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Text Properties"), wx.VERTICAL)
 
-        self.title = wx.TextCtrl(self, P_TITLE, handler.master_dom.getAttribute('name'))
+        self.title = wx.TextCtrl(self, P_TITLE, handler.xml.get('name'))
         self.multi = wx.CheckBox(self, F_MULTI, " Multi-Line")
         self.multi.SetValue(handler.is_multi_line())
         self.raw_send = wx.CheckBox(self, F_RAW_SEND, " Send as Macro")
@@ -341,7 +321,7 @@
             sizer_style=wx.EXPAND
             text_style = 0
             multi = 0
-        self.text = wx.TextCtrl(self, F_TEXT, handler.text._get_nodeValue(),style=text_style)
+        self.text = wx.TextCtrl(self, F_TEXT, handler.get_value(),style=text_style)
         sizer.Add(wx.Size(5,0))
         sizer.Add(self.text, multi, sizer_style)
         self.SetSizer(sizer)
@@ -359,28 +339,24 @@
         if id == P_TITLE:
             txt = self.title.GetValue()
             if not len(txt): return
-            self.handler.master_dom.setAttribute('name',txt)
+            self.handler.xml.set('name',txt)
             self.handler.rename(txt)
         if id == F_TEXT:
             txt = self.text.GetValue()
-            txt = xml.strip_text(txt)
-            self.handler.text._set_nodeValue(txt)
+            txt = strip_text(txt)
+            self.handler.text_elem.text = txt
 
     def on_button(self,evt):
-        self.handler.text_elem.setAttribute("multiline",str(bool2int(evt.Checked())))
+        self.handler.text_elem.set("multiline",str(bool2int(evt.Checked())))
 
     def on_raw_button(self,evt):
-        self.handler.text_elem.setAttribute("raw_mode",str(bool2int(evt.Checked())))
+        self.handler.text_elem.set("raw_mode",str(bool2int(evt.Checked())))
 
     def on_hide_button(self,evt):
-        self.handler.text_elem.setAttribute("hide_title",str(bool2int(evt.Checked())))
+        self.handler.text_elem.set("hide_title",str(bool2int(evt.Checked())))
 
     def on_send_button(self,evt):
-        self.handler.text_elem.setAttribute("send_button",str(bool2int(evt.Checked())))
-
-
-
-
+        self.handler.text_elem.set("send_button",str(bool2int(evt.Checked())))
 
 
 #######################
@@ -406,14 +382,14 @@
         </list>
     </nodehandler>
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
-        self.list = self.master_dom.getElementsByTagName('list')[0]
-        self.options = self.list.getElementsByTagName('option')
-        if self.list.getAttribute("send_button") == "":
-            self.list.setAttribute("send_button","0")
-        if self.list.getAttribute("hide_title") == "":
-            self.list.setAttribute("hide_title","0")
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
+        self.list = self.xml.find('list')
+        self.options = self.list.findall('option')
+        if self.list.get("send_button") == "":
+            self.list.set("send_button","0")
+        if self.list.get("hide_title") == "":
+            self.list.set("hide_title","0")
 
     def get_design_panel(self,parent):
         return listbox_edit_panel(parent,self)
@@ -422,24 +398,24 @@
         return listbox_panel(parent,self)
 
     def get_type(self):
-        return int(self.list.getAttribute("type"))
+        return int(self.list.get("type"))
 
     def set_type(self,type):
-        self.list.setAttribute("type",str(type))
+        self.list.set("type",str(type))
 
     def is_hide_title(self):
-        return int(self.list.getAttribute("hide_title"))
+        return int(self.list.get("hide_title", 0))
 
     # single selection methods
     def get_selected_node(self):
         for opt in self.options:
-            if opt.getAttribute("selected") == "1": return opt
+            if opt.get("selected") == "1": return opt
         return None
 
     def get_selected_index(self):
         i = 0
         for opt in self.options:
-            if opt.getAttribute("selected") == "1":
+            if opt.get("selected") == "1":
                 return i
             i += 1
         return 0
@@ -447,7 +423,7 @@
     def get_selected_text(self):
         node = self.get_selected_node()
         if node:
-            return component.get('xml').safe_get_text_node(node)._get_nodeValue()
+            return node.text
         else:
             return ""
 
@@ -457,22 +433,22 @@
     def get_selections(self):
         opts = []
         for opt in self.options:
-            if opt.getAttribute("selected") == "1":
+            if opt.get("selected") == "1":
                 opts.append(opt)
         return opts
 
     def get_selections_text(self):
         opts = []
         for opt in self.options:
-            if opt.getAttribute("selected") == "1":
-                opts.append(component.get('xml').safe_get_text_node(opt)._get_nodeValue())
+            if opt.get("selected") == "1":
+                opts.append(opt.text)
         return opts
 
     def get_selections_index(self):
         opts = []
         i = 0
         for opt in self.options:
-            if opt.getAttribute("selected") == "1":
+            if opt.get("selected") == "1":
                 opts.append(i)
             i += 1
         return opts
@@ -482,41 +458,40 @@
     def set_selected_node(self,index,selected=1):
         if self.get_type() != L_CHECK:
             self.clear_selections()
-        self.options[index].setAttribute("selected", str(bool2int(selected)))
+        self.options[index].set("selected", str(bool2int(selected)))
 
     def clear_selections(self):
         for opt in self.options:
-            opt.setAttribute("selected","0")
+            opt.set("selected","0")
 
     # misc methods
 
     def get_options(self):
         opts = []
         for opt in self.options:
-            opts.append(component.get('xml').safe_get_text_node(opt)._get_nodeValue())
+            opts.append(opt.text)
         return opts
 
     def get_option(self,index):
-        return component.get('xml').safe_get_text_node(self.options[index])._get_nodeValue()
+        return self.options[index].text
 
     def add_option(self,opt):
-        elem = minidom.Element('option')
-        elem.setAttribute("value","0")
-        elem.setAttribute("selected","0")
-        t_node = minidom.Text(opt)
-        t_node = elem.appendChild(t_node)
-        self.list.appendChild(elem)
-        self.options = self.list.getElementsByTagName('option')
+        elem = Element('option')
+        elem.set("value","0")
+        elem.set("selected","0")
+        elem.text = opt
+        self.list.append(elem)
+        self.options = self.list.findall('option')
 
     def remove_option(self,index):
-        self.list.removeChild(self.options[index])
-        self.options = self.list.getElementsByTagName('option')
+        self.list.remove(self.options[index])
+        self.options = self.list.findall('option')
 
     def edit_option(self,index,value):
-        component.get('xml').safe_get_text_node(self.options[index])._set_nodeValue(value)
+        self.options[index].text = value
 
     def has_send_button(self):
-        if self.list.getAttribute("send_button") == '0':
+        if self.list.get("send_button") == '0':
             return False
         else:
             return True
@@ -531,11 +506,13 @@
         opts = self.get_selections_text()
         text = ""
         if not self.is_hide_title():
-            text = "<b>"+self.master_dom.getAttribute("name")+":</b> "
+            text = "<b>"+self.xml.get("name")+":</b> "
         comma = ", "
         text += comma.join(opts)
         return text
 
+    def get_value(self):
+        return "\n".join(self.get_selections_text())
 
 
 F_LIST = wx.NewId()
@@ -550,7 +527,7 @@
         opts = handler.get_options()
         cur_opt = handler.get_selected_text()
         type = handler.get_type()
-        label = handler.master_dom.getAttribute('name')
+        label = handler.xml.get('name')
 
         if type == L_DROP:
             self.list = wx.ComboBox(self, F_LIST, cur_opt, choices=opts, style=wx.CB_READONLY)
@@ -632,7 +609,7 @@
         self.handler = handler
         sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "List Box Properties"), wx.VERTICAL)
 
-        self.text = wx.TextCtrl(self, P_TITLE, handler.master_dom.getAttribute('name'))
+        self.text = wx.TextCtrl(self, P_TITLE, handler.xml.get('name'))
 
         opts = handler.get_options()
         self.listbox = wx.ListBox(self, F_LIST, choices=opts, style=wx.LB_HSCROLL|wx.LB_SINGLE|wx.LB_NEEDED_SB)
@@ -714,15 +691,14 @@
         txt = self.text.GetValue()
         if not len(txt): return
         if id == P_TITLE:
-            self.handler.master_dom.setAttribute('name',txt)
+            self.handler.xml.set('name',txt)
             self.handler.rename(txt)
 
     def on_send_button(self,evt):
-        self.handler.list.setAttribute("send_button", str( bool2int(evt.Checked()) ))
+        self.handler.list.set("send_button", str( bool2int(evt.Checked()) ))
 
     def on_hide_button(self,evt):
-        print "hide_title, " + str(bool2int(evt.Checked()))
-        self.handler.list.setAttribute("hide_title", str( bool2int(evt.Checked()) ))
+        self.handler.list.set("hide_title", str( bool2int(evt.Checked()) ))
 
 
 ###############################
@@ -735,12 +711,12 @@
                 <link  href='http//??.??'  />
         </nodehandler >
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
-        self.link = self.master_dom._get_firstChild()
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
+        self.link = self.xml[0]
 
     def on_use(self,evt):
-        href = self.link.getAttribute("href")
+        href = self.link.get("href")
         wb = webbrowser.get()
         wb.open(href)
 
@@ -751,14 +727,14 @@
         return link_panel(parent,self)
 
     def tohtml(self):
-        href = self.link.getAttribute("href")
-        title = self.master_dom.getAttribute("name")
+        href = self.link.get("href")
+        title = self.xml.get("name")
         return "<a href=\""+href+"\" >"+title+"</a>"
 
 class link_panel(wx.StaticText):
     def __init__(self,parent,handler):
         self.handler = handler
-        label = handler.master_dom.getAttribute('name')
+        label = handler.xml.get('name')
         wx.StaticText.__init__(self,parent,-1,label)
         self.SetForegroundColour(wx.BLUE)
         self.Bind(wx.EVT_LEFT_DOWN, self.handler.on_use)
@@ -773,8 +749,8 @@
         sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Link Properties"), wx.VERTICAL)
 
         self.text = {}
-        self.text[P_TITLE] = wx.TextCtrl(self, P_TITLE, handler.master_dom.getAttribute('name'))
-        self.text[P_URL] = wx.TextCtrl(self, P_URL, handler.link.getAttribute('href'))
+        self.text[P_TITLE] = wx.TextCtrl(self, P_TITLE, handler.xml.get('name'))
+        self.text[P_URL] = wx.TextCtrl(self, P_URL, handler.link.get('href'))
 
         sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND)
         sizer.Add(self.text[P_TITLE], 0, wx.EXPAND)
@@ -790,10 +766,10 @@
         txt = self.text[id].GetValue()
         if not len(txt): return
         if id == P_TITLE:
-            self.handler.master_dom.setAttribute('name',txt)
+            self.handler.xml.set('name',txt)
             self.handler.rename(txt)
         elif id == P_URL:
-            self.handler.link.setAttribute('href',txt)
+            self.handler.link.set('href',txt)
 
 ##########################
 ## webimg node handler
@@ -804,21 +780,20 @@
                 <link  href='http//??.??'  />
         </nodehandler >
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
-        self.link = self.master_dom._get_firstChild()
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
+        self.link = self.xml[0]
 
     def get_design_panel(self,parent):
         return link_edit_panel(parent,self)
 
     def get_use_panel(self,parent):
-        img = img_helper().load_url(self.link.getAttribute("href"))
-        #print img
+        img = img_helper().load_url(self.link.get("href"))
         if not img is None:
             return wx.StaticBitmap(parent,-1,img,size= wx.Size(img.GetWidth(),img.GetHeight()))
         return wx.EmptyBitmap(1, 1)
 
     def tohtml(self):
-        href = self.link.getAttribute("href")
-        title = self.master_dom.getAttribute("name")
+        href = self.link.get("href")
+        title = self.xml.get("name")
         return "<img src=\""+href+"\" alt="+title+" >"
--- a/orpg/gametree/nodehandlers/map_miniature_nodehandler.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/gametree/nodehandlers/map_miniature_nodehandler.py	Wed Oct 28 14:24:54 2009 -0500
@@ -42,17 +42,15 @@
     """
 
 
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
         self.mapper = component.get("map")
         self.session = component.get("session")
-        self.miniature_dom = self.master_dom.getElementsByTagName("miniature")
-        if self.miniature_dom:
-            self.miniature_dom = self.miniature_dom[0]   # convert to scalar
-
+        self.miniature_xml = self.xml.find("miniature")
+        
     def get_scaled_bitmap(self,x,y):
         my_mini_msg = mini_msg()
-        my_mini_msg.init_from_dom(self.miniature_dom)
+        my_mini_msg.init_from_dom(self.miniature_xml)
         bmp = None
         path = my_mini_msg.get_prop("path")
 
@@ -61,11 +59,11 @@
             if ImageHandler.Cache.has_key(path):
                 bmp = ImageHandler.Cache[path]
             else:
-                #bmp = ImageHandler.directLoad(path, 'miniature', id)
+                #bmp = ImageHandler.directLoad(path, 'miniature', id)
                 bmp = ImageHandler.directLoad(path)# Old Code TaS.
 
             if bmp:
-                img = wx.ImageFromMime(ImageHandler.Cache[path][1], ImageHandler.Cache[path][2])
+                img = wx.ImageFromMime(ImageHandler.Cache[path][1], ImageHandler.Cache[path][2])
                 #img = wx.ImageFromBitmap(bmp)
                 scaled_img = img.Scale(x,y)
                 scaled_bmp = scaled_img.ConvertToBitmap()
@@ -89,9 +87,9 @@
 
     def get_miniature_XML(self):
         my_mini_msg = mini_msg()
-        my_mini_msg.init_from_dom(self.miniature_dom)
+        my_mini_msg.init_from_dom(self.miniature_xml)
         my_mini_msg.init_prop("id",self.session.get_next_id())
-        label = self.master_dom.getAttribute("name")
+        label = self.xml.get("name")
         my_mini_msg.init_prop("label",label)
         new_xml = my_mini_msg.get_all_xml()
         return new_xml
@@ -109,14 +107,14 @@
             dc.SetUserScale(grid.mapscale, grid.mapscale)
             pos = evt.GetLogicalPosition(dc)
             try:
-                align = int(self.miniature_dom.getAttribute("align"))
-                width = int(self.miniature_dom.getAttribute("width"))
-                height = int(self.miniature_dom.getAttribute("height"))
+                align = int(self.xml.get("align"))
+                width = int(self.xml.get("width"))
+                height = int(self.xml.get("height"))
                 pos = grid.get_snapped_to_pos(pos, align, width, height)
             except:
                 pass
-            self.miniature_dom.setAttribute("posx", str(pos.x))
-            self.miniature_dom.setAttribute("posy", str(pos.y))
+            self.miniature_xml.set("posx", str(pos.x))
+            self.miniature_xml.set("posy", str(pos.y))
         new_xml = self.get_to_map_XML()
         if (self.session.my_role() != self.session.ROLE_GM) and (self.session.my_role() != self.session.ROLE_PLAYER):
             component.get("chat").InfoPost("You must be either a player or GM to use the miniature Layer")
@@ -133,7 +131,7 @@
 
     def tohtml(self):
         html_str = "<table><tr><td>"
-        html_str += "<center><img src='" + self.miniature_dom.getAttribute("path") + "'>"
+        html_str += "<center><img src='" + self.xml.get("path") + "'>"
         html_str += "</center></td></tr>\n"
-        html_str += "<tr><td><center>" + self.master_dom.getAttribute("name") + "</center></td></tr></table>"
-        return html_str
+        html_str += "<tr><td><center>" + self.xml.get("name") + "</center></td></tr></table>"
+        return html_str
\ No newline at end of file
--- a/orpg/gametree/nodehandlers/minilib.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/gametree/nodehandlers/minilib.py	Wed Oct 28 14:24:54 2009 -0500
@@ -35,8 +35,8 @@
 from orpg.dirpath import dir_struct
 import string
 import map_miniature_nodehandler
-import orpg.mapper.map_msg
-import orpg.minidom as minidom
+import orpg.mapper.map_msg
+import orpg.minidom as minidom
 # import scriptkit
 
 # Constants
@@ -68,15 +68,13 @@
         &lt;/nodehandler&gt;
     </pre>
     """
-    def __init__(self, xml_dom, tree_node):
+    def __init__(self, xml, tree_node):
         """Instantiates the class, and sets all vars to their default state
         """
-        node_handler.__init__(self, xml_dom, tree_node)
-
+        node_handler.__init__(self, xml, tree_node)
         self.myeditor = None
         self.mywindow = None
         self.tree_node = tree_node
-        # self.xml_dom = xml_dom
         self.update_leaves()
         self.sanity_check_nodes()
 
@@ -101,17 +99,15 @@
         expecting for a given column.
         """
         str = '<table border="2" >'
-        list = self.master_dom.getElementsByTagName(TAG_MINIATURE)
-        str += "<tr><th width='20%'>Label</th><th>Image</th><th width='65%'>URL</th><th>Unique</th></t>"
-        for mini in list:
-            url = mini.getAttribute(ATTRIBUTE_URL)
-            label = mini.getAttribute(ATTRIBUTE_NAME)
+        str += "<tr><th width='20%'>Label</th><th>Image</th><th width='65%'>URL</th><th>Unique</th></tr>"
+        for mini in self.xml.findall(TAG_MINIATURE):
+            url = mini.get(ATTRIBUTE_URL)
+            label = mini.get(ATTRIBUTE_NAME)
             flag = 0
             try:
-                flag = eval( mini.getAttribute(ATTRIBUTE_UNIQUE) )
+                flag = eval( mini.get(ATTRIBUTE_UNIQUE) )
             except:
                 pass
-
             show = 'yes'
             if flag:
                 show = 'no'
@@ -124,7 +120,6 @@
             </tr>""" % ( label, url, url, show )
 
         str += "</table>"
-        print str
         return str
 
     def html_view( self ):
@@ -136,59 +131,55 @@
         drag_obj = self.tree.drag_obj
         if drag_obj == self or self.tree.is_parent_node( self.mytree_node, drag_obj.mytree_node ):
             return
-        if isinstance( drag_obj, minilib_handler ):
-            item = self.tree.GetSelection()
-            name = self.tree.GetItemText( item )
-        if isinstance( drag_obj, map_miniature_nodehandler.map_miniature_handler ):
-            xml_dom = self.tree.drag_obj.master_dom#.delete()
-            obj = xml_dom.firstChild
-            print obj.getAttributeKeys()
+        elif isinstance( drag_obj, map_miniature_nodehandler.map_miniature_handler ):
+            drop_xml = self.tree.drag_obj.xml#.delete()
+            obj = drop_xml[0]
             dict = {}
             unique = ''
-            for attrib in obj.getAttributeKeys():
+            for attrib in obj.keys():
                 key = TO_MINILIB_MAP.get( attrib, attrib )
                 if key != None:
-                    dict[ key ] = obj.getAttribute( attrib )
+                    dict[ key ] = obj.get( attrib )
             dict[ ATTRIBUTE_UNIQUE ] = unique
             self.new_mini( dict )
+        else:
+            node_handler.on_drop(self, evt)
 
 
     def new_mini( self, data={}, add=1 ):
-        mini = minidom.Element( TAG_MINIATURE )
+        mini = Element( TAG_MINIATURE )
         for key in data.keys():
-            mini.setAttribute( key, data[ key ] )
+            mini.set( key, data[ key ] )
         for key in CORE_ATTRIBUTES:
-            if mini.getAttribute( key ) == '':
-                mini.setAttribute( key, '0' )
+            if mini.get( key ) == '':
+                mini.set( key, '0' )
         if add:
             self.add_mini( mini )
             self.add_leaf( mini )
         return mini
 
     def add_mini( self, mini ):
-        self.master_dom.appendChild( mini )
+        self.xml.append( mini )
 
     def add_leaf( self, mini, icon='gear' ):
         tree = self.tree
         icons = tree.icons
-        key = mini.getAttribute( ATTRIBUTE_NAME )
+        key = mini.get( ATTRIBUTE_NAME )
         self.mydata.append( mini )
 
     def update_leaves( self ):
         self.mydata = []
-        nl = self.master_dom.getElementsByTagName( TAG_MINIATURE )
-        for n in nl:
+        for n in self.xml.findall(TAG_MINIATURE):
             self.add_leaf( n )
 
-
     def on_drag( self, evt ):
         print 'drag event caught'
 
     def send_mini_to_map( self, mini, count=1, addName=True ):
         if mini == None:
             return
-        if mini.getAttribute( ATTRIBUTE_URL ) == '' or mini.getAttribute( ATTRIBUTE_URL ) == 'http://':
-            self.chat.ParsePost( self.chat.colorize(self.chat.syscolor, '"%s" is not a valid URL, the mini "%s" will not be added to the map' % ( mini.getAttribute( ATTRIBUTE_URL ), mini.getAttribute( ATTRIBUTE_NAME ) )) )
+        if mini.get( ATTRIBUTE_URL ) == '' or mini.get( ATTRIBUTE_URL ) == 'http://':
+            self.chat.ParsePost( self.chat.colorize(self.chat.syscolor, '"%s" is not a valid URL, the mini "%s" will not be added to the map' % ( mini.get( ATTRIBUTE_URL ), mini.get( ATTRIBUTE_NAME ) )) )
             return
         session = component.get( COMPONENT_SESSION )
         if (session.my_role() != session.ROLE_GM) and (session.my_role() != session.ROLE_PLAYER):
@@ -201,57 +192,50 @@
             map.new_data( msg )
             session.send( msg )
 
-    def get_miniature_XML( self, mini, addName = True ):
+    def get_miniature_XML( self, mini_xml, addName = True ):
         msg = orpg.mapper.map_msg.mini_msg()
         map = component.get( COMPONENT_MAP )
         session = component.get( COMPONENT_SESSION )
         msg.init_prop( ATTRIBUTE_ID, session.get_next_id() )
-        for k in mini.getAttributeKeys():
+        msg.init_prop('selected', '1')# this will make the mini initially selected
+        for k in mini_xml.keys():
             # translate our attributes to map attributes
             key = FROM_MINILIB_MAP.get( k, k )
             if key != None:
                 if not addName and k == 'name':
                     pass
                 else:
-                    msg.init_prop( key, mini.getAttribute( k ) )
-        unique = self.is_unique( mini )
+                    msg.init_prop( key, mini_xml.get( k ) )
+        unique = self.is_unique( mini_xml )
         if addName:
-            label = mini.getAttribute( ATTRIBUTE_NAME )
+            label = mini_xml.get( ATTRIBUTE_NAME )
         else:
             label = ''
         return msg.get_all_xml()
 
     def is_unique( self, mini ):
-        unique = mini.getAttribute( ATTRIBUTE_UNIQUE )
+        unique = mini.get( ATTRIBUTE_UNIQUE )
         val = 0
-        try:
-            val = eval( unique )
-        except:
-            val = len( unique )
+        try: val = eval( unique )
+        except: val = len( unique )
         return val
 
     def sanity_check_nodes( self ):
-        nl = self.master_dom.getElementsByTagName( TAG_MINIATURE )
-        for node in nl:
-            if node.getAttribute( ATTRIBUTE_POSX ) == '':
-                node.setAttribute( ATTRIBUTE_POSX, '0' )
-            if node.getAttribute( ATTRIBUTE_POSY ) == '':
-                node.setAttribute( ATTRIBUTE_POSY, '0' )
+        for node in self.xml.findall(TAG_MINIATURE):
+            if node.get( ATTRIBUTE_POSX ) == '': node.set( ATTRIBUTE_POSX, '0' )
+            if node.get( ATTRIBUTE_POSY ) == '': node.set( ATTRIBUTE_POSY, '0' )
 
     def get_mini( self, index ):
-        try:
-            nl = self.master_dom.getElementsByTagName( TAG_MINIATURE )
-            return nl[ index ]
-        except:
-            return None
+        try: return self.xml.findall(TAG_MINIATURE)[index]
+        except: return None
 
 class mini_handler( node_handler ):
-    def __init__( self, xml_dom, tree_node, handler ):
-        node_handler.__init__( self, xml_dom, tree_node)
+    def __init__( self, xml, tree_node, handler ):
+        node_handler.__init__( self, xml, tree_node)
         self.handler = handler
 
     def on_ldclick( self, evt ):
-        self.handler.send_mini_to_map( self.master_dom )
+        self.handler.send_mini_to_map( self.xml )
 
     def on_drop( self, evt ):
         pass
@@ -313,17 +297,10 @@
     def buildList( self ):
         """Returns a dictionary of label => game tree miniature DOM node mappings.
         """
-        list = self.handler.master_dom.getElementsByTagName(TAG_MINIATURE)
         self.list = []
-        for mini in list:
-            self.list.append( mini.getAttribute( ATTRIBUTE_NAME ) )
+        for mini in self.handler.xml.findall(TAG_MINIATURE):
+            self.list.append( mini.get( ATTRIBUTE_NAME ) )
         return self.list
-        # self.list = {}
-        # for mini in list:
-        #     name = mini.getAttribute( ATTRIBUTE_NAME )
-        #     if name == '':
-        #         name = self.map.canvas.get_label_from_url( mini.getAttribute( ATTRIBUTE_URL ) )
-        #     self.list[ name ] = mini
 
     def on_close(self, evt):
         self.frame.Close()
@@ -454,9 +431,8 @@
         self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.select_cell)
 
     def update_cols( self ):
-        nl = self.handler.master_dom.getElementsByTagName( TAG_MINIATURE )
-        for n in nl:
-            for k in n.getAttributeKeys():
+        for n in self.handler.xml.findall(TAG_MINIATURE):
+            for k in n.keys():
                 if k not in self.keys:
                     self.keys.append( k )
 
@@ -475,7 +451,7 @@
         """Returns the list of 'miniature' DOM elements associated with this
         miniature library.
         """
-        return self.handler.master_dom.getElementsByTagName( TAG_MINIATURE )
+        return self.handler.xml.findall( TAG_MINIATURE )
 
     def add_row( self, count = 1 ):
         """creates a new miniature node, and then adds it to the current
@@ -486,7 +462,7 @@
           ATTRIBUTE_NAME :' ',
           ATTRIBUTE_URL :'http://'} )# minidom.Element( TAG_MINIATURE )
         self.update_all()
-        #self.handler.master_dom.appendChild( node )
+        #self.handler.xml.append( node )
 
     def del_row( self ):
         """deletes the miniature associated with the currently selected
@@ -495,8 +471,8 @@
         """
         if self.selectedRow > -1:
             pos = self.selectedRow
-            list = self.handler.master_dom.getElementsByTagName(TAG_MINIATURE)
-            self.handler.master_dom.removeChild( list[pos] )
+            list = self.handler.xml.findall(TAG_MINIATURE)
+            self.handler.xml.remove( list[pos] )
             self.DeleteRows( pos, 1 )
             list = self.getList()
             del list[ pos ]
@@ -515,7 +491,7 @@
         list = self.getList()
         count = 0
         for n in list:
-            for k in n.getAttributeKeys():
+            for k in n.keys():
                 if k not in self.keys:
                     self.keys.append( k )
         count = len( self.keys )
@@ -555,11 +531,8 @@
         """
         list = self.getList()
         item = list[ row ]
-        # self.GetTable().SetValue( row, 0, item.getAttribute(ATTRIBUTE_NAME) )
-        # self.GetTable().SetValue( row, 1, item.getAttribute(ATTRIBUTE_URL) )
-        # self.GetTable().SetValue( row, 2, item.getAttribute(ATTRIBUTE_UNIQUE) )
         for key in self.keys:
-            self.GetTable().SetValue( row, self.keys.index( key ), item.getAttribute( key ) )
+            self.GetTable().SetValue( row, self.keys.index( key ), item.get( key ) )
 
     def update_data_row( self, row ):
         """Updates the DOM nodw 'row' with grid data from 'row'
@@ -567,10 +540,4 @@
         list = self.getList()
         item = list[ row ]
         for key in self.keys:
-            item.setAttribute( key, string.strip( self.GetTable().GetValue( row, self.keys.index( key ) ) ) )
-        # item.setAttribute( ATTRIBUTE_NAME, string.strip( self.GetTable().GetValue( row, 0 ) ) )
-        # item.setAttribute( ATTRIBUTE_URL, string.strip( self.GetTable().GetValue( row, 1 ) ) )
-        # item.setAttribute( ATTRIBUTE_UNIQUE, string.strip( self.GetTable().GetValue( row, 2 ) ) )
-        # self.GetTable().SetValue( row, 0, item.getAttribute(ATTRIBUTE_NAME) )
-        # self.GetTable().SetValue( row, 1, item.getAttribute(ATTRIBUTE_URL) )
-        # self.GetTable().SetValue( row, 2, item.getAttribute(ATTRIBUTE_UNIQUE) )
+            item.set( key, string.strip( self.GetTable().GetValue( row, self.keys.index( key ) ) ) ) 
--- a/orpg/gametree/nodehandlers/rpg_grid.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/gametree/nodehandlers/rpg_grid.py	Wed Oct 28 14:24:54 2009 -0500
@@ -29,8 +29,7 @@
 __version__ = "$Id: rpg_grid.py,v 1.20 2006/11/15 12:11:24 digitalxero Exp $"
 
 from core import *
-from forms import *
-from orpg.minidom import Element, Text
+from forms import *
 
 class rpg_grid_handler(node_handler):
     """ Node handler for rpg grid tool
@@ -50,14 +49,14 @@
   </macros>
 </nodehandler>
     """
-    def __init__(self,xml_dom,tree_node):
-        node_handler.__init__(self,xml_dom,tree_node)
-        self.grid = self.master_dom.getElementsByTagName('grid')[0]
-        if self.grid.getAttribute("border") == "":
-            self.grid.setAttribute("border","1")
-        if self.grid.getAttribute("autosize") == "":
-            self.grid.setAttribute("autosize","1")
-        self.macros = self.master_dom.getElementsByTagName('macros')[0]
+    def __init__(self,xml,tree_node):
+        node_handler.__init__(self,xml,tree_node)
+        self.grid = self.xml.find('grid')
+        if self.grid.get("border") == "":
+            self.grid.set("border","1")
+        if self.grid.get("autosize") == "":
+            self.grid.set("autosize","1")
+        self.macros = self.xml.find('macros')
         self.myeditor = None
         self.refresh_rows()
 
@@ -69,38 +68,31 @@
         tree = self.tree
         icons = self.tree.icons
         tree.CollapseAndReset(self.mytree_node)
-        node_list = self.master_dom.getElementsByTagName('row')
-        for n in node_list:
-            cells = n.getElementsByTagName('cell')
-            t_node = cells[0]._get_firstChild()
-            if t_node == None:
-                name = "Row"
-            else:
-                name = t_node._get_nodeValue()
-            if name == "":
+        for row in self.grid.findall('row'):
+            first_cell = row.find('cell')
+            name = first_cell.text
+            if name == None or name == '':
                 name = "Row"
             new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear'])
-            handler = grid_row_handler(n,new_tree_node,self)
+            handler = grid_row_handler(row,new_tree_node,self)
             tree.SetPyData(new_tree_node,handler)
 
-
     def tohtml(self):
-        border = self.grid.getAttribute("border")
-        name = self.master_dom.getAttribute('name')
-        rows = self.grid.getElementsByTagName('row')
-        colspan = str(len(rows[0].getElementsByTagName('cell')))
+        border = self.grid.get("border")
+        name = self.xml.get('name')
+        rows = self.grid.findall('row')
+        colspan = str(len(rows[0].findall('cell')))
         html_str = "<table border=\""+border+"\" align=center><tr bgcolor=\""+TH_BG+"\" ><th colspan="+colspan+">"+name+"</th></tr>"
         for r in rows:
-            cells = r.getElementsByTagName('cell')
+            cells = r.findall('cell')
             html_str += "<tr>"
             for c in cells:
-                #html_str += "<td width='"+c.getAttribute('size')+"' >" bug here
+                #html_str += "<td width='"+c.get('size')+"' >" bug here
                 html_str += "<td >"
-                t_node = c._get_firstChild()
-                if t_node == None:
-                    html_str += "<br /></td>"
-                else:
-                    html_str += t_node._get_nodeValue() + "</td>"
+                text = c.text
+                if text == None or text == '':
+                    text = '<br />'
+                html_str += text + "</td>"
             html_str += "</tr>"
         html_str += "</table>"
         return html_str
@@ -115,16 +107,16 @@
         return 1
 
     def is_autosized(self):
-        return self.grid.getAttribute("autosize")
+        return self.grid.get("autosize")
 
     def set_autosize(self,autosize=1):
-        self.grid.setAttribute("autosize",str(autosize))
+        self.grid.set("autosize",str(autosize))
 
 class grid_row_handler(node_handler):
     """ Node Handler grid row.
     """
-    def __init__(self,xml_dom,tree_node,parent):
-        node_handler.__init__(self,xml_dom,tree_node)
+    def __init__(self,xml,tree_node,parent):
+        node_handler.__init__(self,xml,tree_node)
         self.drag = False
 
     def on_drop(self,evt):
@@ -134,19 +126,30 @@
         return 0;
 
     def tohtml(self):
-        cells = self.master_dom.getElementsByTagName('cell')
+        cells = self.xml.findall('cell')
         html_str = "<table border=1 align=center><tr >"
-        for c in cells:
+        for c in cells: # should loop over rows first, then cells
             html_str += "<td >"
-            t_node = c._get_firstChild()
-            if t_node == None:
-                html_str += "<br /></td>"
-            else:
-                html_str += t_node._get_nodeValue() + "</td>"
+            text = c.text
+            if text == '' or text is None:
+                text = '<br />'
+            html_str += text + "</td>"
             html_str += "</tr>"
         html_str += "</table>"
         return html_str
 
+    def get_value(self):
+        cells = self.xml.findall('cell')
+        if len(cells) == 2:
+            return getText(cells[1])
+        else:
+            return None
+
+    def set_value(self, new_value):
+        cells = self.xml.findall('cell')
+        if len(cells) == 2:
+            cells[1].text = new_value
+
 class MyCellEditor(wx.grid.PyGridCellEditor):
     """
     This is a sample GridCellEditor that shows you how to make your own custom
@@ -284,6 +287,7 @@
             evt.Skip()
 
 
+
     def Destroy(self):
         """final cleanup"""
         self.base_Destroy()
@@ -308,9 +312,9 @@
         #  Registers a "custom" cell editor (really the example from Robin Dunn with minor mods
         self.RegisterDataType(wx.grid.GRID_VALUE_STRING, wx.grid.GridCellStringRenderer(),MyCellEditor())
 
-        self.rows = handler.grid.getElementsByTagName('row')
+        self.rows = handler.grid.findall('row')
         rows = len(self.rows)
-        cols = len(self.rows[0].getElementsByTagName('cell'))
+        cols = len(self.rows[0].findall('cell'))
         self.CreateGrid(rows,cols)
         self.SetRowLabelSize(0)
         self.SetColLabelSize(0)
@@ -330,85 +334,76 @@
 
     def on_col_size(self, evt):
         col = evt.GetRowOrCol()
-        cells = self.rows[0].getElementsByTagName('cell')
+        cells = self.rows[0].findall('cell')
         size = self.GetColSize(col)
-        cells[col].setAttribute('size',str(size))
+        cells[col].set('size',str(size))
         evt.Skip()
 
     def on_cell_change(self,evt):
         row = evt.GetRow()
         col = evt.GetCol()
         value = self.GetCellValue(row,col)
-        cells = self.rows[row].getElementsByTagName('cell')
-        t_node = cells[col]._get_firstChild()
-        t_node._set_nodeValue(value)
+        cells = self.rows[row].findall('cell')
+        cells[col].text = value
         if col == 0:
             self.handler.refresh_rows()
 
     def set_col_widths(self):
-        cells = self.rows[0].getElementsByTagName('cell')
+        cells = self.rows[0].findall('cell')
         for i in range(0,len(cells)):
             try:
-                size = int(cells[i].getAttribute('size'))
+                size = int(cells[i].get('size'))
                 self.SetColSize(i,size)
             except:
                 continue
 
     def refresh_row(self,rowi):
-        cells = self.rows[rowi].getElementsByTagName('cell')
+        cells = self.rows[rowi].findall('cell')
         for i in range(0,len(cells)):
-            t_node = cells[i]._get_firstChild()
-            if t_node == None:
-                #doc = cells[i].ownerDocument
-                #t_node = doc.createTextNode("")
-                t_node = Text("")
-                t_node = cells[i].appendChild(t_node)
-            self.SetCellValue(rowi,i,t_node._get_nodeValue())
+            text = cells[i].text
+            if text == None or text == '':
+                text = ''
+                cells[i].text = text
+            self.SetCellValue(rowi,i,text)
 
     def add_row(self,evt=None):
         cols = self.GetNumberCols()
-        #doc = self.handler.grid.ownerDocument
-        #row = doc.createElement('row')
-        row = Element('row')
+        row = ET.Element('row')
         for i in range(0,cols):
-            #cell = doc.createElement('cell')
-            cell = Element('cell')
-            #t_node = doc.createTextNode("")
-            t_node = Text("")
-            t_node = cell.appendChild(t_node)
-            row.appendChild(cell)
-        self.handler.grid.appendChild(row)
+            cell = ET.Element('cell')
+            cell.text = ''
+            row.append(cell)
+        self.handler.grid.append(row)
         self.AppendRows(1)
-        self.rows = self.handler.grid.getElementsByTagName('row')
+        self.rows = self.handler.grid.findall('row')
         self.handler.refresh_rows()
 
     def add_col(self,evt=None):
-        #doc = self.handler.grid.ownerDocument
         for r in self.rows:
-            #cell = doc.createElement('cell')
-            cell = Element('cell')
-            #t_node = doc.createTextNode("")
-            t_node = Text("")
-            t_node = cell.appendChild(t_node)
-            r.appendChild(cell)
+            cell = ET.Element('cell')
+            cell.text = ''
+            r.append(cell)
         self.AppendCols(1)
-        #self.fit_cols()::Where did this go? TaS.
+        self.set_col_widths()
 
     def del_row(self,evt=None):
         num = self.GetNumberRows()
-        row = self.rows[num-1]
-        self.handler.grid.removeChild(row)
+        if num == 1:
+            return
+        self.handler.grid.remove(self.handler.grid[num-1])#always remove last row -- nasty
         self.DeleteRows(num-1,1)
-        self.rows = self.handler.grid.getElementsByTagName('row')
+        self.rows = self.handler.grid.findall('row')
         self.handler.refresh_rows()
 
     def del_col(self,evt=None):
         num = self.GetNumberCols()
+        if num == 1:
+            return
         for r in self.rows:
-            cells = r.getElementsByTagName('cell')
-            r.removeChild(cells[num-1])
+            cells = r.findall('cell')
+            r.remove(r[num-1])# always remove the last column -- nasty
         self.DeleteCols(num-1,1)
-        #self.fit_cols()::Where did this go? TaS.
+        self.set_col_widths()
 
 
 G_TITLE = wx.NewId()
@@ -418,7 +413,7 @@
         wx.Panel.__init__(self, parent, -1)
         self.handler = handler
         self.grid = rpg_grid(self,handler)
-        label = handler.master_dom.getAttribute('name')
+        label = handler.xml.get('name')
         self.main_sizer = wx.BoxSizer(wx.VERTICAL)
         self.main_sizer.Add(wx.StaticText(self, -1, label+": "), 0, wx.EXPAND)
         self.main_sizer.Add(self.grid,1,wx.EXPAND)
@@ -439,10 +434,10 @@
         wx.Panel.__init__(self, parent, -1)
         self.handler = handler
         self.grid = rpg_grid(self,handler)
-        self.title = wx.TextCtrl(self, G_TITLE, handler.master_dom.getAttribute('name'))
+        self.title = wx.TextCtrl(self, G_TITLE, handler.xml.get('name'))
 
         radio_b = wx.RadioBox(self, GRID_BOR, "Border (HTML)", choices=["no","yes"])
-        border = handler.grid.getAttribute("border")
+        border = handler.grid.get("border")
         radio_b.SetSelection(int(border))
 
         self.auto_size = wx.CheckBox(self, G_AUTO_SIZE, " Auto Size")
@@ -487,10 +482,10 @@
         id = evt.GetId()
         index = evt.GetInt()
         if id == GRID_BOR:
-            self.handler.grid.setAttribute("border",str(index))
+            self.handler.grid.set("border",str(index))
 
     def on_text(self,evt):
         txt = self.title.GetValue()
         if txt != "":
-            self.handler.master_dom.setAttribute('name',txt)
+            self.handler.xml.set('name',txt)
             self.handler.rename(txt)
--- a/orpg/main.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/main.py	Wed Oct 28 14:24:54 2009 -0500
@@ -62,8 +62,8 @@
 from orpg.tools.decorators import debugging
 from orpg.tools.metamenus import MenuBarEx
 
-#from xml.etree.ElementTree import ElementTree, Element
-#from xml.etree.ElementTree import fromstring, tostring
+from xml.etree.ElementTree import ElementTree, Element, iselement
+from xml.etree.ElementTree import fromstring, tostring
 from orpg.orpg_xml import xml #to be replaced by etree
 
 
@@ -972,73 +972,46 @@
 
         # ok we are not ignoring this message
         #recvSound = "RecvSound"     #  this will be the default sound.  Whisper will change this below
-        if player: display_name = self.chat.chat_display_name(player)
-        else: display_name = "Server Administrator"
-
-        if data[:5] == "<tree":
-            ### Alpha ### Allows users to decide if they want the node or not.
-            dlg = wx.MessageDialog(None, display_name + 'is trying to send you a tree node. Accept?', 'Question', 
-                wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
-            if dlg.ShowModal() == wx.ID_YES:
-              dlg.Destroy()
-              self.tree.on_receive_data(data,player)
-              self.chat.InfoPost(display_name + " has sent you a tree node...")
-
-        elif data[:4] == "<map": self.map.new_data(data)
-
-        elif data[:5] == "<chat":
-            msg = orpg.chat.chat_msg.chat_msg(data)
-            self.chat.post_incoming_msg(msg,player)
+        ### Alpha  ###
+        etreeEl = Element('msg')
+        try: etreeEl.append(fromstring(data))
+        except: etreeEl.text = data
+        ### Remove after Element Tree is integrated further ###
+        if player:
+            display_name = self.chat.chat_display_name(player)
         else:
-            """
-            all this below code is for comptiablity with older clients and can
-            be removed after a bit
-            """
-            import warnings
-            warnings.warn("Getting here is bad, find out how and fix it",
-          DeprecationWarning, 2)
-            if data[:3] == "/me":
-                """
-                This fixes the emote coloring to comply with what has been
-                asked for by the user population, not to mention, what I
-                committed to many moons ago. In doing so, Woody's scheme has
-                been tossed out.  I'm sure Woody won't be happy but I'm
-                invoking developer priveledge to satisfy user request, not to
-                mention, this scheme actually makes more sense.  In Woody's
-                scheme, a user could over-ride another users emote color. This
-                doesn't make sense, rather, people dictate their OWN colors...
-                which is as it should be in the first place and is as it has
-                been with normal text.  In short, this makes sense and is
-                consistent.
-                """
-                data = data.replace( "/me", "" )
-                """
-                Check to see if we find the closing '>' for the font within the
-                first 22 values
-                """
-                index = data[:22].find(  ">" )
-                if index == -1:
-                    data = "** " + self.chat.colorize( self.chat.infocolor, display_name + data ) + " **"
+            display_name = "Server Administrator"
+
+        if etreeEl.text:
+            self.chat.Post(etreeEl.text)
 
-                else:
-                    """
-                    This means that we found a valid font string, so we can
-                    simply plug the name into the string between the start and
-                    stop font delimiter
-                    """
-                    print "pre data = " + data
-                    data = data[:22] + "** " + display_name + " " + data[22:] + " **"
-                    print "post data = " + data
+        for child in etreeEl.getchildren():
+            if child.tag == 'tree':
+                ### Alpha ### Allows users to decide if they want the node or not.
+                dlg = wx.MessageDialog(None, display_name + 'is trying to send you a tree node. Accept?', 'Question', 
+                    wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
+                if dlg.ShowModal() == wx.ID_YES:
+                  dlg.Destroy()
+                  self.tree.on_receive_data(data,player)
+                  self.chat.InfoPost(display_name + " has sent you a tree node...")
+                ### Core ### to be milked in later.
+                #TODO: Fix game tree to accepts elements
+                #self.tree.on_receive_data(child, player)
+                #self.chat.InfoPost(display_name + " has sent you a tree node...")
 
-            elif data[:2] == "/w":
-                data = data.replace("/w","")
-                data = "<b>" + display_name + "</b> (whispering): " + data
+            elif child.tag == 'map':
+                ### Core ### Adapted from, remove tostring later
+                #TODO: Fix map to accepts elements
+                self.map.new_data(tostring(child))
 
-            else:
-                # Normal text
-                if player: data = "<b>" + display_name + "</b>: " + data
-                else: data = "<b><i><u>" + display_name + "</u>-></i></b> " + data
-            self.chat.Post(data)
+            elif child.tag == 'chat':
+                msg = orpg.chat.chat_msg.chat_msg(data)
+                self.chat.post_incoming_msg(msg,player)
+                ### Core ### to be milked in later
+                #msg = orpg.chat.chat_msg.chat_msg()
+                #msg.takedom(child)
+                #self.chat.post_incoming_msg(msg, player)
+
 
     @debugging
     def on_mplay_event(self, evt):
--- a/orpg/map/__init__.py	Mon Oct 12 23:24:10 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,269 +0,0 @@
-from threading import Lock
-import mimetypes
-import xml.dom.minidom as minidom
-
-import wx
-
-import orpg.dirpath
-from orpg.orpgCore import *
-from orpg.tools.rgbhex import RGBHex
-import orpg.tools.ButtonPanel as BP
-
-from _canvas import MapCanvas
-
-class MapWnd(wx.Panel):
-    def __init__(self, parent, openrpg):
-        wx.Panel.__init__(self, parent, wx.ID_ANY)
-        self.openrpg = openrpg
-        self.log = self.openrpg.get_component("log")
-        self.xml = self.openrpg.get_component("xml")
-        self.dir_struct = self.openrpg.get_component("dir_struct")
-        self.validate = self.openrpg.get_component("validate")
-        self.settings = self.openrpg.get_component("settings")
-
-        self.Freeze()
-        sizer = wx.GridBagSizer(hgap=1, vgap=1)
-        sizer.SetEmptyCellSize((0,0))
-
-        self.canvas = MapCanvas(self, self.openrpg)
-        sizer.Add(self.canvas, (0,0), flag=wx.EXPAND)
-
-        self.gmToolBar = BP.ButtonPanel(self, wx.ID_ANY)
-        sizer.Add(self.gmToolBar, (1,0), flag=wx.EXPAND)
-        self.playerToolBar = BP.ButtonPanel(self, wx.ID_ANY)
-        sizer.Add(self.playerToolBar, (2,0), flag=wx.EXPAND)
-
-        sizer.AddGrowableCol(0)
-        sizer.AddGrowableRow(0)
-
-        self.SetSizer(sizer)
-        self.SetAutoLayout(True)
-
-        self._CreateToolBar()
-
-        self.Bind(wx.EVT_MOUSEWHEEL, self.canvas.OnZoom)
-        self.Bind(wx.EVT_KEY_DOWN, self.canvas.OnKey)
-        self.Bind(wx.EVT_KEY_UP, self.canvas.OnKey)
-        self.Layout()
-        self.Thaw()
-
-        wx.CallAfter(self.PostLoad)
-
-    #Public API
-    def PostLoad(self):
-        self.canvas.Clear()
-        #self.canvas.roleTimer.Start(100)
-        self.canvas.UpdateMap()
-
-    #Events
-
-
-    #Private Methods
-    def _SetColorBtn(self, color, btn):
-        dc = wx.MemoryDC()
-        bmp = wx.EmptyBitmap(16, 16)
-        dc.SelectObject(bmp)
-        dc.SetBrush(wx.Brush(color))
-        dc.DrawRectangle(0,0, 16, 16)
-
-        del dc
-
-        btn.SetBitmap(bmp)
-
-    def _CreateToolBar(self):
-        self.exclusiveToolList = {}
-
-        self.OpenBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'open.bmp', wx.BITMAP_TYPE_BMP), kind=wx.ITEM_NORMAL, shortHelp="Load New Map", longHelp="Load New Map")
-        self.gmToolBar.AddButton(self.OpenBtn)
-
-        self.SaveBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'save.bmp', wx.BITMAP_TYPE_BMP), kind=wx.ITEM_NORMAL, shortHelp="Save Map", longHelp="Save Map")
-        self.gmToolBar.AddButton(self.SaveBtn)
-
-        self.DefaultBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'defaultmap.png', wx.BITMAP_TYPE_PNG), kind=wx.ITEM_NORMAL, shortHelp="Load Default Map", longHelp="Load Default Map")
-        self.gmToolBar.AddButton(self.DefaultBtn)
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnDefaultBtn, id=self.DefaultBtn.GetId())
-
-        self.MapPropsBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'compass.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Map Properties", longHelp="Map Properties")
-        self.gmToolBar.AddButton(self.MapPropsBtn)
-
-
-        self.gmToolBar.AddSeparator()
-
-        self.BGBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'img.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Change Background", longHelp="Change Background")
-        self.gmToolBar.AddButton(self.BGBtn)
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnBGBtn, id=self.BGBtn.GetId())
-
-        self.BGColorBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.EmptyBitmap(16,16), kind=wx.ITEM_NORMAL, shortHelp="Map Background Color", longHelp="Map Background Color")
-        self.gmToolBar.AddButton(self.BGColorBtn)
-        self._SetColorBtn(wx.GREEN, self.BGColorBtn)
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnBGColorBtn, id=self.BGColorBtn.GetId())
-
-        self.TileAddBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'chess.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Add Map Tile", longHelp="Add Map Tile")
-        self.gmToolBar.AddButton(self.TileAddBtn)
-
-        self.TileMoveBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'crosshair.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_CHECK, shortHelp="Edit Tiles", longHelp="Edit Tiles")
-        self.gmToolBar.AddButton(self.TileMoveBtn)
-        self.exclusiveToolList[self.TileMoveBtn.GetId()] = self.TileMoveBtn
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.TileMoveBtn.GetId())
-
-        self.GridBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'grid.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Set Grid", longHelp="Set Grid")
-        self.gmToolBar.AddButton(self.GridBtn)
-
-        self.gmToolBar.AddSeparator()
-
-        self.FogBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'fogon.png', wx.BITMAP_TYPE_PNG), kind=wx.ITEM_CHECK, shortHelp="Turn Fog On", longHelp="Turn Fog On")
-        self.gmToolBar.AddButton(self.FogBtn)
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnFogBtn, id=self.FogBtn.GetId())
-
-        self.FogToolBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'showfog.png', wx.BITMAP_TYPE_PNG), kind=wx.ITEM_CHECK, shortHelp="Show Tool", longHelp="Show Tool")
-        self.gmToolBar.AddButton(self.FogToolBtn)
-        self.exclusiveToolList[self.FogToolBtn.GetId()] = self.FogToolBtn
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.FogToolBtn.GetId())
-        menu = wx.Menu("Fog Tool")
-        item = wx.MenuItem(menu, 1, "Show", "Show")
-        self.Bind(wx.EVT_MENU, self.OnFogSelection, item)
-        menu.AppendItem(item)
-        item = wx.MenuItem(menu, 2, "Hide", "Hide")
-        self.Bind(wx.EVT_MENU, self.OnFogSelection, item)
-        menu.AppendItem(item)
-        self.currentFog = 'Show'
-        self.FogToolBtn.SetMenu(menu)
-
-        self.FogColorBtn = BP.ButtonInfo(self.gmToolBar, wx.ID_ANY, wx.EmptyBitmap(16,16), kind=wx.ITEM_NORMAL, shortHelp="Fog Color", longHelp="Fog Color")
-        self.gmToolBar.AddButton(self.FogColorBtn)
-        self._SetColorBtn(wx.BLACK, self.FogColorBtn)
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnFogColorBtn, id=self.FogColorBtn.GetId())
-
-        self.gmToolBar.AddSeparator()
-
-        self.MiniPropsBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'questionhead.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Miniture Properties", longHelp="Miniture Properties")
-        self.gmToolBar.AddButton(self.MiniPropsBtn)
-
-        self.gmToolBar.DoLayout()
-
-        self.SelectorBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'mouse.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_CHECK, shortHelp="Selection Tool", longHelp="Selection Tool")
-        self.playerToolBar.AddButton(self.SelectorBtn)
-        self.exclusiveToolList[self.SelectorBtn.GetId()] = self.SelectorBtn
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.SelectorBtn.GetId())
-
-        self.MeasureBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'tape.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_CHECK, shortHelp="Measure Tool", longHelp="Measure Tool")
-        self.playerToolBar.AddButton(self.MeasureBtn)
-        self.exclusiveToolList[self.MeasureBtn.GetId()] = self.MeasureBtn
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.MeasureBtn.GetId())
-
-        self.ColorBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.EmptyBitmap(16,16), kind=wx.ITEM_NORMAL, shortHelp="Select a Color", longHelp="Select a Color")
-        self.playerToolBar.AddButton(self.ColorBtn)
-        self._SetColorBtn(wx.BLACK, self.ColorBtn)
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnColorBtn, id=self.ColorBtn.GetId())
-
-        self.DrawBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'draw.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_CHECK, shortHelp="Freehand Line Tool", longHelp="Freehand Line Tool")
-        self.playerToolBar.AddButton(self.DrawBtn)
-        self.exclusiveToolList[self.DrawBtn.GetId()] = self.DrawBtn
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.DrawBtn.GetId())
-        menu = wx.Menu("Line Tool")
-        item = wx.MenuItem(menu, 3, "Free Draw", "Free Draw")
-        self.Bind(wx.EVT_MENU, self.OnLineSelection, item)
-        menu.AppendItem(item)
-        item = wx.MenuItem(menu, 4, "Poly Draw", "Poly Draw")
-        self.Bind(wx.EVT_MENU, self.OnLineSelection, item)
-        menu.AppendItem(item)
-        self.currentLine = 'Free'
-        self.DrawBtn.SetMenu(menu)
-
-        self.AddTextBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'text.png', wx.BITMAP_TYPE_PNG), kind=wx.ITEM_CHECK, shortHelp="Add Text Tool", longHelp="Add Text Tool")
-        self.playerToolBar.AddButton(self.AddTextBtn)
-        self.exclusiveToolList[self.AddTextBtn.GetId()] = self.AddTextBtn
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.AddTextBtn.GetId())
-
-        self.AddShapeBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'circle.png', wx.BITMAP_TYPE_PNG), kind=wx.ITEM_CHECK, shortHelp="Add Shape Tool", longHelp="Add Shape Tool")
-        self.playerToolBar.AddButton(self.AddShapeBtn)
-        self.exclusiveToolList[self.AddShapeBtn.GetId()] = self.AddShapeBtn
-        self.Bind(wx.EVT_BUTTON, self.canvas.OnExlusiveBtn, id=self.AddShapeBtn.GetId())
-        menu = wx.Menu("Shape Tool")
-        item = wx.MenuItem(menu, 5, "Circle", "Circle")
-        self.Bind(wx.EVT_MENU, self.OnShapeSelection, item)
-        menu.AppendItem(item)
-        item = wx.MenuItem(menu, 6, "Rectangle", "Rectangle")
-        self.Bind(wx.EVT_MENU, self.OnShapeSelection, item)
-        menu.AppendItem(item)
-        item = wx.MenuItem(menu, 7, "Arc", "Arc")
-        self.Bind(wx.EVT_MENU, self.OnShapeSelection, item)
-        menu.AppendItem(item)
-        self.currentShape = 'Circle'
-        self.AddShapeBtn.SetMenu(menu)
-
-        self.LineWidth = wx.Choice(self.playerToolBar, wx.ID_ANY, choices=["1","2","3","4","5","6","7","8","9","10"])
-        self.LineWidth.SetSelection(0)
-        self.playerToolBar.AddControl(self.LineWidth)
-
-        self.playerToolBar.AddSeparator()
-
-        self.MiniBtn = BP.ButtonInfo(self.playerToolBar, wx.ID_ANY, wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'player.gif', wx.BITMAP_TYPE_GIF), kind=wx.ITEM_NORMAL, shortHelp="Add Mini", longHelp="Add Mini")
-        self.playerToolBar.AddButton(self.MiniBtn)
-
-        self.playerToolBar.DoLayout()
-
-    def OnShapeSelection(self, event):
-        id = event.GetId()
-        if id == 5:
-            self.currentShape = 'Circle'
-            self.AddShapeBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'circle.png', wx.BITMAP_TYPE_PNG)
-        elif id == 6:
-            self.currentShape = 'Rectangle'
-            self.AddShapeBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'rectangle.png', wx.BITMAP_TYPE_PNG)
-        elif id == 7:
-            self.currentShape = 'Arc'
-            self.AddShapeBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'arc.png', wx.BITMAP_TYPE_PNG)
-
-    def OnLineSelection(self, event):
-        id = event.GetId()
-        if id == 3:
-            self.currentLine = 'Free'
-            self.DrawBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'draw.gif', wx.BITMAP_TYPE_GIF)
-            self.DrawBtn.SetShortHelp("Freehand Line Tool")
-            self.DrawBtn.SetLongHelp("Freehand Line Tool")
-        elif id == 4:
-            self.currentLine = 'Poly'
-            self.DrawBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'dash.png', wx.BITMAP_TYPE_PNG)
-            self.DrawBtn.SetShortHelp("Poly Line Tool")
-            self.DrawBtn.SetLongHelp("Poly Line Tool")
-
-    def OnFogSelection(self, event):
-        id = event.GetId()
-        if id == 1:
-            self.currentFog = 'Show'
-            self.FogToolBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'showfog.png', wx.BITMAP_TYPE_PNG)
-            self.FogToolBtn.SetShortHelp("Show Fog Tool")
-            self.FogToolBtn.SetLongHelp("Show Fog Tool")
-        elif id == 2:
-            self.currentFog = 'Hide'
-            self.FogToolBtn.Bitmap = wx.Bitmap(orpg.dirpath.dir_struct["icon"] + 'hidefog.png', wx.BITMAP_TYPE_PNG)
-            self.FogToolBtn.SetShortHelp("Hide Fog Tool")
-            self.FogToolBtn.SetLongHelp("Hide Fog Tool")
-
-### Test Stuff
-class BlankFrame(wx.Frame):
-    def __init__(self, openrpg):
-        wx.Frame.__init__(self, None, title="New Map Test Window", size=(740,480))
-
-        self.map = MapWnd(self, openrpg)
-        self.basesizer = wx.BoxSizer(wx.VERTICAL)
-        self.basesizer.Add(self.map, 1, wx.EXPAND)
-
-        self.SetSizer(self.basesizer)
-        self.SetAutoLayout(True)
-        #self.Fit()
-
-
-class BlankApp(wx.App):
-    def OnInit(self):
-        self.frame = BlankFrame()
-        self.frame.Show()
-        self.SetTopWindow(self.frame)
-
-
-        return True
-
-if __name__ == "__main__":
-    app = BlankApp(0)
-    app.MainLoop()
\ No newline at end of file
--- a/orpg/map/_canvas.py	Mon Oct 12 23:24:10 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,994 +0,0 @@
-from threading import Lock
-import mimetypes
-import xml.dom.minidom as minidom
-
-import wx
-
-import orpg.dirpath
-from orpg.orpgCore import *
-from orpg.tools.rgbhex import RGBHex
-
-from _object import *
-
-from _circles import MapCircle
-from _text import MapText
-from _lines import MapLine
-from _grid import GridLayer
-from _fog import FogLayer
-
-USE_BUFFER = True
-if "wxMAC" in wx.PlatformInfo:
-    USE_BUFFER = False
-
-class MapCanvas(wx.ScrolledWindow):
-    def __init__(self, parent, openrpg):
-        wx.ScrolledWindow.__init__(self, parent, wx.ID_ANY, style=wx.HSCROLL | wx.VSCROLL | wx.NO_FULL_REPAINT_ON_RESIZE | wx.SUNKEN_BORDER)
-
-        self.openrpg = openrpg
-        self.log = self.openrpg.get_component("log")
-        self.xml = self.openrpg.get_component("xml")
-        self.dir_struct = self.openrpg.get_component("dir_struct")
-        self.validate = self.openrpg.get_component("validate")
-        self.settings = self.openrpg.get_component("settings")
-        self.session = self.openrpg.get_component("session")
-        self.chat = self.openrpg.get_component("chat")
-
-        self.lock = Lock()
-
-        self.RGBHex = RGBHex()
-
-        self.toolWnd = parent
-
-        self.shift = False
-        self.ctrl = False
-
-        self.selectedObjects = []
-        self.overObjects = []
-        self._objectId = 0
-
-        self.gridLayer = GridLayer(self)
-        self.circleLayer = MapCircle(self)
-        self.textLayer = MapText(self)
-        self.lineLayer = MapLine(self)
-        self.fogLayer = FogLayer(self)
-
-        self.zOrder = {}
-        self.zOrder['tiles'] = []
-        self.zOrder["back"] = []
-        self.zOrder["front"] = []
-
-        self.bgImage = None
-        self.bgType = 'Image'
-        self.bgPath = None
-        self.backgroundColor = '#008040'
-
-        self.gridType = 'Square'
-        self.gridLines = wx.SOLID
-        self.gridSnap = True
-        self.gridSize = 60
-        self.gridColor = "#000000"
-
-        self.whiteboardColor = "#000000"
-
-        self.zoomScale = 1.0
-        self.lastZoomTime = time.time()
-        self.lastZoomScale = 1.0
-
-        self.useFog = False
-        self.fogRegion = []
-        self.fogColor = "#000000"
-
-        self.zoomScale = 1.0
-        self.lastZoomTime = time.time()
-        self.lastZoomScale = 1.0
-        self.zoomTimer = wx.Timer(self)
-        self.Bind(wx.EVT_TIMER, self.OnZoomTimer, self.zoomTimer)
-        #self.zoomTimer.Start(1000)
-
-        self.imageCache = {}
-
-        self._SetSize((1000,1000))
-
-        self.Bind(wx.EVT_PAINT, self.OnPaint)
-        self.Bind(wx.EVT_SIZE, self.OnSize)
-        self.Bind(wx.EVT_MOUSEWHEEL, self.OnZoom)
-        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
-        self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick)
-        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
-        self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
-        self.Bind(wx.EVT_MOTION, self.OnMotion)
-        self.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
-        self.Bind(wx.EVT_CLOSE, self.OnClose)
-        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnBackground)
-        self.Bind(wx.EVT_KEY_DOWN, self.OnKey)
-        self.Bind(wx.EVT_KEY_UP, self.OnKey)
-
-        self.Bind(EVT_ENTER_OBJECT, self.EnterObject)
-        self.Bind(EVT_LEAVE_OBJECT, self.LeaveObject)
-        self.Bind(EVT_SELECT_OBJECT, self.ObjectSelected)
-        self.Bind(EVT_DESELECT_OBJECT, self.ObjectDeselected)
-
-        self.roleTimer = wx.Timer(self)
-        self.Bind(wx.EVT_TIMER, self.OnRoleTimer, self.roleTimer)
-
-        wx.CallAfter(self.OnSize, None)
-
-
-    #Public API
-    def UpdateMap(self, send=True):
-        cdc = wx.ClientDC(self)
-        self.PrepareDC(cdc)
-        cdc.SetBackgroundMode(wx.TRANSPARENT)
-        if USE_BUFFER:
-            bdc = wx.BufferedDC(cdc, self._buffer)
-            bdc.Clear()
-            dc = wx.GraphicsContext.Create(bdc)
-        else:
-            cdc.Clear()
-            dc = wx.GraphicsContext.Create(cdc)
-
-
-        dc.SetPen(wx.TRANSPARENT_PEN)
-        dc.SetBrush(wx.TRANSPARENT_BRUSH)
-
-        #Draw BG Color
-        r,g,b = self.RGBHex.rgb_tuple(self.backgroundColor)
-        brush = wx.Brush(wx.Color(r,g,b,255))
-        dc.SetBrush(brush)
-
-        path = dc.CreatePath()
-
-        dc.PushState()
-        path.AddRectangle(0, 0, self.size[0]+2, self.size[1]+2)
-        dc.DrawPath(path)
-        dc.PopState()
-
-        dc.SetBrush(wx.NullBrush)
-
-        #Set the Zoom
-        dc.Scale(self.zoomScale, self.zoomScale)
-
-        #Draw BG Image
-        if self.bgImage != None:
-            if self.bgType == 'Image':
-                dc.DrawBitmap(self.bgImage, self.offset[0], self.offset[1], self.bgImage.GetWidth(), self.bgImage.GetHeight())
-            else:
-                bmpW = self.bgImage.GetWidth()
-                bmpH = self.bgImage.GetHeight()
-
-                pos = wx.Point(self.offset[0], self.offset[1])
-                while pos.x < self.size[0]:
-                    dc.DrawBitmap(self.bgImage, pos.x, pos.y, self.bgImage.GetWidth(), self.bgImage.GetHeight())
-                    while pos.y < self.size[1]:
-                        pos.y += bmpH
-                        dc.DrawBitmap(self.bgImage, pos.x, pos.y, self.bgImage.GetWidth(), self.bgImage.GetHeight())
-                    pos.y = 0
-                    pos.x += bmpW
-
-        #Draw Tiles
-        for tile in self.zOrder['tiles']:
-            tile.Draw(dc)
-
-        #Draw Grid
-        self.gridLayer.Draw(dc)
-
-        #Draw Objects
-        for object in self.zOrder['back']:
-            object.Draw(dc)
-
-        zl = self.zOrder.keys()
-        zl.remove('back')
-        zl.remove('front')
-        zl.remove('tiles')
-        zl.sort()
-
-        for layer in zl:
-            for object in self.zOrder[layer]:
-                object.Draw(dc)
-
-        for object in self.zOrder['front']:
-            object.Draw(dc)
-
-
-        #Draw Fog
-        if self.useFog:
-            self.fogLayer.Draw(dc)
-
-        dc.SetBrush(wx.NullBrush)
-
-        dc.Scale(1/self.zoomScale, 1/self.zoomScale)
-
-        if self.zoomScale != 1.0:
-            pos = self.GetViewStart()
-            unit = self.GetScrollPixelsPerUnit()
-            pos = [pos[0]*unit[0],pos[1]*unit[1]]
-            font = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
-            dc.SetFont(font, wx.BLACK)
-
-            dc.DrawText("Zoom Factor: " + str(self.zoomScale), pos[0], pos[1], dc.CreateBrush(wx.WHITE_BRUSH))
-
-    def Clear(self):
-        self._SetSize((1000,1000))
-        self.selectedObjects = []
-        self.overObjects = []
-        self._objectId = 0
-        self.bgImage = None
-        self.bgType = 'Image'
-        self.bgPath = None
-
-        self.backgroundColor = '#008040'
-        r, g, b = self.RGBHex.rgb_tuple(self.backgroundColor)
-        self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.BGColorBtn)
-
-        self.gridType = 'Square'
-        self.gridLines = wx.SOLID
-        self.gridSnap = True
-        self.gridSize = 60
-        self.gridColor = "#000000"
-
-        self.whiteboardColor = "#000000"
-        r, g, b = self.RGBHex.rgb_tuple(self.whiteboardColor)
-        self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.ColorBtn)
-
-        self.zoomScale = 1.0
-        self.lastZoomTime = time.time()
-        self.lastZoomScale = 1.0
-
-        self.useFog = False
-        self.fogRegion = []
-        self.fogColor = "#000000"
-
-        self.OnRemoveAllObjects(None)
-
-        self.toolWnd.Freeze()
-        for btn in self.toolWnd.exclusiveToolList:
-            self.toolWnd.exclusiveToolList[btn].SetToggled(False)
-
-        self.toolWnd.FogBtn.SetToggled(False)
-        self.toolWnd.SelectorBtn.SetToggled(True)
-        self.toolWnd.Thaw()
-
-    def GetNewObjectId(self):
-        return str(self._objectId+1)
-
-    #Map Events
-    def OnBackground(self, event):
-        #Dont do it
-        pass
-
-    def OnPaint(self, event):
-        if USE_BUFFER:
-            dc = wx.PaintDC(self)
-            self.PrepareDC(dc)
-            dc.DrawBitmap(self._buffer, 0, 0)
-        else:
-            event.Skip()
-
-
-    def OnSize(self, event):
-        self._buffer = wx.EmptyBitmap(self.size[0], self.size[1])
-        self._FixScroll()
-        wx.CallAfter(self.UpdateMap)
-
-
-    def OnZoom(self, event):
-        if event.GetWheelRotation() < 0:
-            self.zoomScale -= .1
-            if self.zoomScale < .5:
-                self.zoomScale = .5
-            else:
-                self.lastZoomTime = time.time()
-                self._FixScroll()
-                self.UpdateMap()
-        else:
-            self.zoomScale += .1
-
-            if self.zoomScale > 1.5:
-                self.zoomScale = 1.5
-            else:
-                self.lastZoomTime = time.time()
-                self._FixScroll()
-                self.UpdateMap()
-
-    def OnKey(self, event):
-        self.shift = False
-        self.ctrl = False
-        if event.ShiftDown():
-            self.shift = True
-        elif event.ControlDown():
-            self.ctrl = True
-
-
-    def EnterObject(self, event):
-        obj = event.GetObject()
-        self.overObjects.append(obj)
-        obj.Highlight()
-
-    def LeaveObject(self, event):
-        obj = event.GetObject()
-        try:
-            self.overObjects.remove(obj)
-        except:
-            pass
-        obj.UnHighlight()
-
-    def ObjectSelected(self, event):
-        obj = event.GetObject()
-        self.selectedObjects.append(obj)
-        try:
-            self.overObjects.remove(obj)
-        except:
-            pass
-        obj.UnHighlight()
-
-    def ObjectDeselected(self, event):
-        obj = event.GetObject()
-        try:
-            self.selectedObjects.remove(obj)
-        except:
-            pass
-        obj.Update()
-
-    def OnLeftDown(self, event):
-        dc = wx.ClientDC(self)
-        self.PrepareDC(dc)
-        pos = event.GetLogicalPosition(dc)
-        pos.x /= self.zoomScale
-        pos.y /= self.zoomScale
-
-        if self.toolWnd.AddShapeBtn.GetToggled() and self.toolWnd.currentShape == 'Circle':
-            self.circleLayer.OnLeftDown(pos)
-
-        elif self.toolWnd.AddTextBtn.GetToggled():
-            self.textLayer.OnLeftDown(pos)
-
-        elif self.toolWnd.DrawBtn.GetToggled():
-            self.lineLayer.OnLeftDown(pos)
-
-        elif self.toolWnd.SelectorBtn.GetToggled() and (self.selectedObjects == [] or self.ctrl or self.shift) and not (self.useFog and self.fogLayer.region.Contains(pos.x, pos.y) and not self.toolWnd.gmToolBar.IsShown()):
-            self.initiatPos = pos
-            self.lxd = 0
-            self.lyd = 0
-            if len(self.overObjects) == 0:
-                return
-            elif len(self.overObjects) == 1:
-                self.overObjects[0].Select()
-            else:
-                if not self.shift:
-                    menu = wx.Menu("Object Selection")
-                    id = 0
-                    for obj in self.overObjects:
-                        menu.Append(id, obj.GetName())
-                        id += 1
-
-                    def selectmenu(event):
-                        id = event.GetId()
-                        self.overObjects[id].Select()
-                        self.Unbind(wx.EVT_MENU)
-
-                    self.Bind(wx.EVT_MENU, selectmenu)
-                    self.PopupMenu(menu)
-                else:
-                    for i in xrange(len(self.overObjects)):
-                        self.overObjects[0].Select()
-
-        elif self.toolWnd.SelectorBtn.GetToggled() and not self.selectedObjects == []:
-            xd = (self.initiatPos.x+pos.x)*(self.initiatPos.x+pos.x)
-            yd = (self.initiatPos.y+pos.y)*(self.initiatPos.y+pos.y)
-
-            for i in xrange(len(self.selectedObjects)):
-                self.selectedObjects[0].Deselect()
-
-        elif self.toolWnd.FogToolBtn.GetToggled():
-            self.fogLayer.OnLeftDown(pos)
-
-    def OnLeftDClick(self, event):
-        dc = wx.ClientDC(self)
-        self.PrepareDC(dc)
-        pos = event.GetLogicalPosition(dc)
-        pos.x /= self.zoomScale
-        pos.y /= self.zoomScale
-
-        if self.toolWnd.DrawBtn.GetToggled():
-            self.lineLayer.OnLeftDClick(pos)
-
-    def OnLeftUp(self, event):
-        dc = wx.ClientDC(self)
-        self.PrepareDC(dc)
-        pos = event.GetLogicalPosition(dc)
-        pos.x /= self.zoomScale
-        pos.y /= self.zoomScale
-
-        if self.toolWnd.AddShapeBtn.GetToggled() and self.toolWnd.currentShape == 'Circle':
-            self.circleLayer.OnLeftUp(pos)
-
-        elif self.toolWnd.FogToolBtn.GetToggled():
-            self.fogLayer.OnLeftUp(pos)
-
-        elif self.toolWnd.DrawBtn.GetToggled():
-            self.lineLayer.OnLeftUp(pos)
-
-        elif self.toolWnd.SelectorBtn.GetToggled() and self.selectedObjects == []:
-            rgn = wx.Region(self.initiatPos.x, self.initiatPos.y, self.lxd, self.lyd)
-
-            for object in self.zOrder['back']:
-                if rgn.Contains(object.start.x, object.start.y):
-                    object.Select()
-
-            zl = self.zOrder.keys()
-            zl.remove('back')
-            zl.remove('front')
-            zl.remove('tiles')
-            zl.sort()
-
-            for layer in zl:
-                for object in self.zOrder[layer]:
-                    if rgn.Contains(object.start.x, object.start.y):
-                        object.Select()
-
-            for object in self.zOrder['front']:
-                if rgn.Contains(object.start.x, object.start.y):
-                    object.Select()
-
-            self.lxd = 0
-            self.lyd = 0
-            self.initiatPos = pos
-        self.Refresh()
-
-    def OnMotion(self, event):
-        dc = wx.ClientDC(self)
-        self.PrepareDC(dc)
-        pos = event.GetLogicalPosition(dc)
-        pos.x /= self.zoomScale
-        pos.y /= self.zoomScale
-
-
-        #HitTest
-        for object in self.zOrder['back']:
-            object.HitTest(pos)
-
-        zl = self.zOrder.keys()
-        zl.remove('back')
-        zl.remove('front')
-        zl.remove('tiles')
-        zl.sort()
-
-        for layer in zl:
-            for object in self.zOrder[layer]:
-                object.HitTest(pos)
-
-        for object in self.zOrder['front']:
-            object.HitTest(pos)
-
-        if self.toolWnd.AddShapeBtn.GetToggled() and event.m_leftDown and self.toolWnd.currentShape == 'Circle':
-            self.circleLayer.OnMotion(pos)
-
-        elif self.toolWnd.DrawBtn.GetToggled() and self.lineLayer.start != wx.Point(0,0):
-            self.lineLayer.OnMotion(pos)
-
-        elif self.toolWnd.SelectorBtn.GetToggled() and self.selectedObjects != [] and not (self.ctrl or self.shift):
-            xd = (pos.x-self.initiatPos.x)
-            yd = (pos.y-self.initiatPos.y)
-            for obj in self.selectedObjects:
-                obj.start.x += xd
-                obj.start.y += yd
-                obj.Update()
-                self.initiatPos = pos
-
-
-        elif self.toolWnd.SelectorBtn.GetToggled() and self.selectedObjects == [] and event.m_leftDown:
-            dc.SetBrush(wx.TRANSPARENT_BRUSH)
-            pen = wx.Pen(wx.BLACK, 3, wx.DOT)
-            dc.SetPen(pen)
-            dc.SetLogicalFunction(wx.INVERT)
-
-            xd = (pos.x-self.initiatPos.x)
-            yd = (pos.y-self.initiatPos.y)
-
-            if self.lxd != 0 and self.lyd != 0:
-                r = wx.Rect(self.initiatPos.x, self.initiatPos.y, self.lxd, self.lyd)
-                dc.DrawRectangleRect(r)
-
-            self.lxd = xd
-            self.lyd = yd
-            r = wx.Rect(self.initiatPos.x, self.initiatPos.y, self.lxd, self.lyd)
-            dc.DrawRectangleRect(r)
-
-        elif (self.toolWnd.FogToolBtn.GetToggled()) and event.m_leftDown:
-            self.fogLayer.OnMotion(pos)
-
-    def OnRightDown(self, event):
-        mapmenu = wx.Menu()
-
-        item = wx.MenuItem(mapmenu, wx.ID_ANY, "Load Map", "Load Map")
-        #self.Bind(wx.EVT_MENU, self.OnOpenBtn, item)
-        mapmenu.AppendItem(item)
-
-        item = wx.MenuItem(mapmenu, wx.ID_ANY, "Save Map", "Save Map")
-        #self.Bind(wx.EVT_MENU, self.OnSaveBtn, item)
-        mapmenu.AppendItem(item)
-
-        item = wx.MenuItem(mapmenu, wx.ID_ANY, "Default Map", "Default Map")
-        self.Bind(wx.EVT_MENU, self.OnDefaultBtn, item)
-        mapmenu.AppendItem(item)
-
-        item = wx.MenuItem(mapmenu, wx.ID_ANY, "Map Properties", "Map Properties")
-        #self.Bind(wx.EVT_MENU, OnMapPropsBtn, item)
-        mapmenu.AppendItem(item)
-
-        bgmenu = wx.Menu()
-
-        item = wx.MenuItem(bgmenu, wx.ID_ANY, "Change Background Image", "Change Background Image")
-        self.Bind(wx.EVT_MENU, self.OnBGBtn, item)
-        bgmenu.AppendItem(item)
-
-        item = wx.MenuItem(bgmenu, wx.ID_ANY, "Change Background Color", "Change Background Color")
-        self.Bind(wx.EVT_MENU, self.OnBGColorBtn, item)
-        bgmenu.AppendItem(item)
-
-        item = wx.MenuItem(bgmenu, wx.ID_ANY, "Grid Properties", "Grid Properties")
-        #self.Bind(wx.EVT_MENU, self.OnGridBtn, item)
-        bgmenu.AppendItem(item)
-
-        fogmenu = wx.Menu()
-
-        item = wx.MenuItem(fogmenu, wx.ID_ANY, "Toggle Fog", "Toggle Fog")
-        self.Bind(wx.EVT_MENU, self.OnFogBtn, item)
-        fogmenu.AppendItem(item)
-
-        item = wx.MenuItem(fogmenu, wx.ID_ANY, "Fog Color", "Fog Color")
-        self.Bind(wx.EVT_MENU, self.OnFogColorBtn, item)
-        fogmenu.AppendItem(item)
-
-        menu = wx.Menu()
-
-        if self.toolWnd.gmToolBar.IsShown():
-            menu.AppendMenu(wx.ID_ANY, "Map", mapmenu)
-            menu.AppendMenu(wx.ID_ANY, "Background", bgmenu)
-            menu.AppendMenu(wx.ID_ANY, "Fog", fogmenu)
-            menu.AppendSeparator()
-            item = wx.MenuItem(menu, wx.ID_ANY, "Miniture Properties", "Miniture Properties")
-            #self.Bind(wx.EVT_MENU, self.OnColorBtn, item)
-            menu.AppendItem(item)
-            menu.AppendSeparator()
-
-        item = wx.MenuItem(menu, wx.ID_ANY, "Whiteboard Color", "Whiteboard Color")
-        self.Bind(wx.EVT_MENU, self.OnColorBtn, item)
-        menu.AppendItem(item)
-
-
-        def ObjectMenu(event):
-            id = event.GetId()
-            objid = int(menu.GetHelpString(id))
-            menuname = menu.GetLabel(id)
-            obj = self.overObjects[objid]
-
-            if menuname == "Move To Back":
-                self.MoveToBack(obj)
-
-            elif menuname == "Move Back":
-                self.MoveBack(obj)
-
-            elif menuname == "Move Forward":
-                self.MoveForward(obj)
-
-            elif menuname == "Move To Front":
-                self.MoveToFront(obj)
-
-            elif menuname == "Remove":
-                self.zOrder[obj.zOrder].remove(obj)
-                obj.Update()
-
-            self.Unbind(wx.EVT_MENU)
-            self.overObjects.remove(obj)
-
-
-        if len(self.overObjects):
-            menu.AppendSeparator()
-
-        id = 0
-        for obj in self.overObjects:
-            if obj.IsShown() or self.toolWnd.gmToolBar.IsShown():
-                objmenu = wx.Menu()
-                item = wx.MenuItem(objmenu, wx.ID_ANY, "Move To Back", str(id))
-                self.Bind(wx.EVT_MENU, ObjectMenu, item)
-                objmenu.AppendItem(item)
-                item = wx.MenuItem(objmenu, wx.ID_ANY, "Move Back", str(id))
-                self.Bind(wx.EVT_MENU, ObjectMenu, item)
-                objmenu.AppendItem(item)
-                item = wx.MenuItem(objmenu, wx.ID_ANY, "Move Forward", str(id))
-                self.Bind(wx.EVT_MENU, ObjectMenu, item)
-                objmenu.AppendItem(item)
-                item = wx.MenuItem(objmenu, wx.ID_ANY, "Move To Front", str(id))
-                self.Bind(wx.EVT_MENU, ObjectMenu, item)
-                objmenu.AppendItem(item)
-                objmenu.AppendSeparator()
-                if obj.IsShown():
-                    item = wx.MenuItem(objmenu, wx.ID_ANY, "Hide", str(id))
-                    self.Bind(wx.EVT_MENU, obj.Hide, item)
-                    objmenu.AppendItem(item)
-                    objmenu.AppendSeparator()
-                elif self.toolWnd.gmToolBar.IsShown():
-                    item = wx.MenuItem(objmenu, wx.ID_ANY, "Show", str(id))
-                    self.Bind(wx.EVT_MENU, obj.Show, item)
-                    objmenu.AppendItem(item)
-                    objmenu.AppendSeparator()
-                item = wx.MenuItem(objmenu, wx.ID_ANY, "Remove", str(id))
-                self.Bind(wx.EVT_MENU, ObjectMenu, item)
-                objmenu.AppendItem(item)
-                item = wx.MenuItem(objmenu, wx.ID_ANY, "Properties", str(id))
-                self.Bind(wx.EVT_MENU, obj.ShowProperties, item)
-                objmenu.AppendItem(item)
-                menu.AppendMenu(wx.ID_ANY, obj.GetName(), objmenu)
-
-        menu.AppendSeparator()
-        item = wx.MenuItem(menu, wx.ID_ANY, "Remove All Objects", "Remove All Whiteboard Items")
-        self.Bind(wx.EVT_MENU, self.OnRemoveAllObjects, item)
-        menu.AppendItem(item)
-
-        self.PopupMenu(menu)
-
-
-    def OnRemoveAllObjects(self, event):
-        for layer in self.zOrder:
-            for i in xrange(len(self.zOrder[layer])):
-                del self.zOrder[layer][0]
-
-        self.zOrder = {}
-        self.zOrder['tiles'] = []
-        self.zOrder["back"] = []
-        self.zOrder["front"] = []
-        if event != None:
-            self.UpdateMap()
-
-    def MoveToBack(self, object):
-        self.zOrder[object.zOrder].remove(object)
-        self.zOrder['back'].append(object)
-        object.zOrder = 'back'
-        self.UpdateMap()
-
-    def MoveToFront(self, object):
-        self.zOrder[object.zOrder].remove(object)
-        self.zOrder['front'].append(object)
-        object.zOrder = 'front'
-        self.UpdateMap()
-
-    def MoveBack(self, object):
-        self.zOrder[object.zOrder].remove(object)
-
-        zl = self.zOrder.keys()
-        zl.remove('back')
-        zl.remove('front')
-        zl.remove('tiles')
-        zl.sort()
-        lzo = 1
-        if len(zl):
-            lzo = zl.pop()
-
-        if object.zOrder == 'back' or object.zOrder == 1:
-            self.zOrder['back'].append(object)
-            object.zOrder = 'back'
-        elif object.zOrder == 'front':
-            if not self.zOrder.has_key(lzo):
-                self.zOrder[lzo] = []
-            self.zOrder[lzo].append(object)
-            object.zOrder = lzo
-        else:
-            object.zOrder -= 1
-            if not self.zOrder.has_key(object.zOrder):
-                self.zOrder[object.zOrder] = []
-            self.zOrder[object.zOrder].append(object)
-        self.UpdateMap()
-
-    def MoveForward(self, object):
-        self.zOrder[object.zOrder].remove(object)
-
-        zl = self.zOrder.keys()
-        zl.remove('back')
-        zl.remove('front')
-        zl.remove('tiles')
-        zl.sort()
-        lzo = 1
-        if len(zl):
-            lzo = zl.pop()
-
-        if object.zOrder == 'back':
-            if not self.zOrder.has_key(1):
-                self.zOrder[1] = []
-            self.zOrder[1].append(object)
-            object.zOrder = 1
-        elif z == 'front':
-            self.zOrder['front'].append(object)
-            object.zOrder = 'front'
-        else:
-            object.zOrder += 1
-            if not self.zOrder.has_key(object.zOrder):
-                self.zOrder[object.zOrder] = []
-            self.zOrder[object.zOrder].append(object)
-        self.UpdateMap()
-
-    def OnScroll(self, event):
-        event.Skip()
-        self.Refresh()
-
-    def OnZoomTimer(self, event):
-        if (time.time() - self.lastZoomTime) >= 3 and self.lastZoomScale != self.zoomScale:
-            #Send Zoome Notice to other clients
-            self.lastZoomTime = time.time()
-            self.lastZoomScale = self.zoomScale
-
-    def OnRoleTimer(self, event):
-        #Figure out the users role
-        if self.session.my_role() == self.session.ROLE_GM:
-            self.role = 'GM'
-        elif self.session.my_role() == self.session.ROLE_PLAYER:
-            self.role = 'Player'
-        else:
-            self.role = 'Lurker'
-
-        if self.role == 'GM' and not self.toolWnd.gmToolBar.IsShown() and not (str(self.session.group_id) == '0' and str(self.session.status) == '1'):
-            self.toolWnd.Freeze()
-            self.toolWnd.gmToolBar.Show()
-            self.toolWnd.Thaw()
-        elif self.role == 'Player' and not (str(self.session.group_id) == '0' and str(self.session.status) == '1'):
-            if self.toolWnd.gmToolBar.IsShown():
-                self.toolWnd.Freeze()
-                self.toolWnd.gmToolBar.Hide()
-                self.toolWnd.Thaw()
-
-            if not self.toolWnd.playerToolBar.IsShown():
-                self.toolWnd.Freeze()
-                self.toolWnd.playerToolBar.Show()
-                self.toolWnd.Thaw()
-        elif self.role == 'Lurker' or (str(self.session.group_id) == '0' and str(self.session.status) == '1'):
-            if self.toolWnd.playerToolBar.IsShown():
-                self.toolWnd.Freeze()
-                self.toolWnd.gmToolBar.Hide()
-                self.toolWnd.playerToolBar.Hide()
-                self.toolWnd.Thaw()
-
-        try:
-            self.toolWnd.Layout()
-        except:
-            pass
-
-    def OnClose(self, event):
-        self.zoomTimer.Stop()
-        self.roleTimer.Stop()
-        event.Skip()
-
-    #Toolbar Events
-    def OnDefaultBtn(self, event):
-        self.Clear()
-        wx.CallAfter(self.UpdateMap)
-
-    def OnColorBtn(self, event):
-        newcolor = self.RGBHex.do_hex_color_dlg(self.toolWnd)
-        if newcolor == None:
-            return
-
-        self.whiteboardColor = newcolor
-        r, g, b = self.RGBHex.rgb_tuple(self.whiteboardColor)
-        self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.ColorBtn)
-
-    def OnBGColorBtn(self, event):
-        newcolor = self.RGBHex.do_hex_color_dlg(self.toolWnd)
-        if newcolor == None:
-            return
-
-        self.backgroundColor = newcolor
-        r, g, b = self.RGBHex.rgb_tuple(self.backgroundColor)
-        self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.BGColorBtn)
-        self.UpdateMap()
-
-    def OnFogColorBtn(self, event):
-        newcolor = self.RGBHex.do_hex_color_dlg(self.toolWnd)
-        if newcolor == None:
-            return
-
-        self.fogColor = newcolor
-        r, g, b = self.RGBHex.rgb_tuple(self.fogColor)
-        self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.FogColorBtn)
-        self.UpdateMap()
-
-    def OnExlusiveBtn(self, event):
-        id = event.GetId()
-        #This is backwards because the Toggle Switch does not get set until AFTER The mouse gets released
-        if not self.toolWnd.exclusiveToolList[id].GetToggled():
-            self.toolWnd.Freeze()
-            #Disable all mutualy exclusive tools
-            for btn in self.toolWnd.exclusiveToolList:
-                if self.toolWnd.exclusiveToolList[btn].GetId() != id:
-                    self.toolWnd.exclusiveToolList[btn].SetToggled(False)
-            self.toolWnd.Thaw()
-        else:
-            wx.CallAfter(self.toolWnd.SelectorBtn.SetToggled, True)
-
-    def OnFogBtn(self, event):
-        if not self.toolWnd.FogBtn.GetToggled():
-            self.useFog = True
-        else:
-            self.useFog = False
-            self.toolWnd.Freeze()
-            self.toolWnd.SelectorBtn.SetToggled(True)
-            self.toolWnd.FogToolBtn.SetToggled(False)
-            self.toolWnd.Thaw()
-        self.fogRegion = []
-        self.UpdateMap()
-
-    def OnBGBtn(self, event):
-        dlg = wx.Dialog(self.toolWnd, wx.ID_ANY, title="Background Properties")
-        sizer = wx.BoxSizer(wx.HORIZONTAL)
-
-        filename = wx.TextCtrl(dlg, wx.ID_ANY)
-        filename.Hide()
-
-        bgpath = wx.TextCtrl(dlg, wx.ID_ANY)
-        if self.bgPath != None:
-            bgpath.SetValue(self.bgPath)
-
-        bgtype = wx.Choice(dlg, wx.ID_ANY, choices=['Image', 'Texture'])
-        bgtype.SetStringSelection(self.bgType)
-
-        browsebtn = wx.Button(dlg, wx.ID_ANY, "Browse")
-        okbtn = wx.Button(dlg, wx.ID_OK)
-        cancelbtn = wx.Button(dlg, wx.ID_CANCEL)
-
-        sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Image Path"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2)
-        sizer.Add(bgpath, 0, wx.EXPAND|wx.ALL, 3)
-        sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Image Type"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2)
-        sizer.Add(bgtype, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 3)
-        sizer.Add(browsebtn, 0, wx.EXPAND|wx.ALL, 2)
-        sizer.Add(okbtn, 0, wx.EXPAND|wx.ALL, 3)
-        sizer.Add(cancelbtn, 0, wx.EXPAND|wx.ALL, 2)
-
-        dlg.SetSizer(sizer)
-        dlg.SetAutoLayout(True)
-        dlg.Fit()
-
-        def OnBrowse(event):
-            filedlg = wx.FileDialog(self, "Select an Image File", self.dir_struct["user"], wildcard="Image files (*.bmp, *.gif, *.jpg, *.png)|*.bmp;*.gif;*.jpg;*.png", style=wx.HIDE_READONLY|wx.OPEN)
-            if filedlg.ShowModal() != wx.ID_OK:
-                filedlg.Destroy()
-                return
-
-            bgpath.SetValue(filedlg.GetPath())
-            filename.SetValue(filedlg.GetFilename())
-
-        dlg.Bind(wx.EVT_BUTTON, OnBrowse, browsebtn)
-        dlg.Show()
-
-        if not dlg.ShowModal() == wx.ID_OK:
-            dlg.Destroy()
-            return
-
-        self.bgType = bgtype.GetStringSelection()
-
-        if bgpath.GetValue().lower().find('http:') == -1:
-            file = open(bgpath.GetValue(), "rb")
-            imgdata = file.read()
-            file.close()
-
-            (imgtype,j) = mimetypes.guess_type(filename.GetValue())
-
-            postdata = urllib.urlencode({'filename':filename.GetValue(), 'imgdata':imgdata, 'imgtype':imgtype})
-
-            thread.start_new_thread(self.__Upload, (postdata, bgpath.GetValue(), "Background"))
-        else:
-            self.bgImage = self._LoadImage(bgpath.GetValue())
-            self.UpdateMap()
-
-
-    #Private Methods
-    def _SetSize(self, size):
-        if size[0] == -1:
-            size[0] = self.size[0]
-        if size[1] == -1:
-            size[1] = self.size[1]
-
-        if size[0] < 300:
-            size = (300, size[1])
-        if size[1] < 300:
-            size = (size[0], 300)
-
-        size1  = self.GetClientSizeTuple()
-
-        if size[0] < size1[0]:
-            size = (size1[0], size[1])
-        if size[1] < size1[1]:
-            size = (size[0], size1[1])
-
-        self.sizeChanged = 1
-        self.size = size
-        self._FixScroll()
-
-    def _FixScroll(self):
-        scale = self.zoomScale
-        pos = self.GetViewStart()
-        unit = self.GetScrollPixelsPerUnit()
-        pos = [pos[0]*unit[0],pos[1]*unit[1]]
-        size = self.GetClientSize()
-        unit = [10*scale,10*scale]
-        if (unit[0] == 0 or unit[1] == 0):
-            return
-        pos[0] /= unit[0]
-        pos[1] /= unit[1]
-        mx = [int(self.size[0]*scale/unit[0])+1, int(self.size[1]*scale/unit[1]+1)]
-        self.SetScrollbars(unit[0], unit[1], mx[0], mx[1], pos[0], pos[1])
-
-    def _LoadImage(self, path, miniId=None):
-        if self.imageCache.has_key(path):
-            return self.imageCache[path]
-
-        while len(self.imageCache) > int(self.settings.get_setting("ImageCacheSize")):
-            keys = self.imageCache.keys()
-            del self.imageCache[keys[0]]
-
-
-        thread.start_new_thread(self.__DownloadImage, (path, miniId))
-
-        return wx.Bitmap(orpg.dirpath.dir_struct["icon"] + "fetching.png", wx.BITMAP_TYPE_PNG)
-
-    def _ClearCache(self):
-        for key in self.imageCache:
-            del self.imageCache[key]
-
-    #Threads
-    def __Upload(self, postdata, filename, type="Background"):
-        self.lock.acquire()
-
-        url = self.settings.get_setting('ImageServerBaseURL')
-        file = urllib.urlopen(url, postdata)
-        recvdata = file.read()
-        file.close()
-        try:
-            xml_dom = minidom.parseString(recvdata)._get_documentElement()
-
-            if xml_dom.nodeName == 'path':
-                path = xml_dom.getAttribute('url')
-                path = urllib.unquote(path)
-
-                if type == 'Background':
-                    self.bgImage = self._LoadImage(path)
-                    self.bgPath = path
-
-                else:
-                    self.minis.append(self.mapLayer.AddMiniture(path))
-
-                self.UpdateMap()
-
-            else:
-                self.chat.InfoPost(xml_dom.getAttribute('msg'))
-        except Exception, e:
-            print e
-            print recvdata
-
-        self.lock.release()
-
-    def __DownloadImage(self, path, miniId):
-        self.lock.acquire()
-
-        uriPath = urllib.unquote(path)
-        try:
-            data = urllib.urlretrieve(uriPath)
-
-            if data[0] and data[1].getmaintype() == "image":
-                imageType = data[1].gettype()
-                img = wx.ImageFromMime(data[0], imageType).ConvertToBitmap()
-                self.imageCache[path] = img
-
-                if miniId == None:
-                    self.bgImage = img
-                    if self.bgType == 'Image':
-                        self._SetSize((img.GetHeight(), img.GetWidth()))
-
-                else:
-                    mini = self.GetMiniById(miniId)
-                    mini.image = img
-
-                self.UpdateMap()
-        except Exception, e:
-            self.chat.InfoPost("Unable to resolve/open the specified URI; image was NOT laoded:" + path)
-
-        urllib.urlcleanup()
-        self.lock.release()
\ No newline at end of file
--- a/orpg/map/_circles.py	Mon Oct 12 23:24:10 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-from math import sqrt
-
-import wx
-
-import orpg.dirpath
-from orpg.orpgCore import *
-
-from _object import MapObject
-
-class MapCircle(MapObject):
-    def __init__(self, canvas, center=wx.Point(0,0), radius=0, color="#000000"):
-        MapObject.__init__(self, canvas=canvas)
-        self.start = center
-        self.radius = int(radius)
-        self.color = color
-
-        r, g, b = self.RGBHex.rgb_tuple(self.color)
-        self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255)
-
-        self.id = 'circle-' + self.canvas.GetNewObjectId()
-
-
-    def Draw(self, dc):
-        path = dc.CreatePath()
-
-        if not self.highlighed:
-            c = self.color
-        else:
-            c = self.hcolor
-        r, g, b = self.RGBHex.rgb_tuple(c)
-
-        pen = wx.TRANSPARENT_PEN
-        brush = wx.TRANSPARENT_BRUSH
-        if self.IsShown():
-            brush = wx.Brush(wx.Color(r, g, b, 128))
-            pen = wx.Pen(wx.Color(r, g, b, 128))
-        elif self.canvas.toolWnd.gmToolBar.IsShown():
-            brush = wx.Brush(wx.Color(r, g, b, 40))
-            pen = wx.Pen(wx.Color(r, g, b, 40))
-            font = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
-            dc.SetFont(font, wx.RED)
-            w, h = dc.GetTextExtent("Hidden")
-            dc.DrawText("Hidden", self.start.x-(w/2), self.start.y-(h/2), dc.CreateBrush(wx.WHITE_BRUSH))
-
-        dc.SetBrush(brush)
-        dc.SetPen(pen)
-
-        path.AddCircle(self.start.x, self.start.y, self.radius)
-        path.CloseSubpath()
-        dc.DrawPath(path)
-
-        dc.SetBrush(wx.NullBrush)
-        dc.SetPen(wx.NullPen)
-
-        if self.selected:
-            self.DrawSelection(dc)
-
-    def DrawSelection(self, dc):
-        dc.SetBrush(wx.GREEN_BRUSH)
-        dc.SetPen(wx.GREEN_PEN)
-        path = dc.CreatePath()
-
-        path.AddRectangle(self.start.x-self.radius, self.start.y-self.radius, 5, 5)
-        path.AddRectangle(self.start.x-self.radius, self.start.y+self.radius, 5, 5)
-        path.AddRectangle(self.start.x+self.radius, self.start.y-self.radius, 5, 5)
-        path.AddRectangle(self.start.x+self.radius, self.start.y+self.radius, 5, 5)
-
-        path.MoveToPoint(self.start.x, self.start.y)
-        path.AddLineToPoint(self.start.x-10, self.start.y)
-        path.MoveToPoint(self.start.x, self.start.y)
-        path.AddLineToPoint(self.start.x, self.start.y+10)
-        path.MoveToPoint(self.start.x, self.start.y)
-        path.AddLineToPoint(self.start.x+10, self.start.y)
-        path.MoveToPoint(self.start.x, self.start.y)
-        path.AddLineToPoint(self.start.x, self.start.y-10)
-
-        dc.DrawPath(path)
-
-        dc.SetBrush(wx.NullBrush)
-        dc.SetPen(wx.NullPen)
-
-    def InObject(self, pos):
-        xd = (self.start.x-pos.x)*(self.start.x-pos.x)
-        yd = (self.start.y-pos.y)*(self.start.y-pos.y)
-        distance = sqrt(xd+yd)
-
-        if distance <= self.radius:
-            return True
-
-        return False
-
-    def GetName(self):
-        return 'Circle: ' + str(self.id) + ' Radius:' + str(self.radius) + ' Color:' + self.color
-
-    def ShowProperties(self, event):
-        dlg = wx.Dialog(self.canvas, wx.ID_ANY, "Circle Properties")
-        sizer = wx.BoxSizer(wx.HORIZONTAL)
-
-        radius = wx.TextCtrl(dlg, wx.ID_ANY)
-        radius.SetValue(str(self.radius))
-
-        colorbtn = wx.Button(dlg, wx.ID_ANY, "Color")
-        colorbtn.SetForegroundColour(self.hcolor)
-
-        def ColorBtn(event):
-            newcolor = self.RGBHex.do_hex_color_dlg(self.canvas)
-            if newcolor == None:
-                return
-
-            colorbtn.SetForegroundColour(newcolor)
-            dlg.Unbind(wx.EVT_BUTTON)
-
-        dlg.Bind(wx.EVT_BUTTON, ColorBtn, colorbtn)
-
-        sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Radius:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2)
-        sizer.Add(radius, 0, wx.EXPAND|wx.ALL, 3)
-        sizer.Add(colorbtn, 0, wx.ALL, 2)
-        sizer.Add(wx.Button(dlg, wx.ID_OK), 0, wx.ALL, 3)
-
-        dlg.SetSizer(sizer)
-        dlg.SetAutoLayout(True)
-        dlg.Fit()
-        dlg.Show()
-
-        if dlg.ShowModal() == wx.ID_OK:
-            self.radius = int(radius.GetValue())
-            r,g,b = colorbtn.GetForegroundColour().Get()
-            self.color = self.RGBHex.hexstring(r, g, b)
-            self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255)
-            self.Update(send=True, action="update")
-
-
-    def OnLeftDown(self, pos):
-        self.start = pos
-        self.lastRadius = 0
-        self.radius = 0
-
-    def OnMotion(self, pos):
-        dc = wx.ClientDC(self.canvas)
-        self.canvas.PrepareDC(dc)
-        dc.SetLogicalFunction(wx.EQUIV)
-        dc.SetUserScale(self.canvas.zoomScale, self.canvas.zoomScale)
-
-
-        if self.radius > 0:
-            dc.DrawCircle(self.start.x, self.start.y, self.radius)
-
-        xd = (self.start.x-pos.x)*(self.start.x-pos.x)
-        yd = (self.start.y-pos.y)*(self.start.y-pos.y)
-        self.radius = sqrt(xd+yd)
-
-        #self.lastRadius = self.radius
-        dc.DrawCircle(self.start.x, self.start.y, self.radius)
-
-    def OnLeftUp(self, pos):
-        xd = (self.start.x-pos.x)*(self.start.x-pos.x)
-        yd = (self.start.y-pos.y)*(self.start.y-pos.y)
-        radius = sqrt(xd+yd)
-
-        if radius > 15:
-            self.canvas.zOrder['front'].append(MapCircle(self.canvas, self.start, radius, self.canvas.whiteboardColor))
-            self.Update(send=True, action='new')
-        self.lastRadius = 0
-        self.start = wx.Point(0,0)
-        self.radius = 0
-
-    def _toxml(self, action="update"):
-        return ''
\ No newline at end of file
--- a/orpg/map/_fog.py	Mon Oct 12 23:24:10 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-from math import sqrt
-
-import wx
-
-import orpg.dirpath
-from orpg.orpgCore import *
-
-from _object import MapObject
-
-class FogLayer(MapObject):
-    def __init__(self, canvas):
-        MapObject.__init__(self, canvas=canvas)
-
-    def Draw(self, dc):
-        path = dc.CreatePath()
-        r, g, b = self.RGBHex.rgb_tuple(self.canvas.fogColor)
-        if self.canvas.toolWnd.gmToolBar.IsShown():
-            brush = wx.Brush(wx.Color(r, g, b, 128))
-        else:
-            brush = wx.Brush(wx.Color(r, g, b, 255))
-        dc.SetBrush(brush)
-
-        self.region = wx.Region(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2)
-
-        points = []
-        lp = 's'
-        for point in self.canvas.fogRegion:
-            if point == 's' or point == 'h':
-                if lp == 's' and len(points) > 0:
-                    self.region.XorRegion(wx.RegionFromPoints(points))
-                    self.region.SubtractRegion(wx.RegionFromPoints(points))
-                elif len(points) > 0:
-                    self.region.UnionRegion(wx.RegionFromPoints(points))
-                lp = point
-                points = []
-            else:
-                points.append((point.x, point.y))
-
-        if len(points) > 0:
-            if lp == 's':
-                self.region.XorRegion(wx.RegionFromPoints(points))
-                self.region.SubtractRegion(wx.RegionFromPoints(points))
-            else:
-                self.region.UnionRegion(wx.RegionFromPoints(points))
-
-        dc.ClipRegion(self.region)
-
-        dc.DrawRectangle(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2)
-
-        dc.SetBrush(wx.NullBrush)
-
-    def OnLeftDown(self, pos):
-        self.start = pos
-        self.lastPoint = pos
-        if self.canvas.toolWnd.currentFog == 'Show':
-            self.canvas.fogRegion.append('s')
-        else:
-            self.canvas.fogRegion.append('h')
-        self.canvas.fogRegion.append(pos)
-
-    def OnMotion(self, pos):
-        cdc = wx.ClientDC(self.canvas)
-        self.canvas.PrepareDC(cdc)
-
-        dc = wx.GraphicsContext.Create(cdc)
-        dc.Scale(self.canvas.zoomScale, self.canvas.zoomScale)
-
-        dc.SetPen(wx.WHITE_PEN)
-
-        path = dc.CreatePath()
-
-        xd = (self.lastPoint.x-pos.x)*(self.lastPoint.x-pos.x)
-        yd = (self.lastPoint.y-pos.y)*(self.lastPoint.y-pos.y)
-        distance = sqrt(xd+yd)
-
-        if distance > 5:
-            path.MoveToPoint(self.lastPoint.x, self.lastPoint.y)
-            path.AddLineToPoint(pos.x, pos.y)
-
-            self.canvas.fogRegion.append(pos)
-            self.lastPoint = pos
-
-        path.CloseSubpath()
-        dc.StrokePath(path)
-
-        dc.SetPen(wx.NullPen)
-
-    def OnLeftUp(self, pos):
-        self.canvas.fogRegion.append(pos)
-        self.canvas.fogRegion.append(self.start)
-        self.canvas.UpdateMap()
-
--- a/orpg/map/_grid.py	Mon Oct 12 23:24:10 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-import wx
-
-import orpg.dirpath
-from orpg.orpgCore import *
-from orpg.tools.rgbhex import RGBHex
-
-class GridLayer:
-    def __init__(self, canvas):
-        self.canvas = canvas
-        self.RGBHex = RGBHex()
-
-    def Draw(self, dc):
-        r, g, b = self.RGBHex.rgb_tuple(self.canvas.gridColor)
-        pen = wx.Pen(wx.Color(r, g, b, 255), 1, self.canvas.gridLines)
-        dc.SetPen(pen)
-
-        path = dc.CreatePath()
-
-        if self.canvas.gridType == 'Square':
-            self._DrawSquare(dc, path)
-
-        dc.SetPen(wx.NullPen)
-
-    def _DrawSquare(self, dc, path):
-        path.MoveToPoint(0, 0)
-        y = 0
-        while y < self.canvas.size[1]:
-            path.AddLineToPoint(self.canvas.size[0], y)
-            y += self.canvas.gridSize
-            path.MoveToPoint(0, y)
-
-        path.MoveToPoint(0, 0)
-        x = 0
-        while x < self.canvas.size[0]:
-            path.AddLineToPoint(x, self.canvas.size[0])
-            x += self.canvas.gridSize
-            path.MoveToPoint(x, 0)
-
-        dc.StrokePath(path)
\ No newline at end of file
--- a/orpg/map/_lines.py	Mon Oct 12 23:24:10 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-from math import sqrt
-
-import wx
-
-import orpg.dirpath
-from orpg.orpgCore import *
-
-from _object import MapObject
-
-class MapLine(MapObject):
-    def __init__(self, canvas, start=wx.Point(0,0), width=1, color="#000000", points=[]):
-        MapObject.__init__(self, canvas=canvas)
-        self.start = wx.Point(start[0], start[1])
-        self.color = color
-        self.points = points
-        self.width = width
-
-        r, g, b = self.RGBHex.rgb_tuple(self.color)
-        self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255)
-
-        self.id = 'line-' + self.canvas.GetNewObjectId()
-
-
-    def Draw(self, dc):
-        path = dc.CreatePath()
-
-        if not self.highlighed:
-            c = self.color
-        else:
-            c = self.hcolor
-        r, g, b = self.RGBHex.rgb_tuple(c)
-
-        pen = wx.Pen(wx.Color(r, g, b, 0), self.width)
-        if self.IsShown():
-            pen = wx.Pen(wx.Color(r, g, b, 255), self.width)
-        elif self.canvas.toolWnd.gmToolBar.IsShown():
-            pen = wx.Pen(wx.Color(r, g, b, 40), self.width)
-        dc.SetPen(pen)
-
-        dc.DrawLines(self.points)
-
-        dc.SetBrush(wx.NullBrush)
-        dc.SetPen(wx.NullPen)
-
-        if self.selected:
-            self.DrawSelection(dc)
-
-    def DrawSelection(self, dc):
-        dc.SetBrush(wx.GREEN_BRUSH)
-        dc.SetPen(wx.GREEN_PEN)
-        path = dc.CreatePath()
-
-        dc.DrawPath(path)
-
-        dc.SetBrush(wx.NullBrush)
-        dc.SetPen(wx.NullPen)
-
-    def InObject(self, pos):
-        for point in self.points:
-            xd = (point[0]-pos.x)*(point[0]-pos.x)
-            yd = (point[1]-pos.y)*(point[1]-pos.y)
-            distance = sqrt(xd+yd)
-
-            if distance <= self.width+1:
-                return True
-
-        return False
-
-    def GetName(self):
-        return self.id + ' Color:' + self.color
-
-    def ShowProperties(self, event):
-        dlg = wx.Dialog(self.canvas, wx.ID_ANY, "Circle Properties")
-        sizer = wx.BoxSizer(wx.HORIZONTAL)
-
-        radius = wx.TextCtrl(dlg, wx.ID_ANY)
-        radius.SetValue(str(self.radius))
-
-        colorbtn = wx.Button(dlg, wx.ID_ANY, "Color")
-        colorbtn.SetForegroundColour(self.hcolor)
-
-        def ColorBtn(event):
-            newcolor = self.RGBHex.do_hex_color_dlg(self.canvas)
-            if newcolor == None:
-                return
-
-            colorbtn.SetForegroundColour(newcolor)
-            dlg.Unbind(wx.EVT_BUTTON)
-
-        dlg.Bind(wx.EVT_BUTTON, ColorBtn, colorbtn)
-
-        sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Radius:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2)
-        sizer.Add(radius, 0, wx.EXPAND|wx.ALL, 3)
-        sizer.Add(colorbtn, 0, wx.ALL, 2)
-        sizer.Add(wx.Button(dlg, wx.ID_OK), 0, wx.ALL, 3)
-
-        dlg.SetSizer(sizer)
-        dlg.SetAutoLayout(True)
-        dlg.Fit()
-        dlg.Show()
-
-        if dlg.ShowModal() == wx.ID_OK:
-            self.radius = int(radius.GetValue())
-            r,g,b = colorbtn.GetForegroundColour().Get()
-            self.color = self.RGBHex.hexstring(r, g, b)
-            self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255)
-            self.Update(send=True, action="update")
-
-
-    def OnLeftDown(self, pos):
-        self.lastPoint = pos
-        self.start = pos
-        self.points.append((pos.x, pos.y))
-
-    def OnMotion(self, pos):
-        dc = wx.ClientDC(self.canvas)
-        self.canvas.PrepareDC(dc)
-
-        r,g,b = self.RGBHex.rgb_tuple(self.canvas.whiteboardColor)
-        pen = wx.Pen(wx.Color(r,g,b,255), int(self.canvas.toolWnd.LineWidth.GetStringSelection()))
-        dc.SetPen(pen)
-
-        xd = (self.lastPoint.x-pos.x)*(self.lastPoint.x-pos.x)
-        yd = (self.lastPoint.y-pos.y)*(self.lastPoint.y-pos.y)
-        distance = sqrt(xd+yd)
-
-        if distance > 5:
-            if self.canvas.toolWnd.currentLine == 'Free':
-                self.points.append((pos.x, pos.y))
-                self.lastPoint = pos
-                dc.DrawLines(self.points)
-            else:
-                dc.SetLogicalFunction(wx.INVERT)
-                dc.DrawLine(self.start.x, self.start.y, self.lastPoint.x, self.lastPoint.y)
-                dc.DrawLine(self.start.x, self.start.y, pos.x, pos.y)
-                dc.SetLogicalFunction(wx.COPY)
-                dc.DrawLines(self.points)
-                self.lastPoint = pos
-
-        dc.SetPen(wx.NullPen)
-
-    def OnLeftUp(self, pos):
-        if self.canvas.toolWnd.currentLine == 'Free' and len(self.points) > 2:
-            self.points.append((pos.x, pos.y))
-            self.canvas.zOrder['front'].append(MapLine(self.canvas, self.points[0], int(self.canvas.toolWnd.LineWidth.GetStringSelection()), self.canvas.whiteboardColor, self.points))
-            self.start = wx.Point(0,0)
-            self.points = []
-
-    def OnLeftDClick(self, pos):
-        if self.canvas.toolWnd.currentLine == 'Poly' and len(self.points) > 2:
-            self.points.append((pos.x, pos.y))
-            self.canvas.zOrder['front'].append(MapLine(self.canvas, self.points[0], int(self.canvas.toolWnd.LineWidth.GetStringSelection()), self.canvas.whiteboardColor, self.points))
-            self.points = []
-            self.start = wx.Point(0,0)
-
-    def _toxml(self, action="update"):
-        return ''
\ No newline at end of file
--- a/orpg/map/_object.py	Mon Oct 12 23:24:10 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-from math import sqrt
-
-import wx
-
-import orpg.dirpath
-from orpg.orpgCore import *
-from orpg.tools.rgbhex import RGBHex
-
-wxEVT_ENTER_OBJECT = wx.NewEventType()
-wxEVT_LEAVE_OBJECT = wx.NewEventType()
-wxEVT_SELECT_OBJECT = wx.NewEventType()
-wxEVT_DESELECT_OBJECT = wx.NewEventType()
-EVT_ENTER_OBJECT = wx.PyEventBinder(wxEVT_ENTER_OBJECT)
-EVT_LEAVE_OBJECT = wx.PyEventBinder(wxEVT_LEAVE_OBJECT)
-EVT_SELECT_OBJECT = wx.PyEventBinder(wxEVT_SELECT_OBJECT)
-EVT_DESELECT_OBJECT = wx.PyEventBinder(wxEVT_DESELECT_OBJECT)
-
-class ObjectEvent(wx.PyCommandEvent):
-    def __init__(self, eventType, object):
-        wx.PyCommandEvent.__init__(self, eventType)
-
-        self._object = object
-
-        self._eventType = eventType
-        self.notify = wx.NotifyEvent(eventType, -1)
-
-    def GetNotifyEvent(self):
-        return self.notify
-
-    def GetObject(self):
-        return self._object
-
-    def GetId(self):
-        return self._object.GetId()
-
-class MapObject:
-    def __init__(self, **kwargs):
-        self.id = -1
-        self.start = wx.Point(0,0)
-        self.color = "#000000"
-        self.hcolor = "#ffffff"
-        self.lineWidth = 1
-        self.zOrder = 'front'
-        self.selected = False
-        self.inObject = False
-        self.highlighed = False
-        self.isshown = True
-        self.canvas = None
-        self.RGBHex = RGBHex()
-        self.trans = 1
-
-        for atter, value in kwargs.iteritems():
-            setattr(self, atter, value)
-
-        try:
-            if self.id == wx.ID_ANY:
-                self.id = wx.NewId()
-        except:
-            self.id = wx.NewId()
-
-    #Public Methods
-    def HitTest(self, pos):
-        if self.InObject(pos) and not self.inObject and not self.selected:
-            self.inObject = True
-            evt = ObjectEvent(wxEVT_ENTER_OBJECT, self)
-            self.canvas.GetEventHandler().ProcessEvent(evt)
-        elif not self.InObject(pos) and self.inObject and not self.selected:
-            self.inObject = False
-            evt = ObjectEvent(wxEVT_LEAVE_OBJECT, self)
-            self.canvas.GetEventHandler().ProcessEvent(evt)
-
-    def GetId(self):
-        return self.id
-
-    def IsShown(self):
-        return self.isshown
-
-    def Show(self, event=None, show=True):
-        self.isshown = show
-        self.Update(send=True, action="update")
-
-    def Hide(self, event=None):
-        self.isshown = False
-        self.Update(send=True, action="update")
-
-    def IsSelected(self):
-        return self.selected
-
-    def Select(self, select=True):
-        self.selected = select
-
-        if select:
-            evt = ObjectEvent(wxEVT_SELECT_OBJECT, self)
-        else:
-            evt = ObjectEvent(wxEVT_DESELECT_OBJECT, self)
-
-        self.canvas.GetEventHandler().ProcessEvent(evt)
-
-    def Deselect(self):
-        self.selected = False
-        evt = ObjectEvent(wxEVT_DESELECT_OBJECT, self)
-        self.canvas.GetEventHandler().ProcessEvent(evt)
-
-    def Update(self, send=False, action="update"):
-        self.canvas.UpdateMap()
-        if send:
-            self.canvas.session.send(self._toxml(action))
-
-    def GetName(self):
-        return 'ID: ' + str(self.id) + ' Color: ' + self.color
-
-    def InObject(self, pos):
-        pass
-
-    def Draw(self, dc):
-        if self.selected:
-            self.DrawSelected(dc)
-
-    def DrawSelected(self, dc):
-        pass
-
-    def Highlight(self):
-        self.highlighed = True
-        self.Update()
-
-    def UnHighlight(self):
-        self.highlighed = False
-        self.Update()
-
-    def OnLeftDown(self, pos):
-        if self.inObject and self.selected:
-            self.start = pos
-            self.Deselect()
-
-        elif self.inObject and not self.selected:
-            self.Select()
-
-        else:
-            self.start = pos
-
-        self.Update()
-
-    def OnMotion(self, pos):
-        cdc = wx.ClientDC(self.canvas)
-        self.canvas.PrepareDC(cdc)
-        dc = wx.GraphicsContext.Create(cdc)
-
-        if self.selected:
-            self.start = pos
-            self.Draw(dc)
-
-    def OnLeftUp(self, pos):
-        pass
-
-    def OnRightDown(self, pos):
-        pass
-
-    def OnLeftDClick(self, pos):
-        pass
-
-    def ShowProperties(self, event):
-        pass
-
-    def _toxml(self, action="update"):
-        return ''
\ No newline at end of file
--- a/orpg/map/_text.py	Mon Oct 12 23:24:10 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-from math import sqrt
-
-import wx
-
-import orpg.dirpath
-from orpg.orpgCore import *
-
-from _object import MapObject
-
-class MapText(MapObject):
-    def __init__(self, canvas, start=wx.Point(0,0), text='', size=12, weight=wx.NORMAL, style=wx.NORMAL, color="#000000"):
-        MapObject.__init__(self, canvas=canvas)
-        self.start = start
-        self.color = color
-        self.text = text
-        self.weight = weight
-        self.style = style
-        self.size = size
-
-        r, g, b = self.RGBHex.rgb_tuple(self.color)
-        self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255)
-
-        self.id = 'text-' + self.canvas.GetNewObjectId()
-
-
-    def Draw(self, dc):
-        if not self.highlighed:
-            c = self.color
-        else:
-            c = self.hcolor
-
-        font = wx.Font(self.size, wx.DEFAULT, self.weight, self.style)
-        dc.SetFont(font, c)
-        w, h = dc.GetTextExtent(self.text)
-
-
-        if self.IsShown():
-            dc.DrawText(self.text, self.start.x-(w/2), self.start.y-(h/2))
-        elif self.canvas.toolWnd.gmToolBar.IsShown():
-            r, g, b = self.RGBHex.rgb_tuple(c)
-            dc.SetFont(font, wx.Color(r, g, b, 40))
-            dc.DrawText(self.text, self.start.x-(w/2), self.start.y-(h/2))
-
-
-        if self.selected:
-            self.DrawSelection(dc)
-
-    def DrawSelection(self, dc):
-        w, h = dc.GetTextExtent(self.text)
-        dc.SetBrush(wx.GREEN_BRUSH)
-        dc.SetPen(wx.GREEN_PEN)
-        path = dc.CreatePath()
-
-        path.AddRectangle(self.start.x-((w/2)+1), self.start.y-((h/2)+1), 5, 5)
-        path.AddRectangle(self.start.x-((w/2)+1), self.start.y+((h/2)+1), 5, 5)
-        path.AddRectangle(self.start.x+((w/2)+1), self.start.y-((h/2)+1), 5, 5)
-        path.AddRectangle(self.start.x+((w/2)+1), self.start.y+((h/2)+1), 5, 5)
-
-        dc.DrawPath(path)
-
-        dc.SetBrush(wx.NullBrush)
-        dc.SetPen(wx.NullPen)
-
-    def InObject(self, pos):
-        dc = wx.ClientDC(self.canvas)
-        self.canvas.PrepareDC(dc)
-        font = wx.Font(self.size, wx.DEFAULT, self.weight, self.style)
-        w, h = dc.GetTextExtent(self.text)
-        rgn = wx.RegionFromPoints([(self.start.x-(w/2), self.start.y-(h/2)), (self.start.x-(w/2), self.start.y+(h/2)), (self.start.x+(w/2), self.start.y-(h/2)), (self.start.x+(w/2), self.start.y+(h/2))])
-
-        if rgn.Contains(pos.x, pos.y):
-            return True
-
-        return False
-
-    def GetName(self):
-        return self.text + ' Color:' + self.color
-
-    def ShowProperties(self, event):
-        dlg = wx.Dialog(self.canvas, wx.ID_ANY, "Circle Properties")
-        sizer = wx.BoxSizer(wx.HORIZONTAL)
-
-        text = wx.TextCtrl(dlg, wx.ID_ANY)
-        text.SetValue(self.text)
-
-        colorbtn = wx.Button(dlg, wx.ID_ANY, "Color")
-        colorbtn.SetForegroundColour(self.color)
-
-        size = wx.SpinCtrl(dlg, wx.ID_ANY, value=str(self.size), min=7, initial=12, name="Font Size: ")
-
-        weight = wx.Choice(dlg, wx.ID_ANY, choices=["Normal", "Bold"])
-        if self.weight == wx.NORMAL:
-            weight.SetSelection(0)
-        else:
-            weight.SetSelection(1)
-
-        style = wx.Choice(dlg, wx.ID_ANY, choices=["Normal", "Italic"])
-        if self.weight == wx.NORMAL:
-            style.SetSelection(0)
-        else:
-            style.SetSelection(1)
-
-        def ColorBtn(event):
-            newcolor = self.RGBHex.do_hex_color_dlg(self.canvas)
-            if newcolor == None:
-                return
-
-            colorbtn.SetForegroundColour(newcolor)
-            dlg.Unbind(wx.EVT_BUTTON)
-
-        dlg.Bind(wx.EVT_BUTTON, ColorBtn, colorbtn)
-
-        sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Text:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2)
-        sizer.Add(text, 0, wx.EXPAND|wx.ALL, 3)
-        sizer.Add(size, 0, wx.ALL, 2)
-        sizer.Add(weight, 0, wx.ALL, 3)
-        sizer.Add(style, 0, wx.ALL, 2)
-        sizer.Add(colorbtn, 0, wx.ALL, 3)
-        sizer.Add(wx.Button(dlg, wx.ID_OK), 0, wx.ALL, 2)
-
-        dlg.SetSizer(sizer)
-        dlg.SetAutoLayout(True)
-        dlg.Fit()
-        dlg.Show()
-
-        if dlg.ShowModal() == wx.ID_OK:
-            self.text = text.GetValue()
-            r,g,b = colorbtn.GetForegroundColour().Get()
-            self.color = self.RGBHex.hexstring(r, g, b)
-            self.hcolor = self.RGBHex.hexstring(r^255, g^255, b^255)
-            self.size = int(size.GetValue())
-            if weight.GetSelection() == 0:
-                self.weight = wx.NORMAL
-            else:
-                self.weight = wx.BOLD
-
-            if style.GetSelection() == 0:
-                self.style = wx.NORMAL
-            else:
-                self.style = wx.ITALIC
-
-            if event != None:
-                self.Update(send=True, action="update")
-
-
-    def OnLeftDown(self, pos):
-        self.ShowProperties(None)
-        self.color = self.canvas.whiteboardColor
-        if self.text != '':
-            self.canvas.zOrder['front'].append(MapText(self.canvas, pos, self.text, self.size, self.weight, self.style, self.color))
-            self.Update(send=True, action='new')
-
-        self.text = ''
-        self.weight = wx.NORMAL
-        self.size = 12
-        self.style = wx.NORMAL
-        self.color = self.canvas.whiteboardColor
-        self.hcolor = self.canvas.whiteboardColor
-
-    def _toxml(self, action="update"):
-        return ''
\ No newline at end of file
--- a/orpg/mapper/background.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/mapper/background.py	Wed Oct 28 14:24:54 2009 -0500
@@ -134,6 +134,12 @@
         if self.bg_bmp == None or not self.bg_bmp.Ok() or ((self.type != BG_TEXTURE) and (self.type != BG_IMAGE)):
             return False
         dc2 = wx.MemoryDC()
+        
+        ### Temporary ###
+        try: self.bg_bmp = self.bg_bmp.ConvertToBitmap()
+        except: pass
+        #################
+        
         dc2.SelectObject(self.bg_bmp)
         topLeft = [int(topleft[0]/scale), int(topleft[1]/scale)]
         topRight = [int((topleft[0]+size[0]+1)/scale)+1, int((topleft[1]+size[1]+1)/scale)+1]
--- a/orpg/mapper/base_msg.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/mapper/base_msg.py	Wed Oct 28 14:24:54 2009 -0500
@@ -30,6 +30,8 @@
 from threading import RLock
 from orpg.networking.mplay_client import *
 
+from xml.etree.ElementTree import XML
+
 class map_element_msg_base:
 #  This is a base class
 
@@ -195,40 +197,41 @@
     #########################################
     #  XML importers begin
 
-    def _from_dom(self,xml_dom,prop_func):
+    def _from_dom(self,xml,prop_func):
         self.p_lock.acquire()
-        if xml_dom.tagName == self.tagname:
-            if xml_dom.getAttributeKeys():
-                for k in xml_dom.getAttributeKeys():
-                    prop_func(k,xml_dom.getAttribute(k))
+        if xml.tag == self.tagname:
+            if xml.keys():
+                for k in xml.keys():
+                    prop_func(k,xml.get(k))
         else:
             self.p_lock.release()
             raise Exception, "Error attempting to modify a " + self.tagname + " from a non-<" + self.tagname + "/> element"
         self.p_lock.release()
 
-    def init_from_dom(self,xml_dom):
-    #  xml_dom must be pointing to an empty tag.  Override in a derived class for <map/> and other similar tags.
-        self._from_dom(xml_dom,self.init_prop)
+    def init_from_dom(self,xml):
+    #  xml must be pointing to an empty tag.  Override in a derived class for <map/> and other similar tags.
+        self._from_dom(xml,self.init_prop)
 
-    def set_from_dom(self,xml_dom):
-    #  xml_dom must be pointing to an empty tag.  Override in a derived class for <map/> and other similar tags
-        self._from_dom(xml_dom,self.set_prop)
+    def set_from_dom(self,xml):
+    #  xml must be pointing to an empty tag.  Override in a derived class for <map/> and other similar tags
+        self._from_dom(xml,self.set_prop)
 
-    def init_from_xml(self,xml):
-        xml_dom = parseXml(xml)
-        node_list = xml_dom.getElementsByTagName(self.tagname)
-        if len(node_list) < 1: print "Warning: no <" + self.tagname + "/> elements found in DOM."
+    def init_from_xml(self,xmlString):
+        tree = XML(xmlString)
+        node_list = tree.findall(self.tagname)
+        if len(node_list) < 1:
+            print "Warning: no <" + self.tagname + "/> elements found in DOM."
         else:
-            while len(node_list): self.init_from_dom(node_list.pop())
-        if xml_dom: xml_dom.unlink()
+            while len(node_list):
+                self.init_from_dom(node_list.pop())
 
-    def set_from_xml(self,xml):
-        xml_dom = parseXml(xml)
-        node_list = xml_dom.getElementsByTagName(self.tagname)
-        if len(node_list) < 1: print "Warning: no <" + self.tagname + "/> elements found in DOM."
+    def set_from_xml(self,xmlString):
+        tree = XML(xmlString)
+        node_list = tree.findall(self.tagname)
+        if len(node_list) < 1:
+            print "Warning: no <" + self.tagname + "/> elements found in DOM."
         else:
-            while len(node_list): self.set_from_dom(node_list.pop())
-        if xml_dom: xml_dom.unlink()
-
+            while len(node_list):
+                self.set_from_dom(node_list.pop())
     # XML importers end
     #########################################
--- a/orpg/mapper/fog.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/mapper/fog.py	Wed Oct 28 14:24:54 2009 -0500
@@ -82,8 +82,8 @@
         self.canvas = canvas
         self.log = component.get('log')
         layer_base.__init__(self)
-        self.color = wx.Color(128,128,128)
-        if "__WXGTK__" not in wx.PlatformInfo: self.color = wx.Color(128,128,128, 128)
+        self.color = wx.Color(128, 128, 128)
+        #if "__WXGTK__" not in wx.PlatformInfo: self.color = wx.Color(128,128,128, 128)
         self.fogregion = wx.Region()
         self.fogregion.Clear()
         self.fog_bmp = None
@@ -116,71 +116,40 @@
         if not self.use_fog:
             return
         size = self.canvas.size
-        self.width = size[0]/COURSE+1
-        self.height = size[1]/COURSE+1
-        self.fog_bmp = wx.EmptyBitmap(self.width+2,self.height+2)
+        self.width = size[0]
+        self.height = size[1]
+        self.fog_bmp = wx.EmptyBitmap(self.width,self.height)
         self.fill_fog()
 
     def fill_fog(self):
         if not self.use_fog:
             return
-        if "__WXGTK__" in wx.PlatformInfo:
-            mdc = wx.MemoryDC()
-            mdc.SelectObject(self.fog_bmp)
-            mdc.SetPen(wx.TRANSPARENT_PEN)
-            if (self.canvas.frame.session.role == "GM"): color = self.color
-            else: color = wx.BLACK
-            self.last_role = self.canvas.frame.session.role
-            mdc.SetBrush(wx.Brush(color,wx.SOLID))
-            mdc.DestroyClippingRegion()
+        mdc = wx.MemoryDC()
+        mdc.SelectObject(self.fog_bmp)
+        mdc.SetPen(wx.TRANSPARENT_PEN)
+        if (self.canvas.frame.session.role == "GM"): color = self.color
+        else: color = wx.BLACK
+        self.last_role = self.canvas.frame.session.role
+        mdc.SetBrush(wx.Brush(color,wx.SOLID))
+        mdc.DestroyClippingRegion()
+        mdc.DrawRectangle(0, 0, self.width+2, self.height+2)
+        mdc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
+        if self.fogregion.GetBox().GetWidth()>0:
+            mdc.SetClippingRegionAsRegion(self.fogregion)
             mdc.DrawRectangle(0, 0, self.width+2, self.height+2)
-            mdc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
-            if self.fogregion.GetBox().GetWidth()>0:
-                mdc.SetClippingRegionAsRegion(self.fogregion)
-                mdc.DrawRectangle(0, 0, self.width+2, self.height+2)
-            mdc.SelectObject(wx.NullBitmap)
-            del mdc
+        mdc.SelectObject(wx.NullBitmap)
+        del mdc
 
     def layerDraw(self, dc, topleft, size):
         if self.fog_bmp == None or not self.fog_bmp.Ok() or not self.use_fog:
             return
         if self.last_role != self.canvas.frame.session.role: self.fill_fog()
-        if "__WXGTK__" not in wx.PlatformInfo:
-            gc = wx.GraphicsContext.Create(dc)
-            gc.SetBrush(wx.Brush(wx.BLACK))
-            if (self.canvas.frame.session.role == "GM"):
-                gc.SetBrush(wx.Brush(self.color))
-            rgn = wx.Region(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2)
-            if not self.fogregion.IsEmpty(): rgn.SubtractRegion(self.fogregion)
-            gc.ClipRegion(rgn)
-            gc.DrawRectangle(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2)
-        else:
-            sc = dc.GetUserScale()
-            bmp = wx.EmptyBitmap(size[0],size[1])
-            mdc = wx.MemoryDC()
-            mdc.BeginDrawing()
-            mdc.SelectObject(bmp)
-            mdc.SetPen(wx.TRANSPARENT_PEN)
-            mdc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
-            mdc.DrawRectangle(0,0,size[0],size[1])
-            srct = [int(topleft[0]/(sc[0]*COURSE)), int(topleft[1]/(sc[1]*COURSE))]
-            srcsz = [int((int(size[0]/COURSE+1)*COURSE)/(sc[0]*COURSE))+2, 
-                int((int(size[1]/COURSE+1)*COURSE)/(sc[1]*COURSE))+2]
-            if (srct[0]+srcsz[0] > self.width): srcsz[0] = self.width-srct[0]
-            if (srct[1]+srcsz[1] > self.height): srcsz[1] = self.height-srct[1]
-            img = wx.ImageFromBitmap(self.fog_bmp).GetSubImage(wx.Rect(srct[0], srct[1], srcsz[0], srcsz[1]))
-            img.Rescale(srcsz[0]*COURSE*sc[0], srcsz[1]*COURSE*sc[1])
-            fog = wx.BitmapFromImage(img)
-            mdc.SetDeviceOrigin(-topleft[0], -topleft[1])
-            mdc.DrawBitmap(fog, srct[0]*COURSE*sc[0], srct[1]*COURSE*sc[1])
-            mdc.SetDeviceOrigin(0,0)
-            mdc.SetUserScale(1,1)
-            mdc.EndDrawing()
-            dc.SetUserScale(1,1)
-            dc.Blit(topleft[0], topleft[1], size[0], size[1], mdc,0,0,wx.AND)
-            dc.SetUserScale(sc[0],sc[1])
-            mdc.SelectObject(wx.NullBitmap)
-            del mdc
+        
+        mdc = wx.MemoryDC()
+        mdc.SelectObject(self.fog_bmp)
+        dc.Blit(0, 0, self.canvas.size[0], self.canvas.size[1], mdc, 0, 0, wx.AND)
+        mdc.SelectObject(wx.NullBitmap)
+        del mdc
 
     def createregn2(self, polyline, mode, show):
         regn = self.scanConvert(polyline)
@@ -198,7 +167,7 @@
             if not self.fogregion.IsEmpty():
                 self.fogregion.SubtractRegion(regn)
             else:
-                self.fogregion = wx.Region(0, 0, self.canvas.size[0]+2, self.canvas.size[1]+2)
+                self.fogregion = wx.Region(0, 0, self.canvas.size[0], self.canvas.size[1])
                 self.fogregion.SubtractRegion(regn)
             self.del_area(area, show)
 
@@ -216,13 +185,13 @@
         list = IRegion().scan_Convert(polypt)
         for i in list:
             if regn.IsEmpty():
-                if "__WXGTK__" not in wx.PlatformInfo: regn = wx.Region(i.left*COURSE, i.y*COURSE, 
-                                                                        i.right*COURSE+1-i.left*COURSE, 1*COURSE)
-                else: regn = wx.Region(i.left, i.y, i.right+1-i.left, 1)
+                #if "__WXGTK__" not in wx.PlatformInfo: 
+                regn = wx.Region(i.left*COURSE, i.y*COURSE, i.right*COURSE+1-i.left*COURSE, 1*COURSE)
+                #else: regn = wx.Region(i.left, i.y, i.right+1-i.left, 1)
             else:
-                if "__WXGTK__" not in wx.PlatformInfo: regn.Union(i.left*COURSE, i.y*COURSE, 
-                                                                i.right*COURSE+1-i.left*COURSE, 1*COURSE)
-                else: regn.Union(i.left, i.y, i.right+1-i.left, 1)
+                #if "__WXGTK__" not in wx.PlatformInfo: 
+                regn.Union(i.left*COURSE, i.y*COURSE, i.right*COURSE+1-i.left*COURSE, 1*COURSE)
+                #else: regn.Union(i.left, i.y, i.right+1-i.left, 1)
         return regn
 
     def add_area(self, area="", show="Yes"):
@@ -246,16 +215,16 @@
         ri = wx.RegionIterator(self.fogregion)
         if not (ri.HaveRects()): fog_string = FogArea("all", self.log).toxml("del")
         while ri.HaveRects():
-            if "__WXGTK__" not in wx.PlatformInfo:
-                x1 = ri.GetX()/COURSE
-                x2 = x1+(ri.GetW()/COURSE)-1
-                y1 = ri.GetY()/COURSE
-                y2 = y1+(ri.GetH()/COURSE)-1
-            else:
-                x1 = ri.GetX()
-                x2 = x1+ri.GetW()-1
-                y1 = ri.GetY()
-                y2 = y1+ri.GetH()-1
+            #if "__WXGTK__" not in wx.PlatformInfo:
+            x1 = ri.GetX()/COURSE
+            x2 = x1+(ri.GetW()/COURSE)-1
+            y1 = ri.GetY()/COURSE
+            y2 = y1+(ri.GetH()/COURSE)-1
+            #else:
+            #    x1 = ri.GetX()
+            #    x2 = x1+ri.GetW()-1
+            #    y1 = ri.GetY()
+            #    y2 = y1+ri.GetH()-1
             poly = FogArea(str(x1) + "," + str(y1) + ";" +
                           str(x2) + "," + str(y1) + ";" +
                           str(x2) + "," + str(y2) + ";" +
--- a/orpg/mapper/images.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/mapper/images.py	Wed Oct 28 14:24:54 2009 -0500
@@ -56,7 +56,7 @@
         # Load an image, with a intermideary fetching image shown while it loads in a background thread
         if self.__cache.has_key(path):
             return wx.ImageFromMime(self.__cache[path][1],
-                                    self.__cache[path][2]).ConvertToBitmap()
+                                    self.__cache[path][2])
         if path not in self.__fetching:
             self.__fetching[path] = True
             #Start Image Loading Thread
@@ -66,15 +66,13 @@
             if self.__fetching[path]:
                 thread.start_new_thread(self.__loadCacheThread,
                                         (path, image_type, imageId))
-        return wx.Bitmap(dir_struct["icon"] + "fetching.png",
-                         wx.BITMAP_TYPE_PNG)
+        return wx.Bitmap(dir_struct["icon"] + "fetching.png", wx.BITMAP_TYPE_PNG)
 
     def directLoad(self, path):
         # Directly load an image, no threads
         if path in self.__cache:
             return wx.ImageFromMime(self.__cache[path][1],
-                                    self.__cache[path][2]).ConvertToBitmap()
-
+                                    self.__cache[path][2])
         uriPath = urllib.unquote(path)
         try:
             d = urllib.urlretrieve(uriPath)
@@ -83,8 +81,7 @@
             if d[0] and d[1].getmaintype() == "image":
                 with self.__lock:
                     self.__cache[path] = (path, d[0], d[1].gettype(), None)
-                return wx.ImageFromMime(self.__cache[path][1],
-                                        self.__cache[path][2]).ConvertToBitmap()
+                return wx.ImageFromMime(self.__cache[path][1], self.__cache[path][2])
             else:
                 logger.general("Image refused to load or URI did not "
                                "reference a valid image: " + path, True)
@@ -115,7 +112,6 @@
 #Private Methods
     def __loadThread(self, path, image_type, imageId):
         uriPath = urllib.unquote(path)
-
         try:
             d = urllib.urlretrieve(uriPath)
             # We have to make sure that not only did we fetch something, but that
@@ -124,9 +120,7 @@
                 with self.__lock:
                     self.__cache[path] = (path, d[0], d[1].gettype(), imageId)
                     self.__queue.put((self.__cache[path], image_type, imageId))
-
-                if path in self.__fetching:
-                    del self.__fetching[path]
+                if path in self.__fetching: del self.__fetching[path]
             else:
                 logger.general("Image refused to load or URI did not "
                                "reference a valid image: " + path, True)
@@ -150,13 +144,11 @@
             logger.general("Unable to resolve/open the specified URI; "
                            "image was NOT loaded: " + path, True)
             return
-
         with self.__lock:
             if path in self.__cache:
                 logger.debug("Adding Image to Queue from Cache: " + str(self.__cache[path]))
                 self.__queue.put((self.__cache[path], image_type, imageId))
-            else:
-                self.__loadThread(path, image_type, imageId)
+            else: self.__loadThread(path, image_type, imageId)
 
     #Property Methods
     def _getCache(self):
--- a/orpg/mapper/map.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/mapper/map.py	Wed Oct 28 14:24:54 2009 -0500
@@ -62,6 +62,7 @@
         self.session = component.get("session")
         wx.ScrolledWindow.__init__(self, parent, ID, 
             style=wx.HSCROLL | wx.VSCROLL | wx.FULL_REPAINT_ON_RESIZE | wx.SUNKEN_BORDER )
+        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
         self.frame = parent
         self.MAP_MODE = 1      #Mode 1 = MINI, 2 = DRAW, 3 = TAPE MEASURE
         self.layers = {}
@@ -125,43 +126,21 @@
 
     def processImages(self, evt=None):
         self.session = component.get("session")
+        tabs = ['Background', 'Grid', 'Miniatures', 'Whiteboard', 'Fog', 'General']
         if self.session.my_role() == self.session.ROLE_LURKER or (str(self.session.group_id) == '0' and str(self.session.status) == '1'):
-            cidx = self.parent.get_tab_index("Background")
-            self.parent.tabs.EnableTab(cidx, False)
-            cidx = self.parent.get_tab_index("Grid")
-            self.parent.tabs.EnableTab(cidx, False)
-            cidx = self.parent.get_tab_index("Miniatures")
-            self.parent.tabs.EnableTab(cidx, False)
-            cidx = self.parent.get_tab_index("Whiteboard")
-            self.parent.tabs.EnableTab(cidx, False)
-            cidx = self.parent.get_tab_index("Fog")
-            self.parent.tabs.EnableTab(cidx, False)
-            cidx = self.parent.get_tab_index("General")
-            self.parent.tabs.EnableTab(cidx, False)
-        else:
-            cidx = self.parent.get_tab_index("Background")
-            if not self.parent.tabs.GetEnabled(cidx):
-                cidx = self.parent.get_tab_index("Miniatures")
+            for tab in tabs:
+                cidx = self.parent.get_tab_index(tab)
+                self.parent.tabs.EnableTab(cidx, False)
+        elif self.session.my_role() == self.session.ROLE_PLAYER:
+            for tab in tabs:
+                cidx = self.parent.get_tab_index(tab)
+                if tab == "Miniatures" or tab == "Whiteboard": 
+                    self.parent.tabs.EnableTab(cidx, True)
+                else: self.parent.tabs.EnableTab(cidx, False)
+        elif self.session.my_role() == self.session.ROLE_GM and str(self.session.group_id) != '0':
+            for tab in tabs:
+                cidx = self.parent.get_tab_index(tab)
                 self.parent.tabs.EnableTab(cidx, True)
-                cidx = self.parent.get_tab_index("Whiteboard")
-                self.parent.tabs.EnableTab(cidx, True)
-                cidx = self.parent.get_tab_index("Background")
-                self.parent.tabs.EnableTab(cidx, False)
-                cidx = self.parent.get_tab_index("Grid")
-                self.parent.tabs.EnableTab(cidx, False)
-                cidx = self.parent.get_tab_index("Fog")
-                self.parent.tabs.EnableTab(cidx, False)
-                cidx = self.parent.get_tab_index("General")
-                self.parent.tabs.EnableTab(cidx, False)
-                if self.session.my_role() == self.session.ROLE_GM:
-                    cidx = self.parent.get_tab_index("Background")
-                    self.parent.tabs.EnableTab(cidx, True)
-                    cidx = self.parent.get_tab_index("Grid")
-                    self.parent.tabs.EnableTab(cidx, True)
-                    cidx = self.parent.get_tab_index("Fog")
-                    self.parent.tabs.EnableTab(cidx, True)
-                    cidx = self.parent.get_tab_index("General")
-                    self.parent.tabs.EnableTab(cidx, True)
         if not self.cacheSizeSet:
             self.cacheSizeSet = True
             cacheSize = component.get('settings').get_setting("ImageCacheSize")
@@ -169,16 +148,14 @@
             else: pass
         if not ImageHandler.Queue.empty():
             (path, image_type, imageId) = ImageHandler.Queue.get()
-            img = wx.ImageFromMime(path[1], path[2]).ConvertToBitmap()
-            try:
-                # Now, apply the image to the proper object
-                if image_type == "miniature":
-                    min = self.layers['miniatures'].get_miniature_by_id(imageId)
-                    min.set_bmp(img)
-                elif image_type == "background" or image_type == "texture":
-                    self.layers['bg'].bg_bmp = img
-                    if image_type == "background": self.set_size([img.GetWidth(), img.GetHeight()])
-            except: pass
+            img = wx.ImageFromMime(path[1], path[2])
+            # Now, apply the image to the proper object
+            if image_type == "miniature":
+                min = self.layers['miniatures'].get_miniature_by_id(imageId)
+                if min: min.set_bmp(img)
+            elif image_type == "background" or image_type == "texture":
+                self.layers['bg'].bg_bmp = img.ConvertToBitmap()
+                if image_type == "background": self.set_size([img.GetWidth(), img.GetHeight()])
             # Flag that we now need to refresh!
             self.requireRefresh += 1
             """ Randomly purge an item from the cache, while this is lamo, it does
@@ -199,7 +176,6 @@
             else: self.lastRefreshValue = self.requireRefresh
 
     def on_scroll(self, evt):
-        print 'scrolling'
         if self.drag: self.drag.Hide()
         if component.get('settings').get_setting("AlwaysShowMapScale") == "1": self.printscale()
         evt.Skip()
@@ -262,9 +238,10 @@
         topleft1 = self.GetViewStart()
         topleft = [topleft1[0]*scrollsize[0], topleft1[1]*scrollsize[1]]
         if (clientsize[0] > 1) and (clientsize[1] > 1):
-            dc = wx.MemoryDC()
-            bmp = wx.EmptyBitmap(clientsize[0]+1, clientsize[1]+1)
-            dc.SelectObject(bmp)
+            #dc = wx.MemoryDC()
+            #bmp = wx.EmptyBitmap(clientsize[0]+1, clientsize[1]+1)
+            #dc.SelectObject(bmp)
+            dc = wx.AutoBufferedPaintDC(self)
             dc.SetPen(wx.TRANSPARENT_PEN)
             dc.SetBrush(wx.Brush(self.GetBackgroundColour(), wx.SOLID))
             dc.DrawRectangle(0,0,clientsize[0]+1,clientsize[1]+1)
@@ -279,12 +256,12 @@
             self.layers['fog'].layerDraw(dc, topleft, clientsize)
             dc.SetPen(wx.NullPen)
             dc.SetBrush(wx.NullBrush)
-            dc.SelectObject(wx.NullBitmap)
-            del dc
-            wdc = self.preppaint()
-            wdc.DrawBitmap(bmp, topleft[0], topleft[1])
+            #dc.SelectObject(wx.NullBitmap)
+            #del dc
+            #wdc = self.preppaint()
+            #wdc.DrawBitmap(bmp, topleft[0], topleft[1])
             if settings.get_setting("AlwaysShowMapScale") == "1":
-                self.showmapscale(wdc)
+                self.showmapscale(dc)
         try: evt.Skip()
         except: pass
 
--- a/orpg/mapper/miniatures.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/mapper/miniatures.py	Wed Oct 28 14:24:54 2009 -0500
@@ -38,6 +38,9 @@
 import xml.dom.minidom as minidom
 from orpg.tools.orpg_settings import settings
 
+from xml.etree.ElementTree import ElementTree, Element
+from xml.etree.ElementTree import fromstring, tostring
+
 MIN_STICKY_BACK = -0XFFFFFF
 MIN_STICKY_FRONT = 0xFFFFFF
 
@@ -68,15 +71,14 @@
     return value
 
 class BmpMiniature:
-    def __init__(self, id,path, bmp, pos=cmpPoint(0,0), 
+    def __init__(self, id, path, bmp, pos=cmpPoint(0,0), 
                 heading=FACE_NONE, face=FACE_NONE, label="", 
                 locked=False, hide=False, snap_to_align=SNAPTO_ALIGN_CENTER, 
-                zorder=0, width=0, height=0, log=None, local=False, localPath='', localTime=-1):
+                zorder=0, width=0, height=0, log=None, local=False, localPath='', localTime=-1, func='none'):
         self.heading = heading
         self.face = face
         self.label = label
         self.path = path
-        self.bmp = bmp
         self.pos = pos
         self.selected = False
         self.locked = locked
@@ -97,13 +99,30 @@
         self.bottom = bmp.GetHeight()
         self.isUpdated = False
         self.gray = False
+        print bmp
+        self.set_bmp(bmp)
 
     def __del__(self):
-        del self.bmp
-        self.bmp = None
+        del self.image
+        self.image = None
 
     def set_bmp(self, bmp):
-        self.bmp = bmp
+        ### Alpha ###
+        try: bmp = bmp.ConvertToImage()
+        except: pass
+        ### Still ironing out some kinks to FlexiRPG's map features ###
+        self.image = bmp
+        self.image.ConvertAlphaToMask()
+        self.generate_bmps()
+        
+    def generate_bmps(self):
+        if self.width:
+            bmp = self.image.Copy()
+            bmp.Rescale(int(self.width), int(self.height))
+        else:
+            bmp = self.image
+        self.bmp = bmp.ConvertToBitmap()
+        self.bmp_gray = bmp.ConvertToGreyscale().ConvertToBitmap()
 
     def set_min_props(self, heading=FACE_NONE, face=FACE_NONE, label="", locked=False, hide=False, width=0, height=0):
         self.heading = heading
@@ -116,6 +135,7 @@
         self.width = int(width)
         self.height = int(height)
         self.isUpdated = True
+        self.generate_bmps()
 
     def hit_test(self, pt):
         rect = self.get_rect()
@@ -128,41 +148,39 @@
         return ret
 
     def draw(self, dc, mini_layer, op=wx.COPY):
-        if isinstance(self.bmp, tuple):
-            self.bmp = wx.ImageFromMime(self.bmp[1], self.bmp[2]).ConvertToBitmap()
-        if self.bmp != None and self.bmp.Ok():
-            # check if hidden and GM: we outline the mini in grey (little bit smaller than the actual size)
-            # and write the label in the center of the mini
-            if self.hide and mini_layer.canvas.frame.session.my_role() == mini_layer.canvas.frame.session.ROLE_GM:
-                # set the width and height of the image
-                if self.width and self.height:
-                    tmp_image = self.bmp.ConvertToImage()
-                    tmp_image.Rescale(int(self.width), int(self.height))
-                    tmp_image.ConvertAlphaToMask()
-                    self.bmp = tmp_image.ConvertToBitmap()
-                    mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(), 
-                        tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue()))
-                    self.bmp.SetMask(mask)
-                    del tmp_image
-                    del mask
-                self.left = 0
-                self.right = self.bmp.GetWidth()
-                self.top = 0
-                self.bottom = self.bmp.GetHeight()
-                # grey outline
-                graypen = wx.Pen("gray", 1, wx.DOT)
-                dc.SetPen(graypen)
-                dc.SetBrush(wx.TRANSPARENT_BRUSH)
-                #if width or height < 20 then offset = 1
-                if self.bmp.GetWidth() <= 20: xoffset = 1
-                else: xoffset = 5
-                if self.bmp.GetHeight() <= 20: yoffset = 1
-                else: yoffset = 5
-                dc.DrawRectangle(self.pos.x + xoffset, 
-                    self.pos.y + yoffset, self.bmp.GetWidth() - (xoffset * 2), 
-                    self.bmp.GetHeight() - (yoffset * 2))
-                dc.SetBrush(wx.NullBrush)
-                dc.SetPen(wx.NullPen)
+        if self.hide and mini_layer.canvas.frame.session.my_role() == mini_layer.canvas.frame.session.ROLE_GM:
+            # set the width and height of the image
+            """
+            if self.width and self.height:
+                tmp_image = self.bmp.ConvertToImage()
+                tmp_image.Rescale(int(self.width), int(self.height))
+                tmp_image.ConvertAlphaToMask()
+                self.bmp = tmp_image.ConvertToBitmap()
+                mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(), 
+                    tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue()))
+                self.bmp.SetMask(mask)
+                del tmp_image
+                del mask
+            """
+            self.left = 0
+            self.right = self.bmp.GetWidth()
+            self.top = 0
+            self.bottom = self.bmp.GetHeight()
+            # grey outline
+            graypen = wx.Pen("gray", 1, wx.DOT)
+            dc.SetPen(graypen)
+            dc.SetBrush(wx.TRANSPARENT_BRUSH)
+            #if width or height < 20 then offset = 1
+            if self.bmp.GetWidth() <= 20: xoffset = 1
+            else: xoffset = 5
+            if self.bmp.GetHeight() <= 20: yoffset = 1
+            else: yoffset = 5
+            dc.DrawRectangle(self.pos.x + xoffset, 
+                self.pos.y + yoffset, self.bmp.GetWidth(), 
+                self.bmp.GetHeight())
+            dc.SetBrush(wx.NullBrush)
+            dc.SetPen(wx.NullPen)
+            if mini_layer.show_labels:
                 ## draw label in the center of the mini
                 label = mini_layer.get_mini_label(self)
                 if len(label):
@@ -180,220 +198,163 @@
                     dc.SetPen(wx.NullPen)
                     dc.SetBrush(wx.NullBrush)
                     dc.DrawText(label, x+1, y+1)
-
-                #selected outline
-                if self.selected:
-                    dc.SetPen(wx.RED_PEN)
-                    dc.SetBrush(wx.TRANSPARENT_BRUSH)
-                    dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
-                    dc.SetBrush(wx.NullBrush)
-                    dc.SetPen(wx.NullPen)
-                return True
-            elif self.hide: return True
-
-            else:
-                # set the width and height of the image
-                bmp = self.bmp
-                if self.width and self.height:
-                    tmp_image = self.bmp.ConvertToImage()
-                    tmp_image.Rescale(int(self.width), int(self.height))
-                    tmp_image.ConvertAlphaToMask()
-                    self.bmp = tmp_image.ConvertToBitmap()
-                    mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(), 
-                        tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue()))
-                    self.bmp.SetMask(mask)
-                    if self.gray:
-                        tmp_image = tmp_image.ConvertToGreyscale()
-                        bmp = tmp_image.ConvertToBitmap()
-                    else: bmp = self.bmp
-                dc.DrawBitmap(bmp, self.pos.x, self.pos.y, True)
-                self.left = 0
-                self.right = self.bmp.GetWidth()
-                self.top = 0
-                self.bottom = self.bmp.GetHeight()
-
-                # Draw the facing marker if needed
-                if self.face != 0:
-                    x_mid = self.pos.x + (self.bmp.GetWidth()/2)
-                    x_right = self.pos.x + self.bmp.GetWidth()
-                    y_mid = self.pos.y + (self.bmp.GetHeight()/2)
-                    y_bottom = self.pos.y + self.bmp.GetHeight()
-                    dc.SetPen(wx.WHITE_PEN)
-                    dc.SetBrush(wx.RED_BRUSH)
-                    triangle = []
-
-                    # Figure out which direction to draw the marker!!
-                    if self.face == FACE_WEST:
-                        triangle.append(cmpPoint(self.pos.x,self.pos.y))
-                        triangle.append(cmpPoint(self.pos.x - 5, y_mid))
-                        triangle.append(cmpPoint(self.pos.x, y_bottom))
-                    elif self.face ==  FACE_EAST:
-                        triangle.append(cmpPoint(x_right, self.pos.y))
-                        triangle.append(cmpPoint(x_right + 5, y_mid))
-                        triangle.append(cmpPoint(x_right, y_bottom))
-                    elif self.face ==  FACE_SOUTH:
-                        triangle.append(cmpPoint(self.pos.x, y_bottom))
-                        triangle.append(cmpPoint(x_mid, y_bottom + 5))
-                        triangle.append(cmpPoint(x_right, y_bottom))
-                    elif self.face ==  FACE_NORTH:
-                        triangle.append(cmpPoint(self.pos.x, self.pos.y))
-                        triangle.append(cmpPoint(x_mid, self.pos.y - 5))
-                        triangle.append(cmpPoint(x_right, self.pos.y))
-                    elif self.face == FACE_NORTHEAST:
-                        triangle.append(cmpPoint(x_mid, self.pos.y))
-                        triangle.append(cmpPoint(x_right + 5, self.pos.y - 5))
-                        triangle.append(cmpPoint(x_right, y_mid))
-                        triangle.append(cmpPoint(x_right, self.pos.y))
-                    elif self.face == FACE_SOUTHEAST:
-                        triangle.append(cmpPoint(x_right, y_mid))
-                        triangle.append(cmpPoint(x_right + 5, y_bottom + 5))
-                        triangle.append(cmpPoint(x_mid, y_bottom))
-                        triangle.append(cmpPoint(x_right, y_bottom))
-                    elif self.face == FACE_SOUTHWEST:
-                        triangle.append(cmpPoint(x_mid, y_bottom))
-                        triangle.append(cmpPoint(self.pos.x - 5, y_bottom + 5))
-                        triangle.append(cmpPoint(self.pos.x, y_mid))
-                        triangle.append(cmpPoint(self.pos.x, y_bottom))
-                    elif self.face == FACE_NORTHWEST:
-                        triangle.append(cmpPoint(self.pos.x, y_mid))
-                        triangle.append(cmpPoint(self.pos.x - 5, self.pos.y - 5))
-                        triangle.append(cmpPoint(x_mid, self.pos.y))
-                        triangle.append(cmpPoint(self.pos.x, self.pos.y))
-                    dc.DrawPolygon(triangle)
-                    dc.SetBrush(wx.NullBrush)
-                    dc.SetPen(wx.NullPen)
-
-                # Draw the heading if needed
-                if self.heading:
-                    x_adjust = 0
-                    y_adjust = 4
-                    x_half = self.bmp.GetWidth()/2
-                    y_half = self.bmp.GetHeight()/2
-                    x_quarter = self.bmp.GetWidth()/4
-                    y_quarter = self.bmp.GetHeight()/4
-                    x_3quarter = x_quarter*3
-                    y_3quarter = y_quarter*3
-                    x_full = self.bmp.GetWidth()
-                    y_full = self.bmp.GetHeight()
-                    x_center = self.pos.x + x_half
-                    y_center = self.pos.y + y_half
-                    # Remember, the pen/brush must be a different color than the
-                    # facing marker!!!!  We'll use black/cyan for starters.
-                    # Also notice that we will draw the heading on top of the
-                    # larger facing marker.
-                    dc.SetPen(wx.BLACK_PEN)
-                    dc.SetBrush(wx.CYAN_BRUSH)
-                    triangle = []
-
-                    # Figure out which direction to draw the marker!!
-                    if self.heading == FACE_NORTH:
-                        triangle.append(cmpPoint(x_center - x_quarter, y_center - y_half ))
-                        triangle.append(cmpPoint(x_center, y_center - y_3quarter ))
-                        triangle.append(cmpPoint(x_center + x_quarter, y_center - y_half ))
-                    elif self.heading ==  FACE_SOUTH:
-                        triangle.append(cmpPoint(x_center - x_quarter, y_center + y_half ))
-                        triangle.append(cmpPoint(x_center, y_center + y_3quarter ))
-                        triangle.append(cmpPoint(x_center + x_quarter, y_center + y_half ))
-                    elif self.heading == FACE_NORTHEAST:
-                        triangle.append(cmpPoint(x_center + x_quarter, y_center - y_half ))
-                        triangle.append(cmpPoint(x_center + x_3quarter, y_center - y_3quarter ))
-                        triangle.append(cmpPoint(x_center + x_half, y_center - y_quarter ))
-                    elif self.heading == FACE_EAST:
-                        triangle.append(cmpPoint(x_center + x_half, y_center - y_quarter ))
-                        triangle.append(cmpPoint(x_center + x_3quarter, y_center ))
-                        triangle.append(cmpPoint(x_center + x_half, y_center + y_quarter ))
-                    elif self.heading == FACE_SOUTHEAST:
-                        triangle.append(cmpPoint(x_center + x_half, y_center + y_quarter ))
-                        triangle.append(cmpPoint(x_center + x_3quarter, y_center + y_3quarter ))
-                        triangle.append(cmpPoint(x_center + x_quarter, y_center + y_half ))
-                    elif self.heading == FACE_SOUTHWEST:
-                        triangle.append(cmpPoint(x_center - x_quarter, y_center + y_half ))
-                        triangle.append(cmpPoint(x_center - x_3quarter, y_center + y_3quarter ))
-                        triangle.append(cmpPoint(x_center - x_half, y_center + y_quarter ))
-                    elif self.heading == FACE_WEST:
-                        triangle.append(cmpPoint(x_center - x_half, y_center + y_quarter ))
-                        triangle.append(cmpPoint(x_center - x_3quarter, y_center ))
-                        triangle.append(cmpPoint(x_center - x_half, y_center - y_quarter ))
-                    elif self.heading == FACE_NORTHWEST:
-                        triangle.append(cmpPoint(x_center - x_half, y_center - y_quarter ))
-                        triangle.append(cmpPoint(x_center - x_3quarter, y_center - y_3quarter ))
-                        triangle.append(cmpPoint(x_center - x_quarter, y_center - y_half ))
-                    dc.DrawPolygon(triangle)
-                    dc.SetBrush(wx.NullBrush)
-                    dc.SetPen(wx.NullPen)
-                #selected outline
-                if self.selected:
-                    dc.SetPen(wx.RED_PEN)
-                    dc.SetBrush(wx.TRANSPARENT_BRUSH)
-                    dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
-                    dc.SetBrush(wx.NullBrush)
-                    dc.SetPen(wx.NullPen)
+        
+            #selected outline
+            if self.selected:
+                dc.SetPen(wx.RED_PEN)
+                dc.SetBrush(wx.TRANSPARENT_BRUSH)
+                dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
+                dc.SetBrush(wx.NullBrush)
+                dc.SetPen(wx.NullPen)
+            return True
+        elif self.hide: return True
+        
+        else:
+            bmp = self.bmp_gray if self.gray else self.bmp
+            try: dc.DrawBitmap(bmp, self.pos.x, self.pos.y, True)
+            except: print bmp
+            self.left = 0
+            self.right = self.bmp.GetWidth()
+            self.top = 0
+            self.bottom = self.bmp.GetHeight()
+        
+            # Draw the facing marker if needed
+            if self.face != 0:
+                x_mid = self.pos.x + (self.bmp.GetWidth()/2)
+                x_right = self.pos.x + self.bmp.GetWidth()
+                y_mid = self.pos.y + (self.bmp.GetHeight()/2)
+                y_bottom = self.pos.y + self.bmp.GetHeight()
+                dc.SetPen(wx.WHITE_PEN)
+                dc.SetBrush(wx.RED_BRUSH)
+                triangle = []
+        
+                # Figure out which direction to draw the marker!!
+                tri_list = {
+                FACE_WEST: [cmpPoint(self.pos.x, self.pos.y), cmpPoint(self.pos.x-5, y_mid), cmpPoint(self.pos.x, y_bottom)], 
+                FACE_EAST: [cmpPoint(x_right, self.pos.y), cmpPoint(x_right + 5, y_mid), cmpPoint(x_right, y_bottom)], 
+                FACE_SOUTH: [cmpPoint(self.pos.x, y_bottom), cmpPoint(x_mid, y_bottom + 5), cmpPoint(x_right, y_bottom)],
+                FACE_NORTH: [cmpPoint(self.pos.x, self.pos.y), cmpPoint(x_mid, self.pos.y - 5), cmpPoint(x_right, self.pos.y)],
+                FACE_NORTHEAST: [cmpPoint(x_mid, self.pos.y), cmpPoint(x_right + 5, self.pos.y - 5), cmpPoint(x_right, y_mid), cmpPoint(x_right, self.pos.y)],
+                FACE_SOUTHEAST: [cmpPoint(x_right, y_mid), cmpPoint(x_right + 5, y_bottom + 5), cmpPoint(x_mid, y_bottom), cmpPoint(x_right, y_bottom)],
+                FACE_SOUTHWEST: [cmpPoint(x_mid, y_bottom), cmpPoint(self.pos.x - 5, y_bottom + 5),
+                cmpPoint(self.pos.x, y_mid), cmpPoint(self.pos.x, y_bottom)],
+                FACE_NORTHWEST: [cmpPoint(self.pos.x, y_mid), cmpPoint(self.pos.x - 5, self.pos.y - 5), cmpPoint(x_mid, self.pos.y), cmpPoint(self.pos.x, self.pos.y)]
+                }
+                for tri in tri_list[self.face]:
+                    triangle.append(tri)
+                del tri_list
+                dc.DrawPolygon(triangle)
+                dc.SetBrush(wx.NullBrush)
+                dc.SetPen(wx.NullPen)
+        
+            # Draw the heading if needed
+            if self.heading:
+                x_adjust = 0
+                y_adjust = 4
+                x_half = self.bmp.GetWidth()/2
+                y_half = self.bmp.GetHeight()/2
+                x_quarter = self.bmp.GetWidth()/4
+                y_quarter = self.bmp.GetHeight()/4
+                x_3quarter = x_quarter*3
+                y_3quarter = y_quarter*3
+                x_full = self.bmp.GetWidth()
+                y_full = self.bmp.GetHeight()
+                x_center = self.pos.x + x_half
+                y_center = self.pos.y + y_half
+                # Remember, the pen/brush must be a different color than the
+                # facing marker!!!!  We'll use black/cyan for starters.
+                # Also notice that we will draw the heading on top of the
+                # larger facing marker.
+                dc.SetPen(wx.BLACK_PEN)
+                dc.SetBrush(wx.CYAN_BRUSH)
+                triangle = []
+                # Figure out which direction to draw the marker!!
+                tri_list = {
+                FACE_NORTH: [cmpPoint(x_center - x_quarter, y_center - y_half ), cmpPoint(x_center, y_center - y_3quarter ), cmpPoint(x_center + x_quarter, y_center - y_half)],
+                FACE_SOUTH: [cmpPoint(x_center - x_quarter, y_center + y_half ), cmpPoint(x_center, y_center + y_3quarter ), cmpPoint(x_center + x_quarter, y_center + y_half )],
+                FACE_NORTHEAST: [cmpPoint(x_center + x_quarter, y_center - y_half ), cmpPoint(x_center + x_3quarter, y_center - y_3quarter ), cmpPoint(x_center + x_half, y_center - y_quarter)],
+                FACE_EAST: [cmpPoint(x_center + x_half, y_center - y_quarter ), cmpPoint(x_center + x_3quarter, y_center ), cmpPoint(x_center + x_half, y_center + y_quarter )],
+                FACE_SOUTHEAST: [cmpPoint(x_center + x_half, y_center + y_quarter ), cmpPoint(x_center + x_3quarter, y_center + y_3quarter ), cmpPoint(x_center + x_quarter, y_center + y_half )],
+                FACE_SOUTHWEST: [cmpPoint(x_center - x_quarter, y_center + y_half ), cmpPoint(x_center - x_3quarter, y_center + y_3quarter ), cmpPoint(x_center - x_half, y_center + y_quarter )],
+                FACE_WEST: [cmpPoint(x_center - x_half, y_center + y_quarter ), cmpPoint(x_center - x_3quarter, y_center ), cmpPoint(x_center - x_half, y_center - y_quarter )],
+                FACE_NORTHWEST: [cmpPoint(x_center - x_half, y_center - y_quarter ), cmpPoint(x_center - x_3quarter, y_center - y_3quarter ), cmpPoint(x_center - x_quarter, y_center - y_half )]}
+                for tri in tri_list[self.heading]:
+                    triangle.append(tri)
+                del tri_list
+                dc.DrawPolygon(triangle)
+                dc.SetBrush(wx.NullBrush)
+                dc.SetPen(wx.NullPen)
+            #selected outline
+            if self.selected:
+                dc.SetPen(wx.RED_PEN)
+                dc.SetBrush(wx.TRANSPARENT_BRUSH)
+                dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
+                dc.SetBrush(wx.NullBrush)
+                dc.SetPen(wx.NullPen)
+            if mini_layer.show_labels:
                 # draw label
-                label = mini_layer.get_mini_label(self)
-                if len(label):
-                    dc.SetTextForeground(wx.RED)
-                    (textWidth,textHeight) = dc.GetTextExtent(label)
-                    x = self.pos.x +((self.bmp.GetWidth() - textWidth) /2) - 1
-                    y = self.pos.y + self.bmp.GetHeight() + 6
-                    dc.SetPen(wx.WHITE_PEN)
-                    dc.SetBrush(wx.WHITE_BRUSH)
-                    dc.DrawRectangle(x,y,textWidth+2,textHeight+2)
-                    if (textWidth+2 > self.right):
-                        self.right += int((textWidth+2-self.right)/2)+1
-                        self.left -= int((textWidth+2-self.right)/2)+1
-                    self.bottom = y+textHeight+2-self.pos.y
-                    dc.SetPen(wx.NullPen)
-                    dc.SetBrush(wx.NullBrush)
-                    dc.DrawText(label,x+1,y+1)
-                self.top-=5
-                self.bottom+=5
-                self.left-=5
-                self.right+=5
-                return True
-        else: return False
+                self.mini_label(mini_layer, dc)
+            self.top-=5
+            self.bottom+=5
+            self.left-=5
+            self.right+=5
+            return True
+        
+        
+    def mini_label(self, mini_layer, dc):
+        label = mini_layer.get_mini_label(self)
+        if len(label):
+            dc.SetTextForeground(wx.RED)
+            (textWidth,textHeight) = dc.GetTextExtent(label)
+            x = self.pos.x +((self.bmp.GetWidth() - textWidth) /2) - 1
+            y = self.pos.y + self.bmp.GetHeight() + 6
+            dc.SetPen(wx.WHITE_PEN)
+            dc.SetBrush(wx.WHITE_BRUSH)
+            dc.DrawRectangle(x,y,textWidth+2,textHeight+2)
+            if (textWidth+2 > self.right):
+                self.right += int((textWidth+2-self.right)/2)+1
+                self.left -= int((textWidth+2-self.right)/2)+1
+            self.bottom = y+textHeight+2-self.pos.y
+            dc.SetPen(wx.NullPen)
+            dc.SetBrush(wx.NullBrush)
+            dc.DrawText(label,x+1,y+1)
 
     def toxml(self, action="update"):
-        if action == "del":
-            xml_str = "<miniature action='del' id='" + self.id + "'/>"
-            return xml_str
-        xml_str = "<miniature"
-        xml_str += " action='" + action + "'"
-        xml_str += " label='" + self.label + "'"
-        xml_str+= " id='" + self.id + "'"
+        mini = Element('miniature')
+        if action == 'del':
+            mini.set('action', action)
+            mini.set('id', str(self.id))
+            return tostring(mini)
+        mini.set('action', action)
+        mini.set('id', str(self.id))
+        mini.set('label', self.label)
         if self.pos != None:
-            xml_str += " posx='" + str(self.pos.x) + "'"
-            xml_str += " posy='" + str(self.pos.y) + "'"
-        if self.heading != None: xml_str += " heading='" + str(self.heading) + "'"
-        if self.face != None: xml_str += " face='" + str(self.face) + "'"
-        if self.path != None: xml_str += " path='" + urllib.quote(self.path).replace('%3A', ':') + "'"
-        if self.locked: xml_str += "  locked='1'"
-        else: xml_str += "  locked='0'"
-        if self.hide: xml_str += " hide='1'"
-        else: xml_str += " hide='0'"
-        if self.snap_to_align != None: xml_str += " align='" + str(self.snap_to_align) + "'"
-        if self.id != None: xml_str += " zorder='" + str(self.zorder) + "'"
-        if self.width != None: xml_str += " width='" + str(self.width) + "'"
-        if self.height != None: xml_str += " height='" + str(self.height) + "'"
+            mini.set('posx', str(self.pos.x))
+            mini.set('posy', str(self.pos.y))
+        if self.heading != None: mini.set('heading', str(self.heading))
+        if self.face != None: mini.set('face', str(self.face))
+        if self.path != None: mini.set('path', str(urllib.quote(self.path).replace('%3A', ':')))
+        mini.set('locked', '1') if self.locked else mini.set('locked', '0')
+        mini.set('hide', '1') if self.hide else mini.set('hide', '0')
+        if self.snap_to_align != None: mini.set('align', str(self.snap_to_align))
+        if self.id != None: mini.set('zorder', str(self.zorder))
+        if self.width != None: mini.set('width', str(self.width))
+        if self.height != None: mini.set('height', str(self.height))
         if self.local:
-            xml_str += ' local="' + str(self.local) + '"'
-            xml_str += ' localPath="' + str(urllib.quote(self.localPath).replace('%3A', ':')) + '"'
-            xml_str += ' localTime="' + str(self.localTime) + '"'
-        xml_str += " />"
+            mini.set('local', str(self.local))
+            mini.set('localPath', str(urllib.quote(self.localPath).replace('%3A', ':')))
+            mini.set('localTime', str(localTime))
         if (action == "update" and self.isUpdated) or action == "new":
             self.isUpdated = False
-            return xml_str
+            return mini
         else: return ''
 
     def takedom(self, xml_dom):
         self.id = xml_dom.getAttribute("id")
-        if xml_dom.hasAttribute("posx"):
-            self.pos.x = int(xml_dom.getAttribute("posx"))
-        if xml_dom.hasAttribute("posy"):
-            self.pos.y = int(xml_dom.getAttribute("posy"))
-        if xml_dom.hasAttribute("heading"):
-            self.heading = int(xml_dom.getAttribute("heading"))
-        if xml_dom.hasAttribute("face"):
-            self.face = int(xml_dom.getAttribute("face"))
+        if xml_dom.hasAttribute("posx"): self.pos.x = int(xml_dom.getAttribute("posx"))
+        if xml_dom.hasAttribute("posy"): self.pos.y = int(xml_dom.getAttribute("posy"))
+        if xml_dom.hasAttribute("heading"): self.heading = int(xml_dom.getAttribute("heading"))
+        if xml_dom.hasAttribute("face"): self.face = int(xml_dom.getAttribute("face"))
         if xml_dom.hasAttribute("path"):
             self.path = urllib.unquote(xml_dom.getAttribute("path"))
             self.set_bmp(ImageHandler.load(self.path, 'miniature', self.id))
@@ -425,7 +386,7 @@
         self.id = -1 #added.
         self.miniatures = []
         self.serial_number = 0
-
+        self.show_labels = True
         # Set the font of the labels to be the same as the chat window
         # only smaller.
         font_size = int(settings.get_setting('defaultfontsize'))
@@ -470,7 +431,7 @@
         bmp = ImageHandler.load(path, 'miniature', id)
         if bmp:
             mini = BmpMiniature(id, path, bmp, pos, heading, face, label, 
-                zorder=self. get_next_highest_z(), width=width, 
+                zorder=self.get_next_highest_z(), width=width, 
                 height=height, local=local, localPath=localPath, localTime=localTime)
             self.miniatures.append(mini)
             xml_str = "<map><miniatures>"
@@ -524,16 +485,20 @@
 
     def layerToXML(self, action="update"):
         """ format  """
-        minis_string = ""
+        mini_string = ""
         if self.miniatures:
-            for m in self.miniatures: minis_string += m.toxml(action)
-        if minis_string != '':
-            s = "<miniatures"
-            s += " serial='" + str(self.serial_number) + "'"
-            s += ">"
-            s += minis_string
-            s += "</miniatures>"
-            return s
+            for m in self.miniatures: mini_string = m.toxml(action)
+        if mini_string != '':
+            s = Element('miniatures')
+            s.set('serial', str(self.serial_number))
+            s.append(mini_string)
+            #s = "<miniatures"
+            #s += " serial='" + str(self.serial_number) + "'"
+            #s += ">"
+            #s += mini_string
+            #s += "</miniatures>"
+            #return s
+            return tostring(s)
         else: return ""
 
     def layerTakeDOM(self, xml_dom):
@@ -562,9 +527,9 @@
                 if c.hasAttribute('face'): face = int(c.getAttribute('face'))
                 if c.hasAttribute('align'): snap_to_align = int(c.getAttribute('align'))
                 if c.getAttribute('zorder'): zorder = int(c.getAttribute('zorder'))
-                min = BmpMiniature(id, path, ImageHandler.load(path, 'miniature', id), pos, heading, 
-                    face, label, locked, hide, snap_to_align, zorder, width, height)
-                self.miniatures.append(min)
+                image = ImageHandler.load(path, 'miniature', id)
+                mini = BmpMiniature(id, path, image, pos, heading, face, label, locked, hide, snap_to_align, zorder, width, height, func='minis')
+                self.miniatures.append(mini)
                 if c.hasAttribute('local') and c.getAttribute('local') == 'True' and os.path.exists(urllib.unquote(c.getAttribute('localPath'))):
                     localPath = urllib.unquote(c.getAttribute('localPath'))
                     local = True
--- a/orpg/mapper/miniatures_handler.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/mapper/miniatures_handler.py	Wed Oct 28 14:24:54 2009 -0500
@@ -42,7 +42,11 @@
 
 from orpg.tools.orpg_settings import settings
 
-LABEL_TOOL = wx.NewId()
+from xml.etree.ElementTree import ElementTree, Element
+from xml.etree.ElementTree import fromstring, tostring
+
+SHOW_LABELS_TOOL = wx.NewId()
+AUTO_LABEL_TOOL = wx.NewId()
 LAYER_TOOL = wx.NewId()
 MIN_LIST_TOOL = wx.NewId()
 MIN_TOOL = wx.NewId()
@@ -103,7 +107,6 @@
         self.sel_min = None
         self.auto_label = 1
         self.use_serial = 1
-        self.auto_label_cb = None
         self.canvas = canvas
         self.settings = settings
         self.mini_rclick_menu_extra_items = {}
@@ -119,19 +122,16 @@
         self.tooltip_timer.Stop()
         dt = myFileDropTarget(self)
         self.canvas.SetDropTarget(dt)
+        self.tooltip = wx.ToolTip('')
         #wxInitAllImageHandlers()
 
     def build_ctrls(self):
         base_layer_handler.build_ctrls(self)
         # add controls in reverse order! (unless you want them after the default tools)
-        self.auto_label_cb = wx.CheckBox(self, wx.ID_ANY, ' Auto Label ', (-1,-1),(-1,-1))
-        self.auto_label_cb.SetValue(self.auto_label)
         self.min_url = wx.ComboBox(self, wx.ID_ANY, "http://", style=wx.CB_DROPDOWN | wx.CB_SORT)
         self.localBrowse = wx.Button(self, wx.ID_ANY, 'Browse', style=wx.BU_EXACTFIT)
         minilist = createMaskedButton( self, dir_struct["icon"]+'questionhead.gif', 'Edit miniature properties', wx.ID_ANY)
         miniadd = wx.Button(self, wx.ID_OK, "Add Miniature", style=wx.BU_EXACTFIT)
-        self.sizer.Add(self.auto_label_cb,0,wx.ALIGN_CENTER)
-        self.sizer.Add((6, 0))
         self.sizer.Add(self.min_url, 1, wx.ALIGN_CENTER)
         self.sizer.Add((6, 0))
         self.sizer.Add(miniadd, 0, wx.ALIGN_CENTER)
@@ -142,7 +142,6 @@
         self.Bind(wx.EVT_BUTTON, self.on_min_list, minilist)
         self.Bind(wx.EVT_BUTTON, self.on_miniature, miniadd)
         self.Bind(wx.EVT_BUTTON, self.on_browse, self.localBrowse)
-        self.Bind(wx.EVT_CHECKBOX, self.on_label, self.auto_label_cb)
 
     def on_browse(self, evt):
         if not self.role_is_gm_or_player(): return
@@ -207,15 +206,18 @@
     def build_menu(self,label = "Miniature"):
         base_layer_handler.build_menu(self,label)
         self.main_menu.AppendSeparator()
-        self.main_menu.Append(LABEL_TOOL,"&Auto label","",1)
-        self.main_menu.Check(LABEL_TOOL,self.auto_label)
+        self.main_menu.Append(SHOW_LABELS_TOOL, "&Show Labels", '', 1)
+        self.main_menu.Check(SHOW_LABELS_TOOL, self.canvas.layers['miniatures'].show_labels)
+        self.main_menu.Append(AUTO_LABEL_TOOL,"&Auto label","",1)
+        self.main_menu.Check(AUTO_LABEL_TOOL, self.auto_label) 
         self.main_menu.Append(SERIAL_TOOL,"&Number minis","",1)
         self.main_menu.Check(SERIAL_TOOL, self.use_serial)
         self.main_menu.Append(MAP_REFRESH_MINI_URLS,"&Refresh miniatures")       #  Add the menu item
         self.main_menu.AppendSeparator()
         self.main_menu.Append(MIN_MOVE, "Move")
         self.canvas.Bind(wx.EVT_MENU, self.on_map_board_menu_item, id=MAP_REFRESH_MINI_URLS)          #  Set the handler
-        self.canvas.Bind(wx.EVT_MENU, self.on_label, id=LABEL_TOOL)
+        self.canvas.Bind(wx.EVT_MENU, self.on_show_labels, id=SHOW_LABELS_TOOL)
+        self.canvas.Bind(wx.EVT_MENU, self.on_auto_label, id=AUTO_LABEL_TOOL)
         self.canvas.Bind(wx.EVT_MENU, self.on_serial, id=SERIAL_TOOL)
         # build miniature meenu
         self.min_menu = wx.Menu()
@@ -355,15 +357,18 @@
             return
         elif id == MIN_REMOVE: self.canvas.layers['miniatures'].del_miniature(self.sel_rmin)
         elif id == MIN_TO_GAMETREE:
+            ### Alpha ### implements ElementTree
             min_xml = self.sel_rmin.toxml(action="new")
-            node_begin = "<nodehandler module='map_miniature_nodehandler' class='map_miniature_handler' name='"
-            if self.sel_rmin.label: node_begin += self.sel_rmin.label + "'"
-            else:  node_begin += "Unnamed Miniature'"
-            node_begin += ">"
-	    gametree = component.get('tree')
-            node_xml = node_begin + min_xml + '</nodehandler>'
-            #print "Sending this XML to insert_xml:" + node_xml
-            gametree.insert_xml(str(node_xml))
+            node = Element('nodehandler')
+            mini = fromstring(min_xml)
+            node.set('module', 'map_miniature_nodehandler')
+            node.set('class', 'map_miniature_handler')
+            name = self.sel_rmin.label if self.sel_rmin.label else 'Unnamed Miniature'
+            node.set('name', name)
+            node.append(mini)
+            gametree = component.get('tree')
+            gametree.insert_xml(tostring(node))
+            ### ElementTree is a nice decision from Core, kudos!! ###
         elif id == MIN_SHOW_HIDE:
             if self.sel_rmin.hide:  self.sel_rmin.hide = 0
             else: self.sel_rmin.hide = 1
@@ -500,6 +505,8 @@
         if min_url == "" or min_url == "http://": return
         if min_url[:7] != "http://" : min_url = "http://" + min_url
         # make label
+        if self.auto_label: print 'auto-label'
+        if not self.auto_label: print 'False'
         if self.auto_label and min_url[-4:-3] == '.':
             start = min_url.rfind("/") + 1
             min_label = min_url[start:len(min_url)-4]
@@ -510,6 +517,7 @@
         try:
             id = 'mini-' + self.canvas.frame.session.get_next_id()
             # make the new mini appear in top left of current viewable map
+            print id
             dc = wx.ClientDC(self.canvas)
             self.canvas.PrepareDC(dc)
             dc.SetUserScale(self.canvas.layers['grid'].mapscale,self.canvas.layers['grid'].mapscale)
@@ -529,9 +537,14 @@
         #except Exception, e:
             #wx.MessageBox(str(e),"Miniature Error")
 
-    def on_label(self,evt):
+    def on_show_labels(self, evt):
+        show_labels = not self.canvas.layers['miniatures'].show_labels
+        self.canvas.layers['miniatures'].show_labels = show_labels
+        self.canvas.Refresh()
+
+    def on_auto_label(self,evt):
         self.auto_label = not self.auto_label
-        self.auto_label_cb.SetValue(self.auto_label)
+        #self.auto_label_cb.SetValue(self.auto_label)
         #self.send_map_data()
         #self.Refresh()
 
@@ -541,7 +554,7 @@
             self.infoPost("You must be a GM to use this feature")
             return
         #d = min_list_panel(self.frame.GetParent(),self.canvas.layers,"Miniature list")
-        d = min_list_panel(self.canvas.frame,self.canvas.layers,"Miniature list")
+        d = min_list_panel(self.canvas.frame, self.canvas.layers, "Miniature list")
         if d.ShowModal() == wx.ID_OK: d.Destroy()
         self.canvas.Refresh(False)
 
@@ -630,9 +643,11 @@
         pos = wx.Point(dc.DeviceToLogicalX(pos.x), dc.DeviceToLogicalY(pos.y))
         mini_list = self.getMiniListOrSelectedMini(pos)
         if len(mini_list) > 0:
-            tooltip = self.get_mini_tooltip(mini_list)
-            self.canvas.SetToolTipString(tooltip)
-        else: self.canvas.SetToolTipString("")
+            tooltip = mini_list[0].label
+            #self.canvas.SetToolTipString(mini_list[0].label) 
+            #Once set, it never unsets, so it sucks.
+        else:
+            self.canvas.SetToolTipString('')
 
     def on_motion(self,evt):
         if evt.Dragging() and evt.LeftIsDown():
@@ -640,8 +655,6 @@
                 drag_bmp = self.drag_mini.bmp
                 if self.drag_mini.width and self.drag_mini.height:
                     tmp_image = drag_bmp.ConvertToImage()
-                    tmp_image.Rescale(int(self.drag_mini.width * self.canvas.layers['grid'].mapscale), 
-                        int(self.drag_mini.height * self.canvas.layers['grid'].mapscale))
                     tmp_image.ConvertAlphaToMask()
                     drag_bmp = tmp_image.ConvertToBitmap()
                     mask = wx.Mask(drag_bmp, wx.Colour(tmp_image.GetMaskRed(), 
@@ -662,7 +675,7 @@
                 self.canvas.drag.Move(evt.GetPosition())
                 self.canvas.drag.Show()
         # reset tool tip timer
-        self.canvas.SetToolTipString("")
+        self.canvas.SetToolTipString('')
         self.tooltip_timer.Restart(self.tooltip_delay_miliseconds, evt.GetPosition())
 
     def on_left_up(self,evt):
--- a/orpg/networking/gsclient.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/networking/gsclient.py	Wed Oct 28 14:24:54 2009 -0500
@@ -360,9 +360,9 @@
         self.texts["address"].SetValue(address + ":" + str(port))
         self.refresh_room_list()
 
-    def on_text(self,evt):
+    def on_text(self, evt):
         id = evt.GetId()
-        if (id == ADDRESS) and (self.cur_server_index >= 0):
+        if (id == self.texts["address"].GetValue()) and (self.cur_server_index >= 0):
             #print "ADDRESS id = ", id, "index = ", self.cur_server_index
             self.cur_server_index = -1
         evt.Skip()
--- a/orpg/networking/mplay_client.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/networking/mplay_client.py	Wed Oct 28 14:24:54 2009 -0500
@@ -46,6 +46,9 @@
 from orpg.orpgCore import component
 from orpg.orpg_xml import xml
 
+from xml.etree.ElementTree import ElementTree, Element
+from xml.etree.ElementTree import fromstring, tostring
+
 try:
     import bz2
     cmpBZ2 = True
@@ -319,6 +322,29 @@
      client provided IP address to have much value.  As such, we now label it as deprecated.
     """
     def toxml(self,action):
+        """
+        el = Element('player')
+        el.set('name', myescape(self.name))
+        el.set('action', action)
+        el.set('id', self.id)
+        el.set('group_id', self.group_id)
+        el.set('ip', self.ip)
+        el.set('status', self.text_status)
+        el.set('version', self.version)
+        el.set('protocol_version', self.protocol_version)
+        el.set('client_string', self.client_string)
+        el.set('useCompression', str(self.useCompression))
+
+        cmpType = 'None'
+        if cmpBZ2 and (self.compressionType == 'Undefined' or self.compressionType == bz2):
+            cmpType = 'bz2'
+        elif cmpZLIB and (self.compressionType == 'Undefined' or self.compressionType == zlib):
+            cmpType = 'zlib'
+
+        el.set('cmpType', cmpType)
+        return el
+        """
+        
         xml_data = '<player name="' + myescape(self.name) + '"'
         xml_data += ' action="' + action + '" id="' + self.id + '"'
         xml_data += ' group_id="' + self.group_id + '" ip="' + self.ip + '"'
--- a/orpg/orpg_version.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/orpg_version.py	Wed Oct 28 14:24:54 2009 -0500
@@ -4,7 +4,7 @@
 #BUILD NUMBER FORMAT: "YYMMDD-##" where ## is the incremental daily build index (if needed)
 DISTRO = "Traipse Alpha"
 DIS_VER = "Ornery Orc"
-BUILD = "091012-02"
+BUILD = "091028-00"
 
 # This version is for network capability.
 PROTOCOL_VERSION = "1.2"
--- a/orpg/orpg_xml.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/orpg_xml.py	Wed Oct 28 14:24:54 2009 -0500
@@ -32,15 +32,15 @@
 from orpg.tools.orpg_log import logger
 from orpg.tools.decorators import debugging
 
-class xml:
+class xml:
     @debugging
     def __init__(self):
         pass
-
+
     @debugging
     def toxml(self, root, pretty=0):
         return root.toxml(pretty)
-
+
     @debugging
     def parseXml(self, s):
         "parse and return doc"
@@ -51,7 +51,7 @@
         except Exception, e:
             print e
             return None
-
+
     @debugging
     def safe_get_text_node(self, xml_dom):
         """ returns the child text node or creates one if doesnt exist """
@@ -60,7 +60,7 @@
             t_node = minidom.Text("")
             t_node = xml_dom.appendChild(t_node)
         return t_node
-
+
     @debugging
     def strip_unicode(self, txt):
         for i in xrange(len(txt)):
@@ -68,7 +68,7 @@
                 try: txt = txt.replace(txt[i], '&#' + str(ord(txt[i])) + ';')
                 except: txt = txt.replace(txt[i], '{?}')
         return txt
-
+
     @debugging
     def strip_text(self, txt):
         #  The following block strips out 8-bit characters
--- a/orpg/tools/pluginui.py	Mon Oct 12 23:24:10 2009 -0500
+++ b/orpg/tools/pluginui.py	Wed Oct 28 14:24:54 2009 -0500
@@ -316,7 +316,7 @@
             i += 1
         self.pluginList.SetColumnWidth(0, wx.LIST_AUTOSIZE)
         self.pluginList.SetColumnWidth(1, wx.LIST_AUTOSIZE)
-        self.pluginList.SetColumnWidth(2, wx.LIST_AUTOSIZE)
+        #self.pluginList.SetColumnWidth(2, wx.LIST_AUTOSIZE)
         self.__doLayout()
         self.__disablePluginBtns()