/*******************************************************************/ // "Меркурий"-"Правда" - open source переводчик // распространяется в соответсвии с лицензией GNU v 2.0 // // t_Windows - главный класс интерфейса (ничего общего с Микрософтом) // Анисимов Д.В. сегодня /*******************************************************************/ # include <string.h> # include <stdlib.h> # include <unistd.h> # include "mylib.h" # include "video.h" # include "color.h" # include "core.h" # include "face.h" # include "menu.h" # include "edit.h" # include "edit1.h" # include "edit2.h" # include "debug.h" # include "path.h" # include "word.h" t_Windows Windows ; t_Dir Dir ; t_HelpData HelpData ; t_Text HelpText ; t_Edit HelpView ; t_EditTrans Edit1,Edit2 ; t_Edit2 EditFrom ; t_Edit3 EditTree1(0),EditTree2(1) ; t_Debug Debug ; t_Path Path ; t_GrammarView GrammarView ; t_SlowoView SlowoView ; t_Slowo3View Slowo3View ; t_NewWord NewWord ; t_AddWord AddWord ; t_Option Option ; char FileName[100]="" ; char MercuryDir[200]="../" ; /***************************************************************************/ // функция определения "слова с точкой" /***************************************************************************/ char is_const( char *Str ) { short part[20] ; if( 0<Perevod.part( Str,part ) ) return 1 ; return 0 ; } /***************************************************************************/ void Window_menu( void *Void ) { switch( ((char *)Void)[0] ) { case '1' : Windows.create( NULL ); break ; case 's' : Windows.save_src( ); break ; case '2' : Windows.save( ); break ; case '3' : Windows.save_as( ); break ; case '4' : Windows.exit( ); break ; case '5' : Windows.find_forward( ); break ; case '6' : Windows.find_backward( );break ; case '7' : Windows.replace( ); break ; case '8' : Windows.goto_str( ); break ; case 'T' : Windows.trans( ); break ; case 't' : Windows.trans_frasa( ); break ; case 'f' : Windows.win_firstlook(); break ; case 'R' : { if( 0>reread_grammar( MercuryDir )) Edit1.read("mercury.err"); else Edit1.init(""); } break ; case 'F' : if( Edit1.Text1.fformat==0 ) { Edit1.Text1.fformat=1 ; Edit2.Text1.fformat=1 ; menu_set( "Спец Формат [ ]","Спец Формат [x]" ); }else { Edit1.Text1.fformat=0 ; Edit2.Text1.fformat=0 ; menu_set( "Спец Формат [x]","Спец Формат [ ]" ); } break ; } } /***************************************************************************/ void Window_help( void *Void ) { char *Str=(char *)Void ; short sx,sy ; s_get_size( sx,sy ); s_save( 1,1,sy-1,sx-1 ); HelpView.init( HelpData.get_help( Str ) ); HelpView.main( ); s_restore(); } /***************************************************************************/ t_Windows :: t_Windows( ) { Reg='1' ; } /***************************************************************************/ void t_Windows :: init( void ) { HelpView.set_text( &HelpText ); HelpView.set_view( 1 ) ; Edit1.set_name("Исходный_текст"); Edit2.set_name("Переведенный_текст"); EditFrom.set_name("Первое чтение"); EditTree1.set_name("Структура источника"); EditTree2.set_name("Структура приемника"); HelpView.set_name("Подсказка"); AddWord.set_name("Новые слова"); Edit1.set_funk_const( &is_const ); } /***************************************************************************/ void t_Windows :: set_pos( void ) { short sx,sy,y ; s_get_size( sx,sy ); y=sy/2 ; Edit1.set_pos ( 0, 1 , sx-1, y ); Edit2.set_pos ( 0, y+1, sx-1, sy-1 ); EditFrom.set_pos ( 1, 2 , sx-2, sy-2 ); EditTree1.set_pos ( 1, 2 , sx-2, sy-2 ); EditTree2.set_pos ( 1, 2 , sx-2, sy-2 ); Debug.set_pos ( 1, 2 , sx-2, sy-2 ); Path.set_pos ( 1, 2 , sx-2, sy-2 ); GrammarView.set_pos( 1, 2 , sx-2, sy-2 ); SlowoView.set_pos ( 1, 2 , sx-2, sy-2 ); Slowo3View.set_pos ( 1, 2 , sx-2, sy-2 ); HelpView.set_pos ( 1, 2 , sx-2, sy-2 ); AddWord.set_pos ( 1, 2 , sx-2, sy-2 ); } /***************************************************************************/ void t_Windows :: main_loop( void ) { e_WinMsg r ; init(); set_pos(); null_menu( ); while( 1 ) { paint( ); switch( Reg ) { case '1': r=Edit1.main_loop( ); Reg1=Reg ; break ; case '2': r=Edit2.main_loop( ); Reg1=Reg ; break ; case '3': r=EditFrom.loop( ); break ; case '4': r=EditTree1.loop( ); break ; case '5': r=EditTree2.loop( ); break ; case '6': r=Debug.loop( ); break ; case '7': r=GrammarView.loop( );break ; case '8': r=SlowoView.loop( ); break ; case '9': r=Slowo3View.loop( ); break ; case 'b': r=win_path( ); break ; case 'c': r=win_path2( ); break ; case 'd': r=AddWord.loop( ); break ; } switch( r ) { case WM_NEXT : if( Reg=='1' ) { Reg='2' ; break ; } if( Reg=='2' ) { Reg='1' ; break ; } case WM_ESC : Reg=Reg1 ; break ; case WM_EDIT1 : Reg='1' ; break ; case WM_EDIT2 : Reg='2' ; break ; case WM_FIRST : Reg='3' ; break ; case WM_SRC : Reg='4' ; break ; case WM_DST : Reg='5' ; break ; case WM_DEBUG : Reg='6' ; break ; case WM_PATH : Reg='b' ; break ; case WM_PATH2 : Reg='c' ; break ; case WM_GRAMMAR: Reg='7' ; break ; case WM_SLOWO : Reg='8' ; break ; case WM_BASE : Reg='9' ; break ; case WM_ADD_WORD: Reg='d' ; break ; } } } /***************************************************************************/ e_WinMsg t_Windows :: win_path2( void ) { // ------ установление размеров окошек --------------- short sx,sy,y1,y2 ; if( Read_Error!=0 ) { figna("Грамматика или словари не прочитаны.\n Перевод невозможен!!!"); return WM_ESC ; } s_get_size( sx,sy ); y2=sy/2 ; y1=y2/2 ; Edit1.set_pos ( 0, 1 , sx-1, y1 ); Edit2.set_pos( 0, y1+1, sx-1, y2 ); Path.set_pos ( 0, y2+1, sx-1, sy-1 ); // ------ чтение текущей фразы ---------------------- char *Str,Str1[1000] ; Str =Edit1.get_frasa( Edit1.current_pos( ) ); if( Str[0]!=0 ) Core.translate( Str,Str1 ); e_WinMsg r ; char Reg2 ,Reg3 ; Reg2=Reg3='b' ; null_menu( ); while( 1 ) { Edit1.raden_y3(); Edit2.raden_y3(); Edit1.paint_main(); Edit2.paint_main(); switch( Reg2 ) { case '1': r=Edit1.main_loop( ); Reg3=Reg2 ; break ; case '2': r=Edit2.main_loop( ); Reg3=Reg2 ; break ; case 'b': r=Path.loop( ); Reg3=Reg2 ; break ; } switch( r ) { case WM_NEXT : switch( Reg2 ) { case '1' : Reg2='2' ; break ; case '2' : Reg2='b' ; break ; case 'b' : Reg2='1' ; break ; } break ; case WM_ESC : if( Reg2=='1' || Reg2=='2' || Reg2=='b') goto M_End ; else Reg2=Reg3 ; break ; case WM_OK : if( Reg2!='b' ) break ; Str=Path.Antwort ; if( Str[0]==0 ) break ; Edit2.put_frasa( Edit2.current_pos( ),Str ); Edit1.next_frasa(); Edit2.next_frasa(); Str =Edit1.get_frasa( Edit1.current_pos( ) ); if( Str[0]!=0 ) Core.translate( Str,Str1 ); break ; case WM_N_FRASA: case WM_P_FRASA: if( Reg2!='b' ) break ; if( r==WM_N_FRASA ) { Edit1.next_frasa(); Edit2.next_frasa(); } else { Edit1.prev_frasa(); Edit2.prev_frasa(); } Str =Edit1.get_frasa( Edit1.current_pos( ) ); if( Str[0]!=0 ) Core.translate( Str,Str1 ); break ; case WM_EDIT1 : Reg='1' ; break ; case WM_EDIT2 : Reg='2' ; break ; case WM_FIRST : Reg='3' ; break ; case WM_SRC : Reg='4' ; break ; case WM_DST : Reg='5' ; break ; case WM_DEBUG : Reg='6' ; break ; case WM_PATH : Reg='b' ; break ; case WM_PATH2 : Reg='c' ; break ; case WM_GRAMMAR: Reg='7' ; break ; case WM_SLOWO : Reg='8' ; break ; case WM_BASE : Reg='a' ; break ; } } M_End: Edit1.set_pos ( 0, 1 , sx-1, y2 ); Edit2.set_pos( 0, y2+1, sx-1, sy-1 ); Path.set_pos ( 1, 2 , sx-2, sy-2 ); return WM_ESC ; } /***************************************************************************/ void t_Windows :: paint( void ) { short sx,sy,yy ; static short sx1=80,sy1=25 ; s_get_size( sx,sy ); yy=sy/2 ; s_rame2_f( 1,0,sy-1,sx-1,red_rame_Color ); if( sx!=sx1 || sy!=sy1 ) { // ------------ переразместить все окошки ---------------- set_pos( ); null_menu(); } Edit1.paint_main(); Edit2.paint_main(); } /***************************************************************************/ void t_Windows :: trans( void ) { long i ; char *Str,Str1[1000] ; char *Text ; if( Read_Error!=0 ) { figna("Грамматика или словари не прочитаны.\n Перевод невозможен!!!"); return ; } Text=(char *)Calloc( 1000000,sizeof(char) ); for( i=0 ; i<Edit1.text()->length() ; i=Edit1.text()->next_frasa(i) ) { Str =Edit1.get_frasa(i); Core.translate( Str,Str1 ); strcat( Text, Str1 ); strcat( Text, "\n" ); } Edit2.init( Text ); Free( Text ); Edit1.paint_main(); Edit2.get_str(); Edit2.paint_main(); } /***************************************************************************/ void t_Windows :: trans_frasa( void ) { char *Str ; long p ; static char Str1[1000] ; if( Read_Error!=0 ) { figna("Грамматика или словари не прочитаны.\n Перевод невозможен!!!"); return ; } p=Edit1.current_pos( ) ; Str =Edit1.get_frasa( p ); Core.translate( Str,Str1 ); Edit2.put_frasa( Edit2.current_pos( ),Str1 ); Edit1.paint_main(); Edit2.get_str(); Edit2.paint_main(); } /***************************************************************************/ void t_Windows :: win_firstlook( void ) { char *Str ; static char Str1[1000] ; Str =Edit1.get_frasa( Edit1.current_pos( ) ); Core.translate( Str,Str1 ); paint( ); EditFrom.loop( ); paint( ); } /***************************************************************************/ e_WinMsg t_Windows :: win_path( void ) { e_WinMsg r ; char *Str ; static char Str1[1000] ; if( Read_Error!=0 ) { figna("Грамматика или словари не прочитаны.\n Перевод невозможен!!!"); return WM_ESC ; } Str =Edit1.get_frasa( Edit1.current_pos( ) ); if( Str[0]!=0 ) Core.translate( Str,Str1 ); r=Path.loop( ); Str=Path.Antwort ; if( Str[0]!=0 ) Edit2.put_frasa( Edit2.current_pos( ),Str ); Edit1.paint_main(); Edit2.get_str(); Edit2.paint_main(); return r ; } /***************************************************************************/ void t_Windows :: exit( void ) { if( 1==fragen( "Запомнить файл перевода? (1-Да 0-Нет)" ) ) save( ) ; s_nacht( ) ; s_redraw( ); s_end_schone( ); ::exit(0); } /***************************************************************************/ void t_Windows :: save_src( void ) { char Buf[200] ; Edit1.write( Edit1.Name ); sprintf( Buf,"Файл \"%s\" сохранен",Edit1.Name ); figna( Buf ); } /***************************************************************************/ void t_Windows :: save( void ) { Edit2.write("mercury_out.txt"); figna( "Файл \"mercury_out.txt\" сохранен" ); } /***************************************************************************/ void t_Windows :: save_as( void ) { char f ; char Buf[200] ; f=Dir.direktor( Buf,1 ); if( f<0 ) strcpy( Buf,"mercury_out.txt" ); Edit2.set_name( Buf ); Edit2.write( Buf ); paint( ); } /***************************************************************************/ void t_Windows :: find_forward( void ) { if( Reg=='1') Edit1.find_forward( ); if( Reg=='2') Edit2.find_forward( ); } /***************************************************************************/ void t_Windows :: find_backward( void ) { if( Reg=='1') Edit1.find_backward( ); if( Reg=='2') Edit2.find_backward( ); } /***************************************************************************/ void t_Windows :: replace( void ) { if( Reg=='1') Edit1.replace( ); if( Reg=='2') Edit2.replace( ); } /***************************************************************************/ void t_Windows :: goto_str( void ) { if( Reg!='1' ) Edit1.goto_str( ); if( Reg!='2' ) Edit2.goto_str( ); } /***************************************************************************/ void t_Windows :: prev_frasa( void ) { Edit1.prev_frasa(); Edit2.prev_frasa(); Edit1.paint_main(); Edit2.paint_main(); } /***************************************************************************/ void t_Windows :: next_frasa( void ) { Edit1.next_frasa(); Edit2.next_frasa(); Edit1.paint_main(); Edit2.paint_main(); } /***************************************************************************/ void t_Windows :: create( char *Name ) { char f ; char Buf[200] ; if( Name==NULL ) { f=Dir.direktor( Buf,0 ); } else { strcpy(Buf,Name); f=0; } if( f>=0 ) { if( f==0 ) Edit1.read( Buf ); Edit1.set_name( Buf ); } else create( "new.txt" ); paint( ); } /************************************************************************/ void preproc_exe( void *S ) { char Str[200] ; int r ; if( Edit1.Text1.fformat==1 ) { figna("Вы уже запускали препроцессор. Хватит."); return ; } Strcpy( Str,MercuryDir, 200 ); Strcat( Str,"/bin/", 200 ); Strcat( Str,(char *)S, 200 ); Strcat( Str," ", 200 ); Strcat( Str,Edit1.Name, 200 ); r=system( Str ); if( r==0 ) { Strcpy( Str,Edit1.Name, 200 ); Strcat( Str,".pre", 200 ); Strcpy( Edit1.Name,Str, 200 ); Edit1.read( Str ); Edit1.Text1.fformat=1 ; } else { figna("Препроцессор не смог нормально отработать.\nПочему - не знаю."); } } /************************************************************************/ void postproc_exe( void *S ) { char Str[200] ; int r ; Edit2.write( "tmp" ); Strcpy( Str,MercuryDir, 200 ); Strcat( Str,"/bin/postproc tmp", 200 ); r=system( Str ); if( r==0 ) { Edit2.read( "tmp.post" ); } else { figna("Постпроцессор не смог нормально отработать.\nПочему - не знаю."); } unlink( "tmp" ); unlink( "tmp.post" ); Edit2.get_str(); Edit2.paint_main(); } /************************************************************************/ // построить данные для препроцессора /************************************************************************/ void preproc_rc( char *File ) { long i,L ; char *Mass ; FILE *ff ; ff=fopen( File,"r" ); if( ff==NULL ) return ; fclose(ff); L=file_to_mass( File,&Mass ); t_Lexer Lexer ; Lexer.set_breaker((uchar *)":"); Lexer.init( Mass,L ); Lexer.remark(); Lexer.make_words(); t_Menu *PP_Menu=(t_Menu *)Calloc(1+Lexer.n_word(),sizeof(t_Menu) ); for( i=0 ; i<Lexer.n_word(); i++ ) { PP_Menu[i].flag=F_FUNK ; PP_Menu[i].ret =0 ; PP_Menu[i].funk=preproc_exe ; PP_Menu[i].data=Calloc( 1+strlen(Lexer.word(i)),1 ); strcpy( (char *)PP_Menu[i].data,Lexer.word(i) ); Strcpy( PP_Menu[i].name,Lexer.word(i),30 ); } PP_Menu[i].flag=F_ENDE ; t_Menu *PP1_Menu=menu_find( "Препроцессор" ); if( PP1_Menu!=NULL ) { PP1_Menu->flag=F_MENU ; PP1_Menu->data=PP_Menu ; } }