~verzegnassi-stefano/+junk/ubuntu-terminal-app-uitk13

« back to all changes in this revision

Viewing changes to src/plugin/qmltermwidget/qtermwidget/lib/TerminalCharacterDecoder.cpp

  • Committer: Filippo Scognamiglio
  • Date: 2014-10-25 04:42:31 UTC
  • Revision ID: flscogna@gmail.com-20141025044231-javjhusbqa171127
Initial reboot commit.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
using namespace Konsole;
 
35
PlainTextDecoder::PlainTextDecoder()
 
36
 : _output(0)
 
37
 , _includeTrailingWhitespace(true)
 
38
 , _recordLinePositions(false)
 
39
{
 
40
 
 
41
}
 
42
void PlainTextDecoder::setTrailingWhitespace(bool enable)
 
43
{
 
44
    _includeTrailingWhitespace = enable;
 
45
}
 
46
bool PlainTextDecoder::trailingWhitespace() const
 
47
{
 
48
    return _includeTrailingWhitespace;
 
49
}
 
50
void PlainTextDecoder::begin(QTextStream* output)
 
51
{
 
52
   _output = output;
 
53
   if (!_linePositions.isEmpty())
 
54
       _linePositions.clear();
 
55
}
 
56
void PlainTextDecoder::end()
 
57
{
 
58
    _output = 0;
 
59
}
 
60
 
 
61
void PlainTextDecoder::setRecordLinePositions(bool record)
 
62
{
 
63
    _recordLinePositions = record;
 
64
}
 
65
QList<int> PlainTextDecoder::linePositions() const
 
66
{
 
67
    return _linePositions;
 
68
}
 
69
void PlainTextDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
 
70
                             )
 
71
{
 
72
    Q_ASSERT( _output );
 
73
 
 
74
    if (_recordLinePositions && _output->string())
 
75
    {
 
76
        int pos = _output->string()->count();
 
77
        _linePositions << pos;
 
78
    }
 
79
 
 
80
    //TODO should we ignore or respect the LINE_WRAPPED line property?
 
81
 
 
82
    //note:  we build up a QString and send it to the text stream rather writing into the text
 
83
    //stream a character at a time because it is more efficient.
 
84
    //(since QTextStream always deals with QStrings internally anyway)
 
85
    QString plainText;
 
86
    plainText.reserve(count);
 
87
   
 
88
    int outputCount = count;
 
89
 
 
90
    // if inclusion of trailing whitespace is disabled then find the end of the
 
91
    // line
 
92
    if ( !_includeTrailingWhitespace )
 
93
    {
 
94
        for (int i = count-1 ; i >= 0 ; i--)
 
95
        {
 
96
            if ( characters[i].character != ' '  )
 
97
                break;
 
98
            else
 
99
                outputCount--;
 
100
        }
 
101
    }
 
102
    
 
103
    for (int i=0;i<outputCount;)
 
104
    {
 
105
        plainText.append( QChar(characters[i].character) );
 
106
        i += qMax(1,konsole_wcwidth(characters[i].character));
 
107
    }
 
108
    *_output << plainText;
 
109
}
 
110
 
 
111
HTMLDecoder::HTMLDecoder() :
 
112
        _output(0)
 
113
    ,_colorTable(base_color_table)
 
114
       ,_innerSpanOpen(false)
 
115
       ,_lastRendition(DEFAULT_RENDITION)
 
116
{
 
117
    
 
118
}
 
119
 
 
120
void HTMLDecoder::begin(QTextStream* output)
 
121
{
 
122
    _output = output;
 
123
 
 
124
    QString text;
 
125
 
 
126
    //open monospace span
 
127
    openSpan(text,"font-family:monospace");
 
128
 
 
129
    *output << text;
 
130
}
 
131
 
 
132
void HTMLDecoder::end()
 
