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