Alexandre Julliard : wrc: Add support for translating accelerators through po files.

Alexandre Julliard julliard at winehq.org
Tue Jan 24 14:25:31 CST 2012


Module: wine
Branch: master
Commit: ceadc43c78b228b9e7d0acafff287b0403907759
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ceadc43c78b228b9e7d0acafff287b0403907759

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jan 24 14:19:36 2012 +0100

wrc: Add support for translating accelerators through po files.

---

 tools/wrc/genres.c   |   68 ++++++++++++++++++++++++++++++++++++++++++++++-
 tools/wrc/parser.y   |    1 +
 tools/wrc/po.c       |   71 +++++++++++++++++++++++++++++++++++++++++++++++--
 tools/wrc/wrctypes.h |    1 +
 4 files changed, 136 insertions(+), 5 deletions(-)

diff --git a/tools/wrc/genres.c b/tools/wrc/genres.c
index 6b2d7ed..d6e641f 100644
--- a/tools/wrc/genres.c
+++ b/tools/wrc/genres.c
@@ -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;
 		}
diff --git a/tools/wrc/parser.y b/tools/wrc/parser.y
index e1a3c68..efcc050 100644
--- a/tools/wrc/parser.y
+++ b/tools/wrc/parser.y
@@ -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;
diff --git a/tools/wrc/po.c b/tools/wrc/po.c
index ffb584f..1d679ba 100644
--- a/tools/wrc/po.c
+++ b/tools/wrc/po.c
@@ -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 );
diff --git a/tools/wrc/wrctypes.h b/tools/wrc/wrctypes.h
index 4df9279..99699d7 100644
--- a/tools/wrc/wrctypes.h
+++ b/tools/wrc/wrctypes.h
@@ -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;




More information about the wine-cvs mailing list