comparison orpg/chat/chatwnd.py @ 184:dcae32e219f1 beta

Traipse Beta 'OpenRPG' {100117-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 (Beta) New Features: Added Bookmarks Added 'boot' command to remote admin Added confirmation window for sent nodes Minor changes to allow for portability to an OpenSUSE linux OS Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG Zoom Mouse plugin added Images added to Plugin UI Switching to Element Tree Map efficiency, from FlexiRPG Added Status Bar to Update Manager New TrueDebug Class in orpg_log (See documentation for usage) Portable Mercurial Tip of the Day added, from Core and community New Reference Syntax added for custom PC sheets New Child Reference for gametree New Parent Reference for gametree New Gametree Recursion method, mapping, context sensitivity, and effeciency.. New Features node with bonus nodes and Node Referencing help added Dieroller structure from Core New DieRoller portability for odd Dice Added 7th Sea die roller; ie [7k3] = [7d10.takeHighest(3).open(10)] New 'Mythos' System die roller added Added new vs. die roller method for WoD; ie [3v3] = [3d10.vs(3)]. Included for Mythos roller also New Warhammer FRPG Die Roller (Special thanks to Puu-san for the support) New EZ_Tree Reference system. Push a button, Traipse the tree, get a reference (Beta!) Fixes: Fix to Text based Server Fix to Remote Admin Commands Fix to Pretty Print, from Core Fix to Splitter Nodes not being created Fix to massive amounts of images loading, from Core Fix to Map from gametree not showing to all clients Fix to gametree about menus Fix to Password Manager check on startup Fix to PC Sheets from tool nodes. They now use the tabber_panel Fix to Whiteboard ID to prevent random line or text deleting. Fixes to Server, Remote Server, and Server GUI Fix to Update Manager; cleaner clode for saved repositories Fixes made to Settings Panel and now reactive settings when Ok is pressed Fixes to Alternity roller's attack roll. Uses a simple Tuple instead of a Splice Fix to Use panel of Forms and Tabbers. Now longer enters design mode Fix made Image Fetching. New fetching image and new failed image Modified ID's to prevent non updated clients from ruining the fix. default_manifest.xml renamed to default_upmana.xml
author sirebral
date Sun, 17 Jan 2010 21:37:34 -0600
parents 0d9b746b5751
children a3d7e05085da
comparison
equal deleted inserted replaced
183:0d9b746b5751 184:dcae32e219f1
19 # 19 #
20 # File: chatutils.py 20 # File: chatutils.py
21 # Author: Chris Davis 21 # Author: Chris Davis
22 # Maintainer: 22 # Maintainer:
23 # Version: 23 # Version:
24 # $Id: chatwnd.py,v 1.177 2007/12/07 20:39:48 digitalxero Exp $ 24 # $Id: chatwnd.py,v Traipse 'Ornery-Orc' prof.ebral Exp $
25 # 25 #
26 # Description: This file contains some of the basic definitions for the chat 26 # Description: This file contains some of the basic definitions for the chat
27 # utilities in the orpg project. 27 # utilities in the orpg project.
28 # 28 #
29 # History 29 # History
35 # + Added strip_script_tags() to post() to remove crash point. See chat_util.py 35 # + Added strip_script_tags() to post() to remove crash point. See chat_util.py
36 # 2005-04-25 Snowdog 36 # 2005-04-25 Snowdog
37 # + Added simple_html_repair() to post() to fix malformed html in the chat window 37 # + Added simple_html_repair() to post() to fix malformed html in the chat window
38 # 38 #
39 39
40 __version__ = "$Id: chatwnd.py,v 1.177 2007/12/07 20:39:48 digitalxero Exp $" 40 __version__ = "$Id: chatwnd.py,v Traipse 'Ornery-Orc' prof.ebral Exp $"
41 41
42 42
43 ## 43 ##
44 ## Module Loading 44 ## Module Loading
45 ## 45 ##
47 47
48 from orpg.orpg_version import VERSION 48 from orpg.orpg_version import VERSION
49 from orpg.orpg_windows import * 49 from orpg.orpg_windows import *
50 from orpg.player_list import WG_LIST 50 from orpg.player_list import WG_LIST
51 from orpg.dirpath import dir_struct 51 from orpg.dirpath import dir_struct
52 #from orpg.tools.metamenus import MenuEx #Needed?
53 from string import * 52 from string import *
54 53
55 import cStringIO # for reading inline imagedata as a stream 54 import cStringIO # for reading inline imagedata as a stream
56 from HTMLParser import HTMLParser 55 from HTMLParser import HTMLParser
57 from wx.lib.expando import EVT_ETC_LAYOUT_NEEDED 56 from wx.lib.expando import EVT_ETC_LAYOUT_NEEDED
63 import orpg.tools.predTextCtrl 62 import orpg.tools.predTextCtrl
64 from orpg.tools.orpg_log import logger, debug 63 from orpg.tools.orpg_log import logger, debug
65 from orpg.orpgCore import component 64 from orpg.orpgCore import component
66 from xml.etree.ElementTree import tostring 65 from xml.etree.ElementTree import tostring
67 66
68 from orpg.networking.mplay_client import MPLAY_CONNECTED # needed to only send typing/not_typing messages while connected 67 from orpg.networking.mplay_client import MPLAY_CONNECTED
69
70 NEWCHAT = False 68 NEWCHAT = False
71 try: 69 try:
72 import wx.webview 70 import wx.webview
73 NEWCHAT = True 71 NEWCHAT = True
74 except: pass 72 except: pass
81 79
82 def __init__(self): 80 def __init__(self):
83 self.accum = "" 81 self.accum = ""
84 self.special_tags = ['hr', 'br', 'img'] 82 self.special_tags = ['hr', 'br', 'img']
85 83
86 def handle_data(self, data): # quote cdata literally 84 def handle_data(self, data):
87 self.accum += data 85 self.accum += data
88 86
89 def handle_entityref(self, name): # entities must be preserved exactly 87 def handle_entityref(self, name):
90 self.accum += "&" + name + ";" 88 self.accum += "&" + name + ";"
91 89
92 def handle_starttag(self, tag, attrs): 90 def handle_starttag(self, tag, attrs):
93 if tag in self.special_tags: 91 if tag in self.special_tags:
94 self.accum += '<' + tag 92 self.accum += '<' + tag
95 for attrib in attrs: self.accum += ' ' + attrib[0] + '="' + attrib[1] + '"' 93 for attrib in attrs: self.accum += ' ' + attrib[0] + '="' + attrib[1] + '"'
96 self.accum += '>' 94 self.accum += '>'
97 95
98 def handle_charref(self, name): # charrefs too 96 def handle_charref(self, name):
99 self.accum += "&#" + name + ";" 97 self.accum += "&#" + name + ";"
100 htmlstripper = HTMLStripper() 98 htmlstripper = HTMLStripper()
101 99
102 # utility function; see Post().
103 100
104 def strip_html(string): 101 def strip_html(string):
105 "Return string tripped of html tags." 102 "Return string tripped of html tags."
106 htmlstripper.reset() 103 htmlstripper.reset()
107 htmlstripper.accum = "" 104 htmlstripper.accum = ""
112 109
113 def log( settings, c, text ): 110 def log( settings, c, text ):
114 filename = settings.get_setting('GameLogPrefix') 111 filename = settings.get_setting('GameLogPrefix')
115 if filename > '' and filename[0] != commands.ANTI_LOG_CHAR: 112 if filename > '' and filename[0] != commands.ANTI_LOG_CHAR:
116 filename = filename + time.strftime( '-%Y-%m-%d.html', time.localtime( time.time() ) ) 113 filename = filename + time.strftime( '-%Y-%m-%d.html', time.localtime( time.time() ) )
117 #filename = time.strftime( filename, time.localtime( time.time() ) )
118 timestamp = time.ctime(time.time()) 114 timestamp = time.ctime(time.time())
119 header = '[%s] : ' % ( timestamp ); 115 header = '[%s] : ' % ( timestamp );
120 if settings.get_setting('TimeStampGameLog') != '1': header = '' 116 if settings.get_setting('TimeStampGameLog') != '1': header = ''
121 try: 117 try:
122 f = open( dir_struct["user"] + filename, 'a' ) 118 f = open( dir_struct["user"] + filename, 'a' )
134 # CalculateAllFonts(self, defaultsize) 130 # CalculateAllFonts(self, defaultsize)
135 # SetDefaultFontAndSize(self, fontname) 131 # SetDefaultFontAndSize(self, fontname)
136 # 132 #
137 class chat_html_window(wx.html.HtmlWindow): 133 class chat_html_window(wx.html.HtmlWindow):
138 """ a wxHTMLwindow that will load links """ 134 """ a wxHTMLwindow that will load links """
139 # initialization subroutine 135
140 #
141 # !self : instance of self
142 # !parent :
143 # !id :
144
145 def __init__(self, parent, id): 136 def __init__(self, parent, id):
146 wx.html.HtmlWindow.__init__(self, parent, id, 137 wx.html.HtmlWindow.__init__(self, parent, id,
147 style=wx.SUNKEN_BORDER|wx.html.HW_SCROLLBAR_AUTO|wx.NO_FULL_REPAINT_ON_RESIZE) 138 style=wx.SUNKEN_BORDER|wx.html.HW_SCROLLBAR_AUTO|wx.NO_FULL_REPAINT_ON_RESIZE)
148 self.parent = parent 139 self.parent = parent
149 self.build_menu() 140 self.build_menu()
150 self.Bind(wx.EVT_LEFT_UP, self.LeftUp) 141 self.Bind(wx.EVT_LEFT_UP, self.LeftUp)
151 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup) 142 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup)
152 if "gtk2" in wx.PlatformInfo: self.SetStandardFonts() 143 if "gtk2" in wx.PlatformInfo: self.SetStandardFonts()
153 # def __init__ - end 144
154
155
156 def onPopup(self, evt): 145 def onPopup(self, evt):
157 self.PopupMenu(self.menu) 146 self.PopupMenu(self.menu)
158 147
159
160 def LeftUp(self, event): 148 def LeftUp(self, event):
161 event.Skip() 149 event.Skip()
162 wx.CallAfter(self.parent.set_chat_text_focus, None) 150 wx.CallAfter(self.parent.set_chat_text_focus, None)
163 151
164
165 def build_menu(self): 152 def build_menu(self):
166 self.menu = wx.Menu() 153 self.menu = wx.Menu()
167 item = wx.MenuItem(self.menu, wx.ID_ANY, "Copy", "Copy") 154 item = wx.MenuItem(self.menu, wx.ID_ANY, "Copy", "Copy")
168 self.Bind(wx.EVT_MENU, self.OnM_EditCopy, item) 155 self.Bind(wx.EVT_MENU, self.OnM_EditCopy, item)
169 self.menu.AppendItem(item) 156 self.menu.AppendItem(item)
172 wx.TheClipboard.UsePrimarySelection(False) 159 wx.TheClipboard.UsePrimarySelection(False)
173 wx.TheClipboard.Open() 160 wx.TheClipboard.Open()
174 wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText())) 161 wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText()))
175 wx.TheClipboard.Close() 162 wx.TheClipboard.Close()
176 163
177
178 def scroll_down(self): 164 def scroll_down(self):
179 maxrange = self.GetScrollRange(wx.VERTICAL) 165 maxrange = self.GetScrollRange(wx.VERTICAL)
180 pagesize = self.GetScrollPageSize(wx.VERTICAL) 166 pagesize = self.GetScrollPageSize(wx.VERTICAL)
181 self.Scroll(-1, maxrange-pagesize) 167 self.Scroll(-1, maxrange-pagesize)
182 168
183
184 def mouse_wheel(self, event): 169 def mouse_wheel(self, event):
185 amt = event.GetWheelRotation() 170 amt = event.GetWheelRotation()
186 units = amt/(-(event.GetWheelDelta())) 171 units = amt/(-(event.GetWheelDelta()))
187 self.ScrollLines(units*3) 172 self.ScrollLines(units*3)
188 173
195 return self.GetPageSource().replace(self.Header(), '') 180 return self.GetPageSource().replace(self.Header(), '')
196 181
197 182
198 def GetPageSource(self): 183 def GetPageSource(self):
199 return self.GetParser().GetSource() 184 return self.GetParser().GetSource()
200
201 # This subroutine fires up the webbrowser when a link is clicked.
202 #
203 # !self : instance of self
204 # !linkinfo : instance of a class that contains the link information
205 185
206 def OnLinkClicked(self, linkinfo): 186 def OnLinkClicked(self, linkinfo):
207 href = linkinfo.GetHref() 187 href = linkinfo.GetHref()
208 wb = webbrowser.get() 188 wb = webbrowser.get()
209 wb.open(href) 189 wb.open(href)
210 # def OnLinkClicked - end 190
211
212
213 def CalculateAllFonts(self, defaultsize): 191 def CalculateAllFonts(self, defaultsize):
214 return [int(defaultsize * 0.4), 192 return [int(defaultsize * 0.4),
215 int(defaultsize * 0.7), 193 int(defaultsize * 0.7),
216 int(defaultsize), 194 int(defaultsize),
217 int(defaultsize * 1.3), 195 int(defaultsize * 1.3),
218 int(defaultsize * 1.7), 196 int(defaultsize * 1.7),
219 int(defaultsize * 2), 197 int(defaultsize * 2),
220 int(defaultsize * 2.5)] 198 int(defaultsize * 2.5)]
221 199
222
223 def SetDefaultFontAndSize(self, fontname, fontsize): 200 def SetDefaultFontAndSize(self, fontname, fontsize):
224 """Set 'fontname' to the default chat font. 201 """Set 'fontname' to the default chat font.
225 Returns current font settings in a (fontname, fontsize) tuple.""" 202 Returns current font settings in a (fontname, fontsize) tuple."""
226 self.SetFonts(fontname, "", self.CalculateAllFonts(int(fontsize))) 203 self.SetFonts(fontname, "", self.CalculateAllFonts(int(fontsize)))
227 return (self.GetFont().GetFaceName(), self.GetFont().GetPointSize()) 204 return (self.GetFont().GetFaceName(), self.GetFont().GetPointSize())
237 self.build_menu() 214 self.build_menu()
238 self.Bind(wx.EVT_LEFT_UP, self.LeftUp) 215 self.Bind(wx.EVT_LEFT_UP, self.LeftUp)
239 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup) 216 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup)
240 self.Bind(wx.webview.EVT_WEBVIEW_BEFORE_LOAD, self.OnLinkClicked) 217 self.Bind(wx.webview.EVT_WEBVIEW_BEFORE_LOAD, self.OnLinkClicked)
241 218
242 #Wrapers so I dont have to add special Code
243 def SetPage(self, htmlstring): 219 def SetPage(self, htmlstring):
244 self.SetPageSource(htmlstring) 220 self.SetPageSource(htmlstring)
245 221
246 def AppendToPage(self, htmlstring): 222 def AppendToPage(self, htmlstring):
247 self.SetPageSource(self.GetPageSource() + htmlstring) 223 self.SetPageSource(self.GetPageSource() + htmlstring)
448 def onPageChanged(self, event): 424 def onPageChanged(self, event):
449 """When private chattabs are selected, set the bitmap back to 'normal'.""" 425 """When private chattabs are selected, set the bitmap back to 'normal'."""
450 selected_idx = event.GetSelection() 426 selected_idx = event.GetSelection()
451 self.SetPageImage(selected_idx, 1) 427 self.SetPageImage(selected_idx, 1)
452 page = self.GetPage(selected_idx) 428 page = self.GetPage(selected_idx)
453 #wx.CallAfter(page.set_chat_text_focus, 0)
454 event.Skip() 429 event.Skip()
455 430
456 """ 431 """
457 This class defines and builds the Chat Frame for OpenRPG 432 This class defines and builds the Chat Frame for OpenRPG
458 433
503 self.activeplugins = component.get('plugins') 478 self.activeplugins = component.get('plugins')
504 self.parent = parent 479 self.parent = parent
505 # who receives outbound messages, either "all" or "playerid" string 480 # who receives outbound messages, either "all" or "playerid" string
506 self.sendtarget = sendtarget 481 self.sendtarget = sendtarget
507 self.type = tab_type 482 self.type = tab_type
508 #self.sound_player = component.get('sound') #Removing!
509 # create die roller manager
510 #self.DiceManager = component.get('DiceManager') #Removing!
511 # create rpghex tool
512 self.r_h = orpg.tools.rgbhex.RGBHex() 483 self.r_h = orpg.tools.rgbhex.RGBHex()
513 self.h = 0 484 self.h = 0
514 self.set_colors() 485 self.set_colors()
515 self.version = VERSION 486 self.version = VERSION
516 self.histidx = -1 487 self.histidx = -1
534 self.defaultFilterName = 'No Filter' 505 self.defaultFilterName = 'No Filter'
535 self.advancedFilter = False 506 self.advancedFilter = False
536 self.lastSend = 0 # this is used to help implement the player typing indicator 507 self.lastSend = 0 # this is used to help implement the player typing indicator
537 self.lastPress = 0 # this is used to help implement the player typing indicator 508 self.lastPress = 0 # this is used to help implement the player typing indicator
538 self.Bind(wx.EVT_SIZE, self.OnSize) 509 self.Bind(wx.EVT_SIZE, self.OnSize)
539 self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnSize) #require to keep text at bottom of chat when text entry expands --SD 510 self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnSize)
540 self.build_ctrls() 511 self.build_ctrls()
541 StartupFont = self.settings.get_setting("defaultfont") 512 StartupFont = self.settings.get_setting("defaultfont")
542 StartupFontSize = self.settings.get_setting("defaultfontsize") 513 StartupFontSize = self.settings.get_setting("defaultfontsize")
543 if(StartupFont != "") and (StartupFontSize != ""): 514 if(StartupFont != "") and (StartupFontSize != ""):
544 try: self.set_default_font(StartupFont, int(StartupFontSize)) 515 try: self.set_default_font(StartupFont, int(StartupFontSize))
776 def get_hot_keys(self): 747 def get_hot_keys(self):
777 # dummy menus for hotkeys 748 # dummy menus for hotkeys
778 self.build_menu() 749 self.build_menu()
779 entries = [] 750 entries = []
780 entries.append((wx.ACCEL_CTRL, ord('H'), self.setChatFocusMenu.GetId())) 751 entries.append((wx.ACCEL_CTRL, ord('H'), self.setChatFocusMenu.GetId()))
781 #entries.append((wx.ACCEL_CTRL, wx.WXK_TAB, SWAP_TABS))
782 return entries 752 return entries
783 753
784 754
785 def forward_tabs(self, evt): 755 def forward_tabs(self, evt):
786 self.parent.AdvanceSelection() 756 self.parent.AdvanceSelection()
787 757
788 def back_tabs(self, evt): 758 def back_tabs(self, evt):
789 self.parent.AdvanceSelection(False) 759 self.parent.AdvanceSelection(False)
790 760
791 # This subroutine builds the controls for the chat frame
792 #
793 # !self : instance of self
794
795 def build_ctrls(self): 761 def build_ctrls(self):
796 self.chatwnd = chat_html_window(self,-1) 762 self.chatwnd = chat_html_window(self,-1)
797 self.set_colors() 763 self.set_colors()
798 wx.CallAfter(self.chatwnd.SetPage, self.chatwnd.Header()) 764 wx.CallAfter(self.chatwnd.SetPage, self.chatwnd.Header())
799 if (self.sendtarget == "all"): 765 if (self.sendtarget == "all"):
800 wx.CallAfter(self.Post, self.colorize(self.syscolor, 766 wx.CallAfter(self.Post, self.colorize(self.syscolor,
801 "<b>Welcome to <a href='http://www.openrpg.com'>OpenRPG</a> version " + self.version + "... </b>")) 767 "<b>Welcome to <a href='http://www.openrpg.com'>OpenRPG</a> version " + self.version + "... </b>"))
802 #self.chat_cmds.on_help()
803 self.chattxt = orpg.tools.predTextCtrl.predTextCtrl(self, -1, "", 768 self.chattxt = orpg.tools.predTextCtrl.predTextCtrl(self, -1, "",
804 style=wx.TE_PROCESS_ENTER |wx.TE_PROCESS_TAB|wx.TE_LINEWRAP, 769 style=wx.TE_PROCESS_ENTER |wx.TE_PROCESS_TAB|wx.TE_LINEWRAP,
805 keyHook = self.myKeyHook, validator=None ) 770 keyHook = self.myKeyHook, validator=None )
806 self.build_bar() 771 self.build_bar()
807 self.basesizer = wx.BoxSizer(wx.VERTICAL) 772 self.basesizer = wx.BoxSizer(wx.VERTICAL)
836 self.Bind(wx.EVT_BUTTON, self.lock_scroll, self.scroll_lock) 801 self.Bind(wx.EVT_BUTTON, self.lock_scroll, self.scroll_lock)
837 self.chattxt.Bind(wx.EVT_MOUSEWHEEL, self.chatwnd.mouse_wheel) 802 self.chattxt.Bind(wx.EVT_MOUSEWHEEL, self.chatwnd.mouse_wheel)
838 self.chattxt.Bind(wx.EVT_CHAR, self.chattxt.OnChar) 803 self.chattxt.Bind(wx.EVT_CHAR, self.chattxt.OnChar)
839 self.chattxt.Bind(wx.EVT_KEY_DOWN, self.on_chat_key_down) 804 self.chattxt.Bind(wx.EVT_KEY_DOWN, self.on_chat_key_down)
840 self.chattxt.Bind(wx.EVT_TEXT_COPY, self.chatwnd.OnM_EditCopy) 805 self.chattxt.Bind(wx.EVT_TEXT_COPY, self.chatwnd.OnM_EditCopy)
841 # def build_ctrls - end
842 806
843 def build_bar(self): 807 def build_bar(self):
844 self.toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL) 808 self.toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL)
845 self.scroll_lock = None 809 self.scroll_lock = None
846 self.numDieText = None 810 self.numDieText = None
853 self.toolbar_sizer.Add(self.textpop_lock, 0, wx.EXPAND) 817 self.toolbar_sizer.Add(self.textpop_lock, 0, wx.EXPAND)
854 self.toolbar_sizer.Add(self.scroll_lock, 0, wx.EXPAND) 818 self.toolbar_sizer.Add(self.scroll_lock, 0, wx.EXPAND)
855 self.build_formating() 819 self.build_formating()
856 self.build_colorbutton() 820 self.build_colorbutton()
857 821
858
859 def build_scroll(self): 822 def build_scroll(self):
860 self.scroll_lock = wx.Button( self, wx.ID_ANY, "Scroll ON",size= wx.Size(80,25)) 823 self.scroll_lock = wx.Button( self, wx.ID_ANY, "Scroll ON",size= wx.Size(80,25))
861 824
862
863 def build_alias(self): 825 def build_alias(self):
864 self.aliasSizer = wx.BoxSizer(wx.HORIZONTAL) 826 self.aliasSizer = wx.BoxSizer(wx.HORIZONTAL)
865 self.aliasList = wx.Choice(self, wx.ID_ANY, size=(100, 25), choices=[self.defaultAliasName]) 827 self.aliasList = wx.Choice(self, wx.ID_ANY, size=(100, 25), choices=[self.defaultAliasName])
866 self.aliasButton = createMaskedButton( self, dir_struct["icon"] + 'player.gif', 828 self.aliasButton = createMaskedButton( self, dir_struct["icon"] + 'player.gif',
867 'Refresh list of aliases from Game Tree', 829 'Refresh list of aliases from Game Tree',
947 def toggle_formating(self, act): 909 def toggle_formating(self, act):
948 if act == '0': self.toolbar_sizer.Show(self.formatSizer, False) 910 if act == '0': self.toolbar_sizer.Show(self.formatSizer, False)
949 else: self.toolbar_sizer.Show(self.formatSizer, True) 911 else: self.toolbar_sizer.Show(self.formatSizer, True)
950 self.toolbar_sizer.Layout() 912 self.toolbar_sizer.Layout()
951 913
952 # Heroman - Ideally, we would use static labels...
953
954 def build_colorbutton(self): 914 def build_colorbutton(self):
955 self.color_button = createMaskedButton(self, dir_struct["icon"]+'textcolor.gif', 915 self.color_button = createMaskedButton(self, dir_struct["icon"]+'textcolor.gif',
956 'Text Color', wx.ID_ANY, '#bdbdbd', 916 'Text Color', wx.ID_ANY, '#bdbdbd',
957 wx.BITMAP_TYPE_GIF) 917 wx.BITMAP_TYPE_GIF)
958 918
981 self.session.set_status_url(link) 941 self.session.set_status_url(link)
982 except: pass 942 except: pass
983 else: logger.general("Error, self.chatwnd.GetInternalRepresentation() return None") 943 else: logger.general("Error, self.chatwnd.GetInternalRepresentation() return None")
984 evt.Skip() 944 evt.Skip()
985 945
986 # This subroutine is registered with predTextCtrl to be run for every OnChar event
987 # It checks if we need to send a typing message
988
989 #
990 # self: duh
991 # event: raw KeyEvent from OnChar()
992
993 def myKeyHook(self, event): 946 def myKeyHook(self, event):
994 if self.session.get_status() == MPLAY_CONNECTED: # only do if we're connected 947 if self.session.get_status() == MPLAY_CONNECTED: # only do if we're connected
995 thisPress = time.time() # thisPress is local temp variable 948 thisPress = time.time() # thisPress is local temp variable
996 if (thisPress - self.lastSend) > 4: # Check to see if it's been 5 seconds since our last notice 949 if (thisPress - self.lastSend) > 4: # Check to see if it's been 5 seconds since our last notice
997 # If we're not already typing, then self.lastSend will be 0 950 # If we're not already typing, then self.lastSend will be 0
1003 return 1 956 return 1
1004 else: 957 else:
1005 logger.debug("Exit chat_panel->myKeyHook(self, event) return 0") 958 logger.debug("Exit chat_panel->myKeyHook(self, event) return 0")
1006 return 0 959 return 0
1007 960
1008 # This subroutine gets called once a second by the typing Timer
1009 # It checks if we need to send a not_typing message
1010 #
1011 # self: duh
1012
1013 def typingTimerFunc(self, event): 961 def typingTimerFunc(self, event):
1014 #following added by mDuo13 962 #following added by mDuo13
1015 ##############refresh_counter()############## 963 ##############refresh_counter()##############
1016 for plugin_fname in self.activeplugins.keys(): 964 for plugin_fname in self.activeplugins.keys():
1017 plugin = self.activeplugins[plugin_fname] 965 plugin = self.activeplugins[plugin_fname]
1025 thisTime = time.time() # thisTime is a local temp variable 973 thisTime = time.time() # thisTime is a local temp variable
1026 if (thisTime - self.lastPress) > 4: # Check to see if it's been 5 seconds since our last keystroke 974 if (thisTime - self.lastPress) > 4: # Check to see if it's been 5 seconds since our last keystroke
1027 # If we're not already typing, then self.lastSend will be 0 975 # If we're not already typing, then self.lastSend will be 0
1028 976
1029 self.sendTyping(0) # send a typing event here (0 for False) 977 self.sendTyping(0) # send a typing event here (0 for False)
1030 # This subroutine actually takes care of sending the messages for typing/not_typing events 978
1031 #
1032 # self: duh
1033 # typing: boolean
1034
1035
1036 def sendTyping(self, typing): 979 def sendTyping(self, typing):
1037 if typing: 980 if typing:
1038 self.lastSend = time.time() # remember our send time for use in myKeyHook() 981 self.lastSend = time.time() # remember our send time for use in myKeyHook()
1039 #I think this is cleaner 982 #I think this is cleaner
1040 status_text = self.settings.get_setting('TypingStatusAlias') 983 status_text = self.settings.get_setting('TypingStatusAlias')
1045 #I think this is cleaner 988 #I think this is cleaner
1046 status_text = self.settings.get_setting('IdleStatusAlias') 989 status_text = self.settings.get_setting('IdleStatusAlias')
1047 if status_text == "" or status_text == None: status_text = "Idle" 990 if status_text == "" or status_text == None: status_text = "Idle"
1048 self.session.set_text_status(status_text) 991 self.session.set_text_status(status_text)
1049 992
1050 # This subroutine sets the colors of the chat based on the settings in the
1051 # self instance.
1052 #
1053 # !self : instance of self
1054
1055 def set_colors(self): 993 def set_colors(self):
1056 # chat window backround color 994 # chat window backround color
1057 self.bgcolor = self.settings.get_setting('bgcolor') 995 self.bgcolor = self.settings.get_setting('bgcolor')
1058 # chat window normal text color 996 # chat window normal text color
1059 self.textcolor = self.settings.get_setting('textcolor') 997 self.textcolor = self.settings.get_setting('textcolor')
1065 self.infocolor = self.settings.get_setting('infocolor') 1003 self.infocolor = self.settings.get_setting('infocolor')
1066 # color of emotes 1004 # color of emotes
1067 self.emotecolor = self.settings.get_setting('emotecolor') 1005 self.emotecolor = self.settings.get_setting('emotecolor')
1068 # color of whispers 1006 # color of whispers
1069 self.whispercolor = self.settings.get_setting('whispercolor') 1007 self.whispercolor = self.settings.get_setting('whispercolor')
1070 # def set_colors - end
1071
1072 # This subroutine will insert text into the chat window
1073 #
1074 # !self : instance of self
1075 # !txt : text to be inserted into the chat window
1076 1008
1077 def set_chat_text(self, txt): 1009 def set_chat_text(self, txt):
1078 self.chattxt.SetValue(txt) 1010 self.chattxt.SetValue(txt)
1079 self.chattxt.SetFocus() 1011 self.chattxt.SetFocus()
1080 self.chattxt.SetInsertionPointEnd() 1012 self.chattxt.SetInsertionPointEnd()
1081 # def set_chat_text - end
1082 1013
1083 1014
1084 def get_chat_text(self): 1015 def get_chat_text(self):
1085 return self.chattxt.GetValue() 1016 return self.chattxt.GetValue()
1086 1017
1087 # This subroutine sets the focus to the chat window 1018 # This subroutine sets the focus to the chat window
1088 1019
1089 def set_chat_text_focus(self, event): 1020 def set_chat_text_focus(self, event):
1090 wx.CallAfter(self.chattxt.SetFocus) 1021 wx.CallAfter(self.chattxt.SetFocus)
1091 # def set_chat_text_focus - end
1092
1093 # This subrtouine grabs the user input and make the special keys and
1094 # modifiers work.
1095 #
1096 # !self : instance of self
1097 # !event :
1098 #
1099 # Note: self.chattxt now handles it's own Key events. It does, however still
1100 # call it's parent's (self) OnChar to handle "default" behavior.
1101 1022
1102 def submit_chat_text(self, s): 1023 def submit_chat_text(self, s):
1103 self.histidx = -1 1024 self.histidx = -1
1104 self.temptext = "" 1025 self.temptext = ""
1105 self.history = [s] + self.history 1026 self.history = [s] + self.history
1106 #if not len(macroText): self.chattxt.SetValue("")
1107 1027
1108 # play sound 1028 # play sound
1109 sound_file = self.settings.get_setting("SendSound") 1029 sound_file = self.settings.get_setting("SendSound")
1110 if sound_file != '': component.get('sound').play(sound_file) 1030 if sound_file != '': component.get('sound').play(sound_file)
1111 if s[0] != "/": ## it's not a slash command 1031 if s[0] != "/": ## it's not a slash command
1142 1062
1143 ## UP KEY 1063 ## UP KEY
1144 elif event.GetKeyCode() == wx.WXK_UP: 1064 elif event.GetKeyCode() == wx.WXK_UP:
1145 logger.debug("event.GetKeyCode() == wx.WXK_UP") 1065 logger.debug("event.GetKeyCode() == wx.WXK_UP")
1146 if self.histidx < len(self.history)-1: 1066 if self.histidx < len(self.history)-1:
1147 #text that's not in history but also hasn't been sent to chat gets stored in self.temptext
1148 #this way if someone presses the up key, they don't lose their current message permanently
1149 #(unless they also press enter at the time)
1150 if self.histidx is -1: self.temptext = self.chattxt.GetValue() 1067 if self.histidx is -1: self.temptext = self.chattxt.GetValue()
1151 self.histidx += 1 1068 self.histidx += 1
1152 self.chattxt.SetValue(self.history[self.histidx]) 1069 self.chattxt.SetValue(self.history[self.histidx])
1153 self.chattxt.SetInsertionPointEnd() 1070 self.chattxt.SetInsertionPointEnd()
1154 else: 1071 else:
1155 self.histidx = len(self.history) -1#in case it got too high somehow, this should fix it 1072 self.histidx = len(self.history) -1
1156 #self.InfoPost("**Going up? I don't think so.**")
1157 #print self.histidx, "in",self.history
1158 1073
1159 ## DOWN KEY 1074 ## DOWN KEY
1160 elif event.GetKeyCode() == wx.WXK_DOWN: 1075 elif event.GetKeyCode() == wx.WXK_DOWN:
1161 logger.debug("event.GetKeyCode() == wx.WXK_DOWN") 1076 logger.debug("event.GetKeyCode() == wx.WXK_DOWN")
1162 #histidx of -1 indicates currently viewing text that's not in self.history 1077 #histidx of -1 indicates currently viewing text that's not in self.history
1164 self.histidx -= 1 1079 self.histidx -= 1
1165 if self.histidx is -1: #remember, it just decreased 1080 if self.histidx is -1: #remember, it just decreased
1166 self.chattxt.SetValue(self.temptext) 1081 self.chattxt.SetValue(self.temptext)
1167 else: self.chattxt.SetValue(self.history[self.histidx]) 1082 else: self.chattxt.SetValue(self.history[self.histidx])
1168 self.chattxt.SetInsertionPointEnd() 1083 self.chattxt.SetInsertionPointEnd()
1169 else: self.histidx = -1 #just in case it somehow got below -1, this should fix it 1084 else: self.histidx = -1
1170 #self.InfoPost("**Going down? I don't think so.**")
1171 #print self.histidx, "in",self.history
1172 1085
1173 ## TAB KEY 1086 ## TAB KEY
1174 elif event.GetKeyCode() == wx.WXK_TAB: 1087 elif event.GetKeyCode() == wx.WXK_TAB:
1175 logger.debug("event.GetKeyCode() == wx.WXK_TAB") 1088 logger.debug("event.GetKeyCode() == wx.WXK_TAB")
1176 if s !="": 1089 if s !="":
1240 return 1153 return
1241 1154
1242 ## NOTHING 1155 ## NOTHING
1243 else: event.Skip() 1156 else: event.Skip()
1244 logger.debug("Exit chat_panel->OnChar(self, event)") 1157 logger.debug("Exit chat_panel->OnChar(self, event)")
1245 # def OnChar - end
1246
1247 1158
1248 def onDieRoll(self, evt): 1159 def onDieRoll(self, evt):
1249 """Roll the dice based on the button pressed and the die modifiers entered, if any.""" 1160 """Roll the dice based on the button pressed and the die modifiers entered, if any."""
1250 # Get any die modifiers if they have been entered 1161 # Get any die modifiers if they have been entered
1251 numDie = self.numDieText.GetValue() 1162 numDie = self.numDieText.GetValue()
1258 dieText += dieMod 1169 dieText += dieMod
1259 dieText = "[" + dieText + "]" 1170 dieText = "[" + dieText + "]"
1260 self.ParsePost(dieText, 1, 1) 1171 self.ParsePost(dieText, 1, 1)
1261 self.chattxt.SetFocus() 1172 self.chattxt.SetFocus()
1262 1173
1263 # This subroutine saves a chat buffer as html to a file chosen via a
1264 # FileDialog.
1265 #
1266 # !self : instance of self
1267 # !evt :
1268
1269 def on_chat_save(self, evt): 1174 def on_chat_save(self, evt):
1270 f = wx.FileDialog(self,"Save Chat Buffer",".","","HTM* (*.htm*)|*.htm*|HTML (*.html)|*.html|HTM (*.htm)|*.htm",wx.SAVE) 1175 f = wx.FileDialog(self,"Save Chat Buffer",".","","HTM* (*.htm*)|*.htm*|HTML (*.html)|*.html|HTM (*.htm)|*.htm",wx.SAVE)
1271 if f.ShowModal() == wx.ID_OK: 1176 if f.ShowModal() == wx.ID_OK:
1272 file = open(f.GetPath(), "w") 1177 file = open(f.GetPath(), "w")
1273 file.write(self.ResetPage() + "</body></html>") 1178 file.write(self.ResetPage() + "</body></html>")
1274 file.close() 1179 file.close()
1275 f.Destroy() 1180 f.Destroy()
1276 os.chdir(dir_struct["home"]) 1181 os.chdir(dir_struct["home"])
1277 # def on_chat_save - end 1182
1278
1279
1280 def ResetPage(self): 1183 def ResetPage(self):
1281 self.set_colors() 1184 self.set_colors()
1282 buffertext = self.chatwnd.Header() + "\n" 1185 buffertext = self.chatwnd.Header() + "\n"
1283 buffertext += chat_util.strip_body_tags(self.chatwnd.StripHeader()).replace("<br>", 1186 buffertext += chat_util.strip_body_tags(self.chatwnd.StripHeader()).replace("<br>",
1284 "<br />").replace('</html>', 1187 "<br />").replace('</html>',
1285 '').replace("<br />", 1188 '').replace("<br />",
1286 "<br />\n").replace("\n\n", '') 1189 "<br />\n").replace("\n\n", '')
1287 return buffertext 1190 return buffertext
1288 1191
1289 # This subroutine sets the color of selected text, or base text color if
1290 # nothing is selected
1291
1292 def on_text_color(self, event): 1192 def on_text_color(self, event):
1293 hexcolor = self.r_h.do_hex_color_dlg(self) 1193 hexcolor = self.r_h.do_hex_color_dlg(self)
1294 if hexcolor != None: 1194 if hexcolor != None:
1295 (beg,end) = self.chattxt.GetSelection() 1195 (beg,end) = self.chattxt.GetSelection()
1296 if beg != end: 1196 if beg != end:
1303 self.color_button.SetBackgroundColour(hexcolor) 1203 self.color_button.SetBackgroundColour(hexcolor)
1304 self.mytextcolor = hexcolor 1204 self.mytextcolor = hexcolor
1305 self.settings.set_setting('mytextcolor',hexcolor) 1205 self.settings.set_setting('mytextcolor',hexcolor)
1306 self.set_colors() 1206 self.set_colors()
1307 self.Post() 1207 self.Post()
1308 # def on_text_color - end 1208
1309
1310 # This subroutine take a color and a text string and formats it into html.
1311 #
1312 # !self : instance of self
1313 # !color : color for the text to be set
1314 # !text : text string to be included in the html.
1315
1316 def colorize(self, color, text): 1209 def colorize(self, color, text):
1317 """Puts font tags of 'color' around 'text' value, and returns the string""" 1210 """Puts font tags of 'color' around 'text' value, and returns the string"""
1318 return "<font color='" + color + "'>" + text + "</font>" 1211 return "<font color='" + color + "'>" + text + "</font>"
1319 # def colorize - end 1212
1320
1321 # This subroutine takes and event and inserts text with the basic format
1322 # tags included.
1323 #
1324 # !self : instance of self
1325 # !event :
1326
1327 def on_text_format(self, event): 1213 def on_text_format(self, event):
1328 id = event.GetId() 1214 id = event.GetId()
1329 txt = self.chattxt.GetValue() 1215 txt = self.chattxt.GetValue()
1330 (beg,end) = self.chattxt.GetSelection() 1216 (beg,end) = self.chattxt.GetSelection()
1331 if beg != end: sel_txt = txt[beg:end] 1217 if beg != end: sel_txt = txt[beg:end]
1336 if beg != end: txt = txt[:beg] + sel_txt + txt[end:] 1222 if beg != end: txt = txt[:beg] + sel_txt + txt[end:]
1337 else: txt = sel_txt 1223 else: txt = sel_txt
1338 self.chattxt.SetValue(txt) 1224 self.chattxt.SetValue(txt)
1339 self.chattxt.SetInsertionPointEnd() 1225 self.chattxt.SetInsertionPointEnd()
1340 self.chattxt.SetFocus() 1226 self.chattxt.SetFocus()
1341 # def on_text_format - end 1227
1342
1343
1344 def lock_scroll(self, event): 1228 def lock_scroll(self, event):
1345 if self.lockscroll: 1229 if self.lockscroll:
1346 self.lockscroll = False 1230 self.lockscroll = False
1347 self.scroll_lock.SetLabel("Scroll ON") 1231 self.scroll_lock.SetLabel("Scroll ON")
1348 if len(self.storedata) != 0: 1232 if len(self.storedata) != 0:
1351 self.scroll_down() 1235 self.scroll_down()
1352 else: 1236 else:
1353 self.lockscroll = True 1237 self.lockscroll = True
1354 self.scroll_lock.SetLabel("Scroll OFF") 1238 self.scroll_lock.SetLabel("Scroll OFF")
1355 1239
1356 # This subroutine will popup a text window with the chatbuffer contents
1357 #
1358 # !self : instance of self
1359 # !event :
1360
1361 def pop_textpop(self, event): 1240 def pop_textpop(self, event):
1362 """searchable popup text view of chatbuffer""" 1241 """searchable popup text view of chatbuffer"""
1363 h_buffertext = self.ResetPage() 1242 h_buffertext = self.ResetPage()
1364 h_dlg = orpgScrolledMessageFrameEditor(self, h_buffertext, "Text View of Chat Window", None, (500,300)) 1243 h_dlg = orpgScrolledMessageFrameEditor(self, h_buffertext, "Text View of Chat Window", None, (500,300))
1365 h_dlg.Show(True) 1244 h_dlg.Show(True)
1366 1245
1367 # This subroutine will change the dimension of the window
1368 #
1369 # !self : instance of self
1370 # !event :
1371
1372 def OnSize(self, event=None): 1246 def OnSize(self, event=None):
1373 event.Skip() 1247 event.Skip()
1374 wx.CallAfter(self.scroll_down) 1248 wx.CallAfter(self.scroll_down)
1375 # def OnSize - end 1249
1376
1377
1378 def scroll_down(self): 1250 def scroll_down(self):
1379 self.Freeze() 1251 self.Freeze()
1380 self.chatwnd.scroll_down() 1252 self.chatwnd.scroll_down()
1381 self.Thaw() 1253 self.Thaw()
1382 1254
1384 1256
1385 def PurgeChat(self): 1257 def PurgeChat(self):
1386 self.set_colors() 1258 self.set_colors()
1387 self.chatwnd.SetPage(self.chatwnd.Header()) 1259 self.chatwnd.SetPage(self.chatwnd.Header())
1388 1260
1389
1390 def system_message(self, text): 1261 def system_message(self, text):
1391 self.send_chat_message(text,chat_msg.SYSTEM_MESSAGE) 1262 self.send_chat_message(text,chat_msg.SYSTEM_MESSAGE)
1392 self.SystemPost(text) 1263 self.SystemPost(text)
1393 1264
1394
1395 def info_message(self, text): 1265 def info_message(self, text):
1396 self.send_chat_message(text,chat_msg.INFO_MESSAGE) 1266 self.send_chat_message(text,chat_msg.INFO_MESSAGE)
1397 self.InfoPost(text) 1267 self.InfoPost(text)
1398 1268
1399
1400 def get_gms(self): 1269 def get_gms(self):
1401 the_gms = [] 1270 the_gms = []
1402 for playerid in self.session.players: 1271 for playerid in self.session.players:
1403 if len(self.session.players[playerid])>7: 1272 if len(self.session.players[playerid])>7:
1404 if self.session.players[playerid][7]=="GM" and self.session.group_id != '0': the_gms += [playerid] 1273 if self.session.players[playerid][7]=="GM" and self.session.group_id != '0': the_gms += [playerid]
1405 return the_gms 1274 return the_gms
1406 1275
1407
1408 def GetName(self): 1276 def GetName(self):
1409 self.AliasLib = component.get('alias') 1277 self.AliasLib = component.get('alias')
1410 player = self.session.get_my_info() 1278 player = self.session.get_my_info()
1411 if self.AliasLib != None: 1279 if self.AliasLib != None:
1412 self.AliasLib.alias = self.aliasList.GetStringSelection(); 1280 self.AliasLib.alias = self.aliasList.GetStringSelection();
1413 if self.AliasLib.alias[0] != self.defaultAliasName: 1281 if self.AliasLib.alias[0] != self.defaultAliasName:
1414 logger.debug("Exit chat_panel->GetName(self)") 1282 logger.debug("Exit chat_panel->GetName(self)")
1415 return [self.chat_display_name([self.AliasLib.alias[0], player[1], player[2]]), self.AliasLib.alias[1]] 1283 return [self.chat_display_name([self.AliasLib.alias[0], player[1], player[2]]), self.AliasLib.alias[1]]
1416 return [self.chat_display_name(player), "Default"] 1284 return [self.chat_display_name(player), "Default"]
1417 1285
1418
1419 def GetFilteredText(self, text): 1286 def GetFilteredText(self, text):
1420 advregex = re.compile('\"(.*?)\"', re.I) 1287 advregex = re.compile('\"(.*?)\"', re.I)
1421 self.AliasLib = component.get('alias') 1288 self.AliasLib = component.get('alias')
1422 if self.AliasLib != None: 1289 if self.AliasLib != None:
1423 self.AliasLib.filter = self.filterList.GetSelection()-1; 1290 self.AliasLib.filter = self.filterList.GetSelection()-1;
1428 match = m.group(0) 1295 match = m.group(0)
1429 newmatch = re.sub(rule[0], rule[1], match) 1296 newmatch = re.sub(rule[0], rule[1], match)
1430 text = text.replace(match, newmatch) 1297 text = text.replace(match, newmatch)
1431 return text 1298 return text
1432 1299
1433
1434 def emote_message(self, text): 1300 def emote_message(self, text):
1435 text = self.NormalizeParse(text) 1301 text = self.NormalizeParse(text)
1436 text = self.colorize(self.emotecolor, text) 1302 text = self.colorize(self.emotecolor, text)
1437
1438 if self.type == MAIN_TAB and self.sendtarget == 'all': self.send_chat_message(text,chat_msg.EMOTE_MESSAGE) 1303 if self.type == MAIN_TAB and self.sendtarget == 'all': self.send_chat_message(text,chat_msg.EMOTE_MESSAGE)
1439 elif self.type == MAIN_TAB and self.sendtarget == "gm": 1304 elif self.type == MAIN_TAB and self.sendtarget == "gm":
1440 msg_type = chat_msg.WHISPER_EMOTE_MESSAGE 1305 msg_type = chat_msg.WHISPER_EMOTE_MESSAGE
1441 the_gms = self.get_gms() 1306 the_gms = self.get_gms()
1442 for each_gm in the_gms: self.send_chat_message(text,chat_msg.WHISPER_EMOTE_MESSAGE, str(each_gm)) 1307 for each_gm in the_gms: self.send_chat_message(text,chat_msg.WHISPER_EMOTE_MESSAGE, str(each_gm))
1447 elif self.type == NULL_TAB: pass 1312 elif self.type == NULL_TAB: pass
1448 name = self.GetName()[0] 1313 name = self.GetName()[0]
1449 text = "** " + name + " " + text + " **" 1314 text = "** " + name + " " + text + " **"
1450 self.EmotePost(text) 1315 self.EmotePost(text)
1451 1316
1452
1453 def whisper_to_players(self, text, player_ids): 1317 def whisper_to_players(self, text, player_ids):
1454 tabbed_whispers_p = self.settings.get_setting("tabbedwhispers") 1318 tabbed_whispers_p = self.settings.get_setting("tabbedwhispers")
1455 # Heroman - apply any filtering selected
1456 text = self.NormalizeParse(text) 1319 text = self.NormalizeParse(text)
1457 player_names = "" 1320 player_names = ""
1458 # post to our chat before we colorize
1459 for m in player_ids: 1321 for m in player_ids:
1460 id = m.strip() 1322 id = m.strip()
1461 if self.session.is_valid_id(id): 1323 if self.session.is_valid_id(id):
1462 returned_name = self.session.get_player_by_player_id(id)[0] 1324 returned_name = self.session.get_player_by_player_id(id)[0]
1463 player_names += returned_name 1325 player_names += returned_name
1467 player_names += ", " 1329 player_names += ", "
1468 comma = "," 1330 comma = ","
1469 comma.join(player_ids) 1331 comma.join(player_ids)
1470 if (self.sendtarget == "all"): 1332 if (self.sendtarget == "all"):
1471 self.InfoPost("<i>whispering to "+ player_names + " " + text + "</i> ") 1333 self.InfoPost("<i>whispering to "+ player_names + " " + text + "</i> ")
1472 # colorize and loop, sending whisper messages to all valid clients
1473 text = self.colorize(self.mytextcolor, text) 1334 text = self.colorize(self.mytextcolor, text)
1474 for id in player_ids: 1335 for id in player_ids:
1475 id = id.strip() 1336 id = id.strip()
1476 if self.session.is_valid_id(id): self.send_chat_message(text,chat_msg.WHISPER_MESSAGE,id) 1337 if self.session.is_valid_id(id): self.send_chat_message(text,chat_msg.WHISPER_MESSAGE,id)
1477 else: self.InfoPost(id + " Unknown!") 1338 else: self.InfoPost(id + " Unknown!")
1499 if turnedoff: self.settings.set_setting("ShowIDInChat", "1") 1360 if turnedoff: self.settings.set_setting("ShowIDInChat", "1")
1500 msg.set_alias(playername) 1361 msg.set_alias(playername)
1501 if send: self.session.send(msg.toxml(),player_id) 1362 if send: self.session.send(msg.toxml(),player_id)
1502 del msg 1363 del msg
1503 1364
1504 #### incoming chat message handler #####
1505
1506 def post_incoming_msg(self, msg, player): 1365 def post_incoming_msg(self, msg, player):
1507
1508 # pull data
1509 type = msg.get_type() 1366 type = msg.get_type()
1510 text = msg.get_text() 1367 text = msg.get_text()
1511 alias = msg.get_alias() 1368 alias = msg.get_alias()
1512 # who sent us the message? 1369 # who sent us the message?
1513 if alias: display_name = self.chat_display_name([alias, player[1], player[2]]) 1370 if alias: display_name = self.chat_display_name([alias, player[1], player[2]])
1520 try: text, type, name = plugin.plugin_incoming_msg(text, type, display_name, player) 1377 try: text, type, name = plugin.plugin_incoming_msg(text, type, display_name, player)
1521 except Exception, e: 1378 except Exception, e:
1522 if str(e) != "'module' object has no attribute 'receive_msg'": 1379 if str(e) != "'module' object has no attribute 'receive_msg'":
1523 logger.general(traceback.format_exc()) 1380 logger.general(traceback.format_exc())
1524 logger.general("EXCEPTION: " + str(e)) 1381 logger.general("EXCEPTION: " + str(e))
1525 #end mDuo13 added code
1526 #image stripping for players' names
1527 strip_img = self.settings.get_setting("Show_Images_In_Chat") 1382 strip_img = self.settings.get_setting("Show_Images_In_Chat")
1528 if (strip_img == "0"): display_name = chat_util.strip_img_tags(display_name) 1383 if (strip_img == "0"): display_name = chat_util.strip_img_tags(display_name)
1529 #end image stripping. --mDuo13, July 11th, 2005
1530 # default sound
1531 recvSound = "RecvSound" 1384 recvSound = "RecvSound"
1532 # act on the type of messsage 1385 # act on the type of messsage
1533 if (type == chat_msg.CHAT_MESSAGE): 1386 if (type == chat_msg.CHAT_MESSAGE):
1534 text = "<b>" + display_name + "</b>: " + text 1387 text = "<b>" + display_name + "</b>: " + text
1535 self.Post(text) 1388 self.Post(text)
1622 self.parent.newMsg(0) 1475 self.parent.newMsg(0)
1623 # playe sound 1476 # playe sound
1624 sound_file = self.settings.get_setting(recvSound) 1477 sound_file = self.settings.get_setting(recvSound)
1625 if sound_file != '': 1478 if sound_file != '':
1626 component.get('sound').play(sound_file) 1479 component.get('sound').play(sound_file)
1480
1627 #### Posting helpers ##### 1481 #### Posting helpers #####
1628 1482
1629
1630 def InfoPost(self, s): 1483 def InfoPost(self, s):
1631 self.Post(self.colorize(self.infocolor, s), c='info') 1484 self.Post(self.colorize(self.infocolor, s), c='info')
1632 1485
1633
1634 def SystemPost(self, s): 1486 def SystemPost(self, s):
1635 self.Post(self.colorize(self.syscolor, s), c='system') 1487 self.Post(self.colorize(self.syscolor, s), c='system')
1636 1488
1637
1638 def EmotePost(self, s): 1489 def EmotePost(self, s):
1639 self.Post(self.colorize(self.emotecolor, s), c='emote') 1490 self.Post(self.colorize(self.emotecolor, s), c='emote')
1640 1491
1641 #### Standard Post method ##### 1492 #### Standard Post method #####
1642 1493
1673 s = self.colorize(self.mytextcolor, s) 1524 s = self.colorize(self.mytextcolor, s)
1674 else: name = "" 1525 else: name = ""
1675 if aliasInfo[1] != 'Default': 1526 if aliasInfo[1] != 'Default':
1676 self.settings.set_setting("mytextcolor", defaultcolor) 1527 self.settings.set_setting("mytextcolor", defaultcolor)
1677 self.set_colors() 1528 self.set_colors()
1678 #following line based on sourceforge patch #880403 from mDuo
1679 # EDIT: Had to rework blank line check to handle malformed HTML throwing error.
1680 # this limits the effectiveness of this check -SD
1681 lineHasText = 1 1529 lineHasText = 1
1682 try: lineHasText = strip_html(s).replace("&nbsp;","").replace(" ","").strip()!="" 1530 try: lineHasText = strip_html(s).replace("&nbsp;","").replace(" ","").strip()!=""
1683 except: 1531 except:
1684 # HTML parser has errored out (most likely). Being as all we are doing is
1685 # scanning for empty/blank lines anyway there is no harm in letting a
1686 # troublesome message though. Worst case is a blank line to chat.
1687 lineHasText = 1 1532 lineHasText = 1
1688 if lineHasText: 1533 if lineHasText:
1689 #following added by mDuo13 1534 #following added by mDuo13
1690 if myself: 1535 if myself:
1691 s2 = s 1536 s2 = s
1729 elif self.type == WHISPER_TAB: self.whisper_to_players(s, [self.sendtarget]) 1574 elif self.type == WHISPER_TAB: self.whisper_to_players(s, [self.sendtarget])
1730 elif self.type == NULL_TAB: pass 1575 elif self.type == NULL_TAB: pass
1731 else: self.InfoPost("Failed to send message, unknown send type for this tab") 1576 else: self.InfoPost("Failed to send message, unknown send type for this tab")
1732 self.parsed=0 1577 self.parsed=0
1733 1578
1734 #
1735 # TimeIndexString()
1736 #
1737 # time indexing for chat display only (don't log time indexing)
1738 # added by Snowdog 4/04
1739
1740 def TimeIndexString(self): 1579 def TimeIndexString(self):
1741 try: 1580 try:
1742 mtime = "" 1581 mtime = ""
1743 if self.settings.get_setting('Chat_Time_Indexing') == "0": pass 1582 if self.settings.get_setting('Chat_Time_Indexing') == "0": pass
1744 elif self.settings.get_setting('Chat_Time_Indexing') == "1": 1583 elif self.settings.get_setting('Chat_Time_Indexing') == "1":
1852 dlg.Destroy() 1691 dlg.Destroy()
1853 return hexcolor 1692 return hexcolor
1854 else: 1693 else:
1855 dlg.Destroy() 1694 dlg.Destroy()
1856 return None 1695 return None
1696
1857 # def get_color - end 1697 # def get_color - end
1858
1859 def replace_quotes(self, s): 1698 def replace_quotes(self, s):
1860 in_tag = 0 1699 in_tag = 0
1861 i = 0 1700 i = 0
1862 rs = s[:] 1701 rs = s[:]
1863 for c in s: 1702 for c in s:
1940 ## Just replace the old tree_map from the index. 1779 ## Just replace the old tree_map from the index.
1941 new_map[index:len(new_map)] = parent_map 1780 new_map[index:len(new_map)] = parent_map
1942 newstr = '::'.join(new_map) 1781 newstr = '::'.join(new_map)
1943 newstr = '!@'+ newstr +'@!' 1782 newstr = '!@'+ newstr +'@!'
1944 s = s.replace(matches[i][0], newstr, 1) 1783 s = s.replace(matches[i][0], newstr, 1)
1945 #s = self.ParseMap(s, node) ## Needs to be added
1946 s = self.ParseNode(s) 1784 s = self.ParseNode(s)
1947 return s 1785 return s
1948 1786
1949 def resolve_nodes(self, s): 1787 def resolve_nodes(self, s):
1950 self.passed = False 1788 self.passed = False
2043 elif pc_stats.has_key(path[step].title()): 1881 elif pc_stats.has_key(path[step].title()):
2044 if step+1 == depth: self.data = pc_stats[path[step].title()][0] + ' +('+pc_stats[path[step].title()][1]+')' 1882 if step+1 == depth: self.data = pc_stats[path[step].title()][0] + ' +('+pc_stats[path[step].title()][1]+')'
2045 elif path[step+1].title() == 'Mod': self.data = pc_stats[path[step].title()][1] 1883 elif path[step+1].title() == 'Mod': self.data = pc_stats[path[step].title()][1]
2046 elif path[step+1].title() == 'Check': self.data = '<b>'+path[step].title()+' Check:</b> [1d20+'+str(pc_stats[path[step].title()][1])+']' 1884 elif path[step+1].title() == 'Check': self.data = '<b>'+path[step].title()+' Check:</b> [1d20+'+str(pc_stats[path[step].title()][1])+']'
2047 return 1885 return
1886