diff orpg/tools/aliaslib.py @ 0:4385a7d0efd1 grumpy-goblin

Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author sirebral
date Tue, 14 Jul 2009 16:41:58 -0500
parents
children c160f26ecf65
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/orpg/tools/aliaslib.py	Tue Jul 14 16:41:58 2009 -0500
@@ -0,0 +1,956 @@
+# Copyright (C) 2000-2001 The OpenRPG Project
+#
+#   openrpg-dev@lists.sourceforge.net
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# --
+#
+# File: aliaslib.py
+# Author: Dj Gilcrease
+# Maintainer:
+# Version:
+#   $Id: aliaslib.py,v 1.20 2007/08/09 05:23:21 digitalxero Exp $
+#
+# Description: nodehandler for alias.
+#
+
+__version__ = "$Id: aliaslib.py,v 1.20 2007/08/09 05:23:21 digitalxero Exp $"
+
+from orpg.orpg_wx import *
+from orpg.orpgCore import *
+from orpg.orpg_windows import createMaskedButton, orpgMultiCheckBoxDlg
+from orpg.tools.rgbhex import RGBHex
+import orpg.tools.orpg_log
+import orpg.dirpath
+import orpg.orpg_xml
+import orpg.tools.validate
+import orpg.tools.orpg_settings
+
+class AliasLib(wx.Frame):
+    def __init__(self):
+        self.orpgframe = open_rpg.get_component('frame')
+        self.log = open_rpg.get_component('log')
+        self.log.log("Enter AliasLib", ORPG_DEBUG)
+        wx.Frame.__init__(self, None, wx.ID_ANY, title="Alias Lib")
+        self.orpgframe.Freeze()
+        self.Freeze()
+        self.SetOwnBackgroundColour('#EFEFEF')
+        self.dir_struct = open_rpg.get_component('dir_struct')
+        self.settings = open_rpg.get_component('settings')
+        self.xml = open_rpg.get_component('xml')
+        self.validate = open_rpg.get_component('validate')
+        self.filename = self.settings.get_setting('aliasfile') + '.alias'
+        self.validate.config_file(self.filename, "default_alias.alias")
+        self.buildMenu()
+        self.buildButtons()
+        self.buildGUI()
+        wx.CallAfter(self.InitSetup)
+        wx.CallAfter(self.loadFile)
+        self.Thaw()
+        self.orpgframe.Thaw()
+        self.Bind(wx.EVT_CLOSE, self.OnMB_FileExit)
+        self.log.log("Exit AliasLib", ORPG_DEBUG)
+
+    def InitSetup(self):
+        self.chat = open_rpg.get_component('chat')
+        self.gametree = open_rpg.get_component('tree')
+        self.map = open_rpg.get_component('map')
+        self.session = open_rpg.get_component('session')
+
+    def buildMenu(self):
+        self.log.log("Enter AliasLib->buildMenu(self)", ORPG_DEBUG)
+        filemenu = wx.Menu()
+        item = wx.MenuItem(filemenu, wx.ID_ANY, "&New\tCtrl+N", "New ALias Lib")
+        self.Bind(wx.EVT_MENU, self.OnMB_FileNew, item)
+        filemenu.AppendItem(item)
+        item = wx.MenuItem(filemenu, wx.ID_ANY, "&Open\tCtrl+O", "Open Alias Lib")
+        self.Bind(wx.EVT_MENU, self.OnMB_FileOpen, item)
+        filemenu.AppendItem(item)
+        item = wx.MenuItem(filemenu, wx.ID_ANY, "&Save\tCtrl+S", "Save Alias Lib")
+        self.Bind(wx.EVT_MENU, self.OnMB_FileSave, item)
+        filemenu.AppendItem(item)
+        item = wx.MenuItem(filemenu, wx.ID_ANY, "&Export to Tree", "Export to Tree")
+        self.Bind(wx.EVT_MENU, self.OnMB_FileExportToTree, item)
+        filemenu.AppendItem(item)
+        item = wx.MenuItem(filemenu, wx.ID_ANY, "&Exit\tCtrl+X", "Exit")
+        self.Bind(wx.EVT_MENU, self.OnMB_FileExit, item)
+        filemenu.AppendItem(item)
+        aliasmenu = wx.Menu()
+        item = wx.MenuItem(aliasmenu, wx.ID_ANY, "New", "New")
+        self.Bind(wx.EVT_MENU, self.OnMB_AliasNew, item)
+        aliasmenu.AppendItem(item)
+        item = wx.MenuItem(aliasmenu, wx.ID_ANY, "Add Temporary", "Add Temporary")
+        self.Bind(wx.EVT_MENU, self.OnMB_AliasAddTemporary, item)
+        aliasmenu.AppendItem(item)
+        item = wx.MenuItem(aliasmenu, wx.ID_ANY, "Edit", "Edit")
+        self.Bind(wx.EVT_MENU, self.OnMB_AliasEdit, item)
+        aliasmenu.AppendItem(item)
+        item = wx.MenuItem(aliasmenu, wx.ID_ANY, "Delete", "Delete")
+        self.Bind(wx.EVT_MENU, self.OnMB_AliasDelete, item)
+        aliasmenu.AppendItem(item)
+        filtermenu = wx.Menu()
+        item = wx.MenuItem(filtermenu, wx.ID_ANY, "New", "New")
+        self.Bind(wx.EVT_MENU, self.OnMB_FilterNew, item)
+        filtermenu.AppendItem(item)
+        item = wx.MenuItem(filtermenu, wx.ID_ANY, "Edit", "Edit")
+        self.Bind(wx.EVT_MENU, self.OnMB_FilterEdit, item)
+        filtermenu.AppendItem(item)
+        item = wx.MenuItem(filtermenu, wx.ID_ANY, "Delete", "Delete")
+        self.Bind(wx.EVT_MENU, self.OnMB_FilterDelete, item)
+        filtermenu.AppendItem(item)
+        transmitmenu = wx.Menu()
+        item = wx.MenuItem(transmitmenu, wx.ID_ANY, "Send\tCtrl+Enter", "Send")
+        self.Bind(wx.EVT_MENU, self.OnMB_TransmitSend, item)
+        transmitmenu.AppendItem(item)
+        item = wx.MenuItem(transmitmenu, wx.ID_ANY, "Emote\tCtrl+E", "Emote")
+        self.Bind(wx.EVT_MENU, self.OnMB_TransmitEmote, item)
+        transmitmenu.AppendItem(item)
+        item = wx.MenuItem(transmitmenu, wx.ID_ANY, "Whisper\tCtrl+W", "Whisper")
+        self.Bind(wx.EVT_MENU, self.OnMB_TransmitWhisper, item)
+        transmitmenu.AppendItem(item)
+        item = wx.MenuItem(transmitmenu, wx.ID_ANY, "Macro\tCtrl+M", "Macro")
+        self.Bind(wx.EVT_MENU, self.OnMB_TransmitMacro, item)
+        transmitmenu.AppendItem(item)
+        menu = wx.MenuBar()
+        menu.Append(filemenu, "&File")
+        menu.Append(aliasmenu, "&Alias")
+        menu.Append(filtermenu, "&Filter")
+        menu.Append(transmitmenu, "&Transmit")
+        self.SetMenuBar(menu)
+        self.log.log("Exit AliasLib->buildMenu(self)", ORPG_DEBUG)
+
+    def OnMB_FileNew(self, event):
+        self.log.log("Enter AliasLib->OnMB_FileNew(self, event)", ORPG_DEBUG)
+        oldfilename = self.filename
+        dlg = wx.TextEntryDialog(self, "Please Name This Alias Lib", "New Alias Lib")
+        if dlg.ShowModal() == wx.ID_OK:
+            self.filename = dlg.GetValue() + '.alias'
+        dlg.Destroy()
+        if oldfilename != self.filename:
+            self.OnMB_FileSave(None, oldfilename)
+            self.aliasList = []
+            self.filterList = []
+            self.OnMB_FileSave(None)
+        self.settings.set_setting('aliasfile', self.filename[:-6])
+        self.log.log("Exit AliasLib->OnMB_FileNew(self, event)", ORPG_DEBUG)
+
+    def OnMB_FileOpen(self, event):
+        self.log.log("Enter AliasLib->OnMB_FileOpen(self, event)", ORPG_DEBUG)
+        oldfilename = self.filename
+        dlg = wx.FileDialog(self, "Select an Alias Lib to Open", self.dir_struct["user"], wildcard="*.alias", style=wx.HIDE_READONLY|wx.OPEN)
+        if dlg.ShowModal() == wx.ID_OK:
+            self.filename = dlg.GetFilename()
+        dlg.Destroy()
+        if oldfilename != self.filename:
+            self.OnMB_FileSave(None, oldfilename)
+            self.loadFile()
+        self.settings.set_setting('aliasfile', self.filename[:-6])
+        self.log.log("Exit AliasLib->OnMB_FileOpen(self, event)", ORPG_DEBUG)
+
+    def OnMB_FileSave(self, event, file=None):
+        self.log.log("Enter AliasLib->OnMB_FileSave(self, event)", ORPG_DEBUG)
+        idx = self.aliasIdx
+        if file == None:
+            file = self.filename
+        xml = "<aliaslib>\n"
+        for n in xrange(self.selectAliasWnd.GetItemCount()):
+            self.alias = n
+            xml += "\t<alias "
+            xml += 'name="' + self.MakeHTMLSafe(self.alias[0]) + '" '
+            xml += 'color="' + self.alias[1] + '" '
+            xml += "/>\n"
+        for n in xrange(1, len(self.filterList)):
+            xml += "\t<filter "
+            xml += 'name="' + self.filterList[n] + '">' + "\n"
+            for rule in self.regExList[n-1]:
+                xml += "\t\t<rule "
+                xml += 'match="' + self.MakeHTMLSafe(rule[0]) + '" '
+                xml += 'sub="' + self.MakeHTMLSafe(rule[1]) + '" '
+                xml += "/>\n"
+            xml += "\t</filter>\n"
+        xml += "</aliaslib>"
+        self.alias = idx
+        f = open(self.dir_struct["user"] + file, "w")
+        f.write(xml)
+        f.close()
+        self.log.log("Exit AliasLib->OnMB_FileSave(self, event)", ORPG_DEBUG)
+
+    def OnMB_FileExportToTree(self, event):
+        self.log.log("Enter AliasLib->OnMB_FileExportToTree(self, event)", ORPG_DEBUG)
+        #tree = open_rpg.get_component("tree")
+        xml = '<nodehandler class="voxchat_handler" icon="player" module="voxchat" name="' + self.filename[:-6] + '" use.filter="0" version="1.0">' + "\n"
+        idx = self.aliasIdx
+        for n in xrange(self.selectAliasWnd.GetItemCount()):
+            self.alias = n
+            xml += "\t<voxchat.alias "
+            xml += 'name="' + self.MakeHTMLSafe(self.alias[0]) + '" '
+            xml += 'color="' + self.alias[1] + '" '
+            xml += "/>\n"
+        self.alias = idx
+        for n in xrange(1, len(self.filterList)):
+            xml += "\t<voxchat.filter "
+            xml += 'name="' + self.filterList[n] + '">' + "\n"
+            for rule in self.regExList[n-1]:
+                xml += "\t\t<rule "
+                xml += 'match="' + self.MakeHTMLSafe(rule[0]) + '" '
+                xml += 'sub="' + self.MakeHTMLSafe(rule[1]) + '" '
+                xml += "/>\n"
+            xml += "\t</voxchat.filter>\n"
+        xml += "</nodehandler>"
+        self.gametree.insert_xml(xml)
+        self.log.log("Exit AliasLib->OnMB_FileExportToTree(self, event)", ORPG_DEBUG)
+
+    def OnMB_FileExit(self, event):
+        self.log.log("Enter AliasLib->OnMB_FileExit(self, event)", ORPG_DEBUG)
+        self.OnMB_FileSave(0)
+        self.Hide()
+        top_frame = open_rpg.get_component('frame')
+        top_frame.mainmenu.Check(top_frame.mainmenu.FindMenuItem("Windows", "Alias Lib"), False)
+        self.log.log("Exit AliasLib->OnMB_FileExit(self, event)", ORPG_DEBUG)
+
+    def OnMB_AliasNew(self, event):
+        self.log.log("Enter AliasLib->OnMB_AliasNew(self, event)", ORPG_DEBUG)
+        self.NewEditAliasDialog("New")
+        self.log.log("Exit AliasLib->OnMB_AliasNew(self, event)", ORPG_DEBUG)
+
+    def OnMB_AliasAddTemporary(self, event):
+        self.log.log("Enter AliasLib->OnMB_AliasAddTemporary(self, event)", ORPG_DEBUG)
+        minis = self.map.canvas.layers['miniatures'].miniatures
+        for min in minis:
+            name = min.label
+            if name not in self.aliasList:
+                i = self.selectAliasWnd.InsertStringItem(self.selectAliasWnd.GetItemCount(), name)
+                self.selectAliasWnd.SetStringItem(i, 1, "Default")
+                self.selectAliasWnd.RefreshItem(i)
+        self.RefreshAliases()
+        self.log.log("Exit AliasLib->OnMB_AliasAddTemporary(self, event)", ORPG_DEBUG)
+
+    def OnMB_AliasEdit(self, event):
+        self.log.log("Enter AliasLib->OnMB_AliasEdit(self, event)", ORPG_DEBUG)
+        if self.aliasIdx != -1:
+            self.NewEditAliasDialog("Edit")
+        self.log.log("Exit AliasLib->OnMB_AliasEdit(self, event)", ORPG_DEBUG)
+
+    def NewEditAliasDialog(self, type):
+        self.log.log("Enter AliasLib->NewEditAliasDialog(self, type)", ORPG_DEBUG)
+        dlg = wx.Dialog(self, wx.ID_ANY, type + " Alias", style=wx.DEFAULT_DIALOG_STYLE|wx.STAY_ON_TOP)
+        txt = wx.TextCtrl(dlg, wx.ID_ANY)
+        if type == 'Edit':
+            txt.SetValue(self.alias[0])
+        self.colorbtn = wx.Button(dlg, wx.ID_ANY, "Default Color")
+        dlg.Bind(wx.EVT_BUTTON, self.ChangeAliasColor, self.colorbtn)
+        if self.alias[1] != 'Default':
+            self.colorbtn.SetLabel("Chat Color")
+            self.colorbtn.SetForegroundColour(self.alias[1])
+        okbtn = wx.Button(dlg, wx.ID_OK)
+        sizer = wx.BoxSizer(wx.HORIZONTAL)
+        sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Alias: "), 0, wx.EXPAND)
+        sizer.Add(txt, 1, wx.EXPAND)
+        sizer.Add(self.colorbtn, 0, wx.EXPAND)
+        sizer.Add(okbtn, 0, wx.EXPAND)
+        dlg.SetSizer(sizer)
+        dlg.SetAutoLayout(True)
+        dlg.Fit()
+        if dlg.ShowModal() == wx.ID_OK:
+            (r, g, b) = self.colorbtn.GetForegroundColour().Get()
+            if type == 'Edit':
+                self.selectAliasWnd.SetStringItem(self.aliasIdx, 0, txt.GetValue())
+                if self.colorbtn.GetLabel() != 'Default Color':
+                    self.aliasColor = RGBHex().hexstring(r, g, b)
+                self.selectAliasWnd.RefreshItem(self.aliasIdx)
+            else:
+                i = self.selectAliasWnd.InsertStringItem(self.selectAliasWnd.GetItemCount(), txt.GetValue())
+                if self.colorbtn.GetLabel() == 'Default Color':
+                    self.selectAliasWnd.SetStringItem(i, 1, "Default")
+                else:
+                    self.selectAliasWnd.SetStringItem(i, 1, RGBHex().hexstring(r, g, b))
+                    self.selectAliasWnd.SetItemTextColour(i, RGBHex().hexstring(r, g, b))
+                self.selectAliasWnd.RefreshItem(i)
+            self.RefreshAliases()
+        self.log.log("Exit AliasLib->NewEditAliasDialog(self, type)", ORPG_DEBUG)
+
+    def ChangeAliasColor(self, event):
+        self.log.log("Enter AliasLib->ChangeAliasColor(self, event)", ORPG_DEBUG)
+        color = RGBHex().do_hex_color_dlg(self)
+        self.colorbtn.SetLabel("Chat Color")
+        self.colorbtn.SetForegroundColour(color)
+        self.log.log("Exit AliasLib->ChangeAliasColor(self, event)", ORPG_DEBUG)
+
+    def OnMB_AliasDelete(self, event):
+        self.log.log("Enter AliasLib->OnMB_AliasDelete(self, event)", ORPG_DEBUG)
+        if self.aliasIdx != -1:
+            self.selectAliasWnd.DeleteItem(self.aliasIdx)
+        self.RefreshAliases()
+        self.log.log("Exit AliasLib->OnMB_AliasDelete(self, event)", ORPG_DEBUG)
+
+    def OnMB_FilterNew(self, event):
+        self.log.log("Enter AliasLib->OnMB_FilterNew(self, event)", ORPG_DEBUG)
+        dlg = wx.TextEntryDialog(self, 'Filter Name: ', 'Please name this filter')
+        if dlg.ShowModal() != wx.ID_OK:
+            dlg.Destroy()
+            return
+        filterName = dlg.GetValue()
+        i = self.selectFilterWnd.InsertStringItem(self.selectFilterWnd.GetItemCount(), filterName)
+        self.filter = i
+        self.regExList.append([])
+        self.OnMB_FilterEdit(None)
+        self.log.log("Exit AliasLib->OnMB_FilterNew(self, event)", ORPG_DEBUG)
+
+    def OnMB_FilterEdit(self, event):
+        self.log.log("Enter AliasLib->OnMB_FilterEdit(self, event)", ORPG_DEBUG)
+        wnd = FilterEditWnd(self, self.filter, self.filterRegEx)
+        wnd.MakeModal(True)
+        wnd.Show()
+        self.log.log("Exit AliasLib->OnMB_FilterEdit(self, event)", ORPG_DEBUG)
+
+    def OnMB_FilterDelete(self, event):
+        self.log.log("Enter AliasLib->OnMB_FilterDelete(self, event)", ORPG_DEBUG)
+        if self.filterIdx != -1:
+            self.selectFilterWnd.DeleteItem(self.filterIdx)
+        self.log.log("Exit AliasLib->OnMB_FilterDelete(self, event)", ORPG_DEBUG)
+
+    def OnMB_TransmitSend(self, event):
+        self.log.log("Enter AliasLib->OnMB_TransmitSend(self, event)", ORPG_DEBUG)
+        self.orpgframe.Freeze()
+        if self.alias[1] != 'Default':
+            defaultcolor = self.settings.get_setting("mytextcolor")
+            self.settings.set_setting("mytextcolor", self.alias[1])
+            self.chat.set_colors()
+        line = self.textWnd.GetValue().replace("\n", "<br />")
+        if self.checkFilterText.IsChecked() and self.filter != self.chat.defaultFilterName:
+            for rule in self.filterRegEx:
+                line = re.sub(rule[0], rule[1], line)
+        if len(line) > 1:
+            if len(line) > 1 and line[0] != "/":
+                self.chat.ParsePost(line, True, True)
+            else:
+                self.chat.chat_cmds.docmd(line)
+        if self.alias[1] != 'Default':
+            self.settings.set_setting("mytextcolor", defaultcolor)
+            self.chat.set_colors()
+        if self.checkClearText.IsChecked():
+            self.textWnd.SetValue("")
+        top_frame.Thaw()
+        self.log.log("Exit AliasLib->OnMB_TransmitSend(self, event)", ORPG_DEBUG)
+
+    def OnMB_TransmitEmote(self, event):
+        self.log.log("Enter AliasLib->OnMB_TransmitEmote(self, event)", ORPG_DEBUG)
+        self.orpgframe.Freeze()
+        line = self.textWnd.GetValue().replace("\n", "<br />")
+        if self.checkFilterText.IsChecked() and self.filter != self.chat.defaultFilterName:
+            for rule in self.filterRegEx:
+                line = re.sub(rule[0], rule[1], line)
+        self.chat.emote_message(line)
+        if self.checkClearText.IsChecked():
+            self.textWnd.SetValue("")
+        top_frame.Thaw()
+        self.log.log("Exit AliasLib->OnMB_TransmitEmote(self, event)", ORPG_DEBUG)
+
+    def OnMB_TransmitWhisper(self, event):
+        self.log.log("Enter AliasLib->OnMB_TransmitWhisper(self, event)", ORPG_DEBUG)
+        self.orpgframe.Freeze()
+        players = self.session.get_players()
+        if self.alias[1] != 'Default':
+            defaultcolor = self.settings.get_setting("mytextcolor")
+            self.settings.set_setting("mytextcolor", self.alias[1])
+            self.chat.set_colors()
+        opts = []
+        myid = session.get_id()
+        for p in players:
+            if p[2] != myid:
+                opts.append("(" + p[2] + ") " + self.chat.html_strip(p[0]))
+        dlg = orpgMultiCheckBoxDlg(self, opts, "Select Players:", "Whisper To", [])
+        sendto = []
+        if dlg.ShowModal() == wx.ID_OK:
+            selections = dlg.get_selections()
+            for s in selections:
+                sendto.append(players[s][2])
+        line = self.textWnd.GetValue().replace("\n", "<br />")
+        if self.checkFilterText.IsChecked() and self.filter != self.chat.defaultFilterName:
+            for rule in self.filterRegEx:
+                line = re.sub(rule[0], rule[1], line)
+        if len(sendto):
+            self.chat.whisper_to_players(line, sendto)
+        if self.alias[1] != 'Default':
+            self.settings.set_setting("mytextcolor", defaultcolor)
+            self.chat.set_colors()
+        if self.checkClearText.IsChecked():
+            self.textWnd.SetValue("")
+        top_frame.Thaw()
+        self.log.log("Exit AliasLib->OnMB_TransmitWhisper(self, event)", ORPG_DEBUG)
+
+    def OnMB_TransmitMacro(self, event):
+        self.log.log("Enter AliasLib->OnMB_TransmitMacro(self, event)", ORPG_DEBUG)
+        self.orpgframe.Freeze()
+        if self.alias[1] != 'Default':
+            defaultcolor = self.settings.get_setting("mytextcolor")
+            self.settings.set_setting("mytextcolor", self.alias[1])
+            self.chat.set_colors()
+        lines = self.textWnd.GetValue().split("\n")
+        if self.checkFilterText.IsChecked() and self.filter != self.chat.defaultFilterName:
+            for rule in self.filterRegEx:
+                line = re.sub(rule[0], rule[1], line)
+        for line in lines:
+            if len(line) > 1:
+                if line[0] != "/":
+                    self.chat.ParsePost(line, True, True)
+                else:
+                    self.chat.chat_cmds.docmd(line)
+        if self.alias[1] != 'Default':
+            self.settings.set_setting("mytextcolor", defaultcolor)
+            self.chat.set_colors()
+        if self.checkClearText.IsChecked():
+            self.textWnd.SetValue("")
+        top_frame.Thaw()
+        self.log.log("Exit AliasLib->OnMB_TransmitMacro(self, event)", ORPG_DEBUG)
+
+    def buildButtons(self):
+        self.log.log("Enter AliasLib->buildButtons(self)", ORPG_DEBUG)
+        self.topBtnSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.middleBtnSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.bottomBtnSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.addFromMapBtn = createMaskedButton(self, self.dir_struct["icon"] + 'install.gif', 'Add temporary aliases from map', wx.ID_ANY, "#C0C0C0")
+        self.newAliasBtn = createMaskedButton(self, self.dir_struct["icon"] + 'player.gif', 'Add a new Alias', wx.ID_ANY)
+        self.delAliasBtn = createMaskedButton(self, self.dir_struct["icon"] + 'noplayer.gif', 'Delete selected Alias', wx.ID_ANY)
+        self.editAliasBtn = createMaskedButton(self, self.dir_struct["icon"] + 'note.gif', 'Edit selected Alias', wx.ID_ANY)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_AliasNew, self.newAliasBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_AliasAddTemporary, self.addFromMapBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_AliasEdit, self.editAliasBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_AliasDelete, self.delAliasBtn)
+        self.newFilterBtn = createMaskedButton(self, self.dir_struct["icon"] + 'add_filter.gif', 'Add a new Filter', wx.ID_ANY, "#0000FF")
+        self.editFilterBtn = createMaskedButton(self, self.dir_struct["icon"] + 'edit_filter.gif', 'Edit selected Filter', wx.ID_ANY, "#FF0000")
+        self.delFilterBtn = createMaskedButton(self, self.dir_struct["icon"] + 'delete_filter.gif', 'Delete selected Filter', wx.ID_ANY, "#0000FF")
+        self.Bind(wx.EVT_BUTTON, self.OnMB_FilterNew, self.newFilterBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_FilterEdit, self.editFilterBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_FilterDelete, self.delFilterBtn)
+        self.textBoldBtn = createMaskedButton(self, self.dir_struct["icon"] + 'bold.gif', 'Bold', wx.ID_ANY, "#BDBDBD")
+        self.textItalicBtn = createMaskedButton(self, self.dir_struct["icon"] + 'italic.gif', 'Italic', wx.ID_ANY, "#BDBDBD")
+        self.textUnderlineBtn = createMaskedButton(self, self.dir_struct["icon"] + 'underlined.gif', 'Underline', wx.ID_ANY, "#BDBDBD")
+        self.textColorBtn = wx.Button(self, wx.ID_ANY, "Color")
+        self.textColorBtn.SetForegroundColour(wx.BLACK)
+        self.exportBtn = createMaskedButton(self, self.dir_struct["icon"] + 'grid.gif', 'Export to Tree', wx.ID_ANY)
+        self.Bind(wx.EVT_BUTTON, self.FormatText, self.textBoldBtn)
+        self.Bind(wx.EVT_BUTTON, self.FormatText, self.textItalicBtn)
+        self.Bind(wx.EVT_BUTTON, self.FormatText, self.textUnderlineBtn)
+        self.Bind(wx.EVT_BUTTON, self.FormatText, self.textColorBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_FileExportToTree, self.exportBtn)
+        self.topBtnSizer.Add(self.newAliasBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.addFromMapBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.editAliasBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.delAliasBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.newFilterBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.editFilterBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.delFilterBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.textBoldBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.textItalicBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.textUnderlineBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.textColorBtn, 0, wx.EXPAND)
+        self.topBtnSizer.Add(self.exportBtn, 0, wx.EXPAND|wx.ALIGN_RIGHT)
+        self.checkFilterText = wx.CheckBox(self, wx.ID_ANY, "Filter Text")
+        self.Bind(wx.EVT_CHECKBOX, self.FilterTextChecked, self.checkFilterText)
+        self.checkClearText = wx.CheckBox(self, wx.ID_ANY, "Auto Clear Text")
+        self.middleBtnSizer.Add(self.checkFilterText, 0, wx.EXPAND)
+        self.middleBtnSizer.Add(self.checkClearText, 0, wx.EXPAND)
+        self.sayBtn = wx.Button(self, wx.ID_ANY, "Say")
+        self.emoteBtn = wx.Button(self, wx.ID_ANY, "Emote")
+        self.whisperBtn = wx.Button(self, wx.ID_ANY, "Whisper")
+        self.macroBtn = wx.Button(self, wx.ID_ANY, "Macro")
+        self.doneBtn = wx.Button(self, wx.ID_ANY, "Done")
+        self.Bind(wx.EVT_BUTTON, self.OnMB_TransmitSend, self.sayBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_TransmitEmote, self.emoteBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_TransmitWhisper, self.whisperBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_TransmitMacro, self.macroBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnMB_FileExit, self.doneBtn)
+        self.bottomBtnSizer.Add(self.sayBtn, 0, wx.EXPAND)
+        self.bottomBtnSizer.Add(self.emoteBtn, 0, wx.EXPAND)
+        self.bottomBtnSizer.Add(self.whisperBtn, 0, wx.EXPAND)
+        self.bottomBtnSizer.Add(self.macroBtn, 0, wx.EXPAND)
+        self.bottomBtnSizer.Add(self.doneBtn, 0, wx.EXPAND|wx.ALIGN_RIGHT)
+        self.log.log("Exit AliasLib->buildButtons(self)", ORPG_DEBUG)
+
+    def buildGUI(self):
+        self.log.log("Enter AliasLib->buildGUI(self)", ORPG_DEBUG)
+        self.sizer = wx.BoxSizer(wx.VERTICAL)
+        rightwnd = wx.SplitterWindow(self, wx.ID_ANY, style=wx.SP_LIVE_UPDATE|wx.SP_NO_XP_THEME|wx.SP_3DSASH)
+        leftwnd = wx.SplitterWindow(rightwnd, wx.ID_ANY, style=wx.SP_LIVE_UPDATE|wx.SP_NO_XP_THEME|wx.SP_3DSASH)
+        self.selectAliasWnd = wx.ListCtrl(leftwnd, wx.ID_ANY, style=wx.LC_SINGLE_SEL|wx.LC_REPORT|wx.LC_HRULES)
+        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.NewAliasSelection, self.selectAliasWnd)
+        self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.NoAliasSelection, self.selectAliasWnd)
+        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnMB_AliasEdit, self.selectAliasWnd)
+        self.selectFilterWnd = wx.ListCtrl(leftwnd, wx.ID_ANY, style=wx.LC_SINGLE_SEL|wx.LC_REPORT|wx.LC_HRULES)
+        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.NewFilterSelection, self.selectFilterWnd)
+        self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.NoFilterSelection, self.selectFilterWnd)
+        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnMB_FilterEdit, self.selectFilterWnd)
+        self.textWnd = wx.TextCtrl(rightwnd, wx.ID_ANY, style=wx.TE_MULTILINE|wx.TE_BESTWRAP)
+        leftwnd.SplitHorizontally(self.selectAliasWnd, self.selectFilterWnd)
+        rightwnd.SplitVertically(leftwnd, self.textWnd)
+        self.sizer.Add(self.topBtnSizer, 0, wx.EXPAND)
+        self.sizer.Add(rightwnd, 1, wx.EXPAND)
+        self.sizer.Add(self.middleBtnSizer, 0, wx.EXPAND)
+        self.sizer.Add(self.bottomBtnSizer, 0, wx.EXPAND)
+        self.SetSizer(self.sizer)
+        self.SetAutoLayout(True)
+        self.Fit()
+        self.log.log("Exit AliasLib->buildGUI(self)", ORPG_DEBUG)
+
+    def loadFile(self):
+        self.log.log("Enter AliasLib->loadFile(self)", ORPG_DEBUG)
+        f = open(self.dir_struct["user"] + self.filename, "r")
+        data = f.read()
+        f.close()
+        self.alias = -1
+        self.filter = -1
+        xml_dom = self.xml.parseXml(data)
+        del data
+        aliases = xml_dom.getElementsByTagName("alias")
+        alist = []
+        for alias in aliases:
+            if alias.hasAttribute("color"):
+                color = alias.getAttribute("color")
+            else:
+                color = 'Default'
+            aname = self.MakeSafeHTML(alias.getAttribute("name"))
+            alist.append([aname, color])
+        alist.sort()
+        self.aliasList = alist
+        filters = xml_dom.getElementsByTagName("filter")
+        flist = []
+        self.regExList = []
+        for filter in filters:
+            flist.append(filter.getAttribute("name"))
+            rules = filter.getElementsByTagName("rule")
+            sub = []
+            for rule in rules:
+                sub.append([self.MakeSafeHTML(rule.getAttribute("match")), self.MakeSafeHTML(rule.getAttribute("sub"))])
+            self.regExList.append(sub)
+        self.filterList = flist
+        xml_dom.unlink()
+        self.alias = -1
+        self.filter = -1
+        self.log.log("Exit AliasLib->loadFile(self)", ORPG_DEBUG)
+
+    def MakeSafeHTML(self, str):
+        return str.replace("&amp;", "&").replace("&lt;", "<").replace("&quot;", '"').replace("&gt;", ">").replace("&#39;", "'")
+    def MakeHTMLSafe(self, str):
+        return str.replace("&", "&amp;").replace("<", "&lt;").replace('"', "&quot;").replace(">", "&gt;").replace("'", "&#39;")
+    def ImportFromTree(self, xml_dom):
+        self.log.log("Enter AliasLib->ImportFromTree(self, xml_dom)", ORPG_DEBUG)
+        oldfilename = self.filename
+        if xml_dom.getAttribute('name') == 'Alias Library':
+            dlg = wx.TextEntryDialog(self, "Please Name This Alias Lib", "New Alias Lib")
+            if dlg.ShowModal() == wx.ID_OK:
+                self.filename = dlg.GetValue() + '.alias'
+                dlg.Destroy()
+            else:
+                dlg.Destroy()
+                return
+        else:
+            self.filename = xml_dom.getAttribute('name') + '.alias'
+        self.settings.set_setting('aliasfile', self.filename[:-6])
+        if oldfilename != self.filename:
+            self.OnMB_FileSave(None, oldfilename)
+        f = open(self.dir_struct["user"] + self.filename, "w")
+        f.write(xml_dom.toxml().replace('nodehandler', 'aliaslib').replace('voxchat.', ''))
+        f.close()
+        wx.CallAfter(self.loadFile)
+        self.log.log("Exit AliasLib->ImportFromTree(self, xml_dom)", ORPG_DEBUG)
+
+    def NewAliasSelection(self, event):
+        self.log.log("Enter AliasLib->NewAliasSelection(self, event)", ORPG_DEBUG)
+        self.alias = event.GetIndex()
+        wx.CallAfter(self.chat.aliasList.SetStringSelection, self.alias[0])
+        self.log.log("Exit AliasLib->NewAliasSelection(self, event)", ORPG_DEBUG)
+
+    def NoAliasSelection(self, event):
+        self.log.log("Enter AliasLib->NoAliasSelection(self, event)", ORPG_DEBUG)
+        self.aliasIdx = -1
+        wx.CallAfter(self.chat.aliasList.SetStringSelection, self.alias[0])
+        self.log.log("Exit AliasLib->NoAliasSelection(self, event)", ORPG_DEBUG)
+
+    def GetSelectedAlias(self):
+        self.log.log("Enter AliasLib->GetSelectedAlias(self)", ORPG_DEBUG)
+        self.InitSetup()
+        if self.aliasIdx != -1:
+            self.log.log("Exit AliasLib->GetSelectedAlias(self) return " + str(self.aliasIdx), ORPG_DEBUG)
+            return [self.selectAliasWnd.GetItem(self.aliasIdx, 0).GetText(), self.selectAliasWnd.GetItem(self.aliasIdx, 1).GetText()]
+        self.log.log("Exit AliasLib->GetSelectedAlias(self) return " + str(self.aliasIdx), ORPG_DEBUG)
+        return [self.chat.defaultAliasName, "Default"]
+
+    def SetSelectedAlias(self, alias):
+        self.log.log("Enter AliasLib->SetSelectedAlias(self, aliasIdx)", ORPG_DEBUG)
+        found = False
+        if isinstance(alias, (int, long)):
+            self.aliasIdx = alias
+            found = True
+        else:
+            for n in xrange(self.selectAliasWnd.GetItemCount()):
+                if self.selectAliasWnd.GetItem(n, 0).GetText() == alias:
+                    self.aliasIdx = n
+                    found = True
+        if not found:
+            self.aliasIdx = -1
+        self.log.log("Exit AliasLib->SetSelectedAlias(self, aliasIdx)", ORPG_DEBUG)
+
+    def GetAliasList(self):
+        self.log.log("Enter AliasLib->GetAliasList(self)", ORPG_DEBUG)
+        alist = []
+        for n in xrange(0, self.selectAliasWnd.GetItemCount()):
+            self.alias = n
+            alist.append(self.alias[0])
+        self.log.log("Exit AliasLib->GetAliasList(self)", ORPG_DEBUG)
+        alist.sort()
+        alist.insert(0, self.chat.defaultAliasName)
+        return alist
+
+    def SetAliasList(self, alist):
+        self.log.log("Enter AliasLib->SetAliasList(self, list)", ORPG_DEBUG)
+        self.selectAliasWnd.ClearAll()
+        self.selectAliasWnd.InsertColumn(0, "Alias")
+        self.selectAliasWnd.InsertColumn(1, "Chat Color")
+        for item in alist:
+            i = self.selectAliasWnd.InsertStringItem(self.selectAliasWnd.GetItemCount(), item[0])
+            self.selectAliasWnd.SetStringItem(i, 1, item[1])
+            if item[1] != 'Default':
+                self.selectAliasWnd.SetItemTextColour(i, item[1])
+            self.selectAliasWnd.RefreshItem(i)
+        self.aliasIdx = -1
+        self.RefreshAliases()
+        self.log.log("Exit AliasLib->SetAliasList(self, list)", ORPG_DEBUG)
+
+    def GetAliasColor(self):
+        self.log.log("Enter/Exit AliasLib->GetAliasColor(self) return " + self.alias[1], ORPG_DEBUG)
+        return self.alias[1]
+
+    def RefreshAliases(self):
+        self.orpgframe.Freeze()
+        self.Freeze()
+        self.alias = -1
+        l1 = len(self.aliasList)
+        l2 = len(self.filterList)
+        if self.chat != None:
+            tmp = self.chat.aliasList.GetStringSelection()
+            self.alias = tmp
+            aidx = self.aliasIdx+1
+            if len(self.aliasList) <= aidx:
+                aidx = 0
+            self.chat.aliasList.Clear()
+            for n in xrange(l1):
+                self.chat.aliasList.Insert(self.aliasList[n], n)
+            self.chat.aliasList.SetStringSelection(self.aliasList[aidx])
+            fidx = self.chat.filterList.GetSelection()
+            if len(self.filterList) <= fidx:
+                fidx = 0
+            self.chat.filterList.Clear()
+            for n in xrange(l2):
+                self.chat.filterList.Insert(self.filterList[n], n)
+            self.chat.filterList.SetStringSelection(self.filterList[fidx])
+            if self.chat.parent.GMChatPanel != None:
+                aidx = self.chat.parent.GMChatPanel.aliasList.GetSelection()
+                if len(self.aliasList) <- aidx:
+                    aidx = 0
+                self.chat.parent.GMChatPanel.aliasList.Clear()
+                for n in xrange(l1):
+                    self.chat.parent.GMChatPanel.aliasList.Insert(self.aliasList[n], n)
+                self.chat.parent.GMChatPanel.aliasList.SetStringSelection(self.aliasList[aidx])
+                fidx = self.chat.parent.GMChatPanel.filterList.GetSelection()
+                self.chat.parent.GMChatPanel.filterList.Clear()
+                for n in xrange(l2):
+                    self.chat.parent.GMChatPanel.filterList.Insert(self.filterList[n], n)
+                self.chat.parent.GMChatPanel.filterList.SetStringSelection(self.filterList[fidx])
+            for tab in self.chat.parent.whisper_tabs:
+                aidx = tab.aliasList.GetSelection()
+                if len(self.aliasList) <= aidx:
+                    aidx = 0
+                tab.aliasList.Clear()
+                for n in xrange(l1):
+                    tab.aliasList.Insert(self.aliasList[n], n)
+                tab.aliasList.SetStringSelection(self.aliasList[aidx])
+                fidx = tab.filterList.GetSelection()
+                tab.filterList.Clear()
+                for n in xrange(l2):
+                    tab.filterList.Insert(self.filterList[n], n)
+                tab.filterList.SetStringSelection(self.filterList[fidx])
+
+            for tab in self.chat.parent.group_tabs:
+                aidx = tab.aliasList.GetSelection()
+                if len(self.aliasList) <= aidx:
+                    aidx = 0
+                tab.aliasList.Clear()
+                for n in xrange(l1):
+                    tab.aliasList.Insert(self.aliasList[n], n)
+                tab.aliasList.SetStringSelection(self.aliasList[aidx])
+                fidx = tab.filterList.GetSelection()
+                tab.filterList.Clear()
+                for n in xrange(l2):
+                    tab.filterList.Insert(self.filterList[n], n)
+                tab.filterList.SetStringSelection(self.filterList[fidx])
+
+            for tab in self.chat.parent.null_tabs:
+                aidx = tab.aliasList.GetSelection()
+                if len(self.aliasList) <= aidx:
+                    aidx = 0
+                tab.aliasList.Clear()
+                for n in xrange(l1):
+                    tab.aliasList.Insert(self.aliasList[n], n)
+                tab.aliasList.SetStringSelection(self.aliasList[aidx])
+                fidx = tab.filterList.GetSelection()
+                tab.filterList.Clear()
+                for n in xrange(l2):
+                    tab.filterList.Insert(self.filterList[n], n)
+                tab.filterList.SetStringSelection(self.filterList[fidx])
+        self.Thaw()
+        wx.CallAfter(self.orpgframe.Thaw)
+
+    def SetAliasColor(self, color):
+        self.log.log("Enter AliasLib->SetAliasColor(self, color)", ORPG_DEBUG)
+        if self.aliasIdx != -1:
+            self.selectAliasWnd.SetStringItem(self.aliasIdx, 1, color)
+            self.selectAliasWnd.SetItemTextColour(self.aliasIdx, color)
+        self.log.log("Exit AliasLib->SetAliasColor(self, color)", ORPG_DEBUG)
+
+    def FilterTextChecked(self, event):
+        if self.checkFilterText.IsChecked():
+            self.chat.filterList.SetStringSelection(self.filter)
+        else:
+            self.chat.filterList.SetStringSelection(self.chat.defaultFilterName)
+
+    def NewFilterSelection(self, event):
+        self.log.log("Enter AliasLib->NewFilterSelection(self, event)", ORPG_DEBUG)
+        self.filter = event.GetIndex()
+        if self.checkFilterText.IsChecked():
+            wx.CallAfter(self.chat.filterList.SetStringSelection, self.filter)
+        self.log.log("Exit AliasLib->NewFilterSelection(self, event)", ORPG_DEBUG)
+
+    def NoFilterSelection(self, event):
+        self.log.log("Enter AliasLib->NoFilterSelection(self, event)", ORPG_DEBUG)
+        self.filter = -1
+        wx.CallAfter(self.chat.filterList.SetStringSelection, self.filter)
+        self.log.log("Exit AliasLib->NoFilterSelection(self, event)", ORPG_DEBUG)
+
+    def GetSelectedFilter(self):
+        self.log.log("Enter AliasLib->GetSelectedFilter(self)", ORPG_DEBUG)
+        if self.filterIdx != -1:
+            self.log.log("Exit AliasLib->GetSelectedFilter(self) return " + str(self.filterIdx), ORPG_DEBUG)
+            return self.selectFilterWnd.GetItem(self.filterIdx, 0).GetText()
+        self.log.log("Exit AliasLib->GetSelectedFilter(self) return " + str(self.filterIdx), ORPG_DEBUG)
+        return self.chat.defaultFilterName
+
+    def SetSelectedFilter(self, idx):
+        self.log.log("Enter AliasLib->SetSelectedFilter(self, filter)", ORPG_DEBUG)
+        self.filterIdx = idx
+        self.log.log("Exit AliasLib->SetSelectedFilter(self, filter)", ORPG_DEBUG)
+
+    def GetFilterList(self):
+        self.log.log("Enter AliasLib->GetFilterList(self)", ORPG_DEBUG)
+        list = []
+        for n in xrange(-1, self.selectFilterWnd.GetItemCount()):
+            self.filter = n
+            list.append(self.filter)
+        self.log.log("Exit AliasLib->GetFilterList(self)", ORPG_DEBUG)
+        return list
+
+    def SetFilterList(self, list):
+        self.log.log("Enter AliasLib->SetFilterList(self, list)", ORPG_DEBUG)
+        self.selectFilterWnd.ClearAll()
+        self.selectFilterWnd.InsertColumn(0, "Filter Name")
+        for item in list:
+            i = self.selectFilterWnd.InsertStringItem(self.selectFilterWnd.GetItemCount(), item)
+            self.selectFilterWnd.RefreshItem(i)
+        self.selectFilterWnd.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+        self.filter = -1
+        self.RefreshAliases()
+        self.log.log("Exit AliasLib->SetFilterList(self, list)", ORPG_DEBUG)
+
+    def GetFilterRegEx(self):
+        if self.filterIdx == -1:
+            return []
+        return self.regExList[self.filterIdx]
+
+    def SetFilterRegEx(self, list):
+        self.regExList[self.filterIdx] = list
+
+    def FormatText(self, event):
+        #self.textColorBtn = wx.Button(self, wx.ID_ANY, "Color")
+        #self.textColorBtn.SetForegroundColour(wx.BLACK)
+        id = event.GetId()
+        txt = self.textWnd.GetValue()
+        (beg, end) = self.textWnd.GetSelection()
+        if beg != end:
+            sel_txt = txt[beg:end]
+        else:
+            sel_txt = txt
+        if id == self.textBoldBtn.GetId():
+            sel_txt = "<b>" + sel_txt + "</b>"
+        elif id == self.textItalicBtn.GetId():
+            sel_txt = "<i>" + sel_txt + "</i>"
+        elif id == self.textUnderlineBtn.GetId():
+            sel_txt = "<u>" + sel_txt + "</u>"
+        elif id == self.textColorBtn.GetId():
+            dlg = wx.ColourDialog(self)
+            if not dlg.ShowModal() == wx.ID_OK:
+                dlg.Destroy()
+                return
+            color = dlg.GetColourData().GetColour()
+            color = RGBHex().hexstring(color[0], color[1], color[2])
+            dlg.Destroy()
+            sel_txt = '<font color="' + color + '">' + sel_txt + '</font>'
+        if beg != end:
+            txt = txt[:beg] + sel_txt + txt[end:]
+        else:
+            txt = sel_txt
+        self.textWnd.SetValue(txt)
+        self.textWnd.SetInsertionPointEnd()
+        self.textWnd.SetFocus()
+
+    #Properties
+    alias = property(GetSelectedAlias, SetSelectedAlias)
+    aliasList = property(GetAliasList, SetAliasList)
+    aliasColor = property(GetAliasColor, SetAliasColor)
+
+    filter = property(GetSelectedFilter, SetSelectedFilter)
+    filterList = property(GetFilterList, SetFilterList)
+    filterRegEx = property(GetFilterRegEx, SetFilterRegEx)
+
+
+
+class FilterEditWnd(wx.Frame):
+    def __init__(self, parent, filterName, filterList):
+        wx.Frame.__init__(self, parent, wx.ID_ANY, "Edit Filter: " + filterName)
+
+        self.filterList = filterList
+        self.parent = parent
+
+        self.Freeze()
+        self.buildGUI()
+        self.fillList()
+        self.Layout()
+        self.grid.Select(0)
+        self.Thaw()
+
+        self.Bind(wx.EVT_CLOSE, self.OnExit)
+
+    def buildGUI(self):
+        bsizer = wx.BoxSizer(wx.VERTICAL)
+        self.panel = wx.Panel(self, wx.ID_ANY)
+        bsizer.Add(self.panel, 1, wx.EXPAND)
+        self.SetSizer(bsizer)
+        self.SetAutoLayout(True)
+
+        self.grid = wx.ListCtrl(self.panel, wx.ID_ANY, style=wx.LC_SINGLE_SEL|wx.LC_REPORT|wx.LC_HRULES)
+        self.grid.InsertColumn(0, "Replace")
+        self.grid.InsertColumn(1, "With")
+        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.selectRule, self.grid)
+        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.RuleEdit, self.grid)
+
+        self.addBtn = wx.Button(self.panel, wx.ID_ANY, 'Add')
+        self.editBtn = wx.Button(self.panel, wx.ID_ANY, 'Edit')
+        self.deleteBtn = wx.Button(self.panel, wx.ID_ANY, 'Delete')
+        self.okBtn = wx.Button(self.panel, wx.ID_OK, 'Done')
+
+        self.Bind(wx.EVT_BUTTON, self.RuleAdd, self.addBtn)
+        self.Bind(wx.EVT_BUTTON, self.RuleEdit, self.editBtn)
+        self.Bind(wx.EVT_BUTTON, self.RuleDelete, self.deleteBtn)
+        self.Bind(wx.EVT_BUTTON, self.OnDone, self.okBtn)
+
+        btsizer = wx.BoxSizer(wx.VERTICAL)
+        btsizer.Add(self.addBtn, 0, wx.EXPAND)
+        btsizer.Add(self.editBtn, 0, wx.EXPAND)
+        btsizer.Add(self.deleteBtn, 0, wx.EXPAND)
+        btsizer.Add(self.okBtn, 0, wx.EXPAND)
+
+        sizer = wx.GridBagSizer(5,5)
+
+        sizer.Add(self.grid, (0,0), flag=wx.EXPAND)
+        sizer.Add(btsizer, (0,1), flag=wx.EXPAND)
+
+        sizer.AddGrowableCol(0)
+        sizer.AddGrowableRow(0)
+        sizer.SetEmptyCellSize((0,0))
+
+        self.panel.SetSizer(sizer)
+        self.panel.SetAutoLayout(True)
+
+    def fillList(self):
+        for rule in self.filterList:
+            i = self.grid.InsertStringItem(self.grid.GetItemCount(), rule[0])
+            self.grid.SetStringItem(i, 1, rule[1])
+
+        self.grid.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+        self.grid.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+
+    def selectRule(self, event):
+        self.currentIdx = event.GetIndex()
+        self.Freeze()
+        for i in xrange(0, self.grid.GetItemCount()):
+            self.grid.SetItemBackgroundColour(i, (255,255,255))
+
+        self.grid.SetItemBackgroundColour(self.currentIdx, (0,255,0))
+        self.grid.SetItemState(self.currentIdx, 0, wx.LIST_STATE_SELECTED)
+        self.grid.EnsureVisible(self.currentIdx)
+        self.Thaw()
+
+    def RuleEdit(self, event):
+        dlg = wx.Dialog(self, wx.ID_ANY, 'Edit Filter Rule')
+        sizer = wx.BoxSizer(wx.HORIZONTAL)
+        sizer.Add(wx.StaticText(dlg, wx.ID_ANY, 'Replace: '), 0, wx.EXPAND)
+        rpltxt = wx.TextCtrl(dlg, wx.ID_ANY)
+        sizer.Add(rpltxt, 0, wx.EXPAND)
+        sizer.Add(wx.StaticText(dlg, wx.ID_ANY, 'With: '), 0, wx.EXPAND)
+        withtxt = wx.TextCtrl(dlg, wx.ID_ANY)
+        sizer.Add(withtxt, 0, wx.EXPAND)
+        sizer.Add(wx.Button(dlg, wx.ID_OK, 'Ok'), 0, wx.EXPAND)
+        sizer.Add(wx.Button(dlg, wx.ID_CANCEL, 'Cancel'), 0, wx.EXPAND)
+
+        dlg.SetSizer(sizer)
+        dlg.SetAutoLayout(True)
+        dlg.Fit()
+
+        rpltxt.SetValue(self.grid.GetItem(self.currentIdx, 0).GetText())
+        withtxt.SetValue(self.grid.GetItem(self.currentIdx, 1).GetText())
+
+        if dlg.ShowModal() != wx.ID_OK:
+            dlg.Destroy()
+            return
+
+        self.grid.SetStringItem(self.currentIdx, 0, rpltxt.GetValue())
+        self.grid.SetStringItem(self.currentIdx, 1, withtxt.GetValue())
+        self.grid.RefreshItem(self.currentIdx)
+        self.grid.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+        self.grid.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+
+        dlg.Destroy()
+
+    def RuleAdd(self, event):
+        i = self.grid.InsertStringItem(self.grid.GetItemCount(), '')
+        self.grid.SetStringItem(i, 1, '')
+        self.grid.Select(i)
+        self.RuleEdit(None)
+
+    def RuleDelete(self, event):
+        self.grid.DeleteItem(self.currentIdx)
+        self.grid.Select(0)
+
+    def OnExit(self, event):
+        self.MakeModal(False)
+
+        list = []
+        for i in xrange(0, self.grid.GetItemCount()):
+            list.append([self.grid.GetItem(i, 0).GetText(), self.grid.GetItem(i, 1).GetText()])
+
+        self.parent.filterRegEx = list
+        event.Skip()
+
+    def OnDone(self, event):
+        self.Close()