diff python/codeedit.py @ 161:956f8e5ee48a

Improvements to code edit
author Windel Bouwman
date Sat, 09 Mar 2013 15:52:55 +0100
parents 10330be89bc2
children d8c735dc31f9
line wrap: on
line diff
--- a/python/codeedit.py	Sat Mar 09 11:56:48 2013 +0100
+++ b/python/codeedit.py	Sat Mar 09 15:52:55 2013 +0100
@@ -34,11 +34,15 @@
       self.adjust()
    def setCursorPosition(self, c):
       self.cursorPosition = clipVal(c, 0, len(self.src))
-      print(self.cursorPosition, self.CursorRow, self.CursorCol)
       self.cursorX = self.CursorCol * self.charWidth + self.xposTXT - self.charWidth
       self.cursorY = self.CursorRow * self.charHeight - self.charHeight
+      self.update()
    CursorPosition = property(lambda self: self.cursorPosition, setCursorPosition)
    @property
+   def Rows(self):
+      # Make this nicer:
+      return self.src.split('\n')
+   @property
    def CursorRow(self):
       # TODO: make this nice.
       txt = self.src[0:self.cursorPosition]
@@ -51,8 +55,12 @@
    @property
    def CurrentLine(self):
       return self.getRow(self.CursorRow)
+   def setRowCol(self, r, c):
+      prevRows = self.Rows[:r]
+      txt = '\n'.join(prevRows)
+      self.CursorPosition = len(txt) + c
    def getRow(self, r):
-      rows = self.src.split('\n')
+      rows = self.Rows
       r = r - 1
       if r < 0 or r > len(rows) - 1:
          return ''
@@ -63,6 +71,8 @@
    def insertText(self, txt):
       self.setSource(self.src[0:self.CursorPosition] + txt + self.src[self.CursorPosition:])
       self.CursorPosition += len(txt)
+   def deleteChar(self):
+      self.setSource(self.src[0:self.CursorPosition] + self.src[self.CursorPosition+1:])
    def GotoNextChar(self):
       if self.src[self.CursorPosition] != '\n':
          self.CursorPosition += 1
@@ -72,11 +82,18 @@
    def GotoNextLine(self):
       curLine = self.CurrentLine
       c = self.CursorCol
-      self.CursorPosition += len(curLine) - c + c + 1 # line break char!
-   def GotoPrevLine(self):
+      self.CursorPosition += len(curLine) - c + 1 # line break char!
       curLine = self.CurrentLine
+      if len(curLine) < c:
+         self.CursorPosition += len(curLine)
+      else:
+         self.CursorPosition += c
+   def GotoPrevLine(self):
       c = self.CursorCol
-      self.CursorPosition -= len(curLine) + c + 1 # line break char!
+      self.CursorPosition -= c + 1 # line break char!
+      curLine = self.CurrentLine
+      if len(curLine) > c:
+         self.CursorPosition -= len(curLine) - c
    def paintEvent(self, event):
       # Helper variables:
       er = event.rect()
@@ -85,51 +102,63 @@
       # Background:
       painter.fillRect(er, self.palette().color(QPalette.Base))
       painter.fillRect(QRect(self.xposLNA, er.top(), 8 * chw, er.bottom() + 1), Qt.gray)
-      painter.fillRect(self.xposTXT, (self.CursorRow - 1) * chh, er.width(), chh, Qt.yellow)
+      painter.fillRect(er.left(), (self.CursorRow - 1) * chh, er.width(), chh, Qt.yellow)
       painter.setPen(Qt.gray)
       # first and last row:
-      row1 = max(int(er.top() / chh) - 1, 0)
-      row2 = max(int(er.bottom() / chh) + 1, 0)
+      row1 = max(int(er.top() / chh) - 1, 1)
+      row2 = max(int(er.bottom() / chh) + 1, 1)
       # Draw contents:
-      txt = self.src.split('\n')
-      print('update', row1, row2)
       for row in range(row1, row2 + 1):
-         ypos = row * chh
+         ypos = row * chh - self.charDescent
          painter.setPen(Qt.black)
          painter.drawText(self.xposLNA, ypos, 'R ={0}'.format(row))
          xpos = self.xposTXT
-         if row - 1 < len(txt):
-            painter.drawText(xpos, ypos, txt[row - 1])
+         painter.drawText(xpos, ypos, self.getRow(row))
       # cursor
       if self.blinkcursor:
          painter.fillRect(self.cursorX, self.cursorY, 2, chh, Qt.black)
    def keyPressEvent(self, event):
       if event.matches(QKeySequence.MoveToNextChar):
          self.GotoNextChar()
-      if event.matches(QKeySequence.MoveToPreviousChar):
+      elif event.matches(QKeySequence.MoveToPreviousChar):
          self.GotoPrevChar()
-      if event.matches(QKeySequence.MoveToNextLine):
+      elif event.matches(QKeySequence.MoveToNextLine):
          self.GotoNextLine()
-      if event.matches(QKeySequence.MoveToPreviousLine):
+      elif event.matches(QKeySequence.MoveToPreviousLine):
          self.GotoPrevLine()
-      if event.matches(QKeySequence.MoveToNextPage):
+      elif event.matches(QKeySequence.MoveToNextPage):
          for i in range(5):
             self.GotoNextLine()
-      if event.matches(QKeySequence.MoveToPreviousPage):
+      elif event.matches(QKeySequence.MoveToPreviousPage):
          for i in range(5):
             self.GotoPrevLine()
-      if event.matches(QKeySequence.MoveToEndOfLine):
+      elif event.matches(QKeySequence.MoveToEndOfLine):
          self.CursorPosition += len(self.CurrentLine) - self.CursorCol + 1
-      if event.matches(QKeySequence.MoveToStartOfLine):
+      elif event.matches(QKeySequence.MoveToStartOfLine):
          self.CursorPosition -= self.CursorCol - 1
-      char = event.text().lower()
-      if char:
-         print('ins', char)
-         self.insertText(char)
+      elif event.matches(QKeySequence.Delete):
+         self.deleteChar()
+      elif event.matches(QKeySequence.InsertParagraphSeparator):
+         self.insertText('\n')
+      elif event.key() == Qt.Key_Backspace:
+         self.CursorPosition -= 1
+         self.deleteChar()
+      else:
+         char = event.text()
+         if char:
+            self.insertText(char)
       self.update()
+   def mousePressEvent(self, event):
+      pos = event.pos()
+      if pos.x() > self.xposTXT and pos.x():
+         c = round((pos.x() - self.xposTXT) / self.charWidth)
+         r = int(pos.y() / self.charHeight)
+         self.setRowCol(r, c)
    def adjust(self):
-      self.charHeight = self.fontMetrics().height()
-      self.charWidth = self.fontMetrics().width('x')
+      metrics = self.fontMetrics()
+      self.charHeight = metrics.height()
+      self.charWidth = metrics.width('x')
+      self.charDescent = metrics.descent()
       self.xposLNA = GAP
       self.xposTXT = self.xposLNA + 8 * self.charWidth + GAP
       self.xposEnd = self.xposTXT + self.charWidth * 80
@@ -154,6 +183,6 @@
    ce.show()
    src = ''.join(inspect.getsourcelines(InnerCode)[0])
    ce.Source = src
-   ce.resize(600, 500)
+   ce.resize(600, 800)
    app.exec()