From b3ec90e07e00f3f28665207987bb9fb73153664b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Mar 2014 14:15:54 -0500 Subject: when choosing a primary device and more than one battery is found, accumulate their percentages and time-remaining properties as per the spec revisions in bug #880881. --- src/service.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 125 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 248f953..e042e9e 100644 --- a/src/service.c +++ b/src/service.c @@ -1125,6 +1125,129 @@ indicator_power_service_set_device_provider (IndicatorPowerService * self, } } +/* If a device has multiple batteries and uses only one of them at a time, + they should be presented as separate items inside the battery menu, + but everywhere else they should be aggregated (bug 880881). + Their percentages should be averaged. If any are discharging, + the aggregated time remaining should be the maximum of the times + for all those that are discharging, plus the sum of the times + for all those that are idle. Otherwise, the aggregated time remaining + should be the the maximum of the times for all those that are charging. */ +static IndicatorPowerDevice * +create_totalled_battery_device (const GList * devices) +{ + const GList * l; + guint n_charged = 0; + guint n_charging = 0; + guint n_discharging = 0; + guint n_batteries = 0; + double sum_percent = 0; + time_t max_discharge_time = 0; + time_t max_charge_time = 0; + time_t sum_charged_time = 0; + IndicatorPowerDevice * device = NULL; + + for (l=devices; l!=NULL; l=l->next) + { + const IndicatorPowerDevice * device = INDICATOR_POWER_DEVICE(l->data); + + if (indicator_power_device_get_kind(device) == UP_DEVICE_KIND_BATTERY) + { + const double percent = indicator_power_device_get_percentage (device); + const time_t t = indicator_power_device_get_time (device); + const UpDeviceState state = indicator_power_device_get_state (device); + + ++n_batteries; + + if (percent > 0.01) + sum_percent += percent; + + if (state == UP_DEVICE_STATE_CHARGING) + { + ++n_charging; + max_charge_time = MAX(max_charge_time, t); + } + else if (state == UP_DEVICE_STATE_DISCHARGING) + { + ++n_discharging; + max_discharge_time = MAX(max_discharge_time, t); + } + else if (state == UP_DEVICE_STATE_FULLY_CHARGED) + { + ++n_charged; + sum_charged_time += t; + } + } + } + + if (n_batteries > 1) + { + const double percent = sum_percent / n_batteries; + UpDeviceState state; + time_t time_left; + + if (n_discharging > 0) + { + state = UP_DEVICE_STATE_DISCHARGING; + time_left = max_discharge_time + sum_charged_time; + } + else if (n_charging > 0) + { + state = UP_DEVICE_STATE_CHARGING; + time_left = max_charge_time; + } + else if (n_charged > 0) + { + state = UP_DEVICE_STATE_FULLY_CHARGED; + time_left = 0; + } + else + { + state = UP_DEVICE_STATE_UNKNOWN; + time_left = 0; + } + + device = indicator_power_device_new (NULL, + UP_DEVICE_KIND_BATTERY, + percent, + state, + time_left); + } + + return device; +} + +/** + * If there are multiple UP_DEVICE_KIND_BATTERY devices in the list, + * they're merged into a new 'totalled' device representing the sum of them. + * + * Returns: (element-type IndicatorPowerDevice)(transfer full): a list of devices + */ +static GList* +merge_batteries_together (GList * devices) +{ + GList * ret; + IndicatorPowerDevice * merged_device; + + if ((merged_device = create_totalled_battery_device (devices))) + { + GList * l; + + ret = g_list_append (NULL, merged_device); + + for (l=devices; l!=NULL; l=l->next) + if (indicator_power_device_get_kind(INDICATOR_POWER_DEVICE(l->data)) != UP_DEVICE_KIND_BATTERY) + ret = g_list_append (ret, g_object_ref(l->data)); + } + else /* not enough batteries to merge */ + { + ret = g_list_copy (devices); + g_list_foreach (ret, (GFunc)g_object_ref, NULL); + } + + return ret; +} + IndicatorPowerDevice * indicator_power_service_choose_primary_device (GList * devices) { @@ -1132,13 +1255,10 @@ indicator_power_service_choose_primary_device (GList * devices) if (devices != NULL) { - GList * tmp; - - tmp = g_list_copy (devices); + GList * tmp = merge_batteries_together (devices); tmp = g_list_sort (tmp, device_compare_func); primary = g_object_ref (tmp->data); - - g_list_free (tmp); + g_list_free_full (tmp, (GDestroyNotify)g_object_unref); } return primary; -- cgit v1.2.3 From 9b33101ad8a9fc093e226c25e497fd8b1d51aee5 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Mar 2014 14:35:17 -0500 Subject: add translator comments to the new translatable strings. --- src/device.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/device.c b/src/device.c index e7384ee..8b97ef5 100644 --- a/src/device.c +++ b/src/device.c @@ -610,10 +610,12 @@ get_expanded_time_remaining (const IndicatorPowerDevice * device, if (p->state == UP_DEVICE_STATE_CHARGING) { + /* TRANSLATORS: H:MM (hours, minutes) to charge the battery. Example: "1:30 to charge" */ g_snprintf (str, size, _("%0d:%02d to charge"), hours, minutes); } else // discharging { + /* TRANSLATORS: H:MM (hours, minutes) to discharge the battery. Example: "1:30 left"*/ g_snprintf (str, size, _("%0d:%02d left"), hours, minutes); } } @@ -652,22 +654,38 @@ get_accessible_time_remaining (const IndicatorPowerDevice * device, if (p->state == UP_DEVICE_STATE_CHARGING) { if (hours > 0) - g_snprintf (str, size, _("%d %s %d %s to charge"), - hours, g_dngettext (NULL, "hour", "hours", hours), - minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + { + /* TRANSLATORS: "X (hour,hours) Y (minute,minutes) to charge" the battery. + Example: "1 hour 10 minutes to charge" */ + g_snprintf (str, size, _("%d %s %d %s to charge"), + hours, g_dngettext (NULL, "hour", "hours", hours), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + } else - g_snprintf (str, size, _("%d %s to charge"), - minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + { + /* TRANSLATORS: "Y (minute,minutes) to charge" the battery. + Example: "59 minutes to charge" */ + g_snprintf (str, size, _("%d %s to charge"), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + } } else // discharging { if (hours > 0) - g_snprintf (str, size, _("%d %s %d %s left"), - hours, g_dngettext (NULL, "hour", "hours", hours), - minutes, g_dngettext (NULL, "minute", "minutes", minutes)); - else - g_snprintf (str, size, _("%d %s left"), - minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + { + /* TRANSLATORS: "X (hour,hours) Y (minute,minutes) left" until the battery's empty. + Example: "1 hour 10 minutes left" */ + g_snprintf (str, size, _("%d %s %d %s left"), + hours, g_dngettext (NULL, "hour", "hours", hours), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + } + else + { + /* TRANSLATORS: "Y (minute,minutes) left" until the battery's empty. + Example: "59 minutes left" */ + g_snprintf (str, size, _("%d %s left"), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + } } } else @@ -720,6 +738,7 @@ get_menuitem_text (const IndicatorPowerDevice * device, if (p->state == UP_DEVICE_STATE_FULLY_CHARGED) { + /* TRANSLATORS: example: "battery (charged)" */ g_snprintf (str, size, _("%s (charged)"), kind_str); } else @@ -739,9 +758,14 @@ get_menuitem_text (const IndicatorPowerDevice * device, } if (*buf) - g_snprintf (str, size, _("%s (%s)"), kind_str, buf); + { + /* TRANSLATORS: example: "battery (time remaining)" */ + g_snprintf (str, size, _("%s (%s)"), kind_str, buf); + } else - g_strlcpy (str, kind_str, size); + { + g_strlcpy (str, kind_str, size); + } } } @@ -819,14 +843,17 @@ indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, if (want_time && want_percent) { + /* TRANSLATORS: after the icon, a time-remaining string + battery %. Example: "(0:59, 33%)" */ g_snprintf (str, size, _("(%s, %.0lf%%)"), tr, p->percentage); } else if (want_time) { + /* TRANSLATORS: after the icon, a time-remaining string Example: "(0:59)" */ g_snprintf (str, size, _("(%s)"), tr); } else if (want_percent) { + /* TRANSLATORS: after the icon, a battery %. Example: "(33%)" */ g_snprintf (str, size, _("(%.0lf%%)"), p->percentage); } else -- cgit v1.2.3