Mercurial > traipse_dev
annotate orpg/chat/chatwnd.py @ 222:bb7b9648792c beta
Traipse Beta 'OpenRPG' {100502-00}
Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for
developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to
the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user.
Update Summary (Patch-2)
New Features:
New Namespace method with two new syntaxes
New Namespace Internal is context sensitive, always!
New Namespace External is 'as narrow as you make it'
New Namespace FutureCheck helps ensure you don't receive an incorrect node
New PluginDB access for URL2Link plugin
New to Forms, they now show their content in Design Mode
New to Update Manager, checks Repo for updates on software start
New to Mini Lin node, change title in design mode
New to Game Tree, never lose a node, appends a number to the end of corrupted trees
New to Server GUI, Traipse Suite's Debug Console
New Namespace plugin, Allows Traipse users to use the Standard syntax !@ :: @!
Updates:
Update to White Board layer, uses a pencil image for color button
Update to Grid Layer, uses a grid image for color button
Update to Chat Window, size of drop down menus
Update to default lobby message
Update to template Text node
Update to 4e PC Sheet node
Fixes:
Fix to Server GUI startup errors
Fix to Server GUI Rooms tab updating
Fix to Chat and Settings if non existant die roller is picked
Fix to Dieroller and .open() used with .vs(). Successes are correctly calculated
Fix to Alias Lib's Export to Tree, Open, Save features
Fix to alias node, now works properly
Fix to Splitter node, minor GUI cleanup
Fix to Backgrounds not loading through remote loader
Fix to Node name errors
Fix to rolling dice in chat Whispers
Fix to Splitters Sizing issues
Fix to URL2Link plugin, modified regex compilation should remove memory leak
Fix to mapy.py, a roll back due to zoomed grid issues
Fix to whiteboard_handler, Circles work by you clicking the center of the circle
Fix to Servers parse_incoming_dom which was outdated and did not respect XML
Fix to a broken link in the server welcome message
Fix to InterParse and logger requiring traceback
Fix to Update Manager Status Bar
Fix to failed image and erroneous pop up
Fix to Mini Lib node that was preventing use
Fix to plugins that parce dice but did not call InterParse
Fix to nodes for name changing by double click
Fix to Game Tree, node ordering on drag and drop corrected
Fix to Game Tree, corrupted error message was not showing
Fix to Update Manager, checks for internet connection
Fix to Update Manager, Auto Update corrections
author | sirebral |
---|---|
date | Sun, 02 May 2010 16:30:28 -0500 |
parents | 13054be69834 |
children | b29454610f36 |
rev | line source |
---|---|
156 | 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: | |
184 | 24 # $Id: chatwnd.py,v Traipse 'Ornery-Orc' prof.ebral Exp $ |
156 | 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 | |
184 | 40 __version__ = "$Id: chatwnd.py,v Traipse 'Ornery-Orc' prof.ebral Exp $" |
156 | 41 |
42 | |
43 ## | |
44 ## Module Loading | |
135 | 45 ## |
46 import os, time, re, sys, traceback, webbrowser, commands, chat_msg, chat_util | |
47 | |
212 | 48 from orpg.orpg_version import VERSION, DISTRO, DIS_VER, BUILD |
156 | 49 from orpg.orpg_windows import * |
50 from orpg.player_list import WG_LIST | |
51 from orpg.dirpath import dir_struct | |
52 from string import * | |
135 | 53 |
156 | 54 import cStringIO # for reading inline imagedata as a stream |
55 from HTMLParser import HTMLParser | |
56 from wx.lib.expando import EVT_ETC_LAYOUT_NEEDED | |
135 | 57 |
156 | 58 import orpg.tools.rgbhex |
59 import orpg.tools.inputValidator | |
60 from orpg.tools.validate import validate | |
135 | 61 from orpg.tools.orpg_settings import settings |
156 | 62 import orpg.tools.predTextCtrl |
135 | 63 from orpg.tools.orpg_log import logger, debug |
191 | 64 from orpg.tools.InterParse import Parse |
135 | 65 from orpg.orpgCore import component |
66 from xml.etree.ElementTree import tostring | |
67 | |
184 | 68 from orpg.networking.mplay_client import MPLAY_CONNECTED |
156 | 69 NEWCHAT = False |
70 try: | |
71 import wx.webview | |
72 NEWCHAT = True | |
73 except: pass | |
74 NEWCHAT = False | |
75 | |
76 # Global parser for stripping HTML tags: | |
77 # The 'tag stripping' is implicit, because this parser echoes every | |
78 # type of html data *except* the tags. | |
79 class HTMLStripper(HTMLParser): | |
80 | |
81 def __init__(self): | |
82 self.accum = "" | |
83 self.special_tags = ['hr', 'br', 'img'] | |
84 | |
184 | 85 def handle_data(self, data): |
156 | 86 self.accum += data |
87 | |
184 | 88 def handle_entityref(self, name): |
156 | 89 self.accum += "&" + name + ";" |
90 | |
91 def handle_starttag(self, tag, attrs): | |
92 if tag in self.special_tags: | |
93 self.accum += '<' + tag | |
94 for attrib in attrs: self.accum += ' ' + attrib[0] + '="' + attrib[1] + '"' | |
95 self.accum += '>' | |
96 | |
184 | 97 def handle_charref(self, name): |
156 | 98 self.accum += "&#" + name + ";" |
99 htmlstripper = HTMLStripper() | |
100 | |
101 | |
102 def strip_html(string): | |
103 "Return string tripped of html tags." | |
104 htmlstripper.reset() | |
105 htmlstripper.accum = "" | |
106 htmlstripper.feed(string) | |
107 htmlstripper.close() | |
108 return htmlstripper.accum | |
109 | |
110 | |
111 def log( settings, c, text ): | |
112 filename = settings.get_setting('GameLogPrefix') | |
113 if filename > '' and filename[0] != commands.ANTI_LOG_CHAR: | |
114 filename = filename + time.strftime( '-%Y-%m-%d.html', time.localtime( time.time() ) ) | |
115 timestamp = time.ctime(time.time()) | |
116 header = '[%s] : ' % ( timestamp ); | |
117 if settings.get_setting('TimeStampGameLog') != '1': header = '' | |
118 try: | |
119 f = open( dir_struct["user"] + filename, 'a' ) | |
120 f.write( '<div class="'+c+'">%s%s</div>\n' % ( header, text ) ) | |
121 f.close() | |
192 | 122 except Exception, e: |
156 | 123 print "could not open " + dir_struct["user"] + filename + ", ignoring..." |
192 | 124 print 'Error given', e |
156 | 125 pass |
126 | |
127 # This class displayes the chat information in html? | |
128 # | |
129 # Defines: | |
130 # __init__(self, parent, id) | |
131 # OnLinkClicked(self, linkinfo) | |
132 # CalculateAllFonts(self, defaultsize) | |
133 # SetDefaultFontAndSize(self, fontname) | |
134 # | |
135 class chat_html_window(wx.html.HtmlWindow): | |
136 """ a wxHTMLwindow that will load links """ | |
184 | 137 |
156 | 138 def __init__(self, parent, id): |
139 wx.html.HtmlWindow.__init__(self, parent, id, | |
140 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: self.SetStandardFonts() | |
146 | |
147 def onPopup(self, evt): | |
148 self.PopupMenu(self.menu) | |
149 | |
150 def LeftUp(self, event): | |
151 event.Skip() | |
152 wx.CallAfter(self.parent.set_chat_text_focus, None) | |
153 | |
154 def build_menu(self): | |
155 self.menu = wx.Menu() | |
156 item = wx.MenuItem(self.menu, wx.ID_ANY, "Copy", "Copy") | |
157 self.Bind(wx.EVT_MENU, self.OnM_EditCopy, item) | |
158 self.menu.AppendItem(item) | |
159 | |
160 def OnM_EditCopy(self, evt): | |
161 wx.TheClipboard.UsePrimarySelection(False) | |
162 wx.TheClipboard.Open() | |
163 wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText())) | |
164 wx.TheClipboard.Close() | |
165 | |
166 def scroll_down(self): | |
167 maxrange = self.GetScrollRange(wx.VERTICAL) | |
168 pagesize = self.GetScrollPageSize(wx.VERTICAL) | |
169 self.Scroll(-1, maxrange-pagesize) | |
170 | |
171 def mouse_wheel(self, event): | |
172 amt = event.GetWheelRotation() | |
173 units = amt/(-(event.GetWheelDelta())) | |
174 self.ScrollLines(units*3) | |
175 | |
176 | |
177 def Header(self): | |
178 return '<html><body bgcolor="' + self.parent.bgcolor + '" text="' + self.parent.textcolor + '">' | |
179 | |
180 | |
181 def StripHeader(self): | |
182 return self.GetPageSource().replace(self.Header(), '') | |
183 | |
184 | |
185 def GetPageSource(self): | |
186 return self.GetParser().GetSource() | |
187 | |
188 def OnLinkClicked(self, linkinfo): | |
189 href = linkinfo.GetHref() | |
190 wb = webbrowser.get() | |
191 wb.open(href) | |
192 | |
193 def CalculateAllFonts(self, defaultsize): | |
194 return [int(defaultsize * 0.4), | |
195 int(defaultsize * 0.7), | |
196 int(defaultsize), | |
197 int(defaultsize * 1.3), | |
198 int(defaultsize * 1.7), | |
199 int(defaultsize * 2), | |
200 int(defaultsize * 2.5)] | |
201 | |
202 def SetDefaultFontAndSize(self, fontname, fontsize): | |
203 """Set 'fontname' to the default chat font. | |
204 Returns current font settings in a (fontname, fontsize) tuple.""" | |
205 self.SetFonts(fontname, "", self.CalculateAllFonts(int(fontsize))) | |
206 return (self.GetFont().GetFaceName(), self.GetFont().GetPointSize()) | |
207 | |
208 # class chat_html_window - end | |
140 | 209 if NEWCHAT: |
156 | 210 class ChatHtmlWindow(wx.webview.WebView): |
211 | |
212 def __init__(self, parent, id): | |
213 wx.webview.WebView.__init__(self, parent, id) | |
214 self.parent = parent | |
215 self.__font = wx.Font(10, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, faceName='Ariel') | |
216 self.build_menu() | |
217 self.Bind(wx.EVT_LEFT_UP, self.LeftUp) | |
218 self.Bind(wx.EVT_RIGHT_DOWN, self.onPopup) | |
219 self.Bind(wx.webview.EVT_WEBVIEW_BEFORE_LOAD, self.OnLinkClicked) | |
220 | |
221 def SetPage(self, htmlstring): | |
222 self.SetPageSource(htmlstring) | |
223 | |
140 | 224 def AppendToPage(self, htmlstring): |
156 | 225 self.SetPageSource(self.GetPageSource() + htmlstring) |
226 | |
227 def GetFont(self): | |
228 return self.__font | |
229 | |
230 def CalculateAllFonts(self, defaultsize): | |
231 return | |
232 | |
233 def SetDefaultFontAndSize(self, fontname, fontsize): | |
234 self.__font = wx.Font(int(fontsize), | |
235 wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, | |
236 wx.FONTWEIGHT_NORMAL, faceName=fontname) | |
237 try: self.SetPageSource(self.Header() + self.StripHeader()) | |
238 except Exception, e: print e | |
239 return (self.GetFont().GetFaceName(), self.GetFont().GetPointSize()) | |
240 | |
241 #Events | |
242 def OnLinkClicked(self, linkinfo): | |
243 href = linkinfo.GetHref() | |
244 wb = webbrowser.get() | |
245 wb.open(href) | |
246 | |
247 def onPopup(self, evt): | |
248 self.PopupMenu(self.menu) | |
249 | |
250 def LeftUp(self, event): | |
251 event.Skip() | |
252 wx.CallAfter(self.parent.set_chat_text_focus, None) | |
253 | |
254 def OnM_EditCopy(self, evt): | |
255 wx.TheClipboard.UsePrimarySelection(False) | |
256 wx.TheClipboard.Open() | |
257 wx.TheClipboard.SetData(wx.TextDataObject(self.SelectionToText())) | |
258 wx.TheClipboard.Close() | |
259 | |
260 #Cutom Methods | |
261 def Header(self): | |
262 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>" | |
263 | |
264 def StripHeader(self): | |
265 tmp = self.GetPageSource().split('<BODY>') | |
266 if tmp[-1].find('<body>') > -1: tmp = tmp[-1].split('<body>') | |
267 return tmp[-1] | |
268 | |
269 def build_menu(self): | |
270 self.menu = wx.Menu() | |
271 item = wx.MenuItem(self.menu, wx.ID_ANY, "Copy", "Copy") | |
272 self.Bind(wx.EVT_MENU, self.OnM_EditCopy, item) | |
273 self.menu.AppendItem(item) | |
274 | |
275 def scroll_down(self): | |
276 maxrange = self.GetScrollRange(wx.VERTICAL) | |
277 pagesize = self.GetScrollPageSize(wx.VERTICAL) | |
278 self.Scroll(-1, maxrange-pagesize) | |
279 | |
280 def mouse_wheel(self, event): | |
281 amt = event.GetWheelRotation() | |
282 units = amt/(-(event.GetWheelDelta())) | |
283 self.ScrollLines(units*3) | |
284 chat_html_window = ChatHtmlWindow | |
285 | |
286 ######################### | |
287 #chat frame window | |
288 ######################### | |
289 # These are kinda global...and static..and should be located somewhere else | |
290 # then the middle of a file between two classes. | |
291 | |
292 ################### | |
293 # Tab Types | |
294 ################### | |
295 MAIN_TAB = wx.NewId() | |
296 WHISPER_TAB = wx.NewId() | |
297 GROUP_TAB = wx.NewId() | |
298 NULL_TAB = wx.NewId() | |
299 | |
300 # This class defines the tabbed 'notebook' that holds multiple chatpanels. | |
301 # It's the widget attached to the main application frame. | |
302 # | |
303 # Inherits: wxNotebook | |
304 # | |
305 # Defines: | |
306 # create_private_tab(self, playerid) | |
307 # get_tab_index(self, chatpanel) | |
308 # destroy_private_tab(self, chatpanel) | |
309 # OnPageChanged(self, event) | |
310 # set_default_font(self, font, fontsize) | |
311 | |
312 class chat_notebook(orpgTabberWnd): | |
313 | |
314 def __init__(self, parent, size): | |
315 orpgTabberWnd.__init__(self, parent, True, size=size, | |
316 style=FNB.FNB_DROPDOWN_TABS_LIST|FNB.FNB_NO_NAV_BUTTONS|FNB.FNB_MOUSE_MIDDLE_CLOSES_TABS) | |
317 self.settings = component.get("settings") | |
318 self.whisper_tabs = [] | |
319 self.group_tabs = [] | |
320 self.null_tabs = [] | |
321 self.il = wx.ImageList(16, 16) | |
322 bmp = wx.Bitmap(dir_struct["icon"]+'player.gif') | |
323 self.il.Add(bmp) | |
324 bmp = wx.Bitmap(dir_struct["icon"]+'clear.gif') | |
325 self.il.Add(bmp) | |
326 self.SetImageList(self.il) | |
327 # Create "main" chatpanel tab, undeletable, connected to 'public' room. | |
328 self.MainChatPanel = chat_panel(self, -1, MAIN_TAB, 'all') | |
329 self.AddPage(self.MainChatPanel, "Main Room") | |
330 self.SetPageImage(0, 1) | |
331 self.chat_timer = wx.Timer(self, wx.NewId()) | |
332 self.Bind(wx.EVT_TIMER, self.MainChatPanel.typingTimerFunc) | |
333 self.chat_timer.Start(1000) | |
334 # Hook up event handler for flipping tabs | |
335 self.Bind(FNB.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.onPageChanged) | |
336 self.Bind(FNB.EVT_FLATNOTEBOOK_PAGE_CHANGING, self.onPageChanging) | |
337 self.Bind(FNB.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.onCloseTab) | |
338 # html font/fontsize is global to all the notebook tabs. | |
339 self.font, self.fontsize = self.MainChatPanel.chatwnd.SetDefaultFontAndSize(self.settings.get_setting('defaultfont'), self.settings.get_setting('defaultfontsize')) | |
340 self.GMChatPanel = None | |
341 if self.settings.get_setting("GMWhisperTab") == '1': | |
342 self.create_gm_tab() | |
343 self.SetSelection(0) | |
344 | |
345 def get_tab_index(self, chatpanel): | |
346 "Return the index of a chatpanel in the wxNotebook." | |
347 for i in xrange(self.GetPageCount()): | |
348 if (self.GetPage(i) == chatpanel): | |
349 return i | |
350 | |
351 def create_gm_tab(self): | |
352 if self.GMChatPanel == None: | |
353 self.GMChatPanel = chat_panel(self, -1, MAIN_TAB, 'gm') | |
354 self.AddPage(self.GMChatPanel, "GM", False) | |
355 self.SetPageImage(self.GetPageCount()-1, 1) | |
356 self.GMChatPanel.chatwnd.SetDefaultFontAndSize(self.font, self.fontsize) | |
357 | |
358 def create_whisper_tab(self, playerid): | |
359 "Add a new chatpanel directly connected to integer 'playerid' via whispering." | |
360 private_tab = chat_panel(self, -1, WHISPER_TAB, playerid) | |
361 playername = strip_html(self.MainChatPanel.session.get_player_by_player_id(playerid)[0]) | |
362 self.AddPage(private_tab, playername, False) | |
363 private_tab.chatwnd.SetDefaultFontAndSize(self.font, self.fontsize) | |
364 self.whisper_tabs.append(private_tab) | |
365 self.newMsg(self.GetPageCount()-1) | |
366 self.AliasLib = component.get('alias') | |
367 wx.CallAfter(self.AliasLib.RefreshAliases) | |
368 return private_tab | |
369 | |
370 def create_group_tab(self, group_name): | |
371 "Add a new chatpanel directly connected to integer 'playerid' via whispering." | |
372 private_tab = chat_panel(self, -1, GROUP_TAB, group_name) | |
373 self.AddPage(private_tab, group_name, False) | |
374 private_tab.chatwnd.SetDefaultFontAndSize(self.font, self.fontsize) | |
375 self.group_tabs.append(private_tab) | |
376 self.newMsg(self.GetPageCount()-1) | |
377 self.AliasLib = component.get('alias') | |
378 wx.CallAfter(self.AliasLib.RefreshAliases) | |
379 return private_tab | |
380 | |
381 def create_null_tab(self, tab_name): | |
382 "Add a new chatpanel directly connected to integer 'playerid' via whispering." | |
383 private_tab = chat_panel(self, -1, NULL_TAB, tab_name) | |
384 self.AddPage(private_tab, tab_name, False) | |
385 private_tab.chatwnd.SetDefaultFontAndSize(self.font, self.fontsize) | |
386 self.null_tabs.append(private_tab) | |
387 self.newMsg(self.GetPageCount()-1) | |
388 self.AliasLib = component.get('alias') | |
389 wx.CallAfter(self.AliasLib.RefreshAliases) | |
390 return private_tab | |
391 | |
392 def onCloseTab(self, evt): | |
393 try: tabid = evt.GetSelection() | |
394 except: tabid = self.GetSelection() | |
395 if self.GetPageText(tabid) == 'Main Room': | |
396 #send no close error to chat | |
397 evt.Veto() | |
398 return | |
399 if self.GetPageText(tabid) == 'GM': | |
400 msg = "Are You Sure You Want To Close This Page?" | |
401 dlg = wx.MessageDialog(self, msg, "NotebookCtrl Question", | |
402 wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) | |
403 if wx.Platform != '__WXMAC__': | |
404 dlg.SetFont(wx.Font(8, wx.NORMAL, wx.NORMAL, wx.NORMAL, False)) | |
405 | |
406 if dlg.ShowModal() in [wx.ID_NO]: | |
407 dlg.Destroy() | |
408 evt.Veto() | |
409 return | |
410 dlg.Destroy() | |
411 self.GMChatPanel = None | |
412 self.settings.set_setting("GMWhisperTab", "0") | |
413 panel = self.GetPage(tabid) | |
414 if panel in self.whisper_tabs: self.whisper_tabs.remove(panel) | |
415 elif panel in self.group_tabs: self.group_tabs.remove(panel) | |
416 elif panel in self.null_tabs: self.null_tabs.remove(panel) | |
417 | |
418 def newMsg(self, tabid): | |
419 if tabid != self.GetSelection(): self.SetPageImage(tabid, 0) | |
420 | |
421 def onPageChanging(self, event): | |
422 """When private chattabs are selected, set the bitmap back to 'normal'.""" | |
423 event.Skip() | |
424 | |
425 def onPageChanged(self, event): | |
426 """When private chattabs are selected, set the bitmap back to 'normal'.""" | |
427 selected_idx = event.GetSelection() | |
428 self.SetPageImage(selected_idx, 1) | |
429 page = self.GetPage(selected_idx) | |
430 event.Skip() | |
431 | |
432 """ | |
433 This class defines and builds the Chat Frame for OpenRPG | |
434 | |
435 Inherits: wxPanel | |
436 | |
437 Defines: | |
438 __init__((self, parent, id, openrpg, sendtarget) | |
439 build_ctrls(self) | |
440 on_buffer_size(self,evt) | |
441 set_colors(self) | |
442 set_buffersize(self) | |
443 set_chat_text(self,txt) | |
444 OnChar(self,event) | |
445 on_chat_save(self,evt) | |
446 on_text_color(self,event) | |
447 colorize(self, color, text) | |
448 on_text_format(self,event) | |
449 OnSize(self,event) | |
450 scroll_down(self) | |
451 InfoPost(self,s) | |
452 Post(self,s="",send=False,myself=False) | |
453 ParsePost(self,s,send=False,myself=False) | |
454 ParseDice(self,s) | |
455 ParseNodes(self,s) | |
456 get_sha_checksum(self) | |
457 get_color(self) | |
458 | |
459 """ | |
460 | |
461 class chat_panel(wx.Panel): | |
462 | |
463 """ | |
464 This is the initialization subroutine | |
465 | |
466 !self : instance of self | |
467 !parent : parent that defines the chatframe | |
468 !id : | |
469 !openrpg : | |
470 !sendtarget: who gets outbound messages: either 'all' or a playerid | |
471 """ | |
472 | |
473 | |
474 def __init__(self, parent, id, tab_type, sendtarget): | |
475 wx.Panel.__init__(self, parent, id) | |
476 logger._set_log_to_console(False) | |
477 self.session = component.get('session') | |
478 self.settings = component.get('settings') | |
479 self.activeplugins = component.get('plugins') | |
480 self.parent = parent | |
481 # who receives outbound messages, either "all" or "playerid" string | |
482 self.sendtarget = sendtarget | |
483 self.type = tab_type | |
484 self.r_h = orpg.tools.rgbhex.RGBHex() | |
485 self.h = 0 | |
486 self.set_colors() | |
487 self.version = VERSION | |
488 self.histidx = -1 | |
489 self.temptext = "" | |
490 self.history = [] | |
491 self.storedata = [] | |
492 #self.lasthistevt = None | |
493 self.parsed=0 | |
494 #chat commands | |
495 self.lockscroll = False # set the default to scrolling on. | |
496 self.chat_cmds = commands.chat_commands(self) | |
497 self.html_strip = strip_html | |
183 | 498 self.f_keys = {wx.WXK_F1: 'event.GetKeyCode() == wx.WXK_F1', wx.WXK_F2: 'event.GetKeyCode() == wx.WXK_F2', |
499 wx.WXK_F3: 'event.GetKeyCode() == wx.WXK_F3', wx.WXK_F4: 'event.GetKeyCode() == wx.WXK_F4', | |
500 wx.WXK_F5: 'event.GetKeyCode() == wx.WXK_F5', wx.WXK_F6: 'event.GetKeyCode() == wx.WXK_F6', | |
501 wx.WXK_F7: 'event.GetKeyCode() == wx.WXK_F7', wx.WXK_F8: 'event.GetKeyCode() == wx.WXK_F8', | |
502 wx.WXK_F9: 'event.GetKeyCode() == wx.WXK_F9', wx.WXK_F10: 'event.GetKeyCode() == wx.WXK_F10', | |
503 wx.WXK_F11: 'event.GetKeyCode() == wx.WXK_F11', wx.WXK_F12: 'event.GetKeyCode() == wx.WXK_F12'} | |
156 | 504 #Alias Lib stuff |
222 | 505 self.defaultAliasName = 'Real Name' |
156 | 506 self.defaultFilterName = 'No Filter' |
507 self.advancedFilter = False | |
508 self.lastSend = 0 # this is used to help implement the player typing indicator | |
509 self.lastPress = 0 # this is used to help implement the player typing indicator | |
510 self.Bind(wx.EVT_SIZE, self.OnSize) | |
184 | 511 self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnSize) |
156 | 512 self.build_ctrls() |
513 StartupFont = self.settings.get_setting("defaultfont") | |
514 StartupFontSize = self.settings.get_setting("defaultfontsize") | |
515 if(StartupFont != "") and (StartupFontSize != ""): | |
516 try: self.set_default_font(StartupFont, int(StartupFontSize)) | |
517 except: pass | |
518 self.font = self.chatwnd.GetFont().GetFaceName() | |
519 self.fontsize = self.chatwnd.GetFont().GetPointSize() | |
520 self.scroll_down() | |
521 | |
522 def set_default_font(self, fontname=None, fontsize=None): | |
523 """Set all chatpanels to new default fontname/fontsize. | |
524 Returns current font settings in a (fontname, fontsize) tuple.""" | |
525 if (fontname is not None): newfont = fontname | |
526 else: newfont = self.font | |
527 if (fontsize is not None): newfontsize = int(fontsize) | |
528 else: newfontsize = int(self.fontsize) | |
529 self.chatwnd.SetDefaultFontAndSize(newfont, newfontsize) | |
530 self.InfoPost("Font is now " + newfont + " point size " + `newfontsize`) | |
531 self.font = newfont | |
532 self.fontsize = newfontsize | |
533 return (self.font, self.fontsize) | |
534 | |
535 def build_menu(self): | |
536 top_frame = component.get('frame') | |
537 menu = wx.Menu() | |
538 item = wx.MenuItem(menu, wx.ID_ANY, "&Background color", "Background color") | |
539 top_frame.Bind(wx.EVT_MENU, self.OnMB_BackgroundColor, item) | |
540 menu.AppendItem(item) | |
541 item = wx.MenuItem(menu, wx.ID_ANY, "&Text color", "Text color") | |
542 top_frame.Bind(wx.EVT_MENU, self.OnMB_TextColor, item) | |
543 menu.AppendItem(item) | |
544 menu.AppendSeparator() | |
545 item = wx.MenuItem(menu, wx.ID_ANY, "&Chat Focus\tCtrl-H", "Chat Focus") | |
546 self.setChatFocusMenu = item | |
547 top_frame.Bind(wx.EVT_MENU, self.set_chat_text_focus, item) | |
548 menu.AppendItem(item) | |
549 menu.AppendSeparator() | |
550 item = wx.MenuItem(menu, wx.ID_ANY, "Toggle &Scroll Lock", "Toggle Scroll Lock") | |
551 top_frame.Bind(wx.EVT_MENU, self.lock_scroll, item) | |
552 menu.AppendItem(item) | |
553 item = wx.MenuItem(menu, wx.ID_ANY, "Save Chat &Log", "Save Chat Log") | |
554 top_frame.Bind(wx.EVT_MENU, self.on_chat_save, item) | |
555 menu.AppendItem(item) | |
556 item = wx.MenuItem(menu, wx.ID_ANY, "Text &View", "Text View") | |
557 top_frame.Bind(wx.EVT_MENU, self.pop_textpop, item) | |
558 menu.AppendItem(item) | |
559 item = wx.MenuItem(menu, wx.ID_ANY, "Forward Tab\tCtrl+Tab", "Swap Tabs") | |
560 top_frame.Bind(wx.EVT_MENU, self.forward_tabs, item) | |
561 menu.AppendItem(item) | |
562 item = wx.MenuItem(menu, wx.ID_ANY, "Forward Tab\tCtrl+Shift+Tab", "Swap Tabs") | |
563 top_frame.Bind(wx.EVT_MENU, self.back_tabs, item) | |
564 menu.AppendItem(item) | |
565 menu.AppendSeparator() | |
566 settingmenu = wx.Menu() | |
567 wndmenu = wx.Menu() | |
568 tabmenu = wx.Menu() | |
569 toolmenu = wx.Menu() | |
570 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Show Images", "Show Images", wx.ITEM_CHECK) | |
571 top_frame.Bind(wx.EVT_MENU, self.OnMB_ShowImages, item) | |
572 | |
573 wndmenu.AppendItem(item) | |
574 if self.settings.get_setting("Show_Images_In_Chat") == '1': item.Check(True) | |
575 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Strip HTML", "Strip HTML", wx.ITEM_CHECK) | |
576 top_frame.Bind(wx.EVT_MENU, self.OnMB_StripHTML, item) | |
577 wndmenu.AppendItem(item) | |
578 if self.settings.get_setting("striphtml") == '1': item.Check(True) | |
579 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Chat Time Index", "Chat Time Index", wx.ITEM_CHECK) | |
580 top_frame.Bind(wx.EVT_MENU, self.OnMB_ChatTimeIndex, item) | |
581 wndmenu.AppendItem(item) | |
582 if self.settings.get_setting("Chat_Time_Indexing") == '1': item.Check(True) | |
583 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Chat Auto Complete", "Chat Auto Complete", wx.ITEM_CHECK) | |
584 top_frame.Bind(wx.EVT_MENU, self.OnMB_ChatAutoComplete, item) | |
585 wndmenu.AppendItem(item) | |
586 if self.settings.get_setting("SuppressChatAutoComplete") == '0': item.Check(True) | |
587 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Show ID in Chat", "Show ID in Chat", wx.ITEM_CHECK) | |
588 top_frame.Bind(wx.EVT_MENU, self.OnMB_ShowIDinChat, item) | |
589 wndmenu.AppendItem(item) | |
590 if self.settings.get_setting("ShowIDInChat") == '1': item.Check(True) | |
591 item = wx.MenuItem(wndmenu, wx.ID_ANY, "Log Time Index", "Log Time Index", wx.ITEM_CHECK) | |
592 top_frame.Bind(wx.EVT_MENU, self.OnMB_LogTimeIndex, item) | |
593 wndmenu.AppendItem(item) | |
594 if self.settings.get_setting("TimeStampGameLog") == '1': item.Check(True) | |
595 settingmenu.AppendMenu(wx.ID_ANY, 'Chat Window', wndmenu ) | |
596 item = wx.MenuItem(tabmenu, wx.ID_ANY, "Tabbed Whispers", "Tabbed Whispers", wx.ITEM_CHECK) | |
597 top_frame.Bind(wx.EVT_MENU, self.OnMB_TabbedWhispers, item) | |
598 tabmenu.AppendItem(item) | |
599 if self.settings.get_setting("tabbedwhispers") == '1': item.Check(True) | |
600 item = wx.MenuItem(tabmenu, wx.ID_ANY, "GM Tab", "GM Tab", wx.ITEM_CHECK) | |
601 top_frame.Bind(wx.EVT_MENU, self.OnMB_GMTab, item) | |
602 tabmenu.AppendItem(item) | |
603 if self.settings.get_setting("GMWhisperTab") == '1':item.Check(True) | |
604 item = wx.MenuItem(tabmenu, wx.ID_ANY, "Group Whisper Tabs", "Group Whisper Tabs", wx.ITEM_CHECK) | |
605 top_frame.Bind(wx.EVT_MENU, self.OnMB_GroupWhisperTabs, item) | |
606 tabmenu.AppendItem(item) | |
607 if self.settings.get_setting("GroupWhisperTab") == '1': item.Check(True) | |
608 settingmenu.AppendMenu(wx.ID_ANY, 'Chat Tabs', tabmenu) | |
609 item = wx.MenuItem(toolmenu, wx.ID_ANY, "Dice Bar", "Dice Bar", wx.ITEM_CHECK) | |
610 top_frame.Bind(wx.EVT_MENU, self.OnMB_DiceBar, item) | |
611 toolmenu.AppendItem(item) | |
612 if self.settings.get_setting("DiceButtons_On") == '1': item.Check(True) | |
613 item = wx.MenuItem(toolmenu, wx.ID_ANY, "Format Buttons", "Format Buttons", wx.ITEM_CHECK) | |
614 top_frame.Bind(wx.EVT_MENU, self.OnMB_FormatButtons, item) | |
615 toolmenu.AppendItem(item) | |
616 if self.settings.get_setting("FormattingButtons_On") == '1': item.Check(True) | |
617 item = wx.MenuItem(toolmenu, wx.ID_ANY, "Alias Tool", "Alias Tool", wx.ITEM_CHECK) | |
618 top_frame.Bind(wx.EVT_MENU, self.OnMB_AliasTool, item) | |
619 toolmenu.AppendItem(item) | |
620 if self.settings.get_setting("AliasTool_On") == '1': item.Check(True) | |
621 settingmenu.AppendMenu(wx.ID_ANY, 'Chat Tool Bars', toolmenu) | |
622 menu.AppendMenu(wx.ID_ANY, 'Chat Settings', settingmenu) | |
623 top_frame.mainmenu.Insert(2, menu, '&Chat') | |
624 | |
625 ## Settings Menu Events | |
626 def OnMB_ShowImages(self, event): | |
627 if event.IsChecked(): self.settings.set_setting("Show_Images_In_Chat", '1') | |
628 else: self.settings.set_setting("Show_Images_In_Chat", '0') | |
629 | |
630 def OnMB_StripHTML(self, event): | |
631 if event.IsChecked(): self.settings.set_setting("striphtml", '1') | |
632 else: self.settings.set_setting("striphtml", '0') | |
633 | |
634 def OnMB_ChatTimeIndex(self, event): | |
635 if event.IsChecked(): self.settings.set_setting("Chat_Time_Indexing", '1') | |
636 else: self.settings.set_setting("Chat_Time_Indexing", '0') | |
637 | |
638 def OnMB_ChatAutoComplete(self, event): | |
639 if event.IsChecked(): self.settings.set_setting("SuppressChatAutoComplete", '0') | |
640 else: self.settings.set_setting("SuppressChatAutoComplete", '1') | |
641 | |
642 def OnMB_ShowIDinChat(self, event): | |
643 if event.IsChecked(): self.settings.set_setting("ShowIDInChat", '1') | |
644 else: self.settings.set_setting("ShowIDInChat", '0') | |
645 | |
646 def OnMB_LogTimeIndex(self, event): | |
647 if event.IsChecked(): self.settings.set_setting("TimeStampGameLog", '1') | |
648 else: self.settings.set_setting("TimeStampGameLog", '0') | |
649 | |
650 def OnMB_TabbedWhispers(self, event): | |
651 if event.IsChecked(): self.settings.set_setting("tabbedwhispers", '1') | |
652 else: self.settings.set_setting("tabbedwhispers", '0') | |
653 | |
654 def OnMB_GMTab(self, event): | |
655 if event.IsChecked(): | |
656 self.settings.set_setting("GMWhisperTab", '1') | |
657 self.parent.create_gm_tab() | |
658 else: self.settings.set_setting("GMWhisperTab", '0') | |
659 | |
660 def OnMB_GroupWhisperTabs(self, event): | |
661 if event.IsChecked(): self.settings.set_setting("GroupWhisperTab", '1') | |
662 else: self.settings.set_setting("GroupWhisperTab", '0') | |
663 | |
664 def OnMB_DiceBar(self, event): | |
665 act = '0' | |
666 if event.IsChecked(): | |
667 self.settings.set_setting("DiceButtons_On", '1') | |
668 act = '1' | |
669 else: self.settings.set_setting("DiceButtons_On", '0') | |
670 self.toggle_dice(act) | |
671 try: self.parent.GMChatPanel.toggle_dice(act) | |
672 except: pass | |
673 for panel in self.parent.whisper_tabs: panel.toggle_dice(act) | |
674 for panel in self.parent.group_tabs: panel.toggle_dice(act) | |
675 for panel in self.parent.null_tabs: panel.toggle_dice(act) | |
676 | |
677 def OnMB_FormatButtons(self, event): | |
678 act = '0' | |
679 if event.IsChecked(): | |
680 self.settings.set_setting("FormattingButtons_On", '1') | |
681 act = '1' | |
682 else: | |
683 self.settings.set_setting("FormattingButtons_On", '0') | |
684 self.toggle_formating(act) | |
685 try: self.parent.GMChatPanel.toggle_formating(act) | |
686 except: pass | |
687 for panel in self.parent.whisper_tabs: panel.toggle_formating(act) | |
688 for panel in self.parent.group_tabs: panel.toggle_formating(act) | |
689 for panel in self.parent.null_tabs: panel.toggle_formating(act) | |
690 | |
691 def OnMB_AliasTool(self, event): | |
692 act = '0' | |
693 if event.IsChecked(): | |
694 self.settings.set_setting("AliasTool_On", '1') | |
695 act = '1' | |
696 else: self.settings.set_setting("AliasTool_On", '0') | |
697 self.toggle_alias(act) | |
698 try: self.parent.GMChatPanel.toggle_alias(act) | |
699 except: pass | |
700 for panel in self.parent.whisper_tabs: panel.toggle_alias(act) | |
701 for panel in self.parent.group_tabs: panel.toggle_alias(act) | |
702 for panel in self.parent.null_tabs:panel.toggle_alias(act) | |
703 | |
704 def OnMB_BackgroundColor(self, event): | |
705 top_frame = component.get('frame') | |
706 hexcolor = self.get_color() | |
707 if hexcolor != None: | |
708 self.bgcolor = hexcolor | |
709 self.settings.set_setting('bgcolor', hexcolor) | |
710 self.chatwnd.SetPage(self.ResetPage()) | |
711 if self.settings.get_setting('ColorTree') == '1': | |
712 top_frame.tree.SetBackgroundColour(self.settings.get_setting('bgcolor')) | |
713 top_frame.tree.Refresh() | |
714 top_frame.players.SetBackgroundColour(self.settings.get_setting('bgcolor')) | |
715 top_frame.players.Refresh() | |
716 else: | |
717 top_frame.tree.SetBackgroundColour('white') | |
718 top_frame.tree.SetForegroundColour('black') | |
719 top_frame.tree.Refresh() | |
720 top_frame.players.SetBackgroundColour('white') | |
721 top_frame.players.SetForegroundColour('black') | |
722 top_frame.players.Refresh() | |
723 self.chatwnd.scroll_down() | |
724 | |
725 | |
726 def OnMB_TextColor(self, event): | |
727 top_frame = component.get('frame') | |
728 hexcolor = self.get_color() | |
729 if hexcolor != None: | |
730 self.textcolor = hexcolor | |
731 self.settings.set_setting('textcolor', hexcolor) | |
732 self.chatwnd.SetPage(self.ResetPage()) | |
733 if self.settings.get_setting('ColorTree') == '1': | |
734 top_frame.tree.SetForegroundColour(self.settings.get_setting('textcolor')) | |
735 top_frame.tree.Refresh() | |
736 top_frame.players.SetForegroundColour(self.settings.get_setting('textcolor')) | |
737 top_frame.players.Refresh() | |
738 else: | |
739 top_frame.tree.SetBackgroundColour('white') | |
740 top_frame.tree.SetForegroundColour('black') | |
741 top_frame.tree.Refresh() | |
742 top_frame.players.SetBackgroundColour('white') | |
743 top_frame.players.SetForegroundColour('black') | |
744 top_frame.players.Refresh() | |
745 self.chatwnd.scroll_down() | |
746 | |
747 | |
748 def get_hot_keys(self): | |
749 # dummy menus for hotkeys | |
750 self.build_menu() | |
751 entries = [] | |
752 entries.append((wx.ACCEL_CTRL, ord('H'), self.setChatFocusMenu.GetId())) | |
753 return entries | |
754 | |
755 | |
756 def forward_tabs(self, evt): | |
757 self.parent.AdvanceSelection() | |
758 | |
759 def back_tabs(self, evt): | |
760 self.parent.AdvanceSelection(False) | |
761 | |
762 def build_ctrls(self): | |
763 self.chatwnd = chat_html_window(self,-1) | |
764 self.set_colors() | |
765 wx.CallAfter(self.chatwnd.SetPage, self.chatwnd.Header()) | |
212 | 766 welcome = "<b>Welcome to <a href='http://www.knowledgearcana.com/traipse-openrpg/'>" |
767 welcome += DISTRO +'</a> '+ DIS_VER +' {'+BUILD+'},' | |
768 welcome += ' built on OpenRPG '+ VERSION +'</b>' | |
156 | 769 if (self.sendtarget == "all"): |
212 | 770 wx.CallAfter(self.Post, self.colorize(self.syscolor, welcome)) |
156 | 771 self.chattxt = orpg.tools.predTextCtrl.predTextCtrl(self, -1, "", |
772 style=wx.TE_PROCESS_ENTER |wx.TE_PROCESS_TAB|wx.TE_LINEWRAP, | |
773 keyHook = self.myKeyHook, validator=None ) | |
774 self.build_bar() | |
775 self.basesizer = wx.BoxSizer(wx.VERTICAL) | |
776 self.basesizer.Add( self.chatwnd, 1, wx.EXPAND ) | |
777 self.basesizer.Add( self.toolbar_sizer, 0, wx.EXPAND ) | |
140 | 778 self.basesizer.Add( self.chattxt, 0, wx.EXPAND ) |
156 | 779 self.SetSizer(self.basesizer) |
780 self.SetAutoLayout(True) | |
781 self.Fit() | |
782 #events | |
783 self.Bind(wx.EVT_BUTTON, self.on_text_format, self.boldButton) | |
784 self.Bind(wx.EVT_BUTTON, self.on_text_format, self.italicButton) | |
785 self.Bind(wx.EVT_BUTTON, self.on_text_format, self.underlineButton) | |
786 self.Bind(wx.EVT_BUTTON, self.on_text_color, self.color_button) | |
787 self.Bind(wx.EVT_BUTTON, self.on_chat_save, self.saveButton) | |
788 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d4Button) | |
789 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d6Button) | |
790 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d8Button) | |
791 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d10Button) | |
792 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d12Button) | |
793 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d20Button) | |
794 self.Bind(wx.EVT_BUTTON, self.onDieRoll, self.d100Button) | |
795 self.dieIDs = {} | |
796 self.dieIDs[self.d4Button.GetId()] = 'd4' | |
797 self.dieIDs[self.d6Button.GetId()] = 'd6' | |
798 self.dieIDs[self.d8Button.GetId()] = 'd8' | |
799 self.dieIDs[self.d10Button.GetId()] = 'd10' | |
800 self.dieIDs[self.d12Button.GetId()] = 'd12' | |
801 self.dieIDs[self.d20Button.GetId()] = 'd20' | |
802 self.dieIDs[self.d100Button.GetId()] = 'd100' | |
803 self.Bind(wx.EVT_BUTTON, self.pop_textpop, self.textpop_lock) | |
804 self.Bind(wx.EVT_BUTTON, self.lock_scroll, self.scroll_lock) | |
805 self.chattxt.Bind(wx.EVT_MOUSEWHEEL, self.chatwnd.mouse_wheel) | |
806 self.chattxt.Bind(wx.EVT_CHAR, self.chattxt.OnChar) | |
183 | 807 self.chattxt.Bind(wx.EVT_KEY_DOWN, self.on_chat_key_down) |
156 | 808 self.chattxt.Bind(wx.EVT_TEXT_COPY, self.chatwnd.OnM_EditCopy) |
809 | |
810 def build_bar(self): | |
811 self.toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL) | |
812 self.scroll_lock = None | |
813 self.numDieText = None | |
814 self.dieModText = None | |
815 if self.settings.get_setting('Toolbar_On') == "1": | |
816 self.build_alias() | |
817 self.build_dice() | |
818 self.build_scroll() | |
819 self.build_text() | |
820 self.toolbar_sizer.Add(self.textpop_lock, 0, wx.EXPAND) | |
821 self.toolbar_sizer.Add(self.scroll_lock, 0, wx.EXPAND) | |
822 self.build_formating() | |
823 self.build_colorbutton() | |
824 | |
825 def build_scroll(self): | |
826 self.scroll_lock = wx.Button( self, wx.ID_ANY, "Scroll ON",size= wx.Size(80,25)) | |
827 | |
135 | 828 def build_alias(self): |
156 | 829 self.aliasSizer = wx.BoxSizer(wx.HORIZONTAL) |
222 | 830 self.aliasList = wx.Choice(self, wx.ID_ANY, size=(120, 25), choices=[self.defaultAliasName]) |
156 | 831 self.aliasButton = createMaskedButton( self, dir_struct["icon"] + 'player.gif', |
140 | 832 'Refresh list of aliases from Game Tree', |
156 | 833 wx.ID_ANY, '#bdbdbd' ) |
834 self.aliasList.SetSelection(0) | |
835 self.filterList = wx.Choice(self, wx.ID_ANY, size=(100, 25), choices=[self.defaultFilterName]) | |
836 self.filterButton = createMaskedButton( self, dir_struct["icon"] + 'add_filter.gif', | |
140 | 837 'Refresh list of filters from Game Tree', |
156 | 838 wx.ID_ANY, '#bdbdbd' ) |
135 | 839 self.filterList.SetSelection(0) |
840 | |
156 | 841 self.aliasSizer.Add( self.aliasButton, 0, wx.EXPAND ) |
842 self.aliasSizer.Add( self.aliasList,0,wx.EXPAND) | |
843 self.aliasSizer.Add( self.filterButton, 0, wx.EXPAND ) | |
135 | 844 self.aliasSizer.Add( self.filterList,0,wx.EXPAND) |
845 | |
846 self.toolbar_sizer.Add(self.aliasSizer, 0, wx.EXPAND) | |
847 | |
156 | 848 if self.settings.get_setting('AliasTool_On') == '0': self.toggle_alias('0') |
849 else: self.toggle_alias('1') | |
850 | |
135 | 851 def toggle_alias(self, act): |
852 if act == '0': self.toolbar_sizer.Show(self.aliasSizer, False) | |
853 else: self.toolbar_sizer.Show(self.aliasSizer, True) | |
156 | 854 self.toolbar_sizer.Layout() |
855 | |
856 def build_text(self): | |
857 self.textpop_lock = createMaskedButton(self, dir_struct["icon"]+'note.gif', 'Open Text View Of Chat Session', wx.ID_ANY, '#bdbdbd') | |
858 | |
859 | |
140 | 860 def build_dice(self): |
156 | 861 self.diceSizer = wx.BoxSizer(wx.HORIZONTAL) |
140 | 862 self.numDieText = wx.TextCtrl( self, wx.ID_ANY, "1", |
156 | 863 size= wx.Size(25, 25), validator=orpg.tools.inputValidator.MathOnlyValidator() ) |
140 | 864 self.dieModText = wx.TextCtrl( self, wx.ID_ANY, "", |
156 | 865 size= wx.Size(50, 25), validator=orpg.tools.inputValidator.MathOnlyValidator() ) |
866 self.d4Button = createMaskedButton(self, dir_struct["icon"]+'b_d4.gif', 'Roll d4', wx.ID_ANY) | |
867 self.d6Button = createMaskedButton(self, dir_struct["icon"]+'b_d6.gif', 'Roll d6', wx.ID_ANY) | |
868 self.d8Button = createMaskedButton(self, dir_struct["icon"]+'b_d8.gif', 'Roll d8', wx.ID_ANY) | |
869 self.d10Button = createMaskedButton(self, dir_struct["icon"]+'b_d10.gif', 'Roll d10', wx.ID_ANY) | |
870 self.d12Button = createMaskedButton(self, dir_struct["icon"]+'b_d12.gif', 'Roll d12', wx.ID_ANY) | |
871 self.d20Button = createMaskedButton(self, dir_struct["icon"]+'b_d20.gif', 'Roll d20', wx.ID_ANY) | |
140 | 872 self.d100Button = createMaskedButton(self, dir_struct["icon"]+'b_d100.gif', 'Roll d100', wx.ID_ANY) |
156 | 873 |
874 self.diceSizer.Add( self.numDieText, 0, wx.ALIGN_CENTER | wx.EXPAND) | |
875 self.diceSizer.Add( self.d4Button, 0 ,wx.EXPAND) | |
876 self.diceSizer.Add( self.d6Button, 0 ,wx.EXPAND) | |
877 self.diceSizer.Add( self.d8Button, 0 ,wx.EXPAND) | |
878 self.diceSizer.Add( self.d10Button, 0 ,wx.EXPAND) | |
879 self.diceSizer.Add( self.d12Button, 0 ,wx.EXPAND) | |
880 self.diceSizer.Add( self.d20Button, 0 ,wx.EXPAND) | |
881 self.diceSizer.Add( self.d100Button, 0 ,wx.EXPAND) | |
140 | 882 self.diceSizer.Add( self.dieModText, 0, wx.ALIGN_CENTER, 5 ) |
883 | |
156 | 884 self.toolbar_sizer.Add( self.diceSizer, 0, wx.EXPAND) |
885 if self.settings.get_setting('DiceButtons_On') == '0': self.toggle_dice('0') | |
886 else: self.toggle_dice('1') | |
887 | |
888 | |
889 def toggle_dice(self, act): | |
140 | 890 if act == '0': self.toolbar_sizer.Show(self.diceSizer, False) |
891 else: self.toolbar_sizer.Show(self.diceSizer, True) | |
156 | 892 self.toolbar_sizer.Layout() |
893 | |
894 | |
140 | 895 def build_formating(self): |
156 | 896 self.formatSizer = wx.BoxSizer(wx.HORIZONTAL) |
897 self.boldButton = createMaskedButton( self, dir_struct["icon"]+'bold.gif', | |
898 'Make the selected text Bold', wx.ID_ANY, '#bdbdbd') | |
899 self.italicButton = createMaskedButton( self, dir_struct["icon"]+'italic.gif', | |
900 'Italicize the selected text', wx.ID_ANY, '#bdbdbd' ) | |
901 self.underlineButton = createMaskedButton( self, dir_struct["icon"]+'underlined.gif', | |
140 | 902 'Underline the selected text', wx.ID_ANY, '#bdbdbd' ) |
156 | 903 |
904 self.formatSizer.Add( self.boldButton, 0, wx.EXPAND ) | |
905 self.formatSizer.Add( self.italicButton, 0, wx.EXPAND ) | |
140 | 906 self.formatSizer.Add( self.underlineButton, 0, wx.EXPAND ) |
156 | 907 self.toolbar_sizer.Add( self.formatSizer, 0, wx.EXPAND ) |
908 if self.settings.get_setting('FormattingButtons_On') == '0': self.toggle_formating('0') | |
909 else: self.toggle_formating('1') | |
910 | |
911 | |
912 def toggle_formating(self, act): | |
140 | 913 if act == '0': self.toolbar_sizer.Show(self.formatSizer, False) |
914 else: self.toolbar_sizer.Show(self.formatSizer, True) | |
156 | 915 self.toolbar_sizer.Layout() |
916 | |
917 def build_colorbutton(self): | |
918 self.color_button = createMaskedButton(self, dir_struct["icon"]+'textcolor.gif', | |
919 'Text Color', wx.ID_ANY, '#bdbdbd', | |
920 wx.BITMAP_TYPE_GIF) | |
921 | |
922 self.saveButton = createMaskedButton(self, dir_struct["icon"]+'save.bmp', | |
923 'Save the chatbuffer', wx.ID_ANY, | |
924 '#c0c0c0', wx.BITMAP_TYPE_BMP ) | |
925 self.color_button.SetBackgroundColour(self.settings.get_setting('mytextcolor')) | |
926 self.toolbar_sizer.Add(self.color_button, 0, wx.EXPAND) | |
927 self.toolbar_sizer.Add(self.saveButton, 0, wx.EXPAND) | |
928 | |
929 | |
930 def OnMotion(self, evt): | |
931 contain = self.chatwnd.GetInternalRepresentation() | |
932 if contain: | |
933 sx = sy = 0 | |
934 x = y = 0 | |
935 (sx,sy) = self.chatwnd.GetViewStart() | |
936 (sx1,sy1) = self.chatwnd.GetScrollPixelsPerUnit() | |
937 sx = sx*sx1 | |
938 sy = sy*sy1 | |
939 (x,y) = evt.GetPosition() | |
940 lnk = contain.GetLink(sx+x,sy+y) | |
941 if lnk: | |
942 try: | |
943 link = lnk.GetHref() | |
944 self.session.set_status_url(link) | |
945 except: pass | |
946 else: logger.general("Error, self.chatwnd.GetInternalRepresentation() return None") | |
947 evt.Skip() | |
948 | |
949 def myKeyHook(self, event): | |
950 if self.session.get_status() == MPLAY_CONNECTED: # only do if we're connected | |
951 thisPress = time.time() # thisPress is local temp variable | |
952 if (thisPress - self.lastSend) > 4: # Check to see if it's been 5 seconds since our last notice | |
953 # If we're not already typing, then self.lastSend will be 0 | |
954 self.sendTyping(1) # send a not typing event here (1 for True) | |
955 self.lastPress = thisPress # either way, record the time of this keystroke for use in | |
956 # self.typingTimerFunc() | |
957 if self.settings.get_setting('SuppressChatAutoComplete') == '1': | |
958 logger.debug("Exit chat_panel->myKeyHook(self, event) return 1") | |
959 return 1 | |
960 else: | |
961 logger.debug("Exit chat_panel->myKeyHook(self, event) return 0") | |
962 return 0 | |
963 | |
964 def typingTimerFunc(self, event): | |
965 #following added by mDuo13 | |
966 ##############refresh_counter()############## | |
967 for plugin_fname in self.activeplugins.keys(): | |
968 plugin = self.activeplugins[plugin_fname] | |
969 try: plugin.refresh_counter() | |
970 except Exception, e: | |
971 if str(e) != "'module' object has no attribute 'refresh_counter'": | |
972 logger.general(traceback.format_exc()) | |
973 logger.general("EXCEPTION: " + str(e)) | |
974 #end mDuo13 added code | |
975 if self.lastSend: # This will be zero when not typing, so equiv to if is_typing | |
976 thisTime = time.time() # thisTime is a local temp variable | |
977 if (thisTime - self.lastPress) > 4: # Check to see if it's been 5 seconds since our last keystroke | |
978 # If we're not already typing, then self.lastSend will be 0 | |
979 | |
980 self.sendTyping(0) # send a typing event here (0 for False) | |
981 | |
982 def sendTyping(self, typing): | |
983 if typing: | |
984 self.lastSend = time.time() # remember our send time for use in myKeyHook() | |
985 #I think this is cleaner | |
986 status_text = self.settings.get_setting('TypingStatusAlias') | |
987 if status_text == "" or status_text == None: status_text = "Typing" | |
988 self.session.set_text_status(status_text) | |
989 else: | |
990 self.lastSend = 0 # set lastSend to zero to indicate we're not typing | |
991 #I think this is cleaner | |
992 status_text = self.settings.get_setting('IdleStatusAlias') | |
993 if status_text == "" or status_text == None: status_text = "Idle" | |
994 self.session.set_text_status(status_text) | |
995 | |
996 def set_colors(self): | |
997 # chat window backround color | |
998 self.bgcolor = self.settings.get_setting('bgcolor') | |
999 # chat window normal text color | |
1000 self.textcolor = self.settings.get_setting('textcolor') | |
1001 # color of text player types | |
1002 self.mytextcolor = self.settings.get_setting('mytextcolor') | |
1003 # color of system warnings | |
1004 self.syscolor = self.settings.get_setting('syscolor') | |
1005 # color of system info messages | |
1006 self.infocolor = self.settings.get_setting('infocolor') | |
1007 # color of emotes | |
1008 self.emotecolor = self.settings.get_setting('emotecolor') | |
1009 # color of whispers | |
1010 self.whispercolor = self.settings.get_setting('whispercolor') | |
1011 | |
1012 def set_chat_text(self, txt): | |
1013 self.chattxt.SetValue(txt) | |
1014 self.chattxt.SetFocus() | |
1015 self.chattxt.SetInsertionPointEnd() | |
1016 | |
1017 | |
1018 def get_chat_text(self): | |
1019 return self.chattxt.GetValue() | |
1020 | |
1021 # This subroutine sets the focus to the chat window | |
1022 | |
1023 def set_chat_text_focus(self, event): | |
1024 wx.CallAfter(self.chattxt.SetFocus) | |
183 | 1025 |
1026 def submit_chat_text(self, s): | |
1027 self.histidx = -1 | |
1028 self.temptext = "" | |
1029 self.history = [s] + self.history | |
1030 | |
1031 # play sound | |
1032 sound_file = self.settings.get_setting("SendSound") | |
1033 if sound_file != '': component.get('sound').play(sound_file) | |
1034 if s[0] != "/": ## it's not a slash command | |
212 | 1035 s = Parse.Post(s, self, True, True) |
183 | 1036 else: self.chat_cmds.docmd(s) # emote is in chatutils.py |
1037 | |
1038 def on_chat_key_down(self, event): | |
1039 s = self.chattxt.GetValue() | |
1040 if event.GetKeyCode() == wx.WXK_RETURN and not event.ShiftDown(): | |
1041 logger.debug("event.GetKeyCode() == wx.WXK_RETURN") | |
1042 self.set_colors() | |
1043 if self.session.get_status() == MPLAY_CONNECTED: | |
1044 self.sendTyping(0) | |
1045 if len(s): | |
1046 self.chattxt.SetValue('') | |
1047 s = s.replace('\n', '<br />') | |
1048 self.submit_chat_text(s) | |
1049 return | |
1050 event.Skip() | |
156 | 1051 |
1052 def OnChar(self, event): | |
1053 s = self.chattxt.GetValue() | |
1054 | |
183 | 1055 macroText = "" |
1056 s_key = False | |
1057 if self.f_keys.has_key(event.GetKeyCode()): s_key = self.f_keys[event.GetKeyCode()] | |
156 | 1058 |
183 | 1059 if s_key: macroText = settings.get(s_key[29:]) |
156 | 1060 |
1061 # Append to the existing typed text as needed and make sure the status doesn't change back. | |
1062 if len(macroText): | |
1063 self.sendTyping(0) | |
183 | 1064 self.submit_chat_text(macroText) |
156 | 1065 |
1066 ## UP KEY | |
1067 elif event.GetKeyCode() == wx.WXK_UP: | |
1068 logger.debug("event.GetKeyCode() == wx.WXK_UP") | |
1069 if self.histidx < len(self.history)-1: | |
1070 if self.histidx is -1: self.temptext = self.chattxt.GetValue() | |
1071 self.histidx += 1 | |
1072 self.chattxt.SetValue(self.history[self.histidx]) | |
1073 self.chattxt.SetInsertionPointEnd() | |
1074 else: | |
184 | 1075 self.histidx = len(self.history) -1 |
156 | 1076 |
1077 ## DOWN KEY | |
1078 elif event.GetKeyCode() == wx.WXK_DOWN: | |
1079 logger.debug("event.GetKeyCode() == wx.WXK_DOWN") | |
1080 #histidx of -1 indicates currently viewing text that's not in self.history | |
1081 if self.histidx > -1: | |
1082 self.histidx -= 1 | |
1083 if self.histidx is -1: #remember, it just decreased | |
1084 self.chattxt.SetValue(self.temptext) | |
1085 else: self.chattxt.SetValue(self.history[self.histidx]) | |
1086 self.chattxt.SetInsertionPointEnd() | |
184 | 1087 else: self.histidx = -1 |
156 | 1088 |
1089 ## TAB KEY | |
1090 elif event.GetKeyCode() == wx.WXK_TAB: | |
1091 logger.debug("event.GetKeyCode() == wx.WXK_TAB") | |
1092 if s !="": | |
1093 found = 0 | |
1094 nicks = [] | |
1095 testnick = "" | |
1096 inlength = len(s) | |
1097 for getnames in self.session.players.keys(): | |
1098 striphtmltag = re.compile ('<[^>]+>*') | |
1099 testnick = striphtmltag.sub ("", self.session.players[getnames][0]) | |
1100 if string.lower(s) == string.lower(testnick[:inlength]): | |
1101 found = found + 1 | |
1102 nicks[len(nicks):]=[testnick] | |
1103 if found == 0: ## no nick match | |
1104 self.Post(self.colorize(self.syscolor," ** No match found")) | |
1105 elif found > 1: ## matched more than 1, tell user what matched | |
1106 nickstring = "" | |
1107 nicklist = [] | |
1108 for foundnicks in nicks: | |
1109 nickstring = nickstring + foundnicks + ", " | |
1110 nicklist.append(foundnicks) | |
1111 nickstring = nickstring[:-2] | |
1112 self.Post(self.colorize(self.syscolor, " ** Multiple matches found: " + nickstring)) | |
1113 # set text to the prefix match between first two matches | |
1114 settext = re.match(''.join(map(lambda x: '(%s?)' % x, string.lower(nicklist[0]))), string.lower(nicklist[1])).group() | |
1115 # run through the rest of the nicks | |
1116 for i in nicklist: | |
1117 settext = re.match(''.join(map(lambda x: '(%s?)' % x, string.lower(i))), string.lower(settext)).group() | |
1118 if settext: | |
1119 self.chattxt.SetValue(settext) | |
1120 self.chattxt.SetInsertionPointEnd() | |
1121 else: ## put the matched name in the chattxt box | |
1122 settext = nicks[0] + ": " | |
1123 self.chattxt.SetValue(settext) | |
1124 self.chattxt.SetInsertionPointEnd() | |
1125 else: ## not online, and no text in chattxt box | |
1126 self.Post(self.colorize(self.syscolor, " ** That's the Tab key, Dave")) | |
1127 | |
1128 ## PAGE UP | |
1129 elif event.GetKeyCode() in (wx.WXK_PRIOR, wx.WXK_PAGEUP): | |
1130 logger.debug("event.GetKeyCode() in (wx.WXK_PRIOR, wx.WXK_PAGEUP)") | |
1131 self.chatwnd.ScrollPages(-1) | |
1132 if not self.lockscroll: self.lock_scroll(0) | |
1133 | |
1134 ## PAGE DOWN | |
1135 elif event.GetKeyCode() in (wx.WXK_NEXT, wx.WXK_PAGEDOWN): | |
1136 logger.debug("event.GetKeyCode() in (wx.WXK_NEXT, wx.WXK_PAGEDOWN)") | |
1137 if not self.lockscroll: self.lock_scroll(0) | |
1138 if ((self.chatwnd.GetScrollRange(1)-self.chatwnd.GetScrollPos(1)-self.chatwnd.GetScrollThumb(1) < 30) and self.lockscroll): | |
1139 self.lock_scroll(0) | |
1140 self.chatwnd.ScrollPages(1) | |
1141 | |
1142 ## END | |
1143 elif event.GetKeyCode() == wx.WXK_END: | |
1144 logger.debug("event.GetKeyCode() == wx.WXK_END") | |
1145 if self.lockscroll: | |
1146 self.lock_scroll(0) | |
1147 self.Post() | |
1148 event.Skip() | |
1149 | |
183 | 1150 elif event.GetKeyCode() == wx.WXK_RETURN and event.ShiftDown(): |
1151 st = self.chattxt.GetValue().split('\x0b') | |
1152 st += '\n' | |
1153 i = self.chattxt.GetInsertionPoint() | |
1154 self.chattxt.SetValue(''.join(st)) | |
1155 self.chattxt.SetInsertionPoint(i+1) | |
1156 return | |
1157 | |
156 | 1158 ## NOTHING |
1159 else: event.Skip() | |
1160 logger.debug("Exit chat_panel->OnChar(self, event)") | |
1161 | |
1162 def onDieRoll(self, evt): | |
1163 """Roll the dice based on the button pressed and the die modifiers entered, if any.""" | |
1164 # Get any die modifiers if they have been entered | |
1165 numDie = self.numDieText.GetValue() | |
1166 dieMod = self.dieModText.GetValue() | |
1167 dieText = numDie | |
1168 # Now, apply and roll die mods based on the button that was pressed | |
1169 id = evt.GetId() | |
1170 if self.dieIDs.has_key(id): dieText += self.dieIDs[id] | |
1171 if len(dieMod) and dieMod[0] not in "*/-+": dieMod = "+" + dieMod | |
1172 dieText += dieMod | |
1173 dieText = "[" + dieText + "]" | |
212 | 1174 Parse.Post(dieText, self, 1, 1) |
156 | 1175 self.chattxt.SetFocus() |
1176 | |
1177 def on_chat_save(self, evt): | |
1178 f = wx.FileDialog(self,"Save Chat Buffer",".","","HTM* (*.htm*)|*.htm*|HTML (*.html)|*.html|HTM (*.htm)|*.htm",wx.SAVE) | |
1179 if f.ShowModal() == wx.ID_OK: | |
1180 file = open(f.GetPath(), "w") | |
1181 file.write(self.ResetPage() + "</body></html>") | |
1182 file.close() | |
1183 f.Destroy() | |
1184 os.chdir(dir_struct["home"]) | |
1185 | |
1186 def ResetPage(self): | |
1187 self.set_colors() | |
1188 buffertext = self.chatwnd.Header() + "\n" | |
1189 buffertext += chat_util.strip_body_tags(self.chatwnd.StripHeader()).replace("<br>", | |
1190 "<br />").replace('</html>', | |
1191 '').replace("<br />", | |
1192 "<br />\n").replace("\n\n", '') | |
1193 return buffertext | |
1194 | |
1195 def on_text_color(self, event): | |
1196 hexcolor = self.r_h.do_hex_color_dlg(self) | |
1197 if hexcolor != None: | |
1198 (beg,end) = self.chattxt.GetSelection() | |
1199 if beg != end: | |
1200 txt = self.chattxt.GetValue() | |
1201 txt = txt[:beg]+self.colorize(hexcolor,txt[beg:end]) +txt[end:] | |
1202 self.chattxt.SetValue(txt) | |
1203 self.chattxt.SetInsertionPointEnd() | |
1204 self.chattxt.SetFocus() | |
1205 else: | |
1206 self.color_button.SetBackgroundColour(hexcolor) | |
1207 self.mytextcolor = hexcolor | |
1208 self.settings.set_setting('mytextcolor',hexcolor) | |
1209 self.set_colors() | |
1210 self.Post() | |
1211 | |
1212 def colorize(self, color, text): | |
1213 """Puts font tags of 'color' around 'text' value, and returns the string""" | |
1214 return "<font color='" + color + "'>" + text + "</font>" | |
1215 | |
1216 def on_text_format(self, event): | |
1217 id = event.GetId() | |
1218 txt = self.chattxt.GetValue() | |
1219 (beg,end) = self.chattxt.GetSelection() | |
1220 if beg != end: sel_txt = txt[beg:end] | |
1221 else: sel_txt = txt | |
1222 if id == self.boldButton.GetId(): sel_txt = "<b>" + sel_txt + "</b>" | |
1223 elif id == self.italicButton.GetId(): sel_txt = "<i>" + sel_txt + "</i>" | |
1224 elif id == self.underlineButton.GetId(): sel_txt = "<u>" + sel_txt + "</u>" | |
1225 if beg != end: txt = txt[:beg] + sel_txt + txt[end:] | |
1226 else: txt = sel_txt | |
1227 self.chattxt.SetValue(txt) | |
1228 self.chattxt.SetInsertionPointEnd() | |
1229 self.chattxt.SetFocus() | |
1230 | |
1231 def lock_scroll(self, event): | |
1232 if self.lockscroll: | |
1233 self.lockscroll = False | |
1234 self.scroll_lock.SetLabel("Scroll ON") | |
1235 if len(self.storedata) != 0: | |
1236 for line in self.storedata: self.chatwnd.AppendToPage(line) | |
1237 self.storedata = [] | |
1238 self.scroll_down() | |
1239 else: | |
1240 self.lockscroll = True | |
1241 self.scroll_lock.SetLabel("Scroll OFF") | |
1242 | |
1243 def pop_textpop(self, event): | |
1244 """searchable popup text view of chatbuffer""" | |
1245 h_buffertext = self.ResetPage() | |
1246 h_dlg = orpgScrolledMessageFrameEditor(self, h_buffertext, "Text View of Chat Window", None, (500,300)) | |
1247 h_dlg.Show(True) | |
1248 | |
1249 def OnSize(self, event=None): | |
1250 event.Skip() | |
1251 wx.CallAfter(self.scroll_down) | |
1252 | |
1253 def scroll_down(self): | |
1254 self.Freeze() | |
1255 self.chatwnd.scroll_down() | |
1256 self.Thaw() | |
1257 | |
1258 ###### message helpers ###### | |
1259 | |
1260 def PurgeChat(self): | |
1261 self.set_colors() | |
1262 self.chatwnd.SetPage(self.chatwnd.Header()) | |
1263 | |
1264 def system_message(self, text): | |
1265 self.send_chat_message(text,chat_msg.SYSTEM_MESSAGE) | |
1266 self.SystemPost(text) | |
1267 | |
1268 def info_message(self, text): | |
1269 self.send_chat_message(text,chat_msg.INFO_MESSAGE) | |
1270 self.InfoPost(text) | |
1271 | |
1272 def get_gms(self): | |
1273 the_gms = [] | |
1274 for playerid in self.session.players: | |
1275 if len(self.session.players[playerid])>7: | |
1276 if self.session.players[playerid][7]=="GM" and self.session.group_id != '0': the_gms += [playerid] | |
1277 return the_gms | |
1278 | |
1279 def GetName(self): | |
1280 self.AliasLib = component.get('alias') | |
1281 player = self.session.get_my_info() | |
1282 if self.AliasLib != None: | |
1283 self.AliasLib.alias = self.aliasList.GetStringSelection(); | |
1284 if self.AliasLib.alias[0] != self.defaultAliasName: | |
1285 logger.debug("Exit chat_panel->GetName(self)") | |
1286 return [self.chat_display_name([self.AliasLib.alias[0], player[1], player[2]]), self.AliasLib.alias[1]] | |
1287 return [self.chat_display_name(player), "Default"] | |
1288 | |
1289 def GetFilteredText(self, text): | |
1290 advregex = re.compile('\"(.*?)\"', re.I) | |
1291 self.AliasLib = component.get('alias') | |
1292 if self.AliasLib != None: | |
1293 self.AliasLib.filter = self.filterList.GetSelection()-1; | |
1294 for rule in self.AliasLib.filterRegEx: | |
1295 if not self.advancedFilter: text = re.sub(rule[0], rule[1], text) | |
1296 else: | |
1297 for m in advregex.finditer(text): | |
1298 match = m.group(0) | |
1299 newmatch = re.sub(rule[0], rule[1], match) | |
1300 text = text.replace(match, newmatch) | |
1301 return text | |
1302 | |
1303 def emote_message(self, text): | |
212 | 1304 text = Parse.Normalize(text, self) |
156 | 1305 text = self.colorize(self.emotecolor, text) |
1306 if self.type == MAIN_TAB and self.sendtarget == 'all': self.send_chat_message(text,chat_msg.EMOTE_MESSAGE) | |
1307 elif self.type == MAIN_TAB and self.sendtarget == "gm": | |
1308 msg_type = chat_msg.WHISPER_EMOTE_MESSAGE | |
1309 the_gms = self.get_gms() | |
1310 for each_gm in the_gms: self.send_chat_message(text,chat_msg.WHISPER_EMOTE_MESSAGE, str(each_gm)) | |
1311 elif self.type == GROUP_TAB and WG_LIST.has_key(self.sendtarget): | |
1312 for pid in WG_LIST[self.sendtarget]: | |
1313 self.send_chat_message(text,chat_msg.WHISPER_EMOTE_MESSAGE, str(pid)) | |
1314 elif self.type == WHISPER_TAB: self.send_chat_message(text,chat_msg.WHISPER_EMOTE_MESSAGE, str(self.sendtarget)) | |
1315 elif self.type == NULL_TAB: pass | |
1316 name = self.GetName()[0] | |
1317 text = "** " + name + " " + text + " **" | |
1318 self.EmotePost(text) | |
1319 | |
1320 def whisper_to_players(self, text, player_ids): | |
1321 tabbed_whispers_p = self.settings.get_setting("tabbedwhispers") | |
212 | 1322 text = Parse.Normalize(text, self) |
156 | 1323 player_names = "" |
1324 for m in player_ids: | |
1325 id = m.strip() | |
1326 if self.session.is_valid_id(id): | |
1327 returned_name = self.session.get_player_by_player_id(id)[0] | |
1328 player_names += returned_name | |
1329 player_names += ", " | |
1330 else: | |
1331 player_names += " Unknown!" | |
1332 player_names += ", " | |
1333 comma = "," | |
1334 comma.join(player_ids) | |
1335 if (self.sendtarget == "all"): | |
1336 self.InfoPost("<i>whispering to "+ player_names + " " + text + "</i> ") | |
1337 text = self.colorize(self.mytextcolor, text) | |
1338 for id in player_ids: | |
1339 id = id.strip() | |
1340 if self.session.is_valid_id(id): self.send_chat_message(text,chat_msg.WHISPER_MESSAGE,id) | |
1341 else: self.InfoPost(id + " Unknown!") | |
1342 | |
1343 | |
1344 def send_chat_message(self, text, type=chat_msg.CHAT_MESSAGE, player_id="all"): | |
1345 #########send_msg()############# | |
1346 send = 1 | |
1347 for plugin_fname in self.activeplugins.keys(): | |
1348 plugin = self.activeplugins[plugin_fname] | |
1349 try: text, send = plugin.send_msg(text, send) | |
1350 except Exception, e: | |
1351 if str(e) != "'module' object has no attribute 'send_msg'": | |
1352 logger.general(traceback.format_exc()) | |
1353 logger.general("EXCEPTION: " + str(e)) | |
1354 msg = chat_msg.chat_msg() | |
1355 msg.set_text(text) | |
1356 msg.set_type(type) | |
1357 turnedoff = False | |
1358 if self.settings.get_setting("ShowIDInChat") == "1": | |
1359 turnedoff = True | |
1360 self.settings.set_setting("ShowIDInChat", "0") | |
1361 playername = self.GetName()[0] | |
1362 | |
1363 if turnedoff: self.settings.set_setting("ShowIDInChat", "1") | |
1364 msg.set_alias(playername) | |
1365 if send: self.session.send(msg.toxml(),player_id) | |
1366 del msg | |
1367 | |
1368 def post_incoming_msg(self, msg, player): | |
1369 type = msg.get_type() | |
1370 text = msg.get_text() | |
1371 alias = msg.get_alias() | |
1372 # who sent us the message? | |
1373 if alias: display_name = self.chat_display_name([alias, player[1], player[2]]) | |
1374 elif player: display_name = self.chat_display_name(player) | |
1375 else: display_name = "Server Administrator" | |
1376 | |
1377 ######### START plugin_incoming_msg() ########### | |
1378 for plugin_fname in self.activeplugins.keys(): | |
1379 plugin = self.activeplugins[plugin_fname] | |
1380 try: text, type, name = plugin.plugin_incoming_msg(text, type, display_name, player) | |
1381 except Exception, e: | |
1382 if str(e) != "'module' object has no attribute 'receive_msg'": | |
1383 logger.general(traceback.format_exc()) | |
1384 logger.general("EXCEPTION: " + str(e)) | |
1385 strip_img = self.settings.get_setting("Show_Images_In_Chat") | |
1386 if (strip_img == "0"): display_name = chat_util.strip_img_tags(display_name) | |
1387 recvSound = "RecvSound" | |
1388 # act on the type of messsage | |
212 | 1389 |
156 | 1390 if (type == chat_msg.CHAT_MESSAGE): |
1391 text = "<b>" + display_name + "</b>: " + text | |
1392 self.Post(text) | |
1393 self.parent.newMsg(0) | |
1394 elif type == chat_msg.WHISPER_MESSAGE or type == chat_msg.WHISPER_EMOTE_MESSAGE: | |
1395 tabbed_whispers_p = self.settings.get_setting("tabbedwhispers") | |
1396 displaypanel = self | |
1397 whisperingstring = " (whispering): " | |
1398 panelexists = 0 | |
1399 GMWhisperTab = self.settings.get_setting("GMWhisperTab") | |
1400 GroupWhisperTab = self.settings.get_setting("GroupWhisperTab") | |
1401 name = '<i><b>' + display_name + '</b>: ' | |
1402 text += '</i>' | |
1403 panelexists = 0 | |
1404 created = 0 | |
1405 try: | |
1406 if GMWhisperTab == '1': | |
1407 the_gms = self.get_gms() | |
1408 #Check if whisper if from a GM | |
1409 if player[2] in the_gms: | |
1410 msg = name + ' (GM Whisper:) ' + text | |
1411 if type == chat_msg.WHISPER_MESSAGE: self.parent.GMChatPanel.Post(msg) | |
1412 else: self.parent.GMChatPanel.EmotePost("**" + msg + "**") | |
1413 idx = self.parent.get_tab_index(self.parent.GMChatPanel) | |
1414 self.parent.newMsg(idx) | |
1415 panelexists = 1 | |
1416 #See if message if from someone in our groups or for a whisper tab we already have | |
1417 if not panelexists and GroupWhisperTab == "1": | |
1418 for panel in self.parent.group_tabs: | |
1419 if WG_LIST.has_key(panel.sendtarget) and WG_LIST[panel.sendtarget].has_key(int(player[2])): | |
1420 msg = name + text | |
1421 if type == chat_msg.WHISPER_MESSAGE: panel.Post(msg) | |
1422 else: panel.EmotePost("**" + msg + "**") | |
1423 idx = self.parent.get_tab_index(panel) | |
1424 self.parent.newMsg(idx) | |
1425 panelexists = 1 | |
1426 break | |
1427 if not panelexists and tabbed_whispers_p == "1": | |
1428 for panel in self.parent.whisper_tabs: | |
1429 #check for whisper tabs as well, to save the number of loops | |
1430 if panel.sendtarget == player[2]: | |
1431 msg = name + whisperingstring + text | |
1432 if type == chat_msg.WHISPER_MESSAGE: panel.Post(msg) | |
1433 else: panel.EmotePost("**" + msg + "**") | |
1434 idx = self.parent.get_tab_index(panel) | |
1435 self.parent.newMsg(idx) | |
1436 panelexists = 1 | |
1437 break | |
1438 #We did not fint the tab | |
1439 if not panelexists: | |
1440 #If we get here the tab was not found | |
1441 if GroupWhisperTab == "1": | |
1442 for group in WG_LIST.keys(): | |
1443 #Check if this group has the player in it | |
1444 if WG_LIST[group].has_key(int(player[2])): | |
1445 #Yup, post message. Player may be in more then 1 group so continue as well | |
1446 panel = self.parent.create_group_tab(group) | |
1447 msg = name + text | |
1448 if type == chat_msg.WHISPER_MESSAGE: wx.CallAfter(panel.Post, msg) | |
1449 else: wx.CallAfter(panel.EmotePost, "**" + msg + "**") | |
1450 created = 1 | |
1451 #Check to see if we should create a whisper tab | |
1452 if not created and tabbed_whispers_p == "1": | |
1453 panel = self.parent.create_whisper_tab(player[2]) | |
1454 msg = name + whisperingstring + text | |
1455 if type == chat_msg.WHISPER_MESSAGE: wx.CallAfter(panel.Post, msg) | |
1456 else: wx.CallAfter(panel.EmotePost, "**" + msg + "**") | |
1457 created = 1 | |
1458 #Final check | |
1459 if not created: | |
1460 #No tabs to create, just send the message to the main chat tab | |
1461 msg = name + whisperingstring + text | |
1462 if type == chat_msg.WHISPER_MESSAGE: self.parent.MainChatPanel.Post(msg) | |
1463 else: self.parent.MainChatPanel.EmotePost("**" + msg + "**") | |
1464 self.parent.newMsg(0) | |
1465 except Exception, e: | |
1466 logger.general(traceback.format_exc()) | |
1467 logger.general("EXCEPTION: 'Error in posting whisper message': " + str(e)) | |
1468 elif (type == chat_msg.EMOTE_MESSAGE): | |
1469 text = "** " + display_name + " " + text + " **" | |
1470 self.EmotePost(text) | |
1471 self.parent.newMsg(0) | |
1472 elif (type == chat_msg.INFO_MESSAGE): | |
1473 text = "<b>" + display_name + "</b>: " + text | |
1474 self.InfoPost(text) | |
1475 self.parent.newMsg(0) | |
1476 elif (type == chat_msg.SYSTEM_MESSAGE): | |
1477 text = "<b>" + display_name + "</b>: " + text | |
1478 self.SystemPost(text) | |
1479 self.parent.newMsg(0) | |
1480 # playe sound | |
1481 sound_file = self.settings.get_setting(recvSound) | |
1482 if sound_file != '': | |
1483 component.get('sound').play(sound_file) | |
184 | 1484 |
156 | 1485 #### Posting helpers ##### |
1486 | |
1487 def InfoPost(self, s): | |
1488 self.Post(self.colorize(self.infocolor, s), c='info') | |
1489 | |
1490 def SystemPost(self, s): | |
1491 self.Post(self.colorize(self.syscolor, s), c='system') | |
1492 | |
1493 def EmotePost(self, s): | |
1494 self.Post(self.colorize(self.emotecolor, s), c='emote') | |
1495 | |
1496 #### Standard Post method ##### | |
1497 | |
1498 def Post(self, s="", send=False, myself=False, c='post'): | |
1499 strip_p = self.settings.get_setting("striphtml") | |
1500 strip_img = self.settings.get_setting("Show_Images_In_Chat")#moved back 7-11-05. --mDuo13 | |
1501 if (strip_p == "1"): s = strip_html(s) | |
1502 if (strip_img == "0"): s = chat_util.strip_img_tags(s) | |
1503 s = chat_util.simple_html_repair(s) | |
1504 s = chat_util.strip_script_tags(s) | |
1505 s = chat_util.strip_li_tags(s) | |
1506 s = chat_util.strip_body_tags(s) #7-27-05 mDuo13 | |
1507 s = chat_util.strip_misalignment_tags(s) #7-27-05 mDuo13 | |
1508 aliasInfo = self.GetName() | |
1509 display_name = aliasInfo[0] | |
1510 if aliasInfo[1] != 'Default': | |
1511 defaultcolor = self.settings.get_setting("mytextcolor") | |
1512 self.settings.set_setting("mytextcolor", aliasInfo[1]) | |
1513 self.set_colors() | |
1514 newline = '' | |
1515 #following added by mDuo13 | |
1516 #########post_msg() - other########## | |
1517 if not myself and not send: | |
1518 for plugin_fname in self.activeplugins.keys(): | |
1519 plugin = self.activeplugins[plugin_fname] | |
1520 try: s = plugin.post_msg(s, myself) | |
1521 except Exception, e: | |
1522 if str(e) != "'module' object has no attribute 'post_msg'": | |
1523 logger.general(traceback.format_exc()) | |
1524 logger.general("EXCEPTION: " + str(e)) | |
1525 #end mDuo13 added code | |
1526 if myself: | |
1527 name = "<b>" + display_name + "</b>: " | |
1528 s = self.colorize(self.mytextcolor, s) | |
1529 else: name = "" | |
1530 if aliasInfo[1] != 'Default': | |
1531 self.settings.set_setting("mytextcolor", defaultcolor) | |
1532 self.set_colors() | |
1533 lineHasText = 1 | |
1534 try: lineHasText = strip_html(s).replace(" ","").replace(" ","").strip()!="" | |
1535 except: | |
1536 lineHasText = 1 | |
140 | 1537 if lineHasText: |
156 | 1538 #following added by mDuo13 |
1539 if myself: | |
1540 s2 = s | |
1541 ########post_msg() - self ####### | |
1542 for plugin_fname in self.activeplugins.keys(): | |
1543 plugin = self.activeplugins[plugin_fname] | |
1544 try: | |
1545 s2 = plugin.post_msg(s2, myself) | |
1546 except Exception, e: | |
1547 if str(e) != "'module' object has no attribute 'post_msg'": | |
1548 logger.general(traceback.format_exc()) | |
1549 logger.general("EXCEPTION: " + str(e)) | |
1550 if s2 != "": | |
1551 #Italici the messages from tabbed whispers | |
1552 if self.type == WHISPER_TAB or self.type == GROUP_TAB or self.sendtarget == 'gm': | |
1553 s2 = s2 + '</i>' | |
1554 name = '<i>' + name | |
1555 if self.type == WHISPER_TAB: name += " (whispering): " | |
1556 elif self.type == GROUP_TAB: name += self.settings.get_setting("gwtext") + ' ' | |
1557 elif self.sendtarget == 'gm': name += " (whispering to GM) " | |
1558 newline = "<div class='"+c+"'> " + self.TimeIndexString() + name + s2 + "</div>" | |
1559 log( self.settings, c, name+s2 ) | |
1560 else: | |
1561 newline = "<div class='"+c+"'> " + self.TimeIndexString() + name + s + "</div>" | |
1562 log( self.settings, c, name+s ) | |
1563 else: send = False | |
1564 newline = chat_util.strip_unicode(newline) | |
140 | 1565 if self.lockscroll == 0: |
156 | 1566 self.chatwnd.AppendToPage(newline) |
1567 self.scroll_down() | |
1568 else: self.storedata.append(newline) | |
59
5aff3ef1ae46
New dev branch for Ornery Orc. Adds CSS styling to chat messages. Updates
sirebral
parents:
0
diff
changeset
|
1569 if send: |
156 | 1570 if self.type == MAIN_TAB and self.sendtarget == 'all': self.send_chat_message(s) |
1571 elif self.type == MAIN_TAB and self.sendtarget == "gm": | |
1572 the_gms = self.get_gms() | |
1573 self.whisper_to_players(s, the_gms) | |
1574 elif self.type == GROUP_TAB and WG_LIST.has_key(self.sendtarget): | |
1575 members = [] | |
1576 for pid in WG_LIST[self.sendtarget]: members.append(str(WG_LIST[self.sendtarget][pid])) | |
1577 self.whisper_to_players(self.settings.get_setting("gwtext") + s, members) | |
1578 elif self.type == WHISPER_TAB: self.whisper_to_players(s, [self.sendtarget]) | |
1579 elif self.type == NULL_TAB: pass | |
1580 else: self.InfoPost("Failed to send message, unknown send type for this tab") | |
1581 self.parsed=0 | |
1582 | |
1583 def TimeIndexString(self): | |
1584 try: | |
1585 mtime = "" | |
1586 if self.settings.get_setting('Chat_Time_Indexing') == "0": pass | |
1587 elif self.settings.get_setting('Chat_Time_Indexing') == "1": | |
1588 mtime = time.strftime("[%I:%M:%S] ", time.localtime()) | |
1589 return mtime | |
1590 except Exception, e: | |
1591 logger.general(traceback.format_exc()) | |
1592 logger.general("EXCEPTION: " + str(e)) | |
1593 return "[ERROR]" | |
1594 | |
1595 # This subroutine builds a chat display name. | |
1596 # | |
1597 def chat_display_name(self, player): | |
1598 if self.settings.get_setting("ShowIDInChat") == "0": | |
1599 display_name = player[0] | |
1600 else: | |
1601 display_name = "("+player[2]+") " + player[0] | |
1602 return display_name | |
1603 | |
1604 # This subroutine will get a hex color and return it, or return nothing | |
1605 # | |
1606 def get_color(self): | |
1607 data = wx.ColourData() | |
1608 data.SetChooseFull(True) | |
1609 dlg = wx.ColourDialog(self, data) | |
1610 if dlg.ShowModal() == wx.ID_OK: | |
1611 data = dlg.GetColourData() | |
1612 (red,green,blue) = data.GetColour().Get() | |
1613 hexcolor = self.r_h.hexstring(red, green, blue) | |
1614 dlg.Destroy() | |
1615 return hexcolor | |
1616 else: | |
1617 dlg.Destroy() | |
1618 return None | |
184 | 1619 |
156 | 1620 # def get_color - end |
1621 def replace_quotes(self, s): | |
1622 in_tag = 0 | |
1623 i = 0 | |
1624 rs = s[:] | |
1625 for c in s: | |
171 | 1626 if c == "<": in_tag += 1 |
156 | 1627 elif c == ">": |
171 | 1628 if in_tag: in_tag -= 1 |
156 | 1629 elif c == '"': |
171 | 1630 if in_tag: rs = rs[:i] + "'" + rs[i+1:] |
156 | 1631 i += 1 |
1632 return rs | |
1633 |