[patch] new menu generation code simplifies translator's work



Hi all,

I rewrote the create_menu() function in src/menu.c to make the work of the translators easier. Until now, they have to count spaces to correctly align the menu items. Now the code inserts these spaces automatically.
Roland
Index: src/main.c
===================================================================
RCS file: /cvsroot/mc/mc/src/main.c,v
retrieving revision 1.349
diff -u -p -r1.349 main.c
--- src/main.c	8 Feb 2005 19:59:45 -0000	1.349
+++ src/main.c	4 Apr 2005 05:10:20 -0000
@@ -793,8 +793,8 @@ listmode_cmd (void)
 /* NOTICE: hotkeys specified here are overriden in menubar_paint_idx (alex) */
 static menu_entry LeftMenu[] = {
     {' ', N_("&Listing mode..."), 'L', listing_cmd},
-    {' ', N_("&Quick view     C-x q"), 'Q', quick_view_cmd},
-    {' ', N_("&Info           C-x i"), 'I', info_cmd},
+    {' ', N_("&Quick view\tC-x q"), 'Q', quick_view_cmd},
+    {' ', N_("&Info\tC-x i"), 'I', info_cmd},
     {' ', N_("&Tree"), 'T', tree_cmd},
     {' ', "", ' ', 0},
     {' ', N_("&Sort order..."), 'S', sort_cmd},
@@ -812,13 +812,13 @@ static menu_entry LeftMenu[] = {
 #endif
 #endif
     {' ', "", ' ', 0},
-    {' ', N_("&Rescan         C-r"), 'R', reread_cmd}
+    {' ', N_("&Rescan\tC-r"), 'R', reread_cmd}
 };
 
 static menu_entry RightMenu[] = {
     {' ', N_("&Listing mode..."), 'L', listing_cmd},
-    {' ', N_("&Quick view     C-x q"), 'Q', quick_view_cmd},
-    {' ', N_("&Info           C-x i"), 'I', info_cmd},
+    {' ', N_("&Quick view\tC-x q"), 'Q', quick_view_cmd},
+    {' ', N_("&Info\tC-x i"), 'I', info_cmd},
     {' ', N_("&Tree"), 'T', tree_cmd},
     {' ', "", ' ', 0},
     {' ', N_("&Sort order..."), 'S', sort_cmd},
@@ -836,32 +836,32 @@ static menu_entry RightMenu[] = {
 #endif
 #endif
     {' ', "", ' ', 0},
-    {' ', N_("&Rescan         C-r"), 'R', reread_cmd}
+    {' ', N_("&Rescan\tC-r"), 'R', reread_cmd}
 };
 
 static menu_entry FileMenu[] = {
-    {' ', N_("&User menu          F2"), 'U', user_file_menu_cmd},
-    {' ', N_("&View               F3"), 'V', view_cmd},
-    {' ', N_("Vie&w file...         "), 'W', view_file_cmd},
-    {' ', N_("&Filtered view     M-!"), 'F', filtered_view_cmd},
-    {' ', N_("&Edit               F4"), 'E', edit_cmd},
-    {' ', N_("&Copy               F5"), 'C', copy_cmd},
-    {' ', N_("c&Hmod           C-x c"), 'H', chmod_cmd},
-    {' ', N_("&Link            C-x l"), 'L', link_cmd},
-    {' ', N_("&SymLink         C-x s"), 'S', symlink_cmd},
-    {' ', N_("edit s&Ymlink  C-x C-s"), 'Y', edit_symlink_cmd},
-    {' ', N_("ch&Own           C-x o"), 'O', chown_cmd},
-    {' ', N_("&Advanced chown       "), 'A', chown_advanced_cmd},
-    {' ', N_("&Rename/Move        F6"), 'R', ren_cmd},
-    {' ', N_("&Mkdir              F7"), 'M', mkdir_cmd},
-    {' ', N_("&Delete             F8"), 'D', delete_cmd},
-    {' ', N_("&Quick cd          M-c"), 'Q', quick_cd_cmd},
+    {' ', N_("&User menu\tF2"), 'U', user_file_menu_cmd},
+    {' ', N_("&View\tF3"), 'V', view_cmd},
+    {' ', N_("Vie&w file..."), 'W', view_file_cmd},
+    {' ', N_("&Filtered view\tM-!"), 'F', filtered_view_cmd},
+    {' ', N_("&Edit\tF4"), 'E', edit_cmd},
+    {' ', N_("&Copy\tF5"), 'C', copy_cmd},
+    {' ', N_("c&Hmod\tC-x c"), 'H', chmod_cmd},
+    {' ', N_("&Link\tC-x l"), 'L', link_cmd},
+    {' ', N_("&SymLink\tC-x s"), 'S', symlink_cmd},
+    {' ', N_("edit s&Ymlink\tC-x C-s"), 'Y', edit_symlink_cmd},
+    {' ', N_("ch&Own\tC-x o"), 'O', chown_cmd},
+    {' ', N_("&Advanced chown"), 'A', chown_advanced_cmd},
+    {' ', N_("&Rename/Move\tF6"), 'R', ren_cmd},
+    {' ', N_("&Mkdir\tF7"), 'M', mkdir_cmd},
+    {' ', N_("&Delete\tF8"), 'D', delete_cmd},
+    {' ', N_("&Quick cd\tM-c"), 'Q', quick_cd_cmd},
     {' ', "", ' ', 0},
-    {' ', N_("select &Group      M-+"), 'G', select_cmd},
-    {' ', N_("u&Nselect group    M-\\"), 'N', unselect_cmd},
-    {' ', N_("reverse selec&Tion M-*"), 'T', reverse_selection_cmd},
+    {' ', N_("select &Group\tM-+"), 'G', select_cmd},
+    {' ', N_("u&Nselect group\tM-\\"), 'N', unselect_cmd},
+    {' ', N_("reverse selec&Tion\tM-*"), 'T', reverse_selection_cmd},
     {' ', "", ' ', 0},
-    {' ', N_("e&Xit              F10"), 'X', quit_cmd}
+    {' ', N_("e&Xit\tF10"), 'X', quit_cmd}
 };
 
 static menu_entry CmdMenu[] = {
@@ -870,20 +870,20 @@ static menu_entry CmdMenu[] = {
      * the WTree widget port, sorry.
      */
     {' ', N_("&Directory tree"), 'D', treebox_cmd},
-    {' ', N_("&Find file            M-?"), 'F', find_cmd},
-    {' ', N_("s&Wap panels          C-u"), 'W', swap_cmd},
-    {' ', N_("switch &Panels on/off C-o"), 'P', view_other_cmd},
-    {' ', N_("&Compare directories  C-x d"), 'C', compare_dirs_cmd},
-    {' ', N_("e&Xternal panelize    C-x !"), 'X', external_panelize},
+    {' ', N_("&Find file\tM-?"), 'F', find_cmd},
+    {' ', N_("s&Wap panels\tC-u"), 'W', swap_cmd},
+    {' ', N_("switch &Panels on/off\tC-o"), 'P', view_other_cmd},
+    {' ', N_("&Compare directories\tC-x d"), 'C', compare_dirs_cmd},
+    {' ', N_("e&Xternal panelize\tC-x !"), 'X', external_panelize},
     {' ', N_("show directory s&Izes"), 'I', dirsizes_cmd},
     {' ', "", ' ', 0},
     {' ', N_("command &History"), 'H', history_cmd},
-    {' ', N_("di&Rectory hotlist    C-\\"), 'R', quick_chdir_cmd},
+    {' ', N_("di&Rectory hotlist\tC-\\"), 'R', quick_chdir_cmd},
 #ifdef USE_VFS
-    {' ', N_("&Active VFS list      C-x a"), 'A', reselect_vfs},
+    {' ', N_("&Active VFS list\tC-x a"), 'A', reselect_vfs},
 #endif
 #ifdef WITH_BACKGROUND
-    {' ', N_("&Background jobs      C-x j"), 'B', jobs_cmd},
+    {' ', N_("&Background jobs\tC-x j"), 'B', jobs_cmd},
 #endif
     {' ', "", ' ', 0},
 #ifdef USE_EXT2FSLIB
Index: src/menu.c
===================================================================
RCS file: /cvsroot/mc/mc/src/menu.c,v
retrieving revision 1.46
diff -u -p -r1.46 menu.c
--- src/menu.c	8 Feb 2005 09:04:03 -0000	1.46
+++ src/menu.c	4 Apr 2005 05:10:21 -0000
@@ -48,35 +48,105 @@ menu_scan_hotkey (Menu *menu)
 	menu->hotkey = 0;
 }
 
+static void
+calculate_width(const char *menuitem, size_t * ret_caption_len,
+    size_t * ret_caption_width, size_t * ret_hotkey_width, int *ret_hot_key)
+{
+    const char *tab, *et;
+    size_t caption_len, hotkey_width, caption_width;
+
+    tab = strchr(menuitem, '\t');
+    if (tab != NULL) {
+	caption_len = (size_t) (tab - menuitem);
+	hotkey_width = strlen(tab + 1);
+    } else {
+	caption_len = strlen(menuitem);
+	hotkey_width = 0;
+    }
+
+    et = strchr(menuitem, '&');
+    caption_width = caption_len;
+    if (et != NULL && *(et + 1) != '\0') {
+	if (ret_hot_key)
+	    *ret_hot_key = tolower((unsigned char) *(et + 1));
+	caption_width--;
+    }
+	
+    *ret_caption_len   = caption_len;
+    *ret_caption_width = caption_width;
+    *ret_hotkey_width    = hotkey_width;
+}
+
+/* NB: will be moved to util.c before the commit */
+static void
+str_fillup(char *s, size_t ssize, char c)
+{
+    size_t slen;
+
+    slen = strlen(s);
+    if (slen < ssize) {
+	for (; slen < ssize - 1; slen++)
+	    s[slen] = c;
+	s[slen] = '\0';
+    }
+}
+
 Menu *
 create_menu (const char *name, menu_entry *entries, int count, const char *help_node)
 {
     Menu *menu;
-    const char *cp;
+    size_t caption_max_len, caption_max_width, hotkey_max_width;
+    size_t caption_len, caption_width, hotkey_width;
+    size_t gap_len;
+    size_t complete_max_len, complete_max_width;
+    int i;
 
     menu = (Menu *) g_malloc (sizeof (*menu));
     menu->count = count;
     menu->max_entry_len = 20;
     menu->entries = entries;
 
+    caption_max_len = 0;
+    caption_max_width = 0;
+    hotkey_max_width = 0;
+    gap_len = 0;
     if (entries != (menu_entry*) NULL) {
-	register menu_entry* mp;
-	for (mp = entries; count--; mp++) {
-	    if (mp->text[0] != '\0') {
-#ifdef ENABLE_NLS
-	        mp->text = _(mp->text);
-#endif /* ENABLE_NLS */
-	        cp = strchr (mp->text,'&');
-
-		if (cp != NULL && *(cp+1) != '\0') {
-		    mp->hot_key = tolower (*(cp+1));
-		    menu->max_entry_len = max ((int) (strlen (mp->text) - 1),
-			menu->max_entry_len);
-		} else {
-		    menu->max_entry_len = max ((int) strlen (mp->text),
-			menu->max_entry_len);
-		}
+	/* calculate the maximum width and length of the menu items */
+	for (i = 0; i < count; i++) {
+	    if (entries[i].text[0] != '\0') {
+	        entries[i].text = _(entries[i].text);
+		calculate_width(entries[i].text, &caption_len,
+		    &caption_width, &hotkey_width, &(entries[i].hot_key));
+
+		caption_max_len   = MAX (caption_max_len,   caption_len);
+		caption_max_width = MAX (caption_max_width, caption_width);
+		hotkey_max_width  = MAX (hotkey_max_width,  hotkey_width);
+	    }
+	}
+	gap_len = (hotkey_max_width != 0) ? 2 : 0;
+	complete_max_len   = caption_max_len   + gap_len + hotkey_max_width;
+	complete_max_width = caption_max_width + gap_len + hotkey_max_width;
+	menu->max_entry_len = complete_max_width;
+
+	/* expand the menu entries to the correct width */
+	for (i = 0; i < count; i++) {
+	    const char *rawtext = entries[i].text, *tab;
+	    char *disptext;
+	    size_t disptextsize = complete_max_len + 1;
+
+	    calculate_width(rawtext, &caption_len, &caption_width, &hotkey_width, NULL);
+	    tab = strchr(rawtext, '\t');
+
+	    /* this g_malloc creates a small memory leak,
+	     * but it is called only once per process */
+	    disptext = g_malloc(disptextsize);
+	    g_strlcpy(disptext, rawtext, caption_len + 1);
+	    str_fillup(disptext, caption_max_len + gap_len + 1, ' ');
+	    if (tab) {
+		str_fillup(disptext, disptextsize - strlen(tab + 1), ' ');
+		g_strlcat(disptext, tab + 1, disptextsize);
 	    }
+	    entries[i].text = disptext;
 	}
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]