comparison orpg/chat/chatwnd.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 5aff3ef1ae46
comparison
equal deleted inserted replaced
-1:000000000000 0:4385a7d0efd1
1 # Copyright (C) 2000-2001 The OpenRPG Project
2 #
3 # openrpg-dev@lists.sourceforge.net
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 # --
19 #
20 # File: chatutils.py
21 # Author: Chris Davis
22 # Maintainer:
23 # Version:
24 # $Id: chatwnd.py,v 1.177 2007/12/07 20:39:48 digitalxero Exp $
25 #
26 # Description: This file contains some of the basic definitions for the chat
27 # utilities in the orpg project.
28 #
29 # History
30 # 2002-01-20 HeroMan
31 # + Added 4 dialog items on toolbar in support of Alias Library Functionallity
32 # + Shrunk the text view button to an image
33 # 2005-04-25 Snowdog
34 # + Added simple_html_repair() to post() to fix malformed html in the chat window
35 # + Added strip_script_tags() to post() to remove crash point. See chat_util.py
36 # 2005-04-25 Snowdog
37 # + Added simple_html_repair() to post() to fix malformed html in the chat window
38 #
39
40 __version__ = "$Id: chatwnd.py,v 1.177 2007/12/07 20:39:48 digitalxero Exp $"
41
42
43 ##
44 ## Module Loading
45 ##
46 from orpg.orpg_windows import *
47 from orpg.player_list import WG_LIST
48 import orpg.dirpath
49 import orpg.tools.rgbhex
50 import orpg.tools.inputValidator
51 from orpg.tools.metamenus import MenuEx
52 from orpg.orpgCore import open_rpg
53 import webbrowser
54 from string import *
55 from orpg.orpg_version import VERSION
56 import commands
57 import chat_msg
58 import time
59 import orpg.tools.predTextCtrl
60 from orpg.networking.mplay_client import MPLAY_CONNECTED # needed to only send typing/not_typing messages while connected
61 import os
62 import time
63 import re
64 import sys
65 import cStringIO # for reading inline imagedata as a stream
66 from HTMLParser import HTMLParser
67 import chat_util
68 import traceback
69 NEWCHAT = False
70 try:
71 import wx.webview
72 NEWCHAT = True
73 except:
74 pass
75 NEWCHAT = False
76
77 # Global parser for stripping HTML tags:
78 # The 'tag stripping' is implicit, because this parser echoes every
79 # type of html data *except* the tags.
80 class HTMLStripper(HTMLParser):
81 def __init__(self):
82 self.accum = ""
83 self.special_tags = ['hr', 'br', 'img']
84 def handle_data(self, data): # quote cdata literally
85 self.accum += data
86 def handle_entityref(self, name): # entities must be preserved exactly
87 self.accum += "&" + name + ";"
88 def handle_starttag(self, tag, attrs):
89 if tag in self.special_tags:
90 self.accum += '<' + tag
91 for attrib in attrs:
92 self.accum += ' ' + attrib[0] + '="' + attrib[1] + '"'
93 self.accum += '>'
94 def handle_charref(self, name): # charrefs too
95 self.accum += "&#" + name + ";"
96 htmlstripper = HTMLStripper()
97
98 # utility function; see Post().
99 def strip_html(string):
100 "Return string tripped of html tags."
101 htmlstripper.reset()
102 htmlstripper.accum = ""
103 htmlstripper.feed(string)
104 htmlstripper.close()
105 return htmlstripper.accum
106
107 def log( settings, text ):
108 filename = settings.get_setting('GameLogPrefix')
109 if filename > '' and filename[0] != commands.ANTI_LOG_CHAR:
110 filename = filename + time.strftime( '-%Y-%m-%d.html', time.localtime( time.time() ) )
111 #filename = time.strftime( filename, time.localtime( time.time() ) )
112 timestamp = time.ctime(time.time())
113 header = '[%s] : ' % ( timestamp );
114 if settings.get_setting('TimeStampGameLog') != '1':
115 header = ''
116 try:
117 f = open( orpg.dirpath.dir_struct["user"] + filename, 'a' )
118 f.write( '%s%s<br />\n' % ( header, text ) )
119 f.close()
120 except:
121 print "could not open " + orpg.dirpath.dir_struct["user"] + filename + ", ignoring..."
122 pass
123
124 # This class displayes the chat information in html?
125 #
126 # Defines:
127 # __init__(self, parent, id)
128 # OnLinkClicked(self, linkinfo)
129 # CalculateAllFonts(self, defaultsize)
130 # SetDefaultFontAndSize(self, fontname)
131 #
132 class chat_html_window(wx.html.HtmlWindow):
133 """ a wxHTMLwindow that will load links """
134 # initialization subroutine
135 #
136 # !self : instance of self
137 # !parent :
138 # !id :
139 def __init__(self, parent, id):
140 wx.html.HtmlWindow.__init__(self, parent, id, style=wx.SUNKEN_BORDER | wx.html.HW_SCROLLBAR_AUTO|wx.NO_FULL_REPAINT_ON_RESIZE)
141 self.parent = parent
142 self.build_menu()
143 self.Bind(wx.EVT_LEFT_UP, self.LeftUp)
144 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup)
145 if "gtk2" in wx.PlatformInfo:
146 self.SetStandardFonts()
147 # def __init__ - end
148
149 def onPopup(self, evt):
150 self.PopupMenu(self.menu)
151
152 def LeftUp(self, event):
153 event.Skip()
154 wx.CallAfter(self.parent.set_chat_text_focus, None)
155
156 def build_menu(self):
157 self.menu = wx.Menu()
158 item = wx.MenuItem(self.menu, wx.ID_ANY, "Copy", "Copy")
159 self.Bind(wx.EVT_MENU, self.OnM_EditCopy, item)
160 self.menu.AppendItem(item)
161
162 def OnM_EditCopy(self, evt):
163 wx.TheClipboard.Open()
164 wx.TheClipboard.Clear()
165 wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText()))
166 wx.TheClipboard.Close()
167
168 def scroll_down(self):
169 maxrange = self.GetScrollRange(wx.VERTICAL)
170 pagesize = self.GetScrollPageSize(wx.VERTICAL)
171 self.Scroll(-1, maxrange-pagesize)
172
173 def mouse_wheel(self, event):
174 amt = event.GetWheelRotation()
175 units = amt/(-(event.GetWheelDelta()))
176 self.ScrollLines(units*3)
177
178 def Header(self):
179 return '<html><body bgcolor="' + self.parent.bgcolor + '" text="' + self.parent.textcolor + '">'
180
181 def StripHeader(self):
182 return self.GetPageSource().replace(self.Header(), '')
183
184 def GetPageSource(self):
185 return self.GetParser().GetSource()
186
187 # This subroutine fires up the webbrowser when a link is clicked.
188 #
189 # !self : instance of self
190 # !linkinfo : instance of a class that contains the link information
191 def OnLinkClicked(self, linkinfo):
192 href = linkinfo.GetHref()
193 wb = webbrowser.get()
194 wb.open(href)
195 # def OnLinkClicked - end
196
197 def CalculateAllFonts(self, defaultsize):
198 return [int(defaultsize * 0.4),
199 int(defaultsize * 0.7),
200 int(defaultsize),
201 int(defaultsize * 1.3),
202 int(defaultsize * 1.7),
203 int(defaultsize * 2),
204 int(defaultsize * 2.5)]
205
206 def SetDefaultFontAndSize(self, fontname, fontsize):
207 """Set 'fontname' to the default chat font.
208 Returns current font settings in a (fontname, fontsize) tuple."""
209 self.SetFonts(fontname, "", self.CalculateAllFonts(int(fontsize)))
210 return (self.GetFont().GetFaceName(), self.GetFont().GetPointSize())
211
212 # class chat_html_window - end
213 if NEWCHAT:
214 class ChatHtmlWindow(wx.webview.WebView):
215 def __init__(self, parent, id):
216 wx.webview.WebView.__init__(self, parent, id)
217
218 self.parent = parent
219
220 self.__font = wx.Font(10, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, faceName='Ariel')
221
222 self.build_menu()
223 self.Bind(wx.EVT_LEFT_UP, self.LeftUp)
224 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup)
225 self.Bind(wx.webview.EVT_WEBVIEW_BEFORE_LOAD, self.OnLinkClicked)
226
227 #Wrapers so I dont have to add special Code
228 def SetPage(self, htmlstring):
229 self.SetPageSource(htmlstring)
230
231 def AppendToPage(self, htmlstring):
232 self.SetPageSource(self.GetPageSource() + htmlstring)
233
234 def GetFont(self):
235 return self.__font
236
237 def CalculateAllFonts(self, defaultsize):
238 return
239
240 def SetDefaultFontAndSize(self, fontname, fontsize):
241 self.__font = wx.Font(int(fontsize), wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, faceName=fontname)
242 try:
243 self.SetPageSource(self.Header() + self.StripHeader())
244 except Exception, e:
245 print e
246 return (self.GetFont().GetFaceName(), self.GetFont().GetPointSize())
247
248 #Events
249 def OnLinkClicked(self, linkinfo):
250 href = linkinfo.GetHref()
251 wb = webbrowser.get()
252 wb.open(href)
253
254 def onPopup(self, evt):
255 self.PopupMenu(self.menu)
256
257 def LeftUp(self, event):
258 event.Skip()
259 wx.CallAfter(self.parent.set_chat_text_focus, None)
260
261 def OnM_EditCopy(self, evt):
262 self.Copy()
263
264 #Cutom Methods
265 def Header(self):
266 return "<html><head><style>body {font-size: " + str(self.GetFont().GetPointSize()) + "px;font-family: " + self.GetFont().GetFaceName() + ";color: " + self.parent.textcolor + ";background-color: " + self.parent.bgcolor + ";margin: 0;padding: 0 0;height: 100%;}</style></head><body>"
267
268 def StripHeader(self):
269 tmp = self.GetPageSource().split('<BODY>')
270 if tmp[-1].find('<body>') > -1:
271 tmp = tmp[-1].split('<body>')
272
273 return tmp[-1]
274
275 def build_menu(self):
276 self.menu = wx.Menu()
277 item = wx.MenuItem(self.menu, wx.ID_ANY, "Copy", "Copy")
278 self.Bind(wx.EVT_MENU, self.OnM_EditCopy, item)
279 self.menu.AppendItem(item)
280
281 def scroll_down(self):
282 maxrange = self.GetScrollRange(wx.VERTICAL)
283 pagesize = self.GetScrollPageSize(wx.VERTICAL)
284 self.Scroll(-1, maxrange-pagesize)
285
286 def mouse_wheel(self, event):
287 amt = event.GetWheelRotation()
288 units = amt/(-(event.GetWheelDelta()))
289 self.ScrollLines(units*3)
290 chat_html_window = ChatHtmlWindow
291
292 #########################
293 #chat frame window
294 #########################
295 # These are kinda global...and static..and should be located somewhere else
296 # then the middle of a file between two classes.
297
298 ###################
299 # Tab Types
300 ###################
301 MAIN_TAB = wx.NewId()
302 WHISPER_TAB = wx.NewId()
303 GROUP_TAB = wx.NewId()
304 NULL_TAB = wx.NewId()
305
306 # This class defines the tabbed 'notebook' that holds multiple chatpanels.
307 # It's the widget attached to the main application frame.
308 #
309 # Inherits: wxNotebook
310 #
311 # Defines:
312 # create_private_tab(self, playerid)
313 # get_tab_index(self, chatpanel)
314 # destroy_private_tab(self, chatpanel)
315 # OnPageChanged(self, event)
316 # set_default_font(self, font, fontsize)
317
318 class chat_notebook(orpgTabberWnd):
319 def __init__(self, parent, size):
320 self.log = open_rpg.get_component("log")
321 self.log.log("Enter chat_notebook", ORPG_DEBUG)
322 orpgTabberWnd.__init__(self, parent, True, size=size, style=FNB.FNB_DROPDOWN_TABS_LIST|FNB.FNB_NO_NAV_BUTTONS|FNB.FNB_MOUSE_MIDDLE_CLOSES_TABS)
323 self.settings = open_rpg.get_component("settings")
324 self.whisper_tabs = []
325 self.group_tabs = []
326 self.null_tabs = []
327 self.il = wx.ImageList(16, 16)
328 bmp = wx.Bitmap(orpg.dirpath.dir_struct["icon"]+'player.gif')
329 self.il.Add(bmp)
330 bmp = wx.Bitmap(orpg.dirpath.dir_struct["icon"]+'clear.gif')
331 self.il.Add(bmp)
332 self.SetImageList(self.il)
333 # Create "main" chatpanel tab, undeletable, connected to 'public' room.
334 self.MainChatPanel = chat_panel(self, -1, MAIN_TAB, 'all')
335 self.AddPage(self.MainChatPanel, "Main Room")
336 self.SetPageImage(0, 1)
337 self.chat_timer = wx.Timer(self, wx.NewId())
338 self.Bind(wx.EVT_TIMER, self.MainChatPanel.typingTimerFunc)
339 self.chat_timer.Start(1000)
340 # Hook up event handler for flipping tabs
341 self.Bind(FNB.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.onPageChanged)
342 self.Bind(FNB.EVT_FLATNOTEBOOK_PAGE_CHANGING, self.onPageChanging)
343 self.Bind(FNB.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.onCloseTab)
344 # html font/fontsize is global to all the notebook tabs.
345 self.font, self.fontsize = self.MainChatPanel.chatwnd.SetDefaultFontAndSize(self.settings.get_setting('defaultfont'), self.settings.get_setting('defaultfontsize'))
346 self.GMChatPanel = None
347 if self.settings.get_setting("GMWhisperTab") == '1':
348 self.create_gm_tab()
349 self.SetSelection(0)
350 self.log.log("Exit chat_notebook", ORPG_DEBUG)
351
352 def get_tab_index(self, chatpanel):
353 "Return the index of a chatpanel in the wxNotebook."
354 self.log.log("Enter chat_notebook->get_tab_index(self, chatpanel)", ORPG_DEBUG)
355
356 for i in xrange(self.GetPageCount()):
357 if (self.GetPage(i) == chatpanel):
358 self.log.log("Exit chat_notebook->get_tab_index(self, chatpanel)", ORPG_DEBUG)
359 return i
360
361 def create_gm_tab(self):
362 self.log.log("Enter chat_notebook->create_gm_tab(self)", ORPG_DEBUG)
363 if self.GMChatPanel == None:
364 self.GMChatPanel = chat_panel(self, -1, MAIN_TAB, 'gm')
365 self.AddPage(self.GMChatPanel, "GM", False)
366 self.SetPageImage(self.GetPageCount()-1, 1)
367 self.GMChatPanel.chatwnd.SetDefaultFontAndSize(self.font, self.fontsize)
368 self.log.log("Exit chat_notebook->create_gm_tab(self)", ORPG_DEBUG)
369
370 def create_whisper_tab(self, playerid):
371 "Add a new chatpanel directly connected to integer 'playerid' via whispering."
372 self.log.log("Enter chat_notebook->create_whisper_tab(self," + str(playerid) +")", ORPG_DEBUG)
373 private_tab = chat_panel(self, -1, WHISPER_TAB, playerid)
374 playername = strip_html(self.MainChatPanel.session.get_player_by_player_id(playerid)[0])
375 self.AddPage(private_tab, playername, False)
376 private_tab.chatwnd.SetDefaultFontAndSize(self.font, self.fontsize)
377 self.whisper_tabs.append(private_tab)
378 self.newMsg(self.GetPageCount()-1)
379 self.AliasLib = open_rpg.get_component('alias')
380 wx.CallAfter(self.AliasLib.RefreshAliases)
381 self.log.log("Exit chat_notebook->create_whisper_tab(self, playerid)", ORPG_DEBUG)
382 return private_tab
383
384 def create_group_tab(self, group_name):
385 "Add a new chatpanel directly connected to integer 'playerid' via whispering."
386 self.log.log("Enter chat_notebook->create_group_tab(self, group_name)", ORPG_DEBUG)
387 private_tab = chat_panel(self, -1, GROUP_TAB, group_name)
388 self.AddPage(private_tab, group_name, False)
389 private_tab.chatwnd.SetDefaultFontAndSize(self.font, self.fontsize)
390 self.group_tabs.append(private_tab)
391 self.newMsg(self.GetPageCount()-1)
392 self.AliasLib = open_rpg.get_component('alias')
393 wx.CallAfter(self.AliasLib.RefreshAliases)
394 self.log.log("Exit chat_notebook->create_group_tab(self, group_name)", ORPG_DEBUG)
395 return private_tab
396
397 def create_null_tab(self, tab_name):
398 "Add a new chatpanel directly connected to integer 'playerid' via whispering."
399 self.log.log("Enter chat_notebook->create_null_tab(self, tab_name)", ORPG_DEBUG)
400 private_tab = chat_panel(self, -1, NULL_TAB, tab_name)
401 self.AddPage(private_tab, tab_name, False)
402 private_tab.chatwnd.SetDefaultFontAndSize(self.font, self.fontsize)
403 self.null_tabs.append(private_tab)
404 self.newMsg(self.GetPageCount()-1)
405 self.AliasLib = open_rpg.get_component('alias')
406 wx.CallAfter(self.AliasLib.RefreshAliases)
407 self.log.log("Exit chat_notebook->create_null_tab(self, tab_name)", ORPG_DEBUG)
408 return private_tab
409
410 def onCloseTab(self, evt):
411 self.log.log("Enter chat_notebook->onCloseTab(self, evt)", ORPG_DEBUG)
412 try:
413 tabid = evt.GetSelection()
414 except:
415 tabid = self.GetSelection()
416
417 if self.GetPageText(tabid) == 'Main Room':
418 #send no close error to chat
419 evt.Veto()
420 return
421 if self.GetPageText(tabid) == 'GM':
422 msg = "Are You Sure You Want To Close This Page?"
423 dlg = wx.MessageDialog(self, msg, "NotebookCtrl Question",
424 wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
425
426 if wx.Platform != '__WXMAC__':
427 dlg.SetFont(wx.Font(8, wx.NORMAL, wx.NORMAL, wx.NORMAL, False))
428
429 if dlg.ShowModal() in [wx.ID_NO]:
430 dlg.Destroy()
431 evt.Veto()
432 return
433 dlg.Destroy()
434 self.GMChatPanel = None
435 self.settings.set_setting("GMWhisperTab", "0")
436 panel = self.GetPage(tabid)
437 if panel in self.whisper_tabs:
438 self.whisper_tabs.remove(panel)
439 elif panel in self.group_tabs:
440 self.group_tabs.remove(panel)
441 elif panel in self.null_tabs:
442 self.null_tabs.remove(panel)
443 self.log.log("Exit chat_notebook->onCloseTab(self, evt)", ORPG_DEBUG)
444
445 def newMsg(self, tabid):
446 self.log.log("Enter chat_notebook->newMsg(self, tabid)", ORPG_DEBUG)
447 if tabid != self.GetSelection():
448 self.SetPageImage(tabid, 0)
449 self.log.log("Exit chat_notebook->newMsg(self, tabid)", ORPG_DEBUG)
450
451 def onPageChanging(self, event):
452 """When private chattabs are selected, set the bitmap back to 'normal'."""
453 self.log.log("Enter chat_notebook->onPageChanging(self, event)", ORPG_DEBUG)
454 event.Skip()
455 self.log.log("Exit chat_notebook->onPageChanging(self, event)", ORPG_DEBUG)
456
457 def onPageChanged(self, event):
458 """When private chattabs are selected, set the bitmap back to 'normal'."""
459 self.log.log("Enter chat_notebook->onPageChanged(self, event)", ORPG_DEBUG)
460 selected_idx = event.GetSelection()
461 self.SetPageImage(selected_idx, 1)
462 page = self.GetPage(selected_idx)
463 #wx.CallAfter(page.set_chat_text_focus, 0)
464 event.Skip()
465 self.log.log("Exit chat_notebook->onPageChanged(self, event)", ORPG_DEBUG)
466
467 # This class defines and builds the Chat Frame for OpenRPG
468 #
469 # Inherits: wxPanel
470 #
471 # Defines:
472 # __init__((self, parent, id, openrpg, sendtarget)
473 # build_ctrls(self)
474 # on_buffer_size(self,evt)
475 # set_colors(self)
476 # set_buffersize(self)
477 # set_chat_text(self,txt)
478 # OnChar(self,event)
479 # on_chat_save(self,evt)
480 # on_text_color(self,event)
481 # colorize(self, color, text)
482 # on_text_format(self,event)
483 # OnSize(self,event)
484 # scroll_down(self)
485 # InfoPost(self,s)
486 # Post(self,s="",send=False,myself=False)
487 # ParsePost(self,s,send=False,myself=False)
488 # ParseDice(self,s)
489 # ParseNodes(self,s)
490 # get_sha_checksum(self)
491 # get_color(self)
492 #
493
494 class chat_panel(wx.Panel):
495
496 # This is the initialization subroutine
497 #
498 # !self : instance of self
499 # !parent : parent that defines the chatframe
500 # !id :
501 # !openrpg :
502 # !sendtarget: who gets outbound messages: either 'all' or a playerid
503 def __init__(self, parent, id, tab_type, sendtarget):
504 self.log = open_rpg.get_component("log")
505 self.log.log("Enter chat_panel", ORPG_DEBUG)
506 wx.Panel.__init__(self, parent, id)
507 self.session = open_rpg.get_component('session')
508 self.settings = open_rpg.get_component('settings')
509 self.activeplugins = open_rpg.get_component('plugins')
510 self.parent = parent
511 # who receives outbound messages, either "all" or "playerid" string
512 self.sendtarget = sendtarget
513 self.type = tab_type
514 self.sound_player = open_rpg.get_component('sound')
515 # create die roller manager
516 self.DiceManager = open_rpg.get_component('DiceManager')
517 # create rpghex tool
518 self.r_h = orpg.tools.rgbhex.RGBHex()
519 self.h = 0
520 self.set_colors()
521 self.version = VERSION
522 self.histidx = -1
523 self.temptext = ""
524 self.history = []
525 self.storedata = []
526 #self.lasthistevt = None
527 self.parsed=0
528 #chat commands
529 self.lockscroll = False # set the default to scrolling on.
530 self.chat_cmds = commands.chat_commands(self)
531 self.html_strip = strip_html
532 #Alias Lib stuff
533 self.defaultAliasName = 'Use Real Name'
534 self.defaultFilterName = 'No Filter'
535 self.advancedFilter = False
536 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
538 self.Bind(wx.EVT_SIZE, self.OnSize)
539 self.build_ctrls()
540 #openrpg dir
541 self.root_dir = orpg.dirpath.dir_struct["home"]
542 # html font/fontsize is global to all the notebook tabs.
543 StartupFont = self.settings.get_setting("defaultfont")
544 StartupFontSize = self.settings.get_setting("defaultfontsize")
545 if(StartupFont != "") and (StartupFontSize != ""):
546 try:
547 self.set_default_font(StartupFont, int(StartupFontSize))
548 except:
549 pass
550 self.font = self.chatwnd.GetFont().GetFaceName()
551 self.fontsize = self.chatwnd.GetFont().GetPointSize()
552 self.scroll_down()
553 self.log.log("Exit chat_panel", ORPG_DEBUG)
554
555 def set_default_font(self, fontname=None, fontsize=None):
556 """Set all chatpanels to new default fontname/fontsize. Returns current font settings in a (fontname, fontsize) tuple."""
557 self.log.log("Enter chat_panel->set_default_font(self, fontname=None, fontsize=None)", ORPG_DEBUG)
558 if (fontname is not None):
559 newfont = fontname
560 else:
561 newfont = self.font
562 if (fontsize is not None):
563 newfontsize = int(fontsize)
564 else:
565 newfontsize = int(self.fontsize)
566 self.chatwnd.SetDefaultFontAndSize(newfont, newfontsize)
567 self.InfoPost("Font is now " + newfont + " point size " + `newfontsize`)
568 self.font = newfont
569 self.fontsize = newfontsize
570 self.log.log("Exit chat_panel->set_default_font(self, fontname=None, fontsize=None)", ORPG_DEBUG)
571 return (self.font, self.fontsize)
572
573 def build_menu(self):
574 self.log.log("Enter chat_panel->build_menu(self)", ORPG_DEBUG)
575 top_frame = open_rpg.get_component('frame')
576 menu = wx.Menu()
577 item = wx.MenuItem(menu, wx.ID_ANY, "&Background color", "Background color")
578 top_frame.Bind(wx.EVT_MENU, self.OnMB_BackgroundColor, item)
579 menu.AppendItem(item)
580 item = wx.MenuItem(menu, wx.ID_ANY, "&Text color", "Text color")
581 top_frame.Bind(wx.EVT_MENU, self.OnMB_TextColor, item)
582 menu.AppendItem(item)
583 menu.AppendSeparator()
584 item = wx.MenuItem(menu, wx.ID_ANY, "&Chat Focus\tCtrl-H", "Chat Focus")
585 self.setChatFocusMenu = item
586 top_frame.Bind(wx.EVT_MENU, self.set_chat_text_focus, item)
587 menu.AppendItem(item)
588 menu.AppendSeparator()
589 item = wx.MenuItem(menu, wx.ID_ANY, "Toggle &Scroll Lock", "Toggle Scroll Lock")
590 top_frame.Bind(wx.EVT_MENU, self.lock_scroll, item)
591 menu.AppendItem(item)
592 item = wx.MenuItem(menu, wx.ID_ANY, "Save Chat &Log", "Save Chat Log")
593 top_frame.Bind(wx.EVT_MENU, self.on_chat_save, item)
594 menu.AppendItem(item)
595 item = wx.MenuItem(menu, wx.ID_ANY, "Text &View", "Text View")
596 top_frame.Bind(wx.EVT_MENU, self.pop_textpop, item)
597 menu.AppendItem(item)
598 item = wx.MenuItem(menu, wx.ID_ANY, "Forward Tab\tCtrl+Tab", "Swap Tabs")
599 top_frame.Bind(wx.EVT_MENU, self.forward_tabs, item)
600 menu.AppendItem(item)
601 item = wx.MenuItem(menu, wx.ID_ANY, "Forward Tab\tCtrl+Shift+Tab", "Swap Tabs")
602 top_frame.Bind(wx.EVT_MENU, self.back_tabs, item)
603 menu.AppendItem(item)
604 menu.AppendSeparator()
605 settingmenu = wx.Menu()
606 wndmenu = wx.Menu()
607 tabmenu = wx.Menu()
608 toolmenu = wx.Menu()
609 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Show Images", "Show Images", wx.ITEM_CHECK)
610 top_frame.Bind(wx.EVT_MENU, self.OnMB_ShowImages, item)
611 wndmenu.AppendItem(item)
612 if self.settings.get_setting("Show_Images_In_Chat") == '1':
613 item.Check(True)
614 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Strip HTML", "Strip HTML", wx.ITEM_CHECK)
615 top_frame.Bind(wx.EVT_MENU, self.OnMB_StripHTML, item)
616 wndmenu.AppendItem(item)
617 if self.settings.get_setting("striphtml") == '1':
618 item.Check(True)
619 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Chat Time Index", "Chat Time Index", wx.ITEM_CHECK)
620 top_frame.Bind(wx.EVT_MENU, self.OnMB_ChatTimeIndex, item)
621 wndmenu.AppendItem(item)
622 if self.settings.get_setting("Chat_Time_Indexing") == '1':
623 item.Check(True)
624 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Chat Auto Complete", "Chat Auto Complete", wx.ITEM_CHECK)
625 top_frame.Bind(wx.EVT_MENU, self.OnMB_ChatAutoComplete, item)
626 wndmenu.AppendItem(item)
627 if self.settings.get_setting("SuppressChatAutoComplete") == '0':
628 item.Check(True)
629 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Show ID in Chat", "Show ID in Chat", wx.ITEM_CHECK)
630 top_frame.Bind(wx.EVT_MENU, self.OnMB_ShowIDinChat, item)
631 wndmenu.AppendItem(item)
632 if self.settings.get_setting("ShowIDInChat") == '1':
633 item.Check(True)
634 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Log Time Index", "Log Time Index", wx.ITEM_CHECK)
635 top_frame.Bind(wx.EVT_MENU, self.OnMB_LogTimeIndex, item)
636 wndmenu.AppendItem(item)
637 if self.settings.get_setting("TimeStampGameLog") == '1':
638 item.Check(True)
639 settingmenu.AppendMenu(wx.ID_ANY, 'Chat Window', wndmenu )
640 item = wx.MenuItem(tabmenu, wx.ID_ANY, "Tabbed Whispers", "Tabbed Whispers", wx.ITEM_CHECK)
641 top_frame.Bind(wx.EVT_MENU, self.OnMB_TabbedWhispers, item)
642 tabmenu.AppendItem(item)
643 if self.settings.get_setting("tabbedwhispers") == '1':
644 item.Check(True)
645 item = wx.MenuItem(tabmenu, wx.ID_ANY, "GM Tab", "GM Tab", wx.ITEM_CHECK)
646 top_frame.Bind(wx.EVT_MENU, self.OnMB_GMTab, item)
647 tabmenu.AppendItem(item)
648 if self.settings.get_setting("GMWhisperTab") == '1':
649 item.Check(True)
650 item = wx.MenuItem(tabmenu, wx.ID_ANY, "Group Whisper Tabs", "Group Whisper Tabs", wx.ITEM_CHECK)
651 top_frame.Bind(wx.EVT_MENU, self.OnMB_GroupWhisperTabs, item)
652 tabmenu.AppendItem(item)
653 if self.settings.get_setting("GroupWhisperTab") == '1':
654 item.Check(True)
655 settingmenu.AppendMenu(wx.ID_ANY, 'Chat Tabs', tabmenu)
656 item = wx.MenuItem(toolmenu, wx.ID_ANY, "Dice Bar", "Dice Bar", wx.ITEM_CHECK)
657 top_frame.Bind(wx.EVT_MENU, self.OnMB_DiceBar, item)
658 toolmenu.AppendItem(item)
659 if self.settings.get_setting("DiceButtons_On") == '1':
660 item.Check(True)
661 item = wx.MenuItem(toolmenu, wx.ID_ANY, "Format Buttons", "Format Buttons", wx.ITEM_CHECK)
662 top_frame.Bind(wx.EVT_MENU, self.OnMB_FormatButtons, item)
663 toolmenu.AppendItem(item)
664 if self.settings.get_setting("FormattingButtons_On") == '1':
665 item.Check(True)
666 item = wx.MenuItem(toolmenu, wx.ID_ANY, "Alias Tool", "Alias Tool", wx.ITEM_CHECK)
667 top_frame.Bind(wx.EVT_MENU, self.OnMB_AliasTool, item)
668 toolmenu.AppendItem(item)
669 if self.settings.get_setting("AliasTool_On") == '1':
670 item.Check(True)
671 settingmenu.AppendMenu(wx.ID_ANY, 'Chat Tool Bars', toolmenu)
672 menu.AppendMenu(wx.ID_ANY, 'Chat Settings', settingmenu)
673 top_frame.mainmenu.Insert(2, menu, '&Chat')
674 self.log.log("Exit chat_panel->build_menu(self)", ORPG_DEBUG)
675
676 ## Settings Menu Events
677 def OnMB_ShowImages(self, event):
678 self.log.log("Enter chat_panel->OnMB_ShowImages(self, event)", ORPG_DEBUG)
679 if event.IsChecked():
680 self.settings.set_setting("Show_Images_In_Chat", '1')
681 else:
682 self.settings.set_setting("Show_Images_In_Chat", '0')
683 self.log.log("Exit chat_panel->OnMB_ShowImages(self, event)", ORPG_DEBUG)
684
685 def OnMB_StripHTML(self, event):
686 self.log.log("Enter chat_panel->OnMB_StripHTML(self, event)", ORPG_DEBUG)
687 if event.IsChecked():
688 self.settings.set_setting("Sstriphtml", '1')
689 else:
690 self.settings.set_setting("striphtml", '0')
691 self.log.log("Exit chat_panel->OnMB_StripHTML(self, event)", ORPG_DEBUG)
692
693 def OnMB_ChatTimeIndex(self, event):
694 self.log.log("Enter chat_panel->OnMB_ChatTimeIndex(self, event)", ORPG_DEBUG)
695 if event.IsChecked():
696 self.settings.set_setting("Chat_Time_Indexing", '1')
697 else:
698 self.settings.set_setting("Chat_Time_Indexing", '0')
699 self.log.log("Exit chat_panel->OnMB_ChatTimeIndex(self, event)", ORPG_DEBUG)
700
701 def OnMB_ChatAutoComplete(self, event):
702 self.log.log("Enter chat_panel->OnMB_ChatAutoComplete(self, event)", ORPG_DEBUG)
703 if event.IsChecked():
704 self.settings.set_setting("SuppressChatAutoComplete", '0')
705 else:
706 self.settings.set_setting("SuppressChatAutoComplete", '1')
707 self.log.log("Exit chat_panel->OnMB_ChatAutoComplete(self, event)", ORPG_DEBUG)
708
709 def OnMB_ShowIDinChat(self, event):
710 self.log.log("Enter chat_panel->OnMB_ShowIDinChat(self, event)", ORPG_DEBUG)
711 if event.IsChecked():
712 self.settings.set_setting("ShowIDInChat", '1')
713 else:
714 self.settings.set_setting("ShowIDInChat", '0')
715 self.log.log("Exit chat_panel->OnMB_ShowIDinChat(self, event)", ORPG_DEBUG)
716
717 def OnMB_LogTimeIndex(self, event):
718 self.log.log("Enter chat_panel->OnMB_LogTimeIndex(self, event)", ORPG_DEBUG)
719 if event.IsChecked():
720 self.settings.set_setting("TimeStampGameLog", '1')
721 else:
722 self.settings.set_setting("TimeStampGameLog", '0')
723 self.log.log("Exit chat_panel->OnMB_LogTimeIndex(self, event)", ORPG_DEBUG)
724
725 def OnMB_TabbedWhispers(self, event):
726 self.log.log("Enter chat_panel->OnMB_TabbedWhispers(self, event)", ORPG_DEBUG)
727 if event.IsChecked():
728 self.settings.set_setting("tabbedwhispers", '1')
729 else:
730 self.settings.set_setting("tabbedwhispers", '0')
731 self.log.log("Exit chat_panel->OnMB_TabbedWhispers(self, event)", ORPG_DEBUG)
732
733 def OnMB_GMTab(self, event):
734 self.log.log("Enter chat_panel->OnMB_GMTab(self, event)", ORPG_DEBUG)
735 if event.IsChecked():
736 self.settings.set_setting("GMWhisperTab", '1')
737 self.parent.create_gm_tab()
738 else:
739 self.settings.set_setting("GMWhisperTab", '0')
740 self.log.log("Exit chat_panel->OnMB_GMTab(self, event)", ORPG_DEBUG)
741
742 def OnMB_GroupWhisperTabs(self, event):
743 self.log.log("Enter chat_panel->OnMB_GroupWhisperTabs(self, event)", ORPG_DEBUG)
744 if event.IsChecked():
745 self.settings.set_setting("GroupWhisperTab", '1')
746 else:
747 self.settings.set_setting("GroupWhisperTab", '0')
748 self.log.log("Exit chat_panel->OnMB_GroupWhisperTabs(self, event)", ORPG_DEBUG)
749
750
751 def OnMB_DiceBar(self, event):
752 self.log.log("Enter chat_panel->OnMB_DiceBar(self, event)", ORPG_DEBUG)
753 act = '0'
754 if event.IsChecked():
755 self.settings.set_setting("DiceButtons_On", '1')
756 act = '1'
757 else:
758 self.settings.set_setting("DiceButtons_On", '0')
759 self.toggle_dice(act)
760 try:
761 self.parent.GMChatPanel.toggle_dice(act)
762 except:
763 pass
764 for panel in self.parent.whisper_tabs:
765 panel.toggle_dice(act)
766 for panel in self.parent.group_tabs:
767 panel.toggle_dice(act)
768 for panel in self.parent.null_tabs:
769 panel.toggle_dice(act)
770 self.log.log("Exit chat_panel->OnMB_DiceBar(self, event)", ORPG_DEBUG)
771
772 def OnMB_FormatButtons(self, event):
773 self.log.log("Enter chat_panel->OnMB_FormatButtons(self, event)", ORPG_DEBUG)
774 act = '0'
775 if event.IsChecked():
776 self.settings.set_setting("FormattingButtons_On", '1')
777 act = '1'
778 else:
779 self.settings.set_setting("FormattingButtons_On", '0')
780 self.toggle_formating(act)
781 try:
782 self.parent.GMChatPanel.toggle_formating(act)
783 except:
784 pass
785 for panel in self.parent.whisper_tabs:
786 panel.toggle_formating(act)
787 for panel in self.parent.group_tabs:
788 panel.toggle_formating(act)
789 for panel in self.parent.null_tabs:
790 panel.toggle_formating(act)
791 self.log.log("Exit chat_panel->OnMB_FormatButtons(self, event)", ORPG_DEBUG)
792
793 def OnMB_AliasTool(self, event):
794 self.log.log("Enter chat_panel->OnMB_AliasTool(self, event)", ORPG_DEBUG)
795 act = '0'
796 if event.IsChecked():
797 self.settings.set_setting("AliasTool_On", '1')
798 act = '1'
799 else:
800 self.settings.set_setting("AliasTool_On", '0')
801 self.toggle_alias(act)
802 try:
803 self.parent.GMChatPanel.toggle_alias(act)
804 except:
805 pass
806 for panel in self.parent.whisper_tabs:
807 panel.toggle_alias(act)
808 for panel in self.parent.group_tabs:
809 panel.toggle_alias(act)
810 for panel in self.parent.null_tabs:
811 panel.toggle_alias(act)
812 self.log.log("Exit chat_panel->OnMB_AliasTool(self, event)", ORPG_DEBUG)
813
814 def OnMB_BackgroundColor(self, event):
815 self.log.log("Enter chat_panel->OnMB_BackgroundColor(self, event)", ORPG_DEBUG)
816 top_frame = open_rpg.get_component('frame')
817 hexcolor = self.get_color()
818 if hexcolor != None:
819 self.bgcolor = hexcolor
820 self.settings.set_setting('bgcolor', hexcolor)
821 self.chatwnd.SetPage(self.ResetPage())
822 if self.settings.get_setting('ColorTree') == '1':
823 top_frame.tree.SetBackgroundColour(self.settings.get_setting('bgcolor'))
824 top_frame.tree.Refresh()
825 top_frame.players.SetBackgroundColour(self.settings.get_setting('bgcolor'))
826 top_frame.players.Refresh()
827 else:
828 top_frame.tree.SetBackgroundColour('white')
829 top_frame.tree.SetForegroundColour('black')
830 top_frame.tree.Refresh()
831 top_frame.players.SetBackgroundColour('white')
832 top_frame.players.SetForegroundColour('black')
833 top_frame.players.Refresh()
834 self.chatwnd.scroll_down()
835 self.log.log("Exit chat_panel->OnMB_BackgroundColor(self, event)", ORPG_DEBUG)
836
837 def OnMB_TextColor(self, event):
838 self.log.log("Enter chat_panel->OnMB_TextColor(self, event)", ORPG_DEBUG)
839 top_frame = open_rpg.get_component('frame')
840 hexcolor = self.get_color()
841 if hexcolor != None:
842 self.textcolor = hexcolor
843 self.settings.set_setting('textcolor', hexcolor)
844 self.chatwnd.SetPage(self.ResetPage())
845 if self.settings.get_setting('ColorTree') == '1':
846 top_frame.tree.SetForegroundColour(self.settings.get_setting('textcolor'))
847 top_frame.tree.Refresh()
848 top_frame.players.SetForegroundColour(self.settings.get_setting('textcolor'))
849 top_frame.players.Refresh()
850 else:
851 top_frame.tree.SetBackgroundColour('white')
852 top_frame.tree.SetForegroundColour('black')
853 top_frame.tree.Refresh()
854 top_frame.players.SetBackgroundColour('white')
855 top_frame.players.SetForegroundColour('black')
856 top_frame.players.Refresh()
857 self.chatwnd.scroll_down()
858 self.log.log("Exit chat_panel->OnMB_TextColor(self, event)", ORPG_DEBUG)
859
860
861 def get_hot_keys(self):
862 self.log.log("Enter chat_panel->get_hot_keys(self)", ORPG_DEBUG)
863 # dummy menus for hotkeys
864 self.build_menu()
865 entries = []
866 entries.append((wx.ACCEL_CTRL, ord('H'), self.setChatFocusMenu.GetId()))
867 #entries.append((wx.ACCEL_CTRL, wx.WXK_TAB, SWAP_TABS))
868 self.log.log("Enter chat_panel->get_hot_keys(self)", ORPG_DEBUG)
869 return entries
870
871 def forward_tabs(self, evt):
872 self.log.log("Enter chat_panel->swap_tabs(self, evt)", ORPG_DEBUG)
873 self.parent.AdvanceSelection()
874 self.log.log("Exit chat_panel->swap_tabs(self, evt)", ORPG_DEBUG)
875
876 def back_tabs(self, evt):
877 self.log.log("Enter chat_panel->swap_tabs(self, evt)", ORPG_DEBUG)
878 self.parent.AdvanceSelection(False)
879 self.log.log("Exit chat_panel->swap_tabs(self, evt)", ORPG_DEBUG)
880
881 # This subroutine builds the controls for the chat frame
882 #
883 # !self : instance of self
884 def build_ctrls(self):
885 self.log.log("Enter chat_panel->build_ctrls(self)", ORPG_DEBUG)
886 self.chatwnd = chat_html_window(self,-1)
887 self.set_colors()
888 wx.CallAfter(self.chatwnd.SetPage, self.chatwnd.Header())
889 if (self.sendtarget == "all"):
890 wx.CallAfter(self.Post, self.colorize(self.syscolor, "<b>Welcome to <a href='http://www.openrpg.com'>OpenRPG</a> version " + self.version + "... </b>"))
891 #self.chat_cmds.on_help()
892 self.chattxt = orpg.tools.predTextCtrl.predTextCtrl(self, -1, "", style=wx.TE_PROCESS_ENTER | wx.TE_PROCESS_TAB,keyHook = self.myKeyHook, validator=None )
893 self.build_bar()
894 self.basesizer = wx.BoxSizer(wx.VERTICAL)
895 self.basesizer.Add( self.chatwnd,1,wx.EXPAND )
896 self.basesizer.Add( self.toolbar_sizer, 0, wx.EXPAND )
897 self.basesizer.Add( self.chattxt, 0, wx.EXPAND )
898 self.SetSizer(self.basesizer)
899 self.SetAutoLayout(True)
900 self.Fit()
901 #events
902 self.Bind(wx.EVT_BUTTON, self.on_text_format, self.boldButton)
903 self.Bind(wx.EVT_BUTTON, self.on_text_format, self.italicButton)
904 self.Bind(wx.EVT_BUTTON, self.on_text_format, self.underlineButton)
905 self.Bind(wx.EVT_BUTTON, self.on_text_color, self.color_button)
906 self.Bind(wx.EVT_BUTTON, self.on_chat_save, self.saveButton)
907 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d4Button)
908 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d6Button)
909 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d8Button)
910 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d10Button)
911 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d12Button)
912 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d20Button)
913 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d100Button)
914 self.dieIDs = {}
915 self.dieIDs[self.d4Button.GetId()] = 'd4'
916 self.dieIDs[self.d6Button.GetId()] = 'd6'
917 self.dieIDs[self.d8Button.GetId()] = 'd8'
918 self.dieIDs[self.d10Button.GetId()] = 'd10'
919 self.dieIDs[self.d12Button.GetId()] = 'd12'
920 self.dieIDs[self.d20Button.GetId()] = 'd20'
921 self.dieIDs[self.d100Button.GetId()] = 'd100'
922 self.Bind(wx.EVT_BUTTON, self.pop_textpop, self.textpop_lock)
923 self.Bind(wx.EVT_BUTTON, self.lock_scroll, self.scroll_lock)
924 self.chattxt.Bind(wx.EVT_MOUSEWHEEL, self.chatwnd.mouse_wheel)
925 self.chattxt.Bind(wx.EVT_CHAR, self.chattxt.OnChar)
926 self.chattxt.Bind(wx.EVT_TEXT_COPY, self.textCopy)
927 self.log.log("Exit chat_panel->build_ctrls(self)", ORPG_DEBUG)
928 # def build_ctrls - end
929
930 def textCopy(self, event):
931 if self.chattxt.GetStringSelection() == '':
932 self.chatwnd.OnM_EditCopy(None)
933 else:
934 self.chatwnd.Copy()
935
936 def build_bar(self):
937 self.log.log("Enter chat_panel->build_bar(self)", ORPG_DEBUG)
938 self.toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL)
939 self.scroll_lock = None
940 self.numDieText = None
941 self.dieModText = None
942 if self.settings.get_setting('Toolbar_On') == "1":
943 self.build_alias()
944 self.build_dice()
945 self.build_scroll()
946 self.build_text()
947 self.toolbar_sizer.Add( self.textpop_lock, 0, wx.EXPAND )
948 self.toolbar_sizer.Add(self.scroll_lock,0,wx.EXPAND)
949 self.build_formating()
950 self.build_colorbutton()
951 self.log.log("Exit chat_panel->build_bar(self)", ORPG_DEBUG)
952
953 def build_scroll(self):
954 self.log.log("Enter chat_panel->build_scroll(self)", ORPG_DEBUG)
955 self.scroll_lock = wx.Button( self, wx.ID_ANY, "Scroll ON",size= wx.Size(80,25))
956 self.log.log("Exit chat_panel->build_scroll(self)", ORPG_DEBUG)
957
958 def build_alias(self):
959 self.log.log("Enter chat_panel->build_alias(self)", ORPG_DEBUG)
960 self.aliasList = wx.Choice(self, wx.ID_ANY, size=(100, 25), choices=[self.defaultAliasName])
961 self.aliasButton = createMaskedButton( self, orpg.dirpath.dir_struct["icon"] + 'player.gif', 'Refresh list of aliases from Game Tree', wx.ID_ANY, '#bdbdbd' )
962 self.aliasList.SetSelection(0)
963 self.filterList = wx.Choice(self, wx.ID_ANY, size=(100, 25), choices=[self.defaultFilterName])
964 self.filterButton = createMaskedButton( self, orpg.dirpath.dir_struct["icon"] + 'add_filter.gif', 'Refresh list of filters from Game Tree', wx.ID_ANY, '#bdbdbd' )
965 self.filterList.SetSelection(0)
966 self.toolbar_sizer.Add( self.aliasButton, 0, wx.EXPAND )
967 self.toolbar_sizer.Add( self.aliasList,0,wx.EXPAND)
968 self.toolbar_sizer.Add( self.filterButton, 0, wx.EXPAND )
969 self.toolbar_sizer.Add( self.filterList,0,wx.EXPAND)
970 if self.settings.get_setting('AliasTool_On') == '0':
971 self.toggle_alias('0')
972 else:
973 self.toggle_alias('1')
974 self.log.log("Exit chat_panel->build_alias(self)", ORPG_DEBUG)
975
976 def toggle_alias(self, act):
977 self.log.log("Enter chat_panel->toggle_alias(self, " + str(act) + ")", ORPG_DEBUG)
978 if act == '0':
979 self.toolbar_sizer.Show(self.aliasList, False)
980 self.toolbar_sizer.Show(self.filterList, False)
981 self.toolbar_sizer.Show(self.aliasButton, False)
982 self.toolbar_sizer.Show(self.filterButton, False)
983 self.toolbar_sizer.Layout()
984 else:
985 self.toolbar_sizer.Show(self.aliasList, True)
986 self.toolbar_sizer.Show(self.filterList, True)
987 self.toolbar_sizer.Show(self.aliasButton, True)
988 self.toolbar_sizer.Show(self.filterButton, True)
989 self.toolbar_sizer.Layout()
990 self.log.log("Exit chat_panel->toggle_alias(self, act)", ORPG_DEBUG)
991
992 def build_text(self):
993 self.log.log("Enter chat_panel->build_text(self)", ORPG_DEBUG)
994 self.textpop_lock = createMaskedButton(self, orpg.dirpath.dir_struct["icon"]+'note.gif', 'Open Text View Of Chat Session', wx.ID_ANY, '#bdbdbd')
995 self.log.log("Exit chat_panel->build_text(self)", ORPG_DEBUG)
996
997 def build_dice(self):
998 self.log.log("Enter chat_panel->build_dice(self)", ORPG_DEBUG)
999 self.numDieText = wx.TextCtrl( self, wx.ID_ANY, "1", size= wx.Size(25, 25), validator=orpg.tools.inputValidator.MathOnlyValidator() )
1000 self.dieModText = wx.TextCtrl( self, wx.ID_ANY, "", size= wx.Size(50, 25), validator=orpg.tools.inputValidator.MathOnlyValidator() )
1001 self.d4Button = createMaskedButton(self, orpg.dirpath.dir_struct["icon"]+'b_d4.gif', 'Roll d4', wx.ID_ANY, '#bdbdbd')
1002 self.d6Button = createMaskedButton(self, orpg.dirpath.dir_struct["icon"]+'b_d6.gif', 'Roll d6', wx.ID_ANY, '#bdbdbd')
1003 self.d8Button = createMaskedButton(self, orpg.dirpath.dir_struct["icon"]+'b_d8.gif', 'Roll d8', wx.ID_ANY, '#bdbdbd')
1004 self.d10Button = createMaskedButton(self, orpg.dirpath.dir_struct["icon"]+'b_d10.gif', 'Roll d10', wx.ID_ANY, '#bdbdbd')
1005 self.d12Button = createMaskedButton(self, orpg.dirpath.dir_struct["icon"]+'b_d12.gif', 'Roll d12', wx.ID_ANY, '#bdbdbd')
1006 self.d20Button = createMaskedButton(self, orpg.dirpath.dir_struct["icon"]+'b_d20.gif', 'Roll d20', wx.ID_ANY, '#bdbdbd')
1007 self.d100Button = createMaskedButton(self, orpg.dirpath.dir_struct["icon"]+'b_d100.gif', 'Roll d100', wx.ID_ANY, '#bdbdbd')
1008 self.toolbar_sizer.Add( self.numDieText, 0, wx.ALIGN_CENTER | wx.EXPAND)
1009 self.toolbar_sizer.Add( self.d4Button, 0 ,wx.EXPAND)
1010 self.toolbar_sizer.Add( self.d6Button, 0 ,wx.EXPAND)
1011 self.toolbar_sizer.Add( self.d8Button, 0 ,wx.EXPAND)
1012 self.toolbar_sizer.Add( self.d10Button, 0 ,wx.EXPAND)
1013 self.toolbar_sizer.Add( self.d12Button, 0 ,wx.EXPAND)
1014 self.toolbar_sizer.Add( self.d20Button, 0 ,wx.EXPAND)
1015 self.toolbar_sizer.Add( self.d100Button, 0 ,wx.EXPAND)
1016 self.toolbar_sizer.Add( self.dieModText, 0, wx.ALIGN_CENTER, 5 )
1017 if self.settings.get_setting('DiceButtons_On') == '0':
1018 self.toggle_dice('0')
1019 else:
1020 self.toggle_dice('1')
1021 self.log.log("Exit chat_panel->build_dice(self)", ORPG_DEBUG)
1022
1023 def toggle_dice(self, act):
1024 self.log.log("Enter chat_panel->toggle_dice(self, "+ str(act) + ")", ORPG_DEBUG)
1025 if act == '0':
1026 self.toolbar_sizer.Show(self.numDieText, False)
1027 self.toolbar_sizer.Show(self.d4Button, False)
1028 self.toolbar_sizer.Show(self.d6Button, False)
1029 self.toolbar_sizer.Show(self.d8Button, False)
1030 self.toolbar_sizer.Show(self.d10Button, False)
1031 self.toolbar_sizer.Show(self.d12Button, False)
1032 self.toolbar_sizer.Show(self.d20Button, False)
1033 self.toolbar_sizer.Show(self.d100Button, False)
1034 self.toolbar_sizer.Show(self.dieModText, False)
1035 self.toolbar_sizer.Layout()
1036 else:
1037 self.toolbar_sizer.Show(self.numDieText, True)
1038 self.toolbar_sizer.Show(self.d4Button, True)
1039 self.toolbar_sizer.Show(self.d6Button, True)
1040 self.toolbar_sizer.Show(self.d8Button, True)
1041 self.toolbar_sizer.Show(self.d10Button, True)
1042 self.toolbar_sizer.Show(self.d12Button, True)
1043 self.toolbar_sizer.Show(self.d20Button, True)
1044 self.toolbar_sizer.Show(self.d100Button, True)
1045 self.toolbar_sizer.Show(self.dieModText, True)
1046 self.toolbar_sizer.Layout()
1047 self.log.log("Exit chat_panel->toggle_dice(self, "+ str(act) + ")", ORPG_DEBUG)
1048
1049 def build_formating(self):
1050 self.log.log("Enter chat_panel->build_formating(self)", ORPG_DEBUG)
1051 self.boldButton = createMaskedButton( self, orpg.dirpath.dir_struct["icon"]+'bold.gif', 'Make the selected text Bold', wx.ID_ANY, '#bdbdbd')
1052 self.italicButton = createMaskedButton( self, orpg.dirpath.dir_struct["icon"]+'italic.gif', 'Italicize the selected text', wx.ID_ANY, '#bdbdbd' )
1053 self.underlineButton = createMaskedButton( self, orpg.dirpath.dir_struct["icon"]+'underlined.gif', 'Underline the selected text', wx.ID_ANY, '#bdbdbd' )
1054 self.toolbar_sizer.Add( self.boldButton, 0, wx.EXPAND )
1055 self.toolbar_sizer.Add( self.italicButton, 0, wx.EXPAND )
1056 self.toolbar_sizer.Add( self.underlineButton, 0, wx.EXPAND )
1057 if self.settings.get_setting('FormattingButtons_On') == '0':
1058 self.toggle_formating('0')
1059 else:
1060 self.toggle_formating('1')
1061 self.log.log("Exit chat_panel->build_formating(self)", ORPG_DEBUG)
1062
1063 def toggle_formating(self, act):
1064 self.log.log("Enter chat_panel->toggle_formating(self, " + str(act) + ")", ORPG_DEBUG)
1065 if act == '0':
1066 self.toolbar_sizer.Show(self.boldButton, False)
1067 self.toolbar_sizer.Show(self.italicButton, False)
1068 self.toolbar_sizer.Show(self.underlineButton, False)
1069 self.toolbar_sizer.Layout()
1070 else:
1071 self.toolbar_sizer.Show(self.boldButton, True)
1072 self.toolbar_sizer.Show(self.italicButton, True)
1073 self.toolbar_sizer.Show(self.underlineButton, True)
1074 self.toolbar_sizer.Layout()
1075 self.log.log("Exit chat_panel->toggle_formating(self, " + str(act) + ")", ORPG_DEBUG)
1076
1077 # Heroman - Ideally, we would use static labels...
1078 def build_colorbutton(self):
1079 self.log.log("Enter chat_panel->build_colorbutton(self)", ORPG_DEBUG)
1080 self.color_button = wx.Button(self, wx.ID_ANY, "C",wx.Point(0,0), wx.Size(22,0))
1081 self.saveButton = createMaskedButton( self, orpg.dirpath.dir_struct["icon"]+'save.bmp', 'Save the chatbuffer', wx.ID_ANY, '#c0c0c0', wx.BITMAP_TYPE_BMP )
1082 self.color_button.SetBackgroundColour(wx.BLACK)
1083 self.color_button.SetForegroundColour(wx.WHITE)
1084 self.toolbar_sizer.Add(self.color_button, 0, wx.EXPAND)
1085 self.toolbar_sizer.Add( self.saveButton, 0, wx.EXPAND )
1086 self.log.log("Exit chat_panel->build_colorbutton(self)", ORPG_DEBUG)
1087
1088 def OnMotion(self, evt):
1089 self.log.log("Enter chat_panel->OnMotion(self, evt)", ORPG_DEBUG)
1090 contain = self.chatwnd.GetInternalRepresentation()
1091 if contain:
1092 sx = sy = 0
1093 x = y = 0
1094 (sx,sy) = self.chatwnd.GetViewStart()
1095 (sx1,sy1) = self.chatwnd.GetScrollPixelsPerUnit()
1096 sx = sx*sx1
1097 sy = sy*sy1
1098 (x,y) = evt.GetPosition()
1099 lnk = contain.GetLink(sx+x,sy+y)
1100 if lnk:
1101 try:
1102 link = lnk.GetHref()
1103 self.session.set_status_url(link)
1104 except:
1105 pass
1106 else:
1107 self.log.log("Error, self.chatwnd.GetInternalRepresentation() return None", ORPG_GENERAL)
1108 evt.Skip()
1109 self.log.log("Exit chat_panel->OnMotion(self, evt)", ORPG_DEBUG)
1110
1111 # This subroutine is registered with predTextCtrl to be run for every OnChar event
1112 # It checks if we need to send a typing message
1113
1114 #
1115 # self: duh
1116 # event: raw KeyEvent from OnChar()
1117 def myKeyHook(self, event):
1118 self.log.log("Enter chat_panel->myKeyHook(self, event)", ORPG_DEBUG)
1119 if self.session.get_status() == MPLAY_CONNECTED: # only do if we're connected
1120 thisPress = time.time() # thisPress is local temp variable
1121 if (thisPress - self.lastSend) > 4: # Check to see if it's been 5 seconds since our last notice
1122 # If we're not already typing, then self.lastSend will be 0
1123 self.sendTyping(1) # send a not typing event here (1 for True)
1124 self.lastPress = thisPress # either way, record the time of this keystroke for use in
1125 # self.typingTimerFunc()
1126 if self.settings.get_setting('SuppressChatAutoComplete') == '1':
1127 self.log.log("Exit chat_panel->myKeyHook(self, event) return 1", ORPG_DEBUG)
1128 return 1
1129 else:
1130 self.log.log("Exit chat_panel->myKeyHook(self, event) return 0", ORPG_DEBUG)
1131 return 0
1132
1133 # This subroutine gets called once a second by the typing Timer
1134 # It checks if we need to send a not_typing message
1135 #
1136 # self: duh
1137 def typingTimerFunc(self, event):
1138 #following added by mDuo13
1139 ##############refresh_counter()##############
1140 for plugin_fname in self.activeplugins.keys():
1141 plugin = self.activeplugins[plugin_fname]
1142 try:
1143 plugin.refresh_counter()
1144 except Exception, e:
1145 if str(e) != "'module' object has no attribute 'refresh_counter'":
1146 self.log.log(traceback.format_exc(), ORPG_GENERAL)
1147 self.log.log("EXCEPTION: " + str(e), ORPG_GENERAL)
1148 #end mDuo13 added code
1149 if self.lastSend: # This will be zero when not typing, so equiv to if is_typing
1150 thisTime = time.time() # thisTime is a local temp variable
1151 if (thisTime - self.lastPress) > 4: # Check to see if it's been 5 seconds since our last keystroke
1152 # If we're not already typing, then self.lastSend will be 0
1153
1154 self.sendTyping(0) # send a typing event here (0 for False)
1155 # This subroutine actually takes care of sending the messages for typing/not_typing events
1156 #
1157 # self: duh
1158 # typing: boolean
1159 def sendTyping(self, typing):
1160 self.log.log("Enter chat_panel->sendTyping(self, typing)", ORPG_DEBUG)
1161 if typing:
1162 self.lastSend = time.time() # remember our send time for use in myKeyHook()
1163 #I think this is cleaner
1164 status_text = self.settings.get_setting('TypingStatusAlias')
1165 if status_text == "" or status_text == None:
1166 status_text = "Typing"
1167 self.session.set_text_status(status_text)
1168 else:
1169 self.lastSend = 0 # set lastSend to zero to indicate we're not typing
1170 #I think this is cleaner
1171 status_text = self.settings.get_setting('IdleStatusAlias')
1172 if status_text == "" or status_text == None:
1173 status_text = "Idle"
1174 self.session.set_text_status(status_text)
1175 self.log.log("Exit chat_panel->sendTyping(self, typing)", ORPG_DEBUG)
1176
1177 # This subroutine sets the colors of the chat based on the settings in the
1178 # self instance.
1179 #
1180 # !self : instance of self
1181 def set_colors(self):
1182 self.log.log("Enter chat_panel->set_colors(self)", ORPG_DEBUG)
1183 # chat window backround color
1184 self.bgcolor = self.settings.get_setting('bgcolor')
1185 # chat window normal text color
1186 self.textcolor = self.settings.get_setting('textcolor')
1187 # color of text player types
1188 self.mytextcolor = self.settings.get_setting('mytextcolor')
1189 # color of system warnings
1190 self.syscolor = self.settings.get_setting('syscolor')
1191 # color of system info messages
1192 self.infocolor = self.settings.get_setting('infocolor')
1193 # color of emotes
1194 self.emotecolor = self.settings.get_setting('emotecolor')
1195 # color of whispers
1196 self.whispercolor = self.settings.get_setting('whispercolor')
1197 self.log.log("Exit chat_panel->set_colors(self)", ORPG_DEBUG)
1198 # def set_colors - end
1199
1200 # This subroutine will insert text into the chat window
1201 #
1202 # !self : instance of self
1203 # !txt : text to be inserted into the chat window
1204 def set_chat_text(self, txt):
1205 self.log.log("Enter chat_panel->set_chat_text(self, txt)", ORPG_DEBUG)
1206 self.chattxt.SetValue(txt)
1207 self.chattxt.SetFocus()
1208 self.chattxt.SetInsertionPointEnd()
1209 self.log.log("Exit chat_panel->set_chat_text(self, txt)", ORPG_DEBUG)
1210 # def set_chat_text - end
1211
1212 def get_chat_text(self):
1213 self.log.log("Enter chat_panel->get_chat_text(self)", ORPG_DEBUG)
1214 self.log.log("Enter chat_panel->get_chat_text(self)", ORPG_DEBUG)
1215 return self.chattxt.GetValue()
1216
1217 # This subroutine sets the focus to the chat window
1218 def set_chat_text_focus(self, event):
1219 self.log.log("Enter chat_panel->set_chat_text_focus(self, event)", ORPG_DEBUG)
1220 wx.CallAfter(self.chattxt.SetFocus)
1221 self.log.log("Exit chat_panel->set_chat_text_focus(self, event)", ORPG_DEBUG)
1222 # def set_chat_text_focus - end
1223
1224 # This subrtouine grabs the user input and make the special keys and
1225 # modifiers work.
1226 #
1227 # !self : instance of self
1228 # !event :
1229 #
1230 # Note: self.chattxt now handles it's own Key events. It does, however still
1231 # call it's parent's (self) OnChar to handle "default" behavior.
1232 def OnChar(self, event):
1233 self.log.log("Enter chat_panel->OnChar(self, event)", ORPG_DEBUG)
1234 s = self.chattxt.GetValue()
1235 #self.histlen = len(self.history) - 1
1236
1237 ## RETURN KEY (no matter if there is text in chattxt)
1238 # This section is run even if there is nothing in the chattxt (as opposed to the next wx.WXK_RETURN handler
1239 if event.GetKeyCode() == wx.WXK_RETURN:
1240 self.log.log("event.GetKeyCode() == wx.WXK_RETURN", ORPG_DEBUG)
1241 self.set_colors()
1242 if self.session.get_status() == MPLAY_CONNECTED: # only do if we're connected
1243 self.sendTyping(0) # Send a "not_typing" event on enter key press
1244 macroText=""
1245
1246
1247 recycle_bin = {wx.WXK_F1: 'event.GetKeyCode() == wx.WXK_F1', wx.WXK_F2: 'event.GetKeyCode() == wx.WXK_F2', wx.WXK_F3: 'event.GetKeyCode() == wx.WXK_F3', wx.WXK_F4: 'event.GetKeyCode() == wx.WXK_F4', wx.WXK_F5: 'event.GetKeyCode() == wx.WXK_F5', wx.WXK_F6: 'event.GetKeyCode() == wx.WXK_F6', wx.WXK_F7: 'event.GetKeyCode() == wx.WXK_F7', wx.WXK_F8: 'event.GetKeyCode() == wx.WXK_F8', wx.WXK_F9: 'event.GetKeyCode() == wx.WXK_F9', wx.WXK_F10: 'event.GetKeyCode() == wx.WXK_F10', wx.WXK_F11: 'event.GetKeyCode() == wx.WXK_F11', wx.WXK_F12: 'event.GetKeyCode() == wx.WXK_F12'}
1248 # Recycle Bin and Lambda should reduce this whole IF ELIF statement block.
1249 bin_event = event.GetKeyCode()
1250 if recycle_bin.has_key(bin_event):
1251 self.log.log(lambda bin_event: recycle_bin[bin_event], ORPG_DEBUG)
1252 macroText = self.settings.get_setting(recycle_bin[bin_event][29:])
1253 recycle_bin = {}; del bin_event
1254
1255 # Append to the existing typed text as needed and make sure the status doesn't change back.
1256 if len(macroText):
1257 self.sendTyping(0)
1258 s = macroText
1259
1260 ## RETURN KEY (and not text in control)
1261 if (event.GetKeyCode() == wx.WXK_RETURN and len(s)) or len(macroText):
1262 self.log.log("(event.GetKeyCode() == wx.WXK_RETURN and len(s)) or len(macroText)", ORPG_DEBUG)
1263 self.histidx = -1
1264 self.temptext = ""
1265 self.history = [s] + self.history#prepended instead of appended now, so higher index = greater age
1266 if not len(macroText):
1267 self.chattxt.SetValue("")
1268 # play sound
1269 sound_file = self.settings.get_setting("SendSound")
1270 if sound_file != '':
1271 self.sound_player.play(sound_file)
1272 if s[0] != "/": ## it's not a slash command
1273 s = self.ParsePost( s, True, True )
1274 else:
1275 self.chat_cmds.docmd(s) # emote is in chatutils.py
1276
1277 ## UP KEY
1278 elif event.GetKeyCode() == wx.WXK_UP:
1279 self.log.log("event.GetKeyCode() == wx.WXK_UP", ORPG_DEBUG)
1280 if self.histidx < len(self.history)-1:
1281 #text that's not in history but also hasn't been sent to chat gets stored in self.temptext
1282 #this way if someone presses the up key, they don't lose their current message permanently
1283 #(unless they also press enter at the time)
1284 if self.histidx is -1:
1285 self.temptext = self.chattxt.GetValue()
1286 self.histidx += 1
1287 self.chattxt.SetValue(self.history[self.histidx])
1288 self.chattxt.SetInsertionPointEnd()
1289 else:
1290 self.histidx = len(self.history) -1#in case it got too high somehow, this should fix it
1291 #self.InfoPost("**Going up? I don't think so.**")
1292 #print self.histidx, "in",self.history
1293
1294 ## DOWN KEY
1295 elif event.GetKeyCode() == wx.WXK_DOWN:
1296 self.log.log("event.GetKeyCode() == wx.WXK_DOWN", ORPG_DEBUG)
1297 #histidx of -1 indicates currently viewing text that's not in self.history
1298 if self.histidx > -1:
1299 self.histidx -= 1
1300 if self.histidx is -1: #remember, it just decreased
1301 self.chattxt.SetValue(self.temptext)
1302 else:
1303 self.chattxt.SetValue(self.history[self.histidx])
1304 self.chattxt.SetInsertionPointEnd()
1305 else:
1306 self.histidx = -1 #just in case it somehow got below -1, this should fix it
1307 #self.InfoPost("**Going down? I don't think so.**")
1308 #print self.histidx, "in",self.history
1309
1310 ## TAB KEY
1311 elif event.GetKeyCode() == wx.WXK_TAB:
1312 self.log.log("event.GetKeyCode() == wx.WXK_TAB", ORPG_DEBUG)
1313 if s !="":
1314 found = 0
1315 nicks = []
1316 testnick = ""
1317 inlength = len(s)
1318 for getnames in self.session.players.keys():
1319 striphtmltag = re.compile ('<[^>]+>*')
1320 testnick = striphtmltag.sub ("", self.session.players[getnames][0])
1321 if string.lower(s) == string.lower(testnick[:inlength]):
1322 found = found + 1
1323 nicks[len(nicks):]=[testnick]
1324 if found == 0: ## no nick match
1325 self.Post(self.colorize(self.syscolor," ** No match found"))
1326 elif found > 1: ## matched more than 1, tell user what matched
1327 nickstring = ""
1328 nicklist = []
1329 for foundnicks in nicks:
1330 nickstring = nickstring + foundnicks + ", "
1331 nicklist.append(foundnicks)
1332 nickstring = nickstring[:-2]
1333 self.Post(self.colorize(self.syscolor, " ** Multiple matches found: " + nickstring))
1334 # set text to the prefix match between first two matches
1335 settext = re.match(''.join(map(lambda x: '(%s?)' % x, string.lower(nicklist[0]))), string.lower(nicklist[1])).group()
1336 # run through the rest of the nicks
1337 for i in nicklist:
1338 settext = re.match(''.join(map(lambda x: '(%s?)' % x, string.lower(i))), string.lower(settext)).group()
1339 if settext:
1340 self.chattxt.SetValue(settext)
1341 self.chattxt.SetInsertionPointEnd()
1342 else: ## put the matched name in the chattxt box
1343 settext = nicks[0] + ": "
1344 self.chattxt.SetValue(settext)
1345 self.chattxt.SetInsertionPointEnd()
1346 else: ## not online, and no text in chattxt box
1347 self.Post(self.colorize(self.syscolor, " ** That's the Tab key, Dave"))
1348
1349 ## PAGE UP
1350 elif event.GetKeyCode() in (wx.WXK_PRIOR, wx.WXK_PAGEUP):
1351 self.log.log("event.GetKeyCode() in (wx.WXK_PRIOR, wx.WXK_PAGEUP)", ORPG_DEBUG)
1352 self.chatwnd.ScrollPages(-1)
1353 if not self.lockscroll:
1354 self.lock_scroll(0)
1355
1356 ## PAGE DOWN
1357 elif event.GetKeyCode() in (wx.WXK_NEXT, wx.WXK_PAGEDOWN):
1358 self.log.log("event.GetKeyCode() in (wx.WXK_NEXT, wx.WXK_PAGEDOWN)", ORPG_DEBUG)
1359 if not self.lockscroll:
1360 self.lock_scroll(0)
1361 if ((self.chatwnd.GetScrollRange(1)-self.chatwnd.GetScrollPos(1)-self.chatwnd.GetScrollThumb(1) < 30) and self.lockscroll):
1362 self.lock_scroll(0)
1363 self.chatwnd.ScrollPages(1)
1364
1365 ## END
1366 elif event.GetKeyCode() == wx.WXK_END:
1367 self.log.log("event.GetKeyCode() == wx.WXK_END", ORPG_DEBUG)
1368 if self.lockscroll:
1369 self.lock_scroll(0)
1370 self.Post()
1371 event.Skip()
1372
1373 ## NOTHING
1374 else:
1375 event.Skip()
1376 self.log.log("Exit chat_panel->OnChar(self, event)", ORPG_DEBUG)
1377 # def OnChar - end
1378
1379 def onDieRoll(self, evt):
1380 """Roll the dice based on the button pressed and the die modifiers entered, if any."""
1381 self.log.log("Enter chat_panel->onDieRoll(self, evt)", ORPG_DEBUG)
1382 # Get any die modifiers if they have been entered
1383 numDie = self.numDieText.GetValue()
1384 dieMod = self.dieModText.GetValue()
1385 dieText = numDie
1386 # Now, apply and roll die mods based on the button that was pressed
1387 id = evt.GetId()
1388 if self.dieIDs.has_key(id):
1389 dieText += self.dieIDs[id]
1390 if len(dieMod) and dieMod[0] not in "*/-+":
1391 dieMod = "+" + dieMod
1392 dieText += dieMod
1393 dieText = "[" + dieText + "]"
1394 self.ParsePost(dieText, 1, 1)
1395 self.chattxt.SetFocus()
1396 self.log.log("Exit chat_panel->onDieRoll(self, evt)", ORPG_DEBUG)
1397
1398 # This subroutine saves a chat buffer as html to a file chosen via a
1399 # FileDialog.
1400 #
1401 # !self : instance of self
1402 # !evt :
1403 def on_chat_save(self, evt):
1404 self.log.log("Enter chat_panel->on_chat_save(self, evt)", ORPG_DEBUG)
1405 f = wx.FileDialog(self,"Save Chat Buffer",".","","HTM* (*.htm*)|*.htm*|HTML (*.html)|*.html|HTM (*.htm)|*.htm",wx.SAVE)
1406 if f.ShowModal() == wx.ID_OK:
1407 file = open(f.GetPath(), "w")
1408 file.write(self.ResetPage() + "</body></html>")
1409 file.close()
1410 f.Destroy()
1411 os.chdir(self.root_dir)
1412 self.log.log("Exit chat_panel->on_chat_save(self, evt)", ORPG_DEBUG)
1413 # def on_chat_save - end
1414
1415 def ResetPage(self):
1416 self.set_colors()
1417 buffertext = self.chatwnd.Header() + "\n"
1418 buffertext += chat_util.strip_body_tags(self.chatwnd.StripHeader()).replace("<br>", "<br />").replace('</html>', '').replace("<br />", "<br />\n").replace("\n\n", '')
1419 return buffertext
1420
1421 # This subroutine sets the color of selected text, or base text color if
1422 # nothing is selected
1423 def on_text_color(self, event):
1424 self.log.log("Enter chat_panel->on_text_color(self, event)", ORPG_DEBUG)
1425 hexcolor = self.r_h.do_hex_color_dlg(self)
1426 if hexcolor != None:
1427 (beg,end) = self.chattxt.GetSelection()
1428 if beg != end:
1429 txt = self.chattxt.GetValue()
1430 txt = txt[:beg]+self.colorize(hexcolor,txt[beg:end]) +txt[end:]
1431 self.chattxt.SetValue(txt)
1432 self.chattxt.SetInsertionPointEnd()
1433 self.chattxt.SetFocus()
1434 else:
1435 self.color_button.SetBackgroundColour(hexcolor)
1436 self.mytextcolor = hexcolor
1437 self.settings.set_setting('mytextcolor',hexcolor)
1438 self.set_colors()
1439 self.Post()
1440 self.log.log("Exit chat_panel->on_text_color(self, event)", ORPG_DEBUG)
1441 # def on_text_color - end
1442
1443 # This subroutine take a color and a text string and formats it into html.
1444 #
1445 # !self : instance of self
1446 # !color : color for the text to be set
1447 # !text : text string to be included in the html.
1448 def colorize(self, color, text):
1449 """Puts font tags of 'color' around 'text' value, and returns the string"""
1450 self.log.log("Enter chat_panel->colorize(self, color, text)", ORPG_DEBUG)
1451 self.log.log("Exit chat_panel->colorize(self, color, text)", ORPG_DEBUG)
1452 return "<font color='" + color + "'>" + text + "</font>"
1453 # def colorize - end
1454
1455 # This subroutine takes and event and inserts text with the basic format
1456 # tags included.
1457 #
1458 # !self : instance of self
1459 # !event :
1460 def on_text_format(self, event):
1461 self.log.log("Enter chat_panel->on_text_format(self, event)", ORPG_DEBUG)
1462 id = event.GetId()
1463 txt = self.chattxt.GetValue()
1464 (beg,end) = self.chattxt.GetSelection()
1465 if beg != end:
1466 sel_txt = txt[beg:end]
1467 else:
1468 sel_txt = txt
1469 if id == self.boldButton.GetId():
1470 sel_txt = "<b>" + sel_txt + "</b>"
1471 elif id == self.italicButton.GetId():
1472 sel_txt = "<i>" + sel_txt + "</i>"
1473 elif id == self.underlineButton.GetId():
1474 sel_txt = "<u>" + sel_txt + "</u>"
1475 if beg != end:
1476 txt = txt[:beg] + sel_txt + txt[end:]
1477 else:
1478 txt = sel_txt
1479 self.chattxt.SetValue(txt)
1480 self.chattxt.SetInsertionPointEnd()
1481 self.chattxt.SetFocus()
1482 self.log.log("Exit chat_panel->on_text_format(self, event)", ORPG_DEBUG)
1483 # def on_text_format - end
1484
1485 def lock_scroll(self, event):
1486 self.log.log("Enter chat_panel->lock_scroll(self, event)", ORPG_DEBUG)
1487 if self.lockscroll:
1488 self.lockscroll = False
1489 self.scroll_lock.SetLabel("Scroll ON")
1490 if len(self.storedata) != 0:
1491 for line in self.storedata:
1492 self.chatwnd.AppendToPage(line)
1493 self.storedata = []
1494 self.scroll_down()
1495 else:
1496 self.lockscroll = True
1497 self.scroll_lock.SetLabel("Scroll OFF")
1498 self.log.log("Exit chat_panel->lock_scroll(self, event)", ORPG_DEBUG)
1499
1500 # This subroutine will popup a text window with the chatbuffer contents
1501 #
1502 # !self : instance of self
1503 # !event :
1504 def pop_textpop(self, event):
1505 """searchable popup text view of chatbuffer"""
1506 self.log.log("Enter chat_panel->pop_textpop(self, event)", ORPG_DEBUG)
1507 h_buffertext = self.ResetPage()
1508 h_dlg = orpgScrolledMessageFrameEditor(self, h_buffertext, "Text View of Chat Window", None, (500,300))
1509 h_dlg.Show(True)
1510 self.log.log("Exit chat_panel->pop_textpop(self, event)", ORPG_DEBUG)
1511
1512 # This subroutine will change the dimension of the window
1513 #
1514 # !self : instance of self
1515 # !event :
1516 def OnSize(self, event=None):
1517 self.log.log("Enter chat_panel->OnSize(self, event=None)", ORPG_DEBUG)
1518 event.Skip()
1519 wx.CallAfter(self.scroll_down)
1520 self.log.log("Exit chat_panel->OnSize(self, event=None)", ORPG_DEBUG)
1521 # def OnSize - end
1522
1523 def scroll_down(self):
1524 self.Freeze()
1525 self.chatwnd.scroll_down()
1526 self.Thaw()
1527
1528 ###### message helpers ######
1529 def PurgeChat(self):
1530 self.set_colors()
1531 self.chatwnd.SetPage(self.chatwnd.Header())
1532
1533 def system_message(self, text):
1534 self.log.log("Enter chat_panel->system_message(self, text)", ORPG_DEBUG)
1535 self.send_chat_message(text,chat_msg.SYSTEM_MESSAGE)
1536 self.SystemPost(text)
1537 self.log.log("Exit chat_panel->system_message(self, text)", ORPG_DEBUG)
1538
1539 def info_message(self, text):
1540 self.log.log("Enter chat_panel->info_message(self, text)", ORPG_DEBUG)
1541 self.send_chat_message(text,chat_msg.INFO_MESSAGE)
1542 self.InfoPost(text)
1543 self.log.log("Exit chat_panel->info_message(self, text)", ORPG_DEBUG)
1544
1545 def get_gms(self):
1546 self.log.log("Enter chat_panel->get_gms(self)", ORPG_DEBUG)
1547 the_gms = []
1548 for playerid in self.session.players:
1549 if len(self.session.players[playerid])>7:
1550 if self.session.players[playerid][7]=="GM" and self.session.group_id != '0':
1551 the_gms += [playerid]
1552 self.log.log("Exit chat_panel->get_gms(self)", ORPG_DEBUG)
1553 return the_gms
1554
1555 def GetName(self):
1556 self.log.log("Enter chat_panel->GetName(self)", ORPG_DEBUG)
1557 self.AliasLib = open_rpg.get_component('alias')
1558 player = self.session.get_my_info()
1559 if self.AliasLib != None:
1560 self.AliasLib.alias = self.aliasList.GetStringSelection();
1561 if self.AliasLib.alias[0] != self.defaultAliasName:
1562 self.log.log("Exit chat_panel->GetName(self)", ORPG_DEBUG)
1563 return [self.chat_display_name([self.AliasLib.alias[0], player[1], player[2]]), self.AliasLib.alias[1]]
1564 self.log.log("Exit chat_panel->GetName(self)", ORPG_DEBUG)
1565 return [self.chat_display_name(player), "Default"]
1566
1567 def GetFilteredText(self, text):
1568 self.log.log("Enter chat_panel->GetFilteredText(self, text)", ORPG_DEBUG)
1569 advregex = re.compile('\"(.*?)\"', re.I)
1570 self.AliasLib = open_rpg.get_component('alias')
1571 if self.AliasLib != None:
1572 self.AliasLib.filter = self.filterList.GetSelection()-1;
1573 for rule in self.AliasLib.filterRegEx:
1574 if not self.advancedFilter:
1575 text = re.sub(rule[0], rule[1], text)
1576 else:
1577 for m in advregex.finditer(text):
1578 match = m.group(0)
1579 newmatch = re.sub(rule[0], rule[1], match)
1580 text = text.replace(match, newmatch)
1581 self.log.log("Exit chat_panel->GetFilteredText(self, text)", ORPG_DEBUG)
1582 return text
1583
1584 def emote_message(self, text):
1585 self.log.log("Enter chat_panel->emote_message(self, text)", ORPG_DEBUG)
1586 text = self.NormalizeParse(text)
1587 text = self.colorize(self.emotecolor, text)
1588
1589 if self.type == MAIN_TAB and self.sendtarget == 'all':
1590 self.send_chat_message(text,chat_msg.EMOTE_MESSAGE)
1591 elif self.type == MAIN_TAB and self.sendtarget == "gm":
1592 msg_type = chat_msg.WHISPER_EMOTE_MESSAGE
1593 the_gms = self.get_gms()
1594 for each_gm in the_gms:
1595 self.send_chat_message(text,chat_msg.WHISPER_EMOTE_MESSAGE, str(each_gm))
1596 elif self.type == GROUP_TAB and WG_LIST.has_key(self.sendtarget):
1597 for pid in WG_LIST[self.sendtarget]:
1598 self.send_chat_message(text,chat_msg.WHISPER_EMOTE_MESSAGE, str(pid))
1599 elif self.type == WHISPER_TAB:
1600 self.send_chat_message(text,chat_msg.WHISPER_EMOTE_MESSAGE, str(self.sendtarget))
1601 elif self.type == NULL_TAB:
1602 pass
1603 name = self.GetName()[0]
1604 text = "** " + name + " " + text + " **"
1605 self.EmotePost(text)
1606 self.log.log("Exit chat_panel->emote_message(self, text)", ORPG_DEBUG)
1607
1608 def whisper_to_players(self, text, player_ids):
1609 self.log.log("Enter chat_panel->whisper_to_players(self, text, player_ids)", ORPG_DEBUG)
1610 tabbed_whispers_p = self.settings.get_setting("tabbedwhispers")
1611 # Heroman - apply any filtering selected
1612 text = self.NormalizeParse(text)
1613 player_names = ""
1614 # post to our chat before we colorize
1615 for m in player_ids:
1616 id = m.strip()
1617 if self.session.is_valid_id(id):
1618 returned_name = self.session.get_player_by_player_id(id)[0]
1619 player_names += returned_name
1620 player_names += ", "
1621 else:
1622 player_names += " Unknown!"
1623 player_names += ", "
1624 comma = ","
1625 comma.join(player_ids)
1626 if (self.sendtarget == "all"):
1627 self.InfoPost("<i>whispering to "+ player_names + " " + text + "</i> ")
1628 # colorize and loop, sending whisper messages to all valid clients
1629 text = self.colorize(self.mytextcolor, text)
1630 for id in player_ids:
1631 id = id.strip()
1632 if self.session.is_valid_id(id):
1633 self.send_chat_message(text,chat_msg.WHISPER_MESSAGE,id)
1634 else:
1635 self.InfoPost(id + " Unknown!")
1636 self.log.log("Exit chat_panel->whisper_to_players(self, text, player_ids)", ORPG_DEBUG)
1637
1638 def send_chat_message(self, text, type=chat_msg.CHAT_MESSAGE, player_id="all"):
1639 self.log.log("Enter chat_panel->send_chat_message(self, text, type, player_id)", ORPG_DEBUG)
1640 #########send_msg()#############
1641 send = 1
1642 for plugin_fname in self.activeplugins.keys():
1643 plugin = self.activeplugins[plugin_fname]
1644 try:
1645 text, send = plugin.send_msg(text, send)
1646 except Exception, e:
1647 if str(e) != "'module' object has no attribute 'send_msg'":
1648 self.log.log(traceback.format_exc(), ORPG_GENERAL)
1649 self.log.log("EXCEPTION: " + str(e), ORPG_GENERAL)
1650 msg = chat_msg.chat_msg()
1651 msg.set_text(text)
1652 msg.set_type(type)
1653 turnedoff = False
1654 if self.settings.get_setting("ShowIDInChat") == "1":
1655 turnedoff = True
1656 self.settings.set_setting("ShowIDInChat", "0")
1657 playername = self.GetName()[0]
1658
1659 if turnedoff:
1660 self.settings.set_setting("ShowIDInChat", "1")
1661 msg.set_alias(playername)
1662 if send:
1663 self.session.send(msg.toxml(),player_id)
1664 del msg
1665 self.log.log("Exit chat_panel->send_chat_message(self, text, type, player_id)", ORPG_DEBUG)
1666
1667 #### incoming chat message handler #####
1668 def post_incoming_msg(self, msg, player):
1669 self.log.log("Enter chat_panel->post_incoming_msg(self, msg, player)", ORPG_DEBUG)
1670
1671 # pull data
1672 type = msg.get_type()
1673 text = msg.get_text()
1674 alias = msg.get_alias()
1675 # who sent us the message?
1676 if alias:
1677 display_name = self.chat_display_name([alias, player[1], player[2]])
1678 elif player:
1679 display_name = self.chat_display_name(player)
1680 else:
1681 display_name = "Server Administrator"
1682
1683 ######### START plugin_incoming_msg() ###########
1684 for plugin_fname in self.activeplugins.keys():
1685 plugin = self.activeplugins[plugin_fname]
1686 try:
1687 text, type, name = plugin.plugin_incoming_msg(text, type, display_name, player)
1688 except Exception, e:
1689 if str(e) != "'module' object has no attribute 'receive_msg'":
1690 self.log.log(traceback.format_exc(), ORPG_GENERAL)
1691 self.log.log("EXCEPTION: " + str(e), ORPG_GENERAL)
1692 #end mDuo13 added code
1693 #image stripping for players' names
1694 strip_img = self.settings.get_setting("Show_Images_In_Chat")
1695 if (strip_img == "0"):
1696 display_name = chat_util.strip_img_tags(display_name)
1697 #end image stripping. --mDuo13, July 11th, 2005
1698 # default sound
1699 recvSound = "RecvSound"
1700 # act on the type of messsage
1701 if (type == chat_msg.CHAT_MESSAGE):
1702 text = "<b>" + display_name + "</b>: " + text
1703 self.Post(text)
1704 self.parent.newMsg(0)
1705 elif type == chat_msg.WHISPER_MESSAGE or type == chat_msg.WHISPER_EMOTE_MESSAGE:
1706 tabbed_whispers_p = self.settings.get_setting("tabbedwhispers")
1707 displaypanel = self
1708 whisperingstring = " (whispering): "
1709 panelexists = 0
1710 GMWhisperTab = self.settings.get_setting("GMWhisperTab")
1711 GroupWhisperTab = self.settings.get_setting("GroupWhisperTab")
1712 name = '<i><b>' + display_name + '</b>: '
1713 text += '</i>'
1714 panelexists = 0
1715 created = 0
1716 try:
1717 if GMWhisperTab == '1':
1718 the_gms = self.get_gms()
1719 #Check if whisper if from a GM
1720 if player[2] in the_gms:
1721 msg = name + ' (GM Whisper:) ' + text
1722 if type == chat_msg.WHISPER_MESSAGE:
1723 self.parent.GMChatPanel.Post(msg)
1724 else:
1725 self.parent.GMChatPanel.EmotePost("**" + msg + "**")
1726 idx = self.parent.get_tab_index(self.parent.GMChatPanel)
1727 self.parent.newMsg(idx)
1728 panelexists = 1
1729 #See if message if from someone in our groups or for a whisper tab we already have
1730 if not panelexists and GroupWhisperTab == "1":
1731 for panel in self.parent.group_tabs:
1732 if WG_LIST.has_key(panel.sendtarget) and WG_LIST[panel.sendtarget].has_key(int(player[2])):
1733 msg = name + text
1734 if type == chat_msg.WHISPER_MESSAGE:
1735 panel.Post(msg)
1736 else:
1737 panel.EmotePost("**" + msg + "**")
1738 idx = self.parent.get_tab_index(panel)
1739 self.parent.newMsg(idx)
1740 panelexists = 1
1741 break
1742 if not panelexists and tabbed_whispers_p == "1":
1743 for panel in self.parent.whisper_tabs:
1744 #check for whisper tabs as well, to save the number of loops
1745 if panel.sendtarget == player[2]:
1746 msg = name + whisperingstring + text
1747 if type == chat_msg.WHISPER_MESSAGE:
1748 panel.Post(msg)
1749 else:
1750 panel.EmotePost("**" + msg + "**")
1751 idx = self.parent.get_tab_index(panel)
1752 self.parent.newMsg(idx)
1753 panelexists = 1
1754 break
1755 #We did not fint the tab
1756 if not panelexists:
1757 #If we get here the tab was not found
1758 if GroupWhisperTab == "1":
1759 for group in WG_LIST.keys():
1760 #Check if this group has the player in it
1761 if WG_LIST[group].has_key(int(player[2])):
1762 #Yup, post message. Player may be in more then 1 group so continue as well
1763 panel = self.parent.create_group_tab(group)
1764 msg = name + text
1765 if type == chat_msg.WHISPER_MESSAGE:
1766 wx.CallAfter(panel.Post, msg)
1767 else:
1768 wx.CallAfter(panel.EmotePost, "**" + msg + "**")
1769 created = 1
1770 #Check to see if we should create a whisper tab
1771 if not created and tabbed_whispers_p == "1":
1772 panel = self.parent.create_whisper_tab(player[2])
1773 msg = name + whisperingstring + text
1774 if type == chat_msg.WHISPER_MESSAGE:
1775 wx.CallAfter(panel.Post, msg)
1776 else:
1777 wx.CallAfter(panel.EmotePost, "**" + msg + "**")
1778 created = 1
1779 #Final check
1780 if not created:
1781 #No tabs to create, just send the message to the main chat tab
1782 msg = name + whisperingstring + text
1783 if type == chat_msg.WHISPER_MESSAGE:
1784 self.parent.MainChatPanel.Post(msg)
1785 else:
1786 self.parent.MainChatPanel.EmotePost("**" + msg + "**")
1787 self.parent.newMsg(0)
1788 except Exception, e:
1789 self.log.log(traceback.format_exc(), ORPG_GENERAL)
1790 self.log.log("EXCEPTION: 'Error in posting whisper message': " + str(e), ORPG_GENERAL)
1791 elif (type == chat_msg.EMOTE_MESSAGE):
1792 text = "** " + display_name + " " + text + " **"
1793 self.EmotePost(text)
1794 self.parent.newMsg(0)
1795 elif (type == chat_msg.INFO_MESSAGE):
1796 text = "<b>" + display_name + "</b>: " + text
1797 self.InfoPost(text)
1798 self.parent.newMsg(0)
1799 elif (type == chat_msg.SYSTEM_MESSAGE):
1800 text = "<b>" + display_name + "</b>: " + text
1801 self.SystemPost(text)
1802 self.parent.newMsg(0)
1803 # playe sound
1804 sound_file = self.settings.get_setting(recvSound)
1805 if sound_file != '':
1806 self.sound_player.play(sound_file)
1807 self.log.log("Exit chat_panel->post_incoming_msg(self, msg, player)", ORPG_DEBUG)
1808 #### Posting helpers #####
1809
1810 def InfoPost(self, s):
1811 self.log.log("Enter chat_panel->InfoPost(self, s)", ORPG_DEBUG)
1812 self.Post(self.colorize(self.infocolor, s))
1813 self.log.log("Exit chat_panel->InfoPost(self, s)", ORPG_DEBUG)
1814
1815 def SystemPost(self, s):
1816 self.log.log("Enter chat_panel->SystemPost(self, s)", ORPG_DEBUG)
1817 self.Post(self.colorize(self.syscolor, s))
1818 self.log.log("Exit chat_panel->SystemPost(self, s)", ORPG_DEBUG)
1819
1820 def EmotePost(self, s):
1821 self.log.log("Enter chat_panel->EmotePost(self, s)", ORPG_DEBUG)
1822 self.Post(self.colorize(self.emotecolor, s))
1823 self.log.log("Exit chat_panel->EmotePost(self, s)", ORPG_DEBUG)
1824
1825 #### Standard Post method #####
1826 def Post(self, s="", send=False, myself=False):
1827 self.log.log("Enter chat_panel->Post(self, s, send, myself)", ORPG_DEBUG)
1828 strip_p = self.settings.get_setting("striphtml")
1829 strip_img = self.settings.get_setting("Show_Images_In_Chat")#moved back 7-11-05. --mDuo13
1830 if (strip_p == "1"):
1831 s = strip_html(s)
1832 if (strip_img == "0"):
1833 s = chat_util.strip_img_tags(s)
1834 s = chat_util.simple_html_repair(s)
1835 s = chat_util.strip_script_tags(s)
1836 s = chat_util.strip_li_tags(s)
1837 s = chat_util.strip_body_tags(s)#7-27-05 mDuo13
1838 s = chat_util.strip_misalignment_tags(s)#7-27-05 mDuo13
1839 aliasInfo = self.GetName()
1840 display_name = aliasInfo[0]
1841 if aliasInfo[1] != 'Default':
1842 defaultcolor = self.settings.get_setting("mytextcolor")
1843 self.settings.set_setting("mytextcolor", aliasInfo[1])
1844 self.set_colors()
1845 newline = ''
1846 #following added by mDuo13
1847 #########post_msg() - other##########
1848 if not myself and not send:
1849 for plugin_fname in self.activeplugins.keys():
1850 plugin = self.activeplugins[plugin_fname]
1851 try:
1852 s = plugin.post_msg(s, myself)
1853 except Exception, e:
1854 if str(e) != "'module' object has no attribute 'post_msg'":
1855 self.log.log(traceback.format_exc(), ORPG_GENERAL)
1856 self.log.log("EXCEPTION: " + str(e), ORPG_GENERAL)
1857 #end mDuo13 added code
1858 if myself:
1859 name = "<b>" + display_name + "</b>: "
1860 s = self.colorize(self.mytextcolor, s)
1861 else:
1862 name = ""
1863 if aliasInfo[1] != 'Default':
1864 self.settings.set_setting("mytextcolor", defaultcolor)
1865 self.set_colors()
1866 #following line based on sourceforge patch #880403 from mDuo
1867 # EDIT: Had to rework blank line check to handle malformed HTML throwing error.
1868 # this limits the effectiveness of this check -SD
1869 lineHasText = 1
1870 try:
1871 lineHasText = strip_html(s).replace("&nbsp;","").replace(" ","").strip()!=""
1872 except:
1873 # HTML parser has errored out (most likely). Being as all we are doing is
1874 # scanning for empty/blank lines anyway there is no harm in letting a
1875 # troublesome message though. Worst case is a blank line to chat.
1876 lineHasText = 1
1877 if lineHasText:
1878 #following added by mDuo13
1879 if myself:
1880 s2 = s
1881 ########post_msg() - self #######
1882 for plugin_fname in self.activeplugins.keys():
1883 plugin = self.activeplugins[plugin_fname]
1884 try:
1885 s2 = plugin.post_msg(s2, myself)
1886 except Exception, e:
1887 if str(e) != "'module' object has no attribute 'post_msg'":
1888 self.log.log(traceback.format_exc(), ORPG_GENERAL)
1889 self.log.log("EXCEPTION: " + str(e), ORPG_GENERAL)
1890 if s2 != "":
1891 #Italici the messages from tabbed whispers
1892 if self.type == WHISPER_TAB or self.type == GROUP_TAB or self.sendtarget == 'gm':
1893 s2 = s2 + '</i>'
1894 name = '<i>' + name
1895 if self.type == WHISPER_TAB:
1896 name += " (whispering): "
1897 elif self.type == GROUP_TAB:
1898 name += self.settings.get_setting("gwtext") + ' '
1899 elif self.sendtarget == 'gm':
1900 name += " (whispering to GM) "
1901 newline = self.TimeIndexString() + name + s2 + "<br />"
1902 log( self.settings, name + s2 )
1903 else:
1904 newline = self.TimeIndexString() + name + s + "<br />"
1905 log( self.settings, name + s )
1906 else:
1907 send = False
1908 newline = chat_util.strip_unicode(newline)
1909 if self.lockscroll == 0:
1910 self.chatwnd.AppendToPage(newline)
1911 self.scroll_down()
1912 else:
1913 self.storedata.append(newline)
1914 if send:
1915 if self.type == MAIN_TAB and self.sendtarget == 'all':
1916 self.send_chat_message(s)
1917 elif self.type == MAIN_TAB and self.sendtarget == "gm":
1918 the_gms = self.get_gms()
1919 self.whisper_to_players(s, the_gms)
1920 elif self.type == GROUP_TAB and WG_LIST.has_key(self.sendtarget):
1921 members = []
1922 for pid in WG_LIST[self.sendtarget]:
1923 members.append(str(WG_LIST[self.sendtarget][pid]))
1924 self.whisper_to_players(self.settings.get_setting("gwtext") + s, members)
1925 elif self.type == WHISPER_TAB:
1926 self.whisper_to_players(s, [self.sendtarget])
1927 elif self.type == NULL_TAB:
1928 pass
1929 else:
1930 self.InfoPost("Failed to send message, unknown send type for this tab")
1931 self.parsed=0
1932 self.log.log("Exit chat_panel->Post(self, s, send, myself)", ORPG_DEBUG)
1933
1934 #
1935 # TimeIndexString()
1936 #
1937 # time indexing for chat display only (don't log time indexing)
1938 # added by Snowdog 4/04
1939 def TimeIndexString(self):
1940 self.log.log("Enter chat_panel->TimeIndexString(self)", ORPG_DEBUG)
1941 try:
1942 mtime = ""
1943 if self.settings.get_setting('Chat_Time_Indexing') == "0":
1944 pass
1945 elif self.settings.get_setting('Chat_Time_Indexing') == "1":
1946 mtime = time.strftime("[%I:%M:%S] ", time.localtime())
1947 self.log.log("Exit chat_panel->TimeIndexString(self)", ORPG_DEBUG)
1948 return mtime
1949 except Exception, e:
1950 self.log.log(traceback.format_exc(), ORPG_GENERAL)
1951 self.log.log("EXCEPTION: " + str(e), ORPG_GENERAL)
1952 return "[ERROR]"
1953
1954 #### Post with parsing dice ####
1955 def ParsePost(self, s, send=False, myself=False):
1956 self.log.log("Enter chat_panel->ParsePost(self, s, send, myself)", ORPG_DEBUG)
1957 s = self.NormalizeParse(s)
1958 self.set_colors()
1959 self.Post(s,send,myself)
1960 self.log.log("Exit chat_panel->ParsePost(self, s, send, myself)", ORPG_DEBUG)
1961
1962 def NormalizeParse(self, s):
1963 self.log.log("Enter chat_panel->NormalizeParse(self, s)", ORPG_DEBUG)
1964 for plugin_fname in self.activeplugins.keys():
1965 plugin = self.activeplugins[plugin_fname]
1966 try:
1967 s = plugin.pre_parse(s)
1968 except Exception, e:
1969 if str(e) != "'module' object has no attribute 'post_msg'":
1970 self.log.log(traceback.format_exc(), ORPG_GENERAL)
1971 self.log.log("EXCEPTION: " + str(e), ORPG_GENERAL)
1972 if self.parsed == 0:
1973 s = self.ParseNode(s)
1974 s = self.ParseDice(s)
1975 s = self.ParseFilter(s)
1976 self.parsed = 1
1977 self.log.log("Exit chat_panel->NormalizeParse(self, s)", ORPG_DEBUG)
1978 return s
1979
1980 def ParseFilter(self, s):
1981 self.log.log("Enter chat_panel->ParseFilter(self, s)", ORPG_DEBUG)
1982 s = self.GetFilteredText(s)
1983 self.log.log("Exit chat_panel->ParseFilter(self, s)", ORPG_DEBUG)
1984 return s
1985
1986 def ParseNode(self, s):
1987 """Parses player input for embedded nodes rolls"""
1988 self.log.log("Enter chat_panel->ParseNode(self, s)", ORPG_DEBUG)
1989 cur_loc = 0
1990 #[a-zA-Z0-9 _\-\.]
1991 reg = re.compile("(!@([a-zA-Z0-9 _\-\./]+(::[a-zA-Z0-9 _\-\./]+)*)@!)")
1992 matches = reg.findall(s)
1993 for i in xrange(0,len(matches)):
1994 newstr = self.ParseNode(self.resolve_nodes(matches[i][1]))
1995 s = s.replace(matches[i][0], newstr, 1)
1996 self.log.log("Exit chat_panel->ParseNode(self, s)", ORPG_DEBUG)
1997 return s
1998
1999 def ParseDice(self, s):
2000 """Parses player input for embedded dice rolls"""
2001 self.log.log("Enter chat_panel->ParseDice(self, s)", ORPG_DEBUG)
2002 reg = re.compile("\[([^]]*?)\]")
2003 matches = reg.findall(s)
2004 for i in xrange(0,len(matches)):
2005 newstr = self.PraseUnknowns(matches[i])
2006 qmode = 0
2007 newstr1 = newstr
2008 if newstr[0].lower() == 'q':
2009 newstr = newstr[1:]
2010 qmode = 1
2011 try:
2012 newstr = self.DiceManager.proccessRoll(newstr)
2013 except:
2014 pass
2015 if qmode == 1:
2016 s = s.replace("[" + matches[i] + "]", "<!-- Official Roll [" + newstr1 + "] => " + newstr + "-->" + newstr, 1)
2017 else:
2018 s = s.replace("[" + matches[i] + "]", "[" + newstr1 + "<!-- Official Roll -->] => " + newstr, 1)
2019 self.log.log("Exit chat_panel->ParseDice(self, s)", ORPG_DEBUG)
2020 return s
2021
2022 def PraseUnknowns(self, s):
2023 # Uses a tuple. Usage: ?Label}dY. If no Label is assigned then use ?}DY
2024 self.log.log("Enter chat_panel->PraseUnknowns(self, s)", ORPG_DEBUG)
2025 newstr = "0"
2026 reg = re.compile("(\?\{*)([a-zA-Z ]*)(\}*)")
2027 matches = reg.findall(s)
2028 for i in xrange(0,len(matches)):
2029 lb = "Replace '?' with: "
2030 if len(matches[i][0]):
2031 lb = matches[i][1] + "?: "
2032 dlg = wx.TextEntryDialog(self, lb, "Missing Value?")
2033 dlg.SetValue('')
2034 if matches[i][0] != '':
2035 dlg.SetTitle("Enter Value for " + matches[i][1])
2036 if dlg.ShowModal() == wx.ID_OK:
2037 newstr = dlg.GetValue()
2038 if newstr == '':
2039 newstr = '0'
2040 s = s.replace(matches[i][0], newstr, 1).replace(matches[i][1], '', 1).replace(matches[i][2], '', 1)
2041 dlg.Destroy()
2042 self.log.log("Exit chat_panel->PraseUnknowns(self, s)", ORPG_DEBUG)
2043 return s
2044
2045 # This subroutine builds a chat display name.
2046 #
2047 def chat_display_name(self, player):
2048 self.log.log("Enter chat_panel->chat_display_name(self, player)", ORPG_DEBUG)
2049 if self.settings.get_setting("ShowIDInChat") == "0":
2050 display_name = player[0]
2051 else:
2052 display_name = "("+player[2]+") " + player[0]
2053 self.log.log("Exit chat_panel->chat_display_name(self, player)", ORPG_DEBUG)
2054 return display_name
2055
2056 # This subroutine will get a hex color and return it, or return nothing
2057 #
2058 def get_color(self):
2059 self.log.log("Enter chat_panel->get_color(self)", ORPG_DEBUG)
2060 data = wx.ColourData()
2061 data.SetChooseFull(True)
2062 dlg = wx.ColourDialog(self, data)
2063 if dlg.ShowModal() == wx.ID_OK:
2064 data = dlg.GetColourData()
2065 (red,green,blue) = data.GetColour().Get()
2066 hexcolor = self.r_h.hexstring(red, green, blue)
2067 dlg.Destroy()
2068 self.log.log("Exit chat_panel->get_color(self) return hexcolor", ORPG_DEBUG)
2069 return hexcolor
2070 else:
2071 dlg.Destroy()
2072 self.log.log("Exit chat_panel->get_color(self) return None", ORPG_DEBUG)
2073 return None
2074 # def get_color - end
2075
2076 def replace_quotes(self, s):
2077 self.log.log("Enter chat_panel->replace_quotes(self, s)", ORPG_DEBUG)
2078 in_tag = 0
2079 i = 0
2080 rs = s[:]
2081 for c in s:
2082 if c == "<":
2083 in_tag += 1
2084 elif c == ">":
2085 if in_tag:
2086 in_tag -= 1
2087 elif c == '"':
2088 if in_tag:
2089 rs = rs[:i] + "'" + rs[i+1:]
2090 i += 1
2091 self.log.log("Exit chat_panel->replace_quotes(self, s)", ORPG_DEBUG)
2092 return rs
2093
2094 def resolve_loop(self, dom, nodeName, doLoop = False):
2095 self.log.log("Enter chat_panel->resolve_loop(self, dom, nodeName)", ORPG_DEBUG)
2096 for node in dom:
2097 if node._get_tagName() != 'nodehandler':
2098 continue
2099 if doLoop and node.getAttribute('class') != 'textctrl_handler' and node.hasChildNodes():
2100 (found, node) = self.resolve_loop(node.getChildren(), nodeName, doLoop)
2101 if not found:
2102 continue
2103 if node.getAttribute('name') != nodeName:
2104 continue
2105 foundNode = node
2106 self.log.log("Exit chat_panel->resolve_loop(self, dom, path) return (True, value)", ORPG_DEBUG)
2107 return (True, foundNode)
2108 self.log.log("Exit chat_panel->resolve_loop(self, dom, path) return (False, '')", ORPG_DEBUG)
2109 return (False, '')
2110
2111 def resolve_nodes(self, s):
2112 self.log.log("Enter chat_panel->resolve_nodes(self, s)", ORPG_DEBUG)
2113 value = ""
2114 node_path_list = s.split("::")
2115 gametree = open_rpg.get_component('tree')
2116 dom = gametree.master_dom.getChildren()
2117 for nodeName in node_path_list:
2118 (found, node) = self.resolve_loop(dom, nodeName)
2119 if not found:
2120 break
2121 dom = node.getChildren()
2122 if not found:
2123 dom = gametree.master_dom.getChildren()
2124 loop = False
2125 if len(node_path_list) == 1:
2126 loop = True
2127 for nodeName in node_path_list:
2128 (found, node) = self.resolve_loop(dom, nodeName, loop)
2129 if not found:
2130 break
2131 dom = node.getChildren()
2132 loop = True
2133 if found:
2134 text = node.getElementsByTagName('text')
2135 node = text[0]._get_firstChild()
2136 value = node._get_nodeValue()
2137 else:
2138 value = s
2139 self.log.log("Exit chat_panel->resolve_nodes(self, s)", ORPG_DEBUG)
2140 return value