/jythonconsole/popup.py

https://github.com/bollwyvl/MagicDrawJythonTerminal · Python · 178 lines · 130 code · 34 blank · 14 comment · 23 complexity · 2aa5752cb4f07e0491b0dc79abd9b39b MD5 · raw file

  1. from java.lang import Character
  2. from javax.swing import JWindow, JList, JScrollPane
  3. from java.awt import Color, Dimension
  4. from java.awt.event import KeyEvent
  5. import sys
  6. __author__ = "Don Coleman <dcoleman@chariotsolutions.com>"
  7. __cvsid__ = "$Id: popup.py,v 1.9 2003/05/01 03:43:53 dcoleman Exp $"
  8. class Popup(JWindow):
  9. """Popup window to display list of methods for completion"""
  10. MAX_HEIGHT = 300
  11. MIN_WIDTH = 200
  12. MAX_WIDTH = 400
  13. def __init__(self, frame, textComponent):
  14. JWindow.__init__(self, frame)
  15. self.textComponent = textComponent
  16. self.size = (200,200)
  17. self.list = JList(keyPressed=self.key)
  18. self.list.setBackground(Color(255,255,225)) # TODO move this color
  19. self.getContentPane().add(JScrollPane(self.list))
  20. self.list.setSelectedIndex(0)
  21. self.originalData = ""
  22. self.data = ""
  23. self.typed = ""
  24. def key(self, e):
  25. # print >> sys.stderr, "Other Listener"
  26. if not self.visible:
  27. return
  28. code = e.getKeyCode()
  29. if code == KeyEvent.VK_ESCAPE:
  30. self.hide()
  31. elif code == KeyEvent.VK_ENTER or code == KeyEvent.VK_TAB:
  32. self.chooseSelected()
  33. e.consume()
  34. elif code == KeyEvent.VK_SPACE:
  35. # TODO for functions: choose the selected option, add parenthesis
  36. # and put the cursor between them. example: obj.function(^cursor_here)
  37. self.chooseSelected()
  38. elif code == KeyEvent.VK_PERIOD:
  39. self.chooseSelected()
  40. #e.consume()
  41. # This fails because the key listener in console gets it first
  42. elif code == KeyEvent.VK_LEFT_PARENTHESIS:
  43. self.chooseSelected()
  44. elif code == 8: # BACKSPACE
  45. if len(self.typed) == 0:
  46. self.hide()
  47. self.typed = self.typed[:-1]
  48. print >> sys.stderr, self.typed
  49. self.data = filter(self.originalData, self.typed)
  50. self.list.setListData(self.data)
  51. self.list.setSelectedIndex(0)
  52. elif code == KeyEvent.VK_UP:
  53. self.up()
  54. # consume event to avoid history previous
  55. e.consume()
  56. elif code == KeyEvent.VK_DOWN:
  57. self.down()
  58. # consume event to avoid history next
  59. e.consume()
  60. elif code == KeyEvent.VK_PAGE_UP:
  61. self.pageUp()
  62. e.consume()
  63. elif code == KeyEvent.VK_PAGE_DOWN:
  64. self.pageDown()
  65. e.consume()
  66. else:
  67. char = e.getKeyChar()
  68. if Character.isJavaLetterOrDigit(char):
  69. self.typed += char
  70. self.data = filter(self.data, self.typed)
  71. self.list.setListData(self.data)
  72. self.list.setSelectedIndex(0)
  73. def down(self):
  74. index = self.list.getSelectedIndex()
  75. max = self.getListSize() - 1
  76. if index < max:
  77. index += 1
  78. self.setSelected(index)
  79. def up(self):
  80. index = self.list.getSelectedIndex()
  81. if index > 0:
  82. index -= 1
  83. self.setSelected(index)
  84. def pageUp(self):
  85. index = self.list.getSelectedIndex()
  86. visibleRows = self.list.getVisibleRowCount()
  87. index = max(index - visibleRows, 0)
  88. self.setSelected(index)
  89. def pageDown(self):
  90. index = self.list.getSelectedIndex()
  91. visibleRows = self.list.getVisibleRowCount()
  92. index = min(index + visibleRows, self.getListSize() - 1)
  93. self.setSelected(index)
  94. def setSelected(self, index):
  95. self.list.setSelectedIndex(index)
  96. self.list.ensureIndexIsVisible(index)
  97. def getListSize(self):
  98. return self.list.getModel().getSize()
  99. def chooseSelected(self):
  100. """Choose the selected value in the list"""
  101. value = self.list.getSelectedValue()
  102. if value != None:
  103. startPosition = self.dotPosition + 1
  104. caretPosition = self.textComponent.getCaretPosition()
  105. self.textComponent.select(startPosition, caretPosition)
  106. self.textComponent.replaceSelection(value)
  107. self.textComponent.setCaretPosition(startPosition + len(value))
  108. self.hide()
  109. def setMethods(self, methodList):
  110. methodList.sort()
  111. self.data = methodList
  112. self.originalData = methodList
  113. self.typed = ""
  114. self.list.setListData(methodList)
  115. def show(self):
  116. # when the popup becomes visible, get the cursor
  117. # so we know how to replace the selection
  118. self.dotPosition = self.textComponent.getCaretPosition()
  119. self.setSize(self.getPreferredSize())
  120. self.super__show()
  121. def showMethodCompletionList(self, list, displayPoint):
  122. self.setLocation(displayPoint)
  123. self.setMethods(list)
  124. self.show()
  125. self.list.setSelectedIndex(0)
  126. def getPreferredSize(self):
  127. # need to add a magic amount to the size to avoid scrollbars
  128. # I'm sure there's a better way to do this
  129. MAGIC = 20
  130. size = self.list.getPreferredScrollableViewportSize()
  131. height = size.height + MAGIC
  132. width = size.width + MAGIC
  133. if height > Popup.MAX_HEIGHT:
  134. height = Popup.MAX_HEIGHT
  135. if width > Popup.MAX_WIDTH:
  136. width = Popup.MAX_WIDTH
  137. if width < Popup.MIN_WIDTH:
  138. width = Popup.MIN_WIDTH
  139. return Dimension(width, height)
  140. # this needs a list renderer that will hilight the prefix
  141. def filter(list, prefix):
  142. prefix = prefix.lower()
  143. list = [eachItem for eachItem in list if str(eachItem).lower().startswith(prefix)]
  144. return list