source: ogBrowser-Git/qtermwidget/lib/TerminalCharacterDecoder.cpp @ ffbf8ac

jenkinsmain
Last change on this file since ffbf8ac was 64efc22, checked in by Vadim Troshchinskiy <vtroshchinskiy@…>, 19 months ago

Update qtermwidget to modern version

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*
2    This file is part of Konsole, an X terminal.
3
4    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU Lesser General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19    02110-1301  USA.
20*/
21
22// Own
23#include "TerminalCharacterDecoder.h"
24
25// Qt
26#include <QTextStream>
27
28// KDE
29//#include <kdebug.h>
30
31// Konsole
32#include "konsole_wcwidth.h"
33
34#include <cwctype>
35
36using namespace Konsole;
37PlainTextDecoder::PlainTextDecoder()
38 : _output(nullptr)
39 , _includeTrailingWhitespace(true)
40 , _recordLinePositions(false)
41{
42
43}
44void PlainTextDecoder::setTrailingWhitespace(bool enable)
45{
46    _includeTrailingWhitespace = enable;
47}
48bool PlainTextDecoder::trailingWhitespace() const
49{
50    return _includeTrailingWhitespace;
51}
52void PlainTextDecoder::begin(QTextStream* output)
53{
54   _output = output;
55   if (!_linePositions.isEmpty())
56       _linePositions.clear();
57}
58void PlainTextDecoder::end()
59{
60    _output = nullptr;
61}
62
63void PlainTextDecoder::setRecordLinePositions(bool record)
64{
65    _recordLinePositions = record;
66}
67QList<int> PlainTextDecoder::linePositions() const
68{
69    return _linePositions;
70}
71void PlainTextDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
72                             )
73{
74    Q_ASSERT( _output );
75
76    if (_recordLinePositions && _output->string())
77    {
78        int pos = _output->string()->count();
79        _linePositions << pos;
80    }
81
82    // check the real length
83    for (int i = 0 ; i < count ; i++)
84    {
85        if (characters + i == nullptr)
86        {
87            count = i;
88            break;
89        }
90    }
91
92    //TODO should we ignore or respect the LINE_WRAPPED line property?
93
94    //note:  we build up a QString and send it to the text stream rather writing into the text
95    //stream a character at a time because it is more efficient.
96    //(since QTextStream always deals with QStrings internally anyway)
97    std::wstring plainText;
98    plainText.reserve(count);
99
100    int outputCount = count;
101
102    // if inclusion of trailing whitespace is disabled then find the end of the
103    // line
104    if ( !_includeTrailingWhitespace )
105    {
106        for (int i = count-1 ; i >= 0 ; i--)
107        {
108            if ( characters[i].character != L' '  )
109                break;
110            else
111                outputCount--;
112        }
113    }
114
115    for (int i=0;i<outputCount;)
116    {
117        plainText.push_back( characters[i].character );
118        i += qMax(1,konsole_wcwidth(characters[i].character));
119    }
120    *_output << QString::fromStdWString(plainText);
121}
122
123HTMLDecoder::HTMLDecoder() :
124        _output(nullptr)
125    ,_colorTable(base_color_table)
126       ,_innerSpanOpen(false)
127       ,_lastRendition(DEFAULT_RENDITION)
128{
129
130}
131
132void HTMLDecoder::begin(QTextStream* output)
133{
134    _output = output;
135
136    std::wstring text;
137
138    //open monospace span
139    openSpan(text,QLatin1String("font-family:monospace"));
140
141    *output << QString::fromStdWString(text);
142}
143
144void HTMLDecoder::end()
145{
146    Q_ASSERT( _output );
147
148    std::wstring text;
149
150    closeSpan(text);
151
152    *_output << QString::fromStdWString(text);
153
154    _output = nullptr;
155
156}
157
158//TODO: Support for LineProperty (mainly double width , double height)
159void HTMLDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
160                            )
161{
162    Q_ASSERT( _output );
163
164    std::wstring text;
165
166    int spaceCount = 0;
167
168    for (int i=0;i<count;i++)
169    {
170        wchar_t ch(characters[i].character);
171
172        //check if appearance of character is different from previous char
173        if ( characters[i].rendition != _lastRendition  ||
174             characters[i].foregroundColor != _lastForeColor  ||
175             characters[i].backgroundColor != _lastBackColor )
176        {
177            if ( _innerSpanOpen )
178                    closeSpan(text);
179
180            _lastRendition = characters[i].rendition;
181            _lastForeColor = characters[i].foregroundColor;
182            _lastBackColor = characters[i].backgroundColor;
183
184            //build up style string
185            QString style;
186
187            bool useBold;
188            ColorEntry::FontWeight weight = characters[i].fontWeight(_colorTable);
189            if (weight == ColorEntry::UseCurrentFormat)
190                useBold = _lastRendition & RE_BOLD;
191            else
192                useBold = weight == ColorEntry::Bold;
193
194            if (useBold)
195                style.append(QLatin1String("font-weight:bold;"));
196
197            if ( _lastRendition & RE_UNDERLINE )
198                    style.append(QLatin1String("font-decoration:underline;"));
199
200            //colours - a colour table must have been defined first
201            if ( _colorTable )
202            {
203                style.append( QString::fromLatin1("color:%1;").arg(_lastForeColor.color(_colorTable).name() ) );
204
205                if (!characters[i].isTransparent(_colorTable))
206                {
207                    style.append( QString::fromLatin1("background-color:%1;").arg(_lastBackColor.color(_colorTable).name() ) );
208                }
209            }
210
211            //open the span with the current style
212            openSpan(text,style);
213            _innerSpanOpen = true;
214        }
215
216        //handle whitespace
217        if (std::iswspace(ch))
218            spaceCount++;
219        else
220            spaceCount = 0;
221
222
223        //output current character
224        if (spaceCount < 2)
225        {
226            //escape HTML tag characters and just display others as they are
227            if ( ch == '<' )
228                text.append(L"&lt;");
229            else if (ch == '>')
230                    text.append(L"&gt;");
231            else
232                    text.push_back(ch);
233        }
234        else
235        {
236            text.append(L"&nbsp;"); //HTML truncates multiple spaces, so use a space marker instead
237        }
238
239    }
240
241    //close any remaining open inner spans
242    if ( _innerSpanOpen )
243        closeSpan(text);
244
245    //start new line
246    text.append(L"<br>");
247
248    *_output << QString::fromStdWString(text);
249}
250void HTMLDecoder::openSpan(std::wstring& text , const QString& style)
251{
252    text.append( QString(QLatin1String("<span style=\"%1\">")).arg(style).toStdWString() );
253}
254
255void HTMLDecoder::closeSpan(std::wstring& text)
256{
257    text.append(L"</span>");
258}
259
260void HTMLDecoder::setColorTable(const ColorEntry* table)
261{
262    _colorTable = table;
263}
Note: See TracBrowser for help on using the repository browser.