comparison orpg/tools/predTextCtrl.py @ 127:0f720618a8bd alpha

Traipse Alpha 'OpenRPG' {091002-01} 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 (Cleaning up for 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 Happy Halloween!
author sirebral
date Mon, 02 Nov 2009 19:20:46 -0600
parents 36919b8a3ef9
children dc74dca250d1
comparison
equal deleted inserted replaced
126:e7f990be5075 127:0f720618a8bd
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
348
349 self.cur = self.tree.rootNode # self.cur is a short cut placeholder for typing consecutive chars
350 # It may be vestigal
351
352 self.keyHook = keyHook # Save the keyHook passed in
353 ExpandoTextCtrl._wrapLine = self._wrapLine 328 ExpandoTextCtrl._wrapLine = self._wrapLine
354 329
355 330
356 def _wrapLine(self, line, dc, width): 331 def _wrapLine(self, line, dc, width):
357 # Estimate where the control will wrap the lines and 332 # Estimate where the control will wrap the lines and
358 # return the count of extra lines needed. 333 # return the count of extra lines needed.
359 # Re writes ExpandoTextCtrl _wrapLine function 334 # Re writes ExpandoTextCtrl _wrapLine function
360 print 'New _wrapLine Function'
361 pte = dc.GetPartialTextExtents(line) 335 pte = dc.GetPartialTextExtents(line)
362 width -= wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X) 336 width -= wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X)
363 idx = 0 337 idx = 0
364 start = 0 338 start = 0
365 count = 0 339 count = 0
366 spc = -1 340 spc = -1
367 while idx < len(pte): 341 while idx < len(pte):
368 if line[idx] == ' ': spc = idx 342 if line[idx] == ' ': debug((line)); spc = idx
369 if pte[idx] - start > width: 343 if pte[idx] - start > width:
370 # we've reached the max width, add a new line 344 # we've reached the max width, add a new line
371 count += 1 345 count += 1
372 # did we see a space? if so restart the count at that pos 346 # did we see a space? if so restart the count at that pos
373 if spc != -1: 347 if spc != -1:
374 idx = spc + 1 348 idx = spc + 1
375 spc = -1 349 spc = -1
376 start = pte[idx] 350 start = pte[idx]
377 else: 351 else:
378 idx += 1 352 idx += 1
379 return count 353 return count
380 354
381 # findWord subroutine. 355 # findWord subroutine.
382 # 356 #
383 # self : instance of self 357 # self : instance of self
392 # 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
393 # 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.
394 # 368 #
395 # 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
396 # current word being typed, for later use in a LetterTree.getPrediction() 370 # current word being typed, for later use in a LetterTree.getPrediction()
397 def findWord(self,insert,st): 371 def findWord(self, insert, st):
398 372
399 # 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
400 # 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
401 # 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
402 # 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
428 if(self.keyHook): 402 if(self.keyHook):
429 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
430 self.parent.OnChar(event) 404 self.parent.OnChar(event)
431 return 405 return
432 406
433
434
435 # 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
436 asciiKey = "" 408 asciiKey = ""
437 if (event.GetKeyCode() < 256) and (event.GetKeyCode() > 19): 409 if (event.GetKeyCode() < 256) and (event.GetKeyCode() > 19):
438 asciiKey = chr(event.GetKeyCode()) 410 asciiKey = chr(event.GetKeyCode())
439 411
440 412 if asciiKey == "": # If we didn't convert it to a char, then process based on the int GetKeyCodes
441 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
442 414 # predicted word.
443 if event.GetKeyCode() == wx.WXK_TAB: # We want to hook tabs to allow the user to signify acceptance of a
444 # predicted word.
445 # Handle Tab key 415 # Handle Tab key
446 416 fromPos = toPos = 0 # get the current selection range
447 fromPos = toPos = 0 # get the current selection range
448 (fromPos,toPos) = self.GetSelection() 417 (fromPos,toPos) = self.GetSelection()
449 418 if (toPos - fromPos) == 0: # if there is no selection, pass tab on
450 if (toPos - fromPos) == 0: # if there is no selection, pass tab on
451 self.parent.OnChar(event) 419 self.parent.OnChar(event)
452 return 420 return
453
454 else: # This means at least one char is selected 421 else: # This means at least one char is selected
455
456 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
457 self.SetSelection(toPos,toPos) # and set the selection to no chars 423 self.SetSelection(toPos,toPos) # and set the selection to no chars
458 # 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
459 # moving the insertion point to the spot directly afterwards is 425 # moving the insertion point to the spot directly afterwards is
460 # equivalent to acceptance. Without this, the next typed key would 426 # equivalent to acceptance. Without this, the next typed key would
465 logger.exception('Shift + Enter Not completed, 439, predtextCtrl', True) 431 logger.exception('Shift + Enter Not completed, 439, predtextCtrl', True)
466 st = self.GetValue() 432 st = self.GetValue()
467 st += '<br />' 433 st += '<br />'
468 return 434 return
469 435
470
471 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
472
473 st = self.GetValue() # Grab the text from the control 437 st = self.GetValue() # Grab the text from the control
474 newSt = "" # Init a buffer 438 newSt = "" # Init a buffer
475
476 # 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
477 # hasn't been "accepted" when the enter key is struck. 440 # hasn't been "accepted" when the enter key is struck.
478 (startSel,endSel) = self.GetSelection() # get the curren selection 441 (startSel,endSel) = self.GetSelection() # get the curren selection
479 442
480 # 443 #
499 for ch in st: 462 for ch in st:
500 if ch not in string.letters: 463 if ch not in string.letters:
501 newSt += " " 464 newSt += " "
502 else: 465 else:
503 newSt += ch 466 newSt += ch
504
505 # 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
506 # 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.
507 # Reminder: incWord will increment the priority of existing words and add 469 # Reminder: incWord will increment the priority of existing words and add
508 # new ones 470 # new ones
509 for aWord in string.split(newSt): 471 for aWord in string.split(newSt):
526 elif event.GetKeyCode() == wx.WXK_LEFT: 488 elif event.GetKeyCode() == wx.WXK_LEFT:
527 (startSel,endSel) = self.GetSelection() 489 (startSel,endSel) = self.GetSelection()
528 self.SetInsertionPoint(startSel) 490 self.SetInsertionPoint(startSel)
529 self.parent.OnChar(event) 491 self.parent.OnChar(event)
530 return 492 return
531
532
533 else: 493 else:
534 # Handle any other non-ascii events by calling parent's OnChar() 494 # Handle any other non-ascii events by calling parent's OnChar()
535 self.parent.OnChar(event) #Call super.OnChar to get default behavior 495 self.parent.OnChar(event) #Call super.OnChar to get default behavior
536 return 496 return
537
538
539 elif asciiKey in string.letters: 497 elif asciiKey in string.letters:
540 # 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
541 # wx.TextCtrl logic is changed. 499 # wx.TextCtrl logic is changed.
542
543 (startSel,endSel) = self.GetSelection() # get the curren selection 500 (startSel,endSel) = self.GetSelection() # get the curren selection
544 st = self.GetValue() # and the text in the control 501 st = self.GetValue() # and the text in the control
545 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
546 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
547
548 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
549 # typed character (asciiKey is generated at the 505 # typed character (asciiKey is generated at the
550 # beginning of OnChar()) into the text. If there 506 # beginning of OnChar()) into the text. If there
551 # was text selected, that text will not be part 507 # was text selected, that text will not be part
552 # of the new string, due to the way front and back 508 # of the new string, due to the way front and back
553 # were sliced. 509 # were sliced.
554 510
555 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
556 # should be. 512 # should be.
557
558 curWord = "" # Assume there's a problem with finding the curWord 513 curWord = "" # Assume there's a problem with finding the curWord
559
560 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
561 # 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
562 # 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
563 # 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
564 # 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
635 # 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
636 # 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
637 # reach. 591 # reach.
638 592
639 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.
640
641
642 else: 594 else:
643 # 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.
644 self.parent.OnChar(event) #Call super.OnChar to get default behavior 596 self.parent.OnChar(event) #Call super.OnChar to get default behavior
645 return 597 return
646
647 # End of class predTextCtrl! 598 # End of class predTextCtrl!