summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/TEWidget.cpp6
1 files changed, 5 insertions, 1 deletions
diff --git a/core/apps/embeddedkonsole/TEWidget.cpp b/core/apps/embeddedkonsole/TEWidget.cpp
index c220e11..23720cd 100644
--- a/core/apps/embeddedkonsole/TEWidget.cpp
+++ b/core/apps/embeddedkonsole/TEWidget.cpp
@@ -1,1350 +1,1354 @@
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#if !(QT_NO_COP) 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;
335 vcolumns = 0; 335 vcolumns = 0;
336 useBeep = true; 336 useBeep = true;
337 337
338 setMouseMarks(TRUE); 338 setMouseMarks(TRUE);
339 setVTFont( QFont("fixed") ); 339 setVTFont( QFont("fixed") );
340 setColorTable(base_color_table); // init color table 340 setColorTable(base_color_table); // init color table
341 341
342 qApp->installEventFilter( this ); //FIXME: see below 342 qApp->installEventFilter( this ); //FIXME: see below
343// KCursor::setAutoHideCursor( this, true ); 343// KCursor::setAutoHideCursor( this, true );
344 344
345 // Init DnD //////////////////////////////////////////////////////////////// 345 // Init DnD ////////////////////////////////////////////////////////////////
346 currentSession = NULL; 346 currentSession = NULL;
347// setAcceptDrops(true); // attempt 347// setAcceptDrops(true); // attempt
348// m_drop = new QPopupMenu(this); 348// m_drop = new QPopupMenu(this);
349// m_drop->insertItem( QString("Paste"), 0); 349// m_drop->insertItem( QString("Paste"), 0);
350// m_drop->insertItem( QString("cd"), 1); 350// m_drop->insertItem( QString("cd"), 1);
351// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int))); 351// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int)));
352 352
353 // we need focus so that the auto-hide cursor feature works 353 // we need focus so that the auto-hide cursor feature works
354 setFocus(); 354 setFocus();
355 setFocusPolicy( WheelFocus ); 355 setFocusPolicy( WheelFocus );
356} 356}
357 357
358//FIXME: make proper destructor 358//FIXME: make proper destructor
359// Here's a start (David) 359// Here's a start (David)
360TEWidget::~TEWidget() 360TEWidget::~TEWidget()
361{ 361{
362 qApp->removeEventFilter( this ); 362 qApp->removeEventFilter( this );
363 if (image) free(image); 363 if (image) free(image);
364} 364}
365 365
366/* ------------------------------------------------------------------------- */ 366/* ------------------------------------------------------------------------- */
367/* */ 367/* */
368/* Display Operations */ 368/* Display Operations */
369/* */ 369/* */
370/* ------------------------------------------------------------------------- */ 370/* ------------------------------------------------------------------------- */
371 371
372/*! 372/*!
373 attributed string draw primitive 373 attributed string draw primitive
374*/ 374*/
375 375
376void TEWidget::drawAttrStr(QPainter &paint, QRect rect, 376void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
377 QString& str, ca attr, BOOL pm, BOOL clear) 377 QString& str, ca attr, BOOL pm, BOOL clear)
378{ 378{
379 if (pm && color_table[attr.b].transparent) 379 if (pm && color_table[attr.b].transparent)
380 { 380 {
381 paint.setBackgroundMode( TransparentMode ); 381 paint.setBackgroundMode( TransparentMode );
382 if (clear) erase(rect); 382 if (clear) erase(rect);
383 } 383 }
384 else 384 else
385 { 385 {
386 if (blinking) 386 if (blinking)
387 paint.fillRect(rect, color_table[attr.b].color); 387 paint.fillRect(rect, color_table[attr.b].color);
388 else 388 else
389 { 389 {
390 paint.setBackgroundMode( OpaqueMode ); 390 paint.setBackgroundMode( OpaqueMode );
391 paint.setBackgroundColor( color_table[attr.b].color ); 391 paint.setBackgroundColor( color_table[attr.b].color );
392 } 392 }
393 } 393 }
394 394
395 if (color_table[attr.f].bold) 395 if (color_table[attr.f].bold)
396 paint.setPen(QColor( 0x8F, 0x00, 0x00 )); 396 paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
397 else 397 else
398 paint.setPen(color_table[attr.f].color); 398 paint.setPen(color_table[attr.f].color);
399 399
400 paint.drawText(rect.x(),rect.y()+font_a, str); 400 paint.drawText(rect.x(),rect.y()+font_a, str);
401 401
402 if (attr.r & RE_UNDERLINE) 402 if (attr.r & RE_UNDERLINE)
403 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 ); 403 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
404} 404}
405 405
406/*! 406/*!
407 The image can only be set completely. 407 The image can only be set completely.
408 408
409 The size of the new image may or may not match the size of the widget. 409 The size of the new image may or may not match the size of the widget.
410*/ 410*/
411 411
412void TEWidget::setImage(const ca* const newimg, int lines, int columns) 412void TEWidget::setImage(const ca* const newimg, int lines, int columns)
413{ int y,x,len; 413{ int y,x,len;
414 const QPixmap* pm = backgroundPixmap(); 414 const QPixmap* pm = backgroundPixmap();
415 QPainter paint; 415 QPainter paint;
416 setUpdatesEnabled(FALSE); 416 setUpdatesEnabled(FALSE);
417 paint.begin( this ); 417 paint.begin( this );
418HCNT("setImage"); 418HCNT("setImage");
419 419
420 QPoint tL = contentsRect().topLeft(); 420 QPoint tL = contentsRect().topLeft();
421 int tLx = tL.x(); 421 int tLx = tL.x();
422 int tLy = tL.y(); 422 int tLy = tL.y();
423 hasBlinker = FALSE; 423 hasBlinker = FALSE;
424 424
425 int cf = -1; // undefined 425 int cf = -1; // undefined
426 int cb = -1; // undefined 426 int cb = -1; // undefined
427 int cr = -1; // undefined 427 int cr = -1; // undefined
428 428
429 int lins = QMIN(this->lines, QMAX(0,lines )); 429 int lins = QMIN(this->lines, QMAX(0,lines ));
430 int cols = QMIN(this->columns,QMAX(0,columns)); 430 int cols = QMIN(this->columns,QMAX(0,columns));
431 QChar *disstrU = new QChar[cols]; 431 QChar *disstrU = new QChar[cols];
432 for (y = 0; y < lins; y++) { 432 for (y = 0; y < lins; y++) {
433 const ca* lcl = &image[y*this->columns]; 433 const ca* lcl = &image[y*this->columns];
434 const ca* const ext = &newimg[y*columns]; 434 const ca* const ext = &newimg[y*columns];
435 if (!resizing) // not while resizing, we're expecting a paintEvent 435 if (!resizing) // not while resizing, we're expecting a paintEvent
436 for (x = 0; x < cols; x++) 436 for (x = 0; x < cols; x++)
437 { 437 {
438 hasBlinker |= (ext[x].r & RE_BLINK); 438 hasBlinker |= (ext[x].r & RE_BLINK);
439 if (ext[x] != lcl[x]) 439 if (ext[x] != lcl[x])
440 { 440 {
441 cr = ext[x].r; 441 cr = ext[x].r;
442 cb = ext[x].b; 442 cb = ext[x].b;
443 if (ext[x].f != cf) cf = ext[x].f; 443 if (ext[x].f != cf) cf = ext[x].f;
444 int lln = cols - x; 444 int lln = cols - x;
445 disstrU[0] = fontMap(ext[x+0].c); 445 disstrU[0] = fontMap(ext[x+0].c);
446 for (len = 1; len < lln; len++) 446 for (len = 1; len < lln; len++)
447 { 447 {
448 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || 448 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
449 ext[x+len] == lcl[x+len] ) 449 ext[x+len] == lcl[x+len] )
450 break; 450 break;
451 disstrU[len] = fontMap(ext[x+len].c); 451 disstrU[len] = fontMap(ext[x+len].c);
452 } 452 }
453 QString unistr(disstrU,len); 453 QString unistr(disstrU,len);
454 drawAttrStr(paint, 454 drawAttrStr(paint,
455 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 455 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
456 unistr, ext[x], pm != NULL, true); 456 unistr, ext[x], pm != NULL, true);
457 x += len - 1; 457 x += len - 1;
458 } 458 }
459 } 459 }
460 // finally, make `image' become `newimg'. 460 // finally, make `image' become `newimg'.
461 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca)); 461 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
462 } 462 }
463 drawFrame( &paint ); 463 drawFrame( &paint );
464 paint.end(); 464 paint.end();
465 setUpdatesEnabled(TRUE); 465 setUpdatesEnabled(TRUE);
466 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms 466 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms
467 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; } 467 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
468 delete [] disstrU; 468 delete [] disstrU;
469} 469}
470 470
471// paint Event //////////////////////////////////////////////////// 471// paint Event ////////////////////////////////////////////////////
472 472
473/*! 473/*!
474 The difference of this routine vs. the `setImage' is, 474 The difference of this routine vs. the `setImage' is,
475 that the drawing does not include a difference analysis 475 that the drawing does not include a difference analysis
476 between the old and the new image. Instead, the internal 476 between the old and the new image. Instead, the internal
477 image is used and the painting bound by the PaintEvent box. 477 image is used and the painting bound by the PaintEvent box.
478*/ 478*/
479 479
480void TEWidget::paintEvent( QPaintEvent* pe ) 480void TEWidget::paintEvent( QPaintEvent* pe )
481{ 481{
482 482
483//{ static int cnt = 0; printf("paint %d\n",cnt++); } 483//{ static int cnt = 0; printf("paint %d\n",cnt++); }
484 const QPixmap* pm = backgroundPixmap(); 484 const QPixmap* pm = backgroundPixmap();
485 QPainter paint; 485 QPainter paint;
486 setUpdatesEnabled(FALSE); 486 setUpdatesEnabled(FALSE);
487 paint.begin( this ); 487 paint.begin( this );
488 paint.setBackgroundMode( TransparentMode ); 488 paint.setBackgroundMode( TransparentMode );
489HCNT("paintEvent"); 489HCNT("paintEvent");
490 490
491 // Note that the actual widget size can be slightly larger 491 // Note that the actual widget size can be slightly larger
492 // that the image (the size is truncated towards the smaller 492 // that the image (the size is truncated towards the smaller
493 // number of characters in `resizeEvent'. The paint rectangle 493 // number of characters in `resizeEvent'. The paint rectangle
494 // can thus be larger than the image, but less then the size 494 // can thus be larger than the image, but less then the size
495 // of one character. 495 // of one character.
496 496
497 QRect rect = pe->rect().intersect(contentsRect()); 497 QRect rect = pe->rect().intersect(contentsRect());
498 498
499 QPoint tL = contentsRect().topLeft(); 499 QPoint tL = contentsRect().topLeft();
500 int tLx = tL.x(); 500 int tLx = tL.x();
501 int tLy = tL.y(); 501 int tLy = tL.y();
502 502
503 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w)); 503 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w));
504 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h)); 504 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h));
505 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w)); 505 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w));
506 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h)); 506 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h));
507 507
508 /* 508 /*
509 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly, 509 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly,
510 rect.left(), rect.right(), rect.top(), rect.bottom()); 510 rect.left(), rect.right(), rect.top(), rect.bottom());
511 */ 511 */
512 512
513 // if (pm != NULL && color_table[image->b].transparent) 513 // if (pm != NULL && color_table[image->b].transparent)
514 // erase(rect); 514 // erase(rect);
515 // BL: I have no idea why we need this, and it breaks the refresh. 515 // BL: I have no idea why we need this, and it breaks the refresh.
516 516
517 QChar *disstrU = new QChar[columns]; 517 QChar *disstrU = new QChar[columns];
518 for (int y = luy; y <= rly; y++) 518 for (int y = luy; y <= rly; y++)
519 for (int x = lux; x <= rlx; x++) 519 for (int x = lux; x <= rlx; x++)
520 { 520 {
521 int len = 1; 521 int len = 1;
522 disstrU[0] = fontMap(image[loc(x,y)].c); 522 disstrU[0] = fontMap(image[loc(x,y)].c);
523 int cf = image[loc(x,y)].f; 523 int cf = image[loc(x,y)].f;
524 int cb = image[loc(x,y)].b; 524 int cb = image[loc(x,y)].b;
525 int cr = image[loc(x,y)].r; 525 int cr = image[loc(x,y)].r;
526 while (x+len <= rlx && 526 while (x+len <= rlx &&
527 image[loc(x+len,y)].f == cf && 527 image[loc(x+len,y)].f == cf &&
528 image[loc(x+len,y)].b == cb && 528 image[loc(x+len,y)].b == cb &&
529 image[loc(x+len,y)].r == cr ) 529 image[loc(x+len,y)].r == cr )
530 { 530 {
531 disstrU[len] = fontMap(image[loc(x+len,y)].c); 531 disstrU[len] = fontMap(image[loc(x+len,y)].c);
532 len += 1; 532 len += 1;
533 } 533 }
534 QString unistr(disstrU,len); 534 QString unistr(disstrU,len);
535 drawAttrStr(paint, 535 drawAttrStr(paint,
536 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 536 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
537 unistr, image[loc(x,y)], pm != NULL, false); 537 unistr, image[loc(x,y)], pm != NULL, false);
538 x += len - 1; 538 x += len - 1;
539 } 539 }
540 delete [] disstrU; 540 delete [] disstrU;
541 drawFrame( &paint ); 541 drawFrame( &paint );
542 paint.end(); 542 paint.end();
543 setUpdatesEnabled(TRUE); 543 setUpdatesEnabled(TRUE);
544} 544}
545 545
546void TEWidget::blinkEvent() 546void TEWidget::blinkEvent()
547{ 547{
548 blinking = !blinking; 548 blinking = !blinking;
549 repaint(FALSE); 549 repaint(FALSE);
550} 550}
551 551
552/* ------------------------------------------------------------------------- */ 552/* ------------------------------------------------------------------------- */
553/* */ 553/* */
554/* Resizing */ 554/* Resizing */
555/* */ 555/* */
556/* ------------------------------------------------------------------------- */ 556/* ------------------------------------------------------------------------- */
557 557
558void TEWidget::resizeEvent(QResizeEvent* ev) 558void TEWidget::resizeEvent(QResizeEvent* ev)
559{ 559{
560// printf("resize: %d,%d\n",ev->size().width(),ev->size().height()); 560// printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
561 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h); 561 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
562 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h); 562 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
563 //printf("curren: %d,%d\n",width(),height()); 563 //printf("curren: %d,%d\n",width(),height());
564HCNT("resizeEvent"); 564HCNT("resizeEvent");
565 565
566 // see comment in `paintEvent' concerning the rounding. 566 // see comment in `paintEvent' concerning the rounding.
567 //FIXME: could make a routine here; check width(),height() 567 //FIXME: could make a routine here; check width(),height()
568 assert(ev->size().width() == width()); 568 assert(ev->size().width() == width());
569 assert(ev->size().height() == height()); 569 assert(ev->size().height() == height());
570 570
571 propagateSize(); 571 propagateSize();
572} 572}
573 573
574void TEWidget::propagateSize() 574void TEWidget::propagateSize()
575{ 575{
576 ca* oldimg = image; 576 ca* oldimg = image;
577 int oldlin = lines; 577 int oldlin = lines;
578 int oldcol = columns; 578 int oldcol = columns;
579 makeImage(); 579 makeImage();
580 // we copy the old image to reduce flicker 580 // we copy the old image to reduce flicker
581 int lins = QMIN(oldlin,lines); 581 int lins = QMIN(oldlin,lines);
582 int cols = QMIN(oldcol,columns); 582 int cols = QMIN(oldcol,columns);
583 if (oldimg) 583 if (oldimg)
584 { 584 {
585 for (int lin = 0; lin < lins; lin++) 585 for (int lin = 0; lin < lins; lin++)
586 memcpy((void*)&image[columns*lin], 586 memcpy((void*)&image[columns*lin],
587 (void*)&oldimg[oldcol*lin],cols*sizeof(ca)); 587 (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
588 free(oldimg); //FIXME: try new,delete 588 free(oldimg); //FIXME: try new,delete
589 } 589 }
590 else 590 else
591 clearImage(); 591 clearImage();
592 592
593 //NOTE: control flows from the back through the chest right into the eye. 593 //NOTE: control flows from the back through the chest right into the eye.
594 // `emu' will call back via `setImage'. 594 // `emu' will call back via `setImage'.
595 595
596 resizing = TRUE; 596 resizing = TRUE;
597 emit changedImageSizeSignal(lines, columns); // expose resizeEvent 597 emit changedImageSizeSignal(lines, columns); // expose resizeEvent
598 resizing = FALSE; 598 resizing = FALSE;
599} 599}
600 600
601/* ------------------------------------------------------------------------- */ 601/* ------------------------------------------------------------------------- */
602/* */ 602/* */
603/* Scrollbar */ 603/* Scrollbar */
604/* */ 604/* */
605/* ------------------------------------------------------------------------- */ 605/* ------------------------------------------------------------------------- */
606 606
607void TEWidget::scrollChanged(int) { 607void TEWidget::scrollChanged(int) {
608 emit changedHistoryCursor(scrollbar->value()); //expose 608 emit changedHistoryCursor(scrollbar->value()); //expose
609} 609}
610 610
611void TEWidget::hScrollChanged(int loc) { 611void TEWidget::hScrollChanged(int loc) {
612 hposition = loc; 612 hposition = loc;
613 propagateSize(); 613 propagateSize();
614 update(); 614 update();
615 615
616// emit changedHorzCursor( hScrollbar->value()); //expose 616// emit changedHorzCursor( hScrollbar->value()); //expose
617} 617}
618 618
619void TEWidget::setScroll(int cursor, int slines) 619void TEWidget::setScroll(int cursor, int slines)
620{ 620{
621 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 621 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
622 scrollbar->setRange(0,slines); 622 scrollbar->setRange(0,slines);
623 scrollbar->setSteps(1,lines); 623 scrollbar->setSteps(1,lines);
624 scrollbar->setValue(cursor); 624 scrollbar->setValue(cursor);
625 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 625 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
626} 626}
627 627
628void TEWidget::setScrollbarLocation(int loc) 628void TEWidget::setScrollbarLocation(int loc)
629{ 629{
630 if (scrollLoc == loc) return; // quickly 630 if (scrollLoc == loc) return; // quickly
631 scrollLoc = loc; 631 scrollLoc = loc;
632 propagateSize(); 632 propagateSize();
633 update(); 633 update();
634} 634}
635 635
636/* ------------------------------------------------------------------------- */ 636/* ------------------------------------------------------------------------- */
637/* */ 637/* */
638/* Mouse */ 638/* Mouse */
639/* */ 639/* */
640/* ------------------------------------------------------------------------- */ 640/* ------------------------------------------------------------------------- */
641 641
642/*! 642/*!
643 Three different operations can be performed using the mouse, and the 643 Three different operations can be performed using the mouse, and the
644 routines in this section serve all of them: 644 routines in this section serve all of them:
645 645
646 1) The press/release events are exposed to the application 646 1) The press/release events are exposed to the application
647 2) Marking (press and move left button) and Pasting (press middle button) 647 2) Marking (press and move left button) and Pasting (press middle button)
648 3) The right mouse button is used from the configuration menu 648 3) The right mouse button is used from the configuration menu
649 649
650 NOTE: During the marking process we attempt to keep the cursor within 650 NOTE: During the marking process we attempt to keep the cursor within
651 the bounds of the text as being displayed by setting the mouse position 651 the bounds of the text as being displayed by setting the mouse position
652 whenever the mouse has left the text area. 652 whenever the mouse has left the text area.
653 653
654 Two reasons to do so: 654 Two reasons to do so:
655 1) QT does not allow the `grabMouse' to confine-to the TEWidget. 655 1) QT does not allow the `grabMouse' to confine-to the TEWidget.
656 Thus a `XGrapPointer' would have to be used instead. 656 Thus a `XGrapPointer' would have to be used instead.
657 2) Even if so, this would not help too much, since the text area 657 2) Even if so, this would not help too much, since the text area
658 of the TEWidget is normally not identical with it's bounds. 658 of the TEWidget is normally not identical with it's bounds.
659 659
660 The disadvantage of the current handling is, that the mouse can visibly 660 The disadvantage of the current handling is, that the mouse can visibly
661 leave the bounds of the widget and is then moved back. Because of the 661 leave the bounds of the widget and is then moved back. Because of the
662 current construction, and the reasons mentioned above, we cannot do better 662 current construction, and the reasons mentioned above, we cannot do better
663 without changing the overall construction. 663 without changing the overall construction.
664*/ 664*/
665 665
666/*! 666/*!
667*/ 667*/
668 668
669void TEWidget::mousePressEvent(QMouseEvent* ev) 669void TEWidget::mousePressEvent(QMouseEvent* ev)
670{ 670{
671//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 671//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
672 if ( !contentsRect().contains(ev->pos()) ) return; 672 if ( !contentsRect().contains(ev->pos()) ) return;
673 QPoint tL = contentsRect().topLeft(); 673 QPoint tL = contentsRect().topLeft();
674 int tLx = tL.x(); 674 int tLx = tL.x();
675 int tLy = tL.y(); 675 int tLy = tL.y();
676 676
677 word_selection_mode = FALSE; 677 word_selection_mode = FALSE;
678 678
679//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY); 679//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
680 if ( ev->button() == LeftButton) 680 if ( ev->button() == LeftButton)
681 { 681 {
682 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 682 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
683 683
684 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ; 684 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
685 685
686 if (mouse_marks || (ev->state() & ShiftButton)) 686 if (mouse_marks || (ev->state() & ShiftButton))
687 { 687 {
688 emit clearSelectionSignal(); 688 emit clearSelectionSignal();
689 iPntSel = pntSel = pos; 689 iPntSel = pntSel = pos;
690 actSel = 1; // left mouse button pressed but nothing selected yet. 690 actSel = 1; // left mouse button pressed but nothing selected yet.
691 grabMouse( /*crossCursor*/ ); // handle with care! 691 grabMouse( /*crossCursor*/ ); // handle with care!
692 } 692 }
693 else 693 else
694 { 694 {
695 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button 695 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
696 } 696 }
697 } 697 }
698 if ( ev->button() == MidButton ) 698 if ( ev->button() == MidButton )
699 { 699 {
700 emitSelection(); 700 emitSelection();
701 } 701 }
702 if ( ev->button() == RightButton ) // Configure 702 if ( ev->button() == RightButton ) // Configure
703 { 703 {
704 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() ); 704 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
705 } 705 }
706} 706}
707 707
708void TEWidget::mouseMoveEvent(QMouseEvent* ev) 708void TEWidget::mouseMoveEvent(QMouseEvent* ev)
709{ 709{
710 // for auto-hiding the cursor, we need mouseTracking 710 // for auto-hiding the cursor, we need mouseTracking
711 if (ev->state() == NoButton ) return; 711 if (ev->state() == NoButton ) return;
712 712
713 if (actSel == 0) return; 713 if (actSel == 0) return;
714 714
715 // don't extend selection while pasting 715 // don't extend selection while pasting
716 if (ev->state() & MidButton) return; 716 if (ev->state() & MidButton) return;
717 717
718 //if ( !contentsRect().contains(ev->pos()) ) return; 718 //if ( !contentsRect().contains(ev->pos()) ) return;
719 QPoint tL = contentsRect().topLeft(); 719 QPoint tL = contentsRect().topLeft();
720 int tLx = tL.x(); 720 int tLx = tL.x();
721 int tLy = tL.y(); 721 int tLy = tL.y();
722 int scroll = scrollbar->value(); 722 int scroll = scrollbar->value();
723// int hScroll = hScrollbar->value(); 723// int hScroll = hScrollbar->value();
724 724
725 // we're in the process of moving the mouse with the left button pressed 725 // we're in the process of moving the mouse with the left button pressed
726 // the mouse cursor will kept catched within the bounds of the text in 726 // the mouse cursor will kept catched within the bounds of the text in
727 // this widget. 727 // this widget.
728 728
729 // Adjust position within text area bounds. See FIXME above. 729 // Adjust position within text area bounds. See FIXME above.
730 QPoint pos = ev->pos(); 730 QPoint pos = ev->pos();
731 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX ); 731 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
732 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w ); 732 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
733 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY ); 733 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
734 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 ); 734 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
735 // check if we produce a mouse move event by this 735 // check if we produce a mouse move event by this
736 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos)); 736 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
737 737
738 if ( pos.y() == tLy+bY+lines*font_h-1 ) 738 if ( pos.y() == tLy+bY+lines*font_h-1 )
739 { 739 {
740 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward 740 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward
741 } 741 }
742 if ( pos.y() == tLy+bY ) 742 if ( pos.y() == tLy+bY )
743 { 743 {
744 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback 744 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
745 } 745 }
746 746
747 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h); 747 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
748 QPoint ohere; 748 QPoint ohere;
749 bool swapping = FALSE; 749 bool swapping = FALSE;
750 750
751 if ( word_selection_mode ) 751 if ( word_selection_mode )
752 { 752 {
753 // Extend to word boundaries 753 // Extend to word boundaries
754 int i; 754 int i;
755 int selClass; 755 int selClass;
756 756
757 bool left_not_right = ( here.y() < iPntSel.y() || 757 bool left_not_right = ( here.y() < iPntSel.y() ||
758 here.y() == iPntSel.y() && here.x() < iPntSel.x() ); 758 here.y() == iPntSel.y() && here.x() < iPntSel.x() );
759 bool old_left_not_right = ( pntSel.y() < iPntSel.y() || 759 bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
760 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() ); 760 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
761 swapping = left_not_right != old_left_not_right; 761 swapping = left_not_right != old_left_not_right;
762 762
763 // Find left (left_not_right ? from here : from start) 763 // Find left (left_not_right ? from here : from start)
764 QPoint left = left_not_right ? here : iPntSel; 764 QPoint left = left_not_right ? here : iPntSel;
765 i = loc(left.x(),left.y()); 765 i = loc(left.x(),left.y());
766 selClass = charClass(image[i].c); 766 selClass = charClass(image[i].c);
767 while ( left.x() > 0 && charClass(image[i-1].c) == selClass ) 767 while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
768 { i--; left.rx()--; } 768 { i--; left.rx()--; }
769 769
770 // Find left (left_not_right ? from start : from here) 770 // Find left (left_not_right ? from start : from here)
771 QPoint right = left_not_right ? iPntSel : here; 771 QPoint right = left_not_right ? iPntSel : here;
772 i = loc(right.x(),right.y()); 772 i = loc(right.x(),right.y());
773 selClass = charClass(image[i].c); 773 selClass = charClass(image[i].c);
774 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass ) 774 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
775 { i++; right.rx()++; } 775 { i++; right.rx()++; }
776 776
777 // Pick which is start (ohere) and which is extension (here) 777 // Pick which is start (ohere) and which is extension (here)
778 if ( left_not_right ) 778 if ( left_not_right )
779 { 779 {
780 here = left; ohere = right; 780 here = left; ohere = right;
781 } 781 }
782 else 782 else
783 { 783 {
784 here = right; ohere = left; 784 here = right; ohere = left;
785 } 785 }
786 } 786 }
787 787
788 if (here == pntSel && scroll == scrollbar->value()) return; // not moved 788 if (here == pntSel && scroll == scrollbar->value()) return; // not moved
789 789
790 if ( word_selection_mode ) { 790 if ( word_selection_mode ) {
791 if ( actSel < 2 || swapping ) { 791 if ( actSel < 2 || swapping ) {
792 emit beginSelectionSignal( ohere.x(), ohere.y() ); 792 emit beginSelectionSignal( ohere.x(), ohere.y() );
793 } 793 }
794 } else if ( actSel < 2 ) { 794 } else if ( actSel < 2 ) {
795 emit beginSelectionSignal( pntSel.x(), pntSel.y() ); 795 emit beginSelectionSignal( pntSel.x(), pntSel.y() );
796 } 796 }
797 797
798 actSel = 2; // within selection 798 actSel = 2; // within selection
799 pntSel = here; 799 pntSel = here;
800 emit extendSelectionSignal( here.x(), here.y() ); 800 emit extendSelectionSignal( here.x(), here.y() );
801} 801}
802 802
803void TEWidget::mouseReleaseEvent(QMouseEvent* ev) 803void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
804{ 804{
805//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 805//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
806 if ( ev->button() == LeftButton) 806 if ( ev->button() == LeftButton)
807 { 807 {
808 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks); 808 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
809 preserve_line_breaks = TRUE; 809 preserve_line_breaks = TRUE;
810 actSel = 0; 810 actSel = 0;
811 811
812 //FIXME: emits a release event even if the mouse is 812 //FIXME: emits a release event even if the mouse is
813 // outside the range. The procedure used in `mouseMoveEvent' 813 // outside the range. The procedure used in `mouseMoveEvent'
814 // applies here, too. 814 // applies here, too.
815 815
816 QPoint tL = contentsRect().topLeft(); 816 QPoint tL = contentsRect().topLeft();
817 int tLx = tL.x(); 817 int tLx = tL.x();
818 int tLy = tL.y(); 818 int tLy = tL.y();
819 819
820 if (!mouse_marks && !(ev->state() & ShiftButton)) 820 if (!mouse_marks && !(ev->state() & ShiftButton))
821 emit mouseSignal( 3, // release 821 emit mouseSignal( 3, // release
822 (ev->x()-tLx-blX)/font_w + 1, 822 (ev->x()-tLx-blX)/font_w + 1,
823 (ev->y()-tLy-bY)/font_h + 1 ); 823 (ev->y()-tLy-bY)/font_h + 1 );
824 releaseMouse(); 824 releaseMouse();
825 } 825 }
826} 826}
827 827
828void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev) 828void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev)
829{ 829{
830 if ( ev->button() != LeftButton) return; 830 if ( ev->button() != LeftButton) return;
831 831
832 QPoint tL = contentsRect().topLeft(); 832 QPoint tL = contentsRect().topLeft();
833 int tLx = tL.x(); 833 int tLx = tL.x();
834 int tLy = tL.y(); 834 int tLy = tL.y();
835 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 835 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
836 836
837 // pass on double click as two clicks. 837 // pass on double click as two clicks.
838 if (!mouse_marks && !(ev->state() & ShiftButton)) 838 if (!mouse_marks && !(ev->state() & ShiftButton))
839 { 839 {
840 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button 840 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
841 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release 841 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release
842 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button 842 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
843 return; 843 return;
844 } 844 }
845 845
846 846
847 emit clearSelectionSignal(); 847 emit clearSelectionSignal();
848 QPoint bgnSel = pos; 848 QPoint bgnSel = pos;
849 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 849 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
850 int i = loc(bgnSel.x(),bgnSel.y()); 850 int i = loc(bgnSel.x(),bgnSel.y());
851 iPntSel = bgnSel; 851 iPntSel = bgnSel;
852 852
853 word_selection_mode = TRUE; 853 word_selection_mode = TRUE;
854 854
855 // find word boundaries... 855 // find word boundaries...
856 int selClass = charClass(image[i].c); 856 int selClass = charClass(image[i].c);
857 { 857 {
858 // set the start... 858 // set the start...
859 int x = bgnSel.x(); 859 int x = bgnSel.x();
860 while ( x > 0 && charClass(image[i-1].c) == selClass ) 860 while ( x > 0 && charClass(image[i-1].c) == selClass )
861 { i--; x--; } 861 { i--; x--; }
862 bgnSel.setX(x); 862 bgnSel.setX(x);
863 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() ); 863 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() );
864 864
865 // set the end... 865 // set the end...
866 i = loc( endSel.x(), endSel.y() ); 866 i = loc( endSel.x(), endSel.y() );
867 x = endSel.x(); 867 x = endSel.x();
868 while( x < columns-1 && charClass(image[i+1].c) == selClass ) 868 while( x < columns-1 && charClass(image[i+1].c) == selClass )
869 { i++; x++ ; } 869 { i++; x++ ; }
870 endSel.setX(x); 870 endSel.setX(x);
871 actSel = 2; // within selection 871 actSel = 2; // within selection
872 emit extendSelectionSignal( endSel.x(), endSel.y() ); 872 emit extendSelectionSignal( endSel.x(), endSel.y() );
873 emit endSelectionSignal(preserve_line_breaks); 873 emit endSelectionSignal(preserve_line_breaks);
874 preserve_line_breaks = TRUE; 874 preserve_line_breaks = TRUE;
875 } 875 }
876} 876}
877 877
878void TEWidget::focusInEvent( QFocusEvent * ) 878void TEWidget::focusInEvent( QFocusEvent * )
879{ 879{
880 880
881 // do nothing, to prevent repainting 881 // do nothing, to prevent repainting
882} 882}
883 883
884 884
885void TEWidget::focusOutEvent( QFocusEvent * ) 885void TEWidget::focusOutEvent( QFocusEvent * )
886{ 886{
887 // do nothing, to prevent repainting 887 // do nothing, to prevent repainting
888} 888}
889 889
890bool TEWidget::focusNextPrevChild( bool next ) 890bool TEWidget::focusNextPrevChild( bool next )
891{ 891{
892 if (next) 892 if (next)
893 return false; // This disables changing the active part in konqueror 893 return false; // This disables changing the active part in konqueror
894 // when pressing Tab 894 // when pressing Tab
895 return QFrame::focusNextPrevChild( next ); 895 return QFrame::focusNextPrevChild( next );
896} 896}
897 897
898 898
899int TEWidget::charClass(char ch) const 899int TEWidget::charClass(char ch) const
900{ 900{
901 // This might seem like overkill, but imagine if ch was a Unicode 901 // This might seem like overkill, but imagine if ch was a Unicode
902 // character (Qt 2.0 QChar) - it might then be sensible to separate 902 // character (Qt 2.0 QChar) - it might then be sensible to separate
903 // the different language ranges, etc. 903 // the different language ranges, etc.
904 904
905 if ( isspace(ch) ) return ' '; 905 if ( isspace(ch) ) return ' ';
906 906
907 static const char *word_characters = ":@-./_~"; 907 static const char *word_characters = ":@-./_~";
908 if ( isalnum(ch) || strchr(word_characters, ch) ) 908 if ( isalnum(ch) || strchr(word_characters, ch) )
909 return 'a'; 909 return 'a';
910 910
911 // Everything else is weird 911 // Everything else is weird
912 return 1; 912 return 1;
913} 913}
914 914
915void TEWidget::setMouseMarks(bool on) 915void TEWidget::setMouseMarks(bool on)
916{ 916{
917 mouse_marks = on; 917 mouse_marks = on;
918 setCursor( mouse_marks ? ibeamCursor : arrowCursor ); 918 setCursor( mouse_marks ? ibeamCursor : arrowCursor );
919} 919}
920 920
921/* ------------------------------------------------------------------------- */ 921/* ------------------------------------------------------------------------- */
922/* */ 922/* */
923/* Clipboard */ 923/* Clipboard */
924/* */ 924/* */
925/* ------------------------------------------------------------------------- */ 925/* ------------------------------------------------------------------------- */
926 926
927#undef KeyPress 927#undef KeyPress
928 928
929void TEWidget::emitSelection() 929void TEWidget::emitSelection()
930// Paste Clipboard by simulating keypress events 930// Paste Clipboard by simulating keypress events
931{ 931{
932#ifndef QT_NO_CLIPBOARD 932#ifndef QT_NO_CLIPBOARD
933 QString text = QApplication::clipboard()->text(); 933 QString text = QApplication::clipboard()->text();
934 if ( ! text.isNull() ) 934 if ( ! text.isNull() )
935 { 935 {
936 text.replace(QRegExp("\n"), "\r"); 936 text.replace(QRegExp("\n"), "\r");
937 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); 937 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
938 emit keyPressedSignal(&e); // expose as a big fat keypress event 938 emit keyPressedSignal(&e); // expose as a big fat keypress event
939 emit clearSelectionSignal(); 939 emit clearSelectionSignal();
940 } 940 }
941#endif 941#endif
942} 942}
943 943
944void TEWidget::emitText(QString text) 944void TEWidget::emitText(QString text)
945{ 945{
946 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); 946 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
947 emit keyPressedSignal(&e); // expose as a big fat keypress event 947 emit keyPressedSignal(&e); // expose as a big fat keypress event
948} 948}
949 949
950void TEWidget::pasteClipboard( ) 950void TEWidget::pasteClipboard( )
951{ 951{
952 emitSelection(); 952 emitSelection();
953} 953}
954 954
955void TEWidget::setSelection(const QString& t) 955void TEWidget::setSelection(const QString& t)
956{ 956{
957#ifndef QT_NO_CLIPBOARD 957#ifndef QT_NO_CLIPBOARD
958 // Disconnect signal while WE set the clipboard 958 // Disconnect signal while WE set the clipboard
959 QObject *cb = QApplication::clipboard(); 959 QObject *cb = QApplication::clipboard();
960 QObject::disconnect( cb, SIGNAL(dataChanged()), 960 QObject::disconnect( cb, SIGNAL(dataChanged()),
961 this, SLOT(onClearSelection()) ); 961 this, SLOT(onClearSelection()) );
962 962
963 QApplication::clipboard()->setText(t); 963 QApplication::clipboard()->setText(t);
964 964
965 QObject::connect( cb, SIGNAL(dataChanged()), 965 QObject::connect( cb, SIGNAL(dataChanged()),
966 this, SLOT(onClearSelection()) ); 966 this, SLOT(onClearSelection()) );
967#endif 967#endif
968} 968}
969 969
970void TEWidget::onClearSelection() 970void TEWidget::onClearSelection()
971{ 971{
972 emit clearSelectionSignal(); 972 emit clearSelectionSignal();
973} 973}
974 974
975/* ------------------------------------------------------------------------- */ 975/* ------------------------------------------------------------------------- */
976/* */ 976/* */
977/* Keyboard */ 977/* Keyboard */
978/* */ 978/* */
979/* ------------------------------------------------------------------------- */ 979/* ------------------------------------------------------------------------- */
980 980
981//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent' 981//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent'
982// due to a bug in `QT' or the ignorance of the author to prevent 982// due to a bug in `QT' or the ignorance of the author to prevent
983// repaint events being emitted to the screen whenever one leaves 983// repaint events being emitted to the screen whenever one leaves
984// or reenters the screen to/from another application. 984// or reenters the screen to/from another application.
985// 985//
986// Troll says one needs to change focusInEvent() and focusOutEvent(), 986// Troll says one needs to change focusInEvent() and focusOutEvent(),
987// which would also let you have an in-focus cursor and an out-focus 987// which would also let you have an in-focus cursor and an out-focus
988// cursor like xterm does. 988// cursor like xterm does.
989 989
990// for the auto-hide cursor feature, I added empty focusInEvent() and 990// for the auto-hide cursor feature, I added empty focusInEvent() and
991// focusOutEvent() so that update() isn't called. 991// focusOutEvent() so that update() isn't called.
992// For auto-hide, we need to get keypress-events, but we only get them when 992// For auto-hide, we need to get keypress-events, but we only get them when
993// we have focus. 993// we have focus.
994 994
995void TEWidget::doScroll(int lines) 995void TEWidget::doScroll(int lines)
996{ 996{
997 scrollbar->setValue(scrollbar->value()+lines); 997 scrollbar->setValue(scrollbar->value()+lines);
998} 998}
999 999
1000void TEWidget::doHScroll(int lines) { 1000void TEWidget::doHScroll(int lines) {
1001 hScrollbar->setValue( hScrollbar->value()+lines); 1001 hScrollbar->setValue( hScrollbar->value()+lines);
1002} 1002}
1003 1003
1004bool TEWidget::eventFilter( QObject *obj, QEvent *e ) 1004bool TEWidget::eventFilter( QObject *obj, QEvent *e )
1005{ 1005{
1006 if ( (e->type() == QEvent::Accel || 1006 if ( (e->type() == QEvent::Accel ||
1007 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) { 1007 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) {
1008 static_cast<QKeyEvent *>( e )->ignore(); 1008 static_cast<QKeyEvent *>( e )->ignore();
1009 return true; 1009 return true;
1010 } 1010 }
1011 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ ) 1011 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ )
1012 return FALSE; // not us 1012 return FALSE; // not us
1013 if ( e->type() == QEvent::Wheel) { 1013 if ( e->type() == QEvent::Wheel) {
1014 QApplication::sendEvent(scrollbar, e); 1014 QApplication::sendEvent(scrollbar, e);
1015 } 1015 }
1016 1016
1017#ifdef FAKE_CTRL_AND_ALT 1017#ifdef FAKE_CTRL_AND_ALT
1018 static bool control = FALSE; 1018 static bool control = FALSE;
1019 static bool alt = FALSE; 1019 static bool alt = FALSE;
1020// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:"); 1020// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:");
1021 bool dele=FALSE; 1021 bool dele=FALSE;
1022 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { 1022 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
1023 QKeyEvent* ke = (QKeyEvent*)e; 1023 QKeyEvent* ke = (QKeyEvent*)e;
1024 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat(); 1024 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat();
1025 switch (ke->key()) { 1025 switch (ke->key()) {
1026 case Key_F9: // let this be "Control" 1026 case Key_F9: // let this be "Control"
1027 control = keydown; 1027 control = keydown;
1028 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state()); 1028 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
1029 dele=TRUE; 1029 dele=TRUE;
1030 break; 1030 break;
1031 case Key_F13: // let this be "Alt" 1031 case Key_F13: // let this be "Alt"
1032 alt = keydown; 1032 alt = keydown;
1033 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state()); 1033 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state());
1034 dele=TRUE; 1034 dele=TRUE;
1035 break; 1035 break;
1036 default: 1036 default:
1037 if ( control ) { 1037 if ( control ) {
1038 int a = toupper(ke->ascii())-64; 1038 int a = toupper(ke->ascii())-64;
1039 if ( a >= 0 && a < ' ' ) { 1039 if ( a >= 0 && a < ' ' ) {
1040 e = new QKeyEvent(e->type(), ke->key(), 1040 e = new QKeyEvent(e->type(), ke->key(),
1041 a, ke->state()|ControlButton, QChar(a,0)); 1041 a, ke->state()|ControlButton, QChar(a,0));
1042 dele=TRUE; 1042 dele=TRUE;
1043 } 1043 }
1044 } 1044 }
1045 if ( alt ) { 1045 if ( alt ) {
1046 e = new QKeyEvent(e->type(), ke->key(), 1046 e = new QKeyEvent(e->type(), ke->key(),
1047 ke->ascii(), ke->state()|AltButton, ke->text()); 1047 ke->ascii(), ke->state()|AltButton, ke->text());
1048 dele=TRUE; 1048 dele=TRUE;
1049 } 1049 }
1050 } 1050 }
1051 } 1051 }
1052#endif 1052#endif
1053 1053
1054 if ( e->type() == QEvent::KeyPress ) { 1054 if ( e->type() == QEvent::KeyPress ) {
1055 QKeyEvent* ke = (QKeyEvent*)e; 1055 QKeyEvent* ke = (QKeyEvent*)e;
1056 actSel=0; // Key stroke implies a screen update, so TEWidget won't 1056 actSel=0; // Key stroke implies a screen update, so TEWidget won't
1057 // know where the current selection is. 1057 // know where the current selection is.
1058 1058
1059// qDebug("key pressed is 0x%x, ascii is 0x%x, state %d", ke->key(), ke->ascii(), ke->state()); 1059// qDebug("key pressed is 0x%x, ascii is 0x%x, state %d", ke->key(), ke->ascii(), ke->state());
1060 1060
1061 if( ke->state() == ShiftButton && ke->key() == Key_Tab) { 1061 if( ke->state() == ShiftButton && ke->key() == Key_Tab) {
1062 //lets hardcode this sucker 1062 //lets hardcode this sucker
1063 1063
1064// qDebug("key pressed 2 is 0x%x", ke->key()); 1064// qDebug("key pressed 2 is 0x%x", ke->key());
1065 emitText("\\"); // expose 1065 emitText("\\"); // expose
1066 } 1066 }
1067 else if( ke->state() == ControlButton && ke->key() == Key_V) { 1067 else if( ke->state() == ControlButton && ke->key() == Key_V) {
1068 pasteClipboard(); 1068 pasteClipboard();
1069 } 1069 }
1070 else 1070 else
1071 emit keyPressedSignal(ke); // expose 1071 emit keyPressedSignal(ke); // expose
1072 ke->accept(); 1072 ke->accept();
1073#ifdef FAKE_CTRL_AND_ALT 1073#ifdef FAKE_CTRL_AND_ALT
1074 if ( dele ) delete e; 1074 if ( dele ) delete e;
1075#endif 1075#endif
1076 return true; // stop the event 1076 return true; // stop the event
1077 } 1077 }
1078 if ( e->type() == QEvent::Enter ) { 1078 if ( e->type() == QEvent::Enter ) {
1079 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()), 1079 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
1080 this, SLOT(onClearSelection()) ); 1080 this, SLOT(onClearSelection()) );
1081 } 1081 }
1082 if ( e->type() == QEvent::Leave ) { 1082 if ( e->type() == QEvent::Leave ) {
1083 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), 1083 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
1084 this, SLOT(onClearSelection()) ); 1084 this, SLOT(onClearSelection()) );
1085 } 1085 }
1086 return QFrame::eventFilter( obj, e ); 1086 return QFrame::eventFilter( obj, e );
1087} 1087}
1088 1088
1089/* ------------------------------------------------------------------------- */ 1089/* ------------------------------------------------------------------------- */
1090/* */ 1090/* */
1091/* Frame */ 1091/* Frame */
1092/* */ 1092/* */
1093/* ------------------------------------------------------------------------- */ 1093/* ------------------------------------------------------------------------- */
1094 1094
1095void TEWidget::frameChanged() 1095void TEWidget::frameChanged()
1096{ 1096{
1097 propagateSize(); 1097 propagateSize();
1098 update(); 1098 update();
1099} 1099}
1100 1100
1101/* ------------------------------------------------------------------------- */ 1101/* ------------------------------------------------------------------------- */
1102/* */ 1102/* */
1103/* Sound */ 1103/* Sound */
1104/* */ 1104/* */
1105/* ------------------------------------------------------------------------- */ 1105/* ------------------------------------------------------------------------- */
1106 1106
1107void TEWidget::Bell() 1107void TEWidget::Bell()
1108{ 1108{
1109//#ifdef QT_QWS_SHARP 1109//#ifdef QT_QWS_SHARP
1110//# ifndef QT_NO_COP 1110//# ifndef QT_NO_COP
1111 if(useBeep) 1111 if(useBeep)
1112 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" ); 1112 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
1113 1113
1114//# endif 1114//# endif
1115//#else 1115//#else
1116//# ifndef QT_NO_SOUND 1116//# ifndef QT_NO_SOUND
1117// QSound::play(Resource::findSound("alarm")); 1117// QSound::play(Resource::findSound("alarm"));
1118//# endif 1118//# endif
1119//#endif 1119//#endif
1120 1120
1121// QApplication::beep(); 1121// QApplication::beep();
1122} 1122}
1123 1123
1124/* ------------------------------------------------------------------------- */ 1124/* ------------------------------------------------------------------------- */
1125/* */ 1125/* */
1126/* Auxiluary */ 1126/* Auxiluary */
1127/* */ 1127/* */
1128/* ------------------------------------------------------------------------- */ 1128/* ------------------------------------------------------------------------- */
1129 1129
1130void TEWidget::clearImage() 1130void TEWidget::clearImage()
1131// initialize the image 1131// initialize the image
1132// for internal use only 1132// for internal use only
1133{ 1133{
1134 for (int y = 0; y < lines; y++) 1134 for (int y = 0; y < lines; y++)
1135 for (int x = 0; x < columns; x++) 1135 for (int x = 0; x < columns; x++)
1136 { 1136 {
1137 image[loc(x,y)].c = 0xff; //' '; 1137 image[loc(x,y)].c = 0xff; //' ';
1138 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR; 1138 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR;
1139 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR; 1139 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
1140 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION; 1140 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
1141 } 1141 }
1142} 1142}
1143 1143
1144// Create Image /////////////////////////////////////////////////////// 1144// Create Image ///////////////////////////////////////////////////////
1145 1145
1146void TEWidget::calcGeometry() 1146void TEWidget::calcGeometry()
1147{ 1147{
1148 int showhscrollbar = 1; 1148 int showhscrollbar = 1;
1149 int hwidth = 0; 1149 int hwidth = 0;
1150 int dcolumns; 1150 int dcolumns;
1151 Config cfg("Konsole"); 1151 Config cfg("Konsole");
1152 cfg.setGroup("ScrollBar"); 1152 cfg.setGroup("ScrollBar");
1153 useHorzScroll=cfg.readBoolEntry("HorzScroll",0); 1153 useHorzScroll=cfg.readBoolEntry("HorzScroll",0);
1154 1154
1155 if(vcolumns == 0) showhscrollbar = 0; 1155 if(vcolumns == 0) showhscrollbar = 0;
1156 if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width(); 1156 if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width();
1157 1157
1158 scrollbar->resize(QApplication::style().scrollBarExtent().width(), 1158 scrollbar->resize(QApplication::style().scrollBarExtent().width(),
1159 contentsRect().height() - hwidth); 1159 contentsRect().height() - hwidth);
1160 1160
1161 switch(scrollLoc) { 1161 switch(scrollLoc) {
1162 case SCRNONE : 1162 case SCRNONE :
1163 columns = ( contentsRect().width() - 2 * rimX ) / font_w; 1163 columns = ( contentsRect().width() - 2 * rimX ) / font_w;
1164 dcolumns = columns; 1164 dcolumns = columns;
1165 if(vcolumns) columns = vcolumns; 1165 if(vcolumns) columns = vcolumns;
1166 blX = (contentsRect().width() - (columns*font_w) ) / 2; 1166 blX = (contentsRect().width() - (columns*font_w) ) / 2;
1167 if(showhscrollbar) 1167 if(showhscrollbar)
1168 blX = -hposition * font_w; 1168 blX = -hposition * font_w;
1169 brX = blX; 1169 brX = blX;
1170 scrollbar->hide(); 1170 scrollbar->hide();
1171 break; 1171 break;
1172 case SCRLEFT : 1172 case SCRLEFT :
1173 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; 1173 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1174 dcolumns = columns; 1174 dcolumns = columns;
1175 if(vcolumns) columns = vcolumns; 1175 if(vcolumns) columns = vcolumns;
1176 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; 1176 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1177 if(showhscrollbar) 1177 if(showhscrollbar)
1178 brX = -hposition * font_w; 1178 brX = -hposition * font_w;
1179 blX = brX + scrollbar->width(); 1179 blX = brX + scrollbar->width();
1180 scrollbar->move(contentsRect().topLeft()); 1180 scrollbar->move(contentsRect().topLeft());
1181 scrollbar->show(); 1181 scrollbar->show();
1182 break; 1182 break;
1183 case SCRRIGHT: 1183 case SCRRIGHT:
1184 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; 1184 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1185 dcolumns = columns; 1185 dcolumns = columns;
1186 if(vcolumns) columns = vcolumns; 1186 if(vcolumns) columns = vcolumns;
1187 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; 1187 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1188 if(showhscrollbar) 1188 if(showhscrollbar)
1189 blX = -hposition * font_w; 1189 blX = -hposition * font_w;
1190 brX = blX; 1190 brX = blX;
1191 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0)); 1191 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
1192 scrollbar->show(); 1192 scrollbar->show();
1193 break; 1193 break;
1194 } 1194 }
1195 //FIXME: support 'rounding' styles 1195 //FIXME: support 'rounding' styles
1196 lines = ( contentsRect().height() - 2 * rimY ) / font_h; 1196 lines = ( contentsRect().height() - 2 * rimY ) / font_h;
1197 bY = (contentsRect().height() - (lines *font_h)) / 2; 1197 bY = (contentsRect().height() - (lines *font_h)) / 2;
1198 1198
1199 if(showhscrollbar == 1) { 1199 if(showhscrollbar == 1) {
1200 hScrollbar->resize(contentsRect().width() - hwidth, hwidth); 1200 hScrollbar->resize(contentsRect().width() - hwidth, hwidth);
1201 hScrollbar->setRange(0, vcolumns - dcolumns); 1201 hScrollbar->setRange(0, vcolumns - dcolumns);
1202 1202
1203 QPoint p = contentsRect().bottomLeft(); 1203 QPoint p = contentsRect().bottomLeft();
1204 hScrollbar->move(QPoint(p.x(), p.y() - hwidth)); 1204 if(scrollLoc == SCRLEFT)
1205 hScrollbar->move(QPoint(p.x()+hwidth, p.y() - hwidth));
1206 else
1207 hScrollbar->move(QPoint(p.x(), p.y() - hwidth));
1208
1205 hScrollbar->show(); 1209 hScrollbar->show();
1206 } 1210 }
1207 else hScrollbar->hide(); 1211 else hScrollbar->hide();
1208 1212
1209 if(showhscrollbar == 1) { 1213 if(showhscrollbar == 1) {
1210 lines = lines - (hwidth / font_h) - 1; 1214 lines = lines - (hwidth / font_h) - 1;
1211 if(lines < 1) lines = 1; 1215 if(lines < 1) lines = 1;
1212 } 1216 }
1213 //FIXME: support 'rounding' styles 1217 //FIXME: support 'rounding' styles
1214} 1218}
1215 1219
1216void TEWidget::makeImage() 1220void TEWidget::makeImage()
1217//FIXME: rename 'calcGeometry? 1221//FIXME: rename 'calcGeometry?
1218{ 1222{
1219 calcGeometry(); 1223 calcGeometry();
1220 image = (ca*) malloc(lines*columns*sizeof(ca)); 1224 image = (ca*) malloc(lines*columns*sizeof(ca));
1221 clearImage(); 1225 clearImage();
1222} 1226}
1223 1227
1224// calculate the needed size 1228// calculate the needed size
1225QSize TEWidget::calcSize(int cols, int lins) const 1229QSize TEWidget::calcSize(int cols, int lins) const
1226{ 1230{
1227 int frw = width() - contentsRect().width(); 1231 int frw = width() - contentsRect().width();
1228 int frh = height() - contentsRect().height(); 1232 int frh = height() - contentsRect().height();
1229 int scw = (scrollLoc==SCRNONE?0:scrollbar->width()); 1233 int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
1230 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh ); 1234 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
1231} 1235}
1232 1236
1233QSize TEWidget::sizeHint() const 1237QSize TEWidget::sizeHint() const
1234{ 1238{
1235 return size(); 1239 return size();
1236} 1240}
1237 1241
1238void TEWidget::styleChange(QStyle &) 1242void TEWidget::styleChange(QStyle &)
1239{ 1243{
1240 propagateSize(); 1244 propagateSize();
1241} 1245}
1242 1246
1243#ifndef QT_NO_DRAGANDDROP 1247#ifndef QT_NO_DRAGANDDROP
1244 1248
1245/* --------------------------------------------------------------------- */ 1249/* --------------------------------------------------------------------- */
1246/* */ 1250/* */
1247/* Drag & Drop */ 1251/* Drag & Drop */
1248/* */ 1252/* */
1249/* --------------------------------------------------------------------- */ 1253/* --------------------------------------------------------------------- */
1250 1254
1251 1255
1252void TEWidget::dragEnterEvent(QDragEnterEvent* e) 1256void TEWidget::dragEnterEvent(QDragEnterEvent* e)
1253{ 1257{
1254 e->accept(QTextDrag::canDecode(e) || 1258 e->accept(QTextDrag::canDecode(e) ||
1255 QUriDrag::canDecode(e)); 1259 QUriDrag::canDecode(e));
1256} 1260}
1257 1261
1258void TEWidget::dropEvent(QDropEvent* event) 1262void TEWidget::dropEvent(QDropEvent* event)
1259{ 1263{
1260 // The current behaviour when url(s) are dropped is 1264 // The current behaviour when url(s) are dropped is
1261 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd 1265 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
1262 // * in all other cases, just paste 1266 // * in all other cases, just paste
1263 // (for non-local ones, or for a list of URLs, 'cd' is nonsense) 1267 // (for non-local ones, or for a list of URLs, 'cd' is nonsense)
1264 QStrList strlist; 1268 QStrList strlist;
1265 int file_count = 0; 1269 int file_count = 0;
1266 dropText = ""; 1270 dropText = "";
1267 bool bPopup = true; 1271 bool bPopup = true;
1268 1272
1269 if(QUriDrag::decode(event, strlist)) { 1273 if(QUriDrag::decode(event, strlist)) {
1270 if (strlist.count()) { 1274 if (strlist.count()) {
1271 for(const char* p = strlist.first(); p; p = strlist.next()) { 1275 for(const char* p = strlist.first(); p; p = strlist.next()) {
1272 if(file_count++ > 0) { 1276 if(file_count++ > 0) {
1273 dropText += " "; 1277 dropText += " ";
1274 bPopup = false; // more than one file, don't popup 1278 bPopup = false; // more than one file, don't popup
1275 } 1279 }
1276 1280
1277/* 1281/*
1278 KURL url(p); 1282 KURL url(p);
1279 if (url.isLocalFile()) { 1283 if (url.isLocalFile()) {
1280 dropText += url.path(); // local URL : remove protocol 1284 dropText += url.path(); // local URL : remove protocol
1281 } 1285 }
1282 else { 1286 else {
1283 dropText += url.prettyURL(); 1287 dropText += url.prettyURL();
1284 bPopup = false; // a non-local file, don't popup 1288 bPopup = false; // a non-local file, don't popup
1285 } 1289 }
1286*/ 1290*/
1287 1291
1288 } 1292 }
1289 1293
1290 if (bPopup) 1294 if (bPopup)
1291 // m_drop->popup(pos() + event->pos()); 1295 // m_drop->popup(pos() + event->pos());
1292 m_drop->popup(mapToGlobal(event->pos())); 1296 m_drop->popup(mapToGlobal(event->pos()));
1293 else 1297 else
1294 { 1298 {
1295 if (currentSession) { 1299 if (currentSession) {
1296 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1300 currentSession->getEmulation()->sendString(dropText.local8Bit());
1297 } 1301 }
1298// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1302// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1299 } 1303 }
1300 } 1304 }
1301 } 1305 }
1302 else if(QTextDrag::decode(event, dropText)) { 1306 else if(QTextDrag::decode(event, dropText)) {
1303// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1307// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1304 if (currentSession) { 1308 if (currentSession) {
1305 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1309 currentSession->getEmulation()->sendString(dropText.local8Bit());
1306 } 1310 }
1307 // Paste it 1311 // Paste it
1308 } 1312 }
1309} 1313}
1310#endif 1314#endif
1311 1315
1312 1316
1313void TEWidget::drop_menu_activated(int item) 1317void TEWidget::drop_menu_activated(int item)
1314{ 1318{
1315#ifndef QT_NO_DRAGANDDROP 1319#ifndef QT_NO_DRAGANDDROP
1316 switch (item) 1320 switch (item)
1317 { 1321 {
1318 case 0: // paste 1322 case 0: // paste
1319 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1323 currentSession->getEmulation()->sendString(dropText.local8Bit());
1320// KWM::activate((Window)this->winId()); 1324// KWM::activate((Window)this->winId());
1321 break; 1325 break;
1322 case 1: // cd ... 1326 case 1: // cd ...
1323 currentSession->getEmulation()->sendString("cd "); 1327 currentSession->getEmulation()->sendString("cd ");
1324 struct stat statbuf; 1328 struct stat statbuf;
1325 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 ) 1329 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
1326 { 1330 {
1327 if ( !S_ISDIR(statbuf.st_mode) ) 1331 if ( !S_ISDIR(statbuf.st_mode) )
1328 { 1332 {
1329/* 1333/*
1330 KURL url; 1334 KURL url;
1331 url.setPath( dropText ); 1335 url.setPath( dropText );
1332 dropText = url.directory( true, false ); // remove filename 1336 dropText = url.directory( true, false ); // remove filename
1333*/ 1337*/
1334 } 1338 }
1335 } 1339 }
1336 dropText.replace(QRegExp(" "), "\\ "); // escape spaces 1340 dropText.replace(QRegExp(" "), "\\ "); // escape spaces
1337 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1341 currentSession->getEmulation()->sendString(dropText.local8Bit());
1338 currentSession->getEmulation()->sendString("\n"); 1342 currentSession->getEmulation()->sendString("\n");
1339// KWM::activate((Window)this->winId()); 1343// KWM::activate((Window)this->winId());
1340 break; 1344 break;
1341 } 1345 }
1342#endif 1346#endif
1343} 1347}
1344 1348
1345void TEWidget::setWrapAt(int columns) 1349void TEWidget::setWrapAt(int columns)
1346{ 1350{
1347 vcolumns = columns; 1351 vcolumns = columns;
1348 propagateSize(); 1352 propagateSize();
1349 update(); 1353 update();
1350} 1354}