Mercurial > traipse_dev
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(" ","").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 |