m_firstCol(0),
m_cursorLine(0),
m_cursorCol(-1),
+ m_cursorVisible(true),
+ m_insertMode(true),
m_breakLines(false),
m_widthLineNo(50),
m_widthVScrollBar(0),
m_keyControlShift(),
m_keyRaw(),
m_keyShift(){
- setFocusPolicy(Qt::WheelFocus);
+ setFocusPolicy(Qt::WheelFocus);
m_standardFont = new QFont("Courier");
m_standardFont->setStyleHint(QFont::TypeWriter);
m_standardFont->setPixelSize(16);
*/
void ReEdit::paintEvent(QPaintEvent* event){
QRect rect = event->rect();
+ m_widthEdit = rect.width();
int lineHeight = heightToFullHeight(m_standardMetrics->height());
- int count = rect.height() / lineHeight;
- m_paragraphs.load(m_paragraphs.firstLine(), count, this);
+ int pageSize = rect.height() / lineHeight;
+ int firstLine = m_paragraphs.firstLine();
+ m_paragraphs.load(firstLine, pageSize, this);
QPainter painter(this);
+ ReLook* look = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
+ painter.setBrush(*look->m_brush);
+ QRect editArea(rect.left() + m_widthLineNo, rect.top(), rect.right(),
+ rect.bottom());
+ painter.drawRect(editArea);
m_paragraphs.draw(painter, rect.top(), rect.left() + m_widthLineNo);
int left = rect.left() + m_widthLineNo - 3;
- painter.drawLine(left, rect.top(), left, rect.bottom());
left = rect.left();
int y = 0;
- int lineNo = m_paragraphs.firstLine() + 1;
+ int lineNo = firstLine + 1;
ReLook* lookStd = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
for (int ix = 0; ix < m_paragraphs.list().length(); ix++, lineNo++){
QString number = QString::number(lineNo) + ":";
painter.setFont(*look->m_font);
painter.setPen(*look->m_pen);
painter.drawText(left + m_widthLineNo - width - 5, y, number);
- y += heightToFullHeight(look->m_metrics->height());
+ y += lineHeight;
+ }
+ // We paint the cursor:
+ if (m_cursorVisible && m_cursorLine >= firstLine
+ && m_cursorLine < firstLine + pageSize){
+ int col = m_cursorCol;
+ if (m_lines->lineAt(m_cursorLine).length() <= col)
+ col = m_lines->lineAt(m_cursorLine).length() - 1;
+ int x = rect.left() + m_widthLineNo + 1
+ + (col + 1) * lookStd->m_metrics->width('x');
+ int y = rect.top() + (m_cursorLine - firstLine) * lineHeight;
+ painter.setPen(*look->m_pen);
+ painter.drawLine(x, y, x, y + lineHeight);
}
}
QPoint position = event->pos();
m_cursorLine = position.y() / heightToFullHeight(m_standardMetrics->height())
+ m_paragraphs.firstLine();
+ int x = position.x();
+ int charWidth = m_standardMetrics->width('x');
+ if (x >= m_widthLineNo && x < m_widthEdit - m_widthVScrollBar){
+ if (x <= m_widthLineNo + charWidth / 2)
+ m_cursorCol = -1;
+ else
+ m_cursorCol = (x - m_widthLineNo) / charWidth;
+ }
emit repaint();
}
+/**
+ * Calculates the index of the line string from the cursor column.
+ *
+ * The index may be smaller because of expanded tabulators.
+ * Example:
+ * <pre>"x\ty", tabulator width: 3, screen display: "x y"
+ * columnToTextIndex(0) == 0; ('x')
+ * columnToTextIndex(1) == 1; ('\t')
+ * columnToTextIndex(2) == 1; ('\t')
+ * columnToTextIndex(3) == 2; ('y')
+ * </pre>
+ *
+ * @param cursorCol the cursor position
+ * @return the
+ */
+int ReEdit::columnToTextIndex(int cursorCol){
+ //@ToDo: tab handling
+ return cursorCol;
+}
+/**
+ * Calculates the cursor column from the line string index.
+ *
+ * The index may be larger because of expanded tabulators.
+ * Example:
+ * <pre>"x\ty", tabulator width: 3, screen display: "x y"
+ * textIndexToColumn(0) == 0;
+ * textIndexToColumn(1) == 1;
+ * textIndexToColumn(2) == 3;
+ * </pre>
+ * @param index the index in the line string
+ * @return the column in the edit field
+ */
+int ReEdit::textIndexToColumn(int index){
+ //@ToDo: tab handling
+ return index;
+}
+
/**
* Handles the key click event.
*
bool shift = event->modifiers() & Qt::ShiftModifier;
bool control = event->modifiers() & Qt::ControlModifier;
bool alt = event->modifiers() & Qt::MetaModifier;
- if (!event->text().isEmpty()){
- m_lines->insertText(m_cursorLine, m_cursorCol + 1, event->text());
+ int key = event->key();
+ QString keyText = event->text();
+ if (!keyText.isEmpty() && !shift && !control && !alt){
+ switch (key) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ m_lines->insertText(m_cursorLine, columnToTextIndex(m_cursorCol + 1),
+ "\n");
+ m_cursorCol = -1;
+ m_cursorLine++;
+ break;
+ case Qt::Key_Backspace:
+ m_lines->remove(m_cursorLine, columnToTextIndex(m_cursorCol + 1), 1);
+ if (m_cursorCol-- < -1)
+ m_cursorCol = -1;
+ break;
+ case Qt::Key_Delete:
+ m_lines->remove(m_cursorLine, columnToTextIndex(m_cursorCol + 1), 1);
+ break;
+ default:
+ m_lines->insertText(m_cursorLine, columnToTextIndex(m_cursorCol + 1),
+ keyText);
+ m_cursorCol++;
+ break;
+ }
}else{
QMap <int, EditorAction>* map;
- int key = event->key();
if (!shift && !alt && !control)
map = &m_keyRaw;
else if (shift && !alt && !control)
map = &m_keyShift;
else if (alt && !shift && !control)
map = &m_keyAlt;
- else if (control && ! alt && ! shift)
+ else if (control && !alt && !shift)
map = &m_keyControl;
else if (alt && control && !shift)
map = &m_keyAltControl;
* @param cursorLine -1 or number of the new cursor line
*/
void ReEdit::ensureCursorVisible(int cursorLine){
- if (cursorLine >= 0)
- m_cursorLine = cursorLine;
- int firstLine = m_paragraphs.firstLine();
- int pageSize = m_paragraphs.list().length();
- if (m_cursorLine < firstLine
- || m_cursorLine >= firstLine + pageSize){
- reposition(m_cursorLine);
- }
+ if (cursorLine >= 0)
+ m_cursorLine = cursorLine;
+ int firstLine = m_paragraphs.firstLine();
+ int pageSize = m_paragraphs.list().length();
+ if (m_cursorLine < firstLine || m_cursorLine >= firstLine + pageSize){
+ reposition(m_cursorLine);
+ }
}
/**
* @param action action to do
*/
void ReEdit::editorAction(ReEdit::EditorAction action){
- int pageSize = m_paragraphs.list().length() - 1;
+ int pageSize = m_paragraphs.list().length() - 1;
switch (action) {
case EA_UNDEF:
break;
ensureCursorVisible();
break;
case EA_CHAR_RIGHT:
- m_cursorCol++;
+ if (++m_cursorCol >= m_lines->lineAt(m_cursorLine).length())
+ m_cursorCol = m_lines->lineAt(m_cursorLine).length() - 1;
ensureCursorVisible();
break;
case EA_LINE_UP:
break;
case EA_LINE_DOWN:
if (++m_cursorLine >= m_lines->lineCount())
- m_cursorLine = m_lines->lineCount() - 1;
+ m_cursorLine = m_lines->lineCount() - 1;
ensureCursorVisible();
break;
case EA_BEGIN_OF_LINE:
ensureCursorVisible();
break;
case EA_END_OF_LINE:
- m_cursorCol = 99;
+ m_cursorCol = m_lines->lineAt(m_cursorLine).length() - 1;
+ ;
ensureCursorVisible();
break;
case EA_BEGIN_OF_FILE:
ensureCursorVisible(m_lines->lineCount() - 1);
break;
case EA_PAGE_UP:
- // Do not change cursor line!
- reposition(m_paragraphs.firstLine() - pageSize);
- break;
+ // Do not change cursor line!
+ reposition(m_paragraphs.firstLine() - pageSize);
+ break;
case EA_PAGE_DOWN:
- // Do not change cursor line!
- reposition(m_paragraphs.firstLine() + pageSize);
- break;
+ // Do not change cursor line!
+ reposition(m_paragraphs.firstLine() + pageSize);
+ break;
case EA_DEL_CHAR:
break;
case EA_BACKSPACE:
* @param firstLine number of the line which should be visible
*/
void ReEdit::reposition(int firstLine){
- int pageSize = m_paragraphs.list().length();
- if (firstLine <= 0)
- firstLine = 0;
- else if (firstLine >= m_lines->lineCount() - pageSize)
- firstLine = m_lines->lineCount() - pageSize + 1;
- m_paragraphs.load(firstLine, pageSize, this);
+ int pageSize = m_paragraphs.list().length();
+ if (firstLine <= 0)
+ firstLine = 0;
+ else if (firstLine >= m_lines->lineCount() - pageSize)
+ firstLine = m_lines->lineCount() - pageSize + 1;
+ // We do not load because each redraw loads it:
+ m_paragraphs.setFirstLine(firstLine);
}
/**