Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
codeeditor.cc
1
2 /*===========================================================================*\
3 * *
4 * OpenFlipper *
5 * Copyright (c) 2001-2015, RWTH-Aachen University *
6 * Department of Computer Graphics and Multimedia *
7 * All rights reserved. *
8 * www.openflipper.org *
9 * *
10 *---------------------------------------------------------------------------*
11 * This file is part of OpenFlipper. *
12 *---------------------------------------------------------------------------*
13 * *
14 * Redistribution and use in source and binary forms, with or without *
15 * modification, are permitted provided that the following conditions *
16 * are met: *
17 * *
18 * 1. Redistributions of source code must retain the above copyright notice, *
19 * this list of conditions and the following disclaimer. *
20 * *
21 * 2. Redistributions in binary form must reproduce the above copyright *
22 * notice, this list of conditions and the following disclaimer in the *
23 * documentation and/or other materials provided with the distribution. *
24 * *
25 * 3. Neither the name of the copyright holder nor the names of its *
26 * contributors may be used to endorse or promote products derived from *
27 * this software without specific prior written permission. *
28 * *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
31 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
32 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
33 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
34 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
35 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
36 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
37 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
38 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
39 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
40 * *
41 \*===========================================================================*/
42
43 /*===========================================================================*\
44 * *
45 * $Revision$ *
46 * $LastChangedBy$ *
47 * $Date$ *
48 * *
49 \*===========================================================================*/
50
51
52 #if QT_VERSION >= 0x050000
53 #include <QtWidgets>
54 #else
55 #include <QtGui>
56 #endif
57
58
59 #include "codeeditor.hh"
60
61
62 CodeEditorWidget::CodeEditorWidget(QWidget *parent) : QPlainTextEdit(parent) {
63 lineNumberArea = new LineNumberArea(this);
64
65 connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
66 connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
67 connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
68
69 updateLineNumberAreaWidth(0);
70 highlightCurrentLine();
71 }
72
73
74
75 int CodeEditorWidget::lineNumberAreaWidth() {
76
77 int digits = 1;
78 int max = qMax(1, blockCount());
79 while (max >= 10) {
80 max /= 10;
81 ++digits;
82 }
83
84 int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;
85
86 return space;
87 }
88
89
90
91 void CodeEditorWidget::updateLineNumberAreaWidth(int /* newBlockCount */) {
92 setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
93 }
94
95
96
97 void CodeEditorWidget::updateLineNumberArea(const QRect &rect, int dy) {
98 if (dy)
99 lineNumberArea->scroll(0, dy);
100 else
101 lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
102
103 if (rect.contains(viewport()->rect()))
104 updateLineNumberAreaWidth(0);
105 }
106
107
108
109 void CodeEditorWidget::resizeEvent(QResizeEvent *e) {
110 QPlainTextEdit::resizeEvent(e);
111
112 QRect cr = contentsRect();
113 lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
114 }
115
116
117
118 void CodeEditorWidget::highlightCurrentLine() {
119 QList<QTextEdit::ExtraSelection> extraSelections;
120
121 if (!isReadOnly()) {
122 QTextEdit::ExtraSelection selection;
123
124 QColor lineColor = QColor(Qt::yellow).lighter(160);
125
126 selection.format.setBackground(lineColor);
127 selection.format.setProperty(QTextFormat::FullWidthSelection, true);
128 selection.cursor = textCursor();
129 selection.cursor.clearSelection();
130 extraSelections.append(selection);
131 }
132
133 setExtraSelections(extraSelections);
134 }
135
136 void CodeEditorWidget::highLightErrorLine(int _line) {
137 QList<QTextEdit::ExtraSelection> extraSelections;
138
139 if (!isReadOnly()) {
140 QTextEdit::ExtraSelection selection;
141
142 QColor lineColor = QColor(Qt::red).lighter(160);
143
144 selection.format.setBackground(lineColor);
145 selection.format.setProperty(QTextFormat::FullWidthSelection, true);
146 selection.cursor = QTextCursor(document());
147 selection.cursor.movePosition ( QTextCursor::Down, QTextCursor::MoveAnchor, _line - 1 );
148 selection.cursor.clearSelection();
149 extraSelections.append(selection);
150 }
151
152 setExtraSelections(extraSelections);
153 }
154
155
156 void CodeEditorWidget::lineNumberAreaPaintEvent(QPaintEvent *event) {
157
158 QPainter painter(lineNumberArea);
159 painter.fillRect(event->rect(), Qt::lightGray);
160
161
162 QTextBlock block = firstVisibleBlock();
163 int blockNumber = block.blockNumber();
164 int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
165 int bottom = top + (int) blockBoundingRect(block).height();
166
167 while (block.isValid() && top <= event->rect().bottom()) {
168 if (block.isVisible() && bottom >= event->rect().top()) {
169 QString number = QString::number(blockNumber + 1);
170 painter.setPen(Qt::black);
171 painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),Qt::AlignRight, number);
172 }
173
174 block = block.next();
175 top = bottom;
176 bottom = top + (int) blockBoundingRect(block).height();
177 ++blockNumber;
178 }
179
180 }
LineNumberArea
Definition: codeeditor.hh:90