wrc: Add support for translating accelerators through po files.

This commit is contained in:
Alexandre Julliard 2012-01-24 14:19:36 +01:00
parent 1bd693b139
commit ceadc43c78
4 changed files with 136 additions and 5 deletions

View File

@ -276,6 +276,66 @@ static void string_to_upper(string_t *str)
}
}
static int parse_accel_string( const string_t *key, int flags )
{
int keycode;
if(key->type == str_char)
{
if((flags & WRC_AF_VIRTKEY) &&
!((key->str.cstr[0] >= 'A' && key->str.cstr[0] <= 'Z') ||
(key->str.cstr[0] >= '0' && key->str.cstr[0] <= '9')))
{
print_location( &key->loc );
error("VIRTKEY code is not equal to ascii value");
}
if(key->str.cstr[0] == '^' && (flags & WRC_AF_CONTROL) != 0)
{
print_location( &key->loc );
error("Cannot use both '^' and CONTROL modifier");
}
else if(key->str.cstr[0] == '^')
{
keycode = toupper((unsigned char)key->str.cstr[1]) - '@';
if(keycode >= ' ')
{
print_location( &key->loc );
error("Control-code out of range");
}
}
else
keycode = key->str.cstr[0];
}
else
{
if((flags & WRC_AF_VIRTKEY) &&
!((key->str.wstr[0] >= 'A' && key->str.wstr[0] <= 'Z') ||
(key->str.wstr[0] >= '0' && key->str.wstr[0] <= '9')))
{
print_location( &key->loc );
error("VIRTKEY code is not equal to ascii value");
}
if(key->str.wstr[0] == '^' && (flags & WRC_AF_CONTROL) != 0)
{
print_location( &key->loc );
error("Cannot use both '^' and CONTROL modifier");
}
else if(key->str.wstr[0] == '^')
{
keycode = toupperW(key->str.wstr[1]) - '@';
if(keycode >= ' ')
{
print_location( &key->loc );
error("Control-code out of range");
}
}
else
keycode = key->str.wstr[0];
}
return keycode;
}
/*
*****************************************************************************
* Function : put_string
@ -514,8 +574,10 @@ static res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
restag = put_res_header(res, WRC_RT_ACCELERATOR, NULL, name, acc->memopt, &(acc->lvc));
while(ev)
{
int key = ev->key;
if (ev->str) key = parse_accel_string( ev->str, ev->flags );
put_word(res, ev->flags | (ev->next ? 0 : 0x80));
put_word(res, ev->key);
put_word(res, key);
put_word(res, ev->id);
put_word(res, 0); /* Padding */
ev = ev->next;
@ -527,8 +589,10 @@ static res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
restag = put_res_header(res, WRC_RT_ACCELERATOR, NULL, name, acc->memopt, NULL);
while(ev)
{
int key = ev->key;
if (ev->str) key = parse_accel_string( ev->str, ev->flags );
put_byte(res, ev->flags | (ev->next ? 0 : 0x80));
put_word(res, ev->key);
put_word(res, key);
put_word(res, ev->id);
ev = ev->next;
}

View File

@ -2219,6 +2219,7 @@ static event_t *add_string_event(string_t *key, int id, int flags, event_t *prev
keycode = key->str.wstr[0];
}
ev->str = key;
ev->key = keycode;
ev->id = id;
ev->flags = flags & ~WRC_AF_ASCII;

View File

@ -124,6 +124,16 @@ static char *get_message_context( char **msgid )
return context;
}
static int string_has_context( const string_t *str )
{
char *id, *id_buffer, *context;
id_buffer = id = convert_msgid_ascii( str, 1 );
context = get_message_context( &id );
free( id_buffer );
return context != NULL;
}
static int control_has_title( const control_t *ctrl )
{
if (!ctrl->title) return 0;
@ -155,6 +165,12 @@ static resource_t *dup_resource( resource_t *res, language_t *lang )
switch (res->type)
{
case res_acc:
new->res.acc = xmalloc( sizeof(*(new)->res.acc) );
*new->res.acc = *res->res.acc;
new->res.acc->lvc.language = lang;
new->res.acc->lvc.version = get_dup_version( lang );
break;
case res_dlg:
new->res.dlg = xmalloc( sizeof(*(new)->res.dlg) );
*new->res.dlg = *res->res.dlg;
@ -803,6 +819,34 @@ static void add_po_menu( const resource_t *english, const resource_t *res )
add_po_menu_items( po, english_items, items, res->res.men->lvc.language );
}
static void add_pot_accel( po_file_t po, const resource_t *res )
{
event_t *event = res->res.acc->events;
while (event)
{
/* accelerators without a context don't make sense in po files */
if (event->str && string_has_context( event->str ))
add_po_string( po, event->str, NULL, NULL );
event = event->next;
}
}
static void add_po_accel( const resource_t *english, const resource_t *res )
{
event_t *english_event = english->res.acc->events;
event_t *event = res->res.acc->events;
po_file_t po = get_po_file( res->res.acc->lvc.language );
while (english_event && event)
{
if (english_event->str && event->str && string_has_context( english_event->str ))
add_po_string( po, english_event->str, event->str, res->res.acc->lvc.language );
event = event->next;
english_event = english_event->next;
}
}
static resource_t *find_english_resource( resource_t *res )
{
resource_t *ptr;
@ -829,7 +873,7 @@ void write_pot_file( const char *outname )
switch (res->type)
{
case res_acc: break; /* FIXME */
case res_acc: add_pot_accel( po, res ); break;
case res_dlg: add_pot_dialog( po, res ); break;
case res_men: add_pot_menu( po, res ); break;
case res_stt: add_pot_stringtable( po, res ); break;
@ -850,7 +894,7 @@ void write_po_files( const char *outname )
if (!(english = find_english_resource( res ))) continue;
switch (res->type)
{
case res_acc: break; /* FIXME */
case res_acc: add_po_accel( english, res ); break;
case res_dlg: add_po_dialog( english, res ); break;
case res_men: add_po_menu( english, res ); break;
case res_stt: add_po_stringtable( english, res ); break;
@ -1089,6 +1133,26 @@ static void translate_dialog( dialog_t *dlg, dialog_t *new, int *found )
new->controls = translate_controls( dlg->controls, found );
}
static event_t *translate_accel( accelerator_t *acc, accelerator_t *new, int *found )
{
event_t *event, *new_ev, *head = NULL, *tail = NULL;
event = acc->events;
while (event)
{
new_ev = new_event();
*new_ev = *event;
if (event->str) new_ev->str = translate_string( event->str, found );
if (tail) tail->next = new_ev;
else head = new_ev;
new_ev->next = NULL;
new_ev->prev = tail;
tail = new_ev;
event = event->next;
}
return head;
}
static void translate_resources( language_t *lang )
{
resource_t *res;
@ -1103,7 +1167,8 @@ static void translate_resources( language_t *lang )
switch (res->type)
{
case res_acc:
/* FIXME */
new = dup_resource( res, lang );
new->res.acc->events = translate_accel( res->res.acc, new->res.acc, &found );
break;
case res_dlg:
new = dup_resource( res, lang );

View File

@ -537,6 +537,7 @@ typedef struct versioninfo {
typedef struct event {
struct event *next;
struct event *prev;
string_t *str;
int flags;
int key;
int id;