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