1 /***************************************************************************
2                           HebrewEditor.cxx  -  description
3                              -------------------
4     begin                : Sun Mar 4 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 #include "HebrewEditor.h"
19 
20 #include "Edit.h"
21 #include "Help.h"
22 #include "LineEdit.h"
23 #include "aSelectionBox.h"
24 #include "aString.h"
25 #include "File.h"
26 #include "aDictionary.h"
27 
28 #include "sysdep.h"
29 
30 #include "aWindow.h"
31 #include <stdio.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #include <unistd.h>
35 
36 #define MAX_BUFFER_COUNT 100
37 
38 #define HEBREW_DICTIONARY_FILE_NAME "hspell.wor"
39 #define ENGLISH_DICTIONARY_FILE_NAME "espell.wor"
40 #define LAXET_DICTIONARY_FILE_NAME "laxet.wor"
41 
42 
43 #define BUFFER_LIST_TITLE "Buffer List"
44 
45 
46 int
list_buffers(Edit ** buffers,int buffer_count,Screen * scr,int current_buffer)47 HebrewEditor::list_buffers(Edit **buffers, int buffer_count, Screen* scr,
48                  int current_buffer)
49 {
50   aSelectionBox<int> sb(this, -1,BUFFER_LIST_TITLE, scr) ;
51   for (int i=0 ; i< buffer_count; i++) {
52     if (!buffers[i]->finished()) {
53       aString name = buffers[i]->getName() ;
54       if (buffers[i]->getModified())
55         name += " (mod.)" ;
56       sb.addMember(name, i, (i==current_buffer)) ;
57     }
58   }
59 
60   return sb.select() ;
61 }
62 
63 
64 
65 
66 Action::Actions
MenuSelect(char * title,menuItem * menu,int count,Screen * scr,Action & act)67 HebrewEditor::MenuSelect(char *title, menuItem *menu,
68        int count, Screen *scr, Action &act)
69 {
70   aSelectionBox<Action::Actions> sb(this, Action::Null, title, scr) ;
71   for (int i =0 ; i<count ; i++) {
72     aString namebar = menu[i].name ;
73     namebar += "  (" ;
74     aString tmp = act.getActionKeyBinding(menu[i].act) ;
75     namebar += tmp ;
76     namebar += ") " ;
77     if (tmp == "") namebar = menu[i].name ;
78     else {
79       aString tmp1 = act.getActionKeyBinding(menu[i].act,1) ;
80       if (!(tmp1 == "")) {
81         namebar = menu[i].name ;
82         namebar += "  (" ;
83         namebar += tmp ;
84         namebar += "  or  " ;
85         namebar += tmp1 ;
86         namebar += ")  " ;
87       }
88     }
89     sb.addMember(namebar, menu[i].act,0, menu[i].comment) ;
90   }
91   return sb.select() ;
92 }
93 
94 
95 Action::Actions
latex_menu(Screen * scr,Action & act)96 HebrewEditor::latex_menu(Screen *scr,Action &act)
97 {
98   static menuItem menu[] = {
99     {"LaTeX...", Action::LaTeX, "(Run LaTeX/LaXeT on a named primary file)"},
100     {"View DVI(xdvi)...", Action::DviView, "(View the DVI output of LaTeX/LaXeT)"},
101     {"View Available Symbols in Math-mode(xdvi)...", Action::MathSymbolsView,
102                                        "(View a DVI file with tables of math symbols and commands)"}} ;
103 
104   return MenuSelect("LaTeX Menu", menu, sizeof(menu)/sizeof(menuItem),
105                        scr, act) ;
106 }
107 
108 
109 Action::Actions
file_menu(Screen * scr,Action & act)110 HebrewEditor::file_menu(Screen *scr,Action &act)
111 {
112   static menuItem menu[] = {
113     {"Open File...", Action::LoadFile, "(Open a file for editing)"},
114     {"Save File", Action::SaveFile, "(Save the current file to disk)"},
115     {"Save File As...", Action::SaveFileAs, "(Save the current file by a different name)"},
116     {"Exit File...", Action::Exit, "(Exit the current file, if no more files are open, exits Hebrew Editor)"}} ;
117 
118   return MenuSelect("File Menu", menu, sizeof(menu)/sizeof(menuItem),
119                        scr, act) ;
120 }
121 
122 
123 Action::Actions
edit_menu(Screen * scr,Action & act)124 HebrewEditor::edit_menu(Screen *scr,Action &act)
125 {
126   static menuItem menu[] = {
127     {"Undo Previous", Action::Undo, "(Undo the previous action)"},
128     {"Redo Next", Action::Redo, "(Redo the previous undo)"},
129     {"Mark Block Begin", Action::MarkBlockBegin, "(Mark the beginning of a block)"},
130     {"MarkBlockEnd", Action::MarkBlockEnd, "(Mark the end of a block)"},
131     {"Unmark Block", Action::UnmarkBlock, "(Unmark the current marked block)"},
132     {"Copy Block", Action::CopyBlock, "(Copy the currently marked block to the location of the cursur)"},
133     {"Delete Block", Action::DeleteBlock, "(Delete the currently marked block)"},
134     {"Move Block", Action::MoveBlock, "(Move the currently marked block to the location of the cursur)"}} ;
135 
136   return MenuSelect("Edit Menu", menu, sizeof(menu)/sizeof(menuItem), scr,act) ;
137 }
138 
139 
140 
141 Action::Actions
search_menu(Screen * scr,Action & act)142 HebrewEditor::search_menu(Screen *scr,Action &act)
143 {
144   static menuItem menu[] = {
145     {"Search For...", Action::Find, "(Search for strings in either Hebrew or English)"},
146     {"Search & Replace...", Action::FindReplace, "(Semi-Automatic Search and Replace of strings)"},
147     {"Goto Line...", Action::GotoLine, "(Move the cursor to a given line)"}} ;
148 
149   return MenuSelect("Search Menu", menu, sizeof(menu)/sizeof(menuItem), scr,act) ;
150 }
151 
152 
153 Action::Actions
main_menu(Screen * scr,Action & act)154 HebrewEditor::main_menu(Screen *scr,Action &act)
155 {
156   static menuItem menu[] = {
157     {"File menu...", Action::FileMenu, "(Open File, Save File, Save File As, Exit File,Online Tutorial)"},
158     {"Edit menu...", Action::EditMenu, "(Undo, Redo, Block Operations)"},
159     {"Search menu...", Action::SearchMenu, "(Search, Search&Replace, Goto Line)"},
160     {"LaTeX menu...", Action::LaTeXMenu, "(Run LaTeX/LaXeT on a primary file, View DVI file)" },
161 //    {"Options...", Action::OptionsMenu},
162     {"Buffer List...", Action::BufferList, "(Select one of the currently open buffers for editing)"},
163     {"Online Tutorial...", Action::Help,"(View the online tutorial)"}} ;
164 //    {"Help...", Action::Help}} ;
165 
166   return MenuSelect("Main Menu", menu, sizeof(menu)/sizeof(menuItem), scr,act) ;
167 }
168 
169 
170 
171 
HebrewEditor(int argc,char ** argv)172 HebrewEditor::HebrewEditor(int argc, char **argv){
173    if ((programPrefix=getenv(PROGRAM_PREFIX_VAR)) == NULL) {
174       programPrefix = "/usr/local" ;
175    }
176 
177    char *home=strdup(getenv("HOME")) ;
178 
179    aString helpTutorialName = programPrefix ;
180            helpTutorialName+= "/" ;
181            helpTutorialName+= HE_TUTORIAL_FILE_NAME ;
182 
183    File helpTutorialFile(helpTutorialName) ;
184    if (!helpTutorialFile.exists()) {
185       printf("%s environment variable is not set, unable to find some needed files\n",
186                PROGRAM_PREFIX_VAR) ;
187       printf("be sure to set %s to the location of the program files\n",
188                PROGRAM_PREFIX_VAR) ;
189       getchar() ;
190    } /* endif */
191 
192    printf("Loading dictionaries\n") ;
193    aString hebrewDictionaryLocation = programPrefix ;
194    aString englishDictionaryLocation = programPrefix ;
195    aString laxetDictionaryLocation = programPrefix ;
196    hebrewDictionaryLocation += "/" ;
197    englishDictionaryLocation += "/" ;
198    laxetDictionaryLocation += "/" ;
199    hebrewDictionaryLocation += HEBREW_DICTIONARY_FILE_NAME ;
200    englishDictionaryLocation += ENGLISH_DICTIONARY_FILE_NAME ;
201    laxetDictionaryLocation += LAXET_DICTIONARY_FILE_NAME ;
202 
203    aString laxetAdd((home) ? home : ".") ;
204    aString espellAdd((home) ? home : ".") ;
205    aString hspellAdd((home) ? home : ".") ;
206 
207    laxetAdd += "/.laxet.add" ;
208    espellAdd += "/.espell.add" ;
209    hspellAdd += "/.hspell.add" ;
210 
211 
212    hebrewDictionary = new aHebrewDictionary(this, (char *)(const char *)hebrewDictionaryLocation, (char *)(const char *)hspellAdd) ;
213    englishDictionary = new aDictionary(this, (char *)(const char *)englishDictionaryLocation, (char *)(const char *)espellAdd) ;
214    laxetDictionary = new aHebrewDictionary(this, (char *)(const char *)laxetDictionaryLocation, (char *)(const char *)(laxetAdd)) ;
215    screen = new SCREEN(HEBREW_NEWCODE, HEBREW_ALTERNATE_CODE) ;
216 
217    globalActionManager = new Action(*screen) ;
218 
219    aWindow *scratchWindow = new aWindow(screen) ;
220    scratch = new Edit(this, SCRATCH_BUFFER_NAME, scratchWindow) ;
221    scratch->processFile(0) ;
222 
223    screen->Erase() ;
224    screen->Refresh() ;
225    screen->GetMaxYX(&sizey, &sizex) ;
226 
227    buffers = new Edit *[MAX_BUFFER_COUNT] ;
228    aString filename ;
229    bufferCount = 0 ;
230    if (argc > 1) {
231       for (int i=1 ; i<argc ; i++) {
232          filename = argv[i] ;
233          buffers[bufferCount] = new Edit(this, filename, new aWindow(screen,-2, 0, 0,0,0) ) ;
234          buffers[bufferCount++]->processFile() ;
235        }
236     } else {
237       buffers[bufferCount] = new Edit(this, "Untitled.tex", new aWindow(screen,-2, 0, 0,0,0)) ;
238       buffers[bufferCount++]->processFile() ;
239     }
240 }
241 
242 
~HebrewEditor()243 HebrewEditor::~HebrewEditor(){
244 }
245 
246 
247 void
appMain()248 HebrewEditor::appMain()
249 {
250    int current_buffer = 0 ; currentEditBuffer = buffers[0] ;
251    int finished = 0 ;
252    buffers[current_buffer]->refresh() ;
253    int last_buffer = 0 ;
254 
255    while (!finished) {
256      Action::Actions act = buffers[current_buffer]->getNextAction() ;
257      if (act == Action::MainMenu) {
258           if (buffers[current_buffer]->file.markActive())
259               buffers[current_buffer]->_markBlock(1) ;
260           act=main_menu(screen,buffers[current_buffer]->action) ;
261           buffers[current_buffer]->refresh() ;
262      }
263      if (act == Action::LaTeXMenu) {
264           if (buffers[current_buffer]->file.markActive())
265               buffers[current_buffer]->_markBlock(1) ;
266           act=latex_menu(screen,buffers[current_buffer]->action) ;
267           buffers[current_buffer]->refresh() ;
268      }
269      if (act == Action::FileMenu) {
270           if (buffers[current_buffer]->file.markActive())
271               buffers[current_buffer]->_markBlock(1) ;
272           act=file_menu(screen,buffers[current_buffer]->action) ;
273           buffers[current_buffer]->refresh() ;
274      }
275      if (act == Action::EditMenu) {
276           if (buffers[current_buffer]->file.markActive())
277               buffers[current_buffer]->_markBlock(1) ;
278           act=edit_menu(screen,buffers[current_buffer]->action) ;
279           buffers[current_buffer]->refresh() ;
280      }
281      if (act == Action::SearchMenu) {
282           if (buffers[current_buffer]->file.markActive())
283               buffers[current_buffer]->_markBlock(1) ;
284           act=search_menu(screen,buffers[current_buffer]->action) ;
285           buffers[current_buffer]->refresh() ;
286      }
287      switch (act) {
288        case Action::BufferList: {
289            if (buffers[current_buffer]->file.markActive())
290                 buffers[current_buffer]->_markBlock(1) ;
291            int tmp = list_buffers(buffers, bufferCount, screen, current_buffer) ;
292          if (tmp >= 0) {
293            current_buffer = tmp ;
294            currentEditBuffer = buffers[current_buffer] ;
295          }
296          buffers[current_buffer]->refresh() ;
297        }
298        break ;
299 
300         case Action::NextBuffer:
301         case Action::Exit:
302            last_buffer = current_buffer ;
303            if (buffers[current_buffer]->file.markActive())
304                 buffers[current_buffer]->_markBlock(1) ;
305            if (act == Action::Exit) {
306              buffers[current_buffer]->processAction(act) ;
307              if (buffers[current_buffer]->finished())
308                last_buffer = current_buffer++ ;
309            } else
310              last_buffer = current_buffer++ ;
311           if (current_buffer >= bufferCount) {
312             current_buffer = 0 ;
313             currentEditBuffer = buffers[current_buffer] ;
314           }
315 
316           while ((buffers[current_buffer]->finished()) && (current_buffer != last_buffer)) {
317             current_buffer++ ;
318             currentEditBuffer = buffers[current_buffer] ;
319             if (current_buffer >= bufferCount) {
320               current_buffer = 0 ;
321               currentEditBuffer = buffers[current_buffer] ;
322             }
323 
324           }
325           finished = buffers[current_buffer]->finished() ;
326        // just to play with scratch
327        // if ((last_buffer == current_buffer) && (current_buffer == bufferCount-1)) finished = 1 ;
328 
329            screen->MessageClear() ;
330           if (!finished)
331              buffers[current_buffer]->refresh() ;
332       break ;
333 
334 
335       case Action::PreviousBuffer:
336           if (buffers[current_buffer]->file.markActive())
337              buffers[current_buffer]->_markBlock(1) ;
338           last_buffer = current_buffer-- ;
339           currentEditBuffer = buffers[current_buffer] ;
340 
341          if (current_buffer <0 ) {
342            current_buffer = bufferCount-1  ;
343            currentEditBuffer = buffers[current_buffer] ;
344          }
345 
346          while ((buffers[current_buffer]->finished()) &&
347                 (current_buffer != last_buffer)) {
348            current_buffer-- ;
349            currentEditBuffer = buffers[current_buffer] ;
350 
351            if (current_buffer < 0) {
352              current_buffer = bufferCount - 1 ;
353              currentEditBuffer = buffers[current_buffer] ;
354            }
355 
356          }
357          finished = buffers[current_buffer]->finished() ;
358          // just to play with scratch
359          //                   if ((last_buffer == current_buffer) && (current_buffer == bufferCount-1)) finished = 1 ;
360 
361          screen->MessageClear() ;
362          if (!finished)
363            buffers[current_buffer]->refresh() ;
364        break ;
365 
366 
367 
368        case Action::LoadFile: {
369           if (buffers[current_buffer]->file.markActive())
370               buffers[current_buffer]->_markBlock(1) ;
371              Action::Actions act ;
372               screen->GetMaxYX(&sizey,&sizex) ;
373               aWindow *linewin =new aWindow(screen,1,sizex,sizey-1,0,0) ;
374 
375              LineEdit *input_line = new GetFileName(this, "Open File: ",linewin) ;
376              input_line->refresh() ;
377 
378              while (!input_line->finished())
379                  input_line->processAction(act=input_line->getNextAction()) ;
380              screen->MessageClear(1) ;
381              if (act == Action::NewLine) {
382                    buffers[bufferCount] = new Edit(this, input_line->getText(),
383                                          new aWindow(screen,-2, 0, 0,0,0)) ;
384                    buffers[bufferCount++]->processFile() ;
385                    current_buffer = bufferCount-1 ;
386                    currentEditBuffer = buffers[current_buffer] ;
387 
388              }
389              buffers[current_buffer]->refresh() ;
390              delete input_line ;
391              delete linewin ;
392              }
393        break ;
394 
395 
396        case Action::SaveFileAs: {
397              Action::Actions act ;
398               screen->GetMaxYX(&sizey,&sizex) ;
399               aWindow *linewin=new aWindow(screen,1,sizex,sizey-1,0,0) ;
400 
401              LineEdit *input_line = new GetFileName(this, "Save File As: ",linewin) ;
402              input_line->refresh() ;
403 
404              while (!input_line->finished())
405                  input_line->processAction(act=input_line->getNextAction()) ;
406              screen->MessageClear(1) ;
407              if (act == Action::NewLine) {
408                    FILE *fp = fopen(input_line->getText(), "r") ;
409                    int flag = 1 ;
410                    if (fp) {
411                          fclose(fp) ;
412                          buffers[current_buffer]->refresh() ;
413                          int c =screen->Question("File exists, are you sure you want to write over it (y/n)? ") ;
414                         while ((c != 'y')&& (c!='Y') && (c!= 'n') && (c!='N'))
415                                c =screen->Question("File exists, are you sure you want to write over it (y/n)? ") ;
416                         if ((c == 'n') || (c == 'N'))
417                                flag = 0 ;
418                    }
419                    screen->MessageClear() ;
420                    if (flag) {
421                       buffers[current_buffer]->setName(input_line->getText()) ;
422                      buffers[current_buffer]->_SaveFile(act) ;
423                    }
424              }
425              buffers[current_buffer]->refresh() ;
426              delete input_line ;
427              delete linewin ;
428              }
429        break ;
430 
431        case Action::GotoLine: {
432            if (buffers[current_buffer]->file.markActive())
433                 buffers[current_buffer]->_markBlock(1) ;
434              Action::Actions act ;
435               screen->GetMaxYX(&sizey,&sizex) ;
436               aWindow *linewin=new aWindow(screen,1,sizex,sizey-1,0,0) ;
437 
438              LineEdit *input_line = new GetNumber(this, "Goto Line: ",linewin) ;
439              input_line->refresh() ;
440 
441              while (!input_line->finished())
442                  input_line->processAction(act=input_line->getNextAction()) ;
443              screen->MessageClear(1) ;
444              if (act == Action::NewLine) {
445                    int num = atoi(input_line->getText()) ;
446                    buffers[current_buffer]->goto_line(num) ;
447              }
448              delete input_line ;
449              delete linewin ;
450              }
451        break ;
452 
453        case Action::LaTeX: {
454            if (buffers[current_buffer]->file.markActive())
455                 buffers[current_buffer]->_markBlock(1) ;
456              Action::Actions act ;
457              aString title = "run LaTeX(" ;
458              title+=DEFAULT_LATEX ;
459              title+= ") on primary file: " ;
460 
461              if (!strcmp((char *)(const char *)primaryFile,""))
462                primaryFile = buffers[current_buffer]->getName() ;
463 
464               screen->GetMaxYX(&sizey,&sizex) ;
465               aWindow *linewin=new aWindow(screen,1,sizex,sizey-1,0,0) ;
466 
467              LineEdit *input_line = new GetFileName(this, (char *)(const char*)title,
468                                           linewin,
469                                           (char *)(const char*)primaryFile) ;
470              input_line->refresh() ;
471 
472              while (!input_line->finished())
473                  input_line->processAction(act=input_line->getNextAction()) ;
474              screen->MessageClear(1) ;
475              if (act == Action::NewLine) {
476                    screen->MessageClear() ;
477                    aString cmd = DEFAULT_LATEX ;
478                    cmd += " " ;
479                    cmd += input_line->getText() ;
480                    primaryFile = input_line->getText() ;
481                    screen->TemporaryExit(0,(char *)(const char*)cmd) ;
482              }
483              buffers[current_buffer]->refresh() ;
484              delete input_line ;
485              delete linewin ;
486              }
487        break ;
488 
489        case Action::DviView: {
490            if (buffers[current_buffer]->file.markActive())
491                 buffers[current_buffer]->_markBlock(1) ;
492              Action::Actions act ;
493              aString title = "View DVI output file: " ;
494 
495               screen->GetMaxYX(&sizey,&sizex) ;
496               aWindow *linewin=new aWindow(screen,1,sizex,sizey-1,0,0) ;
497 
498              if (!strcmp((char *)(const char *)lastDviFile,""))
499                if (strcmp((char *)(const char *)primaryFile,"")) {
500                   char *ptr = (char *)(const char *)primaryFile ;
501                   char *dot = strrchr(ptr,'.') ;
502                   if (dot) {
503                     lastDviFile=primaryFile.at(0,dot-ptr) ;
504                     lastDviFile+=".dvi" ;
505                   } else {
506                     lastDviFile = primaryFile + ".dvi" ;
507                   }
508                }
509 
510              LineEdit *input_line = new GetFileName(this, (char *)(const char*)title,
511                                           linewin,
512                                           (char *)(const char*)lastDviFile) ;
513              input_line->refresh() ;
514 
515              while (!input_line->finished())
516                  input_line->processAction(act=input_line->getNextAction()) ;
517              screen->MessageClear(1) ;
518              if (act == Action::NewLine) {
519                    screen->MessageClear() ;
520                    aString cmd = DEFAULT_DVIVIEW;
521                    cmd += " " ;
522                    cmd += input_line->getText() ;
523                    lastDviFile = input_line->getText() ;
524                    cmd += " " ;
525                    cmd += DISCARD_OUTPUT ;
526                    screen->TemporaryExit(0,(char *)(const char*)cmd,1) ;
527              }
528              buffers[current_buffer]->refresh() ;
529              delete input_line ;
530              delete linewin ;
531              }
532        break ;
533        case Action::MathSymbolsView: {
534            if (buffers[current_buffer]->file.markActive())
535                 buffers[current_buffer]->_markBlock(1) ;
536              aString title = "View Math Symbols: " ;
537 
538              aString cmd = DEFAULT_DVIVIEW;
539              cmd += " " ;
540              cmd += programPrefix ;
541              cmd += "/symbols.dvi" ;
542              cmd += " " ;
543              cmd += DISCARD_OUTPUT ;
544              screen->TemporaryExit(0,(char *)(const char*)cmd,1) ;
545 
546              buffers[current_buffer]->refresh() ;
547              }
548        break ;
549 
550 
551 
552        default:
553          buffers[current_buffer]->processAction(act) ;
554      } /* end of switch */
555    }
556    screen->Erase() ;
557    screen->Refresh() ;
558 }
559 
560 
main(int argc,char ** argv)561 int main(int argc, char **argv) {
562    HebrewEditor *he = new HebrewEditor(argc, argv) ;
563 
564    he->appMain() ;
565 }
566 
567 
568