File indexing completed on 2024-05-19 05:28:19

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 }