File indexing completed on 2025-03-16 08:11:28
0001 /* 0002 This file is part of Konsole, an X terminal. 0003 0004 SPDX-FileCopyrightText: 2006-2008 Robert Knight <robertknight@gmail.com> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 0007 This program is free software; you can redistribute it and/or modify 0008 it under the terms of the GNU Lesser General Public License as published by 0009 the Free Software Foundation; either version 2 of the License, or 0010 (at your option) any later version. 0011 0012 This program is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 GNU General Public License for more details. 0016 0017 You should have received a copy of the GNU Lesser General Public License 0018 along with this program; if not, write to the Free Software 0019 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0020 02110-1301 USA. 0021 */ 0022 0023 // Own 0024 #include "TerminalCharacterDecoder.h" 0025 0026 // stdlib 0027 #include <cwctype> 0028 0029 // Qt 0030 #include <QTextStream> 0031 0032 // KDE 0033 // #include <kdebug.h> 0034 0035 // Konsole 0036 #include "konsole_wcwidth.h" 0037 0038 #include <cwctype> 0039 0040 using namespace Konsole; 0041 PlainTextDecoder::PlainTextDecoder() 0042 : _output(nullptr) 0043 , _includeTrailingWhitespace(true) 0044 , _recordLinePositions(false) 0045 { 0046 } 0047 void PlainTextDecoder::setTrailingWhitespace(bool enable) 0048 { 0049 _includeTrailingWhitespace = enable; 0050 } 0051 bool PlainTextDecoder::trailingWhitespace() const 0052 { 0053 return _includeTrailingWhitespace; 0054 } 0055 void PlainTextDecoder::begin(QTextStream *output) 0056 { 0057 _output = output; 0058 if (!_linePositions.isEmpty()) 0059 _linePositions.clear(); 0060 } 0061 void PlainTextDecoder::end() 0062 { 0063 _output = nullptr; 0064 } 0065 0066 void PlainTextDecoder::setRecordLinePositions(bool record) 0067 { 0068 _recordLinePositions = record; 0069 } 0070 QList<int> PlainTextDecoder::linePositions() const 0071 { 0072 return _linePositions; 0073 } 0074 0075 void PlainTextDecoder::decodeLine(std::span<const Character> characters, LineProperty /*properties*/) 0076 { 0077 Q_ASSERT(_output); 0078 int count = characters.size(); 0079 0080 if (_recordLinePositions && _output->string()) { 0081 int pos = _output->string()->size(); 0082 _linePositions << pos; 0083 } 0084 0085 // check the real length 0086 for (int i = 0; i < count; i++) { 0087 if (characters.subspan(i).empty()) { 0088 count = i; 0089 break; 0090 } 0091 } 0092 0093 // TODO should we ignore or respect the LINE_WRAPPED line property? 0094 0095 // note: we build up a QString and send it to the text stream rather writing into the text 0096 // stream a character at a time because it is more efficient. 0097 //(since QTextStream always deals with QStrings internally anyway) 0098 QString plainText; 0099 plainText.reserve(count); 0100 0101 int outputCount = count; 0102 0103 // if inclusion of trailing whitespace is disabled then find the end of the 0104 // line 0105 if (!_includeTrailingWhitespace) { 0106 for (int i = count - 1; i >= 0; i--) { 0107 if (characters[i].character != u' ') 0108 break; 0109 else 0110 outputCount--; 0111 } 0112 } 0113 0114 for (int i = 0; i < outputCount;) { 0115 plainText.push_back(characters[i].character); 0116 i += qMax(1, konsole_wcwidth(characters[i].character)); 0117 } 0118 *_output << plainText; 0119 }