Merge lp:~charlesk/indicator-power/lp-811777 into lp:indicator-power/13.10

Proposed by Charles Kerr
Status: Merged
Approved by: Charles Kerr
Approved revision: 193
Merged at revision: 188
Proposed branch: lp:~charlesk/indicator-power/lp-811777
Merge into: lp:indicator-power/13.10
Diff against target: 959 lines (+322/-214)
8 files modified
data/com.canonical.indicator.power.gschema.xml.in (+5/-0)
src/device-provider.c (+1/-1)
src/device.c (+120/-56)
src/device.h (+16/-15)
src/service.c (+76/-84)
tests/test-dbus-listener.cc (+11/-11)
tests/test-device.cc (+90/-44)
tests/test-service.cc (+3/-3)
To merge this branch: bzr merge lp:~charlesk/indicator-power/lp-811777
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+181707@code.launchpad.net

Description of the change

Updates the power indicator to match the spec changes at <https://wiki.ubuntu.com/Power?action=diff&rev2=37&rev1=36>.

This patch is based from hloeung's nice patch, fixes a few edge cases, adds unit tests for labels, headers, & accessible text for all combinations of show time & show percentage, and cleans up the bindings between GSettings and the checkbox actions.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
192. By Charles Kerr

copyediting: more descriptive comments when building label/header/a11y text

193. By Charles Kerr

copyediting: some newly-dead code should have been removed instead of just commented out

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ted Gould (ted) wrote :

Only comment is that this should probably be deleted. Otherwise, cool!

610 + //g_signal_connect (p->settings, "changed::" SETTINGS_SHOW_TIME_S,
611 + // G_CALLBACK(on_show_time_setting_changed), self);

Top approve when that gets dropped.

review: Approve
Revision history for this message
Charles Kerr (charlesk) wrote :

heh, looks like we both saw that at the same time :)

> 193. By Charles Kerr 29 minutes ago
> copyediting: some newly-dead code should have been removed instead of just commented out

