/*******************************************************************/
// "Меркурий"-"Правда" - open source переводчик
// распространяется в соответсвии с лицензией GNU v 2.0
//
// Ввод новых слов и выражений
// Анисимов Д.В. сегодня
/*******************************************************************/
# include <string.h>
# include "video.h"
# include "color.h"
# include "face.h"
# include <word.h>
extern t_NewWord NewWord ;
extern char MercuryDir[] ;
e_WinMsg line_edit( short x, short y, char f, char *Str, short Length )
;
/************************************************************************/
t_NewWord :: t_NewWord( )
{ Mass=NULL ;
j_Mass=n_Mass=z_Mass=0 ;
}
/************************************************************************/
t_NewWord :: ~t_NewWord( )
{ Free( Mass );
}
/************************************************************************/
void t_NewWord :: add( char *str )
{ long L,N ;
char *M ;
L=strlen( str );
if( n_Mass<j_Mass+L+2 )
{ N=max(n_Mass/4,L+2);
M=(char *)realloc( Mass,(n_Mass+N)*sizeof(char) );
if( M==NULL ) return ;
Mass=M ; n_Mass+=N ;
}
strcpy( Mass+j_Mass,str );
strcpy( Mass+j_Mass+L,"\n" );
j_Mass+=L+1 ;
}
/************************************************************************/
char
* t_NewWord :: get_all( void )
{
return Mass ;
}
/************************************************************************/
char
* t_NewWord :: get_new( void )
{
return Mass+z_Mass ;
}
/************************************************************************/
void t_NewWord :: remember( )
{
z_Mass=j_Mass ;
}
/************************************************************************/
int tagsort1( const void *a, const void *b )
{ short i1,i2 ;
char s1[3],s2[3] ;
t_Format1 *FF=&Grammar.format1()[0] ;
i1=*(short *)a ;
i2=*(short *)b ;
strcpy( s1,FF->get_tag(0,i1) );
strcpy( s2,FF->get_tag(0,i2) );
return strcmp( s1,s2 );
}
/************************************************************************/
int tagsort2( const void *a, const void *b )
{ short i1,i2 ;
char s1[3],s2[3] ;
t_Format1 *FF=&Grammar.format1()[0] ;
i1=*(short *)a ;
i2=*(short *)b ;
strcpy( s1,FF->get_tag(1,i1) );
strcpy( s2,FF->get_tag(1,i2) );
return strcmp( s1,s2 );
}
/************************************************************************/
t_AddWord :: t_AddWord()
{
sStr [0]=dStr [0]=0 ;
sStr1[0]=dStr1[0]=0 ;
sStr2[0]=dStr2[0]=0 ;
j_Sou=j_Dst=0 ;
s_i_struct=d_i_struct=-1 ;
}
/************************************************************************/
// рассортировать структуры на головные и телесные
/************************************************************************/
void t_AddWord :: init( void )
{
short i,i_struct ;
e_Type t ;
FF=&Grammar.format1()[0] ;
sWord.j=dWord.j=sStruct.j=dStruct.j=0 ;
sWord.add( i_struct=-1 );
for( i=0 ; i<FF->SouPart.j ; i++ )
{ i_struct=FF->SouPart[i].i_part ;
t=Grammar[i_struct].From.type ;
if( t==TNULL || t==TCONST || t==TCONST1 || t==TWORD0 ) continue ;
if( t==TWORD || t==TSTRUCT || t==TSELECT || t==TSELECT1 || t==TSELECT2 )
{ sWord.add( i_struct ); }
if( t==TWORD || t==TSTRUCT1 || t==TSTRUCT2 )
{ sStruct.add( i_struct ); }
}
qsort( sWord.list , sWord.j ,sizeof(short),tagsort1 );
qsort( sStruct.list, sStruct.j ,sizeof(short),tagsort1 );
dWord.add( i_struct=-1 );
for( i=0 ; i<FF->DstPart.j ; i++ )
{ i_struct=FF->DstPart[i].i_part ;
t=Grammar[i_struct].To.type ;
if( t==TNULL || t==TCONST || t==TCONST1 || t==TWORD0 ) continue ;
if( t==TWORD || t==TSTRUCT || t==TSELECT || t==TSELECT1 || t==TSELECT2 )
{ dWord.add( i_struct ); }
if( t==TWORD || t==TSTRUCT1 || t==TSTRUCT2 )
{ dStruct.add( i_struct ); }
}
qsort( dWord.list , dWord.j ,sizeof(short),tagsort2 );
qsort( dStruct.list, dStruct.j ,sizeof(short),tagsort2 );
}
/************************************************************************/
void t_AddWord :: init1( void )
{
// sStr [0]=0 ;
dStr [0]=0 ;
sStr1[0]=dStr1[0]=0 ;
sStr2[0]=dStr2[0]=0 ;
j_Sou=j_Dst=0 ;
s_i_struct=d_i_struct=-1 ;
}
/************************************************************************/
void t_AddWord :: make_str( char *S )
{
strcpy( sStr,S );
}
/************************************************************************/
// разбить фразу на слова, сделать Sou
/************************************************************************/
void t_AddWord :: make_str1( char to )
{ short i,j,j1,j_Str ;
char *sdStr,*sdStr1 ;
t_sWord *WW ;
char Str[100] ;
if( to==0 ){ sdStr =sStr ; sdStr1=sStr1 ; WW=&Sou[0] ; }
else { sdStr =dStr ; sdStr1=dStr1 ; WW=&Dst[0] ; }
for( i=j=j1=j_Str=0 ; i<200 ; i++ )
{
if( (sdStr[i]==' ' || sdStr[i]==0) && 0<j )
{ Str[j]=0 ;
WW[j1].i_struct=-1 ;
WW[j1++].str =sdStr1+j_Str ;
strcpy( sdStr1+j_Str,Str );
sdStr1[j_Str+j]=0 ;
j_Str+=j+1 ;
j=0 ;
if( sdStr[i]==0 ) break ;
continue ;
}
Str[j++]=sdStr[i] ;
}
if( to==0 ) j_Sou=j1 ;
else j_Dst=j1 ;
}
/************************************************************************/
// сделать строку с тегами
/************************************************************************/
void t_AddWord :: make_str2( void )
{
long i ;
t_Format1 FFF=Grammar.format1()[0] ;
char Str1[100] ;
sStr2[0]=0 ;
for( i=0 ; i<j_Sou ; i++ )
{
sprintf( Str1,"%s[%s]", FFF.get_tag( 0,Sou[i].i_struct ),Sou[i].str );
strcat( sStr2,Str1 ); strcat( sStr2," " );
}
}
/************************************************************************/
// нарисовать теги и структуры
/************************************************************************/
void t_AddWord :: paint_struct( t_shortList &List, char to, short current )
{ short i,i1,begin,size_y1,i_struct ;
char f,*s ;
t_Struct *SS ;
char Str[100] ;
size_y1=y2-y1-11 ;
begin=0 ;
if( begin+size_y1<=current ) begin=current-size_y1 ;
for( i=0 ; begin+i<List.j && i<=size_y1 ; i++ )
{ if( begin+i==current ) f=0xf0 ; else f=0x0f ;
i_struct=List[begin+i] ;
if( 0<=i_struct )
{ if( to==0 ) SS=&Grammar[i_struct].From ;
else SS=&Grammar[i_struct].To ;
}
if( i_struct<0 ) s="константа" ; else s=SS->Name ;
sprintf( Str," %2s %s",FF->get_tag(to,i_struct),s );
if( SS->type==TSTRUCT1 )
{ strcat( Str, " =" );
for( i1=0 ; i1<SS->Word.j ; i1++ )
{ strcat( Str, " " );
strcat( Str, FF->get_tag(to,SS->Word[i1].i_struct) );
}
}
s_text_yxf( y1+10+i,3,f,Str );
}
}
/************************************************************************/
void t_AddWord :: paint( void )
{
t_Win::paint();
s_rame2_F( y1-1, x1-1, y2+1, x2+1, 0x0f );
s_text_yxf( y1-1,x1+3 ,name_Color, Name );
s_rame2_F ( y1 ,x1 ,y1+2, x2, 0x0f );
s_text_yxf( y1 ,x1+3 ,0x0f, "Выражение источника" );
if( Reg<=2 ) s_text_yxf( y1+1,x1+3 ,0x0f, sStr );
else s_text_yxf( y1+1,x1+3 ,0x0f, sStr2 );
s_rame2_F ( y1+3,x1 ,y1+5, x2, 0x0f );
s_text_yxf( y1+3,x1+3 ,0x0f, "Выражение приемника" );
s_text_yxf( y1+4,x1+3 ,0x0f, dStr );
s_rame2_F ( y1+6,x1 ,y1+8, x2, 0x0f );
s_text_yxf( y1+6,x1+3 ,0x0f, "Предполагаемый тег" );
s_rame2_F ( y1+9,x1 ,y2, x2, 0x0f );
s_text_yxf( y1+9,x1+3 ,0x0f, "Часть речи" );
}
/************************************************************************/
void t_AddWord :: paint_from( long i_Word )
{ short i,z ;
char Str[100] ;
uchar f[16]={ 0xf0 };
z=0 ;
sprintf( sStr2,"%2s:",FF->get_tag( 0,s_i_struct ) );
for( i=0 ; i<j_Sou ; i++ )
{ if( i_Word==i+1 ) z=strlen(sStr2)+1 ;
sprintf(Str," %2s[%s]",FF->get_tag( 0, Sou[i].i_struct ),Sou[i].str );
strcat( sStr2,Str );
}
s_text_yxf( y1+1, x1+3 ,0x0f, sStr2 );
s_color_yxt( y1+1, x1+3+z, f , "00" );
}
/************************************************************************/
void t_AddWord :: paint_to( long i_Word )
{ short i,z ;
char Str[100] ;
uchar f[16]={ 0xf0 };
z=0 ;
sprintf( dStr2,"%2s:",FF->get_tag( 1,d_i_struct ) );
for( i=0 ; i<j_Dst ; i++ )
{ if( i_Word==i+1 ) z=strlen(sStr2)+1 ;
sprintf(Str," %2s[%s]",FF->get_tag( 1, Dst[i].i_struct ),Dst[i].str );
strcat( dStr2,Str );
}
s_text_yxf( y1+4, x1+3 ,0x0f, dStr2 );
s_color_yxt( y1+1, x1+3+z, f , "00" );
}
/************************************************************************/
e_WinMsg t_AddWord :: loop( void )
{
e_WinMsg r ;
Reg=1 ;
init( );
init1( );
while( 1 )
{
paint( );
switch( Reg )
{
case 1 : r=line_edit( x1+1,y1+1,0x1f,sStr,x2-x1-1 );
make_str1( 0 ); break ;
case 2 : r=tag_edit1( 0 ); break ;
case 3 : paint_from( -1 );
r=line_edit( x1+1,y1+4,0x1f,dStr,x2-x1-1 );
make_str1( 1 ); break ;
case 4 : r=tag_edit1( 1 ); break ;
}
switch( r )
{
case WM_NEXT : case WM_OK :
if( Reg==4 ) goto M_End ;
else Reg++ ;
break ;
case WM_PREV : case WM_ESC :
if( Reg==1 ) return WM_ESC ;
else Reg-- ;
break ;
}
}
M_End:
NewWord.add( antwort() );
message("Идет обновление словаря.\n Ждите...");
Perevod.add_new( filename( MercuryDir,"dicts") ,NewWord.get_all() );
return WM_OK ;
}
/************************************************************************/
e_WinMsg line_edit( short x, short y, char f, char *Str, short Length )
{ e_WinMsg r ;
M1:r=kommand_yxf( y, x, f, Str, Length, 0x01, NULL, 0 );
switch( r )
{ case WM_HELP : Window_help( (void *)"newwords.html") ; goto M1;
case WM_PREV : case WM_NEXT : case WM_ESC : case WM_OK :
return r ;
}
return WM_ESC ;
}
/************************************************************************/
e_WinMsg t_AddWord :: tag_edit1( char to )
{
short i,i_struct,*sd_i_struct,i_Word,n_Word ;
t_shortList *Struct ;
t_shortList *Word ;
t_sWord *WW ;
t_Struct *SS ;
e_WinMsg r ;
e_Type t ;
if( 0==to )
{ n_Word= j_Sou ;
Struct=&sStruct ;
Word =&sWord ;
WW = Sou ;
sd_i_struct=&s_i_struct ;
sStruct1.j=0 ;
for( i=0 ; i<sStruct.j ; i++ )
{ t=Grammar[sStruct[i]].From.type ;
if( (t==TSTRUCT1 && Grammar[sStruct[i]].From.Word.j==n_Word) ||
(t==TWORD && n_Word==1 ) || t==TSTRUCT2 )
sStruct1.add( sStruct[i] );
}
Struct=&sStruct1 ;
}
else
{ n_Word= j_Dst ;
Struct=&dStruct ;
Word =&dWord ;
WW = Dst ;
sd_i_struct=&d_i_struct ;
dStruct1.j=0 ;
for( i=0 ; i<dStruct.j ; i++ )
{ t=Grammar[dStruct[i]].To.type ;
if( (t==TSTRUCT1 && Grammar[dStruct[i]].To.Word.j==n_Word) ||
(t==TWORD && n_Word==1 ) || t==TSTRUCT2 )
dStruct1.add( dStruct[i] );
}
Struct=&dStruct1 ;
if( Grammar[s_i_struct].From.type==TWORD )
WW[0].i_struct=d_i_struct=s_i_struct ;
}
i_Word=0 ;
while( 1 )
{
if( 0==to ) paint_from( i_Word );
else paint_to ( i_Word );
if( i_Word==0 ) r=tag_edit( *Struct, to, i_Word, i_struct );
else r=tag_edit( *Word , to, i_Word, i_struct );
switch( r )
{
case WM_NEXT : case WM_OK :
if( 0<i_Word )
WW[i_Word-1].i_struct=i_struct ;
else
{ *sd_i_struct=i_struct ;
if( 0==to ) SS=&Grammar[i_struct].From ;
else SS=&Grammar[i_struct].To ;
if( SS->type==TSTRUCT1 )
{ for( i=0 ; i<SS->Word.j ; i++ )
WW[i].i_struct=SS->Word[i].i_struct ;
}
if( SS->type==TWORD )
{ WW[0].i_struct=i_struct ; }
}
if( n_Word<=i_Word ) goto M_End ;
i_Word++ ;
break ;
case WM_PREV : case WM_ESC :
if( i_Word<=0 ) return WM_ESC ;
else i_Word-- ;
break ;
}
}
M_End: ;
return WM_OK ;
}
/************************************************************************/
e_WinMsg t_AddWord :: tag_edit( t_shortList &List, char to, short i_Word,
short &i_struct )
{
t_Format1 *FFF=&Grammar.format1()[0] ;
char Tag[10]="",*s ;
short i,z,jTag=0,current ;
short key1,key2 ;
if( to==0 ){ if( i_Word==0 ) z=s_i_struct ; else z=Sou[i_Word-1].i_struct ; }
else { if( i_Word==0 ) z=d_i_struct ; else z=Dst[i_Word-1].i_struct ; }
current=find( List,z ) ;
if( current<0 ) current=0 ;
while( 1 )
{
paint();
if( 0==to ) paint_from( i_Word );
else paint_to ( i_Word );
s_text_yxf( y1+7,3,0x0b,Tag );
paint_struct( List, to, current );
s_getch( &key1,&key2 );
if( key1==0 )
{ switch(key2)
{
case S_key_F1 : Window_help( (void *)"newwords.html") ; continue ;
case S_key_Left : return WM_PREV ;
case S_key_Right: goto M_End ;
case S_key_Up : if( 0<current ) current-- ; break ;
case S_key_Down : if( current<List.j-1 ) current++ ; break ;
}
}
else
{ switch( key1 )
{ case S_key_Back : if( 0<jTag ) Tag[--jTag]=0 ; break ;
case '\r' : goto M_End ;
case S_key_Esc: return WM_ESC ;
default:
Tag[jTag++]=key1 ;
Tag[jTag]=0 ;
for( i=0 ; i<List.j ; i++ )
{ s=FFF->get_tag( to,List[i] );
if( 0==strncmp(Tag,s,jTag ) )
{ current=i ; goto M_Ok ; }
}
Tag[--jTag]=0 ;
M_Ok : ;
if( 2<=jTag ) goto M_End ;
}
}
}
M_End :
i_struct=List[current] ;
return WM_OK ;
}
/************************************************************************/
short t_AddWord :: find( t_shortList &List, short z )
{ short i ;
for( i=0 ; i<List.j ; i++ )
if( List[i]==z ) return i ;
return -1 ;
}
/************************************************************************/
char
* t_AddWord :: antwort( void )
{ long i ;
sprintf( Antwort,"%s=%s",sStr2,dStr2 );
for( i=0 ; i<200 && Antwort[i]!=0 ; i++ )
if( Antwort[i]=='@' && Antwort[i+1]=='1' )
Antwort[i+1]='0' ;
return Antwort;
}