/*******************************************************************/
// "Меркурий"-"Правда" - 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 ;
}
}