author | josef <josef> | 2002-10-26 13:41:03 (UTC) |
---|---|---|
committer | josef <josef> | 2002-10-26 13:41:03 (UTC) |
commit | ffa4d7c4df80207411c27746ae884cbcead4e619 (patch) (unidiff) | |
tree | 2e37f5137deebc5f2e36452ca7fed78630cafeb9 | |
parent | 0d58e14f2bcfa2a1f5c9a197d5bb544571824207 (diff) | |
download | opie-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)
-rw-r--r-- | noncore/apps/opie-console/TEWidget.cpp | 52 | ||||
-rw-r--r-- | noncore/apps/opie-console/TEWidget.h | 6 | ||||
-rw-r--r-- | noncore/apps/opie-console/emulation_handler.cpp | 3 | ||||
-rw-r--r-- | noncore/apps/opie-console/emulation_widget.cpp | 3 | ||||
-rw-r--r-- | noncore/apps/opie-console/widget.cpp | 2 |
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 */ |
99 | namespace { | 97 | namespace { |
100 | static char * menu_xpm[] = { | 98 | static 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. |
131 | static const ColorEntry base_color_table[TABLE_COLORS] = | 129 | static 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 | ||
159 | QColor TEWidget::getDefaultBackColor() | 157 | QColor TEWidget::getDefaultBackColor() |
160 | { | 158 | { |
161 | return color_table[DEFAULT_BACK_COLOR].color; | 159 | return color_table[DEFAULT_BACK_COLOR].color; |
162 | } | 160 | } |
163 | 161 | ||
164 | const ColorEntry* TEWidget::getColorTable() const | 162 | const ColorEntry* TEWidget::getColorTable() const |
165 | { | 163 | { |
166 | return color_table; | 164 | return color_table; |
167 | } | 165 | } |
168 | 166 | ||
169 | const ColorEntry* TEWidget::getdefaultColorTable() const | 167 | const ColorEntry* TEWidget::getdefaultColorTable() const |
170 | { | 168 | { |
171 | return base_color_table; | 169 | return base_color_table; |
172 | } | 170 | } |
173 | 171 | ||
174 | 172 | ||
175 | const QPixmap *TEWidget::backgroundPixmap() | 173 | const 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 | ||
182 | void TEWidget::setColorTable(const ColorEntry table[]) | 180 | void 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 | ||
213 | unsigned short vt100_graphics[32] = | 211 | unsigned 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 | ||
221 | static QChar vt100extended(QChar c) | 219 | static 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 | ||
260 | static QChar identicalMap(QChar c) | 258 | static QChar identicalMap(QChar c) |
261 | { | 259 | { |
262 | return c; | 260 | return c; |
263 | } | 261 | } |
264 | 262 | ||
265 | void TEWidget::fontChange(const QFont &) | 263 | void 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 | ||
287 | void TEWidget::setVTFont(const QFont& f) | 285 | void TEWidget::setVTFont(const QFont& f) |
288 | { | 286 | { |
289 | QFrame::setFont(f); | 287 | QFrame::setFont(f); |
290 | } | 288 | } |
291 | 289 | ||
292 | QFont TEWidget::getVTFont() { | 290 | QFont TEWidget::getVTFont() { |
293 | return font(); | 291 | return font(); |
294 | } | 292 | } |
295 | 293 | ||
296 | void TEWidget::setFont(const QFont &) | 294 | void 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 | ||
309 | TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name) | 307 | TEWidget::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) |
378 | TEWidget::~TEWidget() | 381 | TEWidget::~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 | ||
394 | void TEWidget::drawAttrStr(QPainter &paint, QRect rect, | 397 | void 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 | ||
430 | void TEWidget::setImage(const ca* const newimg, int lines, int columns) | 433 | void 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 ); |
436 | HCNT("setImage"); | 439 | HCNT("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 | ||
501 | void TEWidget::paintEvent( QPaintEvent* pe ) | 504 | void 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 ); |
510 | HCNT("paintEvent"); | 513 | HCNT("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 | ||
567 | void TEWidget::blinkEvent() | 570 | void 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 | ||
579 | void TEWidget::resizeEvent(QResizeEvent* ev) | 582 | void 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()); |
585 | HCNT("resizeEvent"); | 588 | HCNT("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 | ||
595 | void TEWidget::propagateSize() | 598 | void 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 | ||
628 | void TEWidget::scrollChanged(int) | 631 | void TEWidget::scrollChanged(int) |
629 | { | 632 | { |
630 | emit changedHistoryCursor(scrollbar->value()); //expose | 633 | emit changedHistoryCursor(scrollbar->value()); //expose |
631 | } | 634 | } |
632 | 635 | ||
636 | void TEWidget::hscrollChanged(int loc) | ||
637 | { | ||
638 | hposition = loc; | ||
639 | propagateSize(); | ||
640 | update(); | ||
641 | } | ||
642 | |||
633 | void TEWidget::setScroll(int cursor, int slines) | 643 | void 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 | ||
642 | void TEWidget::setScrollbarLocation(int loc) | 652 | void 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 | ||
683 | void TEWidget::mousePressEvent(QMouseEvent* ev) | 693 | void 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 | ||
722 | void TEWidget::mouseMoveEvent(QMouseEvent* ev) | 732 | void 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 | ||
816 | void TEWidget::mouseReleaseEvent(QMouseEvent* ev) | 826 | void 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 | ||
841 | void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev) | 851 | void 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 | ||
891 | void TEWidget::focusInEvent( QFocusEvent * ) | 901 | void 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 | ||
898 | void TEWidget::focusOutEvent( QFocusEvent * ) | 908 | void TEWidget::focusOutEvent( QFocusEvent * ) |
899 | { | 909 | { |
900 | // do nothing, to prevent repainting | 910 | // do nothing, to prevent repainting |
901 | } | 911 | } |
902 | 912 | ||
903 | bool TEWidget::focusNextPrevChild( bool next ) | 913 | bool 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 | ||
912 | int TEWidget::charClass(char ch) const | 922 | int 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 | ||
928 | void TEWidget::setMouseMarks(bool on) | 938 | void 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 | ||
942 | void TEWidget::emitSelection() | 952 | void 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 | ||
957 | void TEWidget::emitText(QString text) | 967 | void 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 | ||
963 | void TEWidget::pasteClipboard( ) | 973 | void TEWidget::pasteClipboard( ) |
964 | { | 974 | { |
965 | emitSelection(); | 975 | emitSelection(); |
966 | } | 976 | } |
967 | 977 | ||
968 | void TEWidget::setSelection(const QString& t) | 978 | void 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 | ||
983 | void TEWidget::onClearSelection() | 993 | void 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 | ||
1008 | void TEWidget::doScroll(int lines) | 1018 | void TEWidget::doScroll(int lines) |
1009 | { | 1019 | { |
1010 | scrollbar->setValue(scrollbar->value()+lines); | 1020 | scrollbar->setValue(scrollbar->value()+lines); |
1011 | } | 1021 | } |
1012 | 1022 | ||
1013 | bool TEWidget::eventFilter( QObject *obj, QEvent *e ) | 1023 | bool 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 | ||
1099 | void TEWidget::frameChanged() | 1109 | void 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 | ||
1111 | void TEWidget::Bell() | 1121 | void 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 | ||
1122 | void TEWidget::clearImage() | 1132 | void 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 | ||
1138 | void TEWidget::calcGeometry() | 1148 | void 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 | ||
1172 | void TEWidget::makeImage() | 1211 | void 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 |
1181 | QSize TEWidget::calcSize(int cols, int lins) const | 1220 | QSize 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 | ||
1189 | QSize TEWidget::sizeHint() const | 1228 | QSize TEWidget::sizeHint() const |
1190 | { | 1229 | { |
1191 | return size(); | 1230 | return size(); |
1192 | } | 1231 | } |
1193 | 1232 | ||
1194 | void TEWidget::styleChange(QStyle &) | 1233 | void 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 | ||
1208 | void TEWidget::dragEnterEvent(QDragEnterEvent* e) | 1247 | void 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 | ||
1214 | void TEWidget::dropEvent(QDropEvent* event) | 1253 | void 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 | ||
1269 | void TEWidget::drop_menu_activated(int) | 1308 | void 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 | ||
1301 | QPushButton* TEWidget::cornerButton() { | 1340 | QPushButton* TEWidget::cornerButton() { |
1302 | return m_cornerButton; | 1341 | return m_cornerButton; |
1303 | } | 1342 | } |
1343 | |||
1344 | void 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 | ||
33 | extern unsigned short vt100_graphics[32]; | 33 | extern unsigned short vt100_graphics[32]; |
34 | 34 | ||
35 | 35 | ||
36 | 36 | ||
37 | 37 | ||
38 | 38 | ||
39 | class TESession; | 39 | class TESession; |
40 | 40 | ||
41 | // class Konsole; | 41 | // class Konsole; |
42 | 42 | ||
43 | class TEWidget : public QFrame | 43 | class 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 | ||
50 | public: | 50 | public: |
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 | ||
55 | public: | 55 | public: |
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 | |||
72 | public: | 74 | public: |
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 | ||
85 | public: | 87 | public: |
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 | ||
91 | signals: | 93 | signals: |
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 | ||
105 | protected: | 107 | protected: |
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 | ||
139 | public: | 141 | public: |
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 | ||
150 | public slots: | 152 | public slots: |
151 | 153 | ||
152 | void onClearSelection(); | 154 | void onClearSelection(); |
153 | 155 | ||
154 | protected slots: | 156 | protected 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 | ||
159 | private: | 162 | private: |
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; |
206 | private slots: | 210 | private 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 | ||
11 | EmulationHandler::EmulationHandler( const Profile& prof, QWidget* parent,const char* name ) | 11 | EmulationHandler::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 | } |
31 | EmulationHandler::~EmulationHandler() { | 34 | EmulationHandler::~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 | ||
38 | void EmulationHandler::load( const Profile& prof) { | 41 | void 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 | } |
59 | void EmulationHandler::recv( const QByteArray& ar) { | 62 | void EmulationHandler::recv( const QByteArray& ar) { |
60 | m_teEmu->onRcvBlock(ar.data(), ar.count() ); | 63 | m_teEmu->onRcvBlock(ar.data(), ar.count() ); |
61 | } | 64 | } |
62 | void EmulationHandler::recvEmulation(const char* src, int len ) { | 65 | void 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 | } |
70 | QWidget* EmulationHandler::widget() { | 73 | QWidget* 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 | */ |
76 | void EmulationHandler::setColor( const QColor& fore, const QColor& back ) { | 79 | void 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 | } |
93 | QFont EmulationHandler::font( int id ) { | 96 | QFont 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 | } |
115 | QColor EmulationHandler::foreColor(int col) { | 118 | QColor 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 | } |
139 | QColor EmulationHandler::backColor(int col ) { | 142 | QColor 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 | ||
164 | QPushButton* EmulationHandler::cornerButton() { | 167 | QPushButton* EmulationHandler::cornerButton() { |
165 | return m_teWid->cornerButton(); | 168 | return m_teWid->cornerButton(); |
166 | } | 169 | } |
167 | 170 | ||
168 | 171 | ||
169 | Script *EmulationHandler::script() { | 172 | Script *EmulationHandler::script() { |
170 | return m_script; | 173 | return m_script; |
171 | } | 174 | } |
172 | 175 | ||
173 | bool EmulationHandler::isRecording() { | 176 | bool EmulationHandler::isRecording() { |
174 | return (m_script != 0); | 177 | return (m_script != 0); |
175 | } | 178 | } |
176 | 179 | ||
177 | void EmulationHandler::startRecording() { | 180 | void EmulationHandler::startRecording() { |
178 | if (!isRecording()) | 181 | if (!isRecording()) |
179 | m_script = new Script(); | 182 | m_script = new Script(); |
180 | } | 183 | } |
181 | 184 | ||
182 | void EmulationHandler::clearScript() { | 185 | void 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 | ||
189 | void EmulationHandler::runScript(const Script *script) { | 192 | void EmulationHandler::runScript(const Script *script) { |
190 | emit send(script->script()); | 193 | emit send(script->script()); |
191 | } | 194 | } |
192 | 195 | ||
193 | void EmulationHandler::copy() { | 196 | void EmulationHandler::copy() { |
194 | m_teWid->emitSelection(); | 197 | m_teWid->emitSelection(); |
195 | } | 198 | } |
196 | void EmulationHandler::paste() { | 199 | void 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 | |||
21 | static const ColorEntry color_table[TABLE_COLORS] = | 18 | static 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 | ||
36 | EmulationWidget::EmulationWidget( const Profile& config, QWidget *parent, const char* name ) : WidgetLayer( config, parent, name ) | 33 | EmulationWidget::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 | ||
59 | void EmulationWidget::reloadConfig( const Profile& config ) | 56 | void EmulationWidget::reloadConfig( const Profile& config ) |
60 | { | 57 | { |
61 | 58 | ||
62 | // nothing yet | 59 | // nothing yet |
63 | } | 60 | } |
64 | 61 | ||
65 | EmulationWidget::~EmulationWidget() | 62 | EmulationWidget::~EmulationWidget() |
66 | { | 63 | { |
67 | //clean up | 64 | //clean up |
68 | } | 65 | } |
69 | 66 | ||
70 | static QChar vt100extended(QChar c) | 67 | static 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 | ||
110 | QSize EmulationWidget::calcSize( int cols, int lins ) const | 107 | QSize 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 | ||
119 | void EmulationWidget::setImage( QArray<Character> const newimg, int lines, int columns ) | 116 | void 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 | ||
189 | void EmulationWidget::paintEvent( QPaintEvent* pe ) | 186 | void 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 | ||
234 | void EmulationWidget::calcGeometry() | 231 | void 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 | ||
270 | void EmulationWidget::drawAttrString( QString& string, QPainter &painter, QRect rect, Character attr, bool usePixmap, bool clear ) | 267 | void 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 | ||
303 | void EmulationWidget::scroll( int value ) | 300 | void EmulationWidget::scroll( int value ) |
304 | { | 301 | { |
305 | } | 302 | } |
306 | 303 | ||
307 | void EmulationWidget::setScroll( int cursor, int slines ) | 304 | void 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,1130 +1,1128 @@ | |||
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 | ||
27 | TODO: | 27 | TODO: |
28 | alter Widget to use only QByteArray, where applicable. | 28 | alter 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. |
118 | static const ColorEntry base_color_table[TABLE_COLORS] = | 116 | static 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 | ||
146 | QColor Widget::getDefaultBackColor() | 144 | QColor Widget::getDefaultBackColor() |
147 | { | 145 | { |
148 | return color_table[DEFAULT_BACK_COLOR].color; | 146 | return color_table[DEFAULT_BACK_COLOR].color; |
149 | } | 147 | } |
150 | 148 | ||
151 | const ColorEntry* Widget::getColorTable() const | 149 | const ColorEntry* Widget::getColorTable() const |
152 | { | 150 | { |
153 | return color_table; | 151 | return color_table; |
154 | } | 152 | } |
155 | 153 | ||
156 | const ColorEntry* Widget::getdefaultColorTable() const | 154 | const ColorEntry* Widget::getdefaultColorTable() const |
157 | { | 155 | { |
158 | return base_color_table; | 156 | return base_color_table; |
159 | } | 157 | } |
160 | 158 | ||
161 | 159 | ||
162 | const QPixmap *Widget::backgroundPixmap() | 160 | const 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 | ||
169 | void Widget::setColorTable(const ColorEntry table[]) | 167 | void 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 | ||
200 | unsigned short vt100_graphics[32] = | 198 | unsigned 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 | ||
208 | static QChar vt100extended(QChar c) | 206 | static 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 | ||
247 | static QChar identicalMap(QChar c) | 245 | static QChar identicalMap(QChar c) |
248 | { | 246 | { |
249 | return c; | 247 | return c; |
250 | } | 248 | } |
251 | 249 | ||
252 | void Widget::fontChange(const QFont &) | 250 | void 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 | ||
274 | void Widget::setVTFont(const QFont& f) | 272 | void Widget::setVTFont(const QFont& f) |
275 | { | 273 | { |
276 | QFrame::setFont(f); | 274 | QFrame::setFont(f); |
277 | } | 275 | } |
278 | 276 | ||
279 | QFont Widget::getVTFont() { | 277 | QFont Widget::getVTFont() { |
280 | return font(); | 278 | return font(); |
281 | } | 279 | } |
282 | 280 | ||
283 | void Widget::setFont(const QFont &) | 281 | void 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 | ||
294 | Widget::Widget(QWidget *parent, const char *name) : QFrame(parent,name) | 292 | Widget::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) |
357 | Widget::~Widget() | 355 | Widget::~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 | ||
373 | void Widget::drawAttrStr(QPainter &paint, QRect rect, | 371 | void 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 | ||
409 | void Widget::setImage(const Character* const newimg, int lines, int columns) | 407 | void 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 ); |
415 | HCNT("setImage"); | 413 | HCNT("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 | ||
480 | void Widget::paintEvent( QPaintEvent* pe ) | 478 | void 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 ); |
489 | HCNT("paintEvent"); | 487 | HCNT("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 | ||
546 | void Widget::blinkEvent() | 544 | void 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 | ||
558 | void Widget::resizeEvent(QResizeEvent* ev) | 556 | void 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()); |
564 | HCNT("resizeEvent"); | 562 | HCNT("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 | ||
574 | void Widget::propagateSize() | 572 | void 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 | ||
607 | void Widget::scrollChanged(int) | 605 | void Widget::scrollChanged(int) |
608 | { | 606 | { |
609 | emit changedHistoryCursor(scrollbar->value()); //expose | 607 | emit changedHistoryCursor(scrollbar->value()); //expose |
610 | } | 608 | } |
611 | 609 | ||
612 | void Widget::setScroll(int cursor, int slines) | 610 | void 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 | ||
621 | void Widget::setScrollbarLocation(int loc) | 619 | void 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 | ||
662 | void Widget::mousePressEvent(QMouseEvent* ev) | 660 | void 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 | ||
701 | void Widget::mouseMoveEvent(QMouseEvent* ev) | 699 | void 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 | ||
795 | void Widget::mouseReleaseEvent(QMouseEvent* ev) | 793 | void 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 | ||
820 | void Widget::mouseDoubleClickEvent(QMouseEvent* ev) | 818 | void 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 | ||
870 | void Widget::focusInEvent( QFocusEvent * ) | 868 | void 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 | ||
877 | void Widget::focusOutEvent( QFocusEvent * ) | 875 | void Widget::focusOutEvent( QFocusEvent * ) |
878 | { | 876 | { |
879 | // do nothing, to prevent repainting | 877 | // do nothing, to prevent repainting |
880 | } | 878 | } |
881 | 879 | ||
882 | bool Widget::focusNextPrevChild( bool next ) | 880 | bool 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 | ||
891 | int Widget::charClass(char ch) const | 889 | int 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 | ||
907 | void Widget::setMouseMarks(bool on) | 905 | void 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 | ||
921 | void Widget::emitSelection() | 919 | void 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 | ||
936 | void Widget::emitText(QString text) | 934 | void 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 | ||
942 | void Widget::pasteClipboard( ) | 940 | void Widget::pasteClipboard( ) |
943 | { | 941 | { |
944 | emitSelection(); | 942 | emitSelection(); |
945 | } | 943 | } |
946 | 944 | ||
947 | void Widget::setSelection(const QString& t) | 945 | void 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 | ||
962 | void Widget::onClearSelection() | 960 | void 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 | ||
987 | void Widget::doScroll(int lines) | 985 | void Widget::doScroll(int lines) |
988 | { | 986 | { |
989 | scrollbar->setValue(scrollbar->value()+lines); | 987 | scrollbar->setValue(scrollbar->value()+lines); |
990 | } | 988 | } |
991 | 989 | ||
992 | bool Widget::eventFilter( QObject *obj, QEvent *e ) | 990 | bool 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 | ||
1078 | void Widget::frameChanged() | 1076 | void 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 | ||
1090 | void Widget::Bell() | 1088 | void 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 | ||
1101 | void Widget::clearImage() | 1099 | void 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 | ||
1117 | void Widget::calcGeometry() | 1115 | void 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; |