summaryrefslogtreecommitdiff
authorllornkcor <llornkcor>2002-11-01 12:56:21 (UTC)
committer llornkcor <llornkcor>2002-11-01 12:56:21 (UTC)
commit287f8a39e757e87a840fbffce258ee03c6b62161 (patch) (unidiff)
treef62a4f36857aeb6f3f270ddadf92010639b6ce94
parent14bd24ba233e370b44ec23cab2733289a3387ca7 (diff)
downloadopie-287f8a39e757e87a840fbffce258ee03c6b62161.zip
opie-287f8a39e757e87a840fbffce258ee03c6b62161.tar.gz
opie-287f8a39e757e87a840fbffce258ee03c6b62161.tar.bz2
remove some commented code
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/TEScreen.cpp60
-rw-r--r--core/apps/embeddedkonsole/TEWidget.cpp63
2 files changed, 3 insertions, 120 deletions
diff --git a/core/apps/embeddedkonsole/TEScreen.cpp b/core/apps/embeddedkonsole/TEScreen.cpp
index 50807d3..a6cf6a1 100644
--- a/core/apps/embeddedkonsole/TEScreen.cpp
+++ b/core/apps/embeddedkonsole/TEScreen.cpp
@@ -1,1278 +1,1220 @@
1/* -------------------------------------------------------------------------- */ 1/* -------------------------------------------------------------------------- */
2/* */ 2/* */
3/* [TEScreen.C] Screen Data Type */ 3/* [TEScreen.C] Screen Data Type */
4/* */ 4/* */
5/* -------------------------------------------------------------------------- */ 5/* -------------------------------------------------------------------------- */
6/* */ 6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ 7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */ 8/* */
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* */ 10/* */
11/* -------------------------------------------------------------------------- */ 11/* -------------------------------------------------------------------------- */
12/* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14/* */ 14/* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16/* */ 16/* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18// enhancements added by L.J. Potter <ljp@llornkcor.com> 18// enhancements added by L.J. Potter <ljp@llornkcor.com>
19 19
20/*! \file 20/*! \file
21*/ 21*/
22 22
23/*! \class TEScreen 23/*! \class TEScreen
24 24
25 \brief The image manipulated by the emulation. 25 \brief The image manipulated by the emulation.
26 26
27 This class implements the operations of the terminal emulation framework. 27 This class implements the operations of the terminal emulation framework.
28 It is a complete passive device, driven by the emulation decoder 28 It is a complete passive device, driven by the emulation decoder
29 (TEmuVT102). By this it forms in fact an ADT, that defines operations 29 (TEmuVT102). By this it forms in fact an ADT, that defines operations
30 on a rectangular image. 30 on a rectangular image.
31 31
32 It does neither know how to display its image nor about escape sequences. 32 It does neither know how to display its image nor about escape sequences.
33 It is further independent of the underlying toolkit. By this, one can even 33 It is further independent of the underlying toolkit. By this, one can even
34 use this module for an ordinary text surface. 34 use this module for an ordinary text surface.
35 35
36 Since the operations are called by a specific emulation decoder, one may 36 Since the operations are called by a specific emulation decoder, one may
37 collect their different operations here. 37 collect their different operations here.
38 38
39 The state manipulated by the operations is mainly kept in `image', though 39 The state manipulated by the operations is mainly kept in `image', though
40 it is a little more complex bejond this. See the header file of the class. 40 it is a little more complex bejond this. See the header file of the class.
41 41
42 \sa TEWidget \sa VT102Emulation 42 \sa TEWidget \sa VT102Emulation
43*/ 43*/
44 44
45#include <stdio.h> 45#include <stdio.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <unistd.h> 47#include <unistd.h>
48// #include <kdebug.h> 48// #include <kdebug.h>
49 49
50#include <assert.h> 50#include <assert.h>
51#include <string.h> 51#include <string.h>
52#include <ctype.h> 52#include <ctype.h>
53 53
54#include <qpe/config.h> 54#include <qpe/config.h>
55#include "TEScreen.h" 55#include "TEScreen.h"
56 56
57#define HERE printf("%s(%d): here\n",__FILE__,__LINE__) 57#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
58 58
59//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI. 59//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI.
60//FIXME: see if we can get this from terminfo. 60//FIXME: see if we can get this from terminfo.
61#define BS_CLEARS FALSE 61#define BS_CLEARS FALSE
62 62
63#define loc(X,Y) ((Y) * columns + (X)) 63#define loc(X,Y) ((Y) * columns + (X))
64 64
65/*! creates a `TEScreen' of `lines' lines and `columns' columns. 65/*! creates a `TEScreen' of `lines' lines and `columns' columns.
66*/ 66*/
67 67
68TEScreen::TEScreen(int lines, int columns) 68TEScreen::TEScreen(int lines, int columns)
69{ 69{
70 this->lines = lines; 70 this->lines = lines;
71 this->columns = columns; 71 this->columns = columns;
72// qDebug("Columns %d", columns); 72// qDebug("Columns %d", columns);
73 73
74 image = (ca*) malloc(lines*columns*sizeof(ca)); 74 image = (ca*) malloc(lines*columns*sizeof(ca));
75 tabstops = NULL; initTabStops(); 75 tabstops = NULL; initTabStops();
76 76
77 histCursor = 0; 77 histCursor = 0;
78 horzCursor = 0; 78 horzCursor = 0;
79 79
80 clearSelection(); 80 clearSelection();
81 reset(); 81 reset();
82} 82}
83 83
84/*! Destructor 84/*! Destructor
85*/ 85*/
86 86
87TEScreen::~TEScreen() 87TEScreen::~TEScreen()
88{ 88{
89 free(image); 89 free(image);
90 if (tabstops) free(tabstops); 90 if (tabstops) free(tabstops);
91} 91}
92 92
93/* ------------------------------------------------------------------------- */ 93/* ------------------------------------------------------------------------- */
94/* */ 94/* */
95/* Normalized Screen Operations */ 95/* Normalized Screen Operations */
96/* */ 96/* */
97/* ------------------------------------------------------------------------- */ 97/* ------------------------------------------------------------------------- */
98 98
99// Cursor Setting -------------------------------------------------------------- 99// Cursor Setting --------------------------------------------------------------
100 100
101/*! \section Cursor 101/*! \section Cursor
102 102
103 The `cursor' is a location within the screen that is implicitely used in 103 The `cursor' is a location within the screen that is implicitely used in
104 many operations. The operations within this section allow to manipulate 104 many operations. The operations within this section allow to manipulate
105 the cursor explicitly and to obtain it's value. 105 the cursor explicitly and to obtain it's value.
106 106
107 The position of the cursor is guarantied to be between (including) 0 and 107 The position of the cursor is guarantied to be between (including) 0 and
108 `columns-1' and `lines-1'. 108 `columns-1' and `lines-1'.
109*/ 109*/
110 110
111/*! 111/*!
112 Move the cursor up. 112 Move the cursor up.
113 113
114 The cursor will not be moved beyond the top margin. 114 The cursor will not be moved beyond the top margin.
115*/ 115*/
116 116
117void TEScreen::cursorUp(int n) 117void TEScreen::cursorUp(int n)
118//=CUU 118//=CUU
119{ 119{
120 if (n == 0) n = 1; // Default 120 if (n == 0) n = 1; // Default
121 int stop = cuY < tmargin ? 0 : tmargin; 121 int stop = cuY < tmargin ? 0 : tmargin;
122 cuX = QMIN(columns-1,cuX); // nowrap! 122 cuX = QMIN(columns-1,cuX); // nowrap!
123 cuY = QMAX(stop,cuY-n); 123 cuY = QMAX(stop,cuY-n);
124} 124}
125 125
126/*! 126/*!
127 Move the cursor down. 127 Move the cursor down.
128 128
129 The cursor will not be moved beyond the bottom margin. 129 The cursor will not be moved beyond the bottom margin.
130*/ 130*/
131 131
132void TEScreen::cursorDown(int n) 132void TEScreen::cursorDown(int n)
133//=CUD 133//=CUD
134{ 134{
135 if (n == 0) n = 1; // Default 135 if (n == 0) n = 1; // Default
136 int stop = cuY > bmargin ? lines-1 : bmargin; 136 int stop = cuY > bmargin ? lines-1 : bmargin;
137 cuX = QMIN(columns-1,cuX); // nowrap! 137 cuX = QMIN(columns-1,cuX); // nowrap!
138 cuY = QMIN(stop,cuY+n); 138 cuY = QMIN(stop,cuY+n);
139} 139}
140 140
141/*! 141/*!
142 Move the cursor left. 142 Move the cursor left.
143 143
144 The cursor will not move beyond the first column. 144 The cursor will not move beyond the first column.
145*/ 145*/
146 146
147void TEScreen::cursorLeft(int n) 147void TEScreen::cursorLeft(int n)
148//=CUB 148//=CUB
149{ 149{
150 if (n == 0) n = 1; // Default 150 if (n == 0) n = 1; // Default
151 cuX = QMIN(columns-1,cuX); // nowrap! 151 cuX = QMIN(columns-1,cuX); // nowrap!
152 cuX = QMAX(0,cuX-n); 152 cuX = QMAX(0,cuX-n);
153} 153}
154 154
155/*! 155/*!
156 Move the cursor left. 156 Move the cursor left.
157 157
158 The cursor will not move beyond the rightmost column. 158 The cursor will not move beyond the rightmost column.
159*/ 159*/
160 160
161void TEScreen::cursorRight(int n) 161void TEScreen::cursorRight(int n)
162//=CUF 162//=CUF
163{ 163{
164 if (n == 0) n = 1; // Default 164 if (n == 0) n = 1; // Default
165 cuX = QMIN(columns-1,cuX+n); 165 cuX = QMIN(columns-1,cuX+n);
166} 166}
167 167
168/*! 168/*!
169 Set top and bottom margin. 169 Set top and bottom margin.
170*/ 170*/
171 171
172void TEScreen::setMargins(int top, int bot) 172void TEScreen::setMargins(int top, int bot)
173//=STBM 173//=STBM
174{ 174{
175 if (top == 0) top = 1; // Default 175 if (top == 0) top = 1; // Default
176 if (bot == 0) bot = lines; // Default 176 if (bot == 0) bot = lines; // Default
177 top = top - 1; // Adjust to internal lineno 177 top = top - 1; // Adjust to internal lineno
178 bot = bot - 1; // Adjust to internal lineno 178 bot = bot - 1; // Adjust to internal lineno
179 if ( !( 0 <= top && top < bot && bot < lines ) ) 179 if ( !( 0 <= top && top < bot && bot < lines ) )
180 { fprintf(stderr,"%s(%d) : setRegion(%d,%d) : bad range.\n", 180 { fprintf(stderr,"%s(%d) : setRegion(%d,%d) : bad range.\n",
181 __FILE__,__LINE__,top,bot); 181 __FILE__,__LINE__,top,bot);
182 return; // Default error action: ignore 182 return; // Default error action: ignore
183 } 183 }
184 tmargin = top; 184 tmargin = top;
185 bmargin = bot; 185 bmargin = bot;
186 cuX = 0; 186 cuX = 0;
187 cuY = getMode(MODE_Origin) ? top : 0; 187 cuY = getMode(MODE_Origin) ? top : 0;
188} 188}
189 189
190/*! 190/*!
191 Move the cursor down one line. 191 Move the cursor down one line.
192 192
193 If cursor is on bottom margin, the region between the 193 If cursor is on bottom margin, the region between the
194 actual top and bottom margin is scrolled up instead. 194 actual top and bottom margin is scrolled up instead.
195*/ 195*/
196 196
197void TEScreen::index() 197void TEScreen::index()
198//=IND 198//=IND
199{ 199{
200 if (cuY == bmargin) 200 if (cuY == bmargin)
201 { 201 {
202 if (tmargin == 0 && bmargin == lines-1) addHistLine(); // hist.history 202 if (tmargin == 0 && bmargin == lines-1) addHistLine(); // hist.history
203 scrollUp(tmargin,1); 203 scrollUp(tmargin,1);
204 } 204 }
205 else if (cuY < lines-1) 205 else if (cuY < lines-1)
206 cuY += 1; 206 cuY += 1;
207} 207}
208 208
209/*! 209/*!
210 Move the cursor up one line. 210 Move the cursor up one line.
211 211
212 If cursor is on the top margin, the region between the 212 If cursor is on the top margin, the region between the
213 actual top and bottom margin is scrolled down instead. 213 actual top and bottom margin is scrolled down instead.
214*/ 214*/
215 215
216void TEScreen::reverseIndex() 216void TEScreen::reverseIndex()
217//=RI 217//=RI
218{ 218{
219 if (cuY == tmargin) 219 if (cuY == tmargin)
220 scrollDown(tmargin,1); 220 scrollDown(tmargin,1);
221 else if (cuY > 0) 221 else if (cuY > 0)
222 cuY -= 1; 222 cuY -= 1;
223} 223}
224 224
225/*! 225/*!
226 Move the cursor to the begin of the next line. 226 Move the cursor to the begin of the next line.
227 227
228 If cursor is on bottom margin, the region between the 228 If cursor is on bottom margin, the region between the
229 actual top and bottom margin is scrolled up. 229 actual top and bottom margin is scrolled up.
230*/ 230*/
231 231
232void TEScreen::NextLine() 232void TEScreen::NextLine()
233//=NEL 233//=NEL
234{ 234{
235 Return(); index(); 235 Return(); index();
236} 236}
237 237
238// Line Editing ---------------------------------------------------------------- 238// Line Editing ----------------------------------------------------------------
239 239
240/*! \section inserting / deleting characters 240/*! \section inserting / deleting characters
241*/ 241*/
242 242
243/*! erase `n' characters starting from (including) the cursor position. 243/*! erase `n' characters starting from (including) the cursor position.
244 244
245 The line is filled in from the right with spaces. 245 The line is filled in from the right with spaces.
246*/ 246*/
247 247
248void TEScreen::eraseChars(int n) 248void TEScreen::eraseChars(int n)
249{ 249{
250 if (n == 0) n = 1; // Default 250 if (n == 0) n = 1; // Default
251 int p = QMAX(0,QMIN(cuX+n-1,columns-1)); 251 int p = QMAX(0,QMIN(cuX+n-1,columns-1));
252 clearImage(loc(cuX,cuY),loc(p,cuY),' '); 252 clearImage(loc(cuX,cuY),loc(p,cuY),' ');
253} 253}
254 254
255/*! delete `n' characters starting from (including) the cursor position. 255/*! delete `n' characters starting from (including) the cursor position.
256 256
257 The line is filled in from the right with spaces. 257 The line is filled in from the right with spaces.
258*/ 258*/
259 259
260void TEScreen::deleteChars(int n) 260void TEScreen::deleteChars(int n)
261{ 261{
262 if (n == 0) n = 1; // Default 262 if (n == 0) n = 1; // Default
263 int p = QMAX(0,QMIN(cuX+n,columns-1)); 263 int p = QMAX(0,QMIN(cuX+n,columns-1));
264 moveImage(loc(cuX,cuY),loc(p,cuY),loc(columns-1,cuY)); 264 moveImage(loc(cuX,cuY),loc(p,cuY),loc(columns-1,cuY));
265 clearImage(loc(columns-n,cuY),loc(columns-1,cuY),' '); 265 clearImage(loc(columns-n,cuY),loc(columns-1,cuY),' ');
266} 266}
267 267
268/*! insert `n' spaces at the cursor position. 268/*! insert `n' spaces at the cursor position.
269 269
270 The cursor is not moved by the operation. 270 The cursor is not moved by the operation.
271*/ 271*/
272 272
273void TEScreen::insertChars(int n) 273void TEScreen::insertChars(int n)
274{ 274{
275 if (n == 0) n = 1; // Default 275 if (n == 0) n = 1; // Default
276 int p = QMAX(0,QMIN(columns-1-n,columns-1)); 276 int p = QMAX(0,QMIN(columns-1-n,columns-1));
277 int q = QMAX(0,QMIN(cuX+n,columns-1)); 277 int q = QMAX(0,QMIN(cuX+n,columns-1));
278 moveImage(loc(q,cuY),loc(cuX,cuY),loc(p,cuY)); 278 moveImage(loc(q,cuY),loc(cuX,cuY),loc(p,cuY));
279 clearImage(loc(cuX,cuY),loc(q-1,cuY),' '); 279 clearImage(loc(cuX,cuY),loc(q-1,cuY),' ');
280} 280}
281 281
282/*! delete `n' lines starting from (including) the cursor position. 282/*! delete `n' lines starting from (including) the cursor position.
283 283
284 The cursor is not moved by the operation. 284 The cursor is not moved by the operation.
285*/ 285*/
286 286
287void TEScreen::deleteLines(int n) 287void TEScreen::deleteLines(int n)
288{ 288{
289 if (n == 0) n = 1; // Default 289 if (n == 0) n = 1; // Default
290 scrollUp(cuY,n); 290 scrollUp(cuY,n);
291} 291}
292 292
293/*! insert `n' lines at the cursor position. 293/*! insert `n' lines at the cursor position.
294 294
295 The cursor is not moved by the operation. 295 The cursor is not moved by the operation.
296*/ 296*/
297 297
298void TEScreen::insertLines(int n) 298void TEScreen::insertLines(int n)
299{ 299{
300 if (n == 0) n = 1; // Default 300 if (n == 0) n = 1; // Default
301 scrollDown(cuY,n); 301 scrollDown(cuY,n);
302} 302}
303 303
304// Mode Operations ----------------------------------------------------------- 304// Mode Operations -----------------------------------------------------------
305 305
306/*! Set a specific mode. */ 306/*! Set a specific mode. */
307 307
308void TEScreen::setMode(int m) 308void TEScreen::setMode(int m)
309{ 309{
310 currParm.mode[m] = TRUE; 310 currParm.mode[m] = TRUE;
311 switch(m) 311 switch(m)
312 { 312 {
313 case MODE_Origin : cuX = 0; cuY = tmargin; break; //FIXME: home 313 case MODE_Origin : cuX = 0; cuY = tmargin; break; //FIXME: home
314 } 314 }
315} 315}
316 316
317/*! Reset a specific mode. */ 317/*! Reset a specific mode. */
318 318
319void TEScreen::resetMode(int m) 319void TEScreen::resetMode(int m)
320{ 320{
321 currParm.mode[m] = FALSE; 321 currParm.mode[m] = FALSE;
322 switch(m) 322 switch(m)
323 { 323 {
324 case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home 324 case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home
325 } 325 }
326} 326}
327 327
328/*! Save a specific mode. */ 328/*! Save a specific mode. */
329 329
330void TEScreen::saveMode(int m) 330void TEScreen::saveMode(int m)
331{ 331{
332 saveParm.mode[m] = currParm.mode[m]; 332 saveParm.mode[m] = currParm.mode[m];
333} 333}
334 334
335/*! Restore a specific mode. */ 335/*! Restore a specific mode. */
336 336
337void TEScreen::restoreMode(int m) 337void TEScreen::restoreMode(int m)
338{ 338{
339 currParm.mode[m] = saveParm.mode[m]; 339 currParm.mode[m] = saveParm.mode[m];
340} 340}
341 341
342//NOTE: this is a helper function 342//NOTE: this is a helper function
343/*! Return the setting a specific mode. */ 343/*! Return the setting a specific mode. */
344BOOL TEScreen::getMode(int m) 344BOOL TEScreen::getMode(int m)
345{ 345{
346 return currParm.mode[m]; 346 return currParm.mode[m];
347} 347}
348 348
349/*! Save the cursor position and the rendition attribute settings. */ 349/*! Save the cursor position and the rendition attribute settings. */
350 350
351void TEScreen::saveCursor() 351void TEScreen::saveCursor()
352{ 352{
353 sa_cuX = cuX; 353 sa_cuX = cuX;
354 sa_cuY = cuY; 354 sa_cuY = cuY;
355 sa_cu_re = cu_re; 355 sa_cu_re = cu_re;
356 sa_cu_fg = cu_fg; 356 sa_cu_fg = cu_fg;
357 sa_cu_bg = cu_bg; 357 sa_cu_bg = cu_bg;
358} 358}
359 359
360/*! Restore the cursor position and the rendition attribute settings. */ 360/*! Restore the cursor position and the rendition attribute settings. */
361 361
362void TEScreen::restoreCursor() 362void TEScreen::restoreCursor()
363{ 363{
364 cuX = QMIN(sa_cuX,columns-1); 364 cuX = QMIN(sa_cuX,columns-1);
365 cuY = QMIN(sa_cuY,lines-1); 365 cuY = QMIN(sa_cuY,lines-1);
366 cu_re = sa_cu_re; 366 cu_re = sa_cu_re;
367 cu_fg = sa_cu_fg; 367 cu_fg = sa_cu_fg;
368 cu_bg = sa_cu_bg; 368 cu_bg = sa_cu_bg;
369 effectiveRendition(); 369 effectiveRendition();
370} 370}
371 371
372/* ------------------------------------------------------------------------- */ 372/* ------------------------------------------------------------------------- */
373/* */ 373/* */
374/* Screen Operations */ 374/* Screen Operations */
375/* */ 375/* */
376/* ------------------------------------------------------------------------- */ 376/* ------------------------------------------------------------------------- */
377 377
378/*! Assing a new size to the screen. 378/*! Assing a new size to the screen.
379 379
380 The topmost left position is maintained, while lower lines 380 The topmost left position is maintained, while lower lines
381 or right hand side columns might be removed or filled with 381 or right hand side columns might be removed or filled with
382 spaces to fit the new size. 382 spaces to fit the new size.
383 383
384 The region setting is reset to the whole screen and the 384 The region setting is reset to the whole screen and the
385 tab positions reinitialized. 385 tab positions reinitialized.
386*/ 386*/
387 387
388void TEScreen::resizeImage(int new_lines, int new_columns) 388void TEScreen::resizeImage(int new_lines, int new_columns)
389{ 389{
390 if (cuY > new_lines-1) { 390 if (cuY > new_lines-1) {
391// attempt to preserve focus and lines 391// attempt to preserve focus and lines
392 bmargin = lines-1; //FIXME: margin lost 392 bmargin = lines-1; //FIXME: margin lost
393 for (int i = 0; i < cuY-(new_lines-1); i++) { 393 for (int i = 0; i < cuY-(new_lines-1); i++) {
394 addHistLine(); scrollUp(horzCursor,1); 394 addHistLine(); scrollUp(horzCursor,1);
395 } 395 }
396 } 396 }
397 397
398 // make new image 398 // make new image
399 ca* newimg = (ca*)malloc( new_lines * new_columns * sizeof( ca)); 399 ca* newimg = (ca*)malloc( new_lines * new_columns * sizeof( ca));
400 400
401 clearSelection(); 401 clearSelection();
402 402
403 // clear new image 403 // clear new image
404 for (int y = 0; y < new_lines; y++) 404 for (int y = 0; y < new_lines; y++)
405 for (int x = 0; x < new_columns; x++) { 405 for (int x = 0; x < new_columns; x++) {
406 newimg[y*new_columns+x].c = ' '; 406 newimg[y*new_columns+x].c = ' ';
407 newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR; 407 newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR;
408 newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR; 408 newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR;
409 newimg[y*new_columns+x].r = DEFAULT_RENDITION; 409 newimg[y*new_columns+x].r = DEFAULT_RENDITION;
410 } 410 }
411 int cpy_lines = QMIN(new_lines, lines); 411 int cpy_lines = QMIN(new_lines, lines);
412 int cpy_columns = QMIN(new_columns,columns); 412 int cpy_columns = QMIN(new_columns,columns);
413 // copy to new image 413 // copy to new image
414 for (int y = 0; y < cpy_lines; y++) 414 for (int y = 0; y < cpy_lines; y++)
415 for (int x = 0; x < cpy_columns; x++) { 415 for (int x = 0; x < cpy_columns; x++) {
416 newimg[y*new_columns+x].c = image[loc(x,y)].c; 416 newimg[y*new_columns+x].c = image[loc(x,y)].c;
417 newimg[y*new_columns+x].f = image[loc(x,y)].f; 417 newimg[y*new_columns+x].f = image[loc(x,y)].f;
418 newimg[y*new_columns+x].b = image[loc(x,y)].b; 418 newimg[y*new_columns+x].b = image[loc(x,y)].b;
419 newimg[y*new_columns+x].r = image[loc(x,y)].r; 419 newimg[y*new_columns+x].r = image[loc(x,y)].r;
420 } 420 }
421 free(image); 421 free(image);
422 image = newimg; 422 image = newimg;
423 lines = new_lines; 423 lines = new_lines;
424 columns = new_columns; 424 columns = new_columns;
425 cuX = QMIN(cuX,columns-1); 425 cuX = QMIN(cuX,columns-1);
426 cuY = QMIN(cuY,lines-1); 426 cuY = QMIN(cuY,lines-1);
427 427
428 // FIXME: try to keep values, evtl. 428 // FIXME: try to keep values, evtl.
429 tmargin=0; 429 tmargin=0;
430 bmargin=lines-1; 430 bmargin=lines-1;
431 initTabStops(); 431 initTabStops();
432 clearSelection(); 432 clearSelection();
433} 433}
434 434
435/* 435/*
436 Clarifying rendition here and in TEWidget. 436 Clarifying rendition here and in TEWidget.
437 437
438 currently, TEWidget's color table is 438 currently, TEWidget's color table is
439 0 1 2 .. 9 10 .. 17 439 0 1 2 .. 9 10 .. 17
440 dft_fg, dft_bg, dim 0..7, intensive 0..7 440 dft_fg, dft_bg, dim 0..7, intensive 0..7
441 441
442 cu_fg, cu_bg contain values 0..8; 442 cu_fg, cu_bg contain values 0..8;
443 - 0 = default color 443 - 0 = default color
444 - 1..8 = ansi specified color 444 - 1..8 = ansi specified color
445 445
446 re_fg, re_bg contain values 0..17 446 re_fg, re_bg contain values 0..17
447 due to the TEWidget's color table 447 due to the TEWidget's color table
448 448
449 rendition attributes are 449 rendition attributes are
450 450
451 attr widget screen 451 attr widget screen
452 -------------- ------ ------ 452 -------------- ------ ------
453 RE_UNDERLINE XX XX affects foreground only 453 RE_UNDERLINE XX XX affects foreground only
454 RE_BLINK XX XX affects foreground only 454 RE_BLINK XX XX affects foreground only
455 RE_BOLD XX XX affects foreground only 455 RE_BOLD XX XX affects foreground only
456 RE_REVERSE -- XX 456 RE_REVERSE -- XX
457 RE_TRANSPARENT XX -- affects background only 457 RE_TRANSPARENT XX -- affects background only
458 RE_INTENSIVE XX -- affects foreground only 458 RE_INTENSIVE XX -- affects foreground only
459 459
460 Note that RE_BOLD is used in both widget 460 Note that RE_BOLD is used in both widget
461 and screen rendition. Since xterm/vt102 461 and screen rendition. Since xterm/vt102
462 is to poor to distinguish between bold 462 is to poor to distinguish between bold
463 (which is a font attribute) and intensive 463 (which is a font attribute) and intensive
464 (which is a color attribute), we translate 464 (which is a color attribute), we translate
465 this and RE_BOLD in falls eventually appart 465 this and RE_BOLD in falls eventually appart
466 into RE_BOLD and RE_INTENSIVE. 466 into RE_BOLD and RE_INTENSIVE.
467*/ 467*/
468 468
469void TEScreen::reverseRendition(ca* p) 469void TEScreen::reverseRendition(ca* p)
470{ UINT8 f = p->f; UINT8 b = p->b; 470{ UINT8 f = p->f; UINT8 b = p->b;
471 p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT; 471 p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT;
472} 472}
473 473
474void TEScreen::effectiveRendition() 474void TEScreen::effectiveRendition()
475// calculate rendition 475// calculate rendition
476{ 476{
477 ef_re = cu_re & (RE_UNDERLINE | RE_BLINK); 477 ef_re = cu_re & (RE_UNDERLINE | RE_BLINK);
478 if (cu_re & RE_REVERSE) 478 if (cu_re & RE_REVERSE)
479 { 479 {
480 ef_fg = cu_bg; 480 ef_fg = cu_bg;
481 ef_bg = cu_fg; 481 ef_bg = cu_fg;
482 } 482 }
483 else 483 else
484 { 484 {
485 ef_fg = cu_fg; 485 ef_fg = cu_fg;
486 ef_bg = cu_bg; 486 ef_bg = cu_bg;
487 } 487 }
488 if (cu_re & RE_BOLD) 488 if (cu_re & RE_BOLD)
489 { 489 {
490 if (ef_fg < BASE_COLORS) 490 if (ef_fg < BASE_COLORS)
491 ef_fg += BASE_COLORS; 491 ef_fg += BASE_COLORS;
492 else 492 else
493 ef_fg -= BASE_COLORS; 493 ef_fg -= BASE_COLORS;
494 } 494 }
495} 495}
496 496
497/*! 497/*!
498 returns the image. 498 returns the image.
499 499
500 Get the size of the image by \sa getLines and \sa getColumns. 500 Get the size of the image by \sa getLines and \sa getColumns.
501 501
502 NOTE that the image returned by this function must later be 502 NOTE that the image returned by this function must later be
503 freed. 503 freed.
504 504
505*/ 505*/
506 506
507ca* TEScreen::getCookedImage() 507ca* TEScreen::getCookedImage()
508{ 508{
509 int x,y; 509 int x,y;
510 ca* merged = (ca*)malloc(lines*columns*sizeof(ca)); 510 ca* merged = (ca*)malloc(lines*columns*sizeof(ca));
511 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION); 511 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
512 512
513 for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++) 513 for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++)
514 { 514 {
515 int len = QMIN(columns,hist.getLineLen(y+histCursor)); 515 int len = QMIN(columns,hist.getLineLen(y+histCursor));
516 int yp = y*columns; 516 int yp = y*columns;
517 int yq = (y+histCursor)*columns; 517 int yq = (y+histCursor)*columns;
518 518
519 hist.getCells(y+histCursor,0,len,merged+yp); 519 hist.getCells(y+histCursor,0,len,merged+yp);
520 for (x = len; x < columns; x++) merged[yp+x] = dft; 520 for (x = len; x < columns; x++) merged[yp+x] = dft;
521 for (x = 0; x < columns; x++) 521 for (x = 0; x < columns; x++)
522 { int p=x + yp; int q=x + yq; 522 { int p=x + yp; int q=x + yq;
523 if ( ( q >= sel_TL ) && ( q <= sel_BR ) ) 523 if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
524 reverseRendition(&merged[p]); // for selection 524 reverseRendition(&merged[p]); // for selection
525 } 525 }
526 } 526 }
527 if (lines >= hist.getLines()-histCursor) 527 if (lines >= hist.getLines()-histCursor)
528 { 528 {
529 for (y = (hist.getLines()-histCursor); y < lines ; y++) 529 for (y = (hist.getLines()-histCursor); y < lines ; y++)
530 { 530 {
531 int yp = y*columns; 531 int yp = y*columns;
532 int yq = (y+histCursor)*columns; 532 int yq = (y+histCursor)*columns;
533 int yr = (y-hist.getLines()+histCursor)*columns; 533 int yr = (y-hist.getLines()+histCursor)*columns;
534 for (x = 0; x < columns; x++) 534 for (x = 0; x < columns; x++)
535 { int p = x + yp; int q = x + yq; int r = x + yr; 535 { int p = x + yp; int q = x + yq; int r = x + yr;
536 merged[p] = image[r]; 536 merged[p] = image[r];
537 if ( q >= sel_TL && q <= sel_BR ) 537 if ( q >= sel_TL && q <= sel_BR )
538 reverseRendition(&merged[p]); // for selection 538 reverseRendition(&merged[p]); // for selection
539 } 539 }
540 540
541 } 541 }
542 } 542 }
543 // evtl. inverse display 543 // evtl. inverse display
544 if (getMode(MODE_Screen)) 544 if (getMode(MODE_Screen))
545 { int i,n = lines*columns; 545 { int i,n = lines*columns;
546 for (i = 0; i < n; i++) 546 for (i = 0; i < n; i++)
547 reverseRendition(&merged[i]); // for reverse display 547 reverseRendition(&merged[i]); // for reverse display
548 } 548 }
549 if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible 549 if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible
550 reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]); 550 reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]);
551 return merged; 551 return merged;
552 552
553 /*
554 int x, y, z;
555
556 ca* merged = (ca*)malloc( lines * columns * sizeof( ca));
557
558 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
559
560// qDebug("hist lines %d, historyCursor %d, minus %d ,lines %d, columns %d",
561// hist.getLines(), histCursor, hist.getLines() - histCursor , lines, columns);
562 for (y = 0; (y < lines) && (y < ( hist.getLines() - histCursor )); y++) {
563
564 int len = QMIN( columns, hist.getLineLen( y + histCursor) );
565 int yp = y * columns;
566 int yq = ( y + histCursor) * columns;
567// qDebug("horzCursor %d, columns %d, len %d", horzCursor, columns, len);
568// qDebug("lineno %d, colno %d, count %d\n", y + histCursor, (horzCursor / 2), len );
569 qDebug("Y %d", y);
570 hist.getCells( y + histCursor, (horzCursor / 2), len, merged + yp);
571
572 for (x = len; x < columns; x++)
573 merged[yp + x] = dft;
574 for (x = 0; x < columns; x++) {
575 int p = x + yp; int q = x + yq;
576 if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
577 reverseRendition(&merged[p]); // for selection
578 }
579 }
580
581 if (lines >= hist.getLines() - histCursor) {
582 for (y = ( hist.getLines() - histCursor); y < lines ; y++) {
583 int z = horzCursor;
584 int yp = y * columns;
585 int yq = ( y + histCursor) * columns;
586 int yr = ( y - hist.getLines() + histCursor) * columns;
587// qDebug("y %d, yp %d, yq %d, columns %d, z cursor %d", y, yp, yq, columns, z);
588 for (x = 0; x < columns; x++) {
589 int p = x + yp; int q = x + yq; int r = (x + (horzCursor/2) ) + yr;
590 merged[p] = image[r];
591 if ( q >= sel_TL && q <= sel_BR )
592 reverseRendition( &merged[p]); // for selection
593 }
594 }
595 }
596
597
598// evtl. inverse display
599 if (getMode(MODE_Screen))
600 { int i, n = lines * columns;
601 for (i = 0; i < n; i++)
602 reverseRendition( &merged[i]); // for reverse display
603 }
604 if (getMode(MODE_Cursor) && ( cuY + ( hist.getLines() - histCursor) < lines)) // cursor visible
605
606 reverseRendition( &merged[ loc( cuX, cuY + ( hist.getLines() - histCursor))] );
607
608 return merged;
609 */
610
611} 553}
612 554
613 555
614/*! 556/*!
615*/ 557*/
616 558
617void TEScreen::reset() 559void TEScreen::reset()
618{ 560{
619 Config cfg("Konsole"); 561 Config cfg("Konsole");
620 cfg.setGroup("ScrollBar"); 562 cfg.setGroup("ScrollBar");
621 if( !cfg.readBoolEntry("HorzScroll",0) ) 563 if( !cfg.readBoolEntry("HorzScroll",0) )
622 setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin 564 setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin
623 565
624 566
625 resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1] 567 resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1]
626 resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke 568 resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke
627 setMode(MODE_Cursor); // cursor visible 569 setMode(MODE_Cursor); // cursor visible
628 resetMode(MODE_Screen); // screen not inverse 570 resetMode(MODE_Screen); // screen not inverse
629 resetMode(MODE_NewLine); 571 resetMode(MODE_NewLine);
630 572
631 tmargin=0; 573 tmargin=0;
632 bmargin=lines-1; 574 bmargin=lines-1;
633 575
634 setDefaultRendition(); 576 setDefaultRendition();
635 saveCursor(); 577 saveCursor();
636 578
637 clear(); 579 clear();
638} 580}
639 581
640/*! Clear the entire screen and home the cursor. 582/*! Clear the entire screen and home the cursor.
641*/ 583*/
642 584
643void TEScreen::clear() 585void TEScreen::clear()
644{ 586{
645 clearEntireScreen(); 587 clearEntireScreen();
646 home(); 588 home();
647} 589}
648 590
649/*! Moves the cursor left one column. 591/*! Moves the cursor left one column.
650*/ 592*/
651 593
652void TEScreen::BackSpace() 594void TEScreen::BackSpace()
653{ 595{
654 cuX = QMAX(0,cuX-1); 596 cuX = QMAX(0,cuX-1);
655 if (BS_CLEARS) image[loc(cuX,cuY)].c = ' '; 597 if (BS_CLEARS) image[loc(cuX,cuY)].c = ' ';
656} 598}
657 599
658/*! 600/*!
659*/ 601*/
660 602
661void TEScreen::Tabulate() 603void TEScreen::Tabulate()
662{ 604{
663 // note that TAB is a format effector (does not write ' '); 605 // note that TAB is a format effector (does not write ' ');
664 cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1); 606 cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1);
665} 607}
666 608
667void TEScreen::clearTabStops() 609void TEScreen::clearTabStops()
668{ 610{
669 for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE; 611 for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE;
670} 612}
671 613
672void TEScreen::changeTabStop(bool set) 614void TEScreen::changeTabStop(bool set)
673{ 615{
674 if (cuX >= columns) return; 616 if (cuX >= columns) return;
675 tabstops[cuX] = set; 617 tabstops[cuX] = set;
676} 618}
677 619
678void TEScreen::initTabStops() 620void TEScreen::initTabStops()
679{ 621{
680 if (tabstops) free(tabstops); 622 if (tabstops) free(tabstops);
681 tabstops = (bool*)malloc(columns*sizeof(bool)); 623 tabstops = (bool*)malloc(columns*sizeof(bool));
682 // Arrg! The 1st tabstop has to be one longer than the other. 624 // Arrg! The 1st tabstop has to be one longer than the other.
683 // i.e. the kids start counting from 0 instead of 1. 625 // i.e. the kids start counting from 0 instead of 1.
684 // Other programs might behave correctly. Be aware. 626 // Other programs might behave correctly. Be aware.
685 for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0); 627 for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0);
686} 628}
687 629
688/*! 630/*!
689 This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine) 631 This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine)
690 depending on the NewLine Mode (LNM). This mode also 632 depending on the NewLine Mode (LNM). This mode also
691 affects the key sequence returned for newline ([CR]LF). 633 affects the key sequence returned for newline ([CR]LF).
692*/ 634*/
693 635
694void TEScreen::NewLine() 636void TEScreen::NewLine()
695{ 637{
696 if (getMode(MODE_NewLine)) Return(); 638 if (getMode(MODE_NewLine)) Return();
697 index(); 639 index();
698} 640}
699 641
700/*! put `c' literally onto the screen at the current cursor position. 642/*! put `c' literally onto the screen at the current cursor position.
701 643
702 VT100 uses the convention to produce an automatic newline (am) 644 VT100 uses the convention to produce an automatic newline (am)
703 with the *first* character that would fall onto the next line (xenl). 645 with the *first* character that would fall onto the next line (xenl).
704*/ 646*/
705 647
706void TEScreen::checkSelection(int from, int to) 648void TEScreen::checkSelection(int from, int to)
707{ 649{
708 if (sel_begin == -1) return; 650 if (sel_begin == -1) return;
709 int scr_TL = loc(0, hist.getLines()); 651 int scr_TL = loc(0, hist.getLines());
710 //Clear entire selection if it overlaps region [from, to] 652 //Clear entire selection if it overlaps region [from, to]
711 if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) ) 653 if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) )
712 { 654 {
713 clearSelection(); 655 clearSelection();
714 } 656 }
715} 657}
716 658
717void TEScreen::ShowCharacter(unsigned short c) 659void TEScreen::ShowCharacter(unsigned short c)
718{ 660{
719 // Note that VT100 does wrapping BEFORE putting the character. 661 // Note that VT100 does wrapping BEFORE putting the character.
720 // This has impact on the assumption of valid cursor positions. 662 // This has impact on the assumption of valid cursor positions.
721 // We indicate the fact that a newline has to be triggered by 663 // We indicate the fact that a newline has to be triggered by
722 // putting the cursor one right to the last column of the screen. 664 // putting the cursor one right to the last column of the screen.
723 665
724 if (cuX >= columns) 666 if (cuX >= columns)
725 { 667 {
726 if (getMode(MODE_Wrap)) NextLine(); else cuX = columns - 1; 668 if (getMode(MODE_Wrap)) NextLine(); else cuX = columns - 1;
727 // comment out for no wrap 669 // comment out for no wrap
728 } 670 }
729 671
730 if (getMode(MODE_Insert)) insertChars(1); 672 if (getMode(MODE_Insert)) insertChars(1);
731 673
732 int i = loc( cuX, cuY); 674 int i = loc( cuX, cuY);
733 675
734 checkSelection(i, i); // check if selection is still valid. 676 checkSelection(i, i); // check if selection is still valid.
735 677
736 image[i].c = c; 678 image[i].c = c;
737 image[i].f = ef_fg; 679 image[i].f = ef_fg;
738 image[i].b = ef_bg; 680 image[i].b = ef_bg;
739 image[i].r = ef_re; 681 image[i].r = ef_re;
740 682
741 cuX += 1; 683 cuX += 1;
742} 684}
743 685
744// Region commands ------------------------------------------------------------- 686// Region commands -------------------------------------------------------------
745 687
746 688
747/*! scroll up `n' lines within current region. 689/*! scroll up `n' lines within current region.
748 The `n' new lines are cleared. 690 The `n' new lines are cleared.
749 \sa setRegion \sa scrollDown 691 \sa setRegion \sa scrollDown
750*/ 692*/
751 693
752void TEScreen::scrollUp(int from, int n) 694void TEScreen::scrollUp(int from, int n)
753{ 695{
754 if (n <= 0 || from + n > bmargin) return; 696 if (n <= 0 || from + n > bmargin) return;
755 //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds. 697 //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
756 698
757 moveImage( loc( 0, from), loc( 0, from + n), loc( columns - 1, bmargin)); 699 moveImage( loc( 0, from), loc( 0, from + n), loc( columns - 1, bmargin));
758 clearImage( loc( 0, bmargin - n + 1), loc( columns - 1, bmargin), ' '); 700 clearImage( loc( 0, bmargin - n + 1), loc( columns - 1, bmargin), ' ');
759} 701}
760 702
761/*! scroll down `n' lines within current region. 703/*! scroll down `n' lines within current region.
762 The `n' new lines are cleared. 704 The `n' new lines are cleared.
763 \sa setRegion \sa scrollUp 705 \sa setRegion \sa scrollUp
764*/ 706*/
765 707
766void TEScreen::scrollDown(int from, int n) 708void TEScreen::scrollDown(int from, int n)
767{ 709{
768 710
769//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds. 711//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
770 if (n <= 0) return; 712 if (n <= 0) return;
771 if (from > bmargin) return; 713 if (from > bmargin) return;
772 if (from + n > bmargin) n = bmargin - from; 714 if (from + n > bmargin) n = bmargin - from;
773 715
774 moveImage( loc(0,from+n), loc(0,from), loc(columns-1,bmargin-n)); 716 moveImage( loc(0,from+n), loc(0,from), loc(columns-1,bmargin-n));
775 clearImage(loc(0,from),loc(columns-1,from+n-1),' '); 717 clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
776} 718}
777 719
778 720
779 721
780/*! position the cursor to a specific line and column. */ 722/*! position the cursor to a specific line and column. */
781void TEScreen::setCursorYX(int y, int x) 723void TEScreen::setCursorYX(int y, int x)
782{ 724{
783 setCursorY(y); setCursorX(x); 725 setCursorY(y); setCursorX(x);
784} 726}
785 727
786/*! Set the cursor to x-th line. */ 728/*! Set the cursor to x-th line. */
787 729
788void TEScreen::setCursorX(int x) 730void TEScreen::setCursorX(int x)
789{ 731{
790 if (x == 0) x = 1; // Default 732 if (x == 0) x = 1; // Default
791 x -= 1; // Adjust 733 x -= 1; // Adjust
792 cuX = QMAX(0,QMIN(columns-1, x)); 734 cuX = QMAX(0,QMIN(columns-1, x));
793} 735}
794 736
795/*! Set the cursor to y-th line. */ 737/*! Set the cursor to y-th line. */
796 738
797void TEScreen::setCursorY(int y) 739void TEScreen::setCursorY(int y)
798{ 740{
799 if (y == 0) y = 1; // Default 741 if (y == 0) y = 1; // Default
800 y -= 1; // Adjust 742 y -= 1; // Adjust
801 cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) )); 743 cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) ));
802} 744}
803 745
804/*! set cursor to the `left upper' corner of the screen (1,1). 746/*! set cursor to the `left upper' corner of the screen (1,1).
805*/ 747*/
806 748
807void TEScreen::home() 749void TEScreen::home()
808{ 750{
809 cuX = 0; 751 cuX = 0;
810 cuY = 0; 752 cuY = 0;
811} 753}
812 754
813/*! set cursor to the begin of the current line. 755/*! set cursor to the begin of the current line.
814*/ 756*/
815 757
816void TEScreen::Return() 758void TEScreen::Return()
817{ 759{
818 cuX = 0; 760 cuX = 0;
819} 761}
820 762
821/*! returns the current cursor columns. 763/*! returns the current cursor columns.
822*/ 764*/
823 765
824int TEScreen::getCursorX() 766int TEScreen::getCursorX()
825{ 767{
826 return cuX; 768 return cuX;
827} 769}
828 770
829/*! returns the current cursor line. 771/*! returns the current cursor line.
830*/ 772*/
831 773
832int TEScreen::getCursorY() 774int TEScreen::getCursorY()
833{ 775{
834 return cuY; 776 return cuY;
835} 777}
836 778
837// Erasing --------------------------------------------------------------------- 779// Erasing ---------------------------------------------------------------------
838 780
839/*! \section Erasing 781/*! \section Erasing
840 782
841 This group of operations erase parts of the screen contents by filling 783 This group of operations erase parts of the screen contents by filling
842 it with spaces colored due to the current rendition settings. 784 it with spaces colored due to the current rendition settings.
843 785
844 Althought the cursor position is involved in most of these operations, 786 Althought the cursor position is involved in most of these operations,
845 it is never modified by them. 787 it is never modified by them.
846*/ 788*/
847 789
848/*! fill screen between (including) `loca' and `loce' with spaces. 790/*! fill screen between (including) `loca' and `loce' with spaces.
849 791
850 This is an internal helper functions. The parameter types are internal 792 This is an internal helper functions. The parameter types are internal
851 addresses of within the screen image and make use of the way how the 793 addresses of within the screen image and make use of the way how the
852 screen matrix is mapped to the image vector. 794 screen matrix is mapped to the image vector.
853*/ 795*/
854 796
855void TEScreen::clearImage(int loca, int loce, char c) 797void TEScreen::clearImage(int loca, int loce, char c)
856{ int i; 798{ int i;
857 int scr_TL=loc(0,hist.getLines()); 799 int scr_TL=loc(0,hist.getLines());
858 //FIXME: check positions 800 //FIXME: check positions
859 801
860 //Clear entire selection if it overlaps region to be moved... 802 //Clear entire selection if it overlaps region to be moved...
861 if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) ) 803 if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) )
862 { 804 {
863 clearSelection(); 805 clearSelection();
864 } 806 }
865 for (i = loca; i <= loce; i++) 807 for (i = loca; i <= loce; i++)
866 { 808 {
867 image[i].c = c; 809 image[i].c = c;
868 image[i].f = ef_fg; //DEFAULT_FORE_COLOR; //FIXME: xterm and linux/ansi 810 image[i].f = ef_fg; //DEFAULT_FORE_COLOR; //FIXME: xterm and linux/ansi
869 image[i].b = ef_bg; //DEFAULT_BACK_COLOR; // many have different 811 image[i].b = ef_bg; //DEFAULT_BACK_COLOR; // many have different
870 image[i].r = ef_re; //DEFAULT_RENDITION; // ideas here. 812 image[i].r = ef_re; //DEFAULT_RENDITION; // ideas here.
871 } 813 }
872} 814}
873 815
874/*! move image between (including) `loca' and `loce' to 'dst'. 816/*! move image between (including) `loca' and `loce' to 'dst'.
875 817
876 This is an internal helper functions. The parameter types are internal 818 This is an internal helper functions. The parameter types are internal
877 addresses of within the screen image and make use of the way how the 819 addresses of within the screen image and make use of the way how the
878 screen matrix is mapped to the image vector. 820 screen matrix is mapped to the image vector.
879*/ 821*/
880 822
881void TEScreen::moveImage(int dst, int loca, int loce) 823void TEScreen::moveImage(int dst, int loca, int loce)
882{ 824{
883//FIXME: check positions 825//FIXME: check positions
884 if (loce < loca) { 826 if (loce < loca) {
885 // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl; 827 // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl;
886 return; 828 return;
887 } 829 }
888 memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca)); 830 memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca));
889} 831}
890 832
891/*! clear from (including) current cursor position to end of screen. 833/*! clear from (including) current cursor position to end of screen.
892*/ 834*/
893 835
894void TEScreen::clearToEndOfScreen() 836void TEScreen::clearToEndOfScreen()
895{ 837{
896 clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' '); 838 clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');
897} 839}
898 840
899/*! clear from begin of screen to (including) current cursor position. 841/*! clear from begin of screen to (including) current cursor position.
900*/ 842*/
901 843
902void TEScreen::clearToBeginOfScreen() 844void TEScreen::clearToBeginOfScreen()
903{ 845{
904 clearImage(loc(0,0),loc(cuX,cuY),' '); 846 clearImage(loc(0,0),loc(cuX,cuY),' ');
905} 847}
906 848
907/*! clear the entire screen. 849/*! clear the entire screen.
908*/ 850*/
909 851
910void TEScreen::clearEntireScreen() 852void TEScreen::clearEntireScreen()
911{ 853{
912 clearImage(loc(0,0),loc(columns-1,lines-1),' '); 854 clearImage(loc(0,0),loc(columns-1,lines-1),' ');
913} 855}
914 856
915/*! fill screen with 'E' 857/*! fill screen with 'E'
916 This is to aid screen alignment 858 This is to aid screen alignment
917*/ 859*/
918 860
919void TEScreen::helpAlign() 861void TEScreen::helpAlign()
920{ 862{
921 clearImage(loc(0,0),loc(columns-1,lines-1),'E'); 863 clearImage(loc(0,0),loc(columns-1,lines-1),'E');
922} 864}
923 865
924/*! clear from (including) current cursor position to end of current cursor line. 866/*! clear from (including) current cursor position to end of current cursor line.
925*/ 867*/
926 868
927void TEScreen::clearToEndOfLine() 869void TEScreen::clearToEndOfLine()
928{ 870{
929 clearImage(loc(cuX,cuY),loc(columns-1,cuY),' '); 871 clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');
930} 872}
931 873
932/*! clear from begin of current cursor line to (including) current cursor position. 874/*! clear from begin of current cursor line to (including) current cursor position.
933*/ 875*/
934 876
935void TEScreen::clearToBeginOfLine() 877void TEScreen::clearToBeginOfLine()
936{ 878{
937 clearImage(loc(0,cuY),loc(cuX,cuY),' '); 879 clearImage(loc(0,cuY),loc(cuX,cuY),' ');
938} 880}
939 881
940/*! clears entire current cursor line 882/*! clears entire current cursor line
941*/ 883*/
942 884
943void TEScreen::clearEntireLine() 885void TEScreen::clearEntireLine()
944{ 886{
945 clearImage( loc( 0, cuY),loc( columns - 1, cuY),' '); 887 clearImage( loc( 0, cuY),loc( columns - 1, cuY),' ');
946} 888}
947 889
948// Rendition ------------------------------------------------------------------ 890// Rendition ------------------------------------------------------------------
949 891
950/*! 892/*!
951 set rendition mode 893 set rendition mode
952*/ 894*/
953 895
954void TEScreen::setRendition(int re) 896void TEScreen::setRendition(int re)
955{ 897{
956 cu_re |= re; 898 cu_re |= re;
957 effectiveRendition(); 899 effectiveRendition();
958} 900}
959 901
960/*! 902/*!
961 reset rendition mode 903 reset rendition mode
962*/ 904*/
963 905
964void TEScreen::resetRendition(int re) 906void TEScreen::resetRendition(int re)
965{ 907{
966 cu_re &= ~re; 908 cu_re &= ~re;
967 effectiveRendition(); 909 effectiveRendition();
968} 910}
969 911
970/*! 912/*!
971*/ 913*/
972 914
973void TEScreen::setDefaultRendition() 915void TEScreen::setDefaultRendition()
974{ 916{
975 setForeColorToDefault(); 917 setForeColorToDefault();
976 setBackColorToDefault(); 918 setBackColorToDefault();
977 cu_re = DEFAULT_RENDITION; 919 cu_re = DEFAULT_RENDITION;
978 effectiveRendition(); 920 effectiveRendition();
979} 921}
980 922
981/*! 923/*!
982*/ 924*/
983 925
984void TEScreen::setForeColor(int fgcolor) 926void TEScreen::setForeColor(int fgcolor)
985{ 927{
986 cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2); 928 cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2);
987 effectiveRendition(); 929 effectiveRendition();
988} 930}
989 931
990/*! 932/*!
991*/ 933*/
992 934
993void TEScreen::setBackColor(int bgcolor) 935void TEScreen::setBackColor(int bgcolor)
994{ 936{
995 cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2); 937 cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2);
996 effectiveRendition(); 938 effectiveRendition();
997} 939}
998 940
999/*! 941/*!
1000*/ 942*/
1001 943
1002void TEScreen::setBackColorToDefault() 944void TEScreen::setBackColorToDefault()
1003{ 945{
1004 cu_bg = DEFAULT_BACK_COLOR; 946 cu_bg = DEFAULT_BACK_COLOR;
1005 effectiveRendition(); 947 effectiveRendition();
1006} 948}
1007 949
1008/*! 950/*!
1009*/ 951*/
1010 952
1011void TEScreen::setForeColorToDefault() 953void TEScreen::setForeColorToDefault()
1012{ 954{
1013 cu_fg = DEFAULT_FORE_COLOR; 955 cu_fg = DEFAULT_FORE_COLOR;
1014 effectiveRendition(); 956 effectiveRendition();
1015} 957}
1016 958
1017/* ------------------------------------------------------------------------- */ 959/* ------------------------------------------------------------------------- */
1018/* */ 960/* */
1019/* Marking & Selection */ 961/* Marking & Selection */
1020/* */ 962/* */
1021/* ------------------------------------------------------------------------- */ 963/* ------------------------------------------------------------------------- */
1022 964
1023void TEScreen::clearSelection() 965void TEScreen::clearSelection()
1024{ 966{
1025 sel_BR = -1; 967 sel_BR = -1;
1026 sel_TL = -1; 968 sel_TL = -1;
1027 sel_begin = -1; 969 sel_begin = -1;
1028} 970}
1029 971
1030void TEScreen::setSelBeginXY(const int x, const int y) 972void TEScreen::setSelBeginXY(const int x, const int y)
1031{ 973{
1032 sel_begin = loc(x,y+histCursor) ; 974 sel_begin = loc(x,y+histCursor) ;
1033 sel_BR = sel_begin; 975 sel_BR = sel_begin;
1034 sel_TL = sel_begin; 976 sel_TL = sel_begin;
1035} 977}
1036 978
1037void TEScreen::setSelExtentXY(const int x, const int y) 979void TEScreen::setSelExtentXY(const int x, const int y)
1038{ 980{
1039 if (sel_begin == -1) return; 981 if (sel_begin == -1) return;
1040 int l = loc(x,y + histCursor); 982 int l = loc(x,y + histCursor);
1041 983
1042 if (l < sel_begin) 984 if (l < sel_begin)
1043 { 985 {
1044 sel_TL = l; 986 sel_TL = l;
1045 sel_BR = sel_begin; 987 sel_BR = sel_begin;
1046 } 988 }
1047 else 989 else
1048 { 990 {
1049 /* FIXME, HACK to correct for x too far to the right... */ 991 /* FIXME, HACK to correct for x too far to the right... */
1050 if (( x == columns )|| (x == 0)) l--; 992 if (( x == columns )|| (x == 0)) l--;
1051 993
1052 sel_TL = sel_begin; 994 sel_TL = sel_begin;
1053 sel_BR = l; 995 sel_BR = l;
1054 } 996 }
1055} 997}
1056 998
1057QString TEScreen::getSelText(const BOOL preserve_line_breaks) 999QString TEScreen::getSelText(const BOOL preserve_line_breaks)
1058{ 1000{
1059 if (sel_begin == -1) 1001 if (sel_begin == -1)
1060 return QString::null; // Selection got clear while selecting. 1002 return QString::null; // Selection got clear while selecting.
1061 1003
1062 int *m; // buffer to fill. 1004 int *m; // buffer to fill.
1063 int s, d; // source index, dest. index. 1005 int s, d; // source index, dest. index.
1064 int hist_BR = loc(0, hist.getLines()); 1006 int hist_BR = loc(0, hist.getLines());
1065 int hY = sel_TL / columns; 1007 int hY = sel_TL / columns;
1066 int hX = sel_TL % columns; 1008 int hX = sel_TL % columns;
1067 int eol; // end of line 1009 int eol; // end of line
1068 1010
1069 s = sel_TL; // tracks copy in source. 1011 s = sel_TL; // tracks copy in source.
1070 1012
1071 // allocate buffer for maximum 1013 // allocate buffer for maximum
1072 // possible size... 1014 // possible size...
1073 d = (sel_BR - sel_TL) / columns + 1; 1015 d = (sel_BR - sel_TL) / columns + 1;
1074 m = new int[d * (columns + 1) + 2]; 1016 m = new int[d * (columns + 1) + 2];
1075 d = 0; 1017 d = 0;
1076 1018
1077 while (s <= sel_BR) 1019 while (s <= sel_BR)
1078 { 1020 {
1079 if (s < hist_BR) 1021 if (s < hist_BR)
1080 { // get lines from hist.history 1022 { // get lines from hist.history
1081 // buffer. 1023 // buffer.
1082 eol = hist.getLineLen(hY); 1024 eol = hist.getLineLen(hY);
1083 1025
1084 if ((hY == (sel_BR / columns)) && 1026 if ((hY == (sel_BR / columns)) &&
1085 (eol >= (sel_BR % columns))) 1027 (eol >= (sel_BR % columns)))
1086 { 1028 {
1087 eol = sel_BR % columns + 1; 1029 eol = sel_BR % columns + 1;
1088 } 1030 }
1089 1031
1090 while (hX < eol) 1032 while (hX < eol)
1091 { 1033 {
1092 m[d++] = hist.getCell(hY, hX++).c; 1034 m[d++] = hist.getCell(hY, hX++).c;
1093 s++; 1035 s++;
1094 } 1036 }
1095 1037
1096 if (s <= sel_BR) 1038 if (s <= sel_BR)
1097 { 1039 {
1098 // The line break handling 1040 // The line break handling
1099 // It's different from the screen 1041 // It's different from the screen
1100 // image case! 1042 // image case!
1101 if (eol % columns == 0) 1043 if (eol % columns == 0)
1102 { 1044 {
1103 // That's either a completely filled 1045 // That's either a completely filled
1104 // line or an empty line 1046 // line or an empty line
1105 if (eol == 0) 1047 if (eol == 0)
1106 { 1048 {
1107 m[d++] = '\n'; 1049 m[d++] = '\n';
1108 } 1050 }
1109 else 1051 else
1110 { 1052 {
1111 // We have a full line. 1053 // We have a full line.
1112 // FIXME: How can we handle newlines 1054 // FIXME: How can we handle newlines
1113 // at this position?! 1055 // at this position?!
1114 } 1056 }
1115 } 1057 }
1116 else if ((eol + 1) % columns == 0) 1058 else if ((eol + 1) % columns == 0)
1117 { 1059 {
1118 // FIXME: We don't know if this was a 1060 // FIXME: We don't know if this was a
1119 // space at the last position or a 1061 // space at the last position or a
1120 // short line!! 1062 // short line!!
1121 m[d++] = ' '; 1063 m[d++] = ' ';
1122 } 1064 }
1123 else 1065 else
1124 { 1066 {
1125 // We have a short line here. Put a 1067 // We have a short line here. Put a
1126 // newline or a space into the 1068 // newline or a space into the
1127 // buffer. 1069 // buffer.
1128 m[d++] = preserve_line_breaks ? '\n' : ' '; 1070 m[d++] = preserve_line_breaks ? '\n' : ' ';
1129 } 1071 }
1130 } 1072 }
1131 1073
1132 hY++; 1074 hY++;
1133 hX = 0; 1075 hX = 0;
1134 s = hY * columns; 1076 s = hY * columns;
1135 } 1077 }
1136 else 1078 else
1137 { // or from screen image. 1079 { // or from screen image.
1138 eol = (s / columns + 1) * columns - 1; 1080 eol = (s / columns + 1) * columns - 1;
1139 1081
1140 if (eol < sel_BR) 1082 if (eol < sel_BR)
1141 { 1083 {
1142 while ((eol > s) && 1084 while ((eol > s) &&
1143 isspace(image[eol - hist_BR].c)) 1085 isspace(image[eol - hist_BR].c))
1144 { 1086 {
1145 eol--; 1087 eol--;
1146 } 1088 }
1147 } 1089 }
1148 else 1090 else
1149 { 1091 {
1150 eol = sel_BR; 1092 eol = sel_BR;
1151 } 1093 }
1152 1094
1153 while (s <= eol) 1095 while (s <= eol)
1154 { 1096 {
1155 m[d++] = image[s++ - hist_BR].c; 1097 m[d++] = image[s++ - hist_BR].c;
1156 } 1098 }
1157 1099
1158 if (eol < sel_BR) 1100 if (eol < sel_BR)
1159 { 1101 {
1160 // eol processing see below ... 1102 // eol processing see below ...
1161 if ((eol + 1) % columns == 0) 1103 if ((eol + 1) % columns == 0)
1162 { 1104 {
1163 if (image[eol - hist_BR].c == ' ') 1105 if (image[eol - hist_BR].c == ' ')
1164 { 1106 {
1165 m[d++] = ' '; 1107 m[d++] = ' ';
1166 } 1108 }
1167 } 1109 }
1168 else 1110 else
1169 { 1111 {
1170 m[d++] = ((preserve_line_breaks || 1112 m[d++] = ((preserve_line_breaks ||
1171 ((eol % columns) == 0)) ? 1113 ((eol % columns) == 0)) ?
1172 '\n' : ' '); 1114 '\n' : ' ');
1173 } 1115 }
1174 } 1116 }
1175 1117
1176 s = (eol / columns + 1) * columns; 1118 s = (eol / columns + 1) * columns;
1177 } 1119 }
1178 } 1120 }
1179 1121
1180 QChar* qc = new QChar[d]; 1122 QChar* qc = new QChar[d];
1181 1123
1182 for (int i = 0; i < d; i++) 1124 for (int i = 0; i < d; i++)
1183 { 1125 {
1184 qc[i] = m[i]; 1126 qc[i] = m[i];
1185 } 1127 }
1186 1128
1187 QString res(qc, d); 1129 QString res(qc, d);
1188 1130
1189 delete m; 1131 delete m;
1190 delete qc; 1132 delete qc;
1191 1133
1192 return res; 1134 return res;
1193} 1135}
1194/* above ... end of line processing for selection -- psilva 1136/* above ... end of line processing for selection -- psilva
1195cases: 1137cases:
1196 1138
11971) (eol+1)%columns == 0 --> the whole line is filled. 11391) (eol+1)%columns == 0 --> the whole line is filled.
1198 If the last char is a space, insert (preserve) space. otherwise 1140 If the last char is a space, insert (preserve) space. otherwise
1199 leave the text alone, so that words that are broken by linewrap 1141 leave the text alone, so that words that are broken by linewrap
1200 are preserved. 1142 are preserved.
1201 1143
1202FIXME: 1144FIXME:
1203 * this suppresses \n for command output that is 1145 * this suppresses \n for command output that is
1204 sized to the exact column width of the screen. 1146 sized to the exact column width of the screen.
1205 1147
12062) eol%columns == 0 --> blank line. 11482) eol%columns == 0 --> blank line.
1207 insert a \n unconditionally. 1149 insert a \n unconditionally.
1208 Do it either you would because you are in preserve_line_break mode, 1150 Do it either you would because you are in preserve_line_break mode,
1209 or because it's an ASCII paragraph delimiter, so even when 1151 or because it's an ASCII paragraph delimiter, so even when
1210 not preserving line_breaks, you want to preserve paragraph breaks. 1152 not preserving line_breaks, you want to preserve paragraph breaks.
1211 1153
12123) else --> partially filled line 11543) else --> partially filled line
1213 insert a \n in preserve line break mode, else a space 1155 insert a \n in preserve line break mode, else a space
1214 The space prevents concatenation of the last word of one 1156 The space prevents concatenation of the last word of one
1215 line with the first of the next. 1157 line with the first of the next.
1216 1158
1217*/ 1159*/
1218 1160
1219void TEScreen::addHistLine() 1161void TEScreen::addHistLine()
1220{ 1162{
1221 assert(hasScroll() || histCursor == 0); 1163 assert(hasScroll() || histCursor == 0);
1222 1164
1223 // add to hist buffer 1165 // add to hist buffer
1224 // we have to take care about scrolling, too... 1166 // we have to take care about scrolling, too...
1225 1167
1226 if (hasScroll()){ 1168 if (hasScroll()){
1227 ca dft; 1169 ca dft;
1228 1170
1229 int end = columns - 1; 1171 int end = columns - 1;
1230 while (end >= 0 && image[end] == dft) 1172 while (end >= 0 && image[end] == dft)
1231 end -= 1; 1173 end -= 1;
1232 1174
1233 hist.addCells( image, end + 1); 1175 hist.addCells( image, end + 1);
1234 hist.addLine(); 1176 hist.addLine();
1235 1177
1236 // adjust history cursor 1178 // adjust history cursor
1237 histCursor += ( hist.getLines() - 1 == histCursor); 1179 histCursor += ( hist.getLines() - 1 == histCursor);
1238 } 1180 }
1239 1181
1240 if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround 1182 if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround
1241} 1183}
1242 1184
1243void TEScreen::setHistCursor(int cursor) 1185void TEScreen::setHistCursor(int cursor)
1244{ 1186{
1245 histCursor = cursor; //FIXME:rangecheck 1187 histCursor = cursor; //FIXME:rangecheck
1246} 1188}
1247 1189
1248void TEScreen::setHorzCursor(int cursor) 1190void TEScreen::setHorzCursor(int cursor)
1249{ 1191{
1250 horzCursor = cursor; 1192 horzCursor = cursor;
1251} 1193}
1252 1194
1253int TEScreen::getHistCursor() 1195int TEScreen::getHistCursor()
1254{ 1196{
1255 return histCursor; 1197 return histCursor;
1256} 1198}
1257 1199
1258int TEScreen::getHorzCursor() 1200int TEScreen::getHorzCursor()
1259{ 1201{
1260 return horzCursor; 1202 return horzCursor;
1261} 1203}
1262 1204
1263int TEScreen::getHistLines() 1205int TEScreen::getHistLines()
1264{ 1206{
1265 return hist.getLines(); 1207 return hist.getLines();
1266} 1208}
1267 1209
1268void TEScreen::setScroll(bool on) 1210void TEScreen::setScroll(bool on)
1269{ 1211{
1270 histCursor = 0; 1212 histCursor = 0;
1271 clearSelection(); 1213 clearSelection();
1272 hist.setScroll(on); 1214 hist.setScroll(on);
1273} 1215}
1274 1216
1275bool TEScreen::hasScroll() 1217bool TEScreen::hasScroll()
1276{ 1218{
1277 return hist.hasScroll(); 1219 return hist.hasScroll();
1278} 1220}
diff --git a/core/apps/embeddedkonsole/TEWidget.cpp b/core/apps/embeddedkonsole/TEWidget.cpp
index 60021f4..d6ee6e8 100644
--- a/core/apps/embeddedkonsole/TEWidget.cpp
+++ b/core/apps/embeddedkonsole/TEWidget.cpp
@@ -1,1406 +1,1347 @@
1/* ------------------------------------------------------------------------ */ 1/* ------------------------------------------------------------------------ */
2/* */ 2/* */
3/* [TEWidget.C] Terminal Emulation Widget */ 3/* [TEWidget.C] Terminal Emulation Widget */
4/* */ 4/* */
5/* ------------------------------------------------------------------------ */ 5/* ------------------------------------------------------------------------ */
6/* */ 6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ 7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */ 8/* */
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* */ 10/* */
11/* ------------------------------------------------------------------------ */ 11/* ------------------------------------------------------------------------ */
12/* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14/* */ 14/* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16/* */ 16/* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18/*! \class TEWidget 18/*! \class TEWidget
19 19
20 \brief Visible screen contents 20 \brief Visible screen contents
21 21
22 This class is responsible to map the `image' of a terminal emulation to the 22 This class is responsible to map the `image' of a terminal emulation to the
23 display. All the dependency of the emulation to a specific GUI or toolkit is 23 display. All the dependency of the emulation to a specific GUI or toolkit is
24 localized here. Further, this widget has no knowledge about being part of an 24 localized here. Further, this widget has no knowledge about being part of an
25 emulation, it simply work within the terminal emulation framework by exposing 25 emulation, it simply work within the terminal emulation framework by exposing
26 size and key events and by being ordered to show a new image. 26 size and key events and by being ordered to show a new image.
27 27
28 <ul> 28 <ul>
29 <li> The internal image has the size of the widget (evtl. rounded up) 29 <li> The internal image has the size of the widget (evtl. rounded up)
30 <li> The external image used in setImage can have any size. 30 <li> The external image used in setImage can have any size.
31 <li> (internally) the external image is simply copied to the internal 31 <li> (internally) the external image is simply copied to the internal
32 when a setImage happens. During a resizeEvent no painting is done 32 when a setImage happens. During a resizeEvent no painting is done
33 a paintEvent is expected to follow anyway. 33 a paintEvent is expected to follow anyway.
34 </ul> 34 </ul>
35 35
36 \sa TEScreen \sa Emulation 36 \sa TEScreen \sa Emulation
37*/ 37*/
38 38
39/* FIXME: 39/* FIXME:
40 - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent 40 - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent
41 - 'font_a' not used in mouse events 41 - 'font_a' not used in mouse events
42 - add destructor 42 - add destructor
43*/ 43*/
44 44
45/* TODO 45/* TODO
46 - evtl. be sensitive to `paletteChange' while using default colors. 46 - evtl. be sensitive to `paletteChange' while using default colors.
47 - set different 'rounding' styles? I.e. have a mode to show clipped chars? 47 - set different 'rounding' styles? I.e. have a mode to show clipped chars?
48*/ 48*/
49 49
50// #include "config.h" 50// #include "config.h"
51#include "TEWidget.h" 51#include "TEWidget.h"
52#include "session.h" 52#include "session.h"
53#include <qpe/config.h> 53#include <qpe/config.h>
54 54
55#include <qpe/resource.h> 55#include <qpe/resource.h>
56#include <qpe/sound.h> 56#include <qpe/sound.h>
57 57
58#ifdef QWS 58#ifdef QWS
59#include <qpe/qcopenvelope_qws.h> 59#include <qpe/qcopenvelope_qws.h>
60#endif 60#endif
61 61
62#include <qcursor.h> 62#include <qcursor.h>
63#include <qregexp.h> 63#include <qregexp.h>
64#include <qpainter.h> 64#include <qpainter.h>
65#include <qclipboard.h> 65#include <qclipboard.h>
66#include <qstyle.h> 66#include <qstyle.h>
67#include <qfile.h> 67#include <qfile.h>
68#include <qdragobject.h> 68#include <qdragobject.h>
69 69
70#include <stdio.h> 70#include <stdio.h>
71#include <stdlib.h> 71#include <stdlib.h>
72#include <unistd.h> 72#include <unistd.h>
73#include <ctype.h> 73#include <ctype.h>
74#include <sys/stat.h> 74#include <sys/stat.h>
75#include <sys/types.h> 75#include <sys/types.h>
76#include <signal.h> 76#include <signal.h>
77 77
78#include <assert.h> 78#include <assert.h>
79 79
80// #include "TEWidget.moc" 80// #include "TEWidget.moc"
81//#include <kapp.h> 81//#include <kapp.h>
82//#include <kcursor.h> 82//#include <kcursor.h>
83//#include <kurl.h> 83//#include <kurl.h>
84//#include <kdebug.h> 84//#include <kdebug.h>
85//#include <klocale.h> 85//#include <klocale.h>
86 86
87#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__) 87#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__)
88#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); } 88#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); }
89 89
90#define loc(X,Y) ((Y)*columns+(X)) 90#define loc(X,Y) ((Y)*columns+(X))
91 91
92//FIXME: the rim should normally be 1, 0 only when running in full screen mode. 92//FIXME: the rim should normally be 1, 0 only when running in full screen mode.
93#define rimX 0 // left/right rim width 93#define rimX 0 // left/right rim width
94#define rimY 0 // top/bottom rim high 94#define rimY 0 // top/bottom rim high
95 95
96#define SCRWIDTH 16 // width of the scrollbar 96#define SCRWIDTH 16 // width of the scrollbar
97 97
98#define yMouseScroll 1 98#define yMouseScroll 1
99// scroll increment used when dragging selection at top/bottom of window. 99// scroll increment used when dragging selection at top/bottom of window.
100 100
101/* ------------------------------------------------------------------------- */ 101/* ------------------------------------------------------------------------- */
102/* */ 102/* */
103/* Colors */ 103/* Colors */
104/* */ 104/* */
105/* ------------------------------------------------------------------------- */ 105/* ------------------------------------------------------------------------- */
106 106
107//FIXME: the default color table is in session.C now. 107//FIXME: the default color table is in session.C now.
108// We need a way to get rid of this one, here. 108// We need a way to get rid of this one, here.
109static const ColorEntry base_color_table[TABLE_COLORS] = 109static const ColorEntry base_color_table[TABLE_COLORS] =
110// The following are almost IBM standard color codes, with some slight 110// The following are almost IBM standard color codes, with some slight
111// gamma correction for the dim colors to compensate for bright X screens. 111// gamma correction for the dim colors to compensate for bright X screens.
112// It contains the 8 ansiterm/xterm colors in 2 intensities. 112// It contains the 8 ansiterm/xterm colors in 2 intensities.
113{ 113{
114 // Fixme: could add faint colors here, also. 114 // Fixme: could add faint colors here, also.
115 // normal 115 // normal
116 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback 116 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback
117 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red 117 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red
118 ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow 118 ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow
119 ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta 119 ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta
120 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White 120 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White
121 // intensiv 121 // intensiv
122 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ), 122 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
123 ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ), 123 ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
124 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ), 124 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
125 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), 125 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ),
126 ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 ) 126 ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
127}; 127};
128 128
129/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb) 129/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb)
130 130
131 Code 0 1 2 3 4 5 6 7 131 Code 0 1 2 3 4 5 6 7
132 ----------- ------- ------- ------- ------- ------- ------- ------- ------- 132 ----------- ------- ------- ------- ------- ------- ------- ------- -------
133 ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White 133 ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White
134 IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White 134 IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White
135*/ 135*/
136 136
137QColor TEWidget::getDefaultBackColor() 137QColor TEWidget::getDefaultBackColor()
138{ 138{
139 return color_table[DEFAULT_BACK_COLOR].color; 139 return color_table[DEFAULT_BACK_COLOR].color;
140} 140}
141 141
142const ColorEntry* TEWidget::getColorTable() const 142const ColorEntry* TEWidget::getColorTable() const
143{ 143{
144 return color_table; 144 return color_table;
145} 145}
146 146
147const ColorEntry* TEWidget::getdefaultColorTable() const 147const ColorEntry* TEWidget::getdefaultColorTable() const
148{ 148{
149 return base_color_table; 149 return base_color_table;
150} 150}
151 151
152 152
153const QPixmap *TEWidget::backgroundPixmap() 153const QPixmap *TEWidget::backgroundPixmap()
154{ 154{
155 static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm"); 155 static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm");
156 const QPixmap *pm = bg; 156 const QPixmap *pm = bg;
157 return pm; 157 return pm;
158} 158}
159 159
160void TEWidget::setColorTable(const ColorEntry table[]) 160void TEWidget::setColorTable(const ColorEntry table[])
161{ 161{
162 for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i]; 162 for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i];
163 163
164 const QPixmap* pm = backgroundPixmap(); 164 const QPixmap* pm = backgroundPixmap();
165 if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color); 165 if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color);
166 update(); 166 update();
167} 167}
168 168
169//FIXME: add backgroundPixmapChanged. 169//FIXME: add backgroundPixmapChanged.
170 170
171/* ------------------------------------------------------------------------- */ 171/* ------------------------------------------------------------------------- */
172/* */ 172/* */
173/* Font */ 173/* Font */
174/* */ 174/* */
175/* ------------------------------------------------------------------------- */ 175/* ------------------------------------------------------------------------- */
176 176
177/* 177/*
178 The VT100 has 32 special graphical characters. The usual vt100 extended 178 The VT100 has 32 special graphical characters. The usual vt100 extended
179 xterm fonts have these at 0x00..0x1f. 179 xterm fonts have these at 0x00..0x1f.
180 180
181 QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals 181 QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals
182 come in here as proper unicode characters. 182 come in here as proper unicode characters.
183 183
184 We treat non-iso10646 fonts as VT100 extended and do the requiered mapping 184 We treat non-iso10646 fonts as VT100 extended and do the requiered mapping
185 from unicode to 0x00..0x1f. The remaining translation is then left to the 185 from unicode to 0x00..0x1f. The remaining translation is then left to the
186 QCodec. 186 QCodec.
187*/ 187*/
188 188
189// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i. 189// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i.
190 190
191unsigned short vt100_graphics[32] = 191unsigned short vt100_graphics[32] =
192{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15 192{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15
193 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 193 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0,
194 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 194 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
195 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534, 195 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534,
196 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7 196 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7
197}; 197};
198 198
199static QChar vt100extended(QChar c) 199static QChar vt100extended(QChar c)
200{ 200{
201 switch (c.unicode()) 201 switch (c.unicode())
202 { 202 {
203 case 0x25c6 : return 1; 203 case 0x25c6 : return 1;
204 case 0x2592 : return 2; 204 case 0x2592 : return 2;
205 case 0x2409 : return 3; 205 case 0x2409 : return 3;
206 case 0x240c : return 4; 206 case 0x240c : return 4;
207 case 0x240d : return 5; 207 case 0x240d : return 5;
208 case 0x240a : return 6; 208 case 0x240a : return 6;
209 case 0x00b0 : return 7; 209 case 0x00b0 : return 7;
210 case 0x00b1 : return 8; 210 case 0x00b1 : return 8;
211 case 0x2424 : return 9; 211 case 0x2424 : return 9;
212 case 0x240b : return 10; 212 case 0x240b : return 10;
213 case 0x2518 : return 11; 213 case 0x2518 : return 11;
214 case 0x2510 : return 12; 214 case 0x2510 : return 12;
215 case 0x250c : return 13; 215 case 0x250c : return 13;
216 case 0x2514 : return 14; 216 case 0x2514 : return 14;
217 case 0x253c : return 15; 217 case 0x253c : return 15;
218 case 0xf800 : return 16; 218 case 0xf800 : return 16;
219 case 0xf801 : return 17; 219 case 0xf801 : return 17;
220 case 0x2500 : return 18; 220 case 0x2500 : return 18;
221 case 0xf803 : return 19; 221 case 0xf803 : return 19;
222 case 0xf804 : return 20; 222 case 0xf804 : return 20;
223 case 0x251c : return 21; 223 case 0x251c : return 21;
224 case 0x2524 : return 22; 224 case 0x2524 : return 22;
225 case 0x2534 : return 23; 225 case 0x2534 : return 23;
226 case 0x252c : return 24; 226 case 0x252c : return 24;
227 case 0x2502 : return 25; 227 case 0x2502 : return 25;
228 case 0x2264 : return 26; 228 case 0x2264 : return 26;
229 case 0x2265 : return 27; 229 case 0x2265 : return 27;
230 case 0x03c0 : return 28; 230 case 0x03c0 : return 28;
231 case 0x2260 : return 29; 231 case 0x2260 : return 29;
232 case 0x00a3 : return 30; 232 case 0x00a3 : return 30;
233 case 0x00b7 : return 31; 233 case 0x00b7 : return 31;
234 } 234 }
235 return c; 235 return c;
236} 236}
237 237
238static QChar identicalMap(QChar c) 238static QChar identicalMap(QChar c)
239{ 239{
240 return c; 240 return c;
241} 241}
242 242
243void TEWidget::fontChange(const QFont &) 243void TEWidget::fontChange(const QFont &)
244{ 244{
245 QFontMetrics fm(font()); 245 QFontMetrics fm(font());
246 font_h = fm.height(); 246 font_h = fm.height();
247 font_w = fm.maxWidth(); 247 font_w = fm.maxWidth();
248 font_a = fm.ascent(); 248 font_a = fm.ascent();
249//printf("font_h: %d\n",font_h); 249//printf("font_h: %d\n",font_h);
250//printf("font_w: %d\n",font_w); 250//printf("font_w: %d\n",font_w);
251//printf("font_a: %d\n",font_a); 251//printf("font_a: %d\n",font_a);
252//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii()); 252//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii());
253//printf("rawname: %s\n",font().rawName().ascii()); 253//printf("rawname: %s\n",font().rawName().ascii());
254 fontMap = 254 fontMap =
255#if QT_VERSION < 300 255#if QT_VERSION < 300
256 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646") 256 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646")
257 ? vt100extended 257 ? vt100extended
258 : 258 :
259#endif 259#endif
260 identicalMap; 260 identicalMap;
261 propagateSize(); 261 propagateSize();
262 update(); 262 update();
263} 263}
264 264
265void TEWidget::setVTFont(const QFont& f) 265void TEWidget::setVTFont(const QFont& f)
266{ 266{
267 QFrame::setFont(f); 267 QFrame::setFont(f);
268} 268}
269 269
270QFont TEWidget::getVTFont() { 270QFont TEWidget::getVTFont() {
271 return font(); 271 return font();
272} 272}
273 273
274void TEWidget::setFont(const QFont &) 274void TEWidget::setFont(const QFont &)
275{ 275{
276 // ignore font change request if not coming from konsole itself 276 // ignore font change request if not coming from konsole itself
277} 277}
278 278
279/* ------------------------------------------------------------------------- */ 279/* ------------------------------------------------------------------------- */
280/* */ 280/* */
281/* Constructor / Destructor */ 281/* Constructor / Destructor */
282/* */ 282/* */
283/* ------------------------------------------------------------------------- */ 283/* ------------------------------------------------------------------------- */
284 284
285TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name) 285TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name)
286{ 286{
287#ifndef QT_NO_CLIPBOARD 287#ifndef QT_NO_CLIPBOARD
288 cb = QApplication::clipboard(); 288 cb = QApplication::clipboard();
289 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), 289 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
290 this, SLOT(onClearSelection()) ); 290 this, SLOT(onClearSelection()) );
291#endif 291#endif
292 292
293 scrollbar = new QScrollBar(this); 293 scrollbar = new QScrollBar(this);
294 scrollbar->setCursor( arrowCursor ); 294 scrollbar->setCursor( arrowCursor );
295 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 295 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
296 296
297 hScrollbar = new QScrollBar(this); 297 hScrollbar = new QScrollBar(this);
298 hScrollbar->setCursor( arrowCursor ); 298 hScrollbar->setCursor( arrowCursor );
299 hScrollbar->setOrientation(QScrollBar::Horizontal); 299 hScrollbar->setOrientation(QScrollBar::Horizontal);
300 hScrollbar->setMaximumHeight(16); 300 hScrollbar->setMaximumHeight(16);
301 301
302 connect( hScrollbar, SIGNAL(valueChanged(int)), this, SLOT( hScrollChanged(int))); 302 connect( hScrollbar, SIGNAL(valueChanged(int)), this, SLOT( hScrollChanged(int)));
303 303
304 Config cfg("Konsole"); 304 Config cfg("Konsole");
305 cfg.setGroup("ScrollBar"); 305 cfg.setGroup("ScrollBar");
306 switch( cfg.readNumEntry("Position",2)){ 306 switch( cfg.readNumEntry("Position",2)){
307 case 0: 307 case 0:
308 scrollLoc = SCRNONE; 308 scrollLoc = SCRNONE;
309 break; 309 break;
310 case 1: 310 case 1:
311 scrollLoc = SCRLEFT; 311 scrollLoc = SCRLEFT;
312 break; 312 break;
313 case 2: 313 case 2:
314 scrollLoc = SCRRIGHT; 314 scrollLoc = SCRRIGHT;
315 break; 315 break;
316 }; 316 };
317 317
318 useHorzScroll=cfg.readBoolEntry("HorzScroll",0); 318 useHorzScroll=cfg.readBoolEntry("HorzScroll",0);
319 319
320 blinkT = new QTimer(this); 320 blinkT = new QTimer(this);
321 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent())); 321 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent()));
322 // blinking = FALSE; 322 // blinking = FALSE;
323 blinking = TRUE; 323 blinking = TRUE;
324 324
325 resizing = FALSE; 325 resizing = FALSE;
326 actSel = 0; 326 actSel = 0;
327 image = 0; 327 image = 0;
328 lines = 1; 328 lines = 1;
329 columns = 1; 329 columns = 1;
330 font_w = 1; 330 font_w = 1;
331 font_h = 1; 331 font_h = 1;
332 font_a = 1; 332 font_a = 1;
333 word_selection_mode = FALSE; 333 word_selection_mode = FALSE;
334 hposition = 0; 334 hposition = 0;
335vcolumns = 0; 335vcolumns = 0;
336 336
337 setMouseMarks(TRUE); 337 setMouseMarks(TRUE);
338 setVTFont( QFont("fixed") ); 338 setVTFont( QFont("fixed") );
339 setColorTable(base_color_table); // init color table 339 setColorTable(base_color_table); // init color table
340 340
341 qApp->installEventFilter( this ); //FIXME: see below 341 qApp->installEventFilter( this ); //FIXME: see below
342// KCursor::setAutoHideCursor( this, true ); 342// KCursor::setAutoHideCursor( this, true );
343 343
344 // Init DnD //////////////////////////////////////////////////////////////// 344 // Init DnD ////////////////////////////////////////////////////////////////
345 currentSession = NULL; 345 currentSession = NULL;
346// setAcceptDrops(true); // attempt 346// setAcceptDrops(true); // attempt
347// m_drop = new QPopupMenu(this); 347// m_drop = new QPopupMenu(this);
348// m_drop->insertItem( QString("Paste"), 0); 348// m_drop->insertItem( QString("Paste"), 0);
349// m_drop->insertItem( QString("cd"), 1); 349// m_drop->insertItem( QString("cd"), 1);
350// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int))); 350// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int)));
351 351
352 // we need focus so that the auto-hide cursor feature works 352 // we need focus so that the auto-hide cursor feature works
353 setFocus(); 353 setFocus();
354 setFocusPolicy( WheelFocus ); 354 setFocusPolicy( WheelFocus );
355} 355}
356 356
357//FIXME: make proper destructor 357//FIXME: make proper destructor
358// Here's a start (David) 358// Here's a start (David)
359TEWidget::~TEWidget() 359TEWidget::~TEWidget()
360{ 360{
361 qApp->removeEventFilter( this ); 361 qApp->removeEventFilter( this );
362 if (image) free(image); 362 if (image) free(image);
363} 363}
364 364
365/* ------------------------------------------------------------------------- */ 365/* ------------------------------------------------------------------------- */
366/* */ 366/* */
367/* Display Operations */ 367/* Display Operations */
368/* */ 368/* */
369/* ------------------------------------------------------------------------- */ 369/* ------------------------------------------------------------------------- */
370 370
371/*! 371/*!
372 attributed string draw primitive 372 attributed string draw primitive
373*/ 373*/
374 374
375void TEWidget::drawAttrStr(QPainter &paint, QRect rect, 375void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
376 QString& str, ca attr, BOOL pm, BOOL clear) 376 QString& str, ca attr, BOOL pm, BOOL clear)
377{ 377{
378 if (pm && color_table[attr.b].transparent) 378 if (pm && color_table[attr.b].transparent)
379 { 379 {
380 paint.setBackgroundMode( TransparentMode ); 380 paint.setBackgroundMode( TransparentMode );
381 if (clear) erase(rect); 381 if (clear) erase(rect);
382 } 382 }
383 else 383 else
384 { 384 {
385 if (blinking) 385 if (blinking)
386 paint.fillRect(rect, color_table[attr.b].color); 386 paint.fillRect(rect, color_table[attr.b].color);
387 else 387 else
388 { 388 {
389 paint.setBackgroundMode( OpaqueMode ); 389 paint.setBackgroundMode( OpaqueMode );
390 paint.setBackgroundColor( color_table[attr.b].color ); 390 paint.setBackgroundColor( color_table[attr.b].color );
391 } 391 }
392 } 392 }
393 393
394 if (color_table[attr.f].bold) 394 if (color_table[attr.f].bold)
395 paint.setPen(QColor( 0x8F, 0x00, 0x00 )); 395 paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
396 else 396 else
397 paint.setPen(color_table[attr.f].color); 397 paint.setPen(color_table[attr.f].color);
398 398
399 paint.drawText(rect.x(),rect.y()+font_a, str); 399 paint.drawText(rect.x(),rect.y()+font_a, str);
400 400
401 if (attr.r & RE_UNDERLINE) 401 if (attr.r & RE_UNDERLINE)
402 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 ); 402 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
403} 403}
404 404
405/*! 405/*!
406 The image can only be set completely. 406 The image can only be set completely.
407 407
408 The size of the new image may or may not match the size of the widget. 408 The size of the new image may or may not match the size of the widget.
409*/ 409*/
410 410
411void TEWidget::setImage(const ca* const newimg, int lines, int columns) 411void TEWidget::setImage(const ca* const newimg, int lines, int columns)
412{ int y,x,len; 412{ int y,x,len;
413 const QPixmap* pm = backgroundPixmap(); 413 const QPixmap* pm = backgroundPixmap();
414 QPainter paint; 414 QPainter paint;
415 setUpdatesEnabled(FALSE); 415 setUpdatesEnabled(FALSE);
416 paint.begin( this ); 416 paint.begin( this );
417HCNT("setImage"); 417HCNT("setImage");
418 418
419 QPoint tL = contentsRect().topLeft(); 419 QPoint tL = contentsRect().topLeft();
420 int tLx = tL.x(); 420 int tLx = tL.x();
421 int tLy = tL.y(); 421 int tLy = tL.y();
422 hasBlinker = FALSE; 422 hasBlinker = FALSE;
423 423
424 int cf = -1; // undefined 424 int cf = -1; // undefined
425 int cb = -1; // undefined 425 int cb = -1; // undefined
426 int cr = -1; // undefined 426 int cr = -1; // undefined
427 427
428 int lins = QMIN(this->lines, QMAX(0,lines )); 428 int lins = QMIN(this->lines, QMAX(0,lines ));
429 int cols = QMIN(this->columns,QMAX(0,columns)); 429 int cols = QMIN(this->columns,QMAX(0,columns));
430 QChar *disstrU = new QChar[cols]; 430 QChar *disstrU = new QChar[cols];
431 for (y = 0; y < lins; y++) { 431 for (y = 0; y < lins; y++) {
432 const ca* lcl = &image[y*this->columns]; 432 const ca* lcl = &image[y*this->columns];
433 const ca* const ext = &newimg[y*columns]; 433 const ca* const ext = &newimg[y*columns];
434 if (!resizing) // not while resizing, we're expecting a paintEvent 434 if (!resizing) // not while resizing, we're expecting a paintEvent
435 for (x = 0; x < cols; x++) 435 for (x = 0; x < cols; x++)
436 { 436 {
437 hasBlinker |= (ext[x].r & RE_BLINK); 437 hasBlinker |= (ext[x].r & RE_BLINK);
438 if (ext[x] != lcl[x]) 438 if (ext[x] != lcl[x])
439 { 439 {
440 cr = ext[x].r; 440 cr = ext[x].r;
441 cb = ext[x].b; 441 cb = ext[x].b;
442 if (ext[x].f != cf) cf = ext[x].f; 442 if (ext[x].f != cf) cf = ext[x].f;
443 int lln = cols - x; 443 int lln = cols - x;
444 disstrU[0] = fontMap(ext[x+0].c); 444 disstrU[0] = fontMap(ext[x+0].c);
445 for (len = 1; len < lln; len++) 445 for (len = 1; len < lln; len++)
446 { 446 {
447 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || 447 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
448 ext[x+len] == lcl[x+len] ) 448 ext[x+len] == lcl[x+len] )
449 break; 449 break;
450 disstrU[len] = fontMap(ext[x+len].c); 450 disstrU[len] = fontMap(ext[x+len].c);
451 } 451 }
452 QString unistr(disstrU,len); 452 QString unistr(disstrU,len);
453 drawAttrStr(paint, 453 drawAttrStr(paint,
454 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 454 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
455 unistr, ext[x], pm != NULL, true); 455 unistr, ext[x], pm != NULL, true);
456 x += len - 1; 456 x += len - 1;
457 } 457 }
458 } 458 }
459 // finally, make `image' become `newimg'. 459 // finally, make `image' become `newimg'.
460 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca)); 460 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
461 } 461 }
462 drawFrame( &paint ); 462 drawFrame( &paint );
463 paint.end(); 463 paint.end();
464 setUpdatesEnabled(TRUE); 464 setUpdatesEnabled(TRUE);
465 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms 465 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms
466 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; } 466 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
467 delete [] disstrU; 467 delete [] disstrU;
468} 468}
469 469
470// paint Event //////////////////////////////////////////////////// 470// paint Event ////////////////////////////////////////////////////
471 471
472/*! 472/*!
473 The difference of this routine vs. the `setImage' is, 473 The difference of this routine vs. the `setImage' is,
474 that the drawing does not include a difference analysis 474 that the drawing does not include a difference analysis
475 between the old and the new image. Instead, the internal 475 between the old and the new image. Instead, the internal
476 image is used and the painting bound by the PaintEvent box. 476 image is used and the painting bound by the PaintEvent box.
477*/ 477*/
478 478
479void TEWidget::paintEvent( QPaintEvent* pe ) 479void TEWidget::paintEvent( QPaintEvent* pe )
480{ 480{
481 481
482//{ static int cnt = 0; printf("paint %d\n",cnt++); } 482//{ static int cnt = 0; printf("paint %d\n",cnt++); }
483 const QPixmap* pm = backgroundPixmap(); 483 const QPixmap* pm = backgroundPixmap();
484 QPainter paint; 484 QPainter paint;
485 setUpdatesEnabled(FALSE); 485 setUpdatesEnabled(FALSE);
486 paint.begin( this ); 486 paint.begin( this );
487 paint.setBackgroundMode( TransparentMode ); 487 paint.setBackgroundMode( TransparentMode );
488HCNT("paintEvent"); 488HCNT("paintEvent");
489 489
490 // Note that the actual widget size can be slightly larger 490 // Note that the actual widget size can be slightly larger
491 // that the image (the size is truncated towards the smaller 491 // that the image (the size is truncated towards the smaller
492 // number of characters in `resizeEvent'. The paint rectangle 492 // number of characters in `resizeEvent'. The paint rectangle
493 // can thus be larger than the image, but less then the size 493 // can thus be larger than the image, but less then the size
494 // of one character. 494 // of one character.
495 495
496 QRect rect = pe->rect().intersect(contentsRect()); 496 QRect rect = pe->rect().intersect(contentsRect());
497 497
498 QPoint tL = contentsRect().topLeft(); 498 QPoint tL = contentsRect().topLeft();
499 int tLx = tL.x(); 499 int tLx = tL.x();
500 int tLy = tL.y(); 500 int tLy = tL.y();
501 501
502 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w)); 502 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w));
503 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h)); 503 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h));
504 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w)); 504 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w));
505 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h)); 505 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h));
506 506
507 /* 507 /*
508 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly, 508 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly,
509 rect.left(), rect.right(), rect.top(), rect.bottom()); 509 rect.left(), rect.right(), rect.top(), rect.bottom());
510 */ 510 */
511 511
512 // if (pm != NULL && color_table[image->b].transparent) 512 // if (pm != NULL && color_table[image->b].transparent)
513 // erase(rect); 513 // erase(rect);
514 // BL: I have no idea why we need this, and it breaks the refresh. 514 // BL: I have no idea why we need this, and it breaks the refresh.
515 515
516 QChar *disstrU = new QChar[columns]; 516 QChar *disstrU = new QChar[columns];
517 for (int y = luy; y <= rly; y++) 517 for (int y = luy; y <= rly; y++)
518 for (int x = lux; x <= rlx; x++) 518 for (int x = lux; x <= rlx; x++)
519 { 519 {
520 int len = 1; 520 int len = 1;
521 disstrU[0] = fontMap(image[loc(x,y)].c); 521 disstrU[0] = fontMap(image[loc(x,y)].c);
522 int cf = image[loc(x,y)].f; 522 int cf = image[loc(x,y)].f;
523 int cb = image[loc(x,y)].b; 523 int cb = image[loc(x,y)].b;
524 int cr = image[loc(x,y)].r; 524 int cr = image[loc(x,y)].r;
525 while (x+len <= rlx && 525 while (x+len <= rlx &&
526 image[loc(x+len,y)].f == cf && 526 image[loc(x+len,y)].f == cf &&
527 image[loc(x+len,y)].b == cb && 527 image[loc(x+len,y)].b == cb &&
528 image[loc(x+len,y)].r == cr ) 528 image[loc(x+len,y)].r == cr )
529 { 529 {
530 disstrU[len] = fontMap(image[loc(x+len,y)].c); 530 disstrU[len] = fontMap(image[loc(x+len,y)].c);
531 len += 1; 531 len += 1;
532 } 532 }
533 QString unistr(disstrU,len); 533 QString unistr(disstrU,len);
534 drawAttrStr(paint, 534 drawAttrStr(paint,
535 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 535 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
536 unistr, image[loc(x,y)], pm != NULL, false); 536 unistr, image[loc(x,y)], pm != NULL, false);
537 x += len - 1; 537 x += len - 1;
538 } 538 }
539 delete [] disstrU; 539 delete [] disstrU;
540 drawFrame( &paint ); 540 drawFrame( &paint );
541 paint.end(); 541 paint.end();
542 setUpdatesEnabled(TRUE); 542 setUpdatesEnabled(TRUE);
543} 543}
544 544
545void TEWidget::blinkEvent() 545void TEWidget::blinkEvent()
546{ 546{
547 blinking = !blinking; 547 blinking = !blinking;
548 repaint(FALSE); 548 repaint(FALSE);
549} 549}
550 550
551/* ------------------------------------------------------------------------- */ 551/* ------------------------------------------------------------------------- */
552/* */ 552/* */
553/* Resizing */ 553/* Resizing */
554/* */ 554/* */
555/* ------------------------------------------------------------------------- */ 555/* ------------------------------------------------------------------------- */
556 556
557void TEWidget::resizeEvent(QResizeEvent* ev) 557void TEWidget::resizeEvent(QResizeEvent* ev)
558{ 558{
559// printf("resize: %d,%d\n",ev->size().width(),ev->size().height()); 559// printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
560 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h); 560 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
561 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h); 561 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
562 //printf("curren: %d,%d\n",width(),height()); 562 //printf("curren: %d,%d\n",width(),height());
563HCNT("resizeEvent"); 563HCNT("resizeEvent");
564 564
565 // see comment in `paintEvent' concerning the rounding. 565 // see comment in `paintEvent' concerning the rounding.
566 //FIXME: could make a routine here; check width(),height() 566 //FIXME: could make a routine here; check width(),height()
567 assert(ev->size().width() == width()); 567 assert(ev->size().width() == width());
568 assert(ev->size().height() == height()); 568 assert(ev->size().height() == height());
569 569
570 propagateSize(); 570 propagateSize();
571} 571}
572 572
573void TEWidget::propagateSize() 573void TEWidget::propagateSize()
574{ 574{
575 ca* oldimg = image; 575 ca* oldimg = image;
576 int oldlin = lines; 576 int oldlin = lines;
577 int oldcol = columns; 577 int oldcol = columns;
578 makeImage(); 578 makeImage();
579 // we copy the old image to reduce flicker 579 // we copy the old image to reduce flicker
580 int lins = QMIN(oldlin,lines); 580 int lins = QMIN(oldlin,lines);
581 int cols = QMIN(oldcol,columns); 581 int cols = QMIN(oldcol,columns);
582 if (oldimg) 582 if (oldimg)
583 { 583 {
584 for (int lin = 0; lin < lins; lin++) 584 for (int lin = 0; lin < lins; lin++)
585 memcpy((void*)&image[columns*lin], 585 memcpy((void*)&image[columns*lin],
586 (void*)&oldimg[oldcol*lin],cols*sizeof(ca)); 586 (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
587 free(oldimg); //FIXME: try new,delete 587 free(oldimg); //FIXME: try new,delete
588 } 588 }
589 else 589 else
590 clearImage(); 590 clearImage();
591 591
592 //NOTE: control flows from the back through the chest right into the eye. 592 //NOTE: control flows from the back through the chest right into the eye.
593 // `emu' will call back via `setImage'. 593 // `emu' will call back via `setImage'.
594 594
595 resizing = TRUE; 595 resizing = TRUE;
596 emit changedImageSizeSignal(lines, columns); // expose resizeEvent 596 emit changedImageSizeSignal(lines, columns); // expose resizeEvent
597 resizing = FALSE; 597 resizing = FALSE;
598} 598}
599 599
600/* ------------------------------------------------------------------------- */ 600/* ------------------------------------------------------------------------- */
601/* */ 601/* */
602/* Scrollbar */ 602/* Scrollbar */
603/* */ 603/* */
604/* ------------------------------------------------------------------------- */ 604/* ------------------------------------------------------------------------- */
605 605
606void TEWidget::scrollChanged(int) { 606void TEWidget::scrollChanged(int) {
607 emit changedHistoryCursor(scrollbar->value()); //expose 607 emit changedHistoryCursor(scrollbar->value()); //expose
608} 608}
609 609
610void TEWidget::hScrollChanged(int loc) { 610void TEWidget::hScrollChanged(int loc) {
611 hposition = loc; 611 hposition = loc;
612 propagateSize(); 612 propagateSize();
613 update(); 613 update();
614 614
615// emit changedHorzCursor( hScrollbar->value()); //expose 615// emit changedHorzCursor( hScrollbar->value()); //expose
616} 616}
617 617
618void TEWidget::setScroll(int cursor, int slines) 618void TEWidget::setScroll(int cursor, int slines)
619{ 619{
620 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 620 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
621 scrollbar->setRange(0,slines); 621 scrollbar->setRange(0,slines);
622 scrollbar->setSteps(1,lines); 622 scrollbar->setSteps(1,lines);
623 scrollbar->setValue(cursor); 623 scrollbar->setValue(cursor);
624 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 624 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
625} 625}
626 626
627void TEWidget::setScrollbarLocation(int loc) 627void TEWidget::setScrollbarLocation(int loc)
628{ 628{
629 if (scrollLoc == loc) return; // quickly 629 if (scrollLoc == loc) return; // quickly
630 scrollLoc = loc; 630 scrollLoc = loc;
631 propagateSize(); 631 propagateSize();
632 update(); 632 update();
633} 633}
634 634
635/* ------------------------------------------------------------------------- */ 635/* ------------------------------------------------------------------------- */
636/* */ 636/* */
637/* Mouse */ 637/* Mouse */
638/* */ 638/* */
639/* ------------------------------------------------------------------------- */ 639/* ------------------------------------------------------------------------- */
640 640
641/*! 641/*!
642 Three different operations can be performed using the mouse, and the 642 Three different operations can be performed using the mouse, and the
643 routines in this section serve all of them: 643 routines in this section serve all of them:
644 644
645 1) The press/release events are exposed to the application 645 1) The press/release events are exposed to the application
646 2) Marking (press and move left button) and Pasting (press middle button) 646 2) Marking (press and move left button) and Pasting (press middle button)
647 3) The right mouse button is used from the configuration menu 647 3) The right mouse button is used from the configuration menu
648 648
649 NOTE: During the marking process we attempt to keep the cursor within 649 NOTE: During the marking process we attempt to keep the cursor within
650 the bounds of the text as being displayed by setting the mouse position 650 the bounds of the text as being displayed by setting the mouse position
651 whenever the mouse has left the text area. 651 whenever the mouse has left the text area.
652 652
653 Two reasons to do so: 653 Two reasons to do so:
654 1) QT does not allow the `grabMouse' to confine-to the TEWidget. 654 1) QT does not allow the `grabMouse' to confine-to the TEWidget.
655 Thus a `XGrapPointer' would have to be used instead. 655 Thus a `XGrapPointer' would have to be used instead.
656 2) Even if so, this would not help too much, since the text area 656 2) Even if so, this would not help too much, since the text area
657 of the TEWidget is normally not identical with it's bounds. 657 of the TEWidget is normally not identical with it's bounds.
658 658
659 The disadvantage of the current handling is, that the mouse can visibly 659 The disadvantage of the current handling is, that the mouse can visibly
660 leave the bounds of the widget and is then moved back. Because of the 660 leave the bounds of the widget and is then moved back. Because of the
661 current construction, and the reasons mentioned above, we cannot do better 661 current construction, and the reasons mentioned above, we cannot do better
662 without changing the overall construction. 662 without changing the overall construction.
663*/ 663*/
664 664
665/*! 665/*!
666*/ 666*/
667 667
668void TEWidget::mousePressEvent(QMouseEvent* ev) 668void TEWidget::mousePressEvent(QMouseEvent* ev)
669{ 669{
670//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 670//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
671 if ( !contentsRect().contains(ev->pos()) ) return; 671 if ( !contentsRect().contains(ev->pos()) ) return;
672 QPoint tL = contentsRect().topLeft(); 672 QPoint tL = contentsRect().topLeft();
673 int tLx = tL.x(); 673 int tLx = tL.x();
674 int tLy = tL.y(); 674 int tLy = tL.y();
675 675
676 word_selection_mode = FALSE; 676 word_selection_mode = FALSE;
677 677
678//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY); 678//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
679 if ( ev->button() == LeftButton) 679 if ( ev->button() == LeftButton)
680 { 680 {
681 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 681 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
682 682
683 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ; 683 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
684 684
685 if (mouse_marks || (ev->state() & ShiftButton)) 685 if (mouse_marks || (ev->state() & ShiftButton))
686 { 686 {
687 emit clearSelectionSignal(); 687 emit clearSelectionSignal();
688 iPntSel = pntSel = pos; 688 iPntSel = pntSel = pos;
689 actSel = 1; // left mouse button pressed but nothing selected yet. 689 actSel = 1; // left mouse button pressed but nothing selected yet.
690 grabMouse( /*crossCursor*/ ); // handle with care! 690 grabMouse( /*crossCursor*/ ); // handle with care!
691 } 691 }
692 else 692 else
693 { 693 {
694 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button 694 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
695 } 695 }
696 } 696 }
697 if ( ev->button() == MidButton ) 697 if ( ev->button() == MidButton )
698 { 698 {
699 emitSelection(); 699 emitSelection();
700 } 700 }
701 if ( ev->button() == RightButton ) // Configure 701 if ( ev->button() == RightButton ) // Configure
702 { 702 {
703 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() ); 703 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
704 } 704 }
705} 705}
706 706
707void TEWidget::mouseMoveEvent(QMouseEvent* ev) 707void TEWidget::mouseMoveEvent(QMouseEvent* ev)
708{ 708{
709 // for auto-hiding the cursor, we need mouseTracking 709 // for auto-hiding the cursor, we need mouseTracking
710 if (ev->state() == NoButton ) return; 710 if (ev->state() == NoButton ) return;
711 711
712 if (actSel == 0) return; 712 if (actSel == 0) return;
713 713
714 // don't extend selection while pasting 714 // don't extend selection while pasting
715 if (ev->state() & MidButton) return; 715 if (ev->state() & MidButton) return;
716 716
717 //if ( !contentsRect().contains(ev->pos()) ) return; 717 //if ( !contentsRect().contains(ev->pos()) ) return;
718 QPoint tL = contentsRect().topLeft(); 718 QPoint tL = contentsRect().topLeft();
719 int tLx = tL.x(); 719 int tLx = tL.x();
720 int tLy = tL.y(); 720 int tLy = tL.y();
721 int scroll = scrollbar->value(); 721 int scroll = scrollbar->value();
722// int hScroll = hScrollbar->value(); 722// int hScroll = hScrollbar->value();
723 723
724 // we're in the process of moving the mouse with the left button pressed 724 // we're in the process of moving the mouse with the left button pressed
725 // the mouse cursor will kept catched within the bounds of the text in 725 // the mouse cursor will kept catched within the bounds of the text in
726 // this widget. 726 // this widget.
727 727
728 // Adjust position within text area bounds. See FIXME above. 728 // Adjust position within text area bounds. See FIXME above.
729 QPoint pos = ev->pos(); 729 QPoint pos = ev->pos();
730 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX ); 730 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
731 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w ); 731 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
732 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY ); 732 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
733 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 ); 733 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
734 // check if we produce a mouse move event by this 734 // check if we produce a mouse move event by this
735 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos)); 735 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
736 736
737 if ( pos.y() == tLy+bY+lines*font_h-1 ) 737 if ( pos.y() == tLy+bY+lines*font_h-1 )
738 { 738 {
739 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward 739 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward
740 } 740 }
741 if ( pos.y() == tLy+bY ) 741 if ( pos.y() == tLy+bY )
742 { 742 {
743 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback 743 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
744 } 744 }
745 745
746 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h); 746 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
747 QPoint ohere; 747 QPoint ohere;
748 bool swapping = FALSE; 748 bool swapping = FALSE;
749 749
750 if ( word_selection_mode ) 750 if ( word_selection_mode )
751 { 751 {
752 // Extend to word boundaries 752 // Extend to word boundaries
753 int i; 753 int i;
754 int selClass; 754 int selClass;
755 755
756 bool left_not_right = ( here.y() < iPntSel.y() || 756 bool left_not_right = ( here.y() < iPntSel.y() ||
757 here.y() == iPntSel.y() && here.x() < iPntSel.x() ); 757 here.y() == iPntSel.y() && here.x() < iPntSel.x() );
758 bool old_left_not_right = ( pntSel.y() < iPntSel.y() || 758 bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
759 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() ); 759 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
760 swapping = left_not_right != old_left_not_right; 760 swapping = left_not_right != old_left_not_right;
761 761
762 // Find left (left_not_right ? from here : from start) 762 // Find left (left_not_right ? from here : from start)
763 QPoint left = left_not_right ? here : iPntSel; 763 QPoint left = left_not_right ? here : iPntSel;
764 i = loc(left.x(),left.y()); 764 i = loc(left.x(),left.y());
765 selClass = charClass(image[i].c); 765 selClass = charClass(image[i].c);
766 while ( left.x() > 0 && charClass(image[i-1].c) == selClass ) 766 while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
767 { i--; left.rx()--; } 767 { i--; left.rx()--; }
768 768
769 // Find left (left_not_right ? from start : from here) 769 // Find left (left_not_right ? from start : from here)
770 QPoint right = left_not_right ? iPntSel : here; 770 QPoint right = left_not_right ? iPntSel : here;
771 i = loc(right.x(),right.y()); 771 i = loc(right.x(),right.y());
772 selClass = charClass(image[i].c); 772 selClass = charClass(image[i].c);
773 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass ) 773 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
774 { i++; right.rx()++; } 774 { i++; right.rx()++; }
775 775
776 // Pick which is start (ohere) and which is extension (here) 776 // Pick which is start (ohere) and which is extension (here)
777 if ( left_not_right ) 777 if ( left_not_right )
778 { 778 {
779 here = left; ohere = right; 779 here = left; ohere = right;
780 } 780 }
781 else 781 else
782 { 782 {
783 here = right; ohere = left; 783 here = right; ohere = left;
784 } 784 }
785 } 785 }
786 786
787 if (here == pntSel && scroll == scrollbar->value()) return; // not moved 787 if (here == pntSel && scroll == scrollbar->value()) return; // not moved
788 788
789 if ( word_selection_mode ) { 789 if ( word_selection_mode ) {
790 if ( actSel < 2 || swapping ) { 790 if ( actSel < 2 || swapping ) {
791 emit beginSelectionSignal( ohere.x(), ohere.y() ); 791 emit beginSelectionSignal( ohere.x(), ohere.y() );
792 } 792 }
793 } else if ( actSel < 2 ) { 793 } else if ( actSel < 2 ) {
794 emit beginSelectionSignal( pntSel.x(), pntSel.y() ); 794 emit beginSelectionSignal( pntSel.x(), pntSel.y() );
795 } 795 }
796 796
797 actSel = 2; // within selection 797 actSel = 2; // within selection
798 pntSel = here; 798 pntSel = here;
799 emit extendSelectionSignal( here.x(), here.y() ); 799 emit extendSelectionSignal( here.x(), here.y() );
800} 800}
801 801
802void TEWidget::mouseReleaseEvent(QMouseEvent* ev) 802void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
803{ 803{
804//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 804//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
805 if ( ev->button() == LeftButton) 805 if ( ev->button() == LeftButton)
806 { 806 {
807 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks); 807 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
808 preserve_line_breaks = TRUE; 808 preserve_line_breaks = TRUE;
809 actSel = 0; 809 actSel = 0;
810 810
811 //FIXME: emits a release event even if the mouse is 811 //FIXME: emits a release event even if the mouse is
812 // outside the range. The procedure used in `mouseMoveEvent' 812 // outside the range. The procedure used in `mouseMoveEvent'
813 // applies here, too. 813 // applies here, too.
814 814
815 QPoint tL = contentsRect().topLeft(); 815 QPoint tL = contentsRect().topLeft();
816 int tLx = tL.x(); 816 int tLx = tL.x();
817 int tLy = tL.y(); 817 int tLy = tL.y();
818 818
819 if (!mouse_marks && !(ev->state() & ShiftButton)) 819 if (!mouse_marks && !(ev->state() & ShiftButton))
820 emit mouseSignal( 3, // release 820 emit mouseSignal( 3, // release
821 (ev->x()-tLx-blX)/font_w + 1, 821 (ev->x()-tLx-blX)/font_w + 1,
822 (ev->y()-tLy-bY)/font_h + 1 ); 822 (ev->y()-tLy-bY)/font_h + 1 );
823 releaseMouse(); 823 releaseMouse();
824 } 824 }
825} 825}
826 826
827void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev) 827void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev)
828{ 828{
829 if ( ev->button() != LeftButton) return; 829 if ( ev->button() != LeftButton) return;
830 830
831 QPoint tL = contentsRect().topLeft(); 831 QPoint tL = contentsRect().topLeft();
832 int tLx = tL.x(); 832 int tLx = tL.x();
833 int tLy = tL.y(); 833 int tLy = tL.y();
834 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 834 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
835 835
836 // pass on double click as two clicks. 836 // pass on double click as two clicks.
837 if (!mouse_marks && !(ev->state() & ShiftButton)) 837 if (!mouse_marks && !(ev->state() & ShiftButton))
838 { 838 {
839 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button 839 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
840 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release 840 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release
841 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button 841 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
842 return; 842 return;
843 } 843 }
844 844
845 845
846 emit clearSelectionSignal(); 846 emit clearSelectionSignal();
847 QPoint bgnSel = pos; 847 QPoint bgnSel = pos;
848 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 848 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
849 int i = loc(bgnSel.x(),bgnSel.y()); 849 int i = loc(bgnSel.x(),bgnSel.y());
850 iPntSel = bgnSel; 850 iPntSel = bgnSel;
851 851
852 word_selection_mode = TRUE; 852 word_selection_mode = TRUE;
853 853
854 // find word boundaries... 854 // find word boundaries...
855 int selClass = charClass(image[i].c); 855 int selClass = charClass(image[i].c);
856 { 856 {
857 // set the start... 857 // set the start...
858 int x = bgnSel.x(); 858 int x = bgnSel.x();
859 while ( x > 0 && charClass(image[i-1].c) == selClass ) 859 while ( x > 0 && charClass(image[i-1].c) == selClass )
860 { i--; x--; } 860 { i--; x--; }
861 bgnSel.setX(x); 861 bgnSel.setX(x);
862 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() ); 862 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() );
863 863
864 // set the end... 864 // set the end...
865 i = loc( endSel.x(), endSel.y() ); 865 i = loc( endSel.x(), endSel.y() );
866 x = endSel.x(); 866 x = endSel.x();
867 while( x < columns-1 && charClass(image[i+1].c) == selClass ) 867 while( x < columns-1 && charClass(image[i+1].c) == selClass )
868 { i++; x++ ; } 868 { i++; x++ ; }
869 endSel.setX(x); 869 endSel.setX(x);
870 actSel = 2; // within selection 870 actSel = 2; // within selection
871 emit extendSelectionSignal( endSel.x(), endSel.y() ); 871 emit extendSelectionSignal( endSel.x(), endSel.y() );
872 emit endSelectionSignal(preserve_line_breaks); 872 emit endSelectionSignal(preserve_line_breaks);
873 preserve_line_breaks = TRUE; 873 preserve_line_breaks = TRUE;
874 } 874 }
875} 875}
876 876
877void TEWidget::focusInEvent( QFocusEvent * ) 877void TEWidget::focusInEvent( QFocusEvent * )
878{ 878{
879 879
880 // do nothing, to prevent repainting 880 // do nothing, to prevent repainting
881} 881}
882 882
883 883
884void TEWidget::focusOutEvent( QFocusEvent * ) 884void TEWidget::focusOutEvent( QFocusEvent * )
885{ 885{
886 // do nothing, to prevent repainting 886 // do nothing, to prevent repainting
887} 887}
888 888
889bool TEWidget::focusNextPrevChild( bool next ) 889bool TEWidget::focusNextPrevChild( bool next )
890{ 890{
891 if (next) 891 if (next)
892 return false; // This disables changing the active part in konqueror 892 return false; // This disables changing the active part in konqueror
893 // when pressing Tab 893 // when pressing Tab
894 return QFrame::focusNextPrevChild( next ); 894 return QFrame::focusNextPrevChild( next );
895} 895}
896 896
897 897
898int TEWidget::charClass(char ch) const 898int TEWidget::charClass(char ch) const
899{ 899{
900 // This might seem like overkill, but imagine if ch was a Unicode 900 // This might seem like overkill, but imagine if ch was a Unicode
901 // character (Qt 2.0 QChar) - it might then be sensible to separate 901 // character (Qt 2.0 QChar) - it might then be sensible to separate
902 // the different language ranges, etc. 902 // the different language ranges, etc.
903 903
904 if ( isspace(ch) ) return ' '; 904 if ( isspace(ch) ) return ' ';
905 905
906 static const char *word_characters = ":@-./_~"; 906 static const char *word_characters = ":@-./_~";
907 if ( isalnum(ch) || strchr(word_characters, ch) ) 907 if ( isalnum(ch) || strchr(word_characters, ch) )
908 return 'a'; 908 return 'a';
909 909
910 // Everything else is weird 910 // Everything else is weird
911 return 1; 911 return 1;
912} 912}
913 913
914void TEWidget::setMouseMarks(bool on) 914void TEWidget::setMouseMarks(bool on)
915{ 915{
916 mouse_marks = on; 916 mouse_marks = on;
917 setCursor( mouse_marks ? ibeamCursor : arrowCursor ); 917 setCursor( mouse_marks ? ibeamCursor : arrowCursor );
918} 918}
919 919
920/* ------------------------------------------------------------------------- */ 920/* ------------------------------------------------------------------------- */
921/* */ 921/* */
922/* Clipboard */ 922/* Clipboard */
923/* */ 923/* */
924/* ------------------------------------------------------------------------- */ 924/* ------------------------------------------------------------------------- */
925 925
926#undef KeyPress 926#undef KeyPress
927 927
928void TEWidget::emitSelection() 928void TEWidget::emitSelection()
929// Paste Clipboard by simulating keypress events 929// Paste Clipboard by simulating keypress events
930{ 930{
931#ifndef QT_NO_CLIPBOARD 931#ifndef QT_NO_CLIPBOARD
932 QString text = QApplication::clipboard()->text(); 932 QString text = QApplication::clipboard()->text();
933 if ( ! text.isNull() ) 933 if ( ! text.isNull() )
934 { 934 {
935 text.replace(QRegExp("\n"), "\r"); 935 text.replace(QRegExp("\n"), "\r");
936 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); 936 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
937 emit keyPressedSignal(&e); // expose as a big fat keypress event 937 emit keyPressedSignal(&e); // expose as a big fat keypress event
938 emit clearSelectionSignal(); 938 emit clearSelectionSignal();
939 } 939 }
940#endif 940#endif
941} 941}
942 942
943void TEWidget::emitText(QString text) 943void TEWidget::emitText(QString text)
944{ 944{
945 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); 945 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
946 emit keyPressedSignal(&e); // expose as a big fat keypress event 946 emit keyPressedSignal(&e); // expose as a big fat keypress event
947} 947}
948 948
949void TEWidget::pasteClipboard( ) 949void TEWidget::pasteClipboard( )
950{ 950{
951 emitSelection(); 951 emitSelection();
952} 952}
953 953
954void TEWidget::setSelection(const QString& t) 954void TEWidget::setSelection(const QString& t)
955{ 955{
956#ifndef QT_NO_CLIPBOARD 956#ifndef QT_NO_CLIPBOARD
957 // Disconnect signal while WE set the clipboard 957 // Disconnect signal while WE set the clipboard
958 QObject *cb = QApplication::clipboard(); 958 QObject *cb = QApplication::clipboard();
959 QObject::disconnect( cb, SIGNAL(dataChanged()), 959 QObject::disconnect( cb, SIGNAL(dataChanged()),
960 this, SLOT(onClearSelection()) ); 960 this, SLOT(onClearSelection()) );
961 961
962 QApplication::clipboard()->setText(t); 962 QApplication::clipboard()->setText(t);
963 963
964 QObject::connect( cb, SIGNAL(dataChanged()), 964 QObject::connect( cb, SIGNAL(dataChanged()),
965 this, SLOT(onClearSelection()) ); 965 this, SLOT(onClearSelection()) );
966#endif 966#endif
967} 967}
968 968
969void TEWidget::onClearSelection() 969void TEWidget::onClearSelection()
970{ 970{
971 emit clearSelectionSignal(); 971 emit clearSelectionSignal();
972} 972}
973 973
974/* ------------------------------------------------------------------------- */ 974/* ------------------------------------------------------------------------- */
975/* */ 975/* */
976/* Keyboard */ 976/* Keyboard */
977/* */ 977/* */
978/* ------------------------------------------------------------------------- */ 978/* ------------------------------------------------------------------------- */
979 979
980//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent' 980//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent'
981// due to a bug in `QT' or the ignorance of the author to prevent 981// due to a bug in `QT' or the ignorance of the author to prevent
982// repaint events being emitted to the screen whenever one leaves 982// repaint events being emitted to the screen whenever one leaves
983// or reenters the screen to/from another application. 983// or reenters the screen to/from another application.
984// 984//
985// Troll says one needs to change focusInEvent() and focusOutEvent(), 985// Troll says one needs to change focusInEvent() and focusOutEvent(),
986// which would also let you have an in-focus cursor and an out-focus 986// which would also let you have an in-focus cursor and an out-focus
987// cursor like xterm does. 987// cursor like xterm does.
988 988
989// for the auto-hide cursor feature, I added empty focusInEvent() and 989// for the auto-hide cursor feature, I added empty focusInEvent() and
990// focusOutEvent() so that update() isn't called. 990// focusOutEvent() so that update() isn't called.
991// For auto-hide, we need to get keypress-events, but we only get them when 991// For auto-hide, we need to get keypress-events, but we only get them when
992// we have focus. 992// we have focus.
993 993
994void TEWidget::doScroll(int lines) 994void TEWidget::doScroll(int lines)
995{ 995{
996 scrollbar->setValue(scrollbar->value()+lines); 996 scrollbar->setValue(scrollbar->value()+lines);
997} 997}
998 998
999void TEWidget::doHScroll(int lines) { 999void TEWidget::doHScroll(int lines) {
1000 hScrollbar->setValue( hScrollbar->value()+lines); 1000 hScrollbar->setValue( hScrollbar->value()+lines);
1001} 1001}
1002 1002
1003bool TEWidget::eventFilter( QObject *obj, QEvent *e ) 1003bool TEWidget::eventFilter( QObject *obj, QEvent *e )
1004{ 1004{
1005 if ( (e->type() == QEvent::Accel || 1005 if ( (e->type() == QEvent::Accel ||
1006 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) { 1006 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) {
1007 static_cast<QKeyEvent *>( e )->ignore(); 1007 static_cast<QKeyEvent *>( e )->ignore();
1008 return true; 1008 return true;
1009 } 1009 }
1010 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ ) 1010 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ )
1011 return FALSE; // not us 1011 return FALSE; // not us
1012 if ( e->type() == QEvent::Wheel) { 1012 if ( e->type() == QEvent::Wheel) {
1013 QApplication::sendEvent(scrollbar, e); 1013 QApplication::sendEvent(scrollbar, e);
1014 } 1014 }
1015 1015
1016#ifdef FAKE_CTRL_AND_ALT 1016#ifdef FAKE_CTRL_AND_ALT
1017 static bool control = FALSE; 1017 static bool control = FALSE;
1018 static bool alt = FALSE; 1018 static bool alt = FALSE;
1019// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:"); 1019// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:");
1020 bool dele=FALSE; 1020 bool dele=FALSE;
1021 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { 1021 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
1022 QKeyEvent* ke = (QKeyEvent*)e; 1022 QKeyEvent* ke = (QKeyEvent*)e;
1023 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat(); 1023 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat();
1024 switch (ke->key()) { 1024 switch (ke->key()) {
1025 case Key_F9: // let this be "Control" 1025 case Key_F9: // let this be "Control"
1026 control = keydown; 1026 control = keydown;
1027 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state()); 1027 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
1028 dele=TRUE; 1028 dele=TRUE;
1029 break; 1029 break;
1030 case Key_F13: // let this be "Alt" 1030 case Key_F13: // let this be "Alt"
1031 alt = keydown; 1031 alt = keydown;
1032 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state()); 1032 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state());
1033 dele=TRUE; 1033 dele=TRUE;
1034 break; 1034 break;
1035 default: 1035 default:
1036 if ( control ) { 1036 if ( control ) {
1037 int a = toupper(ke->ascii())-64; 1037 int a = toupper(ke->ascii())-64;
1038 if ( a >= 0 && a < ' ' ) { 1038 if ( a >= 0 && a < ' ' ) {
1039 e = new QKeyEvent(e->type(), ke->key(), 1039 e = new QKeyEvent(e->type(), ke->key(),
1040 a, ke->state()|ControlButton, QChar(a,0)); 1040 a, ke->state()|ControlButton, QChar(a,0));
1041 dele=TRUE; 1041 dele=TRUE;
1042 } 1042 }
1043 } 1043 }
1044 if ( alt ) { 1044 if ( alt ) {
1045 e = new QKeyEvent(e->type(), ke->key(), 1045 e = new QKeyEvent(e->type(), ke->key(),
1046 ke->ascii(), ke->state()|AltButton, ke->text()); 1046 ke->ascii(), ke->state()|AltButton, ke->text());
1047 dele=TRUE; 1047 dele=TRUE;
1048 } 1048 }
1049 } 1049 }
1050 } 1050 }
1051#endif 1051#endif
1052 1052
1053 if ( e->type() == QEvent::KeyPress ) { 1053 if ( e->type() == QEvent::KeyPress ) {
1054 QKeyEvent* ke = (QKeyEvent*)e; 1054 QKeyEvent* ke = (QKeyEvent*)e;
1055 actSel=0; // Key stroke implies a screen update, so TEWidget won't 1055 actSel=0; // Key stroke implies a screen update, so TEWidget won't
1056 // know where the current selection is. 1056 // know where the current selection is.
1057 1057
1058// qDebug("key pressed is 0x%x, state %d",ke->key(), ke->state()); 1058// qDebug("key pressed is 0x%x, ascii is 0x%x, state %d", ke->key(), ke->ascii(), ke->state());
1059 1059
1060 if( ke->state() == ShiftButton && ke->key() == Key_Tab) { 1060 if( ke->state() == ShiftButton && ke->key() == Key_Tab) {
1061 //lets hardcode this sucker 1061 //lets hardcode this sucker
1062 1062
1063// qDebug("key pressed 2 is 0x%x",ke->key()); 1063// qDebug("key pressed 2 is 0x%x", ke->key());
1064 emitText("\\"); // expose 1064 emitText("\\"); // expose
1065 } 1065 }
1066 else if( ke->state() == ControlButton && ke->key() == Key_V) { 1066 else if( ke->state() == ControlButton && ke->key() == Key_V) {
1067 pasteClipboard(); 1067 pasteClipboard();
1068 } 1068 }
1069 else 1069 else
1070 emit keyPressedSignal(ke); // expose 1070 emit keyPressedSignal(ke); // expose
1071 ke->accept(); 1071 ke->accept();
1072#ifdef FAKE_CTRL_AND_ALT 1072#ifdef FAKE_CTRL_AND_ALT
1073 if ( dele ) delete e; 1073 if ( dele ) delete e;
1074#endif 1074#endif
1075 return true; // stop the event 1075 return true; // stop the event
1076 } 1076 }
1077 if ( e->type() == QEvent::Enter ) { 1077 if ( e->type() == QEvent::Enter ) {
1078 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()), 1078 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
1079 this, SLOT(onClearSelection()) ); 1079 this, SLOT(onClearSelection()) );
1080 } 1080 }
1081 if ( e->type() == QEvent::Leave ) { 1081 if ( e->type() == QEvent::Leave ) {
1082 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), 1082 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
1083 this, SLOT(onClearSelection()) ); 1083 this, SLOT(onClearSelection()) );
1084 } 1084 }
1085 return QFrame::eventFilter( obj, e ); 1085 return QFrame::eventFilter( obj, e );
1086} 1086}
1087 1087
1088/* ------------------------------------------------------------------------- */ 1088/* ------------------------------------------------------------------------- */
1089/* */ 1089/* */
1090/* Frame */ 1090/* Frame */
1091/* */ 1091/* */
1092/* ------------------------------------------------------------------------- */ 1092/* ------------------------------------------------------------------------- */
1093 1093
1094void TEWidget::frameChanged() 1094void TEWidget::frameChanged()
1095{ 1095{
1096 propagateSize(); 1096 propagateSize();
1097 update(); 1097 update();
1098} 1098}
1099 1099
1100/* ------------------------------------------------------------------------- */ 1100/* ------------------------------------------------------------------------- */
1101/* */ 1101/* */
1102/* Sound */ 1102/* Sound */
1103/* */ 1103/* */
1104/* ------------------------------------------------------------------------- */ 1104/* ------------------------------------------------------------------------- */
1105 1105
1106void TEWidget::Bell() 1106void TEWidget::Bell()
1107{ 1107{
1108//#ifdef QT_QWS_CUSTOM 1108//#ifdef QT_QWS_CUSTOM
1109//# ifndef QT_NO_COP 1109//# ifndef QT_NO_COP
1110 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" ); 1110 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
1111//# endif 1111//# endif
1112//#else 1112//#else
1113//# ifndef QT_NO_SOUND 1113//# ifndef QT_NO_SOUND
1114// QSound::play(Resource::findSound("alarm")); 1114// QSound::play(Resource::findSound("alarm"));
1115//# endif 1115//# endif
1116//#endif 1116//#endif
1117 1117
1118// QApplication::beep(); 1118// QApplication::beep();
1119} 1119}
1120 1120
1121/* ------------------------------------------------------------------------- */ 1121/* ------------------------------------------------------------------------- */
1122/* */ 1122/* */
1123/* Auxiluary */ 1123/* Auxiluary */
1124/* */ 1124/* */
1125/* ------------------------------------------------------------------------- */ 1125/* ------------------------------------------------------------------------- */
1126 1126
1127void TEWidget::clearImage() 1127void TEWidget::clearImage()
1128// initialize the image 1128// initialize the image
1129// for internal use only 1129// for internal use only
1130{ 1130{
1131 for (int y = 0; y < lines; y++) 1131 for (int y = 0; y < lines; y++)
1132 for (int x = 0; x < columns; x++) 1132 for (int x = 0; x < columns; x++)
1133 { 1133 {
1134 image[loc(x,y)].c = 0xff; //' '; 1134 image[loc(x,y)].c = 0xff; //' ';
1135 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR; 1135 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR;
1136 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR; 1136 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
1137 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION; 1137 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
1138 } 1138 }
1139} 1139}
1140 1140
1141// Create Image /////////////////////////////////////////////////////// 1141// Create Image ///////////////////////////////////////////////////////
1142 1142
1143void TEWidget::calcGeometry() 1143void TEWidget::calcGeometry()
1144{ 1144{
1145 int showhscrollbar = 1; 1145 int showhscrollbar = 1;
1146 int hwidth = 0; 1146 int hwidth = 0;
1147 int dcolumns; 1147 int dcolumns;
1148 Config cfg("Konsole"); 1148 Config cfg("Konsole");
1149 cfg.setGroup("ScrollBar"); 1149 cfg.setGroup("ScrollBar");
1150 useHorzScroll=cfg.readBoolEntry("HorzScroll",0); 1150 useHorzScroll=cfg.readBoolEntry("HorzScroll",0);
1151 1151
1152 if(vcolumns == 0) showhscrollbar = 0; 1152 if(vcolumns == 0) showhscrollbar = 0;
1153 if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width(); 1153 if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width();
1154 1154
1155 scrollbar->resize(QApplication::style().scrollBarExtent().width(), 1155 scrollbar->resize(QApplication::style().scrollBarExtent().width(),
1156 contentsRect().height() - hwidth); 1156 contentsRect().height() - hwidth);
1157 1157
1158 switch(scrollLoc) { 1158 switch(scrollLoc) {
1159 case SCRNONE : 1159 case SCRNONE :
1160 columns = ( contentsRect().width() - 2 * rimX ) / font_w; 1160 columns = ( contentsRect().width() - 2 * rimX ) / font_w;
1161 dcolumns = columns; 1161 dcolumns = columns;
1162 if(vcolumns) columns = vcolumns; 1162 if(vcolumns) columns = vcolumns;
1163 blX = (contentsRect().width() - (columns*font_w) ) / 2; 1163 blX = (contentsRect().width() - (columns*font_w) ) / 2;
1164 if(showhscrollbar) 1164 if(showhscrollbar)
1165 blX = -hposition * font_w; 1165 blX = -hposition * font_w;
1166 brX = blX; 1166 brX = blX;
1167 scrollbar->hide(); 1167 scrollbar->hide();
1168 break; 1168 break;
1169 case SCRLEFT : 1169 case SCRLEFT :
1170 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; 1170 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1171 dcolumns = columns; 1171 dcolumns = columns;
1172 if(vcolumns) columns = vcolumns; 1172 if(vcolumns) columns = vcolumns;
1173 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; 1173 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1174 if(showhscrollbar) 1174 if(showhscrollbar)
1175 brX = -hposition * font_w; 1175 brX = -hposition * font_w;
1176 blX = brX + scrollbar->width(); 1176 blX = brX + scrollbar->width();
1177 scrollbar->move(contentsRect().topLeft()); 1177 scrollbar->move(contentsRect().topLeft());
1178 scrollbar->show(); 1178 scrollbar->show();
1179 break; 1179 break;
1180 case SCRRIGHT: 1180 case SCRRIGHT:
1181 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; 1181 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1182 dcolumns = columns; 1182 dcolumns = columns;
1183 if(vcolumns) columns = vcolumns; 1183 if(vcolumns) columns = vcolumns;
1184 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; 1184 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1185 if(showhscrollbar) 1185 if(showhscrollbar)
1186 blX = -hposition * font_w; 1186 blX = -hposition * font_w;
1187 brX = blX; 1187 brX = blX;
1188 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0)); 1188 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
1189 scrollbar->show(); 1189 scrollbar->show();
1190 break; 1190 break;
1191 } 1191 }
1192 //FIXME: support 'rounding' styles 1192 //FIXME: support 'rounding' styles
1193 lines = ( contentsRect().height() - 2 * rimY ) / font_h; 1193 lines = ( contentsRect().height() - 2 * rimY ) / font_h;
1194 bY = (contentsRect().height() - (lines *font_h)) / 2; 1194 bY = (contentsRect().height() - (lines *font_h)) / 2;
1195 1195
1196 if(showhscrollbar == 1) { 1196 if(showhscrollbar == 1) {
1197 hScrollbar->resize(contentsRect().width() - hwidth, hwidth); 1197 hScrollbar->resize(contentsRect().width() - hwidth, hwidth);
1198 hScrollbar->setRange(0, vcolumns - dcolumns); 1198 hScrollbar->setRange(0, vcolumns - dcolumns);
1199 1199
1200 QPoint p = contentsRect().bottomLeft(); 1200 QPoint p = contentsRect().bottomLeft();
1201 hScrollbar->move(QPoint(p.x(), p.y() - hwidth)); 1201 hScrollbar->move(QPoint(p.x(), p.y() - hwidth));
1202 hScrollbar->show(); 1202 hScrollbar->show();
1203 } 1203 }
1204 else hScrollbar->hide(); 1204 else hScrollbar->hide();
1205 1205
1206 if(showhscrollbar == 1) { 1206 if(showhscrollbar == 1) {
1207 lines = lines - (hwidth / font_h) - 1; 1207 lines = lines - (hwidth / font_h) - 1;
1208 if(lines < 1) lines = 1; 1208 if(lines < 1) lines = 1;
1209 } 1209 }
1210
1211 /*//FIXME: set rimX == rimY == 0 when running in full screen mode.
1212 Config cfg("Konsole");
1213 cfg.setGroup("ScrollBar");
1214 useHorzScroll=cfg.readBoolEntry("HorzScroll",0);
1215
1216 scrollbar->resize( QApplication::style().scrollBarExtent().width(),
1217 contentsRect().height());
1218 qDebug("font_w %d", font_w);
1219 switch(scrollLoc)
1220 {
1221 case SCRNONE :
1222 columns = ( contentsRect().width() - 2 * rimX ) / font_w;
1223 blX = (contentsRect().width() - (columns*font_w) ) / 2;
1224 brX = blX;
1225 scrollbar->hide();
1226 break;
1227 case SCRLEFT :
1228 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1229 if(useHorzScroll) columns = columns * (font_w/2);
1230 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1231 blX = brX + scrollbar->width();
1232 scrollbar->move(contentsRect().topLeft());
1233 scrollbar->show();
1234 break;
1235 case SCRRIGHT:
1236 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width() ) / font_w;
1237 if(useHorzScroll) columns = columns * (font_w/2);
1238 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1239 if(useHorzScroll) {
1240 brX = blX =2;
1241 } else {
1242 brX=blX;
1243 }
1244 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0) );
1245 scrollbar->show();
1246 break;
1247 }
1248
1249 if( !scrollbar->isHidden())
1250 hScrollbar->resize( contentsRect().width()-SCRWIDTH, QApplication::style()
1251 .scrollBarExtent().height());
1252 else
1253 hScrollbar->resize( contentsRect().width(), QApplication::style()
1254 .scrollBarExtent().height());
1255
1256 hScrollbar->move( 0, contentsRect().height() - SCRWIDTH);
1257
1258
1259 if(useHorzScroll) {
1260 hScrollbar->show();
1261 lines = ( (contentsRect().height() - SCRWIDTH) - 2 * rimY ) / font_h;
1262 bY = ((contentsRect().height() - SCRWIDTH) - (lines *font_h)) / 2;
1263 } else {
1264 hScrollbar->hide();
1265 lines = (contentsRect().height() - 2 * rimY ) / font_h;
1266 bY = (contentsRect().height() - (lines *font_h)) / 2;
1267 }
1268 */
1269 //FIXME: support 'rounding' styles 1210 //FIXME: support 'rounding' styles
1270} 1211}
1271 1212
1272void TEWidget::makeImage() 1213void TEWidget::makeImage()
1273//FIXME: rename 'calcGeometry? 1214//FIXME: rename 'calcGeometry?
1274{ 1215{
1275 calcGeometry(); 1216 calcGeometry();
1276 image = (ca*) malloc(lines*columns*sizeof(ca)); 1217 image = (ca*) malloc(lines*columns*sizeof(ca));
1277 clearImage(); 1218 clearImage();
1278} 1219}
1279 1220
1280// calculate the needed size 1221// calculate the needed size
1281QSize TEWidget::calcSize(int cols, int lins) const 1222QSize TEWidget::calcSize(int cols, int lins) const
1282{ 1223{
1283 int frw = width() - contentsRect().width(); 1224 int frw = width() - contentsRect().width();
1284 int frh = height() - contentsRect().height(); 1225 int frh = height() - contentsRect().height();
1285 int scw = (scrollLoc==SCRNONE?0:scrollbar->width()); 1226 int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
1286 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh ); 1227 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
1287} 1228}
1288 1229
1289QSize TEWidget::sizeHint() const 1230QSize TEWidget::sizeHint() const
1290{ 1231{
1291 return size(); 1232 return size();
1292} 1233}
1293 1234
1294void TEWidget::styleChange(QStyle &) 1235void TEWidget::styleChange(QStyle &)
1295{ 1236{
1296 propagateSize(); 1237 propagateSize();
1297} 1238}
1298 1239
1299#ifndef QT_NO_DRAGANDDROP 1240#ifndef QT_NO_DRAGANDDROP
1300 1241
1301/* --------------------------------------------------------------------- */ 1242/* --------------------------------------------------------------------- */
1302/* */ 1243/* */
1303/* Drag & Drop */ 1244/* Drag & Drop */
1304/* */ 1245/* */
1305/* --------------------------------------------------------------------- */ 1246/* --------------------------------------------------------------------- */
1306 1247
1307 1248
1308void TEWidget::dragEnterEvent(QDragEnterEvent* e) 1249void TEWidget::dragEnterEvent(QDragEnterEvent* e)
1309{ 1250{
1310 e->accept(QTextDrag::canDecode(e) || 1251 e->accept(QTextDrag::canDecode(e) ||
1311 QUriDrag::canDecode(e)); 1252 QUriDrag::canDecode(e));
1312} 1253}
1313 1254
1314void TEWidget::dropEvent(QDropEvent* event) 1255void TEWidget::dropEvent(QDropEvent* event)
1315{ 1256{
1316 // The current behaviour when url(s) are dropped is 1257 // The current behaviour when url(s) are dropped is
1317 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd 1258 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
1318 // * in all other cases, just paste 1259 // * in all other cases, just paste
1319 // (for non-local ones, or for a list of URLs, 'cd' is nonsense) 1260 // (for non-local ones, or for a list of URLs, 'cd' is nonsense)
1320 QStrList strlist; 1261 QStrList strlist;
1321 int file_count = 0; 1262 int file_count = 0;
1322 dropText = ""; 1263 dropText = "";
1323 bool bPopup = true; 1264 bool bPopup = true;
1324 1265
1325 if(QUriDrag::decode(event, strlist)) { 1266 if(QUriDrag::decode(event, strlist)) {
1326 if (strlist.count()) { 1267 if (strlist.count()) {
1327 for(const char* p = strlist.first(); p; p = strlist.next()) { 1268 for(const char* p = strlist.first(); p; p = strlist.next()) {
1328 if(file_count++ > 0) { 1269 if(file_count++ > 0) {
1329 dropText += " "; 1270 dropText += " ";
1330 bPopup = false; // more than one file, don't popup 1271 bPopup = false; // more than one file, don't popup
1331 } 1272 }
1332 1273
1333/* 1274/*
1334 KURL url(p); 1275 KURL url(p);
1335 if (url.isLocalFile()) { 1276 if (url.isLocalFile()) {
1336 dropText += url.path(); // local URL : remove protocol 1277 dropText += url.path(); // local URL : remove protocol
1337 } 1278 }
1338 else { 1279 else {
1339 dropText += url.prettyURL(); 1280 dropText += url.prettyURL();
1340 bPopup = false; // a non-local file, don't popup 1281 bPopup = false; // a non-local file, don't popup
1341 } 1282 }
1342*/ 1283*/
1343 1284
1344 } 1285 }
1345 1286
1346 if (bPopup) 1287 if (bPopup)
1347 // m_drop->popup(pos() + event->pos()); 1288 // m_drop->popup(pos() + event->pos());
1348 m_drop->popup(mapToGlobal(event->pos())); 1289 m_drop->popup(mapToGlobal(event->pos()));
1349 else 1290 else
1350 { 1291 {
1351 if (currentSession) { 1292 if (currentSession) {
1352 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1293 currentSession->getEmulation()->sendString(dropText.local8Bit());
1353 } 1294 }
1354// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1295// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1355 } 1296 }
1356 } 1297 }
1357 } 1298 }
1358 else if(QTextDrag::decode(event, dropText)) { 1299 else if(QTextDrag::decode(event, dropText)) {
1359// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1300// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1360 if (currentSession) { 1301 if (currentSession) {
1361 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1302 currentSession->getEmulation()->sendString(dropText.local8Bit());
1362 } 1303 }
1363 // Paste it 1304 // Paste it
1364 } 1305 }
1365} 1306}
1366#endif 1307#endif
1367 1308
1368 1309
1369void TEWidget::drop_menu_activated(int item) 1310void TEWidget::drop_menu_activated(int item)
1370{ 1311{
1371#ifndef QT_NO_DRAGANDDROP 1312#ifndef QT_NO_DRAGANDDROP
1372 switch (item) 1313 switch (item)
1373 { 1314 {
1374 case 0: // paste 1315 case 0: // paste
1375 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1316 currentSession->getEmulation()->sendString(dropText.local8Bit());
1376// KWM::activate((Window)this->winId()); 1317// KWM::activate((Window)this->winId());
1377 break; 1318 break;
1378 case 1: // cd ... 1319 case 1: // cd ...
1379 currentSession->getEmulation()->sendString("cd "); 1320 currentSession->getEmulation()->sendString("cd ");
1380 struct stat statbuf; 1321 struct stat statbuf;
1381 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 ) 1322 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
1382 { 1323 {
1383 if ( !S_ISDIR(statbuf.st_mode) ) 1324 if ( !S_ISDIR(statbuf.st_mode) )
1384 { 1325 {
1385/* 1326/*
1386 KURL url; 1327 KURL url;
1387 url.setPath( dropText ); 1328 url.setPath( dropText );
1388 dropText = url.directory( true, false ); // remove filename 1329 dropText = url.directory( true, false ); // remove filename
1389*/ 1330*/
1390 } 1331 }
1391 } 1332 }
1392 dropText.replace(QRegExp(" "), "\\ "); // escape spaces 1333 dropText.replace(QRegExp(" "), "\\ "); // escape spaces
1393 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1334 currentSession->getEmulation()->sendString(dropText.local8Bit());
1394 currentSession->getEmulation()->sendString("\n"); 1335 currentSession->getEmulation()->sendString("\n");
1395// KWM::activate((Window)this->winId()); 1336// KWM::activate((Window)this->winId());
1396 break; 1337 break;
1397 } 1338 }
1398#endif 1339#endif
1399} 1340}
1400 1341
1401void TEWidget::setWrapAt(int columns) 1342void TEWidget::setWrapAt(int columns)
1402{ 1343{
1403 vcolumns = columns; 1344 vcolumns = columns;
1404 propagateSize(); 1345 propagateSize();
1405 update(); 1346 update();
1406} 1347}