133
{
 
134
    Q_ASSERT( _output );
 
135
 
 
136
    QString text;
 
137
 
 
138
    closeSpan(text);
 
139
 
 
140
    *_output << text;
 
141
 
 
142
    _output = 0;
 
143
 
 
144
}
 
145
 
 
146
//TODO: Support for LineProperty (mainly double width , double height)
 
147
void HTMLDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
 
148
                            )
 
149
{
 
150
    Q_ASSERT( _output );
 
151
 
 
152
    QString text;
 
153
 
 
154
    int spaceCount = 0;
 
155
        
 
156
    for (int i=0;i<count;i++)
 
157
    {
 
158
        QChar ch(characters[i].character);
 
159
 
 
160
        //check if appearance of character is different from previous char
 
161
        if ( characters[i].rendition != _lastRendition  ||
 
162
             characters[i].foregroundColor != _lastForeColor  ||
 
163
             characters[i].backgroundColor != _lastBackColor )
 
164
        {
 
165
            if ( _innerSpanOpen )
 
166
                    closeSpan(text);
 
167
 
 
168
            _lastRendition = characters[i].rendition;
 
169
            _lastForeColor = characters[i].foregroundColor;
 
170
            _lastBackColor = characters[i].backgroundColor;
 
171
            
 
172
            //build up style string
 
173
            QString style;
 
174
 
 
175
            bool useBold;
 
176
            ColorEntry::FontWeight weight = characters[i].fontWeight(_colorTable);
 
177
            if (weight == ColorEntry::UseCurrentFormat)
 
178
                useBold = _lastRendition & RE_BOLD;
 
179
            else
 
180
                useBold = weight == ColorEntry::Bold;
 
181
            
 
182
            if (useBold)
 
183
                style.append("font-weight:bold;");
 
184
 
 
185
            if ( _lastRendition & RE_UNDERLINE )
 
186
                    style.append("font-decoration:underline;");
 
187
        
 
188
            //colours - a colour table must have been defined first
 
189
            if ( _colorTable )    
 
190
            {
 
191
                style.append( QString("color:%1;").arg(_lastForeColor.color(_colorTable).name() ) );
 
192
 
 
193
                if (!characters[i].isTransparent(_colorTable))
 
194
                {
 
195
                    style.append( QString("background-color:%1;").arg(_lastBackColor.color(_colorTable).name() ) );
 
196
                }
 
197
            }
 
198
        
 
199
            //open the span with the current style    
 
200
            openSpan(text,style);
 
201
            _innerSpanOpen = true;
 
202
        }
 
203
 
 
204
        //handle whitespace
 
205
        if (ch.isSpace())
 
206
            spaceCount++;
 
207
        else
 
208
            spaceCount = 0;
 
209
        
 
210
 
 
211
        //output current character
 
212
        if (spaceCount < 2)
 
213
        {
 
214
            //escape HTML tag characters and just display others as they are
 
215
            if ( ch == '<' )
 
216
                text.append("&lt;");
 
217
            else if (ch == '>')
 
218
                    text.append("&gt;");
 
219
            else    
 
220
                    text.append(ch);
 
221
        }
 
222
        else
 
223
        {
 
224
            text.append("&nbsp;"); //HTML truncates multiple spaces, so use a space marker instead
 
225
        }
 
226
        
 
227
    }
 
228
 
 
229
    //close any remaining open inner spans
 
230
    if ( _innerSpanOpen )
 
231
        closeSpan(text);
 
232
 
 
233
    //start new line
 
234
    text.append("<br>");
 
235
    
 
236
    *_output << text;
 
237
}
 
238
void HTMLDecoder::openSpan(QString& text , const QString& style)
 
239
{
 
240
    text.append( QString("<span style=\"%1\">").arg(style) );
 
241
}
 
242
 
 
243
void HTMLDecoder::closeSpan(QString& text)
 
244
{
 
245
    text.append("</span>");
 
246
}
 
247
 
 
248
void HTMLDecoder::setColorTable(const ColorEntry* table)
 
249
{
 
250
    _colorTable = table;
 
251
}