File indexing completed on 2024-04-28 05:31:41

0001 /*
0002     KSysGuard, the KDE System Guard
0003 
0004     SPDX-FileCopyrightText: 2007 Trent Waddington <trent.waddington@gmail.com>
0005     SPDX-FileCopyrightText: 2008 John Tapsell <tapsell@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 
0009 
0010 */
0011 
0012 #include "KTextEditVT.h"
0013 
0014 #include <QFontDatabase>
0015 
0016 KTextEditVT::KTextEditVT(QWidget *parent)
0017     : QTextEdit(parent)
0018     , escape_code(QChar(0))
0019 {
0020     mParseAnsi = true;
0021     escape_sequence = false;
0022     escape_CSI = false;
0023     escape_OSC = false;
0024     escape_number1 = -1;
0025     escape_number_separator = false;
0026     escape_number2 = -1;
0027     setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
0028 }
0029 
0030 void KTextEditVT::insertVTChar(const QChar &c)
0031 {
0032     if (escape_sequence) {
0033         if (escape_CSI || escape_OSC) {
0034             if (c.isDigit()) {
0035                 if (!escape_number_separator) {
0036                     if (escape_number1 == -1) {
0037                         escape_number1 = c.digitValue();
0038                     } else {
0039                         escape_number1 = escape_number1 * 10 + c.digitValue();
0040                     }
0041                 } else {
0042                     if (escape_number2 == -1) {
0043                         escape_number2 = c.digitValue();
0044                     } else {
0045                         escape_number2 = escape_number2 * 10 + c.digitValue();
0046                     }
0047                 }
0048             } else if (c == QLatin1Char(';')) {
0049                 escape_number_separator = true;
0050             } else if (escape_OSC && c == QChar(7)) { // Throw away any letters that are not OSC
0051                 escape_code = c;
0052             } else if (escape_CSI) {
0053                 escape_code = c;
0054             }
0055         } else if (c == QLatin1Char('[')) {
0056             escape_CSI = true;
0057         } else if (c == QLatin1Char(']')) {
0058             escape_OSC = true;
0059         } else if (c == QLatin1Char('(') || c == QLatin1Char(')')) {
0060             // do nothing
0061         } else {
0062             escape_code = c;
0063         }
0064         if (!escape_code.isNull()) {
0065             // We've read in the whole escape sequence.  Now parse it
0066             if (escape_code == QLatin1Char('m')) { // change color
0067                 switch (escape_number2) {
0068                 case 0: // all off
0069                     setFontWeight(QFont::Normal);
0070                     setTextColor(Qt::black);
0071                     break;
0072                 case 1: // bold
0073                     setFontWeight(QFont::Bold);
0074                     break;
0075                 case 31: // red
0076                     setTextColor(Qt::red);
0077                     break;
0078                 case 32: // green
0079                     setTextColor(Qt::green);
0080                     break;
0081                 case 33: // yellow
0082                     setTextColor(Qt::yellow);
0083                     break;
0084                 case 34: // blue
0085                     setTextColor(Qt::blue);
0086                     break;
0087                 case 35: // magenta
0088                     setTextColor(Qt::magenta);
0089                     break;
0090                 case 36: // cyan
0091                     setTextColor(Qt::cyan);
0092                     break;
0093                 case -1:
0094                 case 30: // black
0095                 case 39: // reset
0096                 case 37: // white
0097                     setTextColor(Qt::black);
0098                     break;
0099                 }
0100             }
0101             escape_code = QChar(0);
0102             escape_number1 = -1;
0103             escape_number2 = -1;
0104             escape_CSI = false;
0105             escape_OSC = false;
0106             escape_sequence = false;
0107             escape_number_separator = false;
0108         }
0109     } else if (c == QChar(0x0d)) {
0110         insertPlainText(QStringLiteral("\n"));
0111     } else if (c.isPrint() || c == QLatin1Char('\n')) {
0112         insertPlainText(c);
0113     } else if (mParseAnsi) {
0114         if (c == QChar(127) || c == QChar(8)) { // delete or backspace, respectively
0115             textCursor().deletePreviousChar();
0116         } else if (c == QChar(27)) { // escape key
0117             escape_sequence = true;
0118         } else if (c == QChar(0x9b)) { // CSI - equivalent to esc [
0119             escape_sequence = true;
0120             escape_CSI = true;
0121         } else if (c == QChar(0x9d)) { // OSC - equivalent to esc ]
0122             escape_sequence = true;
0123             escape_OSC = true;
0124         }
0125     } else if (!c.isNull()) {
0126         insertPlainText(QStringLiteral("["));
0127         QString num;
0128         num = c;
0129         insertPlainText(num);
0130         insertPlainText(QStringLiteral("]"));
0131     }
0132 }
0133 
0134 void KTextEditVT::insertVTText(const QByteArray &string)
0135 {
0136     const int size = string.size();
0137     for (int i = 0; i < size; i++) {
0138         insertVTChar(QLatin1Char(string.at(i)));
0139     }
0140 }
0141 
0142 void KTextEditVT::insertVTText(const QString &string)
0143 {
0144     int size = string.size();
0145     for (int i = 0; i < size; i++) {
0146         insertVTChar(string.at(i));
0147     }
0148 }
0149 
0150 void KTextEditVT::setParseAnsiEscapeCodes(bool parseAnsi)
0151 {
0152     mParseAnsi = parseAnsi;
0153 }
0154 
0155 bool KTextEditVT::parseAnsiEscapeCodes() const
0156 {
0157     return mParseAnsi;
0158 }