~ubuntu-branches/ubuntu/saucy/konsole/saucy-proposed

« back to all changes in this revision

Viewing changes to src/TerminalCharacterDecoder.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2012-06-06 14:29:24 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20120606142924-1rekqv6j25lw2k41
Tags: 4:4.8.80-0ubuntu1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
// Qt
26
26
#include <QtCore/QTextStream>
27
27
 
28
 
// KDE
29
 
#include <KDebug>
30
 
 
31
28
// Konsole
32
29
#include "konsole_wcwidth.h"
 
30
#include "ExtendedCharTable.h"
 
31
#include "ColorScheme.h"
33
32
 
34
33
using namespace Konsole;
35
34
PlainTextDecoder::PlainTextDecoder()
36
 
 : _output(0)
37
 
 , _includeTrailingWhitespace(true)
38
 
 , _recordLinePositions(false)
 
35
    : _output(0)
 
36
    , _includeTrailingWhitespace(true)
 
37
    , _recordLinePositions(false)
39
38
{
40
 
 
41
39
}
42
40
void PlainTextDecoder::setTrailingWhitespace(bool enable)
43
41
{
49
47
}
50
48
void PlainTextDecoder::begin(QTextStream* output)
51
49
{
52
 
   _output = output;
53
 
   if (!_linePositions.isEmpty())
54
 
       _linePositions.clear();
 
50
    _output = output;
 
51
    if (!_linePositions.isEmpty())
 
52
        _linePositions.clear();
55
53
}
56
54
void PlainTextDecoder::end()
57
55
{
67
65
    return _linePositions;
68
66
}
69
67
void PlainTextDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
70
 
                             )
 
68
                                 )
