1
// ----------------------------------------------------------------------------
8
// This file is part of fldigi.
10
// fldigi is free software; you can redistribute it and/or modify
11
// it under the terms of the GNU General Public License as published by
12
// the Free Software Foundation; either version 2 of the License, or
13
// (at your option) any later version.
15
// fldigi is distributed in the hope that it will be useful,
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
// GNU General Public License for more details.
20
// You should have received a copy of the GNU General Public License
21
// along with fldigi; if not, write to the Free Software
22
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
// ----------------------------------------------------------------------------
41
#include <FL/Enumerations.H>
42
#include "File_Selector.h"
49
//=====================================================================
51
// a virtual base class for building either a text viewer or editor
52
// you cannot instantiate this class by itself
53
// only as a base for child classes
55
// text is stored in <string> arrays
56
// the attribute of each character is mirrored in another <string> array
57
//=====================================================================
61
textview :: textview( int x, int y, int w, int h, const char *label )
62
: ReceiveWidget( x, y, w, h, label ),
63
adjusted_colours(false), scrollbar(x+w-SBwidth, y+2, SBwidth, h-4 )
65
scrollbar.linesize( 1 );
66
scrollbar.callback( _scrollbarCB, this );
69
color( FL_BACKGROUND2_COLOR );
72
TextSize = FL_NORMAL_SIZE;
74
for (unsigned i = 0; i < sizeof(TextColor)/sizeof(TextColor[0]); i++) {
75
TextColor[i] = FL_FOREGROUND_COLOR;
77
TextColor[ReceiveWidget::RECV] = FL_FOREGROUND_COLOR;
78
TextColor[ReceiveWidget::XMIT] = FL_RED;
79
TextColor[ReceiveWidget::CTRL] = FL_DARK_GREEN;
80
TextColor[ReceiveWidget::SKIP] = FL_BLUE;
81
TextColor[ReceiveWidget::ALTR] = FL_DARK_MAGENTA;
86
startidx = string::npos;
87
laststartidx = string::npos;
88
highlightstart = string::npos;
89
highlightend = string::npos;
99
textview :: ~textview()
103
void textview::Show() {
108
void textview::Hide() {
113
int textview::handle(int event)
115
if (!adjusted_colours && event == FL_SHOW) {
117
adjusted_colours = true;
123
void textview::setFont(Fl_Font fnt)
127
damage(FL_DAMAGE_ALL);
132
void textview::setFontSize(int siz)
136
damage(FL_DAMAGE_ALL);
141
void textview::setFontColor(Fl_Color clr)
145
int textview::lineCount()
148
size_t len = buff.length();
152
for (size_t n = 0; n < len; n++)
153
if (buff[n] == '\n') cnt++;
157
size_t textview::linePosition(int linenbr)
159
size_t len = buff.length();
161
while (linenbr && (pos < len) ) {
162
if (buff[pos] == '\n')
166
if (pos == len) return 0;
170
size_t textview::xy2bufidx()
172
size_t idx = startidx;
173
size_t len = buff.length();
175
int cheight, cwidth, descent;
178
if (!len) return string::npos;
180
fl_font(TextFont, TextSize);
181
cheight = (int)fl_height();
182
descent = fl_descent();
189
cwidth = (int)fl_width(c);
195
if ( (popx >= xc && (popx < (xc + cwidth))) &&
196
(popy >= yc && (popy < (yc + charheight + descent))) ) {
207
void textview::highlight(bool b)
209
if (highlightstart == string::npos || highlightend == string::npos)
212
for (size_t n = highlightstart; n <= highlightend; n++)
215
for (size_t n = highlightstart; n <= highlightend; n++)
217
damage(FL_DAMAGE_ALL);
220
void textview::adjust_colours(void)
222
for (int i = 0; i < NATTR; i++) {
225
while ((adj = fl_contrast(TextColor[i],
226
FL_BACKGROUND2_COLOR)) != TextColor[i]) {
227
TextColor[i] = (adj == FL_WHITE) ?
228
fl_lighter(TextColor[i]) :
229
fl_darker(TextColor[i]);
235
string textview::findtext()
237
size_t idx, wordstart, wordend;
241
if (idx != string::npos) {
242
wordstart = buff.find_last_of(" \n", idx);
243
if (wordstart == string::npos)
247
wordend = buff.find_first_of(" ,\n", idx);
248
if (wordend == string::npos)
249
wordend = buff.length();
250
selword = buff.substr(wordstart, wordend - wordstart);
257
void textview::highlightword()
259
size_t idx, wordstart, wordend;
262
highlightstart = highlightend = string::npos;
263
if (idx != string::npos) {
264
wordstart = buff.find_last_of(" \n", idx);
265
if (wordstart == string::npos)
269
wordend = buff.find_first_of(" ,\n", idx);
270
if (wordend == string::npos)
271
wordend = buff.length();
274
highlightstart = wordstart;
275
highlightend = wordend;
281
void textview::draw_cursor()
283
if (cursorStyle == NONE) return;
285
typedef struct { int x1, y1, x2, y2; } Segment;
289
int left = cursorX + 1,
290
right = left + cursorwidth,
291
bot = cursorY + descent - 2,
292
top = cursorY - charheight + descent + 2;
294
/* For cursors other than the block, make them around 2/3 of a character
295
width, rounded to an even number of pixels so that X will draw an
296
odd number centered on the stem at x. */
298
if (cursorON == false)
301
fl_color(FL_BACKGROUND2_COLOR);
302
fl_rectf ( X + cursorX, Y + cursorY - charheight + descent, maxcharwidth, charheight);
304
/* Create segments and draw cursor */
305
if ( cursorStyle == CARET_CURSOR ) {
306
int midY = top - charheight / 5;
307
segs[ 0 ].x1 = left; segs[ 0 ].y1 = top; segs[ 0 ].x2 = left; segs[ 0 ].y2 = midY;
308
segs[ 1 ].x1 = left; segs[ 1 ].y1 = midY; segs[ 1 ].x2 = right; segs[ 1 ].y2 = top;
309
segs[ 2 ].x1 = left; segs[ 2 ].y1 = top; segs[ 2 ].x2 = left; segs[ 2 ].y2 = midY - 1;
310
segs[ 3 ].x1 = left; segs[ 3 ].y1 = midY - 1;segs[ 3 ].x2 = right; segs[ 3 ].y2 = top;
312
} else if ( cursorStyle == NORMAL_CURSOR ) {
313
int midX = left + cursorwidth / 2;
314
segs[ 0 ].x1 = left; segs[ 0 ].y1 = bot; segs[ 0 ].x2 = right; segs[ 0 ].y2 = bot;
315
segs[ 1 ].x1 = midX; segs[ 1 ].y1 = bot; segs[ 1 ].x2 = midX; segs[ 1 ].y2 = top;
316
segs[ 2 ].x1 = left; segs[ 2 ].y1 = top; segs[ 2 ].x2 = right; segs[ 2 ].y2 = top;
318
} else if ( cursorStyle == HEAVY_CURSOR ) {
319
int topp1 = top + 1, botm1 = bot - 1,
320
mid = left + cursorwidth / 2,
322
segs[ 0 ].x1 = mid; segs[ 0 ].y1 = bot; segs[ 0 ].x2 = mid; segs[ 0 ].y2 = top;
323
segs[ 1 ].x1 = midp1; segs[ 1 ].y1 = bot; segs[ 1 ].x2 = midp1; segs[ 1 ].y2 = top;
324
segs[ 3 ].x1 = left; segs[ 3 ].y1 = bot; segs[ 3 ].x2 = right; segs[ 3 ].y2 = bot;
325
segs[ 4 ].x1 = left; segs[ 4 ].y1 = top; segs[ 4 ].x2 = right; segs[ 4 ].y2 = top;
326
segs[ 5 ].x1 = left; segs[ 5 ].y1 = botm1; segs[ 5 ].x2 = right; segs[ 5 ].y2 = botm1;
327
segs[ 6 ].x1 = left; segs[ 6 ].y1 = topp1; segs[ 6 ].x2 = right; segs[ 6 ].y2 = topp1;
329
} else if ( cursorStyle == DIM_CURSOR ) {
330
int midX = left + cursorwidth / 2;
331
segs[ 0 ].x1 = left; segs[ 0 ].y1 = bot; segs[ 0 ].x2 = right; segs[ 0 ].y2 = bot;
332
segs[ 1 ].x1 = midX; segs[ 1 ].y1 = bot; segs[ 1 ].x2 = midX; segs[ 1 ].y2 = top;
333
segs[ 2 ].x1 = left; segs[ 2 ].y1 = top; segs[ 2 ].x2 = right; segs[ 2 ].y2 = top;
335
} else if ( cursorStyle == BLOCK_CURSOR ) {
336
right = cursorX + maxcharwidth;
337
segs[ 0 ].x1 = left; segs[ 0 ].y1 = bot; segs[ 0 ].x2 = right; segs[ 0 ].y2 = bot;
338
segs[ 1 ].x1 = right; segs[ 1 ].y1 = bot; segs[ 1 ].x2 = right; segs[ 1 ].y2 = top;
339
segs[ 2 ].x1 = right; segs[ 2 ].y1 = top; segs[ 2 ].x2 = left; segs[ 2 ].y2 = top;
340
segs[ 3 ].x1 = left; segs[ 3 ].y1 = top; segs[ 3 ].x2 = left; segs[ 3 ].y2 = bot;
343
fl_color( TextColor[ReceiveWidget::RECV] );
345
for ( int k = 0; k < nSegs; k++ ) {
346
fl_line( X + segs[ k ].x1, Y + segs[ k ].y1, X + segs[ k ].x2, Y + segs[ k ].y2 );
350
void textview::drawall()
356
fl_font(TextFont, TextSize);
357
charheight = fl_height();
358
maxcharwidth = (int)fl_width('X');
359
descent = fl_descent();
362
// resize the scrollbar to be a constant width
363
scrollbar.resize( x()+w()-SBwidth, y()+2, SBwidth, h()-4 );
367
cursorY = charheight - descent;
369
if ((len = buff.length()) == 0) {
370
fl_push_clip( X, Y, W, H);
376
nlines = lineCount();
377
line = nlines - H / charheight - scrollbar.value();
379
startidx = linePosition(line);
382
fl_push_clip( X, Y, W, H );
384
memset(cstr, 0, 1000);
388
while(endidx < len) {
391
while (endidx < len ) {
396
cursorY += charheight;
398
memset(cstr, 0, 1000);
403
if ((a & 0x20) == 0x20) {
404
fl_color(FL_SELECTION_COLOR);
405
fl_rectf ( X + cursorX, Y + cursorY - charheight + descent, maxcharwidth, charheight);
406
fl_color (TextColor[(int)a & 0x0F]);
407
fl_draw ( cstr, 1, X + cursorX, Y + cursorY );
408
cursorX += (int)fl_width(c);
414
while (endidx < len && c != '\n' && a == attr[endidx] && pos < 999) {
419
fl_color (TextColor[(int)a & 0x0F]);
420
fl_draw ( cstr, X + cursorX, Y + cursorY );
421
cursorX += (int)fl_width(cstr);
422
memset(cstr, 0, 1000);
427
laststartidx = startidx;
433
void textview::drawchars()
436
size_t startidx = string::npos;
442
if ((len = buff.length()) == 0) {
447
fl_font(TextFont, TextSize);
448
charheight = fl_height();
449
descent = fl_descent();
450
maxcharwidth = (int)fl_width('X');
452
nlines = lineCount();
453
line = nlines - H / charheight - scrollbar.value();
455
startidx = linePosition(line);
456
if (startidx != laststartidx) {
461
fl_push_clip( X, Y, W, H );
463
while (endidx < len) {
464
fl_color(FL_BACKGROUND2_COLOR);
465
fl_rectf ( X + cursorX, Y + cursorY - charheight + descent, maxcharwidth, charheight);
470
cursorY += charheight;
473
if ((a & 0x20) == 0x20)
474
fl_color(FL_SELECTION_COLOR);
476
fl_color (TextColor[a & 0x0F]);
477
fl_draw ( cstr, 1, X + cursorX, Y + cursorY );
478
cursorX += (int)fl_width(c);
482
laststartidx = startidx;
488
void textview::drawmodify(size_t modidx)
490
if (modidx < laststartidx )
494
if (buff[modidx] == '\n')
496
// modify the character insitu
497
// find the screen location for the character redraw
498
size_t posidx = laststartidx;
499
int posX = 0, posY = charheight - descent;
502
fl_font(TextFont, TextSize);
503
while (posidx < modidx) {
509
posX += (int)(fl_width(c));
513
// should now be pointing to the (x,y) screen location for the character
515
cstr[0] = buff[modidx];
517
if ((attr[modidx] & 0x20) == 0x20)
518
fl_color(FL_SELECTION_COLOR);
520
fl_color(FL_BACKGROUND2_COLOR);
521
fl_rectf ( X + posX, Y + posY - charheight + descent, (int)fl_width(c), charheight);
522
// draw new with attribute
523
fl_color (TextColor[(int)attr[modidx] & 0x0F]);
524
fl_draw ( cstr, 1, X + posX, Y + posY );
527
void textview::draw()
529
if (damage() & FL_DAMAGE_ALL) {
533
if (damage() & (FL_DAMAGE_ALL | 1)) {
537
if (damage() & (FL_DAMAGE_ALL | 2)) {
541
if (damage() & (FL_DAMAGE_ALL | 4)) {
542
for (size_t i = draw_mod_range.start; i <= draw_mod_range.end; ++i)
544
draw_mod_range.start = draw_mod_range.end + 1;
549
void textview::scrollbarCB()
551
damage(FL_DAMAGE_ALL);
554
void textview::_backspace()
557
if (buff.empty()) return;
559
size_t lastcrlf = buff.rfind('\n');
561
if (lastcrlf == string::npos) lastcrlf = 0;
564
if (attr[attr.length() - 1] == -1) { // soft linefeed skip over
565
buff.erase(buff.length()-1);
566
attr.erase(attr.length()-1);
568
lastcrlf = buff.rfind('\n');
569
if (lastcrlf == string::npos) lastcrlf = 0;
570
fl_font(TextFont, TextSize);
571
for (size_t i = lastcrlf; i < buff.length(); i++) {
572
wrappos += (int)(fl_width(buff[i]));
576
c = buff[buff.length()-1];
578
buff.erase(buff.length()-1);
579
attr.erase(attr.length()-1);
581
lastcrlf = buff.rfind('\n');
582
if (lastcrlf == string::npos) lastcrlf = 0;
583
fl_font(TextFont, TextSize);
584
for (size_t i = lastcrlf; i < buff.length(); i++) {
585
wrappos += (int)(fl_width(buff[i]));
588
buff.erase(buff.length()-1);
589
attr.erase(attr.length()-1);
590
fl_font(TextFont, TextSize);
591
wrappos -= (int)fl_width(c);
593
damage(FL_DAMAGE_ALL);
598
void textview::add_( unsigned char c, int attribute)
606
if (c >= ' ' && c <= '~') {
609
fl_font(TextFont, TextSize);
610
charwidth = (int)fl_width(c);
611
if (charwidth > maxcharwidth)
612
maxcharwidth = charwidth;
613
wrappos += charwidth;
614
} else if (c == '\n') {
620
if (wrappos >= (w() - 24 - maxcharwidth)) {
621
size_t lastspace = buff.find_last_of(' ');
623
|| lastspace == string::npos
624
|| (buff.length() - lastspace) >= 10
625
|| (buff.length() - lastspace) == 1) {
627
attr += -1; // soft linefeed attribute
631
buff.insert(lastspace+1, 1, '\n');
632
attr.insert(lastspace+1, 1, -1);
634
fl_font(TextFont, TextSize);
635
for (size_t i = lastspace+2; i < buff.length(); i++)
636
wrappos += (int)fl_width(buff[i]);
637
damage(FL_DAMAGE_ALL);
647
void textview::add( unsigned char c, int attribute)
649
if (c < ' ' || c == 127) { // we must look this up and insert it as a string
651
const char *cp = (attribute == CTRL) ? ascii2[i] : ascii[i];
653
add_(*cp++, attribute);
660
void textview::add( const char *text, int attr )
666
void textview::clear()
671
highlightstart = string::npos;
672
highlightend = string::npos;
674
startidx = string::npos;
677
// cursorY = charheight;
678
laststartidx = string::npos;
680
damage(FL_DAMAGE_ALL);
686
void textview :: setScrollbar()
688
int lines = lineCount();
691
fl_font(TextFont, TextSize);
692
charheight = fl_height();
693
scrollbar.range (lines, 0);
694
if (lines * charheight <= h()-4)
697
size = (double)(h()-4) / (double)(lines * charheight);
698
if (size < 0.08) size = 0.08;
699
scrollbar.slider_size( size );
702
void textview :: rebuildsoft(int W)
706
return; // same width no rebuild needed
707
// remove all soft linefeeds
708
while ((lfpos = attr.find(-1)) != string::npos) {
709
buff.erase(lfpos, 1);
710
attr.erase(lfpos, 1);
712
int endidx = W - 24 - maxcharwidth;
715
while (chpos < buff.length()) {
716
if (buff[chpos] == '\n')
719
fl_font(TextFont, TextSize);
720
wrappos += (int)fl_width(buff[chpos]);
721
if (wrappos >= endidx) {
722
size_t lastspace = buff.find_last_of(' ', chpos);
724
|| lastspace == string::npos
725
|| (chpos - lastspace) >= 10
726
|| (chpos == lastspace) ) {
727
buff.insert(chpos, 1, '\n');
728
attr.insert(chpos, 1, -1);
732
buff.insert(lastspace+1, 1, '\n');
733
attr.insert(lastspace+1, 1, -1);
736
fl_font(TextFont, TextSize);
737
for (size_t i = lastspace+2; i < chpos; i++)
738
wrappos += (int)fl_width(buff[i]);
745
void textview :: resize( int x, int y, int w, int h )
752
Fl_Widget::resize( x, y, w, h );
757
//=====================================================================
759
// Viewer for received text
760
// derived from Class textview
762
// redefines the handle() and menu_cb() functions specified in the
763
// base class. All other functions are in the base class
764
//=====================================================================
766
void TextView::saveFile()
768
char * fn = File_Select(
769
"Select ASCII text file",
779
Fl_Menu_Item TextView::viewmenu[] = {
780
{"@-9$returnarrow &QRZ this call", 0, 0 }, // 0
781
{"@-9-> &Call", 0, 0 }, // 1
782
{"@-9-> &Name", 0, 0 }, // 2
783
{"@-9-> QT&H", 0, 0 }, // 3
784
{"@-9-> &Locator", 0, 0 }, // 4
785
{"@-9-> &RSTin", 0, 0, 0, FL_MENU_DIVIDER }, // 5
786
{"Insert divider", 0, 0 }, // 6
787
{"C&lear", 0, 0 }, // 7
788
// {"&Copy", 0, 0, 0, FL_MENU_DIVIDER },
789
{"Save to &file...", 0, 0, 0, FL_MENU_DIVIDER }, // 8
790
{"Word &wrap", 0, 0, 0, FL_MENU_TOGGLE }, // 9
794
int viewmenuNbr = 10;
796
TextView::TextView( int x, int y, int w, int h, const char *label )
797
: ReceiveWidget( x, y, w, h, label ), textview ( x, y, w, h, label )
799
cursorStyle = NONE;// BLOCK_CURSOR;
805
void TextView::menu_cb(int val)
807
// handle(FL_UNFOCUS);
809
case 0: // select call & do qrz query
811
extern void QRZquery();
814
case 1: // select call
815
inpCall->value(findtext().c_str());
817
case 2: // select name
818
inpName->value(findtext().c_str());
820
case 3: // select QTH
821
inpQth->value(findtext().c_str());
823
case 4: // select locator
824
inpLoc->value(findtext().c_str());
826
case 5: // select RST rcvd
827
inpRstIn->value(findtext().c_str());
830
add("\n <<================>>\n", RECV);
835
// case 8: // clipboard copy
842
case 9: // wordwrap toggle
843
wordwrap = !wordwrap;
852
int TextView::handle(int event)
854
// handle events inside the textview and invoked by Right Mouse button or scrollbar
855
if (Fl::event_inside( this )) {
856
const Fl_Menu_Item * m;
857
int xpos = Fl::event_x();
858
int ypos = Fl::event_y();
859
if (xpos > x() + w() - SBwidth) {
860
scrollbar.handle(event);
863
if (event == FL_PUSH && Fl::event_button() == 3) {
867
m = viewmenu->popup(xpos, ypos, 0, 0, 0);
869
for (int i = 0; i < viewmenuNbr; i++)
870
if (m == &viewmenu[i]) {
878
// if (event == FL_PUSH && Fl::event_button() == 1) {
879
// popx = xpos - x();
880
// popy = ypos - y();
881
// size_t pos = xy2bufidx();
882
// if (pos != string::npos)
883
// std::cout << buff[pos] << " @ " << pos << " ==> " << popx << ", " << popy << std::endl;
885
// std::cout << "? position\n";
890
return textview::handle(event);
893
//=====================================================================
895
// derived from base class textview
896
// redfines the handle() and menu_cb() functions specified in the
897
// base class. All other functions are in the base class
898
//=====================================================================
900
Fl_Menu_Item editmenu[] = {
901
{"clear", 0, 0, 0, FL_MENU_DIVIDER },
902
{"File", 0, 0, 0, FL_MENU_DIVIDER },
904
{"^r", 0, 0, 0, FL_MENU_DIVIDER },
910
TextEdit::TextEdit( int x, int y, int w, int h, const char *label )
911
: ReceiveWidget( x, y, w, h, label ), textview ( x, y, w, h, label ),
912
TransmitWidget( x, y, w, h, label )
916
textview::cursorStyle = NORMAL_CURSOR;
922
void TextEdit::readFile()
924
char * fn = File_Select(
925
"Select ASCII text file",
941
void TextEdit::menu_cb(int val)
950
if (val == 2 && buff.empty()) {
952
trx_state = STATE_TX;
953
fl_unlock(&trx_mutex);
954
wf->set_XmtRcvBtn(true);
959
if (active_modem->get_mode() == MODE_MFSK16)
960
active_modem->makeTxViewer(0,0);
963
void TextEdit::clear() {
969
void TextEdit::clear_sent() {
970
// FIXME: clear from 0 to xmtidx
974
int TextEdit::handle_fnckey(int key) {
975
int b = key - FL_F - 1;
979
b += altMacros * NUMMACKEYS;
980
if (!(macros.text[b]).empty())
986
int TextEdit::handle_key() {
987
int key = Fl::event_key();
989
if (key == FL_Escape) {
991
active_modem->set_stopflag(true);
996
if (key == FL_Pause) {
997
if (trx_state != STATE_TX) {
999
trx_state = STATE_TX;
1000
fl_unlock(&trx_mutex);
1001
wf->set_XmtRcvBtn(true);
1008
if (key == (FL_KP + '+')) {
1009
if (active_modem == cw_modem) active_modem->incWPM();
1013
if (key == (FL_KP + '-')) {
1014
if (active_modem == cw_modem) active_modem->decWPM();
1018
if (key == (FL_KP + '*')) {
1019
if (active_modem == cw_modem) active_modem->toggleWPM();
1024
if (key >= FL_F && key <= FL_F_Last)
1025
return handle_fnckey(key);
1027
if (key == FL_Tab && active_modem == cw_modem) {
1028
while (xmtidx < buff.length()) {
1029
attr[xmtidx] = SKIP;
1032
damage(FL_DAMAGE_ALL);
1037
if (key == FL_Left) {
1038
active_modem->searchDown();
1042
if (key == FL_Right) {
1043
active_modem->searchUp();
1048
if (key == FL_Enter) {
1054
if (key == FL_BackSpace) {
1056
if (xmtidx > buff.length()) {
1057
xmtidx = buff.length();
1063
if (key == '1' || key == '2' || key == '3' || key == '4')
1064
if (Fl::event_state() && FL_ALT) {
1065
altMacros = key - '1';
1066
for (int i = 0; i < 12; i++)
1067
btnMacro[i]->label(macros.name[i + (altMacros * NUMMACKEYS)].c_str());
1068
static char alt_text[4];
1069
snprintf(alt_text, sizeof(alt_text), "%d", altMacros + 1);
1070
btnAltMacros->label(alt_text);
1071
btnAltMacros->redraw_label();
1075
const char *ch = Fl::event_text();
1081
int TextEdit::handle(int event)
1083
// handle events inside the textedit widget
1084
if (event == FL_UNFOCUS && Fl::focus() != this) {
1085
textview::cursorON = false;
1089
if (event == FL_FOCUS) {
1090
textview::cursorON = true;
1094
if (event == FL_KEYBOARD) {
1095
return handle_key();
1097
if (Fl::event_inside( this )) {
1098
const Fl_Menu_Item * m;
1099
int xpos = Fl::event_x();
1100
int ypos = Fl::event_y();
1101
if (xpos > x() + w() - SBwidth) {
1102
scrollbar.handle(event);
1106
if (event == FL_PUSH && Fl::event_button() == 3) {
1109
m = editmenu->popup(xpos, ypos, 0, 0, 0);
1111
for (int i = 0; i < editmenuNbr; i++)
1112
if (m == &editmenu[i]) {
1123
textview::cursorON = true;
1128
textview::cursorON = true;
1132
textview::cursorON = false;
1137
return textview::handle(event);
1140
int TextEdit::nextChar()
1150
if (buff.empty()) return -1;
1151
if (xmtidx == buff.length()) return -1;
1152
if (attr[xmtidx] == -1) {
1154
if (xmtidx == buff.length()) return -1;
1157
REQ(&TextEdit::update_xmit_text, this, xmtidx);
1160
return (buff[xmtidx++]);
1163
void TextEdit::cursorON()
1165
textview::cursorON = true;
1169
void TextEdit::update_xmit_text(size_t i)
1172
if (draw_mod_range.start > i)
1173
draw_mod_range.start = i;
1174
draw_mod_range.end = i;