/nltk_contrib/lpath/at_lite/tableproxy.py

https://github.com/stesh/nltk_contrib · Python · 183 lines · 150 code · 26 blank · 7 comment · 36 complexity · 7dc757a32b1f2325900afba6f0dd5027 MD5 · raw file

  1. from qt import QObject, PYSIGNAL
  2. __all__ = ['getProxy']
  3. class UndoStack:
  4. def __init__(self):
  5. self.reset()
  6. def reset(self):
  7. self._stack = []
  8. self._top = -1
  9. self._limit = -1
  10. def prev(self):
  11. if self._top >= 0:
  12. r = self._stack[self._top]
  13. self._top -= 1
  14. return r
  15. else:
  16. return None
  17. def next(self):
  18. if self._limit > self._top:
  19. self._top += 1
  20. return self._stack[self._top]
  21. else:
  22. return None
  23. def push(self, *args):
  24. self._top += 1
  25. if len(self._stack) == self._top:
  26. self._stack.append(args)
  27. else:
  28. self._stack[self._top] = args
  29. self._limit = self._top
  30. if self._limit >= 2000:
  31. del self._stack[0]
  32. self._limit -= 1
  33. self._top -= 1
  34. def status(self):
  35. return self._top+1, self._limit-self._top
  36. class _TableRowProxy(object):
  37. """
  38. self.num is a row index in the table
  39. """
  40. def __setitem__(self,i,v):
  41. if type(i) == str:
  42. i = self.getColumnIndex(i)
  43. w = self[i]
  44. super(self.__class__,self).__setitem__(i,v)
  45. self.tab.emitter.emit(PYSIGNAL("cellChanged"),(self.num,i,self.data[i],w))
  46. if not self.tab.undoStackReadOnly:
  47. self.tab.undoStack.push("cellChanged",(self.num,i),(v,w))
  48. def select(self):
  49. self.tab.select(self.num)
  50. class _TableModelProxy(object):
  51. def __init__(self, *args):
  52. self.super = super(self.__class__,self)
  53. self.super.__init__(*args)
  54. self.emitter = QObject()
  55. self.selection = None
  56. self.undoStack = UndoStack()
  57. self.undoStackReadOnly = False
  58. def setHeader(self, col, header):
  59. self.super.setHeader(col, header)
  60. self.emitter.emit(PYSIGNAL("setHeader"),(col,header))
  61. def insertRow(self,i=None,row=None):
  62. if i is None: i=len(self.table)
  63. if self.super.insertRow(i,row):
  64. for k in range(i,len(self.table)):
  65. self.table[k].num = k
  66. self.emitter.emit(PYSIGNAL("insertRow"),(i,self.table[i]))
  67. if not self.undoStackReadOnly:
  68. self.undoStack.push("insertRow",i,row)
  69. return True
  70. else:
  71. return False
  72. def insertColumn(self,i=None,col=None):
  73. if self.super.insertColumn(i,col):
  74. self.emitter.emit(PYSIGNAL("insertColumn"),(i,col))
  75. if type(i)==int and i <= self.selection:
  76. self.selection += 1
  77. return True
  78. else:
  79. return False
  80. def takeRow(self,i):
  81. r = self.super.takeRow(i)
  82. for k in range(i,len(self.table)):
  83. self.table[k].num = k
  84. if i == self.selection:
  85. self.selection = None
  86. self.emitter.emit(PYSIGNAL("takeRow"),(i,r))
  87. if not self.undoStackReadOnly:
  88. self.undoStack.push("takeRow",i,r)
  89. return r
  90. def takeColumn(self,i):
  91. c = self.super.takeColumn(i)
  92. self.emitter.emit(PYSIGNAL("takeColumn"),(i,))
  93. if i == self.selection:
  94. self.selection = None
  95. elif i < self.selection:
  96. self.selection -= 1
  97. return c
  98. def sort(self, *args):
  99. self.super.sort(*args)
  100. for i,row in enumerate(self.table):
  101. row.num = i
  102. self.emitter.emit(PYSIGNAL("sort"),())
  103. def select(self, sel):
  104. self.selection = sel
  105. self.emitter.emit(PYSIGNAL("select"),(sel,))
  106. def getSelection(self):
  107. return self.selection
  108. def resetUndoStack(self):
  109. self.undoStack.reset()
  110. def undo(self, n=1):
  111. for m in range(n):
  112. try:
  113. op, arg1, arg2 = self.undoStack.prev()
  114. #print "undo", op, arg1, arg2
  115. #print len(self.undoStack._stack)
  116. except TypeError:
  117. break
  118. self.undoStackReadOnly = True
  119. if op == 'insertRow':
  120. self.takeRow(arg1)
  121. elif op == 'takeRow':
  122. self.insertRow(arg1,arg2)
  123. elif op == 'cellChanged':
  124. i, j = arg1
  125. v, w = arg2
  126. self[i][j] = w
  127. self.undoStackReadOnly = False
  128. def redo(self, n=1):
  129. for m in range(n):
  130. try:
  131. op, arg1, arg2 = self.undoStack.next()
  132. #print "redo", op, arg1, arg2
  133. #print len(self.undoStack._stack)
  134. except TypeError:
  135. break
  136. self.undoStackReadOnly = True
  137. if op == 'insertRow':
  138. self.insertRow(arg1,arg2)
  139. elif op == 'takeRow':
  140. self.takeRow(arg1)
  141. elif op == 'cellChanged':
  142. i, j = arg1
  143. v, w = arg2
  144. self[i][j] = v
  145. self.undoStackReadOnly = False
  146. def undoStackStatus(self):
  147. return self.undoStack.status()
  148. def getProxy(cls):
  149. name = "Proxy_TableRow"
  150. bases = (cls.TableRow,) + _TableRowProxy.__bases__
  151. dic = dict(_TableRowProxy.__dict__)
  152. rowModelClass = type(name, bases, dic)
  153. name = "Proxy_" + cls.__name__
  154. bases = (cls,) + _TableModelProxy.__bases__
  155. dic = dict(_TableModelProxy.__dict__)
  156. dic['TableRow'] = rowModelClass
  157. return type(name, bases, dic)