diff options
-rw-r--r-- | src/mate-screensaver-preferences.c | 138 |
1 files changed, 62 insertions, 76 deletions
diff --git a/src/mate-screensaver-preferences.c b/src/mate-screensaver-preferences.c index d20c364..1bcdcaf 100644 --- a/src/mate-screensaver-preferences.c +++ b/src/mate-screensaver-preferences.c @@ -969,13 +969,7 @@ static char * time_to_string_text (long time) { char *secs, *mins, *hours, *string; - char *chk_hour_str, *chk_minute_str, *chk_hour_minute_str; - char *chk_ascii_str; int sec, min, hour; - size_t chk_ascii_len; - int len_minutes; - int n, inc_len; - int diff; sec = time % 60; time = time - sec; @@ -992,52 +986,6 @@ time_to_string_text (long time) secs = g_strdup_printf (ngettext ("%d second", "%d seconds", sec), sec); - /* inc_len = it's the lenght of the string "1 hour 59 minutes" */ - chk_hour_str = g_strdup_printf (ngettext ("%d hour", - "%d hours", 1), 1); - chk_minute_str = g_strdup_printf (ngettext ("%d minute", - "%d minutes", 59), 59); - chk_hour_minute_str = g_strdup_printf (_("%s %s"), - chk_hour_str, chk_minute_str); - inc_len = strlen (chk_hour_minute_str) - 1; - g_free (chk_hour_str); - g_free (chk_minute_str); - g_free (chk_hour_minute_str); - - len_minutes = 0; - for (n = 2; n < 60; n++) - { - char *minute_str = g_strdup_printf (ngettext ("%d minute", - "%d minutes", n), n); - char *ascii_str = g_str_to_ascii (minute_str, NULL); - size_t ascii_str_len = strlen (ascii_str); - size_t extra_length = (n < 10) ? 2 : 3; - - diff = (int) (ascii_str_len - extra_length); - if (diff > len_minutes) - len_minutes = diff; - - g_free (minute_str); - g_free (ascii_str); - } - - /* check the lenght of the string "1 minute" */ - chk_minute_str = g_strdup_printf (ngettext ("%d minute", - "%d minutes", 1), 1); - chk_ascii_str = g_str_to_ascii (chk_minute_str, NULL); - chk_ascii_len = strlen (chk_ascii_str); - diff = (int) (chk_ascii_len - 2); - - if (diff > len_minutes) - len_minutes = diff; - - g_free (chk_minute_str); - g_free (chk_ascii_str); - - /* len_minutes = MAX (1, len_minutes) */ - if (len_minutes < 1) - len_minutes = 1; - if (hour > 0) { if (sec > 0) @@ -1060,28 +1008,7 @@ time_to_string_text (long time) else { /* minutes */ - size_t max_len; - string = g_strdup_printf (_("%s"), mins); - if (min == 1) - max_len = (size_t) (len_minutes + inc_len + 3); - else if (min < 10) - max_len = (size_t) (len_minutes + inc_len); - else - max_len = (size_t) (len_minutes + inc_len - 1); - - while (strlen (string) != max_len) - { - char *string_aux; - - if (strlen (string) % 2 == 0) - string_aux = g_strconcat (string, " ", NULL); - else - string_aux = g_strconcat (" " , string, NULL); - - g_free (string); - string = string_aux; - } } } else @@ -1101,11 +1028,70 @@ static char * format_value_callback_time (GtkScale *scale, gdouble value) { - /*You need to make up for 27 characters in length, otherwise the display will split into different lines*/ + gchar *time_str, *big_time_str; + GtkAdjustment *adj; + gdouble lower, range, delta; + gint pad_size; + + /* get the value representation as a string */ if (value == 0) - return g_strdup_printf (_("Never ")); + time_str = g_strdup (_("Never")); + else + time_str = time_to_string_text ((long) (value * 60.0)); + + /* Now, adjust the string so the representation for the bounds are the + * longest ones, and try and adjust the length as smoothly as possible. + * The issue here is that GTK is using the lower and upper value + * representations to compute the largest expected value's bounding box, + * so those need to be bigger than anything else we might represent, + * otherwise layout gets messed up (wraps and overflows). To achieve this, + * we pad the values near each bound so its length is at least the same as + * the biggest actual value. We cannot really do anything perfect here + * because what matters is the pango layout size for the largest value, but + * we don't have access to enough information to create one matching what + * GTK will actually use, and even so it'd be trial-and-error until the + * layout is big enough. So the silly assumptions below are probably good + * enough. */ + adj = gtk_range_get_adjustment (GTK_RANGE (scale)); + lower = gtk_adjustment_get_lower (adj); + range = gtk_adjustment_get_upper (adj) - lower; + delta = range / 2 - (value - lower); + /* the largest (character-wise) time string we expect */ + big_time_str = time_to_string_text (7199 /* 1:59:59 */); + pad_size = ((g_utf8_strlen (big_time_str, -1) * (ABS (delta) / range)) - + g_utf8_strlen (time_str, -1)); + g_free (big_time_str); + if (pad_size > 0) + { + /* pad string with EM SPACE (U+2003) */ + GString *padded = g_string_new (NULL); + + /* adjust pad side in RTL locales that aren't actually translated, as + * a properly translated one would have text drawn RTL already */ + if (gtk_widget_get_direction (GTK_WIDGET (scale)) == GTK_TEXT_DIR_RTL) + { + const gchar *msg_plural = "%d minutes"; + if (ngettext ("%d minute", msg_plural, 2) == msg_plural) + delta *= -1; + } + + if (delta < 0) + { + for (gint i = 0; i < pad_size; i++) + g_string_append_unichar (padded, 0x2003); + g_string_append (padded, time_str); + } + else + { + g_string_append (padded, time_str); + for (gint i = 0; i < pad_size; i++) + g_string_append_unichar (padded, 0x2003); + } + g_free (time_str); + time_str = g_string_free (padded, FALSE); + } - return time_to_string_text ((long) (value * 60.0)); + return time_str; } static void |