C++/Qt/QPlainTextEdit
Code editor
<source lang="cpp"> /****************************************************************************
- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- All rights reserved.
- Contact: Nokia Corporation (qt-info@nokia.com)
- This file is part of the examples of the Qt Toolkit.
- $QT_BEGIN_LICENSE:LGPL$
- Commercial Usage
- Licensees holding valid Qt Commercial licenses may use this file in
- accordance with the Qt Commercial License Agreement provided with the
- Software or, alternatively, in accordance with the terms contained in
- a written agreement between you and Nokia.
- GNU Lesser General Public License Usage
- Alternatively, this file may be used under the terms of the GNU Lesser
- General Public License version 2.1 as published by the Free Software
- Foundation and appearing in the file LICENSE.LGPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU Lesser General Public License version 2.1 requirements
- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- In addition, as a special exception, Nokia gives you certain additional
- rights. These rights are described in the Nokia Qt LGPL Exception
- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- GNU General Public License Usage
- Alternatively, this file may be used under the terms of the GNU
- General Public License version 3.0 as published by the Free Software
- Foundation and appearing in the file LICENSE.GPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU General Public License version 3.0 requirements will be
- met: http://www.gnu.org/copyleft/gpl.html.
- If you have questions regarding the use of this file, please contact
- Nokia at qt-info@nokia.com.
- $QT_END_LICENSE$
-
- /
- ifndef CODEEDITOR_H
- define CODEEDITOR_H
- include <QPlainTextEdit>
- include <QObject>
QT_BEGIN_NAMESPACE class QPaintEvent; class QResizeEvent; class QSize; class QWidget; QT_END_NAMESPACE class LineNumberArea; //![codeeditordefinition] class CodeEditor : public QPlainTextEdit {
Q_OBJECT
public:
CodeEditor(QWidget *parent = 0); void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberAreaWidth();
protected:
void resizeEvent(QResizeEvent *event);
private slots:
void updateLineNumberAreaWidth(int newBlockCount); void highlightCurrentLine(); void updateLineNumberArea(const QRect &, int);
private:
QWidget *lineNumberArea;
}; //![codeeditordefinition] //![extraarea] class LineNumberArea : public QWidget { public:
LineNumberArea(CodeEditor *editor) : QWidget(editor) { codeEditor = editor; } QSize sizeHint() const { return QSize(codeEditor->lineNumberAreaWidth(), 0); }
protected:
void paintEvent(QPaintEvent *event) { codeEditor->lineNumberAreaPaintEvent(event); }
private:
CodeEditor *codeEditor;
}; //![extraarea]
- endif
- include <QtGui>
- include "codeeditor.h"
//![constructor] CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) {
lineNumberArea = new LineNumberArea(this); connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); connect(this, SIGNAL(updateRequest(const QRect &, int)), this, SLOT(updateLineNumberArea(const QRect &, int))); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); updateLineNumberAreaWidth(0); highlightCurrentLine();
} //![constructor] //![extraAreaWidth] int CodeEditor::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;
} //![extraAreaWidth] //![slotUpdateExtraAreaWidth] void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */) {
setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
} //![slotUpdateExtraAreaWidth] //![slotUpdateRequest] void CodeEditor::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);
} //![slotUpdateRequest] //![resizeEvent] void CodeEditor::resizeEvent(QResizeEvent *e) {
QPlainTextEdit::resizeEvent(e); QRect cr = contentsRect(); lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
} //![resizeEvent] //![cursorPositionChanged] void CodeEditor::highlightCurrentLine() {
QList<QTextEdit::ExtraSelection> extraSelections; if (!isReadOnly()) { QTextEdit::ExtraSelection selection; QColor lineColor = QColor(Qt::yellow).lighter(160); selection.format.setBackground(lineColor); selection.format.setProperty(QTextFormat::FullWidthSelection, true); selection.cursor = textCursor(); selection.cursor.clearSelection(); extraSelections.append(selection); } setExtraSelections(extraSelections);
} //![cursorPositionChanged] //![extraAreaPaintEvent_0] void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) {
QPainter painter(lineNumberArea); painter.fillRect(event->rect(), Qt::lightGray);
//![extraAreaPaintEvent_0] //![extraAreaPaintEvent_1]
QTextBlock block = firstVisibleBlock(); int blockNumber = block.blockNumber(); int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); int bottom = top + (int) blockBoundingRect(block).height();
//![extraAreaPaintEvent_1] //![extraAreaPaintEvent_2]
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; }
} //![extraAreaPaintEvent_2]
- include <QtGui>
- include "codeeditor.h"
int main(int argv, char **args) {
QApplication app(argv, args); CodeEditor editor; editor.setWindowTitle(QObject::tr("Code Editor Example")); editor.show(); return app.exec();
}
</source>