summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/TEWidget.cpp6
1 files changed, 6 insertions, 0 deletions
diff --git a/noncore/apps/opie-console/TEWidget.cpp b/noncore/apps/opie-console/TEWidget.cpp
index bf9a313..2db214c 100644
--- a/noncore/apps/opie-console/TEWidget.cpp
+++ b/noncore/apps/opie-console/TEWidget.cpp
@@ -1,1349 +1,1355 @@
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 <qapplication.h> 55#include <qapplication.h>
56#include <qcursor.h> 56#include <qcursor.h>
57#include <qregexp.h> 57#include <qregexp.h>
58#include <qpainter.h> 58#include <qpainter.h>
59#include <qclipboard.h> 59#include <qclipboard.h>
60#include <qstyle.h> 60#include <qstyle.h>
61#include <qfile.h> 61#include <qfile.h>
62#include <qdragobject.h> 62#include <qdragobject.h>
63#include <qvbox.h> 63#include <qvbox.h>
64 64
65#include <stdio.h> 65#include <stdio.h>
66#include <stdlib.h> 66#include <stdlib.h>
67#include <unistd.h> 67#include <unistd.h>
68#include <ctype.h> 68#include <ctype.h>
69#include <sys/stat.h> 69#include <sys/stat.h>
70#include <sys/types.h> 70#include <sys/types.h>
71#include <signal.h> 71#include <signal.h>
72 72
73#include <assert.h> 73#include <assert.h>
74 74
75 75
76 76
77// #include "TEWidget.moc" 77// #include "TEWidget.moc"
78//#include <kapp.h> 78//#include <kapp.h>
79//#include <kcursor.h> 79//#include <kcursor.h>
80//#include <kurl.h> 80//#include <kurl.h>
81//#include <kdebug.h> 81//#include <kdebug.h>
82//#include <klocale.h> 82//#include <klocale.h>
83 83
84#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__) 84#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__)
85#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); } 85#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); }
86 86
87#define loc(X,Y) ((Y)*columns+(X)) 87#define loc(X,Y) ((Y)*columns+(X))
88 88
89//FIXME: the rim should normally be 1, 0 only when running in full screen mode. 89//FIXME: the rim should normally be 1, 0 only when running in full screen mode.
90#define rimX 0 // left/right rim width 90#define rimX 0 // left/right rim width
91#define rimY 0 // top/bottom rim high 91#define rimY 0 // top/bottom rim high
92 92
93#define yMouseScroll 1 93#define yMouseScroll 1
94// scroll increment used when dragging selection at top/bottom of window. 94// scroll increment used when dragging selection at top/bottom of window.
95 95
96/* Button XPM */ 96/* Button XPM */
97namespace { 97namespace {
98static char * menu_xpm[] = { 98static char * menu_xpm[] = {
99"12 12 5 1", 99"12 12 5 1",
100 " c None", 100 " c None",
101 ".c #000000", 101 ".c #000000",
102 "+c #FFFDAD", 102 "+c #FFFDAD",
103 "@c #FFFF00", 103 "@c #FFFF00",
104 "#c #E5E100", 104 "#c #E5E100",
105" ", 105" ",
106" ", 106" ",
107" ......... ", 107" ......... ",
108" .+++++++. ", 108" .+++++++. ",
109" .+@@@@#. ", 109" .+@@@@#. ",
110" .+@@@#. ", 110" .+@@@#. ",
111" .+@@#. ", 111" .+@@#. ",
112" .+@#. ", 112" .+@#. ",
113" .+#. ", 113" .+#. ",
114" .+. ", 114" .+. ",
115" .. ", 115" .. ",
116" "}; 116" "};
117 117
118} 118}
119 119
120 120
121/* ------------------------------------------------------------------------- */ 121/* ------------------------------------------------------------------------- */
122/* */ 122/* */
123/* Colors */ 123/* Colors */
124/* */ 124/* */
125/* ------------------------------------------------------------------------- */ 125/* ------------------------------------------------------------------------- */
126 126
127//FIXME: the default color table is in session.C now. 127//FIXME: the default color table is in session.C now.
128// We need a way to get rid of this one, here. 128// We need a way to get rid of this one, here.
129static const ColorEntry base_color_table[TABLE_COLORS] = 129static const ColorEntry base_color_table[TABLE_COLORS] =
130// The following are almost IBM standard color codes, with some slight 130// The following are almost IBM standard color codes, with some slight
131// gamma correction for the dim colors to compensate for bright X screens. 131// gamma correction for the dim colors to compensate for bright X screens.
132// It contains the 8 ansiterm/xterm colors in 2 intensities. 132// It contains the 8 ansiterm/xterm colors in 2 intensities.
133{ 133{
134 // Fixme: could add faint colors here, also. 134 // Fixme: could add faint colors here, also.
135 // normal 135 // normal
136 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback 136 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback
137 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red 137 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red
138 ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow 138 ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow
139 ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta 139 ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta
140 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White 140 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White
141 // intensiv 141 // intensiv
142 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ), 142 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
143 ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ), 143 ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
144 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ), 144 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
145 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), 145 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ),
146 ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 ) 146 ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
147}; 147};
148 148
149/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb) 149/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb)
150 150
151 Code 0 1 2 3 4 5 6 7 151 Code 0 1 2 3 4 5 6 7
152 ----------- ------- ------- ------- ------- ------- ------- ------- ------- 152 ----------- ------- ------- ------- ------- ------- ------- ------- -------
153 ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White 153 ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White
154 IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White 154 IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White
155*/ 155*/
156 156
157QColor TEWidget::getDefaultBackColor() 157QColor TEWidget::getDefaultBackColor()
158{ 158{
159 return color_table[DEFAULT_BACK_COLOR].color; 159 return color_table[DEFAULT_BACK_COLOR].color;
160} 160}
161 161
162const ColorEntry* TEWidget::getColorTable() const 162const ColorEntry* TEWidget::getColorTable() const
163{ 163{
164 return color_table; 164 return color_table;
165} 165}
166 166
167const ColorEntry* TEWidget::getdefaultColorTable() const 167const ColorEntry* TEWidget::getdefaultColorTable() const
168{ 168{
169 return base_color_table; 169 return base_color_table;
170} 170}
171 171
172 172
173const QPixmap *TEWidget::backgroundPixmap() 173const QPixmap *TEWidget::backgroundPixmap()
174{ 174{
175 static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm"); 175 static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm");
176 const QPixmap *pm = bg; 176 const QPixmap *pm = bg;
177 return pm; 177 return pm;
178} 178}
179 179
180void TEWidget::setColorTable(const ColorEntry table[]) 180void TEWidget::setColorTable(const ColorEntry table[])
181{ 181{
182 for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i]; 182 for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i];
183 183
184 const QPixmap* pm = backgroundPixmap(); 184 const QPixmap* pm = backgroundPixmap();
185 if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color); 185 if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color);
186 update(); 186 update();
187} 187}
188 188
189//FIXME: add backgroundPixmapChanged. 189//FIXME: add backgroundPixmapChanged.
190 190
191/* ------------------------------------------------------------------------- */ 191/* ------------------------------------------------------------------------- */
192/* */ 192/* */
193/* Font */ 193/* Font */
194/* */ 194/* */
195/* ------------------------------------------------------------------------- */ 195/* ------------------------------------------------------------------------- */
196 196
197/* 197/*
198 The VT100 has 32 special graphical characters. The usual vt100 extended 198 The VT100 has 32 special graphical characters. The usual vt100 extended
199 xterm fonts have these at 0x00..0x1f. 199 xterm fonts have these at 0x00..0x1f.
200 200
201 QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals 201 QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals
202 come in here as proper unicode characters. 202 come in here as proper unicode characters.
203 203
204 We treat non-iso10646 fonts as VT100 extended and do the requiered mapping 204 We treat non-iso10646 fonts as VT100 extended and do the requiered mapping
205 from unicode to 0x00..0x1f. The remaining translation is then left to the 205 from unicode to 0x00..0x1f. The remaining translation is then left to the
206 QCodec. 206 QCodec.
207*/ 207*/
208 208
209// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i. 209// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i.
210 210
211unsigned short vt100_graphics[32] = 211unsigned short vt100_graphics[32] =
212{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15 212{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15
213 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 213 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0,
214 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 214 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
215 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534, 215 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534,
216 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7 216 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7
217}; 217};
218 218
219static QChar vt100extended(QChar c) 219static QChar vt100extended(QChar c)
220{ 220{
221 switch (c.unicode()) 221 switch (c.unicode())
222 { 222 {
223 case 0x25c6 : return 1; 223 case 0x25c6 : return 1;
224 case 0x2592 : return 2; 224 case 0x2592 : return 2;
225 case 0x2409 : return 3; 225 case 0x2409 : return 3;
226 case 0x240c : return 4; 226 case 0x240c : return 4;
227 case 0x240d : return 5; 227 case 0x240d : return 5;
228 case 0x240a : return 6; 228 case 0x240a : return 6;
229 case 0x00b0 : return 7; 229 case 0x00b0 : return 7;
230 case 0x00b1 : return 8; 230 case 0x00b1 : return 8;
231 case 0x2424 : return 9; 231 case 0x2424 : return 9;
232 case 0x240b : return 10; 232 case 0x240b : return 10;
233 case 0x2518 : return 11; 233 case 0x2518 : return 11;
234 case 0x2510 : return 12; 234 case 0x2510 : return 12;
235 case 0x250c : return 13; 235 case 0x250c : return 13;
236 case 0x2514 : return 14; 236 case 0x2514 : return 14;
237 case 0x253c : return 15; 237 case 0x253c : return 15;
238 case 0xf800 : return 16; 238 case 0xf800 : return 16;
239 case 0xf801 : return 17; 239 case 0xf801 : return 17;
240 case 0x2500 : return 18; 240 case 0x2500 : return 18;
241 case 0xf803 : return 19; 241 case 0xf803 : return 19;
242 case 0xf804 : return 20; 242 case 0xf804 : return 20;
243 case 0x251c : return 21; 243 case 0x251c : return 21;
244 case 0x2524 : return 22; 244 case 0x2524 : return 22;
245 case 0x2534 : return 23; 245 case 0x2534 : return 23;
246 case 0x252c : return 24; 246 case 0x252c : return 24;
247 case 0x2502 : return 25; 247 case 0x2502 : return 25;
248 case 0x2264 : return 26; 248 case 0x2264 : return 26;
249 case 0x2265 : return 27; 249 case 0x2265 : return 27;
250 case 0x03c0 : return 28; 250 case 0x03c0 : return 28;
251 case 0x2260 : return 29; 251 case 0x2260 : return 29;
252 case 0x00a3 : return 30; 252 case 0x00a3 : return 30;
253 case 0x00b7 : return 31; 253 case 0x00b7 : return 31;
254 } 254 }
255 return c; 255 return c;
256} 256}
257 257
258static QChar identicalMap(QChar c) 258static QChar identicalMap(QChar c)
259{ 259{
260 return c; 260 return c;
261} 261}
262 262
263void TEWidget::fontChange(const QFont &) 263void TEWidget::fontChange(const QFont &)
264{ 264{
265 QFontMetrics fm(font()); 265 QFontMetrics fm(font());
266 font_h = fm.height(); 266 font_h = fm.height();
267 font_w = fm.maxWidth(); 267 font_w = fm.maxWidth();
268 font_a = fm.ascent(); 268 font_a = fm.ascent();
269//printf("font_h: %d\n",font_h); 269//printf("font_h: %d\n",font_h);
270//printf("font_w: %d\n",font_w); 270//printf("font_w: %d\n",font_w);
271//printf("font_a: %d\n",font_a); 271//printf("font_a: %d\n",font_a);
272//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii()); 272//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii());
273//printf("rawname: %s\n",font().rawName().ascii()); 273//printf("rawname: %s\n",font().rawName().ascii());
274 fontMap = 274 fontMap =
275#if QT_VERSION < 300 275#if QT_VERSION < 300
276 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646") 276 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646")
277 ? vt100extended 277 ? vt100extended
278 : 278 :
279#endif 279#endif
280 identicalMap; 280 identicalMap;
281 propagateSize(); 281 propagateSize();
282 update(); 282 update();
283} 283}
284 284
285void TEWidget::setVTFont(const QFont& f) 285void TEWidget::setVTFont(const QFont& f)
286{ 286{
287 QFrame::setFont(f); 287 QFrame::setFont(f);
288} 288}
289 289
290QFont TEWidget::getVTFont() { 290QFont TEWidget::getVTFont() {
291 return font(); 291 return font();
292} 292}
293 293
294void TEWidget::setFont(const QFont &) 294void TEWidget::setFont(const QFont &)
295{ 295{
296 // ignore font change request if not coming from konsole itself 296 // ignore font change request if not coming from konsole itself
297} 297}
298 298
299/* ------------------------------------------------------------------------- */ 299/* ------------------------------------------------------------------------- */
300/* */ 300/* */
301/* Constructor / Destructor */ 301/* Constructor / Destructor */
302/* */ 302/* */
303/* ----------------------------------------------------------------------- */ 303/* ----------------------------------------------------------------------- */
304 304
305 305
306 306
307TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name) 307TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name)
308{ 308{
309#ifndef QT_NO_CLIPBOARD 309#ifndef QT_NO_CLIPBOARD
310 cb = QApplication::clipboard(); 310 cb = QApplication::clipboard();
311 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), 311 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
312 this, SLOT(onClearSelection()) ); 312 this, SLOT(onClearSelection()) );
313#endif 313#endif
314 314
315 315
316 scrollbar = new QScrollBar( this ); 316 scrollbar = new QScrollBar( this );
317 scrollbar->setCursor( arrowCursor ); 317 scrollbar->setCursor( arrowCursor );
318 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 318 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
319 319
320 hscrollbar = new QScrollBar( Qt::Horizontal, this ); 320 hscrollbar = new QScrollBar( Qt::Horizontal, this );
321 hscrollbar->setCursor( arrowCursor ); 321 hscrollbar->setCursor( arrowCursor );
322 connect(hscrollbar, SIGNAL(valueChanged(int)), this, SLOT(hscrollChanged(int))); 322 connect(hscrollbar, SIGNAL(valueChanged(int)), this, SLOT(hscrollChanged(int)));
323 323
324 m_cornerButton = new QPushButton( this ); 324 m_cornerButton = new QPushButton( this );
325 m_cornerButton->setPixmap( QPixmap( (const char**)menu_xpm ) ); 325 m_cornerButton->setPixmap( QPixmap( (const char**)menu_xpm ) );
326 m_cornerButton->setMaximumSize( 14, 14 ); 326 m_cornerButton->setMaximumSize( 14, 14 );
327 m_cornerButton->hide(); 327 m_cornerButton->hide();
328 328
329 Config cfg("Konsole"); 329 Config cfg("Konsole");
330 cfg.setGroup("ScrollBar"); 330 cfg.setGroup("ScrollBar");
331 switch( cfg.readNumEntry("Position",2)){ 331 switch( cfg.readNumEntry("Position",2)){
332 case 0: 332 case 0:
333 scrollLoc = SCRNONE; 333 scrollLoc = SCRNONE;
334 break; 334 break;
335 case 1: 335 case 1:
336 scrollLoc = SCRLEFT; 336 scrollLoc = SCRLEFT;
337 break; 337 break;
338 case 2: 338 case 2:
339 scrollLoc = SCRRIGHT; 339 scrollLoc = SCRRIGHT;
340 break; 340 break;
341 }; 341 };
342 342
343 blinkT = new QTimer(this); 343 blinkT = new QTimer(this);
344 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent())); 344 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent()));
345 // blinking = FALSE; 345 // blinking = FALSE;
346 blinking = TRUE; 346 blinking = TRUE;
347 347
348 resizing = FALSE; 348 resizing = FALSE;
349 actSel = 0; 349 actSel = 0;
350 image = 0; 350 image = 0;
351 lines = 1; 351 lines = 1;
352 columns = 1; 352 columns = 1;
353 font_w = 1; 353 font_w = 1;
354 font_h = 1; 354 font_h = 1;
355 font_a = 1; 355 font_a = 1;
356 word_selection_mode = FALSE; 356 word_selection_mode = FALSE;
357 vcolumns = 0; 357 vcolumns = 0;
358 358
359 setMouseMarks(TRUE); 359 setMouseMarks(TRUE);
360 setVTFont( QFont("fixed") ); 360 setVTFont( QFont("fixed") );
361 setColorTable(base_color_table); // init color table 361 setColorTable(base_color_table); // init color table
362 362
363 qApp->installEventFilter( this ); //FIXME: see below 363 qApp->installEventFilter( this ); //FIXME: see below
364// KCursor::setAutoHideCursor( this, true ); 364// KCursor::setAutoHideCursor( this, true );
365 365
366 // Init DnD //////////////////////////////////////////////////////////////// 366 // Init DnD ////////////////////////////////////////////////////////////////
367 currentSession = NULL; 367 currentSession = NULL;
368// setAcceptDrops(true); // attempt 368// setAcceptDrops(true); // attempt
369// m_drop = new QPopupMenu(this); 369// m_drop = new QPopupMenu(this);
370// m_drop->insertItem( QString("Paste"), 0); 370// m_drop->insertItem( QString("Paste"), 0);
371// m_drop->insertItem( QString("cd"), 1); 371// m_drop->insertItem( QString("cd"), 1);
372// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int))); 372// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int)));
373 373
374 // we need focus so that the auto-hide cursor feature works 374 // we need focus so that the auto-hide cursor feature works
375 setFocus(); 375 setFocus();
376 setFocusPolicy( WheelFocus ); 376 setFocusPolicy( WheelFocus );
377} 377}
378 378
379//FIXME: make proper destructor 379//FIXME: make proper destructor
380// Here's a start (David) 380// Here's a start (David)
381TEWidget::~TEWidget() 381TEWidget::~TEWidget()
382{ 382{
383 qApp->removeEventFilter( this ); 383 qApp->removeEventFilter( this );
384 if (image) free(image); 384 if (image) free(image);
385} 385}
386 386
387/* ------------------------------------------------------------------------- */ 387/* ------------------------------------------------------------------------- */
388/* */ 388/* */
389/* Display Operations */ 389/* Display Operations */
390/* */ 390/* */
391/* ------------------------------------------------------------------------- */ 391/* ------------------------------------------------------------------------- */
392 392
393/*! 393/*!
394 attributed string draw primitive 394 attributed string draw primitive
395*/ 395*/
396 396
397void TEWidget::drawAttrStr(QPainter &paint, QRect rect, 397void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
398 QString& str, ca attr, BOOL pm, BOOL clear) 398 QString& str, ca attr, BOOL pm, BOOL clear)
399{ 399{
400 if (pm && color_table[attr.b].transparent) 400 if (pm && color_table[attr.b].transparent)
401 { 401 {
402 paint.setBackgroundMode( TransparentMode ); 402 paint.setBackgroundMode( TransparentMode );
403 if (clear) erase(rect); 403 if (clear) erase(rect);
404 } 404 }
405 else 405 else
406 { 406 {
407 if (blinking) 407 if (blinking)
408 paint.fillRect(rect, color_table[attr.b].color); 408 paint.fillRect(rect, color_table[attr.b].color);
409 else 409 else
410 { 410 {
411 paint.setBackgroundMode( OpaqueMode ); 411 paint.setBackgroundMode( OpaqueMode );
412 paint.setBackgroundColor( color_table[attr.b].color ); 412 paint.setBackgroundColor( color_table[attr.b].color );
413 } 413 }
414 } 414 }
415 415
416 if (color_table[attr.f].bold) 416 if (color_table[attr.f].bold)
417 paint.setPen(QColor( 0x8F, 0x00, 0x00 )); 417 paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
418 else 418 else
419 paint.setPen(color_table[attr.f].color); 419 paint.setPen(color_table[attr.f].color);
420 420
421 paint.drawText(rect.x(),rect.y()+font_a, str); 421 paint.drawText(rect.x(),rect.y()+font_a, str);
422 422
423 if (attr.r & RE_UNDERLINE) 423 if (attr.r & RE_UNDERLINE)
424 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 ); 424 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
425} 425}
426 426
427/*! 427/*!
428 The image can only be set completely. 428 The image can only be set completely.
429 429
430 The size of the new image may or may not match the size of the widget. 430 The size of the new image may or may not match the size of the widget.
431*/ 431*/
432 432
433void TEWidget::setImage(const ca* const newimg, int lines, int columns) 433void TEWidget::setImage(const ca* const newimg, int lines, int columns)
434{ int y,x,len; 434{ int y,x,len;
435 const QPixmap* pm = backgroundPixmap(); 435 const QPixmap* pm = backgroundPixmap();
436 QPainter paint; 436 QPainter paint;
437 setUpdatesEnabled(FALSE); 437 setUpdatesEnabled(FALSE);
438 paint.begin( this ); 438 paint.begin( this );
439HCNT("setImage"); 439HCNT("setImage");
440 440
441 QPoint tL = contentsRect().topLeft(); 441 QPoint tL = contentsRect().topLeft();
442 int tLx = tL.x(); 442 int tLx = tL.x();
443 int tLy = tL.y(); 443 int tLy = tL.y();
444 hasBlinker = FALSE; 444 hasBlinker = FALSE;
445 445
446 int cf = -1; // undefined 446 int cf = -1; // undefined
447 int cb = -1; // undefined 447 int cb = -1; // undefined
448 int cr = -1; // undefined 448 int cr = -1; // undefined
449 449
450 int lins = QMIN(this->lines, QMAX(0,lines )); 450 int lins = QMIN(this->lines, QMAX(0,lines ));
451 int cols = QMIN(this->columns,QMAX(0,columns)); 451 int cols = QMIN(this->columns,QMAX(0,columns));
452 QChar *disstrU = new QChar[cols]; 452 QChar *disstrU = new QChar[cols];
453 453
454//{ static int cnt = 0; printf("setImage %d\n",cnt++); } 454//{ static int cnt = 0; printf("setImage %d\n",cnt++); }
455 for (y = 0; y < lins; y++) 455 for (y = 0; y < lins; y++)
456 { 456 {
457 const ca* lcl = &image[y*this->columns]; 457 const ca* lcl = &image[y*this->columns];
458 const ca* const ext = &newimg[y*columns]; 458 const ca* const ext = &newimg[y*columns];
459 if (!resizing) // not while resizing, we're expecting a paintEvent 459 if (!resizing) // not while resizing, we're expecting a paintEvent
460 for (x = 0; x < cols; x++) 460 for (x = 0; x < cols; x++)
461 { 461 {
462 hasBlinker |= (ext[x].r & RE_BLINK); 462 hasBlinker |= (ext[x].r & RE_BLINK);
463 if (ext[x] != lcl[x]) 463 if (ext[x] != lcl[x])
464 { 464 {
465 cr = ext[x].r; 465 cr = ext[x].r;
466 cb = ext[x].b; 466 cb = ext[x].b;
467 if (ext[x].f != cf) cf = ext[x].f; 467 if (ext[x].f != cf) cf = ext[x].f;
468 int lln = cols - x; 468 int lln = cols - x;
469 disstrU[0] = fontMap(ext[x+0].c); 469 disstrU[0] = fontMap(ext[x+0].c);
470 for (len = 1; len < lln; len++) 470 for (len = 1; len < lln; len++)
471 { 471 {
472 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || 472 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
473 ext[x+len] == lcl[x+len] ) 473 ext[x+len] == lcl[x+len] )
474 break; 474 break;
475 disstrU[len] = fontMap(ext[x+len].c); 475 disstrU[len] = fontMap(ext[x+len].c);
476 } 476 }
477 QString unistr(disstrU,len); 477 QString unistr(disstrU,len);
478 drawAttrStr(paint, 478 drawAttrStr(paint,
479 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 479 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
480 unistr, ext[x], pm != NULL, true); 480 unistr, ext[x], pm != NULL, true);
481 x += len - 1; 481 x += len - 1;
482 } 482 }
483 } 483 }
484 // finally, make `image' become `newimg'. 484 // finally, make `image' become `newimg'.
485 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca)); 485 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
486 } 486 }
487 drawFrame( &paint ); 487 drawFrame( &paint );
488 paint.end(); 488 paint.end();
489 setUpdatesEnabled(TRUE); 489 setUpdatesEnabled(TRUE);
490 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms 490 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms
491 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; } 491 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
492 delete [] disstrU; 492 delete [] disstrU;
493} 493}
494 494
495// paint Event //////////////////////////////////////////////////// 495// paint Event ////////////////////////////////////////////////////
496 496
497/*! 497/*!
498 The difference of this routine vs. the `setImage' is, 498 The difference of this routine vs. the `setImage' is,
499 that the drawing does not include a difference analysis 499 that the drawing does not include a difference analysis
500 between the old and the new image. Instead, the internal 500 between the old and the new image. Instead, the internal
501 image is used and the painting bound by the PaintEvent box. 501 image is used and the painting bound by the PaintEvent box.
502*/ 502*/
503 503
504void TEWidget::paintEvent( QPaintEvent* pe ) 504void TEWidget::paintEvent( QPaintEvent* pe )
505{ 505{
506 506
507//{ static int cnt = 0; printf("paint %d\n",cnt++); } 507//{ static int cnt = 0; printf("paint %d\n",cnt++); }
508 const QPixmap* pm = backgroundPixmap(); 508 const QPixmap* pm = backgroundPixmap();
509 QPainter paint; 509 QPainter paint;
510 setUpdatesEnabled(FALSE); 510 setUpdatesEnabled(FALSE);
511 paint.begin( this ); 511 paint.begin( this );
512 paint.setBackgroundMode( TransparentMode ); 512 paint.setBackgroundMode( TransparentMode );
513HCNT("paintEvent"); 513HCNT("paintEvent");
514 514
515 // Note that the actual widget size can be slightly larger 515 // Note that the actual widget size can be slightly larger
516 // that the image (the size is truncated towards the smaller 516 // that the image (the size is truncated towards the smaller
517 // number of characters in `resizeEvent'. The paint rectangle 517 // number of characters in `resizeEvent'. The paint rectangle
518 // can thus be larger than the image, but less then the size 518 // can thus be larger than the image, but less then the size
519 // of one character. 519 // of one character.
520 520
521 QRect rect = pe->rect().intersect(contentsRect()); 521 QRect rect = pe->rect().intersect(contentsRect());
522 522
523 QPoint tL = contentsRect().topLeft(); 523 QPoint tL = contentsRect().topLeft();
524 int tLx = tL.x(); 524 int tLx = tL.x();
525 int tLy = tL.y(); 525 int tLy = tL.y();
526 526
527 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w)); 527 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w));
528 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h)); 528 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h));
529 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w)); 529 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w));
530 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h)); 530 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h));
531 531
532 /* 532 /*
533 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly, 533 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly,
534 rect.left(), rect.right(), rect.top(), rect.bottom()); 534 rect.left(), rect.right(), rect.top(), rect.bottom());
535 */ 535 */
536 536
537 // if (pm != NULL && color_table[image->b].transparent) 537 // if (pm != NULL && color_table[image->b].transparent)
538 // erase(rect); 538 // erase(rect);
539 // BL: I have no idea why we need this, and it breaks the refresh. 539 // BL: I have no idea why we need this, and it breaks the refresh.
540 540
541 QChar *disstrU = new QChar[columns]; 541 QChar *disstrU = new QChar[columns];
542 for (int y = luy; y <= rly; y++) 542 for (int y = luy; y <= rly; y++)
543 for (int x = lux; x <= rlx; x++) 543 for (int x = lux; x <= rlx; x++)
544 { 544 {
545 int len = 1; 545 int len = 1;
546 disstrU[0] = fontMap(image[loc(x,y)].c); 546 disstrU[0] = fontMap(image[loc(x,y)].c);
547 int cf = image[loc(x,y)].f; 547 int cf = image[loc(x,y)].f;
548 int cb = image[loc(x,y)].b; 548 int cb = image[loc(x,y)].b;
549 int cr = image[loc(x,y)].r; 549 int cr = image[loc(x,y)].r;
550 while (x+len <= rlx && 550 while (x+len <= rlx &&
551 image[loc(x+len,y)].f == cf && 551 image[loc(x+len,y)].f == cf &&
552 image[loc(x+len,y)].b == cb && 552 image[loc(x+len,y)].b == cb &&
553 image[loc(x+len,y)].r == cr ) 553 image[loc(x+len,y)].r == cr )
554 { 554 {
555 disstrU[len] = fontMap(image[loc(x+len,y)].c); 555 disstrU[len] = fontMap(image[loc(x+len,y)].c);
556 len += 1; 556 len += 1;
557 } 557 }
558 QString unistr(disstrU,len); 558 QString unistr(disstrU,len);
559 drawAttrStr(paint, 559 drawAttrStr(paint,
560 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 560 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
561 unistr, image[loc(x,y)], pm != NULL, false); 561 unistr, image[loc(x,y)], pm != NULL, false);
562 x += len - 1; 562 x += len - 1;
563 } 563 }
564 delete [] disstrU; 564 delete [] disstrU;
565 drawFrame( &paint ); 565 drawFrame( &paint );
566 paint.end(); 566 paint.end();
567 setUpdatesEnabled(TRUE); 567 setUpdatesEnabled(TRUE);
568} 568}
569 569
570void TEWidget::blinkEvent() 570void TEWidget::blinkEvent()
571{ 571{
572 blinking = !blinking; 572 blinking = !blinking;
573 repaint(FALSE); 573 repaint(FALSE);
574} 574}
575 575
576/* ------------------------------------------------------------------------- */ 576/* ------------------------------------------------------------------------- */
577/* */ 577/* */
578/* Resizing */ 578/* Resizing */
579/* */ 579/* */
580/* ------------------------------------------------------------------------- */ 580/* ------------------------------------------------------------------------- */
581 581
582void TEWidget::resizeEvent(QResizeEvent* ev) 582void TEWidget::resizeEvent(QResizeEvent* ev)
583{ 583{
584// printf("resize: %d,%d\n",ev->size().width(),ev->size().height()); 584// printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
585 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h); 585 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
586 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h); 586 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
587 //printf("curren: %d,%d\n",width(),height()); 587 //printf("curren: %d,%d\n",width(),height());
588HCNT("resizeEvent"); 588HCNT("resizeEvent");
589 589
590 // see comment in `paintEvent' concerning the rounding. 590 // see comment in `paintEvent' concerning the rounding.
591 //FIXME: could make a routine here; check width(),height() 591 //FIXME: could make a routine here; check width(),height()
592 assert(ev->size().width() == width()); 592 assert(ev->size().width() == width());
593 assert(ev->size().height() == height()); 593 assert(ev->size().height() == height());
594 594
595 propagateSize(); 595 propagateSize();
596} 596}
597 597
598void TEWidget::propagateSize() 598void TEWidget::propagateSize()
599{ 599{
600 ca* oldimg = image; 600 ca* oldimg = image;
601 int oldlin = lines; 601 int oldlin = lines;
602 int oldcol = columns; 602 int oldcol = columns;
603 makeImage(); 603 makeImage();
604 // we copy the old image to reduce flicker 604 // we copy the old image to reduce flicker
605 int lins = QMIN(oldlin,lines); 605 int lins = QMIN(oldlin,lines);
606 int cols = QMIN(oldcol,columns); 606 int cols = QMIN(oldcol,columns);
607 if (oldimg) 607 if (oldimg)
608 { 608 {
609 for (int lin = 0; lin < lins; lin++) 609 for (int lin = 0; lin < lins; lin++)
610 memcpy((void*)&image[columns*lin], 610 memcpy((void*)&image[columns*lin],
611 (void*)&oldimg[oldcol*lin],cols*sizeof(ca)); 611 (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
612 free(oldimg); //FIXME: try new,delete 612 free(oldimg); //FIXME: try new,delete
613 } 613 }
614 else 614 else
615 clearImage(); 615 clearImage();
616 616
617 //NOTE: control flows from the back through the chest right into the eye. 617 //NOTE: control flows from the back through the chest right into the eye.
618 // `emu' will call back via `setImage'. 618 // `emu' will call back via `setImage'.
619 619
620 resizing = TRUE; 620 resizing = TRUE;
621 emit changedImageSizeSignal(lines, columns); // expose resizeEvent 621 emit changedImageSizeSignal(lines, columns); // expose resizeEvent
622 resizing = FALSE; 622 resizing = FALSE;
623} 623}
624 624
625/* ------------------------------------------------------------------------- */ 625/* ------------------------------------------------------------------------- */
626/* */ 626/* */
627/* Scrollbar */ 627/* Scrollbar */
628/* */ 628/* */
629/* ------------------------------------------------------------------------- */ 629/* ------------------------------------------------------------------------- */
630 630
631void TEWidget::scrollChanged(int) 631void TEWidget::scrollChanged(int)
632{ 632{
633 emit changedHistoryCursor(scrollbar->value()); //expose 633 emit changedHistoryCursor(scrollbar->value()); //expose
634} 634}
635 635
636void TEWidget::hscrollChanged(int loc) 636void TEWidget::hscrollChanged(int loc)
637{ 637{
638 hposition = loc; 638 hposition = loc;
639 propagateSize(); 639 propagateSize();
640 update(); 640 update();
641} 641}
642 642
643void TEWidget::setScroll(int cursor, int slines) 643void TEWidget::setScroll(int cursor, int slines)
644{ 644{
645 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 645 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
646 scrollbar->setRange(0,slines); 646 scrollbar->setRange(0,slines);
647 scrollbar->setSteps(1,lines); 647 scrollbar->setSteps(1,lines);
648 scrollbar->setValue(cursor); 648 scrollbar->setValue(cursor);
649 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 649 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
650} 650}
651 651
652void TEWidget::setScrollbarLocation(int loc) 652void TEWidget::setScrollbarLocation(int loc)
653{ 653{
654 if (scrollLoc == loc) return; // quickly 654 if (scrollLoc == loc) return; // quickly
655 scrollLoc = loc; 655 scrollLoc = loc;
656 propagateSize(); 656 propagateSize();
657 update(); 657 update();
658} 658}
659 659
660/* ------------------------------------------------------------------------- */ 660/* ------------------------------------------------------------------------- */
661/* */ 661/* */
662/* Mouse */ 662/* Mouse */
663/* */ 663/* */
664/* ------------------------------------------------------------------------- */ 664/* ------------------------------------------------------------------------- */
665 665
666/*! 666/*!
667 Three different operations can be performed using the mouse, and the 667 Three different operations can be performed using the mouse, and the
668 routines in this section serve all of them: 668 routines in this section serve all of them:
669 669
670 1) The press/release events are exposed to the application 670 1) The press/release events are exposed to the application
671 2) Marking (press and move left button) and Pasting (press middle button) 671 2) Marking (press and move left button) and Pasting (press middle button)
672 3) The right mouse button is used from the configuration menu 672 3) The right mouse button is used from the configuration menu
673 673
674 NOTE: During the marking process we attempt to keep the cursor within 674 NOTE: During the marking process we attempt to keep the cursor within
675 the bounds of the text as being displayed by setting the mouse position 675 the bounds of the text as being displayed by setting the mouse position
676 whenever the mouse has left the text area. 676 whenever the mouse has left the text area.
677 677
678 Two reasons to do so: 678 Two reasons to do so:
679 1) QT does not allow the `grabMouse' to confine-to the TEWidget. 679 1) QT does not allow the `grabMouse' to confine-to the TEWidget.
680 Thus a `XGrapPointer' would have to be used instead. 680 Thus a `XGrapPointer' would have to be used instead.
681 2) Even if so, this would not help too much, since the text area 681 2) Even if so, this would not help too much, since the text area
682 of the TEWidget is normally not identical with it's bounds. 682 of the TEWidget is normally not identical with it's bounds.
683 683
684 The disadvantage of the current handling is, that the mouse can visibly 684 The disadvantage of the current handling is, that the mouse can visibly
685 leave the bounds of the widget and is then moved back. Because of the 685 leave the bounds of the widget and is then moved back. Because of the
686 current construction, and the reasons mentioned above, we cannot do better 686 current construction, and the reasons mentioned above, we cannot do better
687 without changing the overall construction. 687 without changing the overall construction.
688*/ 688*/
689 689
690/*! 690/*!
691*/ 691*/
692 692
693void TEWidget::mousePressEvent(QMouseEvent* ev) 693void TEWidget::mousePressEvent(QMouseEvent* ev)
694{ 694{
695//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 695//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
696 if ( !contentsRect().contains(ev->pos()) ) return; 696 if ( !contentsRect().contains(ev->pos()) ) return;
697 QPoint tL = contentsRect().topLeft(); 697 QPoint tL = contentsRect().topLeft();
698 int tLx = tL.x(); 698 int tLx = tL.x();
699 int tLy = tL.y(); 699 int tLy = tL.y();
700 700
701 word_selection_mode = FALSE; 701 word_selection_mode = FALSE;
702 702
703//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY); 703//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
704 if ( ev->button() == LeftButton) 704 if ( ev->button() == LeftButton)
705 { 705 {
706 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 706 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
707 707
708 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ; 708 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
709 709
710 if (mouse_marks || (ev->state() & ShiftButton)) 710 if (mouse_marks || (ev->state() & ShiftButton))
711 { 711 {
712 emit clearSelectionSignal(); 712 emit clearSelectionSignal();
713 iPntSel = pntSel = pos; 713 iPntSel = pntSel = pos;
714 actSel = 1; // left mouse button pressed but nothing selected yet. 714 actSel = 1; // left mouse button pressed but nothing selected yet.
715 grabMouse( /*crossCursor*/ ); // handle with care! 715 grabMouse( /*crossCursor*/ ); // handle with care!
716 } 716 }
717 else 717 else
718 { 718 {
719 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button 719 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
720 } 720 }
721 } 721 }
722 if ( ev->button() == MidButton ) 722 if ( ev->button() == MidButton )
723 { 723 {
724 emitSelection(); 724 emitSelection();
725 } 725 }
726 if ( ev->button() == RightButton ) // Configure 726 if ( ev->button() == RightButton ) // Configure
727 { 727 {
728 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() ); 728 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
729 } 729 }
730} 730}
731 731
732void TEWidget::mouseMoveEvent(QMouseEvent* ev) 732void TEWidget::mouseMoveEvent(QMouseEvent* ev)
733{ 733{
734 // for auto-hiding the cursor, we need mouseTracking 734 // for auto-hiding the cursor, we need mouseTracking
735 if (ev->state() == NoButton ) return; 735 if (ev->state() == NoButton ) return;
736 736
737 if (actSel == 0) return; 737 if (actSel == 0) return;
738 738
739 // don't extend selection while pasting 739 // don't extend selection while pasting
740 if (ev->state() & MidButton) return; 740 if (ev->state() & MidButton) return;
741 741
742 //if ( !contentsRect().contains(ev->pos()) ) return; 742 //if ( !contentsRect().contains(ev->pos()) ) return;
743 QPoint tL = contentsRect().topLeft(); 743 QPoint tL = contentsRect().topLeft();
744 int tLx = tL.x(); 744 int tLx = tL.x();
745 int tLy = tL.y(); 745 int tLy = tL.y();
746 int scroll = scrollbar->value(); 746 int scroll = scrollbar->value();
747 747
748 // we're in the process of moving the mouse with the left button pressed 748 // we're in the process of moving the mouse with the left button pressed
749 // the mouse cursor will kept catched within the bounds of the text in 749 // the mouse cursor will kept catched within the bounds of the text in
750 // this widget. 750 // this widget.
751 751
752 // Adjust position within text area bounds. See FIXME above. 752 // Adjust position within text area bounds. See FIXME above.
753 QPoint pos = ev->pos(); 753 QPoint pos = ev->pos();
754 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX ); 754 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
755 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w ); 755 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
756 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY ); 756 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
757 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 ); 757 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
758 // check if we produce a mouse move event by this 758 // check if we produce a mouse move event by this
759 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos)); 759 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
760 760
761 if ( pos.y() == tLy+bY+lines*font_h-1 ) 761 if ( pos.y() == tLy+bY+lines*font_h-1 )
762 { 762 {
763 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward 763 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward
764 } 764 }
765 if ( pos.y() == tLy+bY ) 765 if ( pos.y() == tLy+bY )
766 { 766 {
767 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback 767 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
768 } 768 }
769 769
770 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h); 770 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
771 QPoint ohere; 771 QPoint ohere;
772 bool swapping = FALSE; 772 bool swapping = FALSE;
773 773
774 if ( word_selection_mode ) 774 if ( word_selection_mode )
775 { 775 {
776 // Extend to word boundaries 776 // Extend to word boundaries
777 int i; 777 int i;
778 int selClass; 778 int selClass;
779 779
780 bool left_not_right = ( here.y() < iPntSel.y() || 780 bool left_not_right = ( here.y() < iPntSel.y() ||
781 here.y() == iPntSel.y() && here.x() < iPntSel.x() ); 781 here.y() == iPntSel.y() && here.x() < iPntSel.x() );
782 bool old_left_not_right = ( pntSel.y() < iPntSel.y() || 782 bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
783 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() ); 783 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
784 swapping = left_not_right != old_left_not_right; 784 swapping = left_not_right != old_left_not_right;
785 785
786 // Find left (left_not_right ? from here : from start) 786 // Find left (left_not_right ? from here : from start)
787 QPoint left = left_not_right ? here : iPntSel; 787 QPoint left = left_not_right ? here : iPntSel;
788 i = loc(left.x(),left.y()); 788 i = loc(left.x(),left.y());
789 selClass = charClass(image[i].c); 789 selClass = charClass(image[i].c);
790 while ( left.x() > 0 && charClass(image[i-1].c) == selClass ) 790 while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
791 { i--; left.rx()--; } 791 { i--; left.rx()--; }
792 792
793 // Find left (left_not_right ? from start : from here) 793 // Find left (left_not_right ? from start : from here)
794 QPoint right = left_not_right ? iPntSel : here; 794 QPoint right = left_not_right ? iPntSel : here;
795 i = loc(right.x(),right.y()); 795 i = loc(right.x(),right.y());
796 selClass = charClass(image[i].c); 796 selClass = charClass(image[i].c);
797 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass ) 797 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
798 { i++; right.rx()++; } 798 { i++; right.rx()++; }
799 799
800 // Pick which is start (ohere) and which is extension (here) 800 // Pick which is start (ohere) and which is extension (here)
801 if ( left_not_right ) 801 if ( left_not_right )
802 { 802 {
803 here = left; ohere = right; 803 here = left; ohere = right;
804 } 804 }
805 else 805 else
806 { 806 {
807 here = right; ohere = left; 807 here = right; ohere = left;
808 } 808 }
809 } 809 }
810 810
811 if (here == pntSel && scroll == scrollbar->value()) return; // not moved 811 if (here == pntSel && scroll == scrollbar->value()) return; // not moved
812 812
813 if ( word_selection_mode ) { 813 if ( word_selection_mode ) {
814 if ( actSel < 2 || swapping ) { 814 if ( actSel < 2 || swapping ) {
815 emit beginSelectionSignal( ohere.x(), ohere.y() ); 815 emit beginSelectionSignal( ohere.x(), ohere.y() );
816 } 816 }
817 } else if ( actSel < 2 ) { 817 } else if ( actSel < 2 ) {
818 emit beginSelectionSignal( pntSel.x(), pntSel.y() ); 818 emit beginSelectionSignal( pntSel.x(), pntSel.y() );
819 } 819 }
820 820
821 actSel = 2; // within selection 821 actSel = 2; // within selection
822 pntSel = here; 822 pntSel = here;
823 emit extendSelectionSignal( here.x(), here.y() ); 823 emit extendSelectionSignal( here.x(), here.y() );
824} 824}
825 825
826void TEWidget::mouseReleaseEvent(QMouseEvent* ev) 826void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
827{ 827{
828//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 828//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
829 if ( ev->button() == LeftButton) 829 if ( ev->button() == LeftButton)
830 { 830 {
831 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks); 831 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
832 preserve_line_breaks = TRUE; 832 preserve_line_breaks = TRUE;
833 actSel = 0; 833 actSel = 0;
834 834
835 //FIXME: emits a release event even if the mouse is 835 //FIXME: emits a release event even if the mouse is
836 // outside the range. The procedure used in `mouseMoveEvent' 836 // outside the range. The procedure used in `mouseMoveEvent'
837 // applies here, too. 837 // applies here, too.
838 838
839 QPoint tL = contentsRect().topLeft(); 839 QPoint tL = contentsRect().topLeft();
840 int tLx = tL.x(); 840 int tLx = tL.x();
841 int tLy = tL.y(); 841 int tLy = tL.y();
842 842
843 if (!mouse_marks && !(ev->state() & ShiftButton)) 843 if (!mouse_marks && !(ev->state() & ShiftButton))
844 emit mouseSignal( 3, // release 844 emit mouseSignal( 3, // release
845 (ev->x()-tLx-blX)/font_w + 1, 845 (ev->x()-tLx-blX)/font_w + 1,
846 (ev->y()-tLy-bY)/font_h + 1 ); 846 (ev->y()-tLy-bY)/font_h + 1 );
847 releaseMouse(); 847 releaseMouse();
848 } 848 }
849} 849}
850 850
851void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev) 851void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev)
852{ 852{
853 if ( ev->button() != LeftButton) return; 853 if ( ev->button() != LeftButton) return;
854 854
855 QPoint tL = contentsRect().topLeft(); 855 QPoint tL = contentsRect().topLeft();
856 int tLx = tL.x(); 856 int tLx = tL.x();
857 int tLy = tL.y(); 857 int tLy = tL.y();
858 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 858 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
859 859
860 // pass on double click as two clicks. 860 // pass on double click as two clicks.
861 if (!mouse_marks && !(ev->state() & ShiftButton)) 861 if (!mouse_marks && !(ev->state() & ShiftButton))
862 { 862 {
863 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button 863 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
864 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release 864 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release
865 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button 865 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
866 return; 866 return;
867 } 867 }
868 868
869 869
870 emit clearSelectionSignal(); 870 emit clearSelectionSignal();
871 QPoint bgnSel = pos; 871 QPoint bgnSel = pos;
872 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 872 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
873 int i = loc(bgnSel.x(),bgnSel.y()); 873 int i = loc(bgnSel.x(),bgnSel.y());
874 iPntSel = bgnSel; 874 iPntSel = bgnSel;
875 875
876 word_selection_mode = TRUE; 876 word_selection_mode = TRUE;
877 877
878 // find word boundaries... 878 // find word boundaries...
879 int selClass = charClass(image[i].c); 879 int selClass = charClass(image[i].c);
880 { 880 {
881 // set the start... 881 // set the start...
882 int x = bgnSel.x(); 882 int x = bgnSel.x();
883 while ( x > 0 && charClass(image[i-1].c) == selClass ) 883 while ( x > 0 && charClass(image[i-1].c) == selClass )
884 { i--; x--; } 884 { i--; x--; }
885 bgnSel.setX(x); 885 bgnSel.setX(x);
886 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() ); 886 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() );
887 887
888 // set the end... 888 // set the end...
889 i = loc( endSel.x(), endSel.y() ); 889 i = loc( endSel.x(), endSel.y() );
890 x = endSel.x(); 890 x = endSel.x();
891 while( x < columns-1 && charClass(image[i+1].c) == selClass ) 891 while( x < columns-1 && charClass(image[i+1].c) == selClass )
892 { i++; x++ ; } 892 { i++; x++ ; }
893 endSel.setX(x); 893 endSel.setX(x);
894 actSel = 2; // within selection 894 actSel = 2; // within selection
895 emit extendSelectionSignal( endSel.x(), endSel.y() ); 895 emit extendSelectionSignal( endSel.x(), endSel.y() );
896 emit endSelectionSignal(preserve_line_breaks); 896 emit endSelectionSignal(preserve_line_breaks);
897 preserve_line_breaks = TRUE; 897 preserve_line_breaks = TRUE;
898 } 898 }
899} 899}
900 900
901void TEWidget::focusInEvent( QFocusEvent * ) 901void TEWidget::focusInEvent( QFocusEvent * )
902{ 902{
903 903
904 // do nothing, to prevent repainting 904 // do nothing, to prevent repainting
905} 905}
906 906
907 907
908void TEWidget::focusOutEvent( QFocusEvent * ) 908void TEWidget::focusOutEvent( QFocusEvent * )
909{ 909{
910 // do nothing, to prevent repainting 910 // do nothing, to prevent repainting
911} 911}
912 912
913bool TEWidget::focusNextPrevChild( bool next ) 913bool TEWidget::focusNextPrevChild( bool next )
914{ 914{
915 if (next) 915 if (next)
916 return false; // This disables changing the active part in konqueror 916 return false; // This disables changing the active part in konqueror
917 // when pressing Tab 917 // when pressing Tab
918 return QFrame::focusNextPrevChild( next ); 918 return QFrame::focusNextPrevChild( next );
919} 919}
920 920
921 921
922int TEWidget::charClass(char ch) const 922int TEWidget::charClass(char ch) const
923{ 923{
924 // This might seem like overkill, but imagine if ch was a Unicode 924 // This might seem like overkill, but imagine if ch was a Unicode
925 // character (Qt 2.0 QChar) - it might then be sensible to separate 925 // character (Qt 2.0 QChar) - it might then be sensible to separate
926 // the different language ranges, etc. 926 // the different language ranges, etc.
927 927
928 if ( isspace(ch) ) return ' '; 928 if ( isspace(ch) ) return ' ';
929 929
930 static const char *word_characters = ":@-./_~"; 930 static const char *word_characters = ":@-./_~";
931 if ( isalnum(ch) || strchr(word_characters, ch) ) 931 if ( isalnum(ch) || strchr(word_characters, ch) )
932 return 'a'; 932 return 'a';
933 933
934 // Everything else is weird 934 // Everything else is weird
935 return 1; 935 return 1;
936} 936}
937 937
938void TEWidget::setMouseMarks(bool on) 938void TEWidget::setMouseMarks(bool on)
939{ 939{
940 mouse_marks = on; 940 mouse_marks = on;
941 setCursor( mouse_marks ? ibeamCursor : arrowCursor ); 941 setCursor( mouse_marks ? ibeamCursor : arrowCursor );
942} 942}
943 943
944/* ------------------------------------------------------------------------- */ 944/* ------------------------------------------------------------------------- */
945/* */ 945/* */
946/* Clipboard */ 946/* Clipboard */
947/* */ 947/* */
948/* ------------------------------------------------------------------------- */ 948/* ------------------------------------------------------------------------- */
949 949
950#undef KeyPress 950#undef KeyPress
951 951
952void TEWidget::emitSelection() 952void TEWidget::emitSelection()
953// Paste Clipboard by simulating keypress events 953// Paste Clipboard by simulating keypress events
954{ 954{
955#ifndef QT_NO_CLIPBOARD 955#ifndef QT_NO_CLIPBOARD
956 QString text = QApplication::clipboard()->text(); 956 QString text = QApplication::clipboard()->text();
957 if ( ! text.isNull() ) 957 if ( ! text.isNull() )
958 { 958 {
959 text.replace(QRegExp("\n"), "\r"); 959 text.replace(QRegExp("\n"), "\r");
960 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); 960 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
961 emit keyPressedSignal(&e); // expose as a big fat keypress event 961 emit keyPressedSignal(&e); // expose as a big fat keypress event
962 emit clearSelectionSignal(); 962 emit clearSelectionSignal();
963 } 963 }
964#endif 964#endif
965} 965}
966 966
967void TEWidget::emitText(QString text) 967void TEWidget::emitText(QString text)
968{ 968{
969 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); 969 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
970 emit keyPressedSignal(&e); // expose as a big fat keypress event 970 emit keyPressedSignal(&e); // expose as a big fat keypress event
971} 971}
972 972
973void TEWidget::pasteClipboard( ) 973void TEWidget::pasteClipboard( )
974{ 974{
975 emitSelection(); 975 emitSelection();
976} 976}
977 977
978void TEWidget::setSelection(const QString& t) 978void TEWidget::setSelection(const QString& t)
979{ 979{
980#ifndef QT_NO_CLIPBOARD 980#ifndef QT_NO_CLIPBOARD
981 // Disconnect signal while WE set the clipboard 981 // Disconnect signal while WE set the clipboard
982 QObject *cb = QApplication::clipboard(); 982 QObject *cb = QApplication::clipboard();
983 QObject::disconnect( cb, SIGNAL(dataChanged()), 983 QObject::disconnect( cb, SIGNAL(dataChanged()),
984 this, SLOT(onClearSelection()) ); 984 this, SLOT(onClearSelection()) );
985 985
986 QApplication::clipboard()->setText(t); 986 QApplication::clipboard()->setText(t);
987 987
988 QObject::connect( cb, SIGNAL(dataChanged()), 988 QObject::connect( cb, SIGNAL(dataChanged()),
989 this, SLOT(onClearSelection()) ); 989 this, SLOT(onClearSelection()) );
990#endif 990#endif
991} 991}
992 992
993void TEWidget::onClearSelection() 993void TEWidget::onClearSelection()
994{ 994{
995 emit clearSelectionSignal(); 995 emit clearSelectionSignal();
996} 996}
997 997
998/* ------------------------------------------------------------------------- */ 998/* ------------------------------------------------------------------------- */
999/* */ 999/* */
1000/* Keyboard */ 1000/* Keyboard */
1001/* */ 1001/* */
1002/* ------------------------------------------------------------------------- */ 1002/* ------------------------------------------------------------------------- */
1003 1003
1004//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent' 1004//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent'
1005// due to a bug in `QT' or the ignorance of the author to prevent 1005// due to a bug in `QT' or the ignorance of the author to prevent
1006// repaint events being emitted to the screen whenever one leaves 1006// repaint events being emitted to the screen whenever one leaves
1007// or reenters the screen to/from another application. 1007// or reenters the screen to/from another application.
1008// 1008//
1009// Troll says one needs to change focusInEvent() and focusOutEvent(), 1009// Troll says one needs to change focusInEvent() and focusOutEvent(),
1010// which would also let you have an in-focus cursor and an out-focus 1010// which would also let you have an in-focus cursor and an out-focus
1011// cursor like xterm does. 1011// cursor like xterm does.
1012 1012
1013// for the auto-hide cursor feature, I added empty focusInEvent() and 1013// for the auto-hide cursor feature, I added empty focusInEvent() and
1014// focusOutEvent() so that update() isn't called. 1014// focusOutEvent() so that update() isn't called.
1015// For auto-hide, we need to get keypress-events, but we only get them when 1015// For auto-hide, we need to get keypress-events, but we only get them when
1016// we have focus. 1016// we have focus.
1017 1017
1018void TEWidget::doScroll(int lines) 1018void TEWidget::doScroll(int lines)
1019{ 1019{
1020 scrollbar->setValue(scrollbar->value()+lines); 1020 scrollbar->setValue(scrollbar->value()+lines);
1021} 1021}
1022 1022
1023bool TEWidget::eventFilter( QObject *obj, QEvent *e ) 1023bool TEWidget::eventFilter( QObject *obj, QEvent *e )
1024{ 1024{
1025 if ( (e->type() == QEvent::Accel || 1025 if ( (e->type() == QEvent::Accel ||
1026 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) { 1026 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) {
1027 static_cast<QKeyEvent *>( e )->ignore(); 1027 static_cast<QKeyEvent *>( e )->ignore();
1028 return true; 1028 return true;
1029 } 1029 }
1030 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ ) 1030 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ )
1031 return FALSE; // not us 1031 return FALSE; // not us
1032 if ( e->type() == QEvent::Wheel) { 1032 if ( e->type() == QEvent::Wheel) {
1033 QApplication::sendEvent(scrollbar, e); 1033 QApplication::sendEvent(scrollbar, e);
1034 } 1034 }
1035 1035
1036#ifdef FAKE_CTRL_AND_ALT 1036#ifdef FAKE_CTRL_AND_ALT
1037 static bool control = FALSE; 1037 static bool control = FALSE;
1038 static bool alt = FALSE; 1038 static bool alt = FALSE;
1039// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:"); 1039// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:");
1040 bool dele=FALSE; 1040 bool dele=FALSE;
1041 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { 1041 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
1042 QKeyEvent* ke = (QKeyEvent*)e; 1042 QKeyEvent* ke = (QKeyEvent*)e;
1043 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat(); 1043 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat();
1044 switch (ke->key()) { 1044 switch (ke->key()) {
1045 case Key_F9: // let this be "Control" 1045 case Key_F9: // let this be "Control"
1046 control = keydown; 1046 control = keydown;
1047 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state()); 1047 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
1048 dele=TRUE; 1048 dele=TRUE;
1049 break; 1049 break;
1050 case Key_F13: // let this be "Alt" 1050 case Key_F13: // let this be "Alt"
1051 alt = keydown; 1051 alt = keydown;
1052 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state()); 1052 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state());
1053 dele=TRUE; 1053 dele=TRUE;
1054 break; 1054 break;
1055 default: 1055 default:
1056 if ( control ) { 1056 if ( control ) {
1057 int a = toupper(ke->ascii())-64; 1057 int a = toupper(ke->ascii())-64;
1058 if ( a >= 0 && a < ' ' ) { 1058 if ( a >= 0 && a < ' ' ) {
1059 e = new QKeyEvent(e->type(), ke->key(), 1059 e = new QKeyEvent(e->type(), ke->key(),
1060 a, ke->state()|ControlButton, QChar(a,0)); 1060 a, ke->state()|ControlButton, QChar(a,0));
1061 dele=TRUE; 1061 dele=TRUE;
1062 } 1062 }
1063 } 1063 }
1064 if ( alt ) { 1064 if ( alt ) {
1065 e = new QKeyEvent(e->type(), ke->key(), 1065 e = new QKeyEvent(e->type(), ke->key(),
1066 ke->ascii(), ke->state()|AltButton, ke->text()); 1066 ke->ascii(), ke->state()|AltButton, ke->text());
1067 dele=TRUE; 1067 dele=TRUE;
1068 } 1068 }
1069 } 1069 }
1070 } 1070 }
1071#endif 1071#endif
1072 1072
1073 if ( e->type() == QEvent::KeyPress ) { 1073 if ( e->type() == QEvent::KeyPress ) {
1074 QKeyEvent* ke = (QKeyEvent*)e; 1074 QKeyEvent* ke = (QKeyEvent*)e;
1075 actSel=0; // Key stroke implies a screen update, so TEWidget won't 1075 actSel=0; // Key stroke implies a screen update, so TEWidget won't
1076 // know where the current selection is. 1076 // know where the current selection is.
1077 1077
1078// qDebug("key pressed is 0x%x",ke->key()); 1078// qDebug("key pressed is 0x%x",ke->key());
1079 1079
1080 if( ke->state() == ShiftButton && ke->key() == Key_Tab) { //lets hardcode this sucker 1080 if( ke->state() == ShiftButton && ke->key() == Key_Tab) { //lets hardcode this sucker
1081 1081
1082// qDebug("key pressed 2 is 0x%x",ke->key()); 1082// qDebug("key pressed 2 is 0x%x",ke->key());
1083 emitText("\\"); // expose 1083 emitText("\\"); // expose
1084 } else 1084 } else
1085 emit keyPressedSignal(ke); // expose 1085 emit keyPressedSignal(ke); // expose
1086 ke->accept(); 1086 ke->accept();
1087#ifdef FAKE_CTRL_AND_ALT 1087#ifdef FAKE_CTRL_AND_ALT
1088 if ( dele ) delete e; 1088 if ( dele ) delete e;
1089#endif 1089#endif
1090 return true; // stop the event 1090 return true; // stop the event
1091 } 1091 }
1092 if ( e->type() == QEvent::Enter ) { 1092 if ( e->type() == QEvent::Enter ) {
1093 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()), 1093 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
1094 this, SLOT(onClearSelection()) ); 1094 this, SLOT(onClearSelection()) );
1095 } 1095 }
1096 if ( e->type() == QEvent::Leave ) { 1096 if ( e->type() == QEvent::Leave ) {
1097 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), 1097 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
1098 this, SLOT(onClearSelection()) ); 1098 this, SLOT(onClearSelection()) );
1099 } 1099 }
1100 return QFrame::eventFilter( obj, e ); 1100 return QFrame::eventFilter( obj, e );
1101} 1101}
1102 1102
1103/* ------------------------------------------------------------------------- */ 1103/* ------------------------------------------------------------------------- */
1104/* */ 1104/* */
1105/* Frame */ 1105/* Frame */
1106/* */ 1106/* */
1107/* ------------------------------------------------------------------------- */ 1107/* ------------------------------------------------------------------------- */
1108 1108
1109void TEWidget::frameChanged() 1109void TEWidget::frameChanged()
1110{ 1110{
1111 propagateSize(); 1111 propagateSize();
1112 update(); 1112 update();
1113} 1113}
1114 1114
1115/* ------------------------------------------------------------------------- */ 1115/* ------------------------------------------------------------------------- */
1116/* */ 1116/* */
1117/* Sound */ 1117/* Sound */
1118/* */ 1118/* */
1119/* ------------------------------------------------------------------------- */ 1119/* ------------------------------------------------------------------------- */
1120 1120
1121void TEWidget::Bell() 1121void TEWidget::Bell()
1122{ 1122{
1123 QApplication::beep(); 1123 QApplication::beep();
1124} 1124}
1125 1125
1126/* ------------------------------------------------------------------------- */ 1126/* ------------------------------------------------------------------------- */
1127/* */ 1127/* */
1128/* Auxiluary */ 1128/* Auxiluary */
1129/* */ 1129/* */
1130/* ------------------------------------------------------------------------- */ 1130/* ------------------------------------------------------------------------- */
1131 1131
1132void TEWidget::clearImage() 1132void TEWidget::clearImage()
1133// initialize the image 1133// initialize the image
1134// for internal use only 1134// for internal use only
1135{ 1135{
1136 for (int y = 0; y < lines; y++) 1136 for (int y = 0; y < lines; y++)
1137 for (int x = 0; x < columns; x++) 1137 for (int x = 0; x < columns; x++)
1138 { 1138 {
1139 image[loc(x,y)].c = 0xff; //' '; 1139 image[loc(x,y)].c = 0xff; //' ';
1140 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR; 1140 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR;
1141 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR; 1141 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
1142 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION; 1142 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
1143 } 1143 }
1144} 1144}
1145 1145
1146// Create Image /////////////////////////////////////////////////////// 1146// Create Image ///////////////////////////////////////////////////////
1147 1147
1148void TEWidget::calcGeometry() 1148void TEWidget::calcGeometry()
1149{ 1149{
1150 //FIXME: set rimX == rimY == 0 when running in full screen mode. 1150 //FIXME: set rimX == rimY == 0 when running in full screen mode.
1151 1151
1152 int showhscrollbar = 1; 1152 int showhscrollbar = 1;
1153 int hwidth = 0; 1153 int hwidth = 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 if(showhscrollbar == 1) 1161 if(showhscrollbar == 1)
1162 { 1162 {
1163 hscrollbar->resize(contentsRect().width() - hwidth, hwidth); 1163 hscrollbar->resize(contentsRect().width() - hwidth, hwidth);
1164 hscrollbar->setRange(0, 40); 1164 hscrollbar->setRange(0, 40);
1165 1165
1166 QPoint p = contentsRect().bottomLeft(); 1166 QPoint p = contentsRect().bottomLeft();
1167 hscrollbar->move(QPoint(p.x(), p.y() - hwidth)); 1167 hscrollbar->move(QPoint(p.x(), p.y() - hwidth));
1168 hscrollbar->show(); 1168 hscrollbar->show();
1169 } 1169 }
1170 else hscrollbar->hide(); 1170 else hscrollbar->hide();
1171 1171
1172 switch(scrollLoc) 1172 switch(scrollLoc)
1173 { 1173 {
1174 case SCRNONE : 1174 case SCRNONE :
1175 columns = ( contentsRect().width() - 2 * rimX ) / font_w; 1175 columns = ( contentsRect().width() - 2 * rimX ) / font_w;
1176 if(vcolumns) columns = vcolumns; 1176 if(vcolumns) columns = vcolumns;
1177 blX = (contentsRect().width() - (columns*font_w) ) / 2; 1177 blX = (contentsRect().width() - (columns*font_w) ) / 2;
1178 if(showhscrollbar)
1179 blX = -hposition * font_w;
1178 brX = blX; 1180 brX = blX;
1179 scrollbar->hide(); 1181 scrollbar->hide();
1180 break; 1182 break;
1181 case SCRLEFT : 1183 case SCRLEFT :
1182 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; 1184 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1183 if(vcolumns) columns = vcolumns; 1185 if(vcolumns) columns = vcolumns;
1184 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; 1186 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1187 if(showhscrollbar)
1188 brX = -hposition * font_w;
1185 blX = brX + scrollbar->width(); 1189 blX = brX + scrollbar->width();
1186 scrollbar->move(contentsRect().topLeft()); 1190 scrollbar->move(contentsRect().topLeft());
1187 scrollbar->show(); 1191 scrollbar->show();
1188 break; 1192 break;
1189 case SCRRIGHT: 1193 case SCRRIGHT:
1190 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; 1194 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1191 if(vcolumns) columns = vcolumns; 1195 if(vcolumns) columns = vcolumns;
1192 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; 1196 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1193 if(showhscrollbar) 1197 if(showhscrollbar)
1194 blX = -hposition * font_w; 1198 blX = -hposition * font_w;
1195 brX = blX; 1199 brX = blX;
1196 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0)); 1200 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
1197 scrollbar->show(); 1201 scrollbar->show();
1198 break; 1202 break;
1199 } 1203 }
1200 //FIXME: support 'rounding' styles 1204 //FIXME: support 'rounding' styles
1201 lines = ( contentsRect().height() - 2 * rimY ) / font_h; 1205 lines = ( contentsRect().height() - 2 * rimY ) / font_h;
1202 bY = (contentsRect().height() - (lines *font_h)) / 2; 1206 bY = (contentsRect().height() - (lines *font_h)) / 2;
1203 1207
1204 if(showhscrollbar == 1) 1208 if(showhscrollbar == 1)
1205 { 1209 {
1206 //bY = bY - 10; 1210 //bY = bY - 10;
1207 lines = lines - 1; 1211 lines = lines - 1;
1208 } 1212 }
1209} 1213}
1210 1214
1211void TEWidget::makeImage() 1215void TEWidget::makeImage()
1212//FIXME: rename 'calcGeometry? 1216//FIXME: rename 'calcGeometry?
1213{ 1217{
1214 calcGeometry(); 1218 calcGeometry();
1215 image = (ca*) malloc(lines*columns*sizeof(ca)); 1219 image = (ca*) malloc(lines*columns*sizeof(ca));
1216 clearImage(); 1220 clearImage();
1217} 1221}
1218 1222
1219// calculate the needed size 1223// calculate the needed size
1220QSize TEWidget::calcSize(int cols, int lins) const 1224QSize TEWidget::calcSize(int cols, int lins) const
1221{ 1225{
1222 int frw = width() - contentsRect().width(); 1226 int frw = width() - contentsRect().width();
1223 int frh = height() - contentsRect().height(); 1227 int frh = height() - contentsRect().height();
1224 int scw = (scrollLoc==SCRNONE?0:scrollbar->width()); 1228 int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
1225 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh ); 1229 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
1226} 1230}
1227 1231
1228QSize TEWidget::sizeHint() const 1232QSize TEWidget::sizeHint() const
1229{ 1233{
1230 return size(); 1234 return size();
1231} 1235}
1232 1236
1233void TEWidget::styleChange(QStyle &) 1237void TEWidget::styleChange(QStyle &)
1234{ 1238{
1235 propagateSize(); 1239 propagateSize();
1236} 1240}
1237 1241
1238#ifndef QT_NO_DRAGANDDROP 1242#ifndef QT_NO_DRAGANDDROP
1239 1243
1240/* --------------------------------------------------------------------- */ 1244/* --------------------------------------------------------------------- */
1241/* */ 1245/* */
1242/* Drag & Drop */ 1246/* Drag & Drop */
1243/* */ 1247/* */
1244/* --------------------------------------------------------------------- */ 1248/* --------------------------------------------------------------------- */
1245 1249
1246 1250
1247void TEWidget::dragEnterEvent(QDragEnterEvent* e) 1251void TEWidget::dragEnterEvent(QDragEnterEvent* e)
1248{ 1252{
1249 e->accept(QTextDrag::canDecode(e) || 1253 e->accept(QTextDrag::canDecode(e) ||
1250 QUriDrag::canDecode(e)); 1254 QUriDrag::canDecode(e));
1251} 1255}
1252 1256
1253void TEWidget::dropEvent(QDropEvent* event) 1257void TEWidget::dropEvent(QDropEvent* event)
1254{ 1258{
1255 // The current behaviour when url(s) are dropped is 1259 // The current behaviour when url(s) are dropped is
1256 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd 1260 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
1257 // * in all other cases, just paste 1261 // * in all other cases, just paste
1258 // (for non-local ones, or for a list of URLs, 'cd' is nonsense) 1262 // (for non-local ones, or for a list of URLs, 'cd' is nonsense)
1259 QStrList strlist; 1263 QStrList strlist;
1260 int file_count = 0; 1264 int file_count = 0;
1261 dropText = ""; 1265 dropText = "";
1262 bool bPopup = true; 1266 bool bPopup = true;
1263 1267
1264 if(QUriDrag::decode(event, strlist)) { 1268 if(QUriDrag::decode(event, strlist)) {
1265 if (strlist.count()) { 1269 if (strlist.count()) {
1266 for(const char* p = strlist.first(); p; p = strlist.next()) { 1270 for(const char* p = strlist.first(); p; p = strlist.next()) {
1267 if(file_count++ > 0) { 1271 if(file_count++ > 0) {
1268 dropText += " "; 1272 dropText += " ";
1269 bPopup = false; // more than one file, don't popup 1273 bPopup = false; // more than one file, don't popup
1270 } 1274 }
1271 1275
1272/* 1276/*
1273 KURL url(p); 1277 KURL url(p);
1274 if (url.isLocalFile()) { 1278 if (url.isLocalFile()) {
1275 dropText += url.path(); // local URL : remove protocol 1279 dropText += url.path(); // local URL : remove protocol
1276 } 1280 }
1277 else { 1281 else {
1278 dropText += url.prettyURL(); 1282 dropText += url.prettyURL();
1279 bPopup = false; // a non-local file, don't popup 1283 bPopup = false; // a non-local file, don't popup
1280 } 1284 }
1281*/ 1285*/
1282 1286
1283 } 1287 }
1284 1288
1285 if (bPopup) 1289 if (bPopup)
1286 // m_drop->popup(pos() + event->pos()); 1290 // m_drop->popup(pos() + event->pos());
1287 m_drop->popup(mapToGlobal(event->pos())); 1291 m_drop->popup(mapToGlobal(event->pos()));
1288 else 1292 else
1289 { 1293 {
1290 if (currentSession) { 1294 if (currentSession) {
1291 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1295 currentSession->getEmulation()->sendString(dropText.local8Bit());
1292 } 1296 }
1293// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1297// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1294 } 1298 }
1295 } 1299 }
1296 } 1300 }
1297 else if(QTextDrag::decode(event, dropText)) { 1301 else if(QTextDrag::decode(event, dropText)) {
1298// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1302// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1299 if (currentSession) { 1303 if (currentSession) {
1300 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1304 currentSession->getEmulation()->sendString(dropText.local8Bit());
1301 } 1305 }
1302 // Paste it 1306 // Paste it
1303 } 1307 }
1304} 1308}
1305#endif 1309#endif
1306 1310
1307 1311
1308void TEWidget::drop_menu_activated(int) 1312void TEWidget::drop_menu_activated(int)
1309{ 1313{
1310#ifndef QT_NO_DRAGANDDROP 1314#ifndef QT_NO_DRAGANDDROP
1311 switch (item) 1315 switch (item)
1312 { 1316 {
1313 case 0: // paste 1317 case 0: // paste
1314 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1318 currentSession->getEmulation()->sendString(dropText.local8Bit());
1315// KWM::activate((Window)this->winId()); 1319// KWM::activate((Window)this->winId());
1316 break; 1320 break;
1317 case 1: // cd ... 1321 case 1: // cd ...
1318 currentSession->getEmulation()->sendString("cd "); 1322 currentSession->getEmulation()->sendString("cd ");
1319 struct stat statbuf; 1323 struct stat statbuf;
1320 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 ) 1324 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
1321 { 1325 {
1322 if ( !S_ISDIR(statbuf.st_mode) ) 1326 if ( !S_ISDIR(statbuf.st_mode) )
1323 { 1327 {
1324/* 1328/*
1325 KURL url; 1329 KURL url;
1326 url.setPath( dropText ); 1330 url.setPath( dropText );
1327 dropText = url.directory( true, false ); // remove filename 1331 dropText = url.directory( true, false ); // remove filename
1328*/ 1332*/
1329 } 1333 }
1330 } 1334 }
1331 dropText.replace(QRegExp(" "), "\\ "); // escape spaces 1335 dropText.replace(QRegExp(" "), "\\ "); // escape spaces
1332 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1336 currentSession->getEmulation()->sendString(dropText.local8Bit());
1333 currentSession->getEmulation()->sendString("\n"); 1337 currentSession->getEmulation()->sendString("\n");
1334// KWM::activate((Window)this->winId()); 1338// KWM::activate((Window)this->winId());
1335 break; 1339 break;
1336 } 1340 }
1337#endif 1341#endif
1338} 1342}
1339 1343
1340QPushButton* TEWidget::cornerButton() { 1344QPushButton* TEWidget::cornerButton() {
1341 return m_cornerButton; 1345 return m_cornerButton;
1342} 1346}
1343 1347
1344void TEWidget::setWrapAt(int columns) 1348void TEWidget::setWrapAt(int columns)
1345{ 1349{
1346 vcolumns = columns; 1350 vcolumns = columns;
1351 propagateSize();
1352 update();
1347} 1353}
1348 1354
1349 1355