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