summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/TEWidget.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/core/apps/embeddedkonsole/TEWidget.cpp b/core/apps/embeddedkonsole/TEWidget.cpp
index cacc3c4..4c6ea2a 100644
--- a/core/apps/embeddedkonsole/TEWidget.cpp
+++ b/core/apps/embeddedkonsole/TEWidget.cpp
@@ -1,1347 +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#if !(QT_NO_COP)
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, ascii is 0x%x, state %d", ke->key(), ke->ascii(), 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_SHARP 1108//#ifdef QT_QWS_SHARP
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 //FIXME: support 'rounding' styles 1210 //FIXME: support 'rounding' styles
1211} 1211}
1212 1212
1213void TEWidget::makeImage() 1213void TEWidget::makeImage()
1214//FIXME: rename 'calcGeometry? 1214//FIXME: rename 'calcGeometry?
1215{ 1215{
1216 calcGeometry(); 1216 calcGeometry();
1217 image = (ca*) malloc(lines*columns*sizeof(ca)); 1217 image = (ca*) malloc(lines*columns*sizeof(ca));
1218 clearImage(); 1218 clearImage();
1219} 1219}
1220 1220
1221// calculate the needed size 1221// calculate the needed size
1222QSize TEWidget::calcSize(int cols, int lins) const 1222QSize TEWidget::calcSize(int cols, int lins) const
1223{ 1223{
1224 int frw = width() - contentsRect().width(); 1224 int frw = width() - contentsRect().width();
1225 int frh = height() - contentsRect().height(); 1225 int frh = height() - contentsRect().height();
1226 int scw = (scrollLoc==SCRNONE?0:scrollbar->width()); 1226 int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
1227 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 );
1228} 1228}
1229 1229
1230QSize TEWidget::sizeHint() const 1230QSize TEWidget::sizeHint() const
1231{ 1231{
1232 return size(); 1232 return size();
1233} 1233}
1234 1234
1235void TEWidget::styleChange(QStyle &) 1235void TEWidget::styleChange(QStyle &)
1236{ 1236{
1237 propagateSize(); 1237 propagateSize();
1238} 1238}
1239 1239
1240#ifndef QT_NO_DRAGANDDROP 1240#ifndef QT_NO_DRAGANDDROP
1241 1241
1242/* --------------------------------------------------------------------- */ 1242/* --------------------------------------------------------------------- */
1243/* */ 1243/* */
1244/* Drag & Drop */ 1244/* Drag & Drop */
1245/* */ 1245/* */
1246/* --------------------------------------------------------------------- */ 1246/* --------------------------------------------------------------------- */
1247 1247
1248 1248
1249void TEWidget::dragEnterEvent(QDragEnterEvent* e) 1249void TEWidget::dragEnterEvent(QDragEnterEvent* e)
1250{ 1250{
1251 e->accept(QTextDrag::canDecode(e) || 1251 e->accept(QTextDrag::canDecode(e) ||
1252 QUriDrag::canDecode(e)); 1252 QUriDrag::canDecode(e));
1253} 1253}
1254 1254
1255void TEWidget::dropEvent(QDropEvent* event) 1255void TEWidget::dropEvent(QDropEvent* event)
1256{ 1256{
1257 // The current behaviour when url(s) are dropped is 1257 // The current behaviour when url(s) are dropped is
1258 // * 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
1259 // * in all other cases, just paste 1259 // * in all other cases, just paste
1260 // (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)
1261 QStrList strlist; 1261 QStrList strlist;
1262 int file_count = 0; 1262 int file_count = 0;
1263 dropText = ""; 1263 dropText = "";
1264 bool bPopup = true; 1264 bool bPopup = true;
1265 1265
1266 if(QUriDrag::decode(event, strlist)) { 1266 if(QUriDrag::decode(event, strlist)) {
1267 if (strlist.count()) { 1267 if (strlist.count()) {
1268 for(const char* p = strlist.first(); p; p = strlist.next()) { 1268 for(const char* p = strlist.first(); p; p = strlist.next()) {
1269 if(file_count++ > 0) { 1269 if(file_count++ > 0) {
1270 dropText += " "; 1270 dropText += " ";
1271 bPopup = false; // more than one file, don't popup 1271 bPopup = false; // more than one file, don't popup
1272 } 1272 }
1273 1273
1274/* 1274/*
1275 KURL url(p); 1275 KURL url(p);
1276 if (url.isLocalFile()) { 1276 if (url.isLocalFile()) {
1277 dropText += url.path(); // local URL : remove protocol 1277 dropText += url.path(); // local URL : remove protocol
1278 } 1278 }
1279 else { 1279 else {
1280 dropText += url.prettyURL(); 1280 dropText += url.prettyURL();
1281 bPopup = false; // a non-local file, don't popup 1281 bPopup = false; // a non-local file, don't popup
1282 } 1282 }
1283*/ 1283*/
1284 1284
1285 } 1285 }
1286 1286
1287 if (bPopup) 1287 if (bPopup)
1288 // m_drop->popup(pos() + event->pos()); 1288 // m_drop->popup(pos() + event->pos());
1289 m_drop->popup(mapToGlobal(event->pos())); 1289 m_drop->popup(mapToGlobal(event->pos()));
1290 else 1290 else
1291 { 1291 {
1292 if (currentSession) { 1292 if (currentSession) {
1293 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1293 currentSession->getEmulation()->sendString(dropText.local8Bit());
1294 } 1294 }
1295// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1295// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1296 } 1296 }
1297 } 1297 }
1298 } 1298 }
1299 else if(QTextDrag::decode(event, dropText)) { 1299 else if(QTextDrag::decode(event, dropText)) {
1300// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1300// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1301 if (currentSession) { 1301 if (currentSession) {
1302 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1302 currentSession->getEmulation()->sendString(dropText.local8Bit());
1303 } 1303 }
1304 // Paste it 1304 // Paste it
1305 } 1305 }
1306} 1306}
1307#endif 1307#endif
1308 1308
1309 1309
1310void TEWidget::drop_menu_activated(int item) 1310void TEWidget::drop_menu_activated(int item)
1311{ 1311{
1312#ifndef QT_NO_DRAGANDDROP 1312#ifndef QT_NO_DRAGANDDROP
1313 switch (item) 1313 switch (item)
1314 { 1314 {
1315 case 0: // paste 1315 case 0: // paste
1316 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1316 currentSession->getEmulation()->sendString(dropText.local8Bit());
1317// KWM::activate((Window)this->winId()); 1317// KWM::activate((Window)this->winId());
1318 break; 1318 break;
1319 case 1: // cd ... 1319 case 1: // cd ...
1320 currentSession->getEmulation()->sendString("cd "); 1320 currentSession->getEmulation()->sendString("cd ");
1321 struct stat statbuf; 1321 struct stat statbuf;
1322 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 ) 1322 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
1323 { 1323 {
1324 if ( !S_ISDIR(statbuf.st_mode) ) 1324 if ( !S_ISDIR(statbuf.st_mode) )
1325 { 1325 {
1326/* 1326/*
1327 KURL url; 1327 KURL url;
1328 url.setPath( dropText ); 1328 url.setPath( dropText );
1329 dropText = url.directory( true, false ); // remove filename 1329 dropText = url.directory( true, false ); // remove filename
1330*/ 1330*/
1331 } 1331 }
1332 } 1332 }
1333 dropText.replace(QRegExp(" "), "\\ "); // escape spaces 1333 dropText.replace(QRegExp(" "), "\\ "); // escape spaces
1334 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1334 currentSession->getEmulation()->sendString(dropText.local8Bit());
1335 currentSession->getEmulation()->sendString("\n"); 1335 currentSession->getEmulation()->sendString("\n");
1336// KWM::activate((Window)this->winId()); 1336// KWM::activate((Window)this->winId());
1337 break; 1337 break;
1338 } 1338 }
1339#endif 1339#endif
1340} 1340}
1341 1341
1342void TEWidget::setWrapAt(int columns) 1342void TEWidget::setWrapAt(int columns)
1343{ 1343{
1344 vcolumns = columns; 1344 vcolumns = columns;
1345 propagateSize(); 1345 propagateSize();
1346 update(); 1346 update();
1347} 1347}