Mercurial > traipse_dev
comparison orpg/tools/predTextCtrl.py @ 135:dcf4fbe09b70 beta
Traipse Beta 'OpenRPG' {091010-00}
Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on
code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to
offer more advanced features and enhance the productivity of the user.
Update Summary (Beta)
Added Bookmarks
Fix to Remote Admin Commands
Minor fix to text based Server
Fix to Pretty Print, from Core
Fix to Splitter Nodes not being created
Fix to massive amounts of images loading, from Core
Added 'boot' command to remote admin
Added confirmation window for sent nodes
Minor changes to allow for portability to an OpenSUSE linux OS
Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG
Zoom Mouse plugin added
Images added to Plugin UI
Switching to Element Tree
Map efficiency, from FlexiRPG
Added Status Bar to Update Manager
default_manifest.xml renamed to default_upmana.xml
Cleaner clode for saved repositories
New TrueDebug Class in orpg_log (See documentation for usage)
Mercurial's hgweb folder is ported to upmana
**Pretty important update that can help remove thousands of dead children from your gametree.
**Children, <forms />, <group_atts />, <horizontal />, <cols />, <rows />, <height />, etc... are all tags now. Check your gametree and
look for dead children!!
**New Gamtree Recusion method, mapping, and context sensitivity. !!Alpha - Watch out for infinite loops!!
author | sirebral |
---|---|
date | Tue, 10 Nov 2009 14:11:28 -0600 |
parents | 118fbe111922 |
children | 9babc183fa47 |
comparison
equal
deleted
inserted
replaced
101:394ebb3b6a0f | 135:dcf4fbe09b70 |
---|---|
31 ## Module Loading | 31 ## Module Loading |
32 ## | 32 ## |
33 | 33 |
34 import string | 34 import string |
35 from orpg.orpg_windows import * | 35 from orpg.orpg_windows import * |
36 import wx #wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X) | |
36 from wx.lib.expando import ExpandoTextCtrl | 37 from wx.lib.expando import ExpandoTextCtrl |
37 from orpg.tools.orpg_log import logger | 38 from orpg.tools.orpg_log import logger, debug |
38 | 39 |
39 # This line added to test CVS commit | 40 # This line added to test CVS commit |
40 | 41 |
41 ## | 42 ## |
42 ## Class Definitions | 43 ## Class Definitions |
120 # | 121 # |
121 # Returns: None | 122 # Returns: None |
122 # | 123 # |
123 # Purpose: Sets or increments the priority of a word, adding the word if necessary | 124 # Purpose: Sets or increments the priority of a word, adding the word if necessary |
124 def setWord(self,wordText,priority = 1,sumFlag = 0): | 125 def setWord(self,wordText,priority = 1,sumFlag = 0): |
125 | |
126 cur = self.rootNode # start from the root | 126 cur = self.rootNode # start from the root |
127 | |
128 for ch in wordText: # for each character in the word | 127 for ch in wordText: # for each character in the word |
129 if cur.children.has_key(ch): # check to see if we've found a new word | 128 if cur.children.has_key(ch): # check to see if we've found a new word |
130 | |
131 cur = cur.children[ch] # if we haven't found a new word, move to the next letter and try again | 129 cur = cur.children[ch] # if we haven't found a new word, move to the next letter and try again |
132 | |
133 else: # in this clause, we're creating a new branch, as the word is new | 130 else: # in this clause, we're creating a new branch, as the word is new |
134 newLetter = Letter(ch,cur) # create a new class Letter using this ascii code and the current letter as a parent | 131 newLetter = Letter(ch,cur) # create a new class Letter using this ascii code and the current letter as a parent |
135 | |
136 if cur is self.rootNode: # special case: Others expect the top level letters to point to None, not self.rootNode | 132 if cur is self.rootNode: # special case: Others expect the top level letters to point to None, not self.rootNode |
137 newLetter.parentNode = None | 133 newLetter.parentNode = None |
138 | |
139 cur.children[ch] = newLetter # add the new letter to the list of children of the current letter | 134 cur.children[ch] = newLetter # add the new letter to the list of children of the current letter |
140 cur = newLetter # make the new letter the current one for the next time through | 135 cur = newLetter # make the new letter the current one for the next time through |
141 | 136 |
142 # at this point, cur is pointing to the last letter of either a new or existing word. | 137 # at this point, cur is pointing to the last letter of either a new or existing word. |
143 | 138 if sumFlag: cur.priority += priority # if the caller wants to add to the existing (0 if new) |
144 if sumFlag: # if the caller wants to add to the existing (0 if new) | 139 else: cur.priority = priority # else, the set the priority directly |
145 cur.priority += priority | |
146 else: # else, the set the priority directly | |
147 cur.priority = priority | |
148 | |
149 self.updateMostCommon(cur) # this will run back through the tree to fix up the mostCommon members | 140 self.updateMostCommon(cur) # this will run back through the tree to fix up the mostCommon members |
150 | |
151 | 141 |
152 # addWord subroutine. | 142 # addWord subroutine. |
153 # | 143 # |
154 # self : instance of self | 144 # self : instance of self |
155 # wordText : string representing word to add | 145 # wordText : string representing word to add |
158 # | 148 # |
159 # Purpose: Convenience method that wraps setWord. Used to add words known not to exist. | 149 # Purpose: Convenience method that wraps setWord. Used to add words known not to exist. |
160 def addWord(self,wordText): | 150 def addWord(self,wordText): |
161 self.setWord(wordText,priority = 1) | 151 self.setWord(wordText,priority = 1) |
162 | 152 |
163 | |
164 # incWord subroutine. | 153 # incWord subroutine. |
165 # | 154 # |
166 # self : instance of self | 155 # self : instance of self |
167 # wordText : string representing word to add | 156 # wordText : string representing word to add |
168 # | 157 # |
169 # Returns: None | 158 # Returns: None |
170 # | 159 # |
171 # Purpose: Convenience method that wraps setWord. Used to increment the priority of existing words and add new words. | 160 # Purpose: Convenience method that wraps setWord. Used to increment the priority of existing words and add new words. |
172 # Note: Generally, this method can be used instead of addWord. | 161 # Note: Generally, this method can be used instead of addWord. |
162 | |
173 def incWord(self,wordText): | 163 def incWord(self,wordText): |
174 self.setWord(wordText,priority = 1, sumFlag = 1) | 164 self.setWord(wordText,priority = 1, sumFlag = 1) |
175 | 165 |
176 | |
177 # setWordPriority subroutine. | 166 # setWordPriority subroutine. |
178 # | 167 # |
179 # self : instance of self | 168 # self : instance of self |
180 # wordText : string representing word to add | 169 # wordText : string representing word to add |
181 # priority: int that is the new priority | 170 # priority: int that is the new priority |
182 # | 171 # |
183 # Returns: None | 172 # Returns: None |
184 # | 173 # |
185 # Purpose: Convenience method that wraps setWord. Sets existing words to priority or adds new words with priority = priority | 174 # Purpose: Convenience method that wraps setWord. Sets existing words to priority or adds new words with priority = priority |
175 | |
186 def setWordPriority(self,wordText,priority): | 176 def setWordPriority(self,wordText,priority): |
187 self.setWord(wordText,priority = priority) | 177 self.setWord(wordText,priority = priority) |
188 | 178 |
189 | 179 |
190 # findWordNode subroutine. | 180 # findWordNode subroutine. |
194 # | 184 # |
195 # Returns: class Letter or None if word isn't found. | 185 # Returns: class Letter or None if word isn't found. |
196 # | 186 # |
197 # Purpose: Given a word, it returns the class Letter node that corresponds to the word. Used mostly in prep for a call to | 187 # Purpose: Given a word, it returns the class Letter node that corresponds to the word. Used mostly in prep for a call to |
198 # getPrediction() | 188 # getPrediction() |
189 | |
199 def findWordNode(self,wordText): #returns class Letter that represents the last letter in the word | 190 def findWordNode(self,wordText): #returns class Letter that represents the last letter in the word |
200 | |
201 cur = self.rootNode # start at the root | 191 cur = self.rootNode # start at the root |
202 | |
203 for ch in wordText: # move through each letter in the word | 192 for ch in wordText: # move through each letter in the word |
204 if cur.children.has_key(ch): # if the next letter exists, make cur equal that letter and loop | 193 if cur.children.has_key(ch): # if the next letter exists, make cur equal that letter and loop |
205 cur = cur.children[ch] | 194 cur = cur.children[ch] |
206 else: | 195 else: return None # return None if letter not found |
207 return None # return None if letter not found | |
208 | |
209 return cur # return cur, as this points to the last letter if we got this far | 196 return cur # return cur, as this points to the last letter if we got this far |
210 | 197 |
211 | 198 |
212 # findWordPriority subroutine. | 199 # findWordPriority subroutine. |
213 # | 200 # |
215 # wordText : string representing word to add | 202 # wordText : string representing word to add |
216 # | 203 # |
217 # Returns: Int representing the word's priority or 0 if not found. | 204 # Returns: Int representing the word's priority or 0 if not found. |
218 # | 205 # |
219 # Purpose: Returns the priority of the given word | 206 # Purpose: Returns the priority of the given word |
207 | |
220 def findWordPriority(self,wordText): | 208 def findWordPriority(self,wordText): |
221 | 209 |
222 cur = self.findWordNode(wordText) # find the class Letter node that corresponds to this word | 210 cur = self.findWordNode(wordText) # find the class Letter node that corresponds to this word |
223 if cur: | 211 if cur: return cur.priority # if it was found, return it's priority |
224 return cur.priority # if it was found, return it's priority | 212 else: return 0 # else, return 0, meaning word not found |
225 else: | |
226 return 0 # else, return 0, meaning word not found | |
227 | |
228 | 213 |
229 def printTree(self, current=None): | 214 def printTree(self, current=None): |
230 letters = [] | 215 letters = [] |
231 if current is None: | 216 if current is None: |
232 current = self.rootNode | 217 current = self.rootNode |
233 | |
234 for l, letter in current.children.iteritems(): | 218 for l, letter in current.children.iteritems(): |
235 letters.append(str(letter)) | 219 letters.append(str(letter)) |
236 if letter.children != {}: | 220 if letter.children != {}: |
237 m = self.printTree(letter) | 221 m = self.printTree(letter) |
238 letters.append(m) | 222 letters.append(m) |
239 | |
240 return letters | 223 return letters |
241 | |
242 | |
243 | 224 |
244 # getPrediction subroutine. | 225 # getPrediction subroutine. |
245 # | 226 # |
246 # self : instance of self | 227 # self : instance of self |
247 # k : ASCII char that was typed | 228 # k : ASCII char that was typed |
338 else: | 319 else: |
339 ExpandoTextCtrl.__init__(self, parent, id=id, value=value, size=size, style=style, name=name) | 320 ExpandoTextCtrl.__init__(self, parent, id=id, value=value, size=size, style=style, name=name) |
340 | 321 |
341 self.tree = LetterTree # Instantiate a new LetterTree. | 322 self.tree = LetterTree # Instantiate a new LetterTree. |
342 # TODO: make name of word file an argument. | 323 # TODO: make name of word file an argument. |
343 | 324 self.parent = parent # Save parent for later use in passing KeyEvents |
344 | 325 self.cur = self.tree.rootNode # self.cur is a short cut placeholder for typing consecutive chars |
345 | 326 # It may be vestigal |
346 | 327 self.keyHook = keyHook # Save the keyHook passed in |
347 self.parent = parent # Save parent for later use in passing KeyEvents | 328 ExpandoTextCtrl._wrapLine = self._wrapLine |
348 | 329 |
349 self.cur = self.tree.rootNode # self.cur is a short cut placeholder for typing consecutive chars | 330 |
350 # It may be vestigal | 331 def _wrapLine(self, line, dc, width): |
351 | 332 # Estimate where the control will wrap the lines and |
352 self.keyHook = keyHook # Save the keyHook passed in | 333 # return the count of extra lines needed. |
353 | 334 # Re writes ExpandoTextCtrl _wrapLine function |
335 pte = dc.GetPartialTextExtents(line) | |
336 width -= wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X) | |
337 idx = 0 | |
338 start = 0 | |
339 count = 0 | |
340 spc = -1 | |
341 while idx < len(pte): | |
342 if line[idx] == ' ': debug((line)); spc = idx | |
343 if pte[idx] - start > width: | |
344 # we've reached the max width, add a new line | |
345 count += 1 | |
346 # did we see a space? if so restart the count at that pos | |
347 if spc != -1: | |
348 idx = spc + 1 | |
349 spc = -1 | |
350 start = pte[idx] | |
351 else: | |
352 idx += 1 | |
353 return count | |
354 | 354 |
355 # findWord subroutine. | 355 # findWord subroutine. |
356 # | 356 # |
357 # self : instance of self | 357 # self : instance of self |
358 # insert: index of last char in st | 358 # insert: index of last char in st |
366 # Returns: String that is the word or "" if none found. This generally doesn't | 366 # Returns: String that is the word or "" if none found. This generally doesn't |
367 # happen, as st usually ends in a letter, which will be returned. | 367 # happen, as st usually ends in a letter, which will be returned. |
368 # | 368 # |
369 # Purpose: This function is generally used to figure out the beginning of the | 369 # Purpose: This function is generally used to figure out the beginning of the |
370 # current word being typed, for later use in a LetterTree.getPrediction() | 370 # current word being typed, for later use in a LetterTree.getPrediction() |
371 def findWord(self,insert,st): | 371 def findWord(self, insert, st): |
372 | 372 |
373 # Good luck reading this one. Basically, I started out with an idea, and fiddled with the | 373 # Good luck reading this one. Basically, I started out with an idea, and fiddled with the |
374 # constants as best I could until it worked. It's not a piece of work of which I'm too | 374 # constants as best I could until it worked. It's not a piece of work of which I'm too |
375 # proud. Basically, it's intent is to check each character to the left until it finds one | 375 # proud. Basically, it's intent is to check each character to the left until it finds one |
376 # that isn't a letter. If it finds such a character, it stops and returns the slice | 376 # that isn't a letter. If it finds such a character, it stops and returns the slice |
402 if(self.keyHook): | 402 if(self.keyHook): |
403 if self.keyHook(event) == 1: # if the passed in keyHook routine returns a one, it wants no predictive behavior | 403 if self.keyHook(event) == 1: # if the passed in keyHook routine returns a one, it wants no predictive behavior |
404 self.parent.OnChar(event) | 404 self.parent.OnChar(event) |
405 return | 405 return |
406 | 406 |
407 | |
408 | |
409 # This bit converts the GetKeyCode() return (int) to a char if it's in a certain range | 407 # This bit converts the GetKeyCode() return (int) to a char if it's in a certain range |
410 asciiKey = "" | 408 asciiKey = "" |
411 if (event.GetKeyCode() < 256) and (event.GetKeyCode() > 19): | 409 if (event.GetKeyCode() < 256) and (event.GetKeyCode() > 19): |
412 asciiKey = chr(event.GetKeyCode()) | 410 asciiKey = chr(event.GetKeyCode()) |
413 | 411 |
414 | 412 if asciiKey == "": # If we didn't convert it to a char, then process based on the int GetKeyCodes |
415 if asciiKey == "": # If we didn't convert it to a char, then process based on the int GetKeyCodes | 413 if event.GetKeyCode() == wx.WXK_TAB: # We want to hook tabs to allow the user to signify acceptance of a |
416 | 414 # predicted word. |
417 if event.GetKeyCode() == wx.WXK_TAB: # We want to hook tabs to allow the user to signify acceptance of a | |
418 # predicted word. | |
419 # Handle Tab key | 415 # Handle Tab key |
420 | 416 fromPos = toPos = 0 # get the current selection range |
421 fromPos = toPos = 0 # get the current selection range | |
422 (fromPos,toPos) = self.GetSelection() | 417 (fromPos,toPos) = self.GetSelection() |
423 | 418 if (toPos - fromPos) == 0: # if there is no selection, pass tab on |
424 if (toPos - fromPos) == 0: # if there is no selection, pass tab on | |
425 self.parent.OnChar(event) | 419 self.parent.OnChar(event) |
426 return | 420 return |
427 | |
428 else: # This means at least one char is selected | 421 else: # This means at least one char is selected |
429 | |
430 self.SetInsertionPoint(toPos) # move the insertion point to the end of the selection | 422 self.SetInsertionPoint(toPos) # move the insertion point to the end of the selection |
431 self.SetSelection(toPos,toPos) # and set the selection to no chars | 423 self.SetSelection(toPos,toPos) # and set the selection to no chars |
432 # The prediction, if any, had been inserted into the text earlier, so | 424 # The prediction, if any, had been inserted into the text earlier, so |
433 # moving the insertion point to the spot directly afterwards is | 425 # moving the insertion point to the spot directly afterwards is |
434 # equivalent to acceptance. Without this, the next typed key would | 426 # equivalent to acceptance. Without this, the next typed key would |
439 logger.exception('Shift + Enter Not completed, 439, predtextCtrl', True) | 431 logger.exception('Shift + Enter Not completed, 439, predtextCtrl', True) |
440 st = self.GetValue() | 432 st = self.GetValue() |
441 st += '<br />' | 433 st += '<br />' |
442 return | 434 return |
443 | 435 |
444 | |
445 elif event.GetKeyCode() == wx.WXK_RETURN: # We want to hook returns, so that we can update the word list | 436 elif event.GetKeyCode() == wx.WXK_RETURN: # We want to hook returns, so that we can update the word list |
446 | |
447 st = self.GetValue() # Grab the text from the control | 437 st = self.GetValue() # Grab the text from the control |
448 newSt = "" # Init a buffer | 438 newSt = "" # Init a buffer |
449 | |
450 # This block of code, by popular demand, changes the behavior of the control to ignore any prediction that | 439 # This block of code, by popular demand, changes the behavior of the control to ignore any prediction that |
451 # hasn't been "accepted" when the enter key is struck. | 440 # hasn't been "accepted" when the enter key is struck. |
452 (startSel,endSel) = self.GetSelection() # get the curren selection | 441 (startSel,endSel) = self.GetSelection() # get the curren selection |
453 | 442 |
454 # | 443 # |
473 for ch in st: | 462 for ch in st: |
474 if ch not in string.letters: | 463 if ch not in string.letters: |
475 newSt += " " | 464 newSt += " " |
476 else: | 465 else: |
477 newSt += ch | 466 newSt += ch |
478 | |
479 # Now that we've got a string of just letter sequences (words) and spaces | 467 # Now that we've got a string of just letter sequences (words) and spaces |
480 # split it and to a LetterTree.incWord on the lowercase version of it. | 468 # split it and to a LetterTree.incWord on the lowercase version of it. |
481 # Reminder: incWord will increment the priority of existing words and add | 469 # Reminder: incWord will increment the priority of existing words and add |
482 # new ones | 470 # new ones |
483 for aWord in string.split(newSt): | 471 for aWord in string.split(newSt): |
500 elif event.GetKeyCode() == wx.WXK_LEFT: | 488 elif event.GetKeyCode() == wx.WXK_LEFT: |
501 (startSel,endSel) = self.GetSelection() | 489 (startSel,endSel) = self.GetSelection() |
502 self.SetInsertionPoint(startSel) | 490 self.SetInsertionPoint(startSel) |
503 self.parent.OnChar(event) | 491 self.parent.OnChar(event) |
504 return | 492 return |
505 | |
506 | |
507 else: | 493 else: |
508 # Handle any other non-ascii events by calling parent's OnChar() | 494 # Handle any other non-ascii events by calling parent's OnChar() |
509 self.parent.OnChar(event) #Call super.OnChar to get default behavior | 495 self.parent.OnChar(event) #Call super.OnChar to get default behavior |
510 return | 496 return |
511 | |
512 | |
513 elif asciiKey in string.letters: | 497 elif asciiKey in string.letters: |
514 # This is the real meat and potatoes of predTextCtrl. This is where most of the | 498 # This is the real meat and potatoes of predTextCtrl. This is where most of the |
515 # wx.TextCtrl logic is changed. | 499 # wx.TextCtrl logic is changed. |
516 | |
517 (startSel,endSel) = self.GetSelection() # get the curren selection | 500 (startSel,endSel) = self.GetSelection() # get the curren selection |
518 st = self.GetValue() # and the text in the control | 501 st = self.GetValue() # and the text in the control |
519 front = st[:startSel] # Slice off the text to the front of where we are | 502 front = st[:startSel] # Slice off the text to the front of where we are |
520 back = st[endSel:] # Slice off the text to the end from where we are | 503 back = st[endSel:] # Slice off the text to the end from where we are |
521 | |
522 st = front + asciiKey + back # This expression creates a string that will insert the | 504 st = front + asciiKey + back # This expression creates a string that will insert the |
523 # typed character (asciiKey is generated at the | 505 # typed character (asciiKey is generated at the |
524 # beginning of OnChar()) into the text. If there | 506 # beginning of OnChar()) into the text. If there |
525 # was text selected, that text will not be part | 507 # was text selected, that text will not be part |
526 # of the new string, due to the way front and back | 508 # of the new string, due to the way front and back |
527 # were sliced. | 509 # were sliced. |
528 | 510 |
529 insert = startSel + 1 # creates an int that denotes where the new InsertionPoint | 511 insert = startSel + 1 # creates an int that denotes where the new InsertionPoint |
530 # should be. | 512 # should be. |
531 | |
532 curWord = "" # Assume there's a problem with finding the curWord | 513 curWord = "" # Assume there's a problem with finding the curWord |
533 | |
534 if (len(back) == 0) or (back[0] not in string.letters): # We should only insert a prediction if we are typing | 514 if (len(back) == 0) or (back[0] not in string.letters): # We should only insert a prediction if we are typing |
535 # at the end of a word, not in the middle. There are | 515 # at the end of a word, not in the middle. There are |
536 # three cases: we are typing at the end of the string or | 516 # three cases: we are typing at the end of the string or |
537 # we are typing in the middle of the string and the next | 517 # we are typing in the middle of the string and the next |
538 # char is NOT a letter or we are typing in the middle of the | 518 # char is NOT a letter or we are typing in the middle of the |
609 # s/he must strike the tab key at this point. Of course, one could | 589 # s/he must strike the tab key at this point. Of course, one could |
610 # just use the right arrow key as well, but that's not as easy to | 590 # just use the right arrow key as well, but that's not as easy to |
611 # reach. | 591 # reach. |
612 | 592 |
613 return # Done! Do NOT pass the event on at this point, because it's all done. | 593 return # Done! Do NOT pass the event on at this point, because it's all done. |
614 | |
615 | |
616 else: | 594 else: |
617 # Handle every other non-letter ascii (e.g. semicolon) by passing the event on. | 595 # Handle every other non-letter ascii (e.g. semicolon) by passing the event on. |
618 self.parent.OnChar(event) #Call super.OnChar to get default behavior | 596 self.parent.OnChar(event) #Call super.OnChar to get default behavior |
619 return | 597 return |
620 | |
621 # End of class predTextCtrl! | 598 # End of class predTextCtrl! |