| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- #include "wgtcodeeditor.h"
- #include <QPainter>
- #include <QTextBlock>
- #include "wgtlinenumberarea.h"
- #include "syntaxhighlighter.h"
- WgtCodeEditor::WgtCodeEditor(QWidget *parent)
- : QPlainTextEdit(parent)
- {
- QFont font;
- font.setFamily("Courier");
- font.setStyleHint(QFont::Monospace);
- font.setFixedPitch(true);
- font.setPointSize(10);
- setFont(font);
- const int tabStop = 4; // 4 characters
- QFontMetrics metrics(font);
- setTabStopWidth(tabStop * metrics.width(' '));
- lineNumberArea = new WgtLineNumberArea(this);
- new SyntaxHighlighter(document());
- connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
- connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
- connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
- updateLineNumberAreaWidth(0);
- highlightCurrentLine();
- }
- int WgtCodeEditor::lineNumberAreaWidth()
- {
- int digits = 1;
- int max = qMax(1, blockCount());
- while (max >= 10) {
- max /= 10;
- ++digits;
- }
- int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;
- return space;
- }
- void WgtCodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
- {
- setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
- }
- void WgtCodeEditor::updateLineNumberArea(const QRect &rect, int dy)
- {
- if (dy)
- lineNumberArea->scroll(0, dy);
- else
- lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
- if (rect.contains(viewport()->rect()))
- updateLineNumberAreaWidth(0);
- }
- void WgtCodeEditor::resizeEvent(QResizeEvent *e)
- {
- QPlainTextEdit::resizeEvent(e);
- QRect cr = contentsRect();
- lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
- }
- void WgtCodeEditor::highlightCurrentLine()
- {
- QList<QTextEdit::ExtraSelection> extraSelections;
- if (!isReadOnly()) {
- QTextEdit::ExtraSelection selection;
- selection.format.setBackground(palette().alternateBase());
- selection.format.setProperty(QTextFormat::FullWidthSelection, true);
- selection.cursor = textCursor();
- selection.cursor.clearSelection();
- extraSelections.append(selection);
- }
- setExtraSelections(extraSelections);
- }
- void WgtCodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
- {
- QPainter painter(lineNumberArea);
- painter.fillRect(event->rect(), palette().alternateBase());
- QTextBlock block = firstVisibleBlock();
- int blockNumber = block.blockNumber();
- int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
- int bottom = top + (int) blockBoundingRect(block).height();
- while (block.isValid() && top <= event->rect().bottom()) {
- if (block.isVisible() && bottom >= event->rect().top()) {
- QString number = QString::number(blockNumber + 1);
- painter.setPen(Qt::black);
- painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
- Qt::AlignRight, number);
- }
- block = block.next();
- top = bottom;
- bottom = top + (int) blockBoundingRect(block).height();
- ++blockNumber;
- }
- }
|