> Ted Gould (ted) wrote 13 minutes ago:
> Only comment is that this should probably be deleted. Otherwise, cool!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/com.canonical.indicator.power.gschema.xml.in'
2--- data/com.canonical.indicator.power.gschema.xml.in 2012-02-02 05:00:03 +0000
3+++ data/com.canonical.indicator.power.gschema.xml.in 2013-08-23 14:01:50 +0000
4@@ -10,6 +10,11 @@
5 <_summary>Show time in Menu Bar</_summary>
6 <_description>Whether or not to show the time in the menu bar.</_description>
7 </key>
8+ <key name="show-percentage" type="b">
9+ <default>false</default>
10+ <_summary>Show percentage in Menu Bar</_summary>
11+ <_description>Whether or not to show the percentage in the menu bar.</_description>
12+ </key>
13 <key enum="icon-policy-enum" name="icon-policy">
14 <default>"present"</default>
15 <_summary>When to show the battery status in the menu bar.</_summary>
16
17=== modified file 'src/device-provider.c'
18--- src/device-provider.c 2013-06-19 15:01:19 +0000
19+++ src/device-provider.c 2013-08-23 14:01:50 +0000
20@@ -54,7 +54,7 @@
21 * An easy way to free the list properly in one step is as follows:
22 *
23 * g_slist_free_full (list, (GDestroyNotify)g_object_unref);
24- *
25+ *
26 * Return value: (element-type IndicatorPowerDevice)
27 * (transfer full):
28 * list of devices
29
30=== modified file 'src/device.c'
31--- src/device.c 2013-06-17 04:16:19 +0000
32+++ src/device.c 2013-08-23 14:01:50 +0000
33@@ -449,10 +449,11 @@
34 ****
35 ***/
36
37+/* Format time remaining for reading ("H:MM") and speech ("H hours, MM minutes") */
38 static void
39 get_timestring (guint64 time_secs,
40- gchar **short_timestring,
41- gchar **detailed_timestring)
42+ gchar **readable_timestring,
43+ gchar **accessible_timestring)
44 {
45 gint hours;
46 gint minutes;
47@@ -462,16 +463,16 @@
48
49 if (minutes == 0)
50 {
51- *short_timestring = g_strdup (_("Unknown time"));
52- *detailed_timestring = g_strdup (_("Unknown time"));
53+ *readable_timestring = g_strdup (_("Unknown time"));
54+ *accessible_timestring = g_strdup (_("Unknown time"));
55
56 return;
57 }
58
59 if (minutes < 60)
60 {
61- *short_timestring = g_strdup_printf ("0:%.2i", minutes);
62- *detailed_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%i minute",
63+ *readable_timestring = g_strdup_printf ("0:%.2i", minutes);
64+ *accessible_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%i minute",
65 "%i minutes",
66 minutes), minutes);
67 return;
68@@ -480,11 +481,11 @@
69 hours = minutes / 60;
70 minutes = minutes % 60;
71
72- *short_timestring = g_strdup_printf ("%i:%.2i", hours, minutes);
73+ *readable_timestring = g_strdup_printf ("%i:%.2i", hours, minutes);
74
75 if (minutes == 0)
76 {
77- *detailed_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE,
78+ *accessible_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE,
79 "%i hour",
80 "%i hours",
81 hours), hours);
82@@ -493,7 +494,7 @@
83 {
84 /* TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes"
85 * Swap order with "%2$s %2$i %1$s %1$i if needed */
86- *detailed_timestring = g_strdup_printf (_("%i %s %i %s"),
87+ *accessible_timestring = g_strdup_printf (_("%i %s %i %s"),
88 hours, g_dngettext (GETTEXT_PACKAGE, "hour", "hours", hours),
89 minutes, g_dngettext (GETTEXT_PACKAGE, "minute", "minutes", minutes));
90 }
91@@ -561,86 +562,149 @@
92 return text;
93 }
94
95-void
96-indicator_power_device_get_time_details (const IndicatorPowerDevice * device,
97- gchar ** short_details,
98- gchar ** details,
99- gchar ** accessible_name)
100+static char *
101+join_strings (const char * name, const char * time, const char * percent)
102+{
103+ char * str;
104+ const gboolean have_name = name && *name;
105+ const gboolean have_time = time && *time;
106+ const gboolean have_percent = percent && *percent;
107+
108+ if (have_name && have_time && have_percent)
109+ str = g_strdup_printf (_("%s (%s, %s)"), name, time, percent);
110+ else if (have_name && have_time)
111+ str = g_strdup_printf (_("%s (%s)"), name, time);
112+ else if (have_name && have_percent)
113+ str = g_strdup_printf (_("%s (%s)"), name, percent);
114+ else if (have_name)
115+ str = g_strdup (name);
116+ else if (have_time && have_percent)
117+ str = g_strdup_printf (_("(%s, %s)"), time, percent);
118+ else if (have_time)
119+ str = g_strdup_printf (_("(%s)"), time);
120+ else if (have_percent)
121+ str = g_strdup_printf (_("(%s)"), percent);
122+ else
123+ str = g_strdup ("");
124+
125+ return str;
126+}
127+
128+static void
129+indicator_power_device_get_text (const IndicatorPowerDevice * device,
130+ gboolean show_time_in_header,
131+ gboolean show_percentage_in_header,
132+ gchar ** header,
133+ gchar ** label,
134+ gchar ** a11y)
135 {
136 if (!INDICATOR_IS_POWER_DEVICE(device))
137 {
138- *short_details = NULL;
139- *details = NULL;
140- *accessible_name = NULL;
141+ if (a11y != NULL) *a11y = NULL;
142+ if (label != NULL) *label = NULL;
143+ if (header != NULL) *header = NULL;
144 g_warning ("%s: %p is not an IndicatorPowerDevice", G_STRFUNC, device);
145 return;
146 }
147
148 const time_t time = indicator_power_device_get_time (device);
149 const UpDeviceState state = indicator_power_device_get_state (device);
150+ const UpDeviceKind kind = indicator_power_device_get_kind (device);
151+ const gchar * device_name = device_kind_to_localised_string (kind);
152 const gdouble percentage = indicator_power_device_get_percentage (device);
153- const UpDeviceKind kind = indicator_power_device_get_kind (device);
154- const gchar * device_name = device_kind_to_localised_string (kind);
155+ char pctstr[32] = { '\0' };
156+ g_snprintf (pctstr, sizeof(pctstr), "%.0lf%%", percentage);
157+
158+ GString * terse_time = g_string_new (NULL);
159+ GString * verbose_time = g_string_new (NULL);
160+ GString * accessible_time = g_string_new (NULL);
161
162 if (time > 0)
163 {
164- gchar *short_timestring = NULL;
165- gchar *detailed_timestring = NULL;
166-
167- get_timestring (time,
168- &short_timestring,
169- &detailed_timestring);
170+ char * readable_timestr = NULL;
171+ char * accessible_timestr = NULL;
172+ get_timestring (time, &readable_timestr, &accessible_timestr);
173
174 if (state == UP_DEVICE_STATE_CHARGING)
175 {
176- /* TRANSLATORS: %2 is a time string, e.g. "1 hour 5 minutes" */
177- *accessible_name = g_strdup_printf (_("%s (%s to charge (%.0lf%%))"), device_name, detailed_timestring, percentage);
178- *details = g_strdup_printf (_("%s (%s to charge)"), device_name, short_timestring);
179- *short_details = g_strdup_printf ("(%s)", short_timestring);
180+ g_string_assign (terse_time, readable_timestr);
181+ g_string_printf (verbose_time, _("%s to charge"), readable_timestr);
182+ g_string_printf (accessible_time, _("%s to charge"), accessible_timestr);
183 }
184- else if ((state == UP_DEVICE_STATE_DISCHARGING) && (time > (60*60*12)))
185+ else if ((state == UP_DEVICE_STATE_DISCHARGING) && (time <= (60*60*12)))
186 {
187- *accessible_name = g_strdup_printf (_("%s"), device_name);
188- *details = g_strdup_printf (_("%s"), device_name);
189- *short_details = g_strdup (short_timestring);
190+ g_string_assign (terse_time, readable_timestr);
191+ g_string_printf (verbose_time, _("%s left"), readable_timestr);
192+ g_string_printf (accessible_time, _("%s left"), accessible_timestr);
193 }
194 else
195 {
196- /* TRANSLATORS: %2 is a time string, e.g. "1 hour 5 minutes" */
197- *accessible_name = g_strdup_printf (_("%s (%s left (%.0lf%%))"), device_name, detailed_timestring, percentage);
198- *details = g_strdup_printf (_("%s (%s left)"), device_name, short_timestring);
199- *short_details = g_strdup (short_timestring);
200+ /* if there's more than 12 hours remaining, we don't show it */
201 }
202
203- g_free (short_timestring);
204- g_free (detailed_timestring);
205+ g_free (readable_timestr);
206+ g_free (accessible_timestr);
207 }
208 else if (state == UP_DEVICE_STATE_FULLY_CHARGED)
209 {
210- *details = g_strdup_printf (_("%s (charged)"), device_name);
211- *accessible_name = g_strdup (*details);
212- *short_details = g_strdup ("");
213+ g_string_assign (verbose_time, _("charged"));
214+ g_string_assign (accessible_time, _("charged"));
215 }
216 else if (percentage > 0)
217 {
218- /* TRANSLATORS: %2 is a percentage value. Note: this string is only
219- * used when we don't have a time value */
220- *details = g_strdup_printf (_("%s (%.0lf%%)"), device_name, percentage);
221- *accessible_name = g_strdup (*details);
222- *short_details = g_strdup_printf (_("(%.0lf%%)"), percentage);
223- }
224- else if (kind == UP_DEVICE_KIND_LINE_POWER)
225- {
226- *details = g_strdup (device_name);
227- *accessible_name = g_strdup (device_name);
228- *short_details = g_strdup ("");
229+ g_string_assign (terse_time, _("estimating…"));
230+ g_string_assign (verbose_time, _("estimating…"));
231+ g_string_assign (accessible_time, _("estimating…"));
232 }
233 else
234 {
235- *details = g_strdup_printf (_("%s (not present)"), device_name);
236- *accessible_name = g_strdup (*details);
237- *short_details = g_strdup (_("(not present)"));
238+ *pctstr = '\0';
239+
240+ if (kind != UP_DEVICE_KIND_LINE_POWER)
241+ {
242+ g_string_assign (verbose_time, _("not present"));
243+ g_string_assign (accessible_time, _("not present"));
244+ }
245 }
246+
247+ if (header != NULL)
248+ *header = join_strings (NULL,
249+ show_time_in_header ? terse_time->str : "",
250+ show_percentage_in_header ? pctstr : "");
251+
252+ if (label != NULL)
253+ *label = join_strings (device_name,
254+ verbose_time->str,
255+ NULL);
256+
257+ if (a11y != NULL)
258+ *a11y = join_strings (device_name,
259+ accessible_time->str,
260+ pctstr);
261+
262+ g_string_free (terse_time, TRUE);
263+ g_string_free (verbose_time, TRUE);
264+ g_string_free (accessible_time, TRUE);
265+}
266+
267+gchar *
268+indicator_power_device_get_label (const IndicatorPowerDevice * device)
269+{
270+ gchar * label = NULL;
271+ indicator_power_device_get_text (device, FALSE, FALSE,
272+ NULL, &label, NULL);
273+ return label;
274+}
275+
276+void
277+indicator_power_device_get_header (const IndicatorPowerDevice * device,
278+ gboolean show_time,
279+ gboolean show_percentage,
280+ gchar ** header,
281+ gchar ** a11y)
282+{
283+ indicator_power_device_get_text (device, show_time, show_percentage,
284+ header, NULL, a11y);
285 }
286
287 /***
288
289=== modified file 'src/device.h'
290--- src/device.h 2013-06-17 04:16:19 +0000
291+++ src/device.h 2013-08-23 14:01:50 +0000
292@@ -116,21 +116,22 @@
293 IndicatorPowerDevice* indicator_power_device_new_from_variant (GVariant * variant);
294
295
296-UpDeviceKind indicator_power_device_get_kind (const IndicatorPowerDevice * device);
297-UpDeviceState indicator_power_device_get_state (const IndicatorPowerDevice * device);
298-const gchar * indicator_power_device_get_object_path (const IndicatorPowerDevice * device);
299-gdouble indicator_power_device_get_percentage (const IndicatorPowerDevice * device);
300-time_t indicator_power_device_get_time (const IndicatorPowerDevice * device);
301-
302-GStrv indicator_power_device_get_icon_names (const IndicatorPowerDevice * device);
303-GIcon * indicator_power_device_get_gicon (const IndicatorPowerDevice * device);
304-
305-void indicator_power_device_get_time_details (const IndicatorPowerDevice * device,
306- gchar ** short_details,
307- gchar ** details,
308- gchar ** accessible_name);
309-
310-
311+UpDeviceKind indicator_power_device_get_kind (const IndicatorPowerDevice * device);
312+UpDeviceState indicator_power_device_get_state (const IndicatorPowerDevice * device);
313+const gchar * indicator_power_device_get_object_path (const IndicatorPowerDevice * device);
314+gdouble indicator_power_device_get_percentage (const IndicatorPowerDevice * device);
315+time_t indicator_power_device_get_time (const IndicatorPowerDevice * device);
316+
317+GStrv indicator_power_device_get_icon_names (const IndicatorPowerDevice * device);
318+GIcon * indicator_power_device_get_gicon (const IndicatorPowerDevice * device);
319+
320+gchar * indicator_power_device_get_label (const IndicatorPowerDevice * device);
321+
322+void indicator_power_device_get_header (const IndicatorPowerDevice * device,
323+ gboolean show_time,
324+ gboolean show_percentage,
325+ gchar ** header,
326+ gchar ** a11y);
327
328
329 G_END_DECLS
330
331=== modified file 'src/service.c'
332--- src/service.c 2013-08-20 03:47:23 +0000
333+++ src/service.c 2013-08-23 14:01:50 +0000
334@@ -33,6 +33,7 @@
335
336 #define SETTINGS_SHOW_TIME_S "show-time"
337 #define SETTINGS_ICON_POLICY_S "icon-policy"
338+#define SETTINGS_SHOW_PERCENTAGE_S "show-percentage"
339
340 G_DEFINE_TYPE (IndicatorPowerService,
341 indicator_power_service,
342@@ -112,6 +113,7 @@
343 GSimpleActionGroup * actions;
344 GSimpleAction * header_action;
345 GSimpleAction * show_time_action;
346+ GSimpleAction * show_percentage_action;
347 GSimpleAction * battery_level_action;
348 GSimpleAction * brightness_action;
349
350@@ -318,16 +320,13 @@
351
352 if (p->primary_device != NULL)
353 {
354- gchar * details;
355-
356- indicator_power_device_get_time_details (p->primary_device,
357- &label,
358- &details,
359- &a11y);
360+ indicator_power_device_get_header (p->primary_device,
361+ g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S),
362+ g_settings_get_boolean (p->settings, SETTINGS_SHOW_PERCENTAGE_S),
363+ &label,
364+ &a11y);
365
366 icon = indicator_power_device_get_gicon (p->primary_device);
367-
368- g_free (details);
369 }
370
371 g_variant_builder_init (&b, G_VARIANT_TYPE("a{sv}"));
372@@ -337,9 +336,7 @@
373
374 if (label != NULL)
375 {
376- if (g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S))
377- g_variant_builder_add (&b, "{sv}", "label",
378- g_variant_new_string (label));
379+ g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (label));
380
381 g_free (label);
382 }
383@@ -376,33 +373,24 @@
384
385 if (kind != UP_DEVICE_KIND_LINE_POWER)
386 {
387- char * brief;
388+ GIcon * icon;
389 char * label;
390- char * a11y;
391 GMenuItem * menu_item;
392- GIcon * icon = indicator_power_device_get_gicon (device);
393-
394- indicator_power_device_get_time_details (device,
395- &brief,
396- &label,
397- &a11y);
398-
399+
400+ icon = indicator_power_device_get_gicon (device);
401+ label = indicator_power_device_get_label (device);
402 menu_item = g_menu_item_new (label, "indicator.activate-statistics");
403
404 if (icon != NULL)
405- {
406- g_menu_item_set_attribute_value (menu_item,
407- G_MENU_ATTRIBUTE_ICON,
408- g_icon_serialize (icon));
409- }
410+ g_menu_item_set_attribute_value (menu_item,
411+ G_MENU_ATTRIBUTE_ICON,
412+ g_icon_serialize (icon));
413
414 g_menu_append_item (menu, menu_item);
415 g_object_unref (menu_item);
416
417 g_clear_object (&icon);
418- g_free (brief);
419 g_free (label);
420- g_free (a11y);
421 }
422 }
423
424@@ -521,6 +509,10 @@
425 "indicator.show-time");
426
427 g_menu_append (menu,
428+ _("Show Percentage in Menu Bar"),
429+ "indicator.show-percentage");
430+
431+ g_menu_append (menu,
432 _("Power Settings…"),
433 "indicator.activate-settings");
434
435@@ -706,49 +698,15 @@
436 execute_command ("gnome-power-statistics");
437 }
438
439-/* FIXME: use a GBinding to tie the gaction's state and the GSetting together? */
440-
441-static void
442-set_show_time_flag (IndicatorPowerService * self, gboolean b)
443-{
444- GVariant * v;
445- priv_t * p = self->priv;
446-
447- /* update the settings */
448- if (b != g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S))
449- g_settings_set_boolean (p->settings, SETTINGS_SHOW_TIME_S, b);
450-
451- /* update the action state */
452- v = g_action_get_state (G_ACTION(p->show_time_action));
453- if (b != g_variant_get_boolean (v))
454- g_simple_action_set_state (p->show_time_action, g_variant_new_boolean (b));
455- g_variant_unref (v);
456-
457- rebuild_header_now (self);
458-}
459-static void
460-on_show_time_setting_changed (GSettings * settings, gchar * key, gpointer gself)
461-{
462- set_show_time_flag (INDICATOR_POWER_SERVICE(gself),
463- g_settings_get_boolean (settings, key));
464-}
465-
466-static void
467-on_show_time_action_state_changed (GAction * action,
468- GParamSpec * pspec G_GNUC_UNUSED,
469- gpointer gself)
470-{
471- GVariant * v = g_action_get_state (action);
472- set_show_time_flag (INDICATOR_POWER_SERVICE(gself),
473- g_variant_get_boolean (v));
474- g_variant_unref (v);
475-}
476+/***
477+****
478+***/
479
480 /* toggles the state */
481 static void
482-on_show_time_action_activated (GSimpleAction * simple,
483- GVariant * parameter G_GNUC_UNUSED,
484- gpointer unused G_GNUC_UNUSED)
485+on_toggle_action_activated (GSimpleAction * simple,
486+ GVariant * parameter G_GNUC_UNUSED,
487+ gpointer unused G_GNUC_UNUSED)
488 {
489 GVariant * v = g_action_get_state (G_ACTION (simple));
490 gboolean flag = g_variant_get_boolean (v);
491@@ -756,11 +714,27 @@
492 g_variant_unref (v);
493 }
494
495+static gboolean
496+settings_to_action_state (GValue * value,
497+ GVariant * variant,
498+ gpointer user_data G_GNUC_UNUSED)
499+{
500+ g_value_set_variant (value, variant);
501+ return TRUE;
502+}
503+
504+static GVariant *
505+action_state_to_settings (const GValue * value,
506+ const GVariantType * expected_type G_GNUC_UNUSED,
507+ gpointer user_data G_GNUC_UNUSED)
508+{
509+ return g_value_dup_variant (value);
510+}
511+
512 static void
513 init_gactions (IndicatorPowerService * self)
514 {
515 GSimpleAction * a;
516- gboolean show_time;
517 priv_t * p = self->priv;
518
519 GActionEntry entries[] = {
520@@ -777,33 +751,47 @@
521
522 /* add the header action */
523 a = g_simple_action_new_stateful ("_header", NULL, create_header_state (self));
524- g_simple_action_group_insert (p->actions, G_ACTION(a));
525+ g_action_map_add_action (G_ACTION_MAP(p->actions), G_ACTION(a));
526 p->header_action = a;
527
528 /* add the power-level action */
529 a = g_simple_action_new_stateful ("battery-level", NULL, g_variant_new_uint32(0));
530 g_simple_action_set_enabled (a, FALSE);
531- g_simple_action_group_insert (p->actions, G_ACTION(a));
532+ g_action_map_add_action (G_ACTION_MAP(p->actions), G_ACTION(a));
533 p->battery_level_action = a;
534
535 /* add the brightness action */
536 a = g_simple_action_new_stateful ("brightness", NULL, action_state_for_brightness (self));
537- g_simple_action_group_insert (p->actions, G_ACTION(a));
538+ g_action_map_add_action (G_ACTION_MAP(p->actions), G_ACTION(a));
539 g_signal_connect (a, "change-state", G_CALLBACK(on_brightness_change_requested), self);
540 p->brightness_action = a;
541
542 /* add the show-time action */
543- show_time = g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S);
544- a = g_simple_action_new_stateful ("show-time",
545- NULL,
546- g_variant_new_boolean(show_time));
547- g_signal_connect (a, "activate",
548- G_CALLBACK(on_show_time_action_activated), self);
549- g_signal_connect (a, "notify",
550- G_CALLBACK(on_show_time_action_state_changed), self);
551- g_simple_action_group_insert (p->actions, G_ACTION(a));
552+ a = g_simple_action_new ("show-time", NULL);
553+ g_settings_bind_with_mapping (p->settings, SETTINGS_SHOW_TIME_S,
554+ a, "state",
555+ G_SETTINGS_BIND_DEFAULT,
556+ settings_to_action_state,
557+ action_state_to_settings,
558+ NULL, NULL);
559+ g_signal_connect (a, "activate", G_CALLBACK(on_toggle_action_activated), self);
560+ g_signal_connect_swapped (a, "notify", G_CALLBACK(rebuild_header_now), self);
561+ g_action_map_add_action (G_ACTION_MAP(p->actions), G_ACTION(a));
562 p->show_time_action = a;
563
564+ /* add the show-percentage action */
565+ a = g_simple_action_new ("show-percentage", NULL);
566+ g_settings_bind_with_mapping (p->settings, SETTINGS_SHOW_PERCENTAGE_S,
567+ a, "state",
568+ G_SETTINGS_BIND_DEFAULT,
569+ settings_to_action_state,
570+ action_state_to_settings,
571+ NULL, NULL);
572+ g_signal_connect (a, "activate", G_CALLBACK(on_toggle_action_activated), self);
573+ g_signal_connect_swapped (a, "notify", G_CALLBACK(rebuild_header_now), self);
574+ g_action_map_add_action (G_ACTION_MAP(p->actions), G_ACTION(a));
575+ p->show_percentage_action = a;
576+
577 rebuild_header_now (self);
578 }
579
580@@ -949,7 +937,7 @@
581 {
582 IndicatorPowerService * self = INDICATOR_POWER_SERVICE (o);
583 priv_t * p = self->priv;
584-
585+
586 switch (property_id)
587 {
588 case PROP_DEVICE_PROVIDER:
589@@ -1014,10 +1002,16 @@
590 g_clear_object (&p->show_time_action);
591 }
592
593+ if (p->show_percentage_action != NULL)
594+ {
595+ g_signal_handlers_disconnect_by_data (p->show_percentage_action, self);
596+
597+ g_clear_object (&p->show_percentage_action);
598+ }
599+
600 g_clear_object (&p->brightness_action);
601 g_clear_object (&p->battery_level_action);
602 g_clear_object (&p->header_action);
603- g_clear_object (&p->show_time_action);
604 g_clear_object (&p->actions);
605
606 g_clear_object (&p->conn);
607@@ -1051,8 +1045,6 @@
608
609 g_signal_connect_swapped (p->settings, "changed::" SETTINGS_ICON_POLICY_S,
610 G_CALLBACK(rebuild_header_now), self);
611- g_signal_connect (p->settings, "changed::" SETTINGS_SHOW_TIME_S,
612- G_CALLBACK(on_show_time_setting_changed), self);
613
614 p->own_id = g_bus_own_name (G_BUS_TYPE_SESSION,
615 BUS_NAME,
616
617=== modified file 'tests/test-dbus-listener.cc'
618--- tests/test-dbus-listener.cc 2013-01-17 21:07:08 +0000
619+++ tests/test-dbus-listener.cc 2013-08-23 14:01:50 +0000
620@@ -4,16 +4,16 @@
621 Authors:
622 Charles Kerr <charles.kerr@canonical.com>
623
624-This program is free software: you can redistribute it and/or modify it
625-under the terms of the GNU General Public License version 3, as published
626+This program is free software: you can redistribute it and/or modify it
627+under the terms of the GNU General Public License version 3, as published
628 by the Free Software Foundation.
629
630-This program is distributed in the hope that it will be useful, but
631-WITHOUT ANY WARRANTY; without even the implied warranties of
632-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
633+This program is distributed in the hope that it will be useful, but
634+WITHOUT ANY WARRANTY; without even the implied warranties of
635+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
636 PURPOSE. See the GNU General Public License for more details.
637
638-You should have received a copy of the GNU General Public License along
639+You should have received a copy of the GNU General Public License along
640 with this program. If not, see <http://www.gnu.org/licenses/>.
641 */
642
643@@ -40,7 +40,7 @@
644 int gsd_name_ownership_id;
645 int gsd_power_registration_id;
646 char * gsd_power_error_string;
647-
648+
649 protected:
650
651 static void
652@@ -234,7 +234,7 @@
653
654 // cleanup
655 g_object_run_dispose (o); // used to get coverage of both branches in the object's dispose func's g_clear_*() calls
656- g_object_unref (o);
657+ g_object_unref (o);
658 }
659
660 TEST_F(DbusListenerTest, GSDHasNoDevices)
661@@ -261,7 +261,7 @@
662
663 // cleanup
664 g_object_run_dispose (o); // used to get coverage of both branches in the object's dispose func's g_clear_*() calls
665- g_object_unref (o);
666+ g_object_unref (o);
667 }
668
669 TEST_F(DbusListenerTest, GSDReturnsError)
670@@ -285,7 +285,7 @@
671
672 // cleanup
673 g_object_run_dispose (o); // used to get coverage of both branches in the object's dispose func's g_clear_*() calls
674- g_object_unref (o);
675+ g_object_unref (o);
676 }
677
678 /* This test emits a PropertiesChanged signal and confirms that
679@@ -347,5 +347,5 @@
680 ASSERT_EQ (g_slist_length(devices), 2);
681
682 // cleanup
683- g_object_unref (o);
684+ g_object_unref (o);
685 }
686
687=== modified file 'tests/test-device.cc'
688--- tests/test-device.cc 2013-06-17 23:01:51 +0000
689+++ tests/test-device.cc 2013-08-23 14:01:50 +0000
690@@ -4,16 +4,16 @@
691 Authors:
692 Charles Kerr <charles.kerr@canonical.com>
693
694-This program is free software: you can redistribute it and/or modify it
695-under the terms of the GNU General Public License version 3, as published
696+This program is free software: you can redistribute it and/or modify it
697+under the terms of the GNU General Public License version 3, as published
698 by the Free Software Foundation.
699
700-This program is distributed in the hope that it will be useful, but
701-WITHOUT ANY WARRANTY; without even the implied warranties of
702-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
703+This program is distributed in the hope that it will be useful, but
704+WITHOUT ANY WARRANTY; without even the implied warranties of
705+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
706 PURPOSE. See the GNU General Public License for more details.
707
708-You should have received a copy of the GNU General Public License along
709+You should have received a copy of the GNU General Public License along
710 with this program. If not, see <http://www.gnu.org/licenses/>.
711 */
712
713@@ -69,27 +69,52 @@
714 g_strfreev (names);
715 }
716
717- void check_strings (const IndicatorPowerDevice * device,
718- const char * expected_timestring,
719- const char * expected_details,
720- const char * expected_accessible)
721- {
722- char * timestring = NULL;
723- char * details = NULL;
724- char * accessible = NULL;
725-
726- indicator_power_device_get_time_details (device, &timestring, &details, &accessible);
727- EXPECT_STREQ (expected_timestring, timestring);
728- EXPECT_STREQ (expected_details, details);
729- EXPECT_STREQ (expected_accessible, accessible);
730-
731- g_free (accessible);
732- g_free (details);
733- g_free (timestring);
734+ void check_label (const IndicatorPowerDevice * device,
735+ const char * expected_label)
736+ {
737+ char * label;
738+
739+ label = indicator_power_device_get_label (device);
740+ EXPECT_STREQ (expected_label, label);
741+
742+ g_free (label);
743+ }
744+
745+ void check_header (const IndicatorPowerDevice * device,
746+ const char * expected_time_and_percent,
747+ const char * expected_time,
748+ const char * expected_percent,
749+ const char * expected_a11y)
750+ {
751+ char * label;
752+ char * a11y;
753+
754+ indicator_power_device_get_header (device, true, true, &label, &a11y);
755+ EXPECT_STREQ (expected_time_and_percent, label);
756+ EXPECT_STREQ (expected_a11y, a11y);
757+ g_free (label);
758+ g_free (a11y);
759+
760+ indicator_power_device_get_header (device, true, false, &label, &a11y);
761+ EXPECT_STREQ (expected_time, label);
762+ EXPECT_STREQ (expected_a11y, a11y);
763+ g_free (label);
764+ g_free (a11y);
765+
766+ indicator_power_device_get_header (device, false, true, &label, &a11y);
767+ EXPECT_STREQ (expected_percent, label);
768+ EXPECT_STREQ (expected_a11y, a11y);
769+ g_free (label);
770+ g_free (a11y);
771+
772+ indicator_power_device_get_header (device, false, false, &label, &a11y);
773+ ASSERT_TRUE (!label || !*label);
774+ EXPECT_STREQ (expected_a11y, a11y);
775+ g_free (label);
776+ g_free (a11y);
777 }
778 };
779
780-
781 /***
782 ****
783 ***/
784@@ -266,7 +291,7 @@
785 g_object_set (o, INDICATOR_POWER_DEVICE_KIND, kind,
786 INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_EMPTY,
787 NULL);
788-
789+
790 g_string_append_printf (expected, "%s-empty-symbolic;", kind_str);
791 g_string_append_printf (expected, "gpm-%s-empty;", kind_str);
792 g_string_append_printf (expected, "gpm-%s-000;", kind_str);
793@@ -434,7 +459,7 @@
794
795 // state unknown
796 g_object_set (o, INDICATOR_POWER_DEVICE_KIND, kind,
797- INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_UNKNOWN,
798+ INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_UNKNOWN,
799 NULL);
800 g_string_append_printf (expected, "%s-missing-symbolic;", kind_str);
801 g_string_append_printf (expected, "gpm-%s-missing;", kind_str);
802@@ -456,19 +481,21 @@
803 g_setenv ("LANG", "en_US.UTF-8", TRUE);
804
805 // bad args: NULL device
806- log_count_ipower_expected++;
807- check_strings (NULL, NULL, NULL, NULL);
808+ log_count_ipower_expected += 5;
809+ check_label (NULL, NULL);
810+ check_header (NULL, NULL, NULL, NULL, NULL);
811
812 // bad args: a GObject that isn't a device
813- log_count_ipower_expected++;
814+ log_count_ipower_expected += 5;
815 GObject * o = G_OBJECT(g_cancellable_new());
816- check_strings ((IndicatorPowerDevice*)o, NULL, NULL, NULL);
817+ check_label ((IndicatorPowerDevice*)o, NULL);
818+ check_header (NULL, NULL, NULL, NULL, NULL);
819 g_object_unref (o);
820
821 /**
822 ***
823 **/
824-
825+
826 IndicatorPowerDevice * device = INDICATOR_POWER_DEVICE (g_object_new (INDICATOR_POWER_DEVICE_TYPE, NULL));
827 o = G_OBJECT(device);
828
829@@ -478,9 +505,11 @@
830 INDICATOR_POWER_DEVICE_PERCENTAGE, 50.0,
831 INDICATOR_POWER_DEVICE_TIME, guint64(60*61),
832 NULL);
833- check_strings (device, "(1:01)",
834- "Battery (1:01 to charge)",
835- "Battery (1 hour 1 minute to charge (50%))");
836+ check_label (device, "Battery (1:01 to charge)");
837+ check_header (device, "(1:01, 50%)",
838+ "(1:01)",
839+ "(50%)",
840+ "Battery (1 hour 1 minute to charge, 50%)");
841
842 // discharging, < 12 hours left
843 g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_BATTERY,
844@@ -488,25 +517,36 @@
845 INDICATOR_POWER_DEVICE_PERCENTAGE, 50.0,
846 INDICATOR_POWER_DEVICE_TIME, guint64(60*61),
847 NULL);
848- check_strings (device, "1:01",
849- "Battery (1:01 left)",
850- "Battery (1 hour 1 minute left (50%))");
851+ check_label (device, "Battery (1:01 left)");
852+ check_header (device, "(1:01, 50%)",
853+ "(1:01)",
854+ "(50%)",
855+ "Battery (1 hour 1 minute left, 50%)");
856
857 // discharging, > 12 hours left
858+ // we don't show the clock time when > 12 hours dischargin
859 g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_BATTERY,
860 INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_DISCHARGING,
861 INDICATOR_POWER_DEVICE_PERCENTAGE, 50.0,
862 INDICATOR_POWER_DEVICE_TIME, guint64(60*60*13),
863 NULL);
864- check_strings (device, "13:00", "Battery", "Battery");
865+ check_label (device, "Battery");
866+ check_header (device, "(50%)",
867+ "",
868+ "(50%)",
869+ "Battery (50%)");
870
871- // fully charged
872+// fully charged
873 g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_BATTERY,
874 INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_FULLY_CHARGED,
875 INDICATOR_POWER_DEVICE_PERCENTAGE, 100.0,
876 INDICATOR_POWER_DEVICE_TIME, guint64(0),
877 NULL);
878- check_strings (device, "", "Battery (charged)", "Battery (charged)");
879+ check_label (device, "Battery (charged)");
880+ check_header (device, "(100%)",
881+ "",
882+ "(100%)",
883+ "Battery (charged, 100%)");
884
885 // percentage but no time estimate
886 g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_BATTERY,
887@@ -514,7 +554,11 @@
888 INDICATOR_POWER_DEVICE_PERCENTAGE, 50.0,
889 INDICATOR_POWER_DEVICE_TIME, guint64(0),
890 NULL);
891- check_strings (device, "(50%)", "Battery (50%)", "Battery (50%)");
892+ check_label (device, "Battery (estimating…)");
893+ check_header (device, "(estimating…, 50%)",
894+ "(estimating…)",
895+ "(50%)",
896+ "Battery (estimating…, 50%)");
897
898 // no percentage, no time estimate
899 g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_BATTERY,
900@@ -522,7 +566,8 @@
901 INDICATOR_POWER_DEVICE_PERCENTAGE, 0.0,
902 INDICATOR_POWER_DEVICE_TIME, guint64(0),
903 NULL);
904- check_strings (device, "(not present)", "Battery (not present)", "Battery (not present)");
905+ check_label (device, "Battery (not present)");
906+ check_header (device, "", "", "", "Battery (not present)");
907
908 // power line
909 g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_LINE_POWER,
910@@ -530,7 +575,8 @@
911 INDICATOR_POWER_DEVICE_PERCENTAGE, 0.0,
912 INDICATOR_POWER_DEVICE_TIME, guint64(0),
913 NULL);
914- check_strings (device, "", "AC Adapter", "AC Adapter");
915+ check_label (device, "AC Adapter");
916+ check_header (device, "", "", "", "AC Adapter");
917
918 // cleanup
919 g_object_unref(o);
920@@ -605,7 +651,7 @@
921 ASSERT_EQ (a, indicator_power_service_choose_primary_device(device_list));
922 }
923 }
924-
925+
926 // cleanup
927 g_list_free_full (device_list, g_object_unref);
928 }
929
930=== modified file 'tests/test-service.cc'
931--- tests/test-service.cc 2013-06-17 23:01:51 +0000
932+++ tests/test-service.cc 2013-08-23 14:01:50 +0000
933@@ -65,7 +65,7 @@
934 virtual void SetUp()
935 {
936 ensure_glib_initialized ();
937-
938+
939 g_setenv( "GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, TRUE);
940
941 ac_device = indicator_power_device_new (
942@@ -90,7 +90,7 @@
943 const char* GetAccessibleDesc (IndicatorPower * power) const
944 {
945 GList * entries = indicator_object_get_entries (INDICATOR_OBJECT(power));
946- g_assert (g_list_length(entries) == 1);
947+ g_assert (g_list_length(entries) == 1);
948 IndicatorObjectEntry * entry = static_cast<IndicatorObjectEntry*>(entries->data);
949 const char * ret = entry->accessible_desc;
950 g_list_free (entries);
951@@ -120,7 +120,7 @@
952 devices = g_slist_append (devices, ac_device);
953 devices = g_slist_append (devices, battery_device);
954 indicator_power_set_devices (power, devices);
955- g_slist_free (devices);
956+ g_slist_free (devices);
957
958 g_object_unref (power);
959 }

Subscribers

People subscribed via source and target branches