File indexing completed on 2024-05-12 17:11:40
0001 /*************************************************************************** 0002 * Copyright (C) 2016 by Renaud Guezennec * 0003 * http://www.rolisteam.org/contact * 0004 * * 0005 * rolisteam is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "codeeditor.h" 0021 0022 #include <QtWidgets> 0023 0024 #include <QFontDatabase> 0025 0026 CodeEditor::CodeEditor(QWidget* parent) : QPlainTextEdit(parent) 0027 { 0028 const QFont fixedFont= QFontDatabase::systemFont(QFontDatabase::FixedFont); 0029 setFont(fixedFont); 0030 QFontMetrics metrics(fixedFont); 0031 // setTabStopWidth(metrics.boundingRect(" ").width()); 0032 lineNumberArea= new LineNumberArea(this); 0033 0034 connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); 0035 connect(this, SIGNAL(updateRequest(QRect, int)), this, SLOT(updateLineNumberArea(QRect, int))); 0036 connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); 0037 0038 updateLineNumberAreaWidth(0); 0039 highlightCurrentLine(); 0040 } 0041 0042 int CodeEditor::lineNumberAreaWidth() 0043 { 0044 int digits= 1; 0045 int max= qMax(1, blockCount()); 0046 while(max >= 10) 0047 { 0048 max/= 10; 0049 ++digits; 0050 } 0051 0052 int space= 3 + fontMetrics().boundingRect('9').width() * digits; 0053 0054 return space; 0055 } 0056 0057 void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */) 0058 { 0059 setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); 0060 } 0061 0062 void CodeEditor::updateLineNumberArea(const QRect& rect, int dy) 0063 { 0064 if(dy) 0065 lineNumberArea->scroll(0, dy); 0066 else 0067 lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); 0068 0069 if(rect.contains(viewport()->rect())) 0070 updateLineNumberAreaWidth(0); 0071 } 0072 0073 void CodeEditor::resizeEvent(QResizeEvent* e) 0074 { 0075 QPlainTextEdit::resizeEvent(e); 0076 0077 QRect cr= contentsRect(); 0078 lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); 0079 } 0080 0081 void CodeEditor::highlightCurrentLine() 0082 { 0083 QList<QTextEdit::ExtraSelection> extraSelections; 0084 0085 if(!isReadOnly()) 0086 { 0087 QTextEdit::ExtraSelection selection; 0088 0089 QColor lineColor= QColor(Qt::yellow).lighter(160); 0090 0091 selection.format.setBackground(lineColor); 0092 selection.format.setProperty(QTextFormat::FullWidthSelection, true); 0093 selection.cursor= textCursor(); 0094 selection.cursor.clearSelection(); 0095 extraSelections.append(selection); 0096 } 0097 0098 setExtraSelections(extraSelections); 0099 } 0100 0101 void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent* event) 0102 { 0103 QPainter painter(lineNumberArea); 0104 painter.fillRect(event->rect(), Qt::lightGray); 0105 0106 QTextBlock block= firstVisibleBlock(); 0107 int blockNumber= block.blockNumber(); 0108 int top= (int)blockBoundingGeometry(block).translated(contentOffset()).top(); 0109 int bottom= top + (int)blockBoundingRect(block).height(); 0110 0111 while(block.isValid() && top <= event->rect().bottom()) 0112 { 0113 if(block.isVisible() && bottom >= event->rect().top()) 0114 { 0115 QString number= QString::number(blockNumber + 1); 0116 painter.setPen(Qt::black); 0117 painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), Qt::AlignRight, number); 0118 } 0119 0120 block= block.next(); 0121 top= bottom; 0122 bottom= top + (int)blockBoundingRect(block).height(); 0123 ++blockNumber; 0124 } 0125 }