tui: add nmt_newt_text_width()
We were using g_utf8_strlen() to measure strings for layout, but that counts combining marks too, and also fails to deal with "fullwidth" (ie, double-width) CJK characters. Add a new utility function to do a better job of this (based on code from vte), and use it everywhere.
This commit is contained in:
@@ -95,7 +95,7 @@ nmt_newt_textbox_set_text (NmtNewtTextbox *textbox,
|
||||
{
|
||||
NmtNewtTextboxPrivate *priv = NMT_NEWT_TEXTBOX_GET_PRIVATE (textbox);
|
||||
char **lines;
|
||||
int i, len;
|
||||
int i, width;
|
||||
|
||||
if (!text)
|
||||
text = "";
|
||||
@@ -108,9 +108,9 @@ nmt_newt_textbox_set_text (NmtNewtTextbox *textbox,
|
||||
priv->width = priv->height = 0;
|
||||
lines = g_strsplit (priv->text, "\n", -1);
|
||||
for (i = 0; lines[i]; i++) {
|
||||
len = g_utf8_strlen (lines[i], -1);
|
||||
if (len > priv->width)
|
||||
priv->width = len;
|
||||
width = nmt_newt_text_width (lines[i]);
|
||||
if (width > priv->width)
|
||||
priv->width = width;
|
||||
}
|
||||
g_free (lines);
|
||||
priv->height = MIN (i, 1);
|
||||
|
@@ -259,6 +259,37 @@ nmt_newt_locale_from_utf8 (const char *str_utf8)
|
||||
return str_lc;
|
||||
}
|
||||
|
||||
/**
|
||||
* nmt_newt_text_width
|
||||
* @str: a UTF-8 string
|
||||
*
|
||||
* Computes the width (in terminal columns) of @str.
|
||||
*
|
||||
* Returns: the width of @str
|
||||
*/
|
||||
int
|
||||
nmt_newt_text_width (const char *str)
|
||||
{
|
||||
int width;
|
||||
gunichar ch;
|
||||
|
||||
for (width = 0; *str; str = g_utf8_next_char (str)) {
|
||||
ch = g_utf8_get_char (str);
|
||||
|
||||
/* Based on _vte_iso2022_unichar_width */
|
||||
if (G_LIKELY (ch < 0x80))
|
||||
width += 1;
|
||||
else if (G_UNLIKELY (g_unichar_iszerowidth (ch)))
|
||||
width += 0;
|
||||
else if (G_UNLIKELY (g_unichar_iswide (ch)))
|
||||
width += 2;
|
||||
else
|
||||
width += 1;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* nmt_newt_edit_string:
|
||||
* @data: data to edit
|
||||
|
@@ -37,6 +37,8 @@ typedef enum {
|
||||
char *nmt_newt_locale_to_utf8 (const char *str_lc);
|
||||
char *nmt_newt_locale_from_utf8 (const char *str_utf8);
|
||||
|
||||
int nmt_newt_text_width (const char *str);
|
||||
|
||||
void nmt_newt_message_dialog (const char *message,
|
||||
...);
|
||||
int nmt_newt_choice_dialog (const char *button1,
|
||||
|
@@ -436,7 +436,7 @@ nmt_connect_connection_list_rebuild (NmtConnectConnectionList *list)
|
||||
for (citer = nmtdev->conns; citer; citer = citer->next) {
|
||||
nmtconn = citer->data;
|
||||
|
||||
max_width = MAX (max_width, g_utf8_strlen (nmtconn->name, -1));
|
||||
max_width = MAX (max_width, nmt_newt_text_width (nmtconn->name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ nmt_connect_connection_list_rebuild (NmtConnectConnectionList *list)
|
||||
row = g_strdup_printf ("%c %s%-*s%s",
|
||||
active_col,
|
||||
nmtconn->name,
|
||||
(int)(max_width - g_utf8_strlen (nmtconn->name, -1)), "",
|
||||
(int)(max_width - nmt_newt_text_width (nmtconn->name)), "",
|
||||
strength_col);
|
||||
|
||||
nmt_newt_listbox_append (listbox, row, nmtconn);
|
||||
|
@@ -211,13 +211,13 @@ nmt_route_table_init (NmtRouteTable *table)
|
||||
NmtRouteTablePrivate *priv = NMT_ROUTE_TABLE_GET_PRIVATE (table);
|
||||
NmtNewtWidget *header, *empty;
|
||||
NmtNewtWidget *dest_prefix_label, *next_hop_label, *metric_label;
|
||||
int dest_prefix_len, next_hop_len, metric_len;
|
||||
int dest_prefix_width, next_hop_width, metric_width;
|
||||
char *text;
|
||||
|
||||
header = nmt_newt_grid_new ();
|
||||
|
||||
text = g_strdup_printf ("%s/%s", _("Destination"), _("Prefix"));
|
||||
dest_prefix_len = g_utf8_strlen (text, -1);
|
||||
dest_prefix_width = nmt_newt_text_width (text);
|
||||
dest_prefix_label = g_object_new (NMT_TYPE_NEWT_LABEL,
|
||||
"text", text,
|
||||
"style", NMT_NEWT_LABEL_PLAIN,
|
||||
@@ -230,7 +230,7 @@ nmt_route_table_init (NmtRouteTable *table)
|
||||
"text", text,
|
||||
"style", NMT_NEWT_LABEL_PLAIN,
|
||||
NULL);
|
||||
next_hop_len = g_utf8_strlen (text, -1);
|
||||
next_hop_width = nmt_newt_text_width (text);
|
||||
nmt_newt_grid_add (NMT_NEWT_GRID (header), next_hop_label, 1, 0);
|
||||
|
||||
text = _("Metric");
|
||||
@@ -238,18 +238,18 @@ nmt_route_table_init (NmtRouteTable *table)
|
||||
"text", text,
|
||||
"style", NMT_NEWT_LABEL_PLAIN,
|
||||
NULL);
|
||||
metric_len = g_utf8_strlen (text, -1);
|
||||
metric_width = nmt_newt_text_width (text);
|
||||
nmt_newt_grid_add (NMT_NEWT_GRID (header), metric_label, 2, 0);
|
||||
|
||||
priv->ip_entry_width = MAX (20, MAX (dest_prefix_len, next_hop_len));
|
||||
priv->metric_entry_width = MAX (7, metric_len);
|
||||
priv->ip_entry_width = MAX (20, MAX (dest_prefix_width, next_hop_width));
|
||||
priv->metric_entry_width = MAX (7, metric_width);
|
||||
|
||||
nmt_newt_widget_set_padding (dest_prefix_label,
|
||||
0, 0, priv->ip_entry_width - dest_prefix_len, 0);
|
||||
0, 0, priv->ip_entry_width - dest_prefix_width, 0);
|
||||
nmt_newt_widget_set_padding (next_hop_label,
|
||||
2, 0, priv->ip_entry_width - next_hop_len, 0);
|
||||
2, 0, priv->ip_entry_width - next_hop_width, 0);
|
||||
nmt_newt_widget_set_padding (metric_label,
|
||||
2, 0, priv->metric_entry_width - metric_len, 0);
|
||||
2, 0, priv->metric_entry_width - metric_width, 0);
|
||||
|
||||
nmt_newt_grid_add (NMT_NEWT_GRID (table), header, 0, 0);
|
||||
|
||||
|
@@ -193,15 +193,15 @@ listbox_active_changed (GObject *object,
|
||||
gboolean has_selection;
|
||||
|
||||
if (G_UNLIKELY (activate == NULL)) {
|
||||
int activate_len, deactivate_len;
|
||||
int activate_width, deactivate_width;
|
||||
|
||||
activate = _("Activate");
|
||||
activate_len = g_utf8_strlen (activate, -1);
|
||||
activate_width = nmt_newt_text_width (activate);
|
||||
deactivate = _("Deactivate");
|
||||
deactivate_len = g_utf8_strlen (deactivate, -1);
|
||||
deactivate_width = nmt_newt_text_width (deactivate);
|
||||
|
||||
activate_padding = MAX (0, deactivate_len - activate_len);
|
||||
deactivate_padding = MAX (0, activate_len - deactivate_len);
|
||||
activate_padding = MAX (0, deactivate_width - activate_width);
|
||||
deactivate_padding = MAX (0, activate_width - deactivate_width);
|
||||
}
|
||||
|
||||
has_selection = nmt_connect_connection_list_get_selection (list, NULL, NULL, NULL, &ac);
|
||||
|
@@ -164,7 +164,7 @@ usage (void)
|
||||
g_printerr ("%s: nmtui\n", usage);
|
||||
for (i = 0; i < num_subprograms; i++) {
|
||||
g_printerr ("%*s nmtui %s [%s]\n",
|
||||
(int) g_utf8_strlen (usage, -1), " ",
|
||||
nmt_newt_text_width (usage), " ",
|
||||
subprograms[i].name,
|
||||
_(subprograms[i].arg));
|
||||
}
|
||||
|
Reference in New Issue
Block a user