summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/TEWidget.cpp1
1 files changed, 1 insertions, 0 deletions
diff --git a/noncore/apps/opie-console/TEWidget.cpp b/noncore/apps/opie-console/TEWidget.cpp
index d1ff85e..1c83710 100644
--- a/noncore/apps/opie-console/TEWidget.cpp
+++ b/noncore/apps/opie-console/TEWidget.cpp
@@ -1,869 +1,870 @@
1/* ------------------------------------------------------------------------ */ 1/* ------------------------------------------------------------------------ */
2/* */ 2/* */
3/* [TEWidget.C] Terminal Emulation Widget */ 3/* [TEWidget.C] Terminal Emulation Widget */
4/* */ 4/* */
5/* ------------------------------------------------------------------------ */ 5/* ------------------------------------------------------------------------ */
6/* */ 6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ 7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */ 8/* */
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* */ 10/* */
11/* ------------------------------------------------------------------------ */ 11/* ------------------------------------------------------------------------ */
12/* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14/* */ 14/* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16/* */ 16/* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18/*! \class TEWidget 18/*! \class TEWidget
19 19
20 \brief Visible screen contents 20 \brief Visible screen contents
21 21
22 This class is responsible to map the `image' of a terminal emulation to the 22 This class is responsible to map the `image' of a terminal emulation to the
23 display. All the dependency of the emulation to a specific GUI or toolkit is 23 display. All the dependency of the emulation to a specific GUI or toolkit is
24 localized here. Further, this widget has no knowledge about being part of an 24 localized here. Further, this widget has no knowledge about being part of an
25 emulation, it simply work within the terminal emulation framework by exposing 25 emulation, it simply work within the terminal emulation framework by exposing
26 size and key events and by being ordered to show a new image. 26 size and key events and by being ordered to show a new image.
27 27
28 <ul> 28 <ul>
29 <li> The internal image has the size of the widget (evtl. rounded up) 29 <li> The internal image has the size of the widget (evtl. rounded up)
30 <li> The external image used in setImage can have any size. 30 <li> The external image used in setImage can have any size.
31 <li> (internally) the external image is simply copied to the internal 31 <li> (internally) the external image is simply copied to the internal
32 when a setImage happens. During a resizeEvent no painting is done 32 when a setImage happens. During a resizeEvent no painting is done
33 a paintEvent is expected to follow anyway. 33 a paintEvent is expected to follow anyway.
34 </ul> 34 </ul>
35 35
36 \sa TEScreen \sa Emulation 36 \sa TEScreen \sa Emulation
37*/ 37*/
38 38
39/* FIXME: 39/* FIXME:
40 - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent 40 - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent
41 - 'font_a' not used in mouse events 41 - 'font_a' not used in mouse events
42 - add destructor 42 - add destructor
43*/ 43*/
44 44
45/* TODO 45/* TODO
46 - evtl. be sensitive to `paletteChange' while using default colors. 46 - evtl. be sensitive to `paletteChange' while using default colors.
47 - set different 'rounding' styles? I.e. have a mode to show clipped chars? 47 - set different 'rounding' styles? I.e. have a mode to show clipped chars?
48*/ 48*/
49 49
50// #include "config.h" 50// #include "config.h"
51#include "TEWidget.h" 51#include "TEWidget.h"
52#include "session.h" 52#include "session.h"
53#include <qpe/config.h> 53#include <qpe/config.h>
54 54
55#include <qapplication.h> 55#include <qapplication.h>
56#include <qcursor.h> 56#include <qcursor.h>
57#include <qregexp.h> 57#include <qregexp.h>
58#include <qpainter.h> 58#include <qpainter.h>
59#include <qclipboard.h> 59#include <qclipboard.h>
60#include <qstyle.h> 60#include <qstyle.h>
61#include <qfile.h> 61#include <qfile.h>
62#include <qdragobject.h> 62#include <qdragobject.h>
63#include <qvbox.h> 63#include <qvbox.h>
64 64
65#include <stdio.h> 65#include <stdio.h>
66#include <stdlib.h> 66#include <stdlib.h>
67#include <unistd.h> 67#include <unistd.h>
68#include <ctype.h> 68#include <ctype.h>
69#include <sys/stat.h> 69#include <sys/stat.h>
70#include <sys/types.h> 70#include <sys/types.h>
71#include <signal.h> 71#include <signal.h>
72 72
73#include <assert.h> 73#include <assert.h>
74 74
75 75
76 76
77// #include "TEWidget.moc" 77// #include "TEWidget.moc"
78//#include <kapp.h> 78//#include <kapp.h>
79//#include <kcursor.h> 79//#include <kcursor.h>
80//#include <kurl.h> 80//#include <kurl.h>
81//#include <kdebug.h> 81//#include <kdebug.h>
82//#include <klocale.h> 82//#include <klocale.h>
83 83
84#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__) 84#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__)
85#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); } 85#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); }
86 86
87#define loc(X,Y) ((Y)*columns+(X)) 87#define loc(X,Y) ((Y)*columns+(X))
88 88
89//FIXME: the rim should normally be 1, 0 only when running in full screen mode. 89//FIXME: the rim should normally be 1, 0 only when running in full screen mode.
90#define rimX 0 // left/right rim width 90#define rimX 0 // left/right rim width
91#define rimY 0 // top/bottom rim high 91#define rimY 0 // top/bottom rim high
92 92
93#define yMouseScroll 1 93#define yMouseScroll 1
94// scroll increment used when dragging selection at top/bottom of window. 94// scroll increment used when dragging selection at top/bottom of window.
95 95
96/* Button XPM */ 96/* Button XPM */
97namespace { 97namespace {
98static char * menu_xpm[] = { 98static char * menu_xpm[] = {
99"12 12 5 1", 99"12 12 5 1",
100 " c None", 100 " c None",
101 ".c #000000", 101 ".c #000000",
102 "+c #FFFDAD", 102 "+c #FFFDAD",
103 "@c #FFFF00", 103 "@c #FFFF00",
104 "#c #E5E100", 104 "#c #E5E100",
105" ", 105" ",
106" ", 106" ",
107" ......... ", 107" ......... ",
108" .+++++++. ", 108" .+++++++. ",
109" .+@@@@#. ", 109" .+@@@@#. ",
110" .+@@@#. ", 110" .+@@@#. ",
111" .+@@#. ", 111" .+@@#. ",
112" .+@#. ", 112" .+@#. ",
113" .+#. ", 113" .+#. ",
114" .+. ", 114" .+. ",
115" .. ", 115" .. ",
116" "}; 116" "};
117 117
118} 118}
119 119
120 120
121/* ------------------------------------------------------------------------- */ 121/* ------------------------------------------------------------------------- */
122/* */ 122/* */
123/* Colors */ 123/* Colors */
124/* */ 124/* */
125/* ------------------------------------------------------------------------- */ 125/* ------------------------------------------------------------------------- */
126 126
127//FIXME: the default color table is in session.C now. 127//FIXME: the default color table is in session.C now.
128// We need a way to get rid of this one, here. 128// We need a way to get rid of this one, here.
129static const ColorEntry base_color_table[TABLE_COLORS] = 129static const ColorEntry base_color_table[TABLE_COLORS] =
130// The following are almost IBM standard color codes, with some slight 130// The following are almost IBM standard color codes, with some slight
131// gamma correction for the dim colors to compensate for bright X screens. 131// gamma correction for the dim colors to compensate for bright X screens.
132// It contains the 8 ansiterm/xterm colors in 2 intensities. 132// It contains the 8 ansiterm/xterm colors in 2 intensities.
133{ 133{
134 // Fixme: could add faint colors here, also. 134 // Fixme: could add faint colors here, also.
135 // normal 135 // normal
136 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback 136 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback
137 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red 137 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red
138 ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow 138 ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow
139 ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta 139 ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta
140 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White 140 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White
141 // intensiv 141 // intensiv
142 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ), 142 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
143 ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ), 143 ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
144 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ), 144 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
145 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), 145 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ),
146 ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 ) 146 ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
147}; 147};
148 148
149/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb) 149/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb)
150 150
151 Code 0 1 2 3 4 5 6 7 151 Code 0 1 2 3 4 5 6 7
152 ----------- ------- ------- ------- ------- ------- ------- ------- ------- 152 ----------- ------- ------- ------- ------- ------- ------- ------- -------
153 ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White 153 ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White
154 IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White 154 IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White
155*/ 155*/
156 156
157QColor TEWidget::getDefaultBackColor() 157QColor TEWidget::getDefaultBackColor()
158{ 158{
159 return color_table[DEFAULT_BACK_COLOR].color; 159 return color_table[DEFAULT_BACK_COLOR].color;
160} 160}
161 161
162const ColorEntry* TEWidget::getColorTable() const 162const ColorEntry* TEWidget::getColorTable() const
163{ 163{
164 return color_table; 164 return color_table;
165} 165}
166 166
167const ColorEntry* TEWidget::getdefaultColorTable() const 167const ColorEntry* TEWidget::getdefaultColorTable() const
168{ 168{
169 return base_color_table; 169 return base_color_table;
170} 170}
171 171
172 172
173const QPixmap *TEWidget::backgroundPixmap() 173const QPixmap *TEWidget::backgroundPixmap()
174{ 174{
175 static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm"); 175 static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm");
176 const QPixmap *pm = bg; 176 const QPixmap *pm = bg;
177 return pm; 177 return pm;
178} 178}
179 179
180void TEWidget::setColorTable(const ColorEntry table[]) 180void TEWidget::setColorTable(const ColorEntry table[])
181{ 181{
182 for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i]; 182 for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i];
183 183
184 const QPixmap* pm = backgroundPixmap(); 184 const QPixmap* pm = backgroundPixmap();
185 if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color); 185 if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color);
186 update(); 186 update();
187} 187}
188 188
189//FIXME: add backgroundPixmapChanged. 189//FIXME: add backgroundPixmapChanged.
190 190
191/* ------------------------------------------------------------------------- */ 191/* ------------------------------------------------------------------------- */
192/* */ 192/* */
193/* Font */ 193/* Font */
194/* */ 194/* */
195/* ------------------------------------------------------------------------- */ 195/* ------------------------------------------------------------------------- */
196 196
197/* 197/*
198 The VT100 has 32 special graphical characters. The usual vt100 extended 198 The VT100 has 32 special graphical characters. The usual vt100 extended
199 xterm fonts have these at 0x00..0x1f. 199 xterm fonts have these at 0x00..0x1f.
200 200
201 QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals 201 QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals
202 come in here as proper unicode characters. 202 come in here as proper unicode characters.
203 203
204 We treat non-iso10646 fonts as VT100 extended and do the requiered mapping 204 We treat non-iso10646 fonts as VT100 extended and do the requiered mapping
205 from unicode to 0x00..0x1f. The remaining translation is then left to the 205 from unicode to 0x00..0x1f. The remaining translation is then left to the
206 QCodec. 206 QCodec.
207*/ 207*/
208 208
209// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i. 209// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i.
210 210
211unsigned short vt100_graphics[32] = 211unsigned short vt100_graphics[32] =
212{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15 212{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15
213 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 213 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0,
214 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 214 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
215 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534, 215 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534,
216 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7 216 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7
217}; 217};
218 218
219static QChar vt100extended(QChar c) 219static QChar vt100extended(QChar c)
220{ 220{
221 switch (c.unicode()) 221 switch (c.unicode())
222 { 222 {
223 case 0x25c6 : return 1; 223 case 0x25c6 : return 1;
224 case 0x2592 : return 2; 224 case 0x2592 : return 2;
225 case 0x2409 : return 3; 225 case 0x2409 : return 3;
226 case 0x240c : return 4; 226 case 0x240c : return 4;
227 case 0x240d : return 5; 227 case 0x240d : return 5;
228 case 0x240a : return 6; 228 case 0x240a : return 6;
229 case 0x00b0 : return 7; 229 case 0x00b0 : return 7;
230 case 0x00b1 : return 8; 230 case 0x00b1 : return 8;
231 case 0x2424 : return 9; 231 case 0x2424 : return 9;
232 case 0x240b : return 10; 232 case 0x240b : return 10;
233 case 0x2518 : return 11; 233 case 0x2518 : return 11;
234 case 0x2510 : return 12; 234 case 0x2510 : return 12;
235 case 0x250c : return 13; 235 case 0x250c : return 13;
236 case 0x2514 : return 14; 236 case 0x2514 : return 14;
237 case 0x253c : return 15; 237 case 0x253c : return 15;
238 case 0xf800 : return 16; 238 case 0xf800 : return 16;
239 case 0xf801 : return 17; 239 case 0xf801 : return 17;
240 case 0x2500 : return 18; 240 case 0x2500 : return 18;
241 case 0xf803 : return 19; 241 case 0xf803 : return 19;
242 case 0xf804 : return 20; 242 case 0xf804 : return 20;
243 case 0x251c : return 21; 243 case 0x251c : return 21;
244 case 0x2524 : return 22; 244 case 0x2524 : return 22;
245 case 0x2534 : return 23; 245 case 0x2534 : return 23;
246 case 0x252c : return 24; 246 case 0x252c : return 24;
247 case 0x2502 : return 25; 247 case 0x2502 : return 25;
248 case 0x2264 : return 26; 248 case 0x2264 : return 26;
249 case 0x2265 : return 27; 249 case 0x2265 : return 27;
250 case 0x03c0 : return 28; 250 case 0x03c0 : return 28;
251 case 0x2260 : return 29; 251 case 0x2260 : return 29;
252 case 0x00a3 : return 30; 252 case 0x00a3 : return 30;
253 case 0x00b7 : return 31; 253 case 0x00b7 : return 31;
254 } 254 }
255 return c; 255 return c;
256} 256}
257 257
258static QChar identicalMap(QChar c) 258static QChar identicalMap(QChar c)
259{ 259{
260 return c; 260 return c;
261} 261}
262 262
263void TEWidget::fontChange(const QFont &) 263void TEWidget::fontChange(const QFont &)
264{ 264{
265 QFontMetrics fm(font()); 265 QFontMetrics fm(font());
266 font_h = fm.height(); 266 font_h = fm.height();
267 font_w = fm.maxWidth(); 267 font_w = fm.maxWidth();
268 font_a = fm.ascent(); 268 font_a = fm.ascent();
269//printf("font_h: %d\n",font_h); 269//printf("font_h: %d\n",font_h);
270//printf("font_w: %d\n",font_w); 270//printf("font_w: %d\n",font_w);
271//printf("font_a: %d\n",font_a); 271//printf("font_a: %d\n",font_a);
272//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii()); 272//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii());
273//printf("rawname: %s\n",font().rawName().ascii()); 273//printf("rawname: %s\n",font().rawName().ascii());
274 fontMap = 274 fontMap =
275#if QT_VERSION < 300 275#if QT_VERSION < 300
276 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646") 276 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646")
277 ? vt100extended 277 ? vt100extended
278 : 278 :
279#endif 279#endif
280 identicalMap; 280 identicalMap;
281 propagateSize(); 281 propagateSize();
282 update(); 282 update();
283} 283}
284 284
285void TEWidget::setVTFont(const QFont& f) 285void TEWidget::setVTFont(const QFont& f)
286{ 286{
287 QFrame::setFont(f); 287 QFrame::setFont(f);
288} 288}
289 289
290QFont TEWidget::getVTFont() { 290QFont TEWidget::getVTFont() {
291 return font(); 291 return font();
292} 292}
293 293
294void TEWidget::setFont(const QFont &) 294void TEWidget::setFont(const QFont &)
295{ 295{
296 // ignore font change request if not coming from konsole itself 296 // ignore font change request if not coming from konsole itself
297} 297}
298 298
299/* ------------------------------------------------------------------------- */ 299/* ------------------------------------------------------------------------- */
300/* */ 300/* */
301/* Constructor / Destructor */ 301/* Constructor / Destructor */
302/* */ 302/* */
303/* ----------------------------------------------------------------------- */ 303/* ----------------------------------------------------------------------- */
304 304
305 305
306 306
307TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name) 307TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name)
308{ 308{
309#ifndef QT_NO_CLIPBOARD 309#ifndef QT_NO_CLIPBOARD
310 cb = QApplication::clipboard(); 310 cb = QApplication::clipboard();
311 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), 311 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
312 this, SLOT(onClearSelection()) ); 312 this, SLOT(onClearSelection()) );
313#endif 313#endif
314 314
315 315
316 scrollbar = new QScrollBar( this ); 316 scrollbar = new QScrollBar( this );
317 scrollbar->setCursor( arrowCursor ); 317 scrollbar->setCursor( arrowCursor );
318 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 318 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
319 319
320 hscrollbar = new QScrollBar( Qt::Horizontal, this ); 320 hscrollbar = new QScrollBar( Qt::Horizontal, this );
321 hscrollbar->setCursor( arrowCursor ); 321 hscrollbar->setCursor( arrowCursor );
322 connect(hscrollbar, SIGNAL(valueChanged(int)), this, SLOT(hscrollChanged(int))); 322 connect(hscrollbar, SIGNAL(valueChanged(int)), this, SLOT(hscrollChanged(int)));
323 323
324 m_cornerButton = new QPushButton( this ); 324 m_cornerButton = new QPushButton( this );
325 m_cornerButton->setPixmap( QPixmap( (const char**)menu_xpm ) ); 325 m_cornerButton->setPixmap( QPixmap( (const char**)menu_xpm ) );
326 m_cornerButton->setMaximumSize( 14, 14 ); 326 m_cornerButton->setMaximumSize( 14, 14 );
327 m_cornerButton->hide(); 327 m_cornerButton->hide();
328 328
329 Config cfg("Konsole"); 329 Config cfg("Konsole");
330 cfg.setGroup("ScrollBar"); 330 cfg.setGroup("ScrollBar");
331 switch( cfg.readNumEntry("Position",2)){ 331 switch( cfg.readNumEntry("Position",2)){
332 case 0: 332 case 0:
333 scrollLoc = SCRNONE; 333 scrollLoc = SCRNONE;
334 break; 334 break;
335 case 1: 335 case 1:
336 scrollLoc = SCRLEFT; 336 scrollLoc = SCRLEFT;
337 break; 337 break;
338 case 2: 338 case 2:
339 scrollLoc = SCRRIGHT; 339 scrollLoc = SCRRIGHT;
340 break; 340 break;
341 }; 341 };
342 342
343 blinkT = new QTimer(this); 343 blinkT = new QTimer(this);
344 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent())); 344 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent()));
345 // blinking = FALSE; 345 // blinking = FALSE;
346 blinking = TRUE; 346 blinking = TRUE;
347 347
348 resizing = FALSE; 348 resizing = FALSE;
349 actSel = 0; 349 actSel = 0;
350 image = 0; 350 image = 0;
351 lines = 1; 351 lines = 1;
352 columns = 1; 352 columns = 1;
353 font_w = 1; 353 font_w = 1;
354 font_h = 1; 354 font_h = 1;
355 font_a = 1; 355 font_a = 1;
356 word_selection_mode = FALSE; 356 word_selection_mode = FALSE;
357 vcolumns = 0; 357 vcolumns = 0;
358 hposition = 0;
358 359
359 setMouseMarks(TRUE); 360 setMouseMarks(TRUE);
360 setVTFont( QFont("fixed") ); 361 setVTFont( QFont("fixed") );
361 setColorTable(base_color_table); // init color table 362 setColorTable(base_color_table); // init color table
362 363
363 qApp->installEventFilter( this ); //FIXME: see below 364 qApp->installEventFilter( this ); //FIXME: see below
364// KCursor::setAutoHideCursor( this, true ); 365// KCursor::setAutoHideCursor( this, true );
365 366
366 // Init DnD //////////////////////////////////////////////////////////////// 367 // Init DnD ////////////////////////////////////////////////////////////////
367 currentSession = NULL; 368 currentSession = NULL;
368// setAcceptDrops(true); // attempt 369// setAcceptDrops(true); // attempt
369// m_drop = new QPopupMenu(this); 370// m_drop = new QPopupMenu(this);
370// m_drop->insertItem( QString("Paste"), 0); 371// m_drop->insertItem( QString("Paste"), 0);
371// m_drop->insertItem( QString("cd"), 1); 372// m_drop->insertItem( QString("cd"), 1);
372// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int))); 373// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int)));
373 374
374 // we need focus so that the auto-hide cursor feature works 375 // we need focus so that the auto-hide cursor feature works
375 setFocus(); 376 setFocus();
376 setFocusPolicy( WheelFocus ); 377 setFocusPolicy( WheelFocus );
377} 378}
378 379
379//FIXME: make proper destructor 380//FIXME: make proper destructor
380// Here's a start (David) 381// Here's a start (David)
381TEWidget::~TEWidget() 382TEWidget::~TEWidget()
382{ 383{
383 qApp->removeEventFilter( this ); 384 qApp->removeEventFilter( this );
384 if (image) free(image); 385 if (image) free(image);
385} 386}
386 387
387/* ------------------------------------------------------------------------- */ 388/* ------------------------------------------------------------------------- */
388/* */ 389/* */
389/* Display Operations */ 390/* Display Operations */
390/* */ 391/* */
391/* ------------------------------------------------------------------------- */ 392/* ------------------------------------------------------------------------- */
392 393
393/*! 394/*!
394 attributed string draw primitive 395 attributed string draw primitive
395*/ 396*/
396 397
397void TEWidget::drawAttrStr(QPainter &paint, QRect rect, 398void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
398 QString& str, ca attr, BOOL pm, BOOL clear) 399 QString& str, ca attr, BOOL pm, BOOL clear)
399{ 400{
400 if (pm && color_table[attr.b].transparent) 401 if (pm && color_table[attr.b].transparent)
401 { 402 {
402 paint.setBackgroundMode( TransparentMode ); 403 paint.setBackgroundMode( TransparentMode );
403 if (clear) erase(rect); 404 if (clear) erase(rect);
404 } 405 }
405 else 406 else
406 { 407 {
407 if (blinking) 408 if (blinking)
408 paint.fillRect(rect, color_table[attr.b].color); 409 paint.fillRect(rect, color_table[attr.b].color);
409 else 410 else
410 { 411 {
411 paint.setBackgroundMode( OpaqueMode ); 412 paint.setBackgroundMode( OpaqueMode );
412 paint.setBackgroundColor( color_table[attr.b].color ); 413 paint.setBackgroundColor( color_table[attr.b].color );
413 } 414 }
414 } 415 }
415 416
416 if (color_table[attr.f].bold) 417 if (color_table[attr.f].bold)
417 paint.setPen(QColor( 0x8F, 0x00, 0x00 )); 418 paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
418 else 419 else
419 paint.setPen(color_table[attr.f].color); 420 paint.setPen(color_table[attr.f].color);
420 421
421 paint.drawText(rect.x(),rect.y()+font_a, str); 422 paint.drawText(rect.x(),rect.y()+font_a, str);
422 423
423 if (attr.r & RE_UNDERLINE) 424 if (attr.r & RE_UNDERLINE)
424 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 ); 425 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
425} 426}
426 427
427/*! 428/*!
428 The image can only be set completely. 429 The image can only be set completely.
429 430
430 The size of the new image may or may not match the size of the widget. 431 The size of the new image may or may not match the size of the widget.
431*/ 432*/
432 433
433void TEWidget::setImage(const ca* const newimg, int lines, int columns) 434void TEWidget::setImage(const ca* const newimg, int lines, int columns)
434{ int y,x,len; 435{ int y,x,len;
435 const QPixmap* pm = backgroundPixmap(); 436 const QPixmap* pm = backgroundPixmap();
436 QPainter paint; 437 QPainter paint;
437 setUpdatesEnabled(FALSE); 438 setUpdatesEnabled(FALSE);
438 paint.begin( this ); 439 paint.begin( this );
439HCNT("setImage"); 440HCNT("setImage");
440 441
441 QPoint tL = contentsRect().topLeft(); 442 QPoint tL = contentsRect().topLeft();
442 int tLx = tL.x(); 443 int tLx = tL.x();
443 int tLy = tL.y(); 444 int tLy = tL.y();
444 hasBlinker = FALSE; 445 hasBlinker = FALSE;
445 446
446 int cf = -1; // undefined 447 int cf = -1; // undefined
447 int cb = -1; // undefined 448 int cb = -1; // undefined
448 int cr = -1; // undefined 449 int cr = -1; // undefined
449 450
450 int lins = QMIN(this->lines, QMAX(0,lines )); 451 int lins = QMIN(this->lines, QMAX(0,lines ));
451 int cols = QMIN(this->columns,QMAX(0,columns)); 452 int cols = QMIN(this->columns,QMAX(0,columns));
452 QChar *disstrU = new QChar[cols]; 453 QChar *disstrU = new QChar[cols];
453 454
454//{ static int cnt = 0; printf("setImage %d\n",cnt++); } 455//{ static int cnt = 0; printf("setImage %d\n",cnt++); }
455 for (y = 0; y < lins; y++) 456 for (y = 0; y < lins; y++)
456 { 457 {
457 const ca* lcl = &image[y*this->columns]; 458 const ca* lcl = &image[y*this->columns];
458 const ca* const ext = &newimg[y*columns]; 459 const ca* const ext = &newimg[y*columns];
459 if (!resizing) // not while resizing, we're expecting a paintEvent 460 if (!resizing) // not while resizing, we're expecting a paintEvent
460 for (x = 0; x < cols; x++) 461 for (x = 0; x < cols; x++)
461 { 462 {
462 hasBlinker |= (ext[x].r & RE_BLINK); 463 hasBlinker |= (ext[x].r & RE_BLINK);
463 if (ext[x] != lcl[x]) 464 if (ext[x] != lcl[x])
464 { 465 {
465 cr = ext[x].r; 466 cr = ext[x].r;
466 cb = ext[x].b; 467 cb = ext[x].b;
467 if (ext[x].f != cf) cf = ext[x].f; 468 if (ext[x].f != cf) cf = ext[x].f;
468 int lln = cols - x; 469 int lln = cols - x;
469 disstrU[0] = fontMap(ext[x+0].c); 470 disstrU[0] = fontMap(ext[x+0].c);
470 for (len = 1; len < lln; len++) 471 for (len = 1; len < lln; len++)
471 { 472 {
472 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || 473 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
473 ext[x+len] == lcl[x+len] ) 474 ext[x+len] == lcl[x+len] )
474 break; 475 break;
475 disstrU[len] = fontMap(ext[x+len].c); 476 disstrU[len] = fontMap(ext[x+len].c);
476 } 477 }
477 QString unistr(disstrU,len); 478 QString unistr(disstrU,len);
478 drawAttrStr(paint, 479 drawAttrStr(paint,
479 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 480 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
480 unistr, ext[x], pm != NULL, true); 481 unistr, ext[x], pm != NULL, true);
481 x += len - 1; 482 x += len - 1;
482 } 483 }
483 } 484 }
484 // finally, make `image' become `newimg'. 485 // finally, make `image' become `newimg'.
485 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca)); 486 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
486 } 487 }
487 drawFrame( &paint ); 488 drawFrame( &paint );
488 paint.end(); 489 paint.end();
489 setUpdatesEnabled(TRUE); 490 setUpdatesEnabled(TRUE);
490 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms 491 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms
491 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; } 492 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
492 delete [] disstrU; 493 delete [] disstrU;
493} 494}
494 495
495// paint Event //////////////////////////////////////////////////// 496// paint Event ////////////////////////////////////////////////////
496 497
497/*! 498/*!
498 The difference of this routine vs. the `setImage' is, 499 The difference of this routine vs. the `setImage' is,
499 that the drawing does not include a difference analysis 500 that the drawing does not include a difference analysis
500 between the old and the new image. Instead, the internal 501 between the old and the new image. Instead, the internal
501 image is used and the painting bound by the PaintEvent box. 502 image is used and the painting bound by the PaintEvent box.
502*/ 503*/
503 504
504void TEWidget::paintEvent( QPaintEvent* pe ) 505void TEWidget::paintEvent( QPaintEvent* pe )
505{ 506{
506 507
507//{ static int cnt = 0; printf("paint %d\n",cnt++); } 508//{ static int cnt = 0; printf("paint %d\n",cnt++); }
508 const QPixmap* pm = backgroundPixmap(); 509 const QPixmap* pm = backgroundPixmap();
509 QPainter paint; 510 QPainter paint;
510 setUpdatesEnabled(FALSE); 511 setUpdatesEnabled(FALSE);
511 paint.begin( this ); 512 paint.begin( this );
512 paint.setBackgroundMode( TransparentMode ); 513 paint.setBackgroundMode( TransparentMode );
513HCNT("paintEvent"); 514HCNT("paintEvent");
514 515
515 // Note that the actual widget size can be slightly larger 516 // Note that the actual widget size can be slightly larger
516 // that the image (the size is truncated towards the smaller 517 // that the image (the size is truncated towards the smaller
517 // number of characters in `resizeEvent'. The paint rectangle 518 // number of characters in `resizeEvent'. The paint rectangle
518 // can thus be larger than the image, but less then the size 519 // can thus be larger than the image, but less then the size
519 // of one character. 520 // of one character.
520 521
521 QRect rect = pe->rect().intersect(contentsRect()); 522 QRect rect = pe->rect().intersect(contentsRect());
522 523
523 QPoint tL = contentsRect().topLeft(); 524 QPoint tL = contentsRect().topLeft();
524 int tLx = tL.x(); 525 int tLx = tL.x();
525 int tLy = tL.y(); 526 int tLy = tL.y();
526 527
527 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w)); 528 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w));
528 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h)); 529 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h));
529 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w)); 530 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w));
530 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h)); 531 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h));
531 532
532 /* 533 /*
533 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly, 534 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly,
534 rect.left(), rect.right(), rect.top(), rect.bottom()); 535 rect.left(), rect.right(), rect.top(), rect.bottom());
535 */ 536 */
536 537
537 // if (pm != NULL && color_table[image->b].transparent) 538 // if (pm != NULL && color_table[image->b].transparent)
538 // erase(rect); 539 // erase(rect);
539 // BL: I have no idea why we need this, and it breaks the refresh. 540 // BL: I have no idea why we need this, and it breaks the refresh.
540 541
541 QChar *disstrU = new QChar[columns]; 542 QChar *disstrU = new QChar[columns];
542 for (int y = luy; y <= rly; y++) 543 for (int y = luy; y <= rly; y++)
543 for (int x = lux; x <= rlx; x++) 544 for (int x = lux; x <= rlx; x++)
544 { 545 {
545 int len = 1; 546 int len = 1;
546 disstrU[0] = fontMap(image[loc(x,y)].c); 547 disstrU[0] = fontMap(image[loc(x,y)].c);
547 int cf = image[loc(x,y)].f; 548 int cf = image[loc(x,y)].f;
548 int cb = image[loc(x,y)].b; 549 int cb = image[loc(x,y)].b;
549 int cr = image[loc(x,y)].r; 550 int cr = image[loc(x,y)].r;
550 while (x+len <= rlx && 551 while (x+len <= rlx &&
551 image[loc(x+len,y)].f == cf && 552 image[loc(x+len,y)].f == cf &&
552 image[loc(x+len,y)].b == cb && 553 image[loc(x+len,y)].b == cb &&
553 image[loc(x+len,y)].r == cr ) 554 image[loc(x+len,y)].r == cr )
554 { 555 {
555 disstrU[len] = fontMap(image[loc(x+len,y)].c); 556 disstrU[len] = fontMap(image[loc(x+len,y)].c);
556 len += 1; 557 len += 1;
557 } 558 }
558 QString unistr(disstrU,len); 559 QString unistr(disstrU,len);
559 drawAttrStr(paint, 560 drawAttrStr(paint,
560 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 561 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
561 unistr, image[loc(x,y)], pm != NULL, false); 562 unistr, image[loc(x,y)], pm != NULL, false);
562 x += len - 1; 563 x += len - 1;
563 } 564 }
564 delete [] disstrU; 565 delete [] disstrU;
565 drawFrame( &paint ); 566 drawFrame( &paint );
566 paint.end(); 567 paint.end();
567 setUpdatesEnabled(TRUE); 568 setUpdatesEnabled(TRUE);
568} 569}
569 570
570void TEWidget::blinkEvent() 571void TEWidget::blinkEvent()
571{ 572{
572 blinking = !blinking; 573 blinking = !blinking;
573 repaint(FALSE); 574 repaint(FALSE);
574} 575}
575 576
576/* ------------------------------------------------------------------------- */ 577/* ------------------------------------------------------------------------- */
577/* */ 578/* */
578/* Resizing */ 579/* Resizing */
579/* */ 580/* */
580/* ------------------------------------------------------------------------- */ 581/* ------------------------------------------------------------------------- */
581 582
582void TEWidget::resizeEvent(QResizeEvent* ev) 583void TEWidget::resizeEvent(QResizeEvent* ev)
583{ 584{
584// printf("resize: %d,%d\n",ev->size().width(),ev->size().height()); 585// printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
585 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h); 586 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
586 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h); 587 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
587 //printf("curren: %d,%d\n",width(),height()); 588 //printf("curren: %d,%d\n",width(),height());
588HCNT("resizeEvent"); 589HCNT("resizeEvent");
589 590
590 // see comment in `paintEvent' concerning the rounding. 591 // see comment in `paintEvent' concerning the rounding.
591 //FIXME: could make a routine here; check width(),height() 592 //FIXME: could make a routine here; check width(),height()
592 assert(ev->size().width() == width()); 593 assert(ev->size().width() == width());
593 assert(ev->size().height() == height()); 594 assert(ev->size().height() == height());
594 595
595 propagateSize(); 596 propagateSize();
596} 597}
597 598
598void TEWidget::propagateSize() 599void TEWidget::propagateSize()
599{ 600{
600 ca* oldimg = image; 601 ca* oldimg = image;
601 int oldlin = lines; 602 int oldlin = lines;
602 int oldcol = columns; 603 int oldcol = columns;
603 makeImage(); 604 makeImage();
604 // we copy the old image to reduce flicker 605 // we copy the old image to reduce flicker
605 int lins = QMIN(oldlin,lines); 606 int lins = QMIN(oldlin,lines);
606 int cols = QMIN(oldcol,columns); 607 int cols = QMIN(oldcol,columns);
607 if (oldimg) 608 if (oldimg)
608 { 609 {
609 for (int lin = 0; lin < lins; lin++) 610 for (int lin = 0; lin < lins; lin++)
610 memcpy((void*)&image[columns*lin], 611 memcpy((void*)&image[columns*lin],
611 (void*)&oldimg[oldcol*lin],cols*sizeof(ca)); 612 (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
612 free(oldimg); //FIXME: try new,delete 613 free(oldimg); //FIXME: try new,delete
613 } 614 }
614 else 615 else
615 clearImage(); 616 clearImage();
616 617
617 //NOTE: control flows from the back through the chest right into the eye. 618 //NOTE: control flows from the back through the chest right into the eye.
618 // `emu' will call back via `setImage'. 619 // `emu' will call back via `setImage'.
619 620
620 resizing = TRUE; 621 resizing = TRUE;
621 emit changedImageSizeSignal(lines, columns); // expose resizeEvent 622 emit changedImageSizeSignal(lines, columns); // expose resizeEvent
622 resizing = FALSE; 623 resizing = FALSE;
623} 624}
624 625
625/* ------------------------------------------------------------------------- */ 626/* ------------------------------------------------------------------------- */
626/* */ 627/* */
627/* Scrollbar */ 628/* Scrollbar */
628/* */ 629/* */
629/* ------------------------------------------------------------------------- */ 630/* ------------------------------------------------------------------------- */
630 631
631void TEWidget::scrollChanged(int) 632void TEWidget::scrollChanged(int)
632{ 633{
633 emit changedHistoryCursor(scrollbar->value()); //expose 634 emit changedHistoryCursor(scrollbar->value()); //expose
634} 635}
635 636
636void TEWidget::hscrollChanged(int loc) 637void TEWidget::hscrollChanged(int loc)
637{ 638{
638 hposition = loc; 639 hposition = loc;
639 propagateSize(); 640 propagateSize();
640 update(); 641 update();
641} 642}
642 643
643void TEWidget::setScroll(int cursor, int slines) 644void TEWidget::setScroll(int cursor, int slines)
644{ 645{
645 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 646 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
646 scrollbar->setRange(0,slines); 647 scrollbar->setRange(0,slines);
647 scrollbar->setSteps(1,lines); 648 scrollbar->setSteps(1,lines);
648 scrollbar->setValue(cursor); 649 scrollbar->setValue(cursor);
649 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 650 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
650} 651}
651 652
652void TEWidget::setScrollbarLocation(int loc) 653void TEWidget::setScrollbarLocation(int loc)
653{ 654{
654 if (scrollLoc == loc) return; // quickly 655 if (scrollLoc == loc) return; // quickly
655 scrollLoc = loc; 656 scrollLoc = loc;
656 propagateSize(); 657 propagateSize();
657 update(); 658 update();
658} 659}
659 660
660/* ------------------------------------------------------------------------- */ 661/* ------------------------------------------------------------------------- */
661/* */ 662/* */
662/* Mouse */ 663/* Mouse */
663/* */ 664/* */
664/* ------------------------------------------------------------------------- */ 665/* ------------------------------------------------------------------------- */
665 666
666/*! 667/*!
667 Three different operations can be performed using the mouse, and the 668 Three different operations can be performed using the mouse, and the
668 routines in this section serve all of them: 669 routines in this section serve all of them:
669 670
670 1) The press/release events are exposed to the application 671 1) The press/release events are exposed to the application
671 2) Marking (press and move left button) and Pasting (press middle button) 672 2) Marking (press and move left button) and Pasting (press middle button)
672 3) The right mouse button is used from the configuration menu 673 3) The right mouse button is used from the configuration menu
673 674
674 NOTE: During the marking process we attempt to keep the cursor within 675 NOTE: During the marking process we attempt to keep the cursor within
675 the bounds of the text as being displayed by setting the mouse position 676 the bounds of the text as being displayed by setting the mouse position
676 whenever the mouse has left the text area. 677 whenever the mouse has left the text area.
677 678
678 Two reasons to do so: 679 Two reasons to do so:
679 1) QT does not allow the `grabMouse' to confine-to the TEWidget. 680 1) QT does not allow the `grabMouse' to confine-to the TEWidget.
680 Thus a `XGrapPointer' would have to be used instead. 681 Thus a `XGrapPointer' would have to be used instead.
681 2) Even if so, this would not help too much, since the text area 682 2) Even if so, this would not help too much, since the text area
682 of the TEWidget is normally not identical with it's bounds. 683 of the TEWidget is normally not identical with it's bounds.
683 684
684 The disadvantage of the current handling is, that the mouse can visibly 685 The disadvantage of the current handling is, that the mouse can visibly
685 leave the bounds of the widget and is then moved back. Because of the 686 leave the bounds of the widget and is then moved back. Because of the
686 current construction, and the reasons mentioned above, we cannot do better 687 current construction, and the reasons mentioned above, we cannot do better
687 without changing the overall construction. 688 without changing the overall construction.
688*/ 689*/
689 690
690/*! 691/*!
691*/ 692*/
692 693
693void TEWidget::mousePressEvent(QMouseEvent* ev) 694void TEWidget::mousePressEvent(QMouseEvent* ev)
694{ 695{
695//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 696//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
696 if ( !contentsRect().contains(ev->pos()) ) return; 697 if ( !contentsRect().contains(ev->pos()) ) return;
697 QPoint tL = contentsRect().topLeft(); 698 QPoint tL = contentsRect().topLeft();
698 int tLx = tL.x(); 699 int tLx = tL.x();
699 int tLy = tL.y(); 700 int tLy = tL.y();
700 701
701 word_selection_mode = FALSE; 702 word_selection_mode = FALSE;
702 703
703//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY); 704//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
704 if ( ev->button() == LeftButton) 705 if ( ev->button() == LeftButton)
705 { 706 {
706 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 707 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
707 708
708 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ; 709 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
709 710
710 if (mouse_marks || (ev->state() & ShiftButton)) 711 if (mouse_marks || (ev->state() & ShiftButton))
711 { 712 {
712 emit clearSelectionSignal(); 713 emit clearSelectionSignal();
713 iPntSel = pntSel = pos; 714 iPntSel = pntSel = pos;
714 actSel = 1; // left mouse button pressed but nothing selected yet. 715 actSel = 1; // left mouse button pressed but nothing selected yet.
715 grabMouse( /*crossCursor*/ ); // handle with care! 716 grabMouse( /*crossCursor*/ ); // handle with care!
716 } 717 }
717 else 718 else
718 { 719 {
719 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button 720 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
720 } 721 }
721 } 722 }
722 if ( ev->button() == MidButton ) 723 if ( ev->button() == MidButton )
723 { 724 {
724 emitSelection(); 725 emitSelection();
725 } 726 }
726 if ( ev->button() == RightButton ) // Configure 727 if ( ev->button() == RightButton ) // Configure
727 { 728 {
728 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() ); 729 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
729 } 730 }
730} 731}
731 732
732void TEWidget::mouseMoveEvent(QMouseEvent* ev) 733void TEWidget::mouseMoveEvent(QMouseEvent* ev)
733{ 734{
734 // for auto-hiding the cursor, we need mouseTracking 735 // for auto-hiding the cursor, we need mouseTracking
735 if (ev->state() == NoButton ) return; 736 if (ev->state() == NoButton ) return;
736 737
737 if (actSel == 0) return; 738 if (actSel == 0) return;
738 739
739 // don't extend selection while pasting 740 // don't extend selection while pasting
740 if (ev->state() & MidButton) return; 741 if (ev->state() & MidButton) return;
741 742
742 //if ( !contentsRect().contains(ev->pos()) ) return; 743 //if ( !contentsRect().contains(ev->pos()) ) return;
743 QPoint tL = contentsRect().topLeft(); 744 QPoint tL = contentsRect().topLeft();
744 int tLx = tL.x(); 745 int tLx = tL.x();
745 int tLy = tL.y(); 746 int tLy = tL.y();
746 int scroll = scrollbar->value(); 747 int scroll = scrollbar->value();
747 748
748 // we're in the process of moving the mouse with the left button pressed 749 // we're in the process of moving the mouse with the left button pressed
749 // the mouse cursor will kept catched within the bounds of the text in 750 // the mouse cursor will kept catched within the bounds of the text in
750 // this widget. 751 // this widget.
751 752
752 // Adjust position within text area bounds. See FIXME above. 753 // Adjust position within text area bounds. See FIXME above.
753 QPoint pos = ev->pos(); 754 QPoint pos = ev->pos();
754 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX ); 755 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
755 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w ); 756 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
756 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY ); 757 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
757 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 ); 758 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
758 // check if we produce a mouse move event by this 759 // check if we produce a mouse move event by this
759 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos)); 760 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
760 761
761 if ( pos.y() == tLy+bY+lines*font_h-1 ) 762 if ( pos.y() == tLy+bY+lines*font_h-1 )
762 { 763 {
763 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward 764 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward
764 } 765 }
765 if ( pos.y() == tLy+bY ) 766 if ( pos.y() == tLy+bY )
766 { 767 {
767 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback 768 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
768 } 769 }
769 770
770 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h); 771 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
771 QPoint ohere; 772 QPoint ohere;
772 bool swapping = FALSE; 773 bool swapping = FALSE;
773 774
774 if ( word_selection_mode ) 775 if ( word_selection_mode )
775 { 776 {
776 // Extend to word boundaries 777 // Extend to word boundaries
777 int i; 778 int i;
778 int selClass; 779 int selClass;
779 780
780 bool left_not_right = ( here.y() < iPntSel.y() || 781 bool left_not_right = ( here.y() < iPntSel.y() ||
781 here.y() == iPntSel.y() && here.x() < iPntSel.x() ); 782 here.y() == iPntSel.y() && here.x() < iPntSel.x() );
782 bool old_left_not_right = ( pntSel.y() < iPntSel.y() || 783 bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
783 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() ); 784 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
784 swapping = left_not_right != old_left_not_right; 785 swapping = left_not_right != old_left_not_right;
785 786
786 // Find left (left_not_right ? from here : from start) 787 // Find left (left_not_right ? from here : from start)
787 QPoint left = left_not_right ? here : iPntSel; 788 QPoint left = left_not_right ? here : iPntSel;
788 i = loc(left.x(),left.y()); 789 i = loc(left.x(),left.y());
789 selClass = charClass(image[i].c); 790 selClass = charClass(image[i].c);
790 while ( left.x() > 0 && charClass(image[i-1].c) == selClass ) 791 while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
791 { i--; left.rx()--; } 792 { i--; left.rx()--; }
792 793
793 // Find left (left_not_right ? from start : from here) 794 // Find left (left_not_right ? from start : from here)
794 QPoint right = left_not_right ? iPntSel : here; 795 QPoint right = left_not_right ? iPntSel : here;
795 i = loc(right.x(),right.y()); 796 i = loc(right.x(),right.y());
796 selClass = charClass(image[i].c); 797 selClass = charClass(image[i].c);
797 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass ) 798 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
798 { i++; right.rx()++; } 799 { i++; right.rx()++; }
799 800
800 // Pick which is start (ohere) and which is extension (here) 801 // Pick which is start (ohere) and which is extension (here)
801 if ( left_not_right ) 802 if ( left_not_right )
802 { 803 {
803 here = left; ohere = right; 804 here = left; ohere = right;
804 } 805 }
805 else 806 else
806 { 807 {
807 here = right; ohere = left; 808 here = right; ohere = left;
808 } 809 }
809 } 810 }
810 811
811 if (here == pntSel && scroll == scrollbar->value()) return; // not moved 812 if (here == pntSel && scroll == scrollbar->value()) return; // not moved
812 813
813 if ( word_selection_mode ) { 814 if ( word_selection_mode ) {
814 if ( actSel < 2 || swapping ) { 815 if ( actSel < 2 || swapping ) {
815 emit beginSelectionSignal( ohere.x(), ohere.y() ); 816 emit beginSelectionSignal( ohere.x(), ohere.y() );
816 } 817 }
817 } else if ( actSel < 2 ) { 818 } else if ( actSel < 2 ) {
818 emit beginSelectionSignal( pntSel.x(), pntSel.y() ); 819 emit beginSelectionSignal( pntSel.x(), pntSel.y() );
819 } 820 }
820 821
821 actSel = 2; // within selection 822 actSel = 2; // within selection
822 pntSel = here; 823 pntSel = here;
823 emit extendSelectionSignal( here.x(), here.y() ); 824 emit extendSelectionSignal( here.x(), here.y() );
824} 825}
825 826
826void TEWidget::mouseReleaseEvent(QMouseEvent* ev) 827void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
827{ 828{
828//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 829//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
829 if ( ev->button() == LeftButton) 830 if ( ev->button() == LeftButton)
830 { 831 {
831 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks); 832 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
832 preserve_line_breaks = TRUE; 833 preserve_line_breaks = TRUE;
833 actSel = 0; 834 actSel = 0;
834 835
835 //FIXME: emits a release event even if the mouse is 836 //FIXME: emits a release event even if the mouse is
836 // outside the range. The procedure used in `mouseMoveEvent' 837 // outside the range. The procedure used in `mouseMoveEvent'
837 // applies here, too. 838 // applies here, too.
838 839
839 QPoint tL = contentsRect().topLeft(); 840 QPoint tL = contentsRect().topLeft();
840 int tLx = tL.x(); 841 int tLx = tL.x();
841 int tLy = tL.y(); 842 int tLy = tL.y();
842 843
843 if (!mouse_marks && !(ev->state() & ShiftButton)) 844 if (!mouse_marks && !(ev->state() & ShiftButton))
844 emit mouseSignal( 3, // release 845 emit mouseSignal( 3, // release
845 (ev->x()-tLx-blX)/font_w + 1, 846 (ev->x()-tLx-blX)/font_w + 1,
846 (ev->y()-tLy-bY)/font_h + 1 ); 847 (ev->y()-tLy-bY)/font_h + 1 );
847 releaseMouse(); 848 releaseMouse();
848 } 849 }
849} 850}
850 851
851void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev) 852void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev)
852{ 853{
853 if ( ev->button() != LeftButton) return; 854 if ( ev->button() != LeftButton) return;
854 855
855 QPoint tL = contentsRect().topLeft(); 856 QPoint tL = contentsRect().topLeft();
856 int tLx = tL.x(); 857 int tLx = tL.x();
857 int tLy = tL.y(); 858 int tLy = tL.y();
858 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 859 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
859 860
860 // pass on double click as two clicks. 861 // pass on double click as two clicks.
861 if (!mouse_marks && !(ev->state() & ShiftButton)) 862 if (!mouse_marks && !(ev->state() & ShiftButton))
862 { 863 {
863 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button 864 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
864 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release 865 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release
865 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button 866 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
866 return; 867 return;
867 } 868 }
868 869
869 870