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