Merge lp:~dedunumax/ubuntu/raring/gnome-power-manager/bug-923292 into lp:ubuntu/raring/gnome-power-manager

Proposed by U.W.D.Dhananjaya
Status: Merged
Merged at revision: 212
Proposed branch: lp:~dedunumax/ubuntu/raring/gnome-power-manager/bug-923292
Merge into: lp:ubuntu/raring/gnome-power-manager
Diff against target: 2329 lines (+2280/-0)
6 files modified
.pc/923292-fix.patch/src/gpm-statistics.c (+2176/-0)
.pc/applied-patches (+1/-0)
debian/changelog (+6/-0)
debian/patches/923292-fix.patch (+57/-0)
debian/patches/series (+1/-0)
src/gpm-statistics.c (+39/-0)
To merge this branch: bzr merge lp:~dedunumax/ubuntu/raring/gnome-power-manager/bug-923292
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+148190@code.launchpad.net

Description of the change

 * Added window_key_press_event to window and added Ctrl+q to make it exit

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory '.pc/923292-fix.patch'
2=== added file '.pc/923292-fix.patch/.timestamp'
3=== added directory '.pc/923292-fix.patch/src'
4=== added file '.pc/923292-fix.patch/src/gpm-statistics.c'
5--- .pc/923292-fix.patch/src/gpm-statistics.c 1970-01-01 00:00:00 +0000
6+++ .pc/923292-fix.patch/src/gpm-statistics.c 2013-02-13 13:56:48 +0000
7@@ -0,0 +1,2176 @@
8+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
9+ *
10+ * Copyright (C) 2008-2011 Richard Hughes <richard@hughsie.com>
11+ *
12+ * Licensed under the GNU General Public License Version 2
13+ *
14+ * This program is free software; you can redistribute it and/or modify
15+ * it under the terms of the GNU General Public License as published by
16+ * the Free Software Foundation; either version 2 of the License, or
17+ * (at your option) any later version.
18+ *
19+ * This program is distributed in the hope that it will be useful,
20+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+ * GNU General Public License for more details.
23+ *
24+ * You should have received a copy of the GNU General Public License
25+ * along with this program; if not, write to the Free Software
26+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27+ */
28+
29+#include "config.h"
30+
31+#include <locale.h>
32+#include <glib.h>
33+#include <glib/gi18n.h>
34+#include <gtk/gtk.h>
35+#include <libupower-glib/upower.h>
36+
37+#include "gpm-array-float.h"
38+#include "gpm-graph-widget.h"
39+
40+#define GPM_SETTINGS_SCHEMA "org.gnome.power-manager"
41+#define GPM_SETTINGS_INFO_HISTORY_TIME "info-history-time"
42+#define GPM_SETTINGS_INFO_HISTORY_TYPE "info-history-type"
43+#define GPM_SETTINGS_INFO_HISTORY_GRAPH_SMOOTH "info-history-graph-smooth"
44+#define GPM_SETTINGS_INFO_HISTORY_GRAPH_POINTS "info-history-graph-points"
45+#define GPM_SETTINGS_INFO_STATS_TYPE "info-stats-type"
46+#define GPM_SETTINGS_INFO_STATS_GRAPH_SMOOTH "info-stats-graph-smooth"
47+#define GPM_SETTINGS_INFO_STATS_GRAPH_POINTS "info-stats-graph-points"
48+#define GPM_SETTINGS_INFO_PAGE_NUMBER "info-page-number"
49+#define GPM_SETTINGS_INFO_LAST_DEVICE "info-last-device"
50+
51+static GtkBuilder *builder = NULL;
52+static GtkListStore *list_store_info = NULL;
53+static GtkListStore *list_store_devices = NULL;
54+static GtkListStore *list_store_wakeups = NULL;
55+gchar *current_device = NULL;
56+static const gchar *history_type;
57+static const gchar *stats_type;
58+static guint history_time;
59+static GSettings *settings;
60+static gfloat sigma_smoothing = 0.0f;
61+static UpWakeups *wakeups = NULL;
62+static GtkWidget *graph_history = NULL;
63+static GtkWidget *graph_statistics = NULL;
64+
65+enum {
66+ GPM_INFO_COLUMN_TEXT,
67+ GPM_INFO_COLUMN_VALUE,
68+ GPM_INFO_COLUMN_LAST
69+};
70+
71+enum {
72+ GPM_DEVICES_COLUMN_ICON,
73+ GPM_DEVICES_COLUMN_TEXT,
74+ GPM_DEVICES_COLUMN_ID,
75+ GPM_DEVICES_COLUMN_LAST
76+};
77+
78+enum {
79+ GPM_WAKEUPS_COLUMN_ICON,
80+ GPM_WAKEUPS_COLUMN_ID,
81+ GPM_WAKEUPS_COLUMN_VALUE,
82+ GPM_WAKEUPS_COLUMN_CMDLINE,
83+ GPM_WAKEUPS_COLUMN_DETAILS,
84+ GPM_WAKEUPS_COLUMN_LAST
85+};
86+
87+#define GPM_HISTORY_RATE_TEXT _("Rate")
88+#define GPM_HISTORY_CHARGE_TEXT _("Charge")
89+#define GPM_HISTORY_TIME_FULL_TEXT _("Time to full")
90+#define GPM_HISTORY_TIME_EMPTY_TEXT _("Time to empty")
91+
92+#define GPM_HISTORY_RATE_VALUE "rate"
93+#define GPM_HISTORY_CHARGE_VALUE "charge"
94+#define GPM_HISTORY_TIME_FULL_VALUE "time-full"
95+#define GPM_HISTORY_TIME_EMPTY_VALUE "time-empty"
96+
97+#define GPM_HISTORY_MINUTE_TEXT _("10 minutes")
98+#define GPM_HISTORY_HOUR_TEXT _("2 hours")
99+#define GPM_HISTORY_HOURS_TEXT _("6 hours")
100+#define GPM_HISTORY_DAY_TEXT _("1 day")
101+#define GPM_HISTORY_WEEK_TEXT _("1 week")
102+
103+#define GPM_HISTORY_MINUTE_VALUE 10*60
104+#define GPM_HISTORY_HOUR_VALUE 2*60*60
105+#define GPM_HISTORY_HOURS_VALUE 6*60*60
106+#define GPM_HISTORY_DAY_VALUE 24*60*60
107+#define GPM_HISTORY_WEEK_VALUE 7*24*60*60
108+
109+/* TRANSLATORS: what we've observed about the device */
110+#define GPM_STATS_CHARGE_DATA_TEXT _("Charge profile")
111+#define GPM_STATS_DISCHARGE_DATA_TEXT _("Discharge profile")
112+/* TRANSLATORS: how accurately we can predict the time remaining of the battery */
113+#define GPM_STATS_CHARGE_ACCURACY_TEXT _("Charge accuracy")
114+#define GPM_STATS_DISCHARGE_ACCURACY_TEXT _("Discharge accuracy")
115+
116+#define GPM_STATS_CHARGE_DATA_VALUE "charge-data"
117+#define GPM_STATS_CHARGE_ACCURACY_VALUE "charge-accuracy"
118+#define GPM_STATS_DISCHARGE_DATA_VALUE "discharge-data"
119+#define GPM_STATS_DISCHARGE_ACCURACY_VALUE "discharge-accuracy"
120+
121+#define GPM_UP_TIME_PRECISION 5*60 /* seconds */
122+#define GPM_UP_TEXT_MIN_TIME 120 /* seconds */
123+
124+/**
125+ * gpm_stats_get_device_icon_index:
126+ * @device: The UpDevice
127+ *
128+ * Return value: The character string for the filename suffix.
129+ **/
130+static const gchar *
131+gpm_stats_get_device_icon_index (UpDevice *device)
132+{
133+ gdouble percentage;
134+ /* get device properties */
135+ g_object_get (device, "percentage", &percentage, NULL);
136+ if (percentage < 10)
137+ return "000";
138+ else if (percentage < 30)
139+ return "020";
140+ else if (percentage < 50)
141+ return "040";
142+ else if (percentage < 70)
143+ return "060";
144+ else if (percentage < 90)
145+ return "080";
146+ return "100";
147+}
148+
149+/**
150+ * gpm_stats_get_device_icon_suffix:
151+ * @device: The UpDevice
152+ *
153+ * Return value: The character string for the filename suffix.
154+ **/
155+static const gchar *
156+gpm_stats_get_device_icon_suffix (UpDevice *device)
157+{
158+ gdouble percentage;
159+ /* get device properties */
160+ g_object_get (device, "percentage", &percentage, NULL);
161+ if (percentage < 10)
162+ return "caution";
163+ else if (percentage < 30)
164+ return "low";
165+ else if (percentage < 60)
166+ return "good";
167+ return "full";
168+}
169+
170+/**
171+ * gpm_stats_get_device_icon:
172+ *
173+ * Return value: The device icon, use g_object_unref() when done.
174+ **/
175+static GIcon *
176+gpm_stats_get_device_icon (UpDevice *device, gboolean use_symbolic)
177+{
178+ GString *filename;
179+ gchar **iconnames;
180+ const gchar *kind_str;
181+ const gchar *suffix_str;
182+ const gchar *index_str;
183+ UpDeviceKind kind;
184+ UpDeviceState state;
185+ gboolean is_present;
186+ gdouble percentage;
187+ GIcon *icon = NULL;
188+
189+ g_return_val_if_fail (device != NULL, NULL);
190+
191+ /* get device properties */
192+ g_object_get (device,
193+ "kind", &kind,
194+ "state", &state,
195+ "percentage", &percentage,
196+ "is-present", &is_present,
197+ NULL);
198+
199+ /* get correct icon prefix */
200+ filename = g_string_new (NULL);
201+
202+ /* get the icon from some simple rules */
203+ if (kind == UP_DEVICE_KIND_LINE_POWER) {
204+ if (use_symbolic)
205+ g_string_append (filename, "ac-adapter-symbolic;");
206+ g_string_append (filename, "ac-adapter;");
207+
208+ } else if (kind == UP_DEVICE_KIND_MONITOR) {
209+ if (use_symbolic)
210+ g_string_append (filename, "gpm-monitor-symbolic;");
211+ g_string_append (filename, "gpm-monitor;");
212+
213+ } else {
214+
215+ kind_str = up_device_kind_to_string (kind);
216+ if (!is_present) {
217+ if (use_symbolic)
218+ g_string_append (filename, "battery-missing-symbolic;");
219+ g_string_append_printf (filename, "gpm-%s-missing;", kind_str);
220+ g_string_append_printf (filename, "gpm-%s-000;", kind_str);
221+ g_string_append (filename, "battery-missing;");
222+
223+ } else {
224+ switch (state) {
225+ case UP_DEVICE_STATE_EMPTY:
226+ if (use_symbolic)
227+ g_string_append (filename, "battery-empty-symbolic;");
228+ g_string_append_printf (filename, "gpm-%s-empty;", kind_str);
229+ g_string_append_printf (filename, "gpm-%s-000;", kind_str);
230+ g_string_append (filename, "battery-empty;");
231+ break;
232+ case UP_DEVICE_STATE_FULLY_CHARGED:
233+ if (use_symbolic) {
234+ g_string_append (filename, "battery-full-charged-symbolic;");
235+ g_string_append (filename, "battery-full-charging-symbolic;");
236+ }
237+ g_string_append_printf (filename, "gpm-%s-full;", kind_str);
238+ g_string_append_printf (filename, "gpm-%s-100;", kind_str);
239+ g_string_append (filename, "battery-full-charged;");
240+ g_string_append (filename, "battery-full-charging;");
241+ break;
242+ case UP_DEVICE_STATE_CHARGING:
243+ case UP_DEVICE_STATE_PENDING_CHARGE:
244+ suffix_str = gpm_stats_get_device_icon_suffix (device);
245+ index_str = gpm_stats_get_device_icon_index (device);
246+ if (use_symbolic)
247+ g_string_append_printf (filename, "battery-%s-charging-symbolic;", suffix_str);
248+ g_string_append_printf (filename, "gpm-%s-%s-charging;", kind_str, index_str);
249+ g_string_append_printf (filename, "battery-%s-charging;", suffix_str);
250+ break;
251+ case UP_DEVICE_STATE_DISCHARGING:
252+ case UP_DEVICE_STATE_PENDING_DISCHARGE:
253+ suffix_str = gpm_stats_get_device_icon_suffix (device);
254+ index_str = gpm_stats_get_device_icon_index (device);
255+ if (use_symbolic)
256+ g_string_append_printf (filename, "battery-%s-symbolic;", suffix_str);
257+ g_string_append_printf (filename, "gpm-%s-%s;", kind_str, index_str);
258+ g_string_append_printf (filename, "battery-%s;", suffix_str);
259+ break;
260+ default:
261+ if (use_symbolic)
262+ g_string_append (filename, "battery-missing-symbolic;");
263+ g_string_append (filename, "gpm-battery-missing;");
264+ g_string_append (filename, "battery-missing;");
265+ }
266+ }
267+ }
268+
269+ /* nothing matched */
270+ if (filename->len == 0) {
271+ g_warning ("nothing matched, falling back to default icon");
272+ g_string_append (filename, "dialog-warning;");
273+ }
274+
275+ g_debug ("got filename: %s", filename->str);
276+
277+ iconnames = g_strsplit (filename->str, ";", -1);
278+ icon = g_themed_icon_new_from_names (iconnames, -1);
279+
280+ g_strfreev (iconnames);
281+ g_string_free (filename, TRUE);
282+ return icon;
283+}
284+
285+/**
286+ * gpm_device_kind_to_localised_string:
287+ **/
288+static const gchar *
289+gpm_device_kind_to_localised_string (UpDeviceKind kind, guint number)
290+{
291+ const gchar *text = NULL;
292+ switch (kind) {
293+ case UP_DEVICE_KIND_LINE_POWER:
294+ /* TRANSLATORS: system power cord */
295+ text = ngettext ("AC adapter", "AC adapters", number);
296+ break;
297+ case UP_DEVICE_KIND_BATTERY:
298+ /* TRANSLATORS: laptop primary battery */
299+ text = ngettext ("Laptop battery", "Laptop batteries", number);
300+ break;
301+ case UP_DEVICE_KIND_UPS:
302+ /* TRANSLATORS: battery-backed AC power source */
303+ text = ngettext ("UPS", "UPSs", number);
304+ break;
305+ case UP_DEVICE_KIND_MONITOR:
306+ /* TRANSLATORS: a monitor is a device to measure voltage and current */
307+ text = ngettext ("Monitor", "Monitors", number);
308+ break;
309+ case UP_DEVICE_KIND_MOUSE:
310+ /* TRANSLATORS: wireless mice with internal batteries */
311+ text = ngettext ("Mouse", "Mice", number);
312+ break;
313+ case UP_DEVICE_KIND_KEYBOARD:
314+ /* TRANSLATORS: wireless keyboard with internal battery */
315+ text = ngettext ("Keyboard", "Keyboards", number);
316+ break;
317+ case UP_DEVICE_KIND_PDA:
318+ /* TRANSLATORS: portable device */
319+ text = ngettext ("PDA", "PDAs", number);
320+ break;
321+ case UP_DEVICE_KIND_PHONE:
322+ /* TRANSLATORS: cell phone (mobile...) */
323+ text = ngettext ("Cell phone", "Cell phones", number);
324+ break;
325+#if UP_CHECK_VERSION(0,9,5)
326+ case UP_DEVICE_KIND_MEDIA_PLAYER:
327+ /* TRANSLATORS: media player, mp3 etc */
328+ text = ngettext ("Media player", "Media players", number);
329+ break;
330+ case UP_DEVICE_KIND_TABLET:
331+ /* TRANSLATORS: tablet device */
332+ text = ngettext ("Tablet", "Tablets", number);
333+ break;
334+ case UP_DEVICE_KIND_COMPUTER:
335+ /* TRANSLATORS: tablet device */
336+ text = ngettext ("Computer", "Computers", number);
337+ break;
338+#endif
339+ default:
340+ g_warning ("enum unrecognised: %i", kind);
341+ text = up_device_kind_to_string (kind);
342+ }
343+ return text;
344+}
345+
346+/**
347+ * gpm_device_technology_to_localised_string:
348+ **/
349+static const gchar *
350+gpm_device_technology_to_localised_string (UpDeviceTechnology technology_enum)
351+{
352+ const gchar *technology = NULL;
353+ switch (technology_enum) {
354+ case UP_DEVICE_TECHNOLOGY_LITHIUM_ION:
355+ /* TRANSLATORS: battery technology */
356+ technology = _("Lithium Ion");
357+ break;
358+ case UP_DEVICE_TECHNOLOGY_LITHIUM_POLYMER:
359+ /* TRANSLATORS: battery technology */
360+ technology = _("Lithium Polymer");
361+ break;
362+ case UP_DEVICE_TECHNOLOGY_LITHIUM_IRON_PHOSPHATE:
363+ /* TRANSLATORS: battery technology */
364+ technology = _("Lithium Iron Phosphate");
365+ break;
366+ case UP_DEVICE_TECHNOLOGY_LEAD_ACID:
367+ /* TRANSLATORS: battery technology */
368+ technology = _("Lead acid");
369+ break;
370+ case UP_DEVICE_TECHNOLOGY_NICKEL_CADMIUM:
371+ /* TRANSLATORS: battery technology */
372+ technology = _("Nickel Cadmium");
373+ break;
374+ case UP_DEVICE_TECHNOLOGY_NICKEL_METAL_HYDRIDE:
375+ /* TRANSLATORS: battery technology */
376+ technology = _("Nickel metal hydride");
377+ break;
378+ case UP_DEVICE_TECHNOLOGY_UNKNOWN:
379+ /* TRANSLATORS: battery technology */
380+ technology = _("Unknown technology");
381+ break;
382+ default:
383+ g_assert_not_reached ();
384+ break;
385+ }
386+ return technology;
387+}
388+
389+/**
390+ * gpm_device_state_to_localised_string:
391+ **/
392+static const gchar *
393+gpm_device_state_to_localised_string (UpDeviceState state)
394+{
395+ const gchar *state_string = NULL;
396+
397+ switch (state) {
398+ case UP_DEVICE_STATE_CHARGING:
399+ /* TRANSLATORS: battery state */
400+ state_string = _("Charging");
401+ break;
402+ case UP_DEVICE_STATE_DISCHARGING:
403+ /* TRANSLATORS: battery state */
404+ state_string = _("Discharging");
405+ break;
406+ case UP_DEVICE_STATE_EMPTY:
407+ /* TRANSLATORS: battery state */
408+ state_string = _("Empty");
409+ break;
410+ case UP_DEVICE_STATE_FULLY_CHARGED:
411+ /* TRANSLATORS: battery state */
412+ state_string = _("Charged");
413+ break;
414+ case UP_DEVICE_STATE_PENDING_CHARGE:
415+ /* TRANSLATORS: battery state */
416+ state_string = _("Waiting to charge");
417+ break;
418+ case UP_DEVICE_STATE_PENDING_DISCHARGE:
419+ /* TRANSLATORS: battery state */
420+ state_string = _("Waiting to discharge");
421+ break;
422+ case UP_DEVICE_STATE_UNKNOWN:
423+ /* TRANSLATORS: battery state */
424+ state_string = _("Unknown");
425+ break;
426+ default:
427+ g_assert_not_reached ();
428+ break;
429+ }
430+ return state_string;
431+}
432+
433+/**
434+ * gpm_stats_add_info_columns:
435+ **/
436+static void
437+gpm_stats_add_info_columns (GtkTreeView *treeview)
438+{
439+ GtkCellRenderer *renderer;
440+ GtkTreeViewColumn *column;
441+
442+ /* image */
443+ renderer = gtk_cell_renderer_text_new ();
444+ column = gtk_tree_view_column_new_with_attributes (_("Attribute"), renderer,
445+ "markup", GPM_INFO_COLUMN_TEXT, NULL);
446+ gtk_tree_view_column_set_sort_column_id (column, GPM_INFO_COLUMN_TEXT);
447+ gtk_tree_view_append_column (treeview, column);
448+
449+ /* column for text */
450+ renderer = gtk_cell_renderer_text_new ();
451+ column = gtk_tree_view_column_new_with_attributes (_("Value"), renderer,
452+ "markup", GPM_INFO_COLUMN_VALUE, NULL);
453+ gtk_tree_view_append_column (treeview, column);
454+}
455+
456+/**
457+ * gpm_stats_add_devices_columns:
458+ **/
459+static void
460+gpm_stats_add_devices_columns (GtkTreeView *treeview)
461+{
462+ GtkCellRenderer *renderer;
463+ GtkTreeViewColumn *column;
464+
465+ /* image */
466+ renderer = gtk_cell_renderer_pixbuf_new ();
467+ g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DND, NULL);
468+ column = gtk_tree_view_column_new_with_attributes (_("Image"), renderer,
469+ "gicon", GPM_DEVICES_COLUMN_ICON, NULL);
470+ gtk_tree_view_append_column (treeview, column);
471+
472+ /* column for text */
473+ renderer = gtk_cell_renderer_text_new ();
474+ column = gtk_tree_view_column_new_with_attributes (_("Description"), renderer,
475+ "markup", GPM_DEVICES_COLUMN_TEXT, NULL);
476+ gtk_tree_view_column_set_sort_column_id (column, GPM_INFO_COLUMN_TEXT);
477+ gtk_tree_view_append_column (treeview, column);
478+ gtk_tree_view_column_set_expand (column, TRUE);
479+}
480+
481+/**
482+ * gpm_stats_add_wakeups_columns:
483+ **/
484+static void
485+gpm_stats_add_wakeups_columns (GtkTreeView *treeview)
486+{
487+ GtkCellRenderer *renderer;
488+ GtkTreeViewColumn *column;
489+
490+ /* image */
491+ renderer = gtk_cell_renderer_pixbuf_new ();
492+ g_object_set (renderer, "stock-size", GTK_ICON_SIZE_BUTTON, NULL);
493+ column = gtk_tree_view_column_new_with_attributes (_("Type"), renderer,
494+ "icon-name", GPM_WAKEUPS_COLUMN_ICON, NULL);
495+ gtk_tree_view_append_column (treeview, column);
496+
497+ /* column for id */
498+ renderer = gtk_cell_renderer_text_new ();
499+ column = gtk_tree_view_column_new_with_attributes (_("ID"), renderer,
500+ "markup", GPM_WAKEUPS_COLUMN_ID, NULL);
501+ gtk_tree_view_append_column (treeview, column);
502+ gtk_tree_view_column_set_expand (column, TRUE);
503+
504+ /* column for value */
505+ renderer = gtk_cell_renderer_text_new ();
506+ column = gtk_tree_view_column_new_with_attributes (_("Wakeups"), renderer,
507+ "markup", GPM_WAKEUPS_COLUMN_VALUE, NULL);
508+ gtk_tree_view_append_column (treeview, column);
509+ gtk_tree_view_column_set_expand (column, TRUE);
510+
511+ /* column for cmdline */
512+ renderer = gtk_cell_renderer_text_new ();
513+ column = gtk_tree_view_column_new_with_attributes (_("Command"), renderer,
514+ "markup", GPM_WAKEUPS_COLUMN_CMDLINE, NULL);
515+ gtk_tree_view_append_column (treeview, column);
516+ gtk_tree_view_column_set_expand (column, TRUE);
517+
518+ /* column for details */
519+ renderer = gtk_cell_renderer_text_new ();
520+ column = gtk_tree_view_column_new_with_attributes (_("Details"), renderer,
521+ "markup", GPM_WAKEUPS_COLUMN_DETAILS, NULL);
522+ gtk_tree_view_append_column (treeview, column);
523+ gtk_tree_view_column_set_expand (column, TRUE);
524+}
525+
526+/**
527+ * gpm_stats_add_info_data:
528+ **/
529+static void
530+gpm_stats_add_info_data (const gchar *attr, const gchar *text)
531+{
532+ GtkTreeIter iter;
533+ gtk_list_store_append (list_store_info, &iter);
534+ gtk_list_store_set (list_store_info, &iter,
535+ GPM_INFO_COLUMN_TEXT, attr,
536+ GPM_INFO_COLUMN_VALUE, text, -1);
537+}
538+
539+/**
540+ * gpm_stats_update_smooth_data:
541+ **/
542+static GPtrArray *
543+gpm_stats_update_smooth_data (GPtrArray *list)
544+{
545+ guint i;
546+ GpmPointObj *point;
547+ GpmPointObj *point_new;
548+ GPtrArray *new;
549+ GpmArrayFloat *raw;
550+ GpmArrayFloat *convolved;
551+ GpmArrayFloat *outliers;
552+ GpmArrayFloat *gaussian = NULL;
553+
554+ /* convert the y data to a GpmArrayFloat array */
555+ raw = gpm_array_float_new (list->len);
556+ for (i=0; i<list->len; i++) {
557+ point = (GpmPointObj *) g_ptr_array_index (list, i);
558+ gpm_array_float_set (raw, i, point->y);
559+ }
560+
561+ /* remove any outliers */
562+ outliers = gpm_array_float_remove_outliers (raw, 3, 0.1);
563+
564+ /* convolve with gaussian */
565+ gaussian = gpm_array_float_compute_gaussian (15, sigma_smoothing);
566+ convolved = gpm_array_float_convolve (outliers, gaussian);
567+
568+ /* add the smoothed data back into a new array */
569+ new = g_ptr_array_new_with_free_func ((GDestroyNotify) gpm_point_obj_free);
570+ for (i=0; i<list->len; i++) {
571+ point = (GpmPointObj *) g_ptr_array_index (list, i);
572+ point_new = g_new0 (GpmPointObj, 1);
573+ point_new->color = point->color;
574+ point_new->x = point->x;
575+ point_new->y = gpm_array_float_get (convolved, i);
576+ g_ptr_array_add (new, point_new);
577+ }
578+
579+ /* free data */
580+ gpm_array_float_free (gaussian);
581+ gpm_array_float_free (raw);
582+ gpm_array_float_free (convolved);
583+ gpm_array_float_free (outliers);
584+
585+ return new;
586+}
587+
588+/**
589+ * gpm_stats_time_to_string:
590+ **/
591+static gchar *
592+gpm_stats_time_to_string (gint seconds)
593+{
594+ gfloat value = seconds;
595+
596+ if (value < 0) {
597+ /* TRANSLATORS: this is when the stats time is not known */
598+ return g_strdup (_("Unknown"));
599+ }
600+ if (value < 60) {
601+ /* TRANSLATORS: this is a time value, usually to show on a graph */
602+ return g_strdup_printf (ngettext ("%.0f second", "%.0f seconds", value), value);
603+ }
604+ value /= 60.0;
605+ if (value < 60) {
606+ /* TRANSLATORS: this is a time value, usually to show on a graph */
607+ return g_strdup_printf (ngettext ("%.1f minute", "%.1f minutes", value), value);
608+ }
609+ value /= 60.0;
610+ if (value < 60) {
611+ /* TRANSLATORS: this is a time value, usually to show on a graph */
612+ return g_strdup_printf (ngettext ("%.1f hour", "%.1f hours", value), value);
613+ }
614+ value /= 24.0;
615+ /* TRANSLATORS: this is a time value, usually to show on a graph */
616+ return g_strdup_printf (ngettext ("%.1f day", "%.1f days", value), value);
617+}
618+
619+/**
620+ * gpm_stats_bool_to_string:
621+ **/
622+static const gchar *
623+gpm_stats_bool_to_string (gboolean ret)
624+{
625+ return ret ? _("Yes") : _("No");
626+}
627+
628+/**
629+ * gpm_stats_get_printable_device_path:
630+ **/
631+static gchar *
632+gpm_stats_get_printable_device_path (UpDevice *device)
633+{
634+ const gchar *object_path;
635+ gchar *device_path = NULL;
636+
637+ /* get object path */
638+ object_path = up_device_get_object_path (device);
639+ if (object_path != NULL)
640+ device_path = g_filename_display_basename (object_path);
641+
642+ return device_path;
643+}
644+
645+/**
646+ * gpm_stats_update_info_page_details:
647+ **/
648+static void
649+gpm_stats_update_info_page_details (UpDevice *device)
650+{
651+ struct tm *time_tm;
652+ time_t t;
653+ gchar time_buf[256];
654+ gchar *text;
655+ guint refreshed;
656+ UpDeviceKind kind;
657+ UpDeviceState state;
658+ UpDeviceTechnology technology;
659+ gdouble percentage;
660+ gdouble capacity;
661+ gdouble energy;
662+ gdouble energy_empty;
663+ gdouble energy_full;
664+ gdouble energy_full_design;
665+ gdouble energy_rate;
666+ gdouble voltage;
667+ gboolean online;
668+ gboolean is_present;
669+ gboolean power_supply;
670+ gboolean is_rechargeable;
671+ guint64 update_time;
672+ gint64 time_to_full;
673+ gint64 time_to_empty;
674+ gchar *vendor = NULL;
675+ gchar *serial = NULL;
676+ gchar *model = NULL;
677+ gchar *device_path = NULL;
678+
679+ gtk_list_store_clear (list_store_info);
680+
681+ /* get device properties */
682+ g_object_get (device,
683+ "kind", &kind,
684+ "state", &state,
685+ "percentage", &percentage,
686+ "online", &online,
687+ "update_time", &update_time,
688+ "power_supply", &power_supply,
689+ "is_rechargeable", &is_rechargeable,
690+ "is-present", &is_present,
691+ "time-to-full", &time_to_full,
692+ "time-to-empty", &time_to_empty,
693+ "technology", &technology,
694+ "capacity", &capacity,
695+ "energy", &energy,
696+ "energy-empty", &energy_empty,
697+ "energy-full", &energy_full,
698+ "energy-full-design", &energy_full_design,
699+ "energy-rate", &energy_rate,
700+ "voltage", &voltage,
701+ "vendor", &vendor,
702+ "serial", &serial,
703+ "model", &model,
704+ NULL);
705+
706+ /* get a human readable time */
707+ t = (time_t) update_time;
708+ time_tm = localtime (&t);
709+ strftime (time_buf, sizeof time_buf, "%c", time_tm);
710+
711+ /* remove prefix */
712+ device_path = gpm_stats_get_printable_device_path (device);
713+ /* TRANSLATORS: the device ID of the current device, e.g. "battery0" */
714+ gpm_stats_add_info_data (_("Device"), device_path);
715+ g_free (device_path);
716+
717+ gpm_stats_add_info_data (_("Type"), gpm_device_kind_to_localised_string (kind, 1));
718+ if (vendor != NULL && vendor[0] != '\0')
719+ gpm_stats_add_info_data (_("Vendor"), vendor);
720+ if (model != NULL && model[0] != '\0')
721+ gpm_stats_add_info_data (_("Model"), model);
722+ if (serial != NULL && serial[0] != '\0')
723+ gpm_stats_add_info_data (_("Serial number"), serial);
724+
725+ /* TRANSLATORS: a boolean attribute that means if the device is supplying the
726+ * main power for the computer. For instance, an AC adapter or laptop battery
727+ * would be TRUE, but a mobile phone or mouse taking power is FALSE */
728+ gpm_stats_add_info_data (_("Supply"), gpm_stats_bool_to_string (power_supply));
729+
730+ refreshed = (int) (time (NULL) - update_time);
731+ text = g_strdup_printf (ngettext ("%d second", "%d seconds", refreshed), refreshed);
732+
733+ /* TRANSLATORS: when the device was last updated with new data. It's
734+ * usually a few seconds when a device is discharging or charging. */
735+ gpm_stats_add_info_data (_("Refreshed"), text);
736+ g_free (text);
737+
738+ if (kind == UP_DEVICE_KIND_BATTERY ||
739+ kind == UP_DEVICE_KIND_MOUSE ||
740+ kind == UP_DEVICE_KIND_KEYBOARD ||
741+ kind == UP_DEVICE_KIND_UPS) {
742+ /* TRANSLATORS: Present is whether the device is currently attached
743+ * to the computer, as some devices (e.g. laptop batteries) can
744+ * be removed, but still observed as devices on the system */
745+ gpm_stats_add_info_data (_("Present"), gpm_stats_bool_to_string (is_present));
746+ }
747+ if (kind == UP_DEVICE_KIND_BATTERY ||
748+ kind == UP_DEVICE_KIND_MOUSE ||
749+ kind == UP_DEVICE_KIND_KEYBOARD) {
750+ /* TRANSLATORS: If the device can be recharged, e.g. lithium
751+ * batteries rather than alkaline ones */
752+ gpm_stats_add_info_data (_("Rechargeable"), gpm_stats_bool_to_string (is_rechargeable));
753+ }
754+ if (kind == UP_DEVICE_KIND_BATTERY ||
755+ kind == UP_DEVICE_KIND_MOUSE ||
756+ kind == UP_DEVICE_KIND_KEYBOARD) {
757+ /* TRANSLATORS: The state of the device, e.g. "Changing" or "Fully charged" */
758+ gpm_stats_add_info_data (_("State"), gpm_device_state_to_localised_string (state));
759+ }
760+ if (kind == UP_DEVICE_KIND_BATTERY) {
761+ text = g_strdup_printf ("%.1f Wh", energy);
762+ gpm_stats_add_info_data (_("Energy"), text);
763+ g_free (text);
764+ text = g_strdup_printf ("%.1f Wh", energy_empty);
765+ gpm_stats_add_info_data (_("Energy when empty"), text);
766+ g_free (text);
767+ text = g_strdup_printf ("%.1f Wh", energy_full);
768+ gpm_stats_add_info_data (_("Energy when full"), text);
769+ g_free (text);
770+ text = g_strdup_printf ("%.1f Wh", energy_full_design);
771+ gpm_stats_add_info_data (_("Energy (design)"), text);
772+ g_free (text);
773+ }
774+ if (kind == UP_DEVICE_KIND_BATTERY ||
775+ kind == UP_DEVICE_KIND_MONITOR) {
776+ text = g_strdup_printf ("%.1f W", energy_rate);
777+ /* TRANSLATORS: the rate of discharge for the device */
778+ gpm_stats_add_info_data (_("Rate"), text);
779+ g_free (text);
780+ }
781+ if (kind == UP_DEVICE_KIND_UPS ||
782+ kind == UP_DEVICE_KIND_BATTERY ||
783+ kind == UP_DEVICE_KIND_MONITOR) {
784+ text = g_strdup_printf ("%.1f V", voltage);
785+ gpm_stats_add_info_data (_("Voltage"), text);
786+ g_free (text);
787+ }
788+ if (kind == UP_DEVICE_KIND_BATTERY ||
789+ kind == UP_DEVICE_KIND_UPS) {
790+ if (time_to_full >= 0) {
791+ text = gpm_stats_time_to_string (time_to_full);
792+ gpm_stats_add_info_data (_("Time to full"), text);
793+ g_free (text);
794+ }
795+ if (time_to_empty >= 0) {
796+ text = gpm_stats_time_to_string (time_to_empty);
797+ gpm_stats_add_info_data (_("Time to empty"), text);
798+ g_free (text);
799+ }
800+ }
801+ if (kind == UP_DEVICE_KIND_BATTERY ||
802+ kind == UP_DEVICE_KIND_MOUSE ||
803+ kind == UP_DEVICE_KIND_KEYBOARD ||
804+ kind == UP_DEVICE_KIND_UPS) {
805+ text = g_strdup_printf ("%.1f%%", percentage);
806+ /* TRANSLATORS: the amount of charge the cell contains */
807+ gpm_stats_add_info_data (_("Percentage"), text);
808+ g_free (text);
809+ }
810+ if (kind == UP_DEVICE_KIND_BATTERY) {
811+ text = g_strdup_printf ("%.1f%%", capacity);
812+ /* TRANSLATORS: the capacity of the device, which is basically a measure
813+ * of how full it can get, relative to the design capacity */
814+ gpm_stats_add_info_data (_("Capacity"), text);
815+ g_free (text);
816+ }
817+ if (kind == UP_DEVICE_KIND_BATTERY) {
818+ /* TRANSLATORS: the type of battery, e.g. lithium or nikel metal hydroxide */
819+ gpm_stats_add_info_data (_("Technology"), gpm_device_technology_to_localised_string (technology));
820+ }
821+ if (kind == UP_DEVICE_KIND_LINE_POWER) {
822+ /* TRANSLATORS: this is when the device is plugged in, typically
823+ * only shown for the ac adaptor device */
824+ gpm_stats_add_info_data (_("Online"), gpm_stats_bool_to_string (online));
825+ }
826+
827+ g_free (vendor);
828+ g_free (serial);
829+ g_free (model);
830+}
831+
832+/**
833+ * gpm_stats_set_graph_data:
834+ **/
835+static void
836+gpm_stats_set_graph_data (GtkWidget *widget, GPtrArray *data, gboolean use_smoothed, gboolean use_points)
837+{
838+ GPtrArray *smoothed;
839+
840+ gpm_graph_widget_data_clear (GPM_GRAPH_WIDGET (widget));
841+
842+ /* add correct data */
843+ if (!use_smoothed) {
844+ if (use_points)
845+ gpm_graph_widget_data_assign (GPM_GRAPH_WIDGET (widget), GPM_GRAPH_WIDGET_PLOT_BOTH, data);
846+ else
847+ gpm_graph_widget_data_assign (GPM_GRAPH_WIDGET (widget), GPM_GRAPH_WIDGET_PLOT_LINE, data);
848+ } else {
849+ smoothed = gpm_stats_update_smooth_data (data);
850+ if (use_points)
851+ gpm_graph_widget_data_assign (GPM_GRAPH_WIDGET (widget), GPM_GRAPH_WIDGET_PLOT_POINTS, data);
852+ gpm_graph_widget_data_assign (GPM_GRAPH_WIDGET (widget), GPM_GRAPH_WIDGET_PLOT_LINE, smoothed);
853+ g_ptr_array_unref (smoothed);
854+ }
855+
856+ /* show */
857+ gtk_widget_show (widget);
858+}
859+
860+/**
861+ * gpm_color_from_rgb:
862+ * @red: The red value
863+ * @green: The green value
864+ * @blue: The blue value
865+ **/
866+static guint32
867+gpm_color_from_rgb (guint8 red, guint8 green, guint8 blue)
868+{
869+ guint32 color = 0;
870+ color += (guint32) red * 0x10000;
871+ color += (guint32) green * 0x100;
872+ color += (guint32) blue;
873+ return color;
874+}
875+
876+/**
877+ * gpm_stats_update_info_page_history:
878+ **/
879+static void
880+gpm_stats_update_info_page_history (UpDevice *device)
881+{
882+ GPtrArray *array;
883+ guint i;
884+ UpHistoryItem *item;
885+ GtkWidget *widget;
886+ gboolean checked;
887+ gboolean points;
888+ GpmPointObj *point;
889+ GPtrArray *new;
890+ gint32 offset = 0;
891+ GTimeVal timeval;
892+
893+ new = g_ptr_array_new_with_free_func ((GDestroyNotify) gpm_point_obj_free);
894+ if (g_strcmp0 (history_type, GPM_HISTORY_CHARGE_VALUE) == 0) {
895+ g_object_set (graph_history,
896+ "type-x", GPM_GRAPH_WIDGET_TYPE_TIME,
897+ "type-y", GPM_GRAPH_WIDGET_TYPE_PERCENTAGE,
898+ "autorange-x", FALSE,
899+ "start-x", -history_time,
900+ "stop-x", 0,
901+ "autorange-y", FALSE,
902+ "start-y", 0,
903+ "stop-y", 100,
904+ NULL);
905+ } else if (g_strcmp0 (history_type, GPM_HISTORY_RATE_VALUE) == 0) {
906+ g_object_set (graph_history,
907+ "type-x", GPM_GRAPH_WIDGET_TYPE_TIME,
908+ "type-y", GPM_GRAPH_WIDGET_TYPE_POWER,
909+ "autorange-x", FALSE,
910+ "start-x", -history_time,
911+ "stop-x", 0,
912+ "autorange-y", TRUE,
913+ NULL);
914+ } else {
915+ g_object_set (graph_history,
916+ "type-x", GPM_GRAPH_WIDGET_TYPE_TIME,
917+ "type-y", GPM_GRAPH_WIDGET_TYPE_TIME,
918+ "autorange-x", FALSE,
919+ "start-x", -history_time,
920+ "stop-x", 0,
921+ "autorange-y", TRUE,
922+ NULL);
923+ }
924+
925+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_history_nodata"));
926+ array = up_device_get_history_sync (device, history_type, history_time, 150, NULL, NULL);
927+ if (array == NULL) {
928+ /* show no data label and hide graph */
929+ gtk_widget_hide (graph_history);
930+ gtk_widget_show (widget);
931+ goto out;
932+ }
933+
934+ /* hide no data and show graph */
935+ gtk_widget_hide (widget);
936+ gtk_widget_show (graph_history);
937+
938+ g_get_current_time (&timeval);
939+ offset = timeval.tv_sec;
940+
941+ for (i=0; i<array->len; i++) {
942+ item = (UpHistoryItem *) g_ptr_array_index (array, i);
943+
944+ /* abandon this point */
945+ if (up_history_item_get_state (item) == UP_DEVICE_STATE_UNKNOWN)
946+ continue;
947+
948+ point = gpm_point_obj_new ();
949+ point->x = (gint32) up_history_item_get_time (item) - offset;
950+ point->y = up_history_item_get_value (item);
951+ if (up_history_item_get_state (item) == UP_DEVICE_STATE_CHARGING)
952+ point->color = gpm_color_from_rgb (255, 0, 0);
953+ else if (up_history_item_get_state (item) == UP_DEVICE_STATE_DISCHARGING)
954+ point->color = gpm_color_from_rgb (0, 0, 255);
955+ else if (up_history_item_get_state (item) == UP_DEVICE_STATE_PENDING_CHARGE)
956+ point->color = gpm_color_from_rgb (200, 0, 0);
957+ else if (up_history_item_get_state (item) == UP_DEVICE_STATE_PENDING_DISCHARGE)
958+ point->color = gpm_color_from_rgb (0, 0, 200);
959+ else {
960+ if (g_strcmp0 (history_type, GPM_HISTORY_RATE_VALUE) == 0)
961+ point->color = gpm_color_from_rgb (255, 255, 255);
962+ else
963+ point->color = gpm_color_from_rgb (0, 255, 0);
964+ }
965+ g_ptr_array_add (new, point);
966+ }
967+
968+ /* render */
969+ sigma_smoothing = 2.0;
970+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_smooth_history"));
971+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
972+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_points_history"));
973+ points = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
974+
975+ /* present data to graph */
976+ gpm_stats_set_graph_data (graph_history, new, checked, points);
977+
978+ g_ptr_array_unref (array);
979+ g_ptr_array_unref (new);
980+out:
981+ return;
982+}
983+
984+/**
985+ * gpm_stats_update_info_page_stats:
986+ **/
987+static void
988+gpm_stats_update_info_page_stats (UpDevice *device)
989+{
990+ GPtrArray *array;
991+ guint i;
992+ UpStatsItem *item;
993+ GtkWidget *widget;
994+ gboolean checked;
995+ gboolean points;
996+ GpmPointObj *point;
997+ GPtrArray *new;
998+ gboolean use_data = FALSE;
999+ const gchar *type = NULL;
1000+
1001+ new = g_ptr_array_new_with_free_func ((GDestroyNotify) gpm_point_obj_free);
1002+ if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_DATA_VALUE) == 0) {
1003+ type = "charging";
1004+ use_data = TRUE;
1005+ } else if (g_strcmp0 (stats_type, GPM_STATS_DISCHARGE_DATA_VALUE) == 0) {
1006+ type = "discharging";
1007+ use_data = TRUE;
1008+ } else if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_ACCURACY_VALUE) == 0) {
1009+ type = "charging";
1010+ use_data = FALSE;
1011+ } else if (g_strcmp0 (stats_type, GPM_STATS_DISCHARGE_ACCURACY_VALUE) == 0) {
1012+ type = "discharging";
1013+ use_data = FALSE;
1014+ } else {
1015+ g_assert_not_reached ();
1016+ }
1017+
1018+ if (use_data) {
1019+ g_object_set (graph_statistics,
1020+ "type-x", GPM_GRAPH_WIDGET_TYPE_PERCENTAGE,
1021+ "type-y", GPM_GRAPH_WIDGET_TYPE_FACTOR,
1022+ "autorange-x", TRUE,
1023+ "autorange-y", TRUE,
1024+ NULL);
1025+ } else {
1026+ g_object_set (graph_statistics,
1027+ "type-x", GPM_GRAPH_WIDGET_TYPE_PERCENTAGE,
1028+ "type-y", GPM_GRAPH_WIDGET_TYPE_PERCENTAGE,
1029+ "autorange-x", TRUE,
1030+ "autorange-y", TRUE,
1031+ NULL);
1032+ }
1033+
1034+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_stats_nodata"));
1035+ array = up_device_get_statistics_sync (device, type, NULL, NULL);
1036+ if (array == NULL) {
1037+ /* show no data label and hide graph */
1038+ gtk_widget_hide (graph_statistics);
1039+ gtk_widget_show (widget);
1040+ goto out;
1041+ }
1042+
1043+ /* hide no data and show graph */
1044+ gtk_widget_hide (widget);
1045+ gtk_widget_show (graph_statistics);
1046+
1047+ for (i=0; i<array->len; i++) {
1048+ item = (UpStatsItem *) g_ptr_array_index (array, i);
1049+ point = gpm_point_obj_new ();
1050+ point->x = i;
1051+ if (use_data)
1052+ point->y = up_stats_item_get_value (item);
1053+ else
1054+ point->y = up_stats_item_get_accuracy (item);
1055+ point->color = gpm_color_from_rgb (255, 0, 0);
1056+ g_ptr_array_add (new, point);
1057+ }
1058+
1059+ /* render */
1060+ sigma_smoothing = 1.1;
1061+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_smooth_stats"));
1062+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
1063+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_points_stats"));
1064+ points = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
1065+
1066+ /* present data to graph */
1067+ gpm_stats_set_graph_data (graph_statistics, new, checked, points);
1068+
1069+ g_ptr_array_unref (array);
1070+ g_ptr_array_unref (new);
1071+out:
1072+ return;
1073+}
1074+
1075+/**
1076+ * gpm_stats_update_info_data_page:
1077+ **/
1078+static void
1079+gpm_stats_update_info_data_page (UpDevice *device, gint page)
1080+{
1081+ if (page == 0)
1082+ gpm_stats_update_info_page_details (device);
1083+ else if (page == 1)
1084+ gpm_stats_update_info_page_history (device);
1085+ else if (page == 2)
1086+ gpm_stats_update_info_page_stats (device);
1087+}
1088+
1089+/**
1090+ * gpm_stats_update_info_data:
1091+ **/
1092+static void
1093+gpm_stats_update_info_data (UpDevice *device)
1094+{
1095+ gint page;
1096+ GtkNotebook *notebook;
1097+ GtkWidget *page_widget;
1098+ gboolean has_history;
1099+ gboolean has_statistics;
1100+
1101+ /* get properties */
1102+ g_object_get (device,
1103+ "has-history", &has_history,
1104+ "has-statistics", &has_statistics,
1105+ NULL);
1106+
1107+ notebook = GTK_NOTEBOOK (gtk_builder_get_object (builder, "notebook1"));
1108+
1109+ /* show info page */
1110+ page_widget = gtk_notebook_get_nth_page (notebook, 0);
1111+ gtk_widget_show (page_widget);
1112+
1113+ /* hide history if no support */
1114+ page_widget = gtk_notebook_get_nth_page (notebook, 1);
1115+ if (has_history)
1116+ gtk_widget_show (page_widget);
1117+ else
1118+ gtk_widget_hide (page_widget);
1119+
1120+ /* hide statistics if no support */
1121+ page_widget = gtk_notebook_get_nth_page (notebook, 2);
1122+ if (has_statistics)
1123+ gtk_widget_show (page_widget);
1124+ else
1125+ gtk_widget_hide (page_widget);
1126+
1127+ /* hide wakeups page */
1128+ page_widget = gtk_notebook_get_nth_page (notebook, 3);
1129+ gtk_widget_hide (page_widget);
1130+
1131+ page = gtk_notebook_get_current_page (notebook);
1132+ gpm_stats_update_info_data_page (device, page);
1133+
1134+ return;
1135+}
1136+
1137+/**
1138+ * gpm_stats_format_cmdline:
1139+ **/
1140+static gchar *
1141+gpm_stats_format_cmdline (UpWakeupItem *item)
1142+{
1143+ gchar *found;
1144+ gchar *temp = NULL;
1145+ gchar *cmdline;
1146+ const gchar *temp_ptr;
1147+
1148+ /* nothing */
1149+ if (up_wakeup_item_get_cmdline (item) == NULL) {
1150+ /* TRANSLATORS: the command line was not provided */
1151+ temp_ptr = _("No data");
1152+ goto out;
1153+ }
1154+
1155+ /* common kernel cmd names */
1156+ if (g_strcmp0 (up_wakeup_item_get_cmdline (item), "insmod") == 0) {
1157+ /* TRANSLATORS: kernel module, usually a device driver */
1158+ temp_ptr = _("Kernel module");
1159+ goto out;
1160+ }
1161+ if (g_strcmp0 (up_wakeup_item_get_cmdline (item), "modprobe") == 0) {
1162+ /* TRANSLATORS: kernel module, usually a device driver */
1163+ temp_ptr = _("Kernel module");
1164+ goto out;
1165+ }
1166+ if (g_strcmp0 (up_wakeup_item_get_cmdline (item), "swapper") == 0) {
1167+ /* TRANSLATORS: kernel housekeeping */
1168+ temp_ptr = _("Kernel core");
1169+ goto out;
1170+ }
1171+ if (g_strcmp0 (up_wakeup_item_get_cmdline (item), "kernel-ipi") == 0) {
1172+ /* TRANSLATORS: interrupt between processors */
1173+ temp_ptr = _("Interprocessor interrupt");
1174+ goto out;
1175+ }
1176+ if (g_strcmp0 (up_wakeup_item_get_cmdline (item), "interrupt") == 0) {
1177+ /* TRANSLATORS: unknown interrupt */
1178+ temp_ptr = _("Interrupt");
1179+ goto out;
1180+ }
1181+
1182+ /* truncate at first space or ':' */
1183+ temp = g_strdup (up_wakeup_item_get_cmdline (item));
1184+ found = strstr (temp, ":");
1185+ if (found != NULL)
1186+ *found = '\0';
1187+ found = strstr (temp, " ");
1188+ if (found != NULL)
1189+ *found = '\0';
1190+
1191+ /* remove path */
1192+ found = g_strrstr (temp, "/");
1193+ if (found != NULL && strncmp (temp, "event", 5) != 0)
1194+ temp_ptr = found + 1;
1195+ else
1196+ temp_ptr = temp;
1197+
1198+out:
1199+ /* format command line */
1200+ if (up_wakeup_item_get_is_userspace (item))
1201+ cmdline = g_markup_escape_text (temp_ptr, -1);
1202+ else
1203+ cmdline = g_markup_printf_escaped ("<i>%s</i>", temp_ptr);
1204+ g_free (temp);
1205+
1206+ /* return */
1207+ return cmdline;
1208+}
1209+
1210+/**
1211+ * gpm_stats_format_details:
1212+ **/
1213+static gchar *
1214+gpm_stats_format_details (UpWakeupItem *item)
1215+{
1216+ gchar *details;
1217+ const gchar *data;
1218+
1219+ /* get this once to avoid a load of derefs */
1220+ data = up_wakeup_item_get_details (item);
1221+
1222+ /* replace common driver names */
1223+ if (g_strcmp0 (data, "i8042") == 0) {
1224+ /* TRANSLATORS: the keyboard and mouse device event */
1225+ details = g_strdup (_("PS/2 keyboard/mouse/touchpad"));
1226+ } else if (g_strcmp0 (data, "acpi") == 0) {
1227+ /* TRANSLATORS: ACPI, the Intel power standard on laptops and desktops */
1228+ details = g_strdup (_("ACPI"));
1229+ } else if (g_strcmp0 (data, "ata_piix") == 0) {
1230+ /* TRANSLATORS: serial ATA is a new style of hard disk interface */
1231+ details = g_strdup (_("Serial ATA"));
1232+ } else if (g_strcmp0 (data, "libata") == 0) {
1233+ /* TRANSLATORS: this is the old-style ATA interface */
1234+ details = g_strdup (_("ATA host controller"));
1235+ } else if (g_strcmp0 (data, "iwl3945") == 0 || g_strcmp0 (data, "iwlagn") == 0) {
1236+ /* TRANSLATORS: 802.11 wireless adaptor */
1237+ details = g_strdup (_("Intel wireless adaptor"));
1238+
1239+ /* try to make the wakeup type nicer */
1240+ } else if (g_str_has_prefix (data, "__mod_timer")) {
1241+ /* TRANSLATORS: a timer is something that fires periodically.
1242+ * The parameter is a process name, e.g. "firefox-bin".
1243+ * This is shown when the timer wakes up. */
1244+ details = g_strdup_printf (_("Timer %s"), data+12);
1245+ } else if (g_str_has_prefix (data, "mod_timer")) {
1246+ /* TRANSLATORS: a timer is something that fires periodically.
1247+ * The parameter is a process name, e.g. "firefox-bin".
1248+ * This is shown when the timer wakes up. */
1249+ details = g_strdup_printf (_("Timer %s"), data+10);
1250+ } else if (g_str_has_prefix (data, "hrtimer_start_expires")) {
1251+ /* TRANSLATORS: a timer is something that fires periodically.
1252+ * The parameter is a process name, e.g. "firefox-bin".
1253+ * This is shown when the timer wakes up. */
1254+ details = g_strdup_printf (_("Timer %s"), data+22);
1255+ } else if (g_str_has_prefix (data, "hrtimer_start")) {
1256+ /* TRANSLATORS: a timer is something that fires periodically.
1257+ * The parameter is a process name, e.g. "firefox-bin".
1258+ * This is shown when the timer wakes up. */
1259+ details = g_strdup_printf (_("Timer %s"), data+14);
1260+ } else if (g_str_has_prefix (data, "do_setitimer")) {
1261+ /* TRANSLATORS: a timer is something that fires periodically.
1262+ * The parameter is a process name, e.g. "firefox-bin".
1263+ * This is shown when the timer wakes up. */
1264+ details = g_strdup_printf (_("Timer %s"), data+10);
1265+ } else if (g_str_has_prefix (data, "do_nanosleep")) {
1266+ /* TRANSLATORS: the parameter is the name of task that's woken up from sleeping.
1267+ * This is shown when the task wakes up. */
1268+ details = g_strdup_printf (_("Sleep %s"), data+13);
1269+ } else if (g_str_has_prefix (data, "enqueue_task_rt")) {
1270+ /* TRANSLATORS: this is the name of a new realtime task. */
1271+ details = g_strdup_printf (_("New task %s"), data+16);
1272+ } else if (g_str_has_prefix (data, "futex_wait")) {
1273+ /* TRANSLATORS: this is the name of a task that's woken to check state.
1274+ * This is shown when the task wakes up. */
1275+ details = g_strdup_printf (_("Wait %s"), data+11);
1276+ } else if (g_str_has_prefix (data, "queue_delayed_work_on")) {
1277+ /* TRANSLATORS: this is the name of a work queue.
1278+ * A work queue is a list of work that has to be done. */
1279+ details = g_strdup_printf (_("Work queue %s"), data+22);
1280+ } else if (g_str_has_prefix (data, "queue_delayed_work")) {
1281+ /* TRANSLATORS: this is the name of a work queue.
1282+ * A work queue is a list of work that has to be done. */
1283+ details = g_strdup_printf (_("Work queue %s"), data+19);
1284+ } else if (g_str_has_prefix (data, "dst_run_gc")) {
1285+ /* TRANSLATORS: this is when the networking subsystem clears out old entries */
1286+ details = g_strdup_printf (_("Network route flush %s"), data+11);
1287+ } else if (g_str_has_prefix (data, "usb_hcd_poll_rh_status")) {
1288+ /* TRANSLATORS: this is the name of an activity on the USB bus */
1289+ details = g_strdup_printf (_("USB activity %s"), data+23);
1290+ } else if (g_str_has_prefix (data, "schedule_hrtimeout_range")) {
1291+ /* TRANSLATORS: we've timed out of an aligned timer, with the name */
1292+ details = g_strdup_printf (_("Wakeup %s"), data+25);
1293+ } else if (g_str_has_prefix (data, "Local timer interrupts")) {
1294+ /* TRANSLATORS: interupts on the system required for basic operation */
1295+ details = g_strdup (_("Local interrupts"));
1296+ } else if (g_str_has_prefix (data, "Rescheduling interrupts")) {
1297+ /* TRANSLATORS: interrupts when a task gets moved from one core to another */
1298+ details = g_strdup (_("Rescheduling interrupts"));
1299+ } else
1300+ details = g_markup_escape_text (data, -1);
1301+
1302+ return details;
1303+}
1304+/**
1305+ * gpm_stats_add_wakeups_item:
1306+ **/
1307+static void
1308+gpm_stats_add_wakeups_item (UpWakeupItem *item)
1309+{
1310+ const gchar *icon;
1311+ gchar *value;
1312+ gchar *id;
1313+ gchar *details;
1314+ gchar *cmdline;
1315+ GtkTreeIter iter;
1316+
1317+ if (up_wakeup_item_get_is_userspace (item)) {
1318+ icon = "application-x-executable";
1319+ id = g_strdup_printf ("%i", up_wakeup_item_get_id (item));
1320+ } else {
1321+ icon = "applications-system";
1322+ if (up_wakeup_item_get_id (item) < 0xff0)
1323+ id = g_strdup_printf ("IRQ%i", up_wakeup_item_get_id (item));
1324+ else
1325+ id = g_strdup ("IRQx");
1326+ }
1327+
1328+ /* formate value to one decimal place */
1329+ value = g_strdup_printf ("%.1f", up_wakeup_item_get_value (item));
1330+
1331+ /* get formatted lines */
1332+ cmdline = gpm_stats_format_cmdline (item);
1333+ details = gpm_stats_format_details (item);
1334+
1335+ gtk_list_store_append (list_store_wakeups, &iter);
1336+ gtk_list_store_set (list_store_wakeups, &iter,
1337+ GPM_WAKEUPS_COLUMN_ID, id,
1338+ GPM_WAKEUPS_COLUMN_VALUE, value,
1339+ GPM_WAKEUPS_COLUMN_CMDLINE, cmdline,
1340+ GPM_WAKEUPS_COLUMN_DETAILS, details,
1341+ GPM_WAKEUPS_COLUMN_ICON, icon, -1);
1342+ g_free (cmdline);
1343+ g_free (details);
1344+ g_free (value);
1345+ g_free (id);
1346+}
1347+
1348+/**
1349+ * gpm_stats_update_wakeups_data:
1350+ **/
1351+static void
1352+gpm_stats_update_wakeups_data (void)
1353+{
1354+ GtkWidget *widget;
1355+ GtkWidget *page_widget;
1356+ guint total;
1357+ UpWakeupItem *item;
1358+ gchar *text;
1359+ guint i;
1360+ GError *error = NULL;
1361+ GPtrArray *array;
1362+
1363+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "notebook1"));
1364+
1365+ /* hide other pages */
1366+ page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK(widget), 0);
1367+ gtk_widget_hide (page_widget);
1368+ page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK(widget), 1);
1369+ gtk_widget_hide (page_widget);
1370+ page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK(widget), 2);
1371+ gtk_widget_hide (page_widget);
1372+
1373+ /* show wakeups page */
1374+ page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK(widget), 3);
1375+ gtk_widget_show (page_widget);
1376+
1377+ /* show total */
1378+ total = up_wakeups_get_total_sync (wakeups, NULL, &error);
1379+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_total_wakeups"));
1380+ if (error == NULL) {
1381+ text = g_strdup_printf ("%i", total);
1382+ gtk_label_set_label (GTK_LABEL(widget), text);
1383+ g_free (text);
1384+ } else {
1385+ gtk_label_set_label (GTK_LABEL(widget), error->message);
1386+ g_error_free (error);
1387+ }
1388+
1389+ /* get data */
1390+ gtk_list_store_clear (list_store_wakeups);
1391+ array = up_wakeups_get_data_sync (wakeups, NULL, NULL);
1392+ if (array == NULL)
1393+ return;
1394+ for (i=0; i<array->len; i++) {
1395+ item = g_ptr_array_index (array, i);
1396+ gpm_stats_add_wakeups_item (item);
1397+ }
1398+ g_ptr_array_unref (array);
1399+}
1400+
1401+static void
1402+gpm_stats_set_title (GtkWindow *window, gint page_num)
1403+{
1404+ gchar *title;
1405+ const gchar * const page_titles[] = {
1406+ /* TRANSLATORS: shown on the titlebar */
1407+ N_("Device Information"),
1408+ /* TRANSLATORS: shown on the titlebar */
1409+ N_("Device History"),
1410+ /* TRANSLATORS: shown on the titlebar */
1411+ N_("Device Profile"),
1412+ /* TRANSLATORS: shown on the titlebar */
1413+ N_("Processor Wakeups")
1414+ };
1415+
1416+ /* TRANSLATORS: shown on the titlebar */
1417+ title = g_strdup_printf ("%s - %s", _("Power Statistics"), _(page_titles[page_num]));
1418+ gtk_window_set_title (window, title);
1419+ g_free (title);
1420+}
1421+
1422+/**
1423+ * gpm_stats_notebook_changed_cb:
1424+ **/
1425+static void
1426+gpm_stats_notebook_changed_cb (GtkNotebook *notebook, gpointer page, gint page_num, gpointer user_data)
1427+{
1428+ UpDevice *device;
1429+ GtkWidget *widget;
1430+
1431+ /* set the window title depending on the mode */
1432+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_stats"));
1433+ gpm_stats_set_title (GTK_WINDOW (widget), page_num);
1434+
1435+ /* save page in gconf */
1436+ g_settings_set_int (settings, GPM_SETTINGS_INFO_PAGE_NUMBER, page_num);
1437+
1438+ if (current_device == NULL)
1439+ return;
1440+
1441+ if (g_strcmp0 (current_device, "wakeups") == 0)
1442+ return;
1443+
1444+ device = up_device_new ();
1445+ up_device_set_object_path_sync (device, current_device, NULL, NULL);
1446+ gpm_stats_update_info_data_page (device, page_num);
1447+ gpm_stats_update_info_data (device);
1448+ g_object_unref (device);
1449+}
1450+
1451+/**
1452+ * gpm_stats_button_update_ui:
1453+ **/
1454+static void
1455+gpm_stats_button_update_ui (void)
1456+{
1457+ UpDevice *device;
1458+ device = up_device_new ();
1459+ up_device_set_object_path_sync (device, current_device, NULL, NULL);
1460+ gpm_stats_update_info_data (device);
1461+ g_object_unref (device);
1462+}
1463+
1464+/**
1465+ * gpm_stats_devices_treeview_clicked_cb:
1466+ **/
1467+static void
1468+gpm_stats_devices_treeview_clicked_cb (GtkTreeSelection *selection, gpointer user_data)
1469+{
1470+ GtkTreeModel *model;
1471+ GtkTreeIter iter;
1472+ UpDevice *device;
1473+
1474+ /* This will only work in single or browse selection mode! */
1475+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
1476+ g_free (current_device);
1477+ gtk_tree_model_get (model, &iter, GPM_DEVICES_COLUMN_ID, &current_device, -1);
1478+
1479+ /* save device in gconf */
1480+ g_settings_set_string (settings, GPM_SETTINGS_INFO_LAST_DEVICE, current_device);
1481+
1482+ /* show transaction_id */
1483+ g_debug ("selected row is: %s", current_device);
1484+
1485+ /* is special device */
1486+ if (g_strcmp0 (current_device, "wakeups") == 0) {
1487+ gpm_stats_update_wakeups_data ();
1488+ } else {
1489+ device = up_device_new ();
1490+ up_device_set_object_path_sync (device, current_device, NULL, NULL);
1491+ gpm_stats_update_info_data (device);
1492+ g_object_unref (device);
1493+ }
1494+
1495+ } else {
1496+ g_debug ("no row selected");
1497+ }
1498+}
1499+
1500+/**
1501+ * gpm_stats_add_device:
1502+ **/
1503+static void
1504+gpm_stats_add_device (UpDevice *device)
1505+{
1506+ const gchar *id;
1507+ GtkTreeIter iter;
1508+ const gchar *text;
1509+ GIcon *icon;
1510+ UpDeviceKind kind;
1511+
1512+ /* get device properties */
1513+ g_object_get (device,
1514+ "kind", &kind,
1515+ NULL);
1516+
1517+ id = up_device_get_object_path (device);
1518+ text = gpm_device_kind_to_localised_string (kind, 1);
1519+ icon = gpm_stats_get_device_icon (device, FALSE);
1520+
1521+ gtk_list_store_append (list_store_devices, &iter);
1522+ gtk_list_store_set (list_store_devices, &iter,
1523+ GPM_DEVICES_COLUMN_ID, id,
1524+ GPM_DEVICES_COLUMN_TEXT, text,
1525+ GPM_DEVICES_COLUMN_ICON, icon, -1);
1526+ g_object_unref (icon);
1527+}
1528+
1529+/**
1530+ * gpm_stats_data_changed_cb:
1531+ **/
1532+static void
1533+gpm_stats_data_changed_cb (UpClient *client, gpointer user_data)
1534+{
1535+ if (g_strcmp0 (current_device, "wakeups") == 0)
1536+ gpm_stats_update_wakeups_data ();
1537+}
1538+
1539+/**
1540+ * gpm_stats_device_added_cb:
1541+ **/
1542+static void
1543+gpm_stats_device_added_cb (UpClient *client, UpDevice *device, gpointer user_data)
1544+{
1545+ const gchar *object_path;
1546+ object_path = up_device_get_object_path (device);
1547+ g_debug ("added: %s", object_path);
1548+ gpm_stats_add_device (device);
1549+}
1550+
1551+/**
1552+ * gpm_stats_device_changed_cb:
1553+ **/
1554+static void
1555+gpm_stats_device_changed_cb (UpClient *client, UpDevice *device, gpointer user_data)
1556+{
1557+ const gchar *object_path;
1558+ object_path = up_device_get_object_path (device);
1559+ if (object_path == NULL || current_device == NULL)
1560+ return;
1561+ g_debug ("changed: %s", object_path);
1562+ if (g_strcmp0 (current_device, object_path) == 0)
1563+ gpm_stats_update_info_data (device);
1564+}
1565+
1566+/**
1567+ * gpm_stats_device_removed_cb:
1568+ **/
1569+static void
1570+gpm_stats_device_removed_cb (UpClient *client, UpDevice *device, gpointer user_data)
1571+{
1572+ const gchar *object_path;
1573+ GtkTreeIter iter;
1574+ gchar *id = NULL;
1575+ gboolean ret;
1576+
1577+ object_path = up_device_get_object_path (device);
1578+ g_debug ("removed: %s", object_path);
1579+ if (g_strcmp0 (current_device, object_path) == 0) {
1580+ gtk_list_store_clear (list_store_info);
1581+ }
1582+
1583+ /* search the list and remove the object path entry */
1584+ ret = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store_devices), &iter);
1585+ while (ret) {
1586+ gtk_tree_model_get (GTK_TREE_MODEL (list_store_devices), &iter, GPM_DEVICES_COLUMN_ID, &id, -1);
1587+ if (g_strcmp0 (id, object_path) == 0) {
1588+ gtk_list_store_remove (list_store_devices, &iter);
1589+ break;
1590+ }
1591+ g_free (id);
1592+ ret = gtk_tree_model_iter_next (GTK_TREE_MODEL (list_store_devices), &iter);
1593+ };
1594+}
1595+
1596+/**
1597+ * gpm_stats_history_type_combo_changed_cb:
1598+ **/
1599+static void
1600+gpm_stats_history_type_combo_changed_cb (GtkWidget *widget, gpointer data)
1601+{
1602+ gchar *value;
1603+ const gchar *axis_x = NULL;
1604+ const gchar *axis_y = NULL;
1605+ value = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (widget));
1606+ if (g_strcmp0 (value, GPM_HISTORY_RATE_TEXT) == 0) {
1607+ history_type = GPM_HISTORY_RATE_VALUE;
1608+ /* TRANSLATORS: this is the X axis on the graph */
1609+ axis_x = _("Time elapsed");
1610+ /* TRANSLATORS: this is the Y axis on the graph */
1611+ axis_y = _("Power");
1612+ } else if (g_strcmp0 (value, GPM_HISTORY_CHARGE_TEXT) == 0) {
1613+ history_type = GPM_HISTORY_CHARGE_VALUE;
1614+ /* TRANSLATORS: this is the X axis on the graph */
1615+ axis_x = _("Time elapsed");
1616+ /* TRANSLATORS: this is the Y axis on the graph for the whole battery device */
1617+ axis_y = _("Cell charge");
1618+ } else if (g_strcmp0 (value, GPM_HISTORY_TIME_FULL_TEXT) == 0) {
1619+ history_type = GPM_HISTORY_TIME_FULL_VALUE;
1620+ /* TRANSLATORS: this is the X axis on the graph */
1621+ axis_x = _("Time elapsed");
1622+ /* TRANSLATORS: this is the Y axis on the graph */
1623+ axis_y = _("Predicted time");
1624+ } else if (g_strcmp0 (value, GPM_HISTORY_TIME_EMPTY_TEXT) == 0) {
1625+ history_type = GPM_HISTORY_TIME_EMPTY_VALUE;
1626+ /* TRANSLATORS: this is the X axis on the graph */
1627+ axis_x = _("Time elapsed");
1628+ /* TRANSLATORS: this is the Y axis on the graph */
1629+ axis_y = _("Predicted time");
1630+ } else {
1631+ g_assert (FALSE);
1632+ }
1633+
1634+ /* set axis */
1635+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_axis_history_x"));
1636+ gtk_label_set_label (GTK_LABEL(widget), axis_x);
1637+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_axis_history_y"));
1638+ gtk_label_set_label (GTK_LABEL(widget), axis_y);
1639+
1640+ gpm_stats_button_update_ui ();
1641+ g_free (value);
1642+
1643+ /* save to gconf */
1644+ g_settings_set_string (settings, GPM_SETTINGS_INFO_HISTORY_TYPE, history_type);
1645+}
1646+
1647+/**
1648+ * gpm_stats_type_combo_changed_cb:
1649+ **/
1650+static void
1651+gpm_stats_type_combo_changed_cb (GtkWidget *widget, gpointer data)
1652+{
1653+ gchar *value;
1654+ const gchar *axis_x = NULL;
1655+ const gchar *axis_y = NULL;
1656+ value = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (widget));
1657+ if (g_strcmp0 (value, GPM_STATS_CHARGE_DATA_TEXT) == 0) {
1658+ stats_type = GPM_STATS_CHARGE_DATA_VALUE;
1659+ /* TRANSLATORS: this is the X axis on the graph for the whole battery device */
1660+ axis_x = _("Cell charge");
1661+ /* TRANSLATORS: this is the Y axis on the graph */
1662+ axis_y = _("Correction factor");
1663+ } else if (g_strcmp0 (value, GPM_STATS_CHARGE_ACCURACY_TEXT) == 0) {
1664+ stats_type = GPM_STATS_CHARGE_ACCURACY_VALUE;
1665+ /* TRANSLATORS: this is the X axis on the graph for the whole battery device */
1666+ axis_x = _("Cell charge");
1667+ /* TRANSLATORS: this is the Y axis on the graph */
1668+ axis_y = _("Prediction accuracy");
1669+ } else if (g_strcmp0 (value, GPM_STATS_DISCHARGE_DATA_TEXT) == 0) {
1670+ stats_type = GPM_STATS_DISCHARGE_DATA_VALUE;
1671+ /* TRANSLATORS: this is the X axis on the graph for the whole battery device */
1672+ axis_x = _("Cell charge");
1673+ /* TRANSLATORS: this is the Y axis on the graph */
1674+ axis_y = _("Correction factor");
1675+ } else if (g_strcmp0 (value, GPM_STATS_DISCHARGE_ACCURACY_TEXT) == 0) {
1676+ stats_type = GPM_STATS_DISCHARGE_ACCURACY_VALUE;
1677+ /* TRANSLATORS: this is the X axis on the graph for the whole battery device */
1678+ axis_x = _("Cell charge");
1679+ /* TRANSLATORS: this is the Y axis on the graph */
1680+ axis_y = _("Prediction accuracy");
1681+ } else {
1682+ g_assert (FALSE);
1683+ }
1684+
1685+ /* set axis */
1686+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_axis_stats_x"));
1687+ gtk_label_set_label (GTK_LABEL(widget), axis_x);
1688+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_axis_stats_y"));
1689+ gtk_label_set_label (GTK_LABEL(widget), axis_y);
1690+
1691+ gpm_stats_button_update_ui ();
1692+ g_free (value);
1693+
1694+ /* save to gconf */
1695+ g_settings_set_string (settings, GPM_SETTINGS_INFO_STATS_TYPE, stats_type);
1696+}
1697+
1698+/**
1699+ * gpm_stats_range_combo_changed:
1700+ **/
1701+static void
1702+gpm_stats_range_combo_changed (GtkWidget *widget, gpointer data)
1703+{
1704+ gchar *value;
1705+ value = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (widget));
1706+ if (g_strcmp0 (value, GPM_HISTORY_MINUTE_TEXT) == 0)
1707+ history_time = GPM_HISTORY_MINUTE_VALUE;
1708+ else if (g_strcmp0 (value, GPM_HISTORY_HOUR_TEXT) == 0)
1709+ history_time = GPM_HISTORY_HOUR_VALUE;
1710+ else if (g_strcmp0 (value, GPM_HISTORY_HOURS_TEXT) == 0)
1711+ history_time = GPM_HISTORY_HOURS_VALUE;
1712+ else if (g_strcmp0 (value, GPM_HISTORY_DAY_TEXT) == 0)
1713+ history_time = GPM_HISTORY_DAY_VALUE;
1714+ else if (g_strcmp0 (value, GPM_HISTORY_WEEK_TEXT) == 0)
1715+ history_time = GPM_HISTORY_WEEK_VALUE;
1716+ else
1717+ g_assert (FALSE);
1718+
1719+ /* save to gconf */
1720+ g_settings_set_int (settings, GPM_SETTINGS_INFO_HISTORY_TIME, history_time);
1721+
1722+ gpm_stats_button_update_ui ();
1723+ g_free (value);
1724+}
1725+
1726+/**
1727+ * gpm_stats_smooth_checkbox_history_cb:
1728+ * @widget: The GtkWidget object
1729+ **/
1730+static void
1731+gpm_stats_smooth_checkbox_history_cb (GtkWidget *widget, gpointer data)
1732+{
1733+ gboolean checked;
1734+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
1735+ g_settings_set_boolean (settings, GPM_SETTINGS_INFO_HISTORY_GRAPH_SMOOTH, checked);
1736+ gpm_stats_button_update_ui ();
1737+}
1738+
1739+/**
1740+ * gpm_stats_smooth_checkbox_stats_cb:
1741+ * @widget: The GtkWidget object
1742+ **/
1743+static void
1744+gpm_stats_smooth_checkbox_stats_cb (GtkWidget *widget, gpointer data)
1745+{
1746+ gboolean checked;
1747+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
1748+ g_settings_set_boolean (settings, GPM_SETTINGS_INFO_STATS_GRAPH_SMOOTH, checked);
1749+ gpm_stats_button_update_ui ();
1750+}
1751+
1752+/**
1753+ * gpm_stats_points_checkbox_history_cb:
1754+ * @widget: The GtkWidget object
1755+ **/
1756+static void
1757+gpm_stats_points_checkbox_history_cb (GtkWidget *widget, gpointer data)
1758+{
1759+ gboolean checked;
1760+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
1761+ g_settings_set_boolean (settings, GPM_SETTINGS_INFO_HISTORY_GRAPH_POINTS, checked);
1762+ gpm_stats_button_update_ui ();
1763+}
1764+
1765+/**
1766+ * gpm_stats_points_checkbox_stats_cb:
1767+ * @widget: The GtkWidget object
1768+ **/
1769+static void
1770+gpm_stats_points_checkbox_stats_cb (GtkWidget *widget, gpointer data)
1771+{
1772+ gboolean checked;
1773+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
1774+ g_settings_set_boolean (settings, GPM_SETTINGS_INFO_STATS_GRAPH_POINTS, checked);
1775+ gpm_stats_button_update_ui ();
1776+}
1777+
1778+/**
1779+ * gpm_stats_highlight_device:
1780+ **/
1781+static gboolean
1782+gpm_stats_highlight_device (const gchar *object_path)
1783+{
1784+ gboolean ret;
1785+ gboolean found = FALSE;
1786+ gchar *id = NULL;
1787+ gchar *path_str;
1788+ guint i;
1789+ GtkTreeIter iter;
1790+ GtkTreePath *path;
1791+ GtkWidget *widget;
1792+
1793+ /* check valid */
1794+ if (!g_str_has_prefix (object_path, "/") &&
1795+ g_strcmp0 (object_path, "wakeups") != 0) {
1796+ goto out;
1797+ }
1798+
1799+ /* we have to reuse the treeview data as it may be sorted */
1800+ ret = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store_devices), &iter);
1801+ for (i=0; ret && !found; i++) {
1802+ gtk_tree_model_get (GTK_TREE_MODEL (list_store_devices), &iter,
1803+ GPM_DEVICES_COLUMN_ID, &id,
1804+ -1);
1805+ if (g_strcmp0 (id, object_path) == 0) {
1806+ path_str = g_strdup_printf ("%i", i);
1807+ path = gtk_tree_path_new_from_string (path_str);
1808+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_devices"));
1809+ gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (widget), path, NULL, NULL, FALSE);
1810+ g_free (path_str);
1811+ gtk_tree_path_free (path);
1812+ found = TRUE;
1813+ }
1814+ g_free (id);
1815+ ret = gtk_tree_model_iter_next (GTK_TREE_MODEL (list_store_devices), &iter);
1816+ }
1817+out:
1818+ return found;
1819+}
1820+
1821+/**
1822+ * gpm_stats_delete_event_cb:
1823+ **/
1824+static gboolean
1825+gpm_stats_delete_event_cb (GtkWidget *widget, GdkEvent *event, GtkApplication *application)
1826+{
1827+ g_application_release (G_APPLICATION (application));
1828+ return TRUE;
1829+}
1830+
1831+/**
1832+ * gpm_stats_button_close_cb:
1833+ **/
1834+static void
1835+gpm_stats_button_close_cb (GtkWidget *widget, GtkApplication *application)
1836+{
1837+ g_application_release (G_APPLICATION (application));
1838+}
1839+
1840+/**
1841+ * gpm_stats_commandline_cb:
1842+ **/
1843+static int
1844+gpm_stats_commandline_cb (GApplication *application,
1845+ GApplicationCommandLine *cmdline,
1846+ gpointer user_data)
1847+{
1848+ gboolean ret;
1849+ gboolean verbose = FALSE;
1850+ gchar **argv;
1851+ gchar *last_device = NULL;
1852+ gint argc;
1853+ GOptionContext *context;
1854+ GtkWindow *window;
1855+
1856+ const GOptionEntry options[] = {
1857+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
1858+ /* TRANSLATORS: show verbose debugging */
1859+ N_("Show extra debugging information"), NULL },
1860+ { "device", '\0', 0, G_OPTION_ARG_STRING, &last_device,
1861+ /* TRANSLATORS: show a device by default */
1862+ N_("Select this device at startup"), NULL },
1863+ { NULL}
1864+ };
1865+
1866+ /* get arguments */
1867+ argv = g_application_command_line_get_arguments (cmdline, &argc);
1868+
1869+ context = g_option_context_new (NULL);
1870+ /* TRANSLATORS: the program name */
1871+ g_option_context_set_summary (context, _("Power Statistics"));
1872+ g_option_context_add_main_entries (context, options, NULL);
1873+ ret = g_option_context_parse (context, &argc, &argv, NULL);
1874+ if (!ret)
1875+ goto out;
1876+
1877+ /* get from GSettings if we never specified on the command line */
1878+ if (last_device == NULL)
1879+ last_device = g_settings_get_string (settings, GPM_SETTINGS_INFO_LAST_DEVICE);
1880+
1881+ /* set the correct focus on the last device */
1882+ if (last_device != NULL) {
1883+ ret = gpm_stats_highlight_device (last_device);
1884+ if (!ret)
1885+ g_warning ("failed to select");
1886+ g_free (last_device);
1887+ }
1888+
1889+ /* make sure the window is raised */
1890+ window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_stats"));
1891+ gtk_window_present (window);
1892+out:
1893+ g_strfreev (argv);
1894+ g_option_context_free (context);
1895+ return ret;
1896+}
1897+
1898+/**
1899+ * gpm_stats_startup_cb:
1900+ **/
1901+static void
1902+gpm_stats_startup_cb (GApplication *application,
1903+ gpointer user_data)
1904+{
1905+ GtkBox *box;
1906+ GtkWidget *widget;
1907+ GtkWindow *window;
1908+ GtkTreeSelection *selection;
1909+ gboolean ret;
1910+ UpClient *client;
1911+ GPtrArray *devices;
1912+ UpDevice *device;
1913+ UpDeviceKind kind;
1914+ guint i, j;
1915+ gint page;
1916+ gboolean checked;
1917+ guint retval;
1918+ GError *error = NULL;
1919+
1920+ /* get UI */
1921+ builder = gtk_builder_new ();
1922+ retval = gtk_builder_add_from_resource (builder,
1923+ "/org/gnome/power-manager/gpm-statistics.ui",
1924+ &error);
1925+ if (retval == 0) {
1926+ g_warning ("failed to load ui: %s", error->message);
1927+ g_error_free (error);
1928+ }
1929+
1930+ /* add history graph */
1931+ box = GTK_BOX (gtk_builder_get_object (builder, "hbox_history"));
1932+ graph_history = gpm_graph_widget_new ();
1933+ gtk_box_pack_start (box, graph_history, TRUE, TRUE, 0);
1934+ gtk_widget_set_size_request (graph_history, 400, 250);
1935+ gtk_widget_show (graph_history);
1936+
1937+ /* add statistics graph */
1938+ box = GTK_BOX (gtk_builder_get_object (builder, "hbox_statistics"));
1939+ graph_statistics = gpm_graph_widget_new ();
1940+ gtk_box_pack_start (box, graph_statistics, TRUE, TRUE, 0);
1941+ gtk_widget_set_size_request (graph_statistics, 400, 250);
1942+ gtk_widget_show (graph_statistics);
1943+
1944+ window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_stats"));
1945+ gtk_window_set_application (window, GTK_APPLICATION (application));
1946+ gtk_window_set_default_size (window, 800, 500);
1947+ gtk_window_set_application (window, GTK_APPLICATION (application));
1948+ gtk_window_set_default_icon_name ("gnome-power-manager");
1949+
1950+ /* Get the main window quit */
1951+ g_signal_connect (window, "delete-event",
1952+ G_CALLBACK (gpm_stats_delete_event_cb), application);
1953+
1954+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_close"));
1955+ g_signal_connect (widget, "clicked",
1956+ G_CALLBACK (gpm_stats_button_close_cb), application);
1957+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_close"));
1958+ gtk_widget_grab_default (widget);
1959+
1960+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_smooth_history"));
1961+ checked = g_settings_get_boolean (settings, GPM_SETTINGS_INFO_HISTORY_GRAPH_SMOOTH);
1962+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), checked);
1963+ g_signal_connect (widget, "clicked",
1964+ G_CALLBACK (gpm_stats_smooth_checkbox_history_cb), NULL);
1965+
1966+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_smooth_stats"));
1967+ checked = g_settings_get_boolean (settings, GPM_SETTINGS_INFO_STATS_GRAPH_SMOOTH);
1968+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), checked);
1969+ g_signal_connect (widget, "clicked",
1970+ G_CALLBACK (gpm_stats_smooth_checkbox_stats_cb), NULL);
1971+
1972+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_points_history"));
1973+ checked = g_settings_get_boolean (settings, GPM_SETTINGS_INFO_HISTORY_GRAPH_POINTS);
1974+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), checked);
1975+ g_signal_connect (widget, "clicked",
1976+ G_CALLBACK (gpm_stats_points_checkbox_history_cb), NULL);
1977+
1978+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_points_stats"));
1979+ checked = g_settings_get_boolean (settings, GPM_SETTINGS_INFO_STATS_GRAPH_POINTS);
1980+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), checked);
1981+ g_signal_connect (widget, "clicked",
1982+ G_CALLBACK (gpm_stats_points_checkbox_stats_cb), NULL);
1983+
1984+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "notebook1"));
1985+ page = g_settings_get_int (settings, GPM_SETTINGS_INFO_PAGE_NUMBER);
1986+ gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), page);
1987+ g_signal_connect (widget, "switch-page",
1988+ G_CALLBACK (gpm_stats_notebook_changed_cb), NULL);
1989+
1990+ /* create list stores */
1991+ list_store_info = gtk_list_store_new (GPM_INFO_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING);
1992+ list_store_devices = gtk_list_store_new (GPM_DEVICES_COLUMN_LAST, G_TYPE_ICON,
1993+ G_TYPE_STRING, G_TYPE_STRING);
1994+ list_store_wakeups = gtk_list_store_new (GPM_WAKEUPS_COLUMN_LAST, G_TYPE_STRING,
1995+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
1996+
1997+ /* create transaction_id tree view */
1998+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_info"));
1999+ gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
2000+ GTK_TREE_MODEL (list_store_info));
2001+
2002+ /* add columns to the tree view */
2003+ gpm_stats_add_info_columns (GTK_TREE_VIEW (widget));
2004+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget)); /* show */
2005+
2006+ /* create transaction_id tree view */
2007+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_devices"));
2008+ gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
2009+ GTK_TREE_MODEL (list_store_devices));
2010+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
2011+ g_signal_connect (selection, "changed",
2012+ G_CALLBACK (gpm_stats_devices_treeview_clicked_cb), NULL);
2013+
2014+ /* add columns to the tree view */
2015+ gpm_stats_add_devices_columns (GTK_TREE_VIEW (widget));
2016+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget)); /* show */
2017+
2018+ /* create wakeups tree view */
2019+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_wakeups"));
2020+ gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
2021+ GTK_TREE_MODEL (list_store_wakeups));
2022+
2023+ /* add columns to the tree view */
2024+ gpm_stats_add_wakeups_columns (GTK_TREE_VIEW (widget));
2025+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget)); /* show */
2026+
2027+ history_type = g_settings_get_string (settings, GPM_SETTINGS_INFO_HISTORY_TYPE);
2028+ history_time = g_settings_get_int (settings, GPM_SETTINGS_INFO_HISTORY_TIME);
2029+ if (history_type == NULL)
2030+ history_type = GPM_HISTORY_CHARGE_VALUE;
2031+ if (history_time == 0)
2032+ history_time = GPM_HISTORY_HOUR_VALUE;
2033+
2034+ stats_type = g_settings_get_string (settings, GPM_SETTINGS_INFO_STATS_TYPE);
2035+ if (stats_type == NULL)
2036+ stats_type = GPM_STATS_CHARGE_DATA_VALUE;
2037+
2038+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_history_type"));
2039+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_HISTORY_RATE_TEXT);
2040+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_HISTORY_CHARGE_TEXT);
2041+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_HISTORY_TIME_FULL_TEXT);
2042+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_HISTORY_TIME_EMPTY_TEXT);
2043+ if (g_strcmp0 (history_type, GPM_HISTORY_RATE_VALUE) == 0)
2044+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
2045+ else
2046+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
2047+ g_signal_connect (G_OBJECT (widget), "changed",
2048+ G_CALLBACK (gpm_stats_history_type_combo_changed_cb), NULL);
2049+
2050+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_stats_type"));
2051+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_STATS_CHARGE_DATA_TEXT);
2052+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_STATS_CHARGE_ACCURACY_TEXT);
2053+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_STATS_DISCHARGE_DATA_TEXT);
2054+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_STATS_DISCHARGE_ACCURACY_TEXT);
2055+ if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_DATA_VALUE) == 0)
2056+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
2057+ else if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_DATA_VALUE) == 0)
2058+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
2059+ else if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_DATA_VALUE) == 0)
2060+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
2061+ else if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_DATA_VALUE) == 0)
2062+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
2063+ else
2064+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 3);
2065+ g_signal_connect (G_OBJECT (widget), "changed",
2066+ G_CALLBACK (gpm_stats_type_combo_changed_cb), NULL);
2067+
2068+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_history_time"));
2069+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_HISTORY_MINUTE_TEXT);
2070+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_HISTORY_HOUR_TEXT);
2071+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_HISTORY_HOURS_TEXT);
2072+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_HISTORY_DAY_TEXT);
2073+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), GPM_HISTORY_WEEK_TEXT);
2074+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
2075+ if (history_time == GPM_HISTORY_MINUTE_VALUE)
2076+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
2077+ else if (history_time == GPM_HISTORY_HOUR_VALUE)
2078+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
2079+ else
2080+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
2081+ g_signal_connect (G_OBJECT (widget), "changed",
2082+ G_CALLBACK (gpm_stats_range_combo_changed), NULL);
2083+
2084+ wakeups = up_wakeups_new ();
2085+ g_signal_connect (wakeups, "data-changed", G_CALLBACK (gpm_stats_data_changed_cb), NULL);
2086+
2087+ /* coldplug */
2088+ client = up_client_new ();
2089+ ret = up_client_enumerate_devices_sync (client, NULL, NULL);
2090+ if (!ret)
2091+ goto out;
2092+ devices = up_client_get_devices (client);
2093+ g_signal_connect (client, "device-added", G_CALLBACK (gpm_stats_device_added_cb), NULL);
2094+ g_signal_connect (client, "device-removed", G_CALLBACK (gpm_stats_device_removed_cb), NULL);
2095+ g_signal_connect (client, "device-changed", G_CALLBACK (gpm_stats_device_changed_cb), NULL);
2096+
2097+ /* add devices in visually pleasing order */
2098+ for (j=0; j<UP_DEVICE_KIND_LAST; j++) {
2099+ for (i=0; i < devices->len; i++) {
2100+ device = g_ptr_array_index (devices, i);
2101+ g_object_get (device, "kind", &kind, NULL);
2102+ if (kind == j)
2103+ gpm_stats_add_device (device);
2104+ }
2105+ }
2106+
2107+ /* set current device */
2108+ if (devices->len > 0) {
2109+ device = g_ptr_array_index (devices, 0);
2110+ gpm_stats_update_info_data (device);
2111+ current_device = g_strdup (up_device_get_object_path (device));
2112+ }
2113+
2114+ /* has capability to measure wakeups */
2115+ ret = up_wakeups_get_has_capability (wakeups);
2116+ if (ret) {
2117+ GtkTreeIter iter;
2118+ GIcon *icon;
2119+ icon = g_themed_icon_new ("computer");
2120+ gtk_list_store_append (list_store_devices, &iter);
2121+ gtk_list_store_set (list_store_devices, &iter,
2122+ GPM_DEVICES_COLUMN_ID, "wakeups",
2123+ /* TRANSLATORS: the icon for the CPU */
2124+ GPM_DEVICES_COLUMN_TEXT, _("Processor"),
2125+ GPM_DEVICES_COLUMN_ICON, icon, -1);
2126+ g_object_unref (icon);
2127+ }
2128+
2129+ g_ptr_array_unref (devices);
2130+
2131+ /* set axis */
2132+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_history_type"));
2133+ gpm_stats_history_type_combo_changed_cb (widget, NULL);
2134+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_stats_type"));
2135+ gpm_stats_type_combo_changed_cb (widget, NULL);
2136+
2137+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_stats"));
2138+ gtk_widget_show (widget);
2139+out:
2140+ g_object_unref (client);
2141+}
2142+
2143+/**
2144+ * main:
2145+ **/
2146+int
2147+main (int argc, char *argv[])
2148+{
2149+ GtkApplication *application;
2150+ int status = 0;
2151+
2152+ setlocale (LC_ALL, "");
2153+
2154+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
2155+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
2156+ textdomain (GETTEXT_PACKAGE);
2157+
2158+ g_type_init ();
2159+
2160+ gtk_init (&argc, &argv);
2161+
2162+ /* get data from gconf */
2163+ settings = g_settings_new (GPM_SETTINGS_SCHEMA);
2164+
2165+ /* are we already activated? */
2166+ application = gtk_application_new ("org.gnome.PowerManager.Statistics",
2167+ G_APPLICATION_HANDLES_COMMAND_LINE);
2168+ g_signal_connect (application, "startup",
2169+ G_CALLBACK (gpm_stats_startup_cb), NULL);
2170+ g_signal_connect (application, "command-line",
2171+ G_CALLBACK (gpm_stats_commandline_cb), NULL);
2172+
2173+ /* add application specific icons to search path */
2174+ gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
2175+ GPM_DATA G_DIR_SEPARATOR_S "icons");
2176+
2177+ /* run */
2178+ status = g_application_run (G_APPLICATION (application), argc, argv);
2179+
2180+ g_object_unref (settings);
2181+ g_object_unref (application);
2182+ return status;
2183+}
2184
2185=== modified file '.pc/applied-patches'
2186--- .pc/applied-patches 2012-11-02 23:20:01 +0000
2187+++ .pc/applied-patches 2013-02-13 13:56:48 +0000
2188@@ -0,0 +1,1 @@
2189+923292-fix.patch
2190
2191=== modified file 'debian/changelog'
2192--- debian/changelog 2012-11-02 23:20:01 +0000
2193+++ debian/changelog 2013-02-13 13:56:48 +0000
2194@@ -1,3 +1,9 @@
2195+gnome-power-manager (3.6.0-1ubuntu1) precise; urgency=low
2196+
2197+ * Added key press event for ctrl+q
2198+
2199+ -- Dedunu Dhananjaya <admin@dedunu.info> Wed, 13 Feb 2013 16:38:30 +0530
2200+
2201 gnome-power-manager (3.6.0-1) experimental; urgency=low
2202
2203 * New upstream release
2204
2205=== added directory 'debian/patches'
2206=== added file 'debian/patches/923292-fix.patch'
2207--- debian/patches/923292-fix.patch 1970-01-01 00:00:00 +0000
2208+++ debian/patches/923292-fix.patch 2013-02-13 13:56:48 +0000
2209@@ -0,0 +1,57 @@
2210+Index: gnome-power-manager/src/gpm-statistics.c
2211+===================================================================
2212+--- gnome-power-manager.orig/src/gpm-statistics.c 2013-02-13 16:29:17.809998000 +0530
2213++++ gnome-power-manager/src/gpm-statistics.c 2013-02-13 19:05:41.410822950 +0530
2214+@@ -1831,6 +1831,41 @@
2215+ }
2216+
2217+ /**
2218++ * window_key_press_event:
2219++ **/
2220++static gboolean
2221++window_key_press_event (GtkWidget *win,
2222++ GdkEventKey *event,
2223++ GApplication *self)
2224++{
2225++ GdkKeymap *keymap;
2226++ gboolean retval;
2227++ GdkModifierType state;
2228++
2229++ if (event->state == 0)
2230++ return FALSE;
2231++
2232++ retval = FALSE;
2233++ state = event->state;
2234++ keymap = gdk_keymap_get_default ();
2235++ gdk_keymap_add_virtual_modifiers (keymap, &state);
2236++ state = state & gtk_accelerator_get_default_mod_mask ();
2237++
2238++ if (state == GDK_CONTROL_MASK)
2239++ {
2240++ switch (event->keyval)
2241++ {
2242++ case GDK_KEY_Q:
2243++ case GDK_KEY_q:
2244++ g_application_quit(self);
2245++ retval = TRUE;
2246++ break;
2247++ }
2248++ }
2249++ return retval;
2250++}
2251++
2252++/**
2253+ * gpm_stats_commandline_cb:
2254+ **/
2255+ static int
2256+@@ -1980,6 +2015,10 @@
2257+ g_signal_connect (widget, "switch-page",
2258+ G_CALLBACK (gpm_stats_notebook_changed_cb), NULL);
2259+
2260++ /* listen to signal of keys */
2261++ g_signal_connect_after (window, "key_press_event",
2262++ G_CALLBACK (window_key_press_event), application);
2263++
2264+ /* create list stores */
2265+ list_store_info = gtk_list_store_new (GPM_INFO_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING);
2266+ list_store_devices = gtk_list_store_new (GPM_DEVICES_COLUMN_LAST, G_TYPE_ICON,
2267
2268=== added file 'debian/patches/series'
2269--- debian/patches/series 1970-01-01 00:00:00 +0000
2270+++ debian/patches/series 2013-02-13 13:56:48 +0000
2271@@ -0,0 +1,1 @@
2272+923292-fix.patch
2273
2274=== modified file 'src/gpm-statistics.c'
2275--- src/gpm-statistics.c 2012-11-02 23:20:01 +0000
2276+++ src/gpm-statistics.c 2013-02-13 13:56:48 +0000
2277@@ -1831,6 +1831,41 @@
2278 }
2279
2280 /**
2281+ * window_key_press_event:
2282+ **/
2283+static gboolean
2284+window_key_press_event (GtkWidget *win,
2285+ GdkEventKey *event,
2286+ GApplication *self)
2287+{
2288+ GdkKeymap *keymap;
2289+ gboolean retval;
2290+ GdkModifierType state;
2291+
2292+ if (event->state == 0)
2293+ return FALSE;
2294+
2295+ retval = FALSE;
2296+ state = event->state;
2297+ keymap = gdk_keymap_get_default ();
2298+ gdk_keymap_add_virtual_modifiers (keymap, &state);
2299+ state = state & gtk_accelerator_get_default_mod_mask ();
2300+
2301+ if (state == GDK_CONTROL_MASK)
2302+ {
2303+ switch (event->keyval)
2304+ {
2305+ case GDK_KEY_Q:
2306+ case GDK_KEY_q:
2307+ g_application_quit(self);
2308+ retval = TRUE;
2309+ break;
2310+ }
2311+ }
2312+ return retval;
2313+}
2314+
2315+/**
2316 * gpm_stats_commandline_cb:
2317 **/
2318 static int
2319@@ -1980,6 +2015,10 @@
2320 g_signal_connect (widget, "switch-page",
2321 G_CALLBACK (gpm_stats_notebook_changed_cb), NULL);
2322
2323+ /* listen to signal of keys */
2324+ g_signal_connect_after (window, "key_press_event",
2325+ G_CALLBACK (window_key_press_event), application);
2326+
2327 /* create list stores */
2328 list_store_info = gtk_list_store_new (GPM_INFO_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING);
2329 list_store_devices = gtk_list_store_new (GPM_DEVICES_COLUMN_LAST, G_TYPE_ICON,

Subscribers

People subscribed via source and target branches