1 /***************************************************************************
2 Edit.cxx - The main Editor implementation
3 -------------------
4 begin : Thu Mar 1 13:15:18 IST 2001
5 copyright : (C) 2001 by Arie Tal
6 email : tal_arie@yahoo.com
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22
23 #ifndef WIN32
24 # include <unistd.h> //PORT:
25 #endif
26 #include <signal.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include "Edit.h"
30 #include "Action.h"
31 #include <stdlib.h>
32 #include "langdep.h"
33 #include "HebrewEditor.h"
34
35 #ifndef TRUE
36 #define TRUE 1
37 #define FALSE 0
38 #endif
39
40 #include "LineEdit.h"
41
42 char
43 Edit::buffer[MAX_SCREEN_WIDTH] ;
44 char
45 Edit::buffer2[MAX_SCREEN_WIDTH] ;
46
47
48 ///////////////////////////////////////////////////////
49 //// AUXILIARY FUNCTIONS
50 ///////////////////////////////////////////////////////
51
52
53
54 void
_markBlock(int copy_to_scratch)55 Edit::_markBlock(int copy_to_scratch)
56 {
57 _markBlock(file.getStartMarker(), file.getEndMarker(), copy_to_scratch) ;
58 }
59
60 void
_markBlock(Marker startm,Marker endm,int copy_to_scratch)61 Edit::_markBlock(Marker startm, Marker endm, int copy_to_scratch)
62 {
63 if (!copy_to_scratch) return ;
64
65 if ((startm.line > 0) && (endm.line > 0) &&
66 ((endm.line > startm.line) || ((endm.line == startm.line) && (endm.offset > startm.offset))) ) {
67 int curline = current_line ;
68 if (he->scratch->from)
69 if (he->scratch->from != this)
70 he->scratch->from->file.unmarkBlock() ;
71 if (!read_only)
72 he->scratch->from = this ;
73 else
74 he->scratch->from = (Edit *)0 ;
75
76 he->scratch->file.eraseContent() ;
77 he->scratch->current_offset = 0 ; he->scratch->curx = 1 ; he->scratch->current_line = 1 ;
78
79 if (startm.line == endm.line) {
80 aString tmp = ((aString &)(file.line(startm.line))).at(startm.offset, endm.offset) ;
81 (aString &)(he->scratch->file.line(1)) = tmp ;
82 } else {
83 int cl=1 ;
84 aString tmp = ((aString &)(file.line(startm.line))).at(startm.offset, ((aString &)(file.line(startm.line))).length()) ;
85 (aString &)(he->scratch->file.line(cl)) = tmp ;
86 for (int l = startm.line+1; l < endm.line ; l++) {
87 tmp = (aString &)(file.line(l)) ;
88 he->scratch->file.insert_after(cl++, (char *)(const char *)tmp) ;
89 }
90 (aString &)tmp = ((aString &)(file.line(endm.line))).at(0, endm.offset) ;
91 he->scratch->file.insert_after(cl++,(char *)(const char *)tmp) ;
92 he->scratch->file.line(1) ;
93 he->scratch->current_offset = 0 ; he->scratch->curx = 1 ; he->scratch->current_line = 1 ;
94 }
95 // he->scratch->file.recompile_file(sizex) ;
96 // he->scratch->_relocate_curx(0) ;
97 // he->scratch->modified = 1 ;
98 // he->scratch->_calc_curx() ;
99 file.line(curline) ;
100 } else {
101 he->scratch->file.eraseContent() ;
102 he->scratch->current_offset = 0 ; he->scratch->curx = 1 ; he->scratch->current_line = 1 ;
103 // he->scratch->file.recompile_file(sizex) ;
104 // he->scratch->_relocate_curx(0) ;
105 // he->scratch->modified = 1 ;
106 // he->scratch->_calc_curx() ;
107 }
108 }
109
110
111
112 int
_x_pos()113 Edit::_x_pos()
114 {
115 return _x_position ;
116 }
117
118 char*
_newline()119 Edit::_newline()
120 {
121 static aString data ;
122 data = " \n" ;
123 file.line(current_line)._insert_ch(curx,current_offset,input.translate_char(' '), _x_position) ;
124 _relocate_curx(1) ;
125 file.insert_after(current_line, (file.line(current_line)).split(curx)) ;
126 file.recompile_section(sizex) ;
127 if (current_offset >= file.line(current_line).line_count(sizex)) cury-- ;
128 _relocate_curx(0) ;
129
130 int tmp=current_line ; /////// TAKE CARE OF AUTOINDENT
131 int margin = (file.line(tmp-1)).getMargin() + MARGIN_FIX ;
132 if (margin < 0) margin = 0 ;
133 if (margin > sizex/2) margin = sizex/2 ;
134 aString tmpstr = (aString &)(file.line(tmp)) ;
135 aString tmprep = areplicate(' ', margin) ;
136 data += tmprep ;
137 (aString& )(file.line(tmp)) = tmprep + tmpstr ;
138 file.recompile_section(sizex) ;
139 for (int i=0; i<margin; i++) _relocate_curx(1) ;
140 return (char *)(const char *)data ;
141 }
142
143 void
_maketitle(int show)144 Edit::_maketitle(int show)
145 {
146 input.set_mode(keyboard_mode) ;
147 if (show) {
148 aString kbmode = "(English)" ;
149 aString Modified = "(modified)" ;
150 char buff[1000] ;
151 if (keyboard_mode == hebrew)
152 kbmode="(Hebrew) " ;
153 if (!undo.is_modified()) Modified = " " ;
154 sprintf(buff,"%10s Line: %5d Column: %5d %s #%s", (const char *)Modified,
155 current_line, curx, (const char *)kbmode,
156 (const char *)name) ;
157 for (int i=strlen(buff) ; i<sizex ; i++)
158 strcat(buff," ") ;
159 win->BottomTitleStr(buff) ;
160 }
161 }
162
163 void
_quite_refresh()164 Edit::_quite_refresh()
165 {
166 _display_line(cury) ;
167 }
168
169 void
_refresh()170 Edit::_refresh()
171 {
172 aString emptyline = areplicate(' ',sizex) ;
173 int i ;
174 _maketitle() ;
175 for (i=1 ; (i <= sizey) /*&& (i <= file.lines())*/ ; i++)
176 _display_line(i) ;
177 for (; i <= sizey ; i++)
178 win->MVAddStr(i-1+screen_start_line,screen_start_column,(char *)(const char *)emptyline) ;
179 win->Move(cury-1+screen_start_line,_x_pos()+screen_start_column) ;
180 win->scr->Refresh() ;
181 win->Refresh() ;
182 }
183 void
184
_scroll(int lines,int refresh_flag)185 Edit::_scroll(int lines, int refresh_flag)
186 {
187 if (lines < 0) {
188 for (int i=0; i< -lines; i++) {
189 if (_line_to_display(sizey+1)) {
190 if (refresh_flag) {
191 win->Move(screen_start_line,sizex-1+screen_start_column) ;
192 win->DeleteLn() ;
193 }
194 if (first_offset < (file.line(first_line)).line_count(sizex) - 1)
195 first_offset++ ;
196 else {
197 first_line++ ;
198 first_offset = 0 ;
199 }
200 if (refresh_flag)
201 _display_line(sizey) ;
202 }
203 }
204 } else {
205 for (int i=0; i< lines ; i++) {
206 if ((first_line > 1) || ((first_line == 1) && first_offset)) {
207 if (refresh_flag) {
208 win->Move(sizey-1+screen_start_line,screen_start_column) ;
209 win->DeleteLn() ;
210 win->Move(screen_start_line,sizex-1+screen_start_column) ;
211 win->InsertLn() ;
212 }
213 if (first_offset)
214 first_offset-- ;
215 else {
216 first_line-- ;
217 first_offset = (file.line(first_line)).line_count(sizex)-1 ;
218 }
219 if (refresh_flag)
220 _display_line(1) ;
221 }
222 }
223 }
224 }
225
226 void
_display_line(int num)227 Edit::_display_line(int num) // display screan line number num
228 {
229 aString emptyline = areplicate(' ',sizex) ;
230 int tnum = 0 ;
231 int line, offset ;
232 line=first_line ;
233 if ((file.line(line)).line_count(sizex) - first_offset >= num)
234 offset = first_offset + num - 1;
235 else {
236 tnum = (file.line(line)).line_count(sizex) - first_offset ;
237 for (line++;((line <= file.lines()) && (tnum + (file.line(line)).line_count(sizex) < num)) ;
238 tnum += (file.line(line++)).line_count(sizex)) ;
239 offset = (num - tnum) - 1 ;
240 }
241 if ((line<=file.lines()) && (offset >= 0)) {
242 // aString attributes = areplicate(' ', sizex) ;
243 // The following code will be replaced with a code getting the original attributes
244 // from the representation strings
245 char *origatts = new char [sizex+1] ;
246 for (int j=0; j<sizex; j++)
247 origatts[j] = ' ' ;
248 origatts[sizex] = '\0' ;
249 char *origattptr = origatts ;
250 // end of to be replaced code
251
252 char *atts = workbuffer ;
253 *atts = '\0' ;
254
255 hebStringMode lang = (file.line(line)).getMajorMode() ;
256 hebStringMode mlang = lang ;
257 // if (lang == StrHebrew) {
258 // *atts++ = '2' ;
259 // *atts='\0' ;
260 // }
261 char lastCode = 0 ;
262 int att1on = 0 ;
263 int att2on = 0 ;
264 int att3on = 0 ;
265 for (int i=0; i< sizex; i++) {
266 int l = (file.line(line)).getCurrentXlocation(offset, i) ;
267 hebStringMode nlang= (file.line(line)).getCurrentXlang(offset, i) ;
268 char code = (file.line(line)).getCurrentXcode(offset, i) ;
269 if (l != SPLIT_VALUE) {
270 if (nlang != lang) {
271 if (nlang == mlang) {
272 *atts++ = '@' ;
273 *atts='\0' ;
274 att1on = 0 ;
275 } else {
276 *atts++ = '2' ;
277 *atts='\0' ;
278 att1on = 1 ;
279 }
280 lang = nlang ;
281 } // end if
282 if (code != lastCode) {
283 if ((code & INVALID_HEBREW_WORD) ||
284 (code & INVALID_ENGLISH_WORD))
285 {
286
287 *atts++ = '3' ;
288 *atts='\0' ;
289 att2on = 1 ;
290 } else {
291 *atts++ = '#' ;
292 *atts='\0' ;
293 att2on = 0 ;
294 }
295 if (code & INVALID_LAXET_COMMAND)
296 {
297
298 *atts++ = '4' ;
299 *atts='\0' ;
300 att3on = 1 ;
301 } else {
302 *atts++ = '$' ;
303 *atts='\0' ;
304 att3on = 0 ;
305 }
306 lastCode = code ;
307 }
308 } else {
309 if (att1on) {
310 *atts++ = '@' ;
311 *atts='\0' ;
312 att1on = 0 ;
313 lang=mlang ;
314 }
315 if (att2on) {
316 *atts++= '#' ;
317 *atts='\0' ;
318 att2on = 0 ;
319 lastCode = 0 ;
320 }
321 if (att3on) {
322 *atts++= '$' ;
323 *atts='\0' ;
324 att3on = 0 ;
325 lastCode = 0 ;
326 }
327 }
328
329 while ((*atts++=*origattptr++) != ' ') ;
330 // *atts++ = ' ' ; // replace this with the original attributes instead
331 // by copying all non spaces until and including the first
332 // encountered space
333 *atts='\0' ;
334 // while (strcmp(attributes.at(locale-1, locale) , " ")) locale++ ;
335 } // end for
336 // add code here to copy all attributes until end of original attribute string
337 strcat(atts, origattptr) ;
338 // code to be removed
339 delete origatts ;
340 // end of code to be removed
341
342 Marker startm = file.getStartMarker() , endm = file.getEndMarker() ;
343 if ((!file.markActive()) || (line < startm.line) || (line > endm.line)) {
344 strcpy(workbuffer2, workbuffer) ;
345 } else {
346 // char *rep = (file.line(line)).represent(sizex,offset) ;
347 // char *prep = rep ;
348 if ((line >= startm.line) && (line <= endm.line)) {
349 char *atts1 = workbuffer ;
350 char *atts2 = workbuffer2 ;
351 int reversed = 0 ;
352 if ((line > startm.line) && (line < endm.line)) {
353 *atts2++ = '1' ;
354 *atts2='\0' ;
355 reversed =1 ;
356 }
357 for (int i=0; i< sizex; i++) {
358 int l = (file.line(line)).getCurrentXlocation(offset, i) ;
359 if ((l != SPLIT_VALUE) &&
360 (
361 ((line > startm.line) && (line < endm.line)) ||
362 ((line == startm.line) && (startm.line < endm.line) && (l > startm.offset)) ||
363 ((startm.line < endm.line) && (line == endm.line) && (l <= endm.offset)) ||
364 ((startm.line == endm.line) && (l > startm.offset) && (l <= endm.offset))
365 )
366 ) {
367 if (!reversed) {
368 *atts2++ = '1' ;
369 *atts2='\0' ;
370 reversed = 1 ;
371 }
372 } else {
373 if (reversed) {
374 *atts2++ = '!' ;
375 *atts2='\0' ;
376 reversed = 0 ;
377 }
378 }
379 while ((*atts2++=*atts1++) != ' ') ;
380 *atts2 = '\0' ;
381 // *atts2++ = *atts1++ ;
382 // while (*atts1 != ' ') *atts2++ = *atts1++ ;
383 } // end of for
384 strcpy(atts2,"!@#$") ; // Turn off all attributes
385 } // end of if
386 }
387 // aString toDisplay = (file.line(line)).represent(sizex, offset) ;
388
389 win->MVAddStrAttr(num-1+screen_start_line,screen_start_column,
390 (file.line(line)).represent(sizex,offset),
391 workbuffer2) ;
392 } else
393 win->MVAddStr(num-1+screen_start_line,screen_start_column,(char *)(const char *)emptyline) ;
394 }
395
396 int
_line_to_display(int num)397 Edit::_line_to_display(int num) // display screan line number num
398 {
399 int tnum = 0 ;
400 int line, offset ;
401 line=first_line ;
402 if ((file.line(line)).line_count(sizex) - first_offset >= num)
403 offset = first_offset + num - 1;
404 else {
405 tnum = (file.line(line)).line_count(sizex) - first_offset ;
406 for (line++;(tnum + (file.line(line)).line_count(sizex) < num) &&
407 (line <= file.lines()) ;
408 tnum += (file.line(line++)).line_count(sizex)) ;
409 offset = (num - tnum) - 1 ;
410 }
411 if (line <= file.lines())
412 return TRUE ;
413 return FALSE ;
414 }
415
416 int
_relocate_curx(int update)417 Edit::_relocate_curx(int update)
418 {
419 if (curx + update < 1) {
420 if ((current_offset > 0) || (current_line > 1)) {
421 _previous_line() ;
422 curx = file.line(current_line).length() ;
423 return _relocate_curx(0) ;
424 }
425 return 0 ;
426 }
427
428 if (curx+update > ((aString &)file.line(current_line)).length()) {
429 if ((current_offset < (file.line(current_line)).line_count(sizex)-1) || (current_line < file.lines())) {
430 _next_line() ;
431 curx = 1 ;
432 return _relocate_curx(0) ;
433 }
434 return 0 ;
435 }
436 curx += update ;
437 int newcurx = curx ;
438 int count = file.line(current_line).line_count(sizex) ;
439 for (int i=0 ; i<count; i++) {
440 for (int j=0; j<sizex ; j++) {
441 if (file.line(current_line).getCurrentXlocation(i,j) == curx) {
442 while (current_offset > i) _previous_line() ;
443 while (current_offset < i) _next_line() ;
444 _x_position = j ;
445 curx = newcurx ;
446 hebStringMode mode = file.line(current_line).getCurrentXlang(current_offset,_x_position) ;
447 if (mode == StrHebrew)
448 keyboard_mode = hebrew ;
449 else
450 keyboard_mode = english ;
451 return 1;
452 }
453 }
454 }
455 return 0 ;
456 }
457
458 // calculate curx, while fixing _x_position and languageMode as well
459 void
_calc_curx()460 Edit::_calc_curx()
461 {
462 int x = file.line(current_line).getCurrentXlocation(current_offset, _x_position) ;
463 hebStringMode mode = file.line(current_line).getCurrentXlang(current_offset,_x_position) ;
464 if (x != SPLIT_VALUE) {
465 if (mode == StrHebrew)
466 keyboard_mode = hebrew ;
467 else
468 keyboard_mode = english ;
469 curx = x ;
470 return ; // a correct location
471 }
472 // current_offset = 0 ;
473 if (mode == StrHebrew) { // look to the left until you reach sizex, then look to the right
474 int tmp = _x_position ;
475 while ((x==SPLIT_VALUE) && (++_x_position < sizex))
476 x = file.line(current_line).getCurrentXlocation(current_offset,_x_position) ;
477 if (x == SPLIT_VALUE) {
478 _x_position = tmp ;
479 while ((x==SPLIT_VALUE) && (--_x_position >= 0))
480 x = file.line(current_line).getCurrentXlocation(current_offset,_x_position) ;
481 }
482 // hebStringMode mode1 = file.line(current_line).getCurrentXlang(current_offset,_x_position) ;
483 // assert(x != SPLIT_VALUE) ; // has to be here, or else it is a bug elsewhere
484 if (x==SPLIT_VALUE) { // this is probably an empty line
485 if ((file.line(current_line)).getMajorMode() == StrHebrew)
486 x = sizex ;
487 else
488 x = 1 ;
489 }
490 if (mode == StrHebrew)
491 keyboard_mode = hebrew ;
492 else
493 keyboard_mode = english ;
494 curx = x ;
495 return ;
496 } else {
497 int tmp = _x_position ;
498 while ((x==SPLIT_VALUE) && (--_x_position >= 0))
499 x = file.line(current_line).getCurrentXlocation(current_offset,_x_position) ;
500 if (x == SPLIT_VALUE) {
501 _x_position = tmp ;
502 while ((x==SPLIT_VALUE) && (++_x_position < sizex))
503 x = file.line(current_line).getCurrentXlocation(current_offset,_x_position) ;
504 }
505 // hebStringMode mode1 = file.line(current_line).getCurrentXlang(current_offset,_x_position) ;
506 // assert(x!=SPLIT_VALUE) ; // has to be here, or else it is a bug elsewhere
507 if (x==SPLIT_VALUE) { // this is probably an empty line
508 if ((file.line(current_line)).getMajorMode() == StrHebrew)
509 x = sizex ;
510 else
511 x = 1 ;
512 }
513 if (mode == StrHebrew)
514 keyboard_mode = hebrew ;
515 else
516 keyboard_mode = english ;
517 curx = x ;
518 return ;
519 }
520 }
521
522 // for (i=0; i<sizey-2; i++) _next_line() ;
523 // _scroll(-(sizey-2)) ;
524 void
_next_page(int refresh_flag)525 Edit::_next_page(int refresh_flag)
526 {
527 // for (i=0; i<sizey-2; i++) _next_line() ;
528 // _scroll(-(sizey-2)) ;
529 int flag = 0 ;
530 int current_visual_line = cury ;
531
532 for (int i=0; i<sizey; i++)
533 _next_line(0) ;
534 /*
535 if ((current_line < file.lines()) ||
536 ((current_line == file.lines())
537 && (current_offset < (file.line(current_line)).line_count(sizex)-1))) {
538 if (current_offset < (file.line(current_line)).line_count(sizex)-1) {
539 current_offset++ ;
540 }
541 else {
542 if (current_line < file.lines()) current_line++ ;
543 current_offset = 0 ;
544 }
545 if (cury < sizey) cury++ ;
546 else if (_line_to_display(sizey+1)) {
547 flag =1 ;
548 if (first_offset < (file.line(first_line)).line_count(sizex) - 1)
549 first_offset++ ;
550 else {
551 first_line++ ;
552 first_offset = 0 ;
553 }
554 }
555 }
556 }
557 */
558 _calc_curx() ;
559 if (refresh_flag) {
560 if (flag==0) {
561 Marker rescroll = {current_line, curx-1, current_visual_line} ;
562 _relocateAtMarker(rescroll) ;
563 win->Refresh();
564 }
565 _refresh() ;
566 }
567 }
568
569 void
_previous_page(int refresh_flag)570 Edit::_previous_page(int refresh_flag)
571 {
572 int flag = 0 ;
573 int current_visual_line = cury ;
574 for (int i=0; i<sizey; i++)
575 _previous_line(0) ;
576 /*
577 if ((current_line > 1) ||
578 ((current_line == 1) && current_offset)) {
579 if (cury > 1) cury-- ;
580 else if ((first_line > 1) ||
581 ((first_line == 1) && first_offset)) {
582 flag = 1 ;
583 if (first_offset)
584 first_offset-- ;
585 else {
586 first_line-- ;
587 first_offset = (file.line(first_line)).line_count(sizex)-1 ;
588 }
589 }
590 if (current_offset) {
591 current_offset-- ;
592 }
593 else {
594 current_line-- ;
595 current_offset = (file.line(current_line)).line_count(sizex)-1 ;
596 }
597 }
598 }
599 */
600 _calc_curx() ;
601 if (refresh_flag) {
602 if (flag==0) {
603 Marker rescroll = {current_line, curx-1, current_visual_line} ;
604 _relocateAtMarker(rescroll) ;
605 win->Refresh();
606 }
607 _refresh() ;
608 }
609 }
610
611 int
_next_line(int refresh_flag)612 Edit::_next_line(int refresh_flag)
613 {
614 if ((current_line < file.lines()) ||
615 ((current_line == file.lines())
616 && (current_offset < (file.line(current_line)).line_count(sizex)-1))) {
617 if (current_offset < (file.line(current_line)).line_count(sizex)-1) {
618 current_offset++ ;
619 }
620 else {
621 if (current_line < file.lines()) current_line++ ;
622 current_offset = 0 ;
623 }
624 if (cury < sizey) cury++ ;
625 else if (_line_to_display(sizey+1)) _scroll(-1, refresh_flag) ;
626 } else return 0 ;
627 _calc_curx() ;
628 _relocate_curx(0) ;
629 return 1 ;
630 }
631
632 int
_previous_line(int refresh_flag)633 Edit::_previous_line(int refresh_flag)
634 {
635 if ((current_line > 1) ||
636 ((current_line == 1) && current_offset)) {
637 if (cury > 1) cury-- ;
638 else if ((first_line > 1) ||
639 ((first_line == 1) && first_offset)) _scroll(1, refresh_flag) ;
640 if (current_offset) {
641 current_offset-- ;
642 }
643 else {
644 current_line-- ;
645 current_offset = (file.line(current_line)).line_count(sizex)-1 ;
646 }
647 } else return 0 ;
648 _calc_curx() ;
649 _relocate_curx(0) ;
650 return 1 ;
651 }
652
653 void
_forward()654 Edit::_forward() // actually go right!
655 {
656 hebStringMode mode = file.line(current_line).getMajorMode() ;
657 if (_x_position < sizex-1) {
658 int tmp ;
659 while ((_x_position < sizex-1) &&
660 ((tmp=file.line(current_line).getCurrentXlocation(current_offset,++_x_position))== SPLIT_VALUE)) ;
661 // if there is no chage, meaning we are at an end or beginning of line, so
662 // added this if statement 18/4/97
663 if ((current_offset < (file.line(current_line)).line_count(sizex)-1) || (current_line < file.lines())) {
664 if (tmp == SPLIT_VALUE) {
665 _x_position = 0 ;
666 if (mode == StrHebrew)
667 _previous_line() ;
668 else
669 _next_line() ;
670 }
671 }
672 } else if ((current_offset < (file.line(current_line)).line_count(sizex)-1) || (current_line < file.lines())) {
673 _x_position=0 ;
674 if (mode == StrHebrew)
675 _previous_line() ;
676 else
677 _next_line() ;
678 }
679 _calc_curx() ;
680 }
681
682 void
_backward()683 Edit::_backward() // actually go left!
684 {
685 hebStringMode mode = file.line(current_line).getMajorMode() ;
686 if (_x_position > 0) {
687 int tmp ;
688 while ((_x_position > 0) &&
689 ((tmp=file.line(current_line).getCurrentXlocation(current_offset,--_x_position))== SPLIT_VALUE)) ;
690 if (tmp == SPLIT_VALUE) {
691 _x_position = sizex-1 ;
692 if (mode == StrEnglish)
693 _previous_line() ;
694 else
695 _next_line() ;
696 }
697 } else if ((current_offset > 0) || (current_line > 1)) {
698 _x_position=sizex-1 ;
699 if (mode == StrEnglish)
700 _previous_line() ;
701 else
702 _next_line() ;
703 }
704 _calc_curx() ;
705 }
706
707
708 void
_relocateAtMarker(Marker mark)709 Edit::_relocateAtMarker(Marker mark)
710 {
711 if ((current_line > mark.line) || ((current_line == mark.line) && (curx > mark.offset+1))) {
712 for (;first_line>mark.line ; _previous_page(0)) ;
713 for (;current_line < mark.line ; _next_line(0)) ;
714 for (;current_line > mark.line ; _previous_line(0)) ;
715 for (;curx>mark.offset+1; _relocate_curx(-1)) ;
716 for (;curx<mark.offset+1; _relocate_curx(1)) ;
717 // win->Refresh() ;
718 // _refresh() ;
719 } else
720 if ((current_line < mark.line) || ((current_line == mark.line) && (curx < mark.offset+1))) {
721 for (;current_line <mark.line ; _next_page(0)) ;
722 // for (;current_line > mark.line ; _previous_line(0)) ;
723 if (current_line > mark.line) _previous_page(0) ;
724 for (;current_line < mark.line ; _next_line(0)) ;
725 for (;curx>mark.offset+1; _relocate_curx(-1)) ;
726 for (;curx<mark.offset+1; _relocate_curx(1)) ;
727 // win->Refresh() ;
728 // _refresh() ;
729 } // else you are already located there.
730 if ((mark.offset_from_top >= 0) && (cury < mark.offset_from_top)) {
731 int i, count=0 ;
732 for (i=0; i< mark.offset_from_top-1; i++) count+=_previous_line(0) ;
733 for (i=0; i< count; i++) _next_line(0) ;
734 for (;curx>mark.offset+1; _relocate_curx(-1)) ;
735 for (;curx<mark.offset+1; _relocate_curx(1)) ;
736 } else
737 if ((mark.offset_from_top >= 0) && (cury > mark.offset_from_top)) {
738 int i , count=0;
739 for (i=0; i< (sizey)-mark.offset_from_top; i++) count+=_next_line(0) ;
740 for (i=0; i< count; i++) _previous_line(0) ;
741 for (;curx>mark.offset+1; _relocate_curx(-1)) ;
742 for (;curx<mark.offset+1; _relocate_curx(1)) ;
743 }
744 /*
745 // just in case this last trick, moved your from where you were supposed to be
746 if ((current_line > mark.line) || ((current_line == mark.line) && (curx > mark.offset+1))) {
747 for (;first_line>mark.line ; _previous_page(0)) ;
748 for (;current_line < mark.line ; _next_line(0)) ;
749 for (;current_line > mark.line ; _previous_line(0)) ;
750 for (;curx>mark.offset+1; _relocate_curx(-1)) ;
751 for (;curx<mark.offset+1; _relocate_curx(1)) ;
752 // win->Refresh() ;
753 // _refresh() ;
754 } else
755 if ((current_line < mark.line) || ((current_line == mark.line) && (curx < mark.offset+1))) {
756 for (;current_line <mark.line ; _next_page(0)) ;
757 // for (;current_line > mark.line ; _previous_line(0)) ;
758 if (current_line > mark.line) _previous_page(0) ;
759 for (;current_line < mark.line ; _next_line(0)) ;
760 for (;curx>mark.offset+1; _relocate_curx(-1)) ;
761 for (;curx<mark.offset+1; _relocate_curx(1)) ;
762 // win->Refresh() ;
763 // _refresh() ;
764 } // else you are already located there.
765 */
766 }
767
768
769 void
goto_line(int num)770 Edit::goto_line(int num) {
771 Marker where = {num, 0,-1} ;
772
773 if ((num <=0) || (num > file.lines())) {
774 _refresh() ;
775 win->Message(MSG_INVALID_LINE_NUMBER) ;
776 return ;
777 }
778 _relocateAtMarker(where) ;
779 win->MessageClear(1) ;
780 win->Refresh() ;
781 _refresh() ;
782 }
783
784
785 void
searchForNext(char * text)786 Edit::searchForNext(char *text)
787 {
788 if (!text) return ;
789 if (!*text) return ;
790 Marker starting_point = {current_line, curx, -1} ;
791 Marker find = file.search(text,starting_point) ;
792 if (find.line > 0) {
793 _relocateAtMarker(find) ;
794 file.setStartMarker(find.line, find.offset) ;
795 file.setEndMarker( find.line, find.offset + strlen(text) ) ;
796 _markBlock() ;
797 }
798
799 win->Refresh();
800 _refresh() ;
801 }
802
803 void
searchForPrevious(char * text)804 Edit::searchForPrevious(char *text)
805 {
806 if (!text) return ;
807 if (!*text) return ;
808 Marker starting_point = {current_line, curx-2, -1} ;
809 Marker find = file.searchBackward(text,starting_point) ;
810 if (find.line > 0) {
811 _relocateAtMarker(find) ;
812 file.setStartMarker(find.line, find.offset) ;
813 file.setEndMarker( find.line, find.offset + strlen(text) ) ;
814 _markBlock() ;
815 }
816
817 win->Refresh();
818 _refresh() ;
819 }
820
821
822 void
searchFor(char * text)823 Edit::searchFor(char *text)
824 {
825 Marker starting_point = {current_line, curx-1, cury} ;
826 Marker find = file.search(text,starting_point) ;
827 if (find.line > 0) {
828 _relocateAtMarker(find) ;
829 file.setStartMarker(find.line, find.offset) ;
830 file.setEndMarker( find.line, find.offset + strlen(text) ) ;
831 _markBlock() ;
832 }
833
834 win->Refresh();
835 _refresh() ;
836 }
837
838
_insertDataBlock(Marker location,char * data_block)839 void Edit::_insertDataBlock(Marker location, char * data_block)
840 {
841 _relocateAtMarker(location) ;
842 char *data = strdup((char *)(const char *)(data_block)) ;
843 if (!*data) {
844 delete data ;
845 return ;
846 }
847 char *ptr=data , *ptr2 ;
848
849 if (!strchr(ptr,'\n')) { // only one line
850 aString tmp = ((aString &)(file.line(current_line))).at(0,curx-1) ;
851 tmp += (const char *)ptr ;
852 tmp+= ((aString &)(file.line(current_line))).at(curx-1,((aString &)(file.line(current_line))).length()) ;
853 (aString &)(file.line(current_line)) = tmp ;
854 // file.setStartMarker(current_line, curx-1) ;
855 // file.setEndMarker(current_line, curx-1+((aString &)((he->scratch->file).line(1))).length()-1) ;
856 // _markBlock() ;
857 file.recompile_section(sizex) ;
858 } else {
859 ptr2 = strchr(ptr, '\n') ;
860 *ptr2 = '\0' ;
861 int cl=current_line ;
862 int curline = current_line ;
863 aString tmp = ((aString &)(file.line(current_line))).at(0,curx-1) ;
864 if (*ptr)
865 tmp += ptr ;
866 // remember the rest of the line to add it
867 aString restofline = ((aString &)(file.line(current_line))).at(curx-1,((aString &)(file.line(current_line))).length()) ;
868 // set the current line to the new value.
869 (aString &)(file.line(cl)) = tmp ;
870 // now insert the rest of the line
871 file.insert_after(cl, (char *)(const char *)restofline) ; // sort of a place holder
872 ptr = ptr2+1 ;
873 for (ptr2=strchr(ptr,'\n'); ptr2!=0 ; ptr2 = strchr(ptr, '\n')) {
874 *ptr2 = '\0' ;
875 file.insert_after(cl++, ptr) ;
876 ptr = ptr2+1 ;
877 }
878 if (*ptr) {
879 tmp = ptr ;
880 (aString &)(file.line(++cl)) = tmp + restofline ;
881 } else (aString &)(file.line(++cl)) = restofline ;
882 // file.setEndMarker(cl, tmp.length()) ;
883 // _markBlock() ;
884 file.line(curline) ;
885 file.recompile_section(sizex) ;
886 }
887 delete data ;
888 }
889
890
891
_deleteDataBlock(Marker location,char * data_block)892 void Edit::_deleteDataBlock(Marker location, char * data_block)
893 {
894 _relocateAtMarker(location) ;
895 char *data = strdup((char *)(const char *)(data_block)) ;
896 if (!*data) {
897 delete data ;
898 return ;
899 }
900 char *ptr=data , *ptr2 ;
901
902 if (!strchr(ptr,'\n')) { // only one line
903 aString tmp = ((aString &)(file.line(current_line))).at(0,curx-1) ;
904 tmp+= ((aString &)(file.line(current_line))).at(curx-1+strlen(ptr),
905 ((aString &)(file.line(current_line))).length()) ;
906 (aString &)(file.line(current_line)) = tmp ;
907 file.recompile_section(sizex) ;
908 } else {
909 ptr2 = strchr(ptr, '\n') ;
910 *ptr2 = '\0' ;
911 int cl=current_line ;
912 aString tmp = ((aString &)(file.line(cl))).at(0,curx-1) ;
913 for (ptr = ptr2+1, ptr2=strchr(ptr,'\n'); ptr2 ; ptr=ptr2+1, ptr2 = strchr(ptr, '\n')) {
914 file.delete_line(cl+1) ; ;
915 }
916 tmp+= ((aString &)(file.line(cl+1))).at(strlen(ptr),((aString &)(file.line(cl+1))).length()) ;
917 (aString &)(file.line(cl)) = tmp ;
918 file.delete_line(cl+1) ;
919 file.line(cl) ;
920 file.recompile_section(sizex) ;
921 }
922 delete data ;
923 }
924
925 // Constructors
Edit(HebrewEditor * he,const char * name,aWindow * win,int read_only,char * title)926 Edit::Edit(HebrewEditor *he, const char *name, aWindow *win, int read_only, char *title) :
927 he(he),
928 undo(this),
929 screen_start_line(0) , screen_start_column(0),
930 file_p( new hebFile(he, name,win->scr->hebrew_location,*(win->scr),1,getActiveSpelling())),
931 name(name) ,
932 curx(1), cury(1),
933 cury_offset(0) ,
934 win(win),
935 input(win->scr->hebrew_location,english),
936 continue_edit(TRUE),
937 first_line(1), first_offset(0),
938 sizex(80), sizey(23),
939 specialSeparator(win->scr->special_separator),
940 last_action(Action::Null),
941 esc(0),
942 ctrlK(0), ctrlQ(0),
943 left_end_mark(win->get_left_end_mark()),
944 right_end_mark(win->get_right_end_mark()),
945 read_only(read_only),
946 _x_position(0),
947 delay_compilation(0),
948 modified(0) ,
949 file(*file_p),
950 from(0),
951 action(*he->globalActionManager) {
952 keyboard_mode = english;
953 current_line = first_line ;
954 current_offset = first_offset ;
955 win->GetMaxYX(&sizey,&sizex) ;
956 // --sizey ;
957 if (title) {
958 win->setWindowTopTitle(title) ;
959 } /* endif */
960 }
961
962 // READ ONLY initialized from data_block ;
Edit(HebrewEditor * he,char * title,const char * text,aWindow * win,int read_only)963 Edit::Edit(HebrewEditor *he, char *title, const char *text, aWindow *win, int read_only ) :
964 he(he),
965 undo(this),
966 screen_start_line(0) , screen_start_column(0),
967 file_p( new hebFile(he, "",win->scr->hebrew_location,*(win->scr),1, getActiveSpelling())),
968 name(name),
969 curx(1), cury(1), cury_offset(0),
970 win(win),
971 input(win->scr->hebrew_location,english),
972 continue_edit(TRUE),
973 first_line(1), first_offset(0),
974 sizex(80), sizey(23),
975 specialSeparator(win->scr->special_separator),
976 last_action(Action::Null),
977 esc(0),
978 ctrlK(0), ctrlQ(0),
979 left_end_mark(win->get_left_end_mark()), right_end_mark(win->get_right_end_mark()),
980 read_only(read_only),
981 _x_position(0),
982 delay_compilation(0),
983 modified(0) ,
984 file(*file_p),
985 from(0),
986 action(*he->globalActionManager) {
987 keyboard_mode = english;
988 current_line = first_line ;
989 current_offset = first_offset ;
990 win->GetMaxYX(&sizey,&sizex) ;
991 // --sizey ;
992 file.recompile_file(sizex) ;
993 Marker beginning = {1,0,-1} ;
994 if (text) {
995 _insertDataBlock(beginning, (char *)text) ;
996 } /* endif */
997 if (title) {
998 win->setWindowTopTitle(title) ;
999 } /* endif */
1000 }
1001
1002
1003
1004 //#include "Edit_events.cxx"
1005