71
69
{
72
 
    Q_ASSERT( _output );
 
70
    Q_ASSERT(_output);
73
71
 
74
 
    if (_recordLinePositions && _output->string())
75
 
    {
 
72
    if (_recordLinePositions && _output->string()) {
76
73
        int pos = _output->string()->count();
77
74
        _linePositions << pos;
78
75
    }
89
86
 
90
87
    // if inclusion of trailing whitespace is disabled then find the end of the
91
88
    // line
92
 
    if ( !_includeTrailingWhitespace )
93
 
    {
94
 
        for (int i = count-1 ; i >= 0 ; i--)
95
 
        {
96
 
            if ( !characters[i].isSpace() )
 
89
    if (!_includeTrailingWhitespace) {
 
90
        for (int i = count - 1 ; i >= 0 ; i--) {
 
91
            if (!characters[i].isSpace())
97
92
                break;
98
93
            else
99
94
                outputCount--;
101
96
    }
102
97
 
103
98
    // find out the last technically real character in the line
104
 
    int guard = -1 ;
105
 
    for (int i = count-1 ; i >= 0 ; i--)
106
 
    {
 
99
    int guard = -1;
 
100
    for (int i = count - 1 ; i >= 0 ; i--) {
107
101
        // FIXME: the special case of '\n' here is really ugly
108
102
        // Maybe the '\n' should be added after calling this method in
109
103
        // Screen::copyLineToStream()
110
 
        if ( characters[i].isRealCharacter && characters[i].character != '\n' )
111
 
        {
 
104
        if (characters[i].isRealCharacter && characters[i].character != '\n') {
112
105
            guard = i;
113
106
            break;
114
107
        }
115
108
    }
116
109
 
117
 
    for (int i=0;i<outputCount;)
118
 
    {
119
 
        if (characters[i].rendition & RE_EXTENDED_CHAR)
120
 
        {
 
110
    for (int i = 0; i < outputCount;) {
 
111
        if (characters[i].rendition & RE_EXTENDED_CHAR) {
121
112
            ushort extendedCharLength = 0;
122
113
            const ushort* chars = ExtendedCharTable::instance.lookupExtendedChar(characters[i].character, extendedCharLength);
123
 
            if (chars)
124
 
            {
 
114
            if (chars) {
125
115
                const QString s = QString::fromUtf16(chars, extendedCharLength);
126
116
                plainText.append(s);
127
117
                i += string_width(s);
128
118
            }
129
 
        }
130
 
        else
131
 
        {
 
119
        } else {
132
120
            // All characters which appear before the last real character are
133
121
            // seen as real characters, even when they are technically marked as
134
122
            // non-real.
136
124
            // This feels tricky, but otherwise leading "whitespaces" may be
137
125
            // lost in some situation. One typical example is copying the result
138
126
            // of `dialog --infobox "qwe" 10 10` .
139
 
            if ( characters[i].isRealCharacter || i <= guard )
140
 
            {
141
 
                plainText.append( QChar(characters[i].character) );
142
 
                i += qMax(1,konsole_wcwidth(characters[i].character));
143
 
            }
144
 
            else
145
 
            {
 
127
            if (characters[i].isRealCharacter || i <= guard) {
 
128
                plainText.append(QChar(characters[i].character));
 
129
                i += qMax(1, konsole_wcwidth(characters[i].character));
 
130
            } else {
146
131
                ++i;  // should we 'break' directly here?
147
132
            }
148
133
        }
151
136
}
152
137
 
153
138
HTMLDecoder::HTMLDecoder() :
154
 
        _output(0)
155
 
    ,_colorTable(base_color_table)
156
 
       ,_innerSpanOpen(false)
157
 
       ,_lastRendition(DEFAULT_RENDITION)
 
139
    _output(0)
 
140
    , _colorTable(ColorScheme::defaultTable)
 
141
    , _innerSpanOpen(false)
 
142
    , _lastRendition(DEFAULT_RENDITION)
158
143
{
159
 
 
160
144
}
161
145
 
162
146
void HTMLDecoder::begin(QTextStream* output)
166
150
    QString text;
167
151
 
168
152
    //open monospace span
169
 
    openSpan(text,"font-family:monospace");
 
153
    openSpan(text, "font-family:monospace");
170
154
 
171
155
    *output << text;
172
156
}
173
157
 
174
158
void HTMLDecoder::end()
175
159
{
176
 
    Q_ASSERT( _output );
 
160
    Q_ASSERT(_output);
177
161
 
178
162
    QString text;
179
163
 
182
166
    *_output << text;
183
167
 
184
168
    _output = 0;
185
 
 
186
169
}
187
170
 
188
171
//TODO: Support for LineProperty (mainly double width , double height)
189
172
void HTMLDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
190
173
                            )
191
174
{
192
 
    Q_ASSERT( _output );
 
175
    Q_ASSERT(_output);
193
176
 
194
177
    QString text;
195
178
 
196
179
    int spaceCount = 0;
197
180
 
198
 
    for (int i=0;i<count;i++)
199
 
    {
 
181
    for (int i = 0; i < count; i++) {
200
182
        //check if appearance of character is different from previous char
201
 
        if ( characters[i].rendition != _lastRendition  ||
202
 
             characters[i].foregroundColor != _lastForeColor  ||
203
 
             characters[i].backgroundColor != _lastBackColor )
204
 
        {
205
 
            if ( _innerSpanOpen )
206
 
                    closeSpan(text);
 
183
        if (characters[i].rendition != _lastRendition  ||
 
184
                characters[i].foregroundColor != _lastForeColor  ||
 
185
                characters[i].backgroundColor != _lastBackColor) {
 
186
            if (_innerSpanOpen)
 
187
                closeSpan(text);
207
188
 
208
189
            _lastRendition = characters[i].rendition;
209
190
            _lastForeColor = characters[i].foregroundColor;
222
203
            if (useBold)
223
204
                style.append("font-weight:bold;");
224
205
 
225
 
            if ( _lastRendition & RE_UNDERLINE )
226
 
                    style.append("font-decoration:underline;");
 
206
            if (_lastRendition & RE_UNDERLINE)
 
207
                style.append("font-decoration:underline;");
227
208
 
228
209
            //colors - a color table must have been defined first
229
 
            if ( _colorTable )    
230
 
            {
231
 
                style.append( QString("color:%1;").arg(_lastForeColor.color(_colorTable).name() ) );
 
210
            if (_colorTable) {
 
211
                style.append(QString("color:%1;").arg(_lastForeColor.color(_colorTable).name()));
232
212
 
233
 
                if (!characters[i].isTransparent(_colorTable))
234
 
                {
235
 
                    style.append( QString("background-color:%1;").arg(_lastBackColor.color(_colorTable).name() ) );
236
 
                }
 
213
                style.append(QString("background-color:%1;").arg(_lastBackColor.color(_colorTable).name()));
237
214
            }
238
215
 
239
 
            //open the span with the current style    
240
 
            openSpan(text,style);
 
216
            //open the span with the current style
 
217
            openSpan(text, style);
241
218
            _innerSpanOpen = true;
242
219
        }
243
220
 
247
224
        else
248
225
            spaceCount = 0;
249
226
 
250
 
 
251
227
        //output current character
252
 
        if (spaceCount < 2)
253
 
        {
254
 
            if (characters[i].rendition & RE_EXTENDED_CHAR)
255
 
            {
 
228
        if (spaceCount < 2) {
 
229
            if (characters[i].rendition & RE_EXTENDED_CHAR) {
256
230
                ushort extendedCharLength = 0;
257
231
                const ushort* chars = ExtendedCharTable::instance.lookupExtendedChar(characters[i].character, extendedCharLength);
258
 
                if (chars)
259
 
                {
 
232
                if (chars) {
260
233
                    text.append(QString::fromUtf16(chars, extendedCharLength));
261
234
                }
262
 
            }
263
 
            else
264
 
            {
 
235
            } else {
265
236
                //escape HTML tag characters and just display others as they are
266
237
                const QChar ch = characters[i].character;
267
 
                if ( ch == '<' )
 
238
                if (ch == '<')
268
239
                    text.append("&lt;");
269
240
                else if (ch == '>')
270
241
                    text.append("&gt;");
271
 
                else    
 
242
                else
272
243
                    text.append(ch);
273
244
            }
274
 
        }
275
 
        else
276
 
        {
 
245
        } else {
277
246
            text.append("&nbsp;"); //HTML truncates multiple spaces, so use a space marker instead
278
247
        }
279
 
 
280
248
    }
281
249
 
282
250
    //close any remaining open inner spans
283
 
    if ( _innerSpanOpen )
 
251
    if (_innerSpanOpen)
284
252
        closeSpan(text);
285
253
 
286
254
    //start new line
290
258
}
291
259
void HTMLDecoder::openSpan(QString& text , const QString& style)
292
260
{
293
 
    text.append( QString("<span style=\"%1\">").arg(style) );
 
261
    text.append(QString("<span style=\"%1\">").arg(style));
294
262
}
295
263
 
296
264
void HTMLDecoder::closeSpan(QString& text)