Mega Code Archive

 
Categories / C++ / Qt
 

Code editor

/**************************************************************************** ** ** 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(); }