~ubuntu-desktop/indicator-power/ubuntu

« back to all changes in this revision

Viewing changes to src/device.c

  • Committer: Sebastien Bacher
  • Date: 2012-07-11 19:46:25 UTC
  • mfrom: (67.1.14)
  • Revision ID: seb128@ubuntu.com-20120711194625-jag33fim95b6qle4
* New upstream release.
* debian/control: updated glib requirement

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
A simple Device structure used internally by indicator-power
 
4
 
 
5
Copyright 2012 Canonical Ltd.
 
6
 
 
7
Authors:
 
8
    Charles Kerr <charles.kerr@canonical.com>
 
9
 
 
10
This library is free software; you can redistribute it and/or
 
11
modify it under the terms of the GNU General Public License
 
12
version 3.0 as published by the Free Software Foundation.
 
13
 
 
14
This library is distributed in the hope that it will be useful,
 
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
GNU General Public License version 3.0 for more details.
 
18
 
 
19
You should have received a copy of the GNU General Public
 
20
License along with this library. If not, see
 
21
<http://www.gnu.org/licenses/>.
 
22
*/
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
 #include "config.h"
 
26
#endif
 
27
 
 
28
#include <glib/gi18n.h>
 
29
 
 
30
#include "device.h"
 
31
 
 
32
struct _IndicatorPowerDevicePrivate
 
33
{
 
34
  UpDeviceKind kind;
 
35
  UpDeviceState state;
 
36
  gchar * object_path;
 
37
  gdouble percentage;
 
38
  time_t time;
 
39
};
 
40
 
 
41
#define INDICATOR_POWER_DEVICE_GET_PRIVATE(o) (INDICATOR_POWER_DEVICE(o)->priv)
 
42
 
 
43
/* Properties */
 
44
/* Enum for the properties so that they can be quickly found and looked up. */
 
45
enum {
 
46
  PROP_0,
 
47
  PROP_KIND,
 
48
  PROP_STATE,
 
49
  PROP_OBJECT_PATH,
 
50
  PROP_PERCENTAGE,
 
51
  PROP_TIME,
 
52
  N_PROPERTIES
 
53
};
 
54
 
 
55
static GParamSpec * properties[N_PROPERTIES];
 
56
 
 
57
/* GObject stuff */
 
58
static void indicator_power_device_class_init (IndicatorPowerDeviceClass *klass);
 
59
static void indicator_power_device_init       (IndicatorPowerDevice *self);
 
60
static void indicator_power_device_dispose    (GObject *object);
 
61
static void indicator_power_device_finalize   (GObject *object);
 
62
static void set_property (GObject*, guint prop_id, const GValue*, GParamSpec* );
 
63
static void get_property (GObject*, guint prop_id,       GValue*, GParamSpec* );
 
64
 
 
65
/* LCOV_EXCL_START */
 
66
G_DEFINE_TYPE (IndicatorPowerDevice, indicator_power_device, G_TYPE_OBJECT);
 
67
/* LCOV_EXCL_STOP */
 
68
 
 
69
static void
 
70
indicator_power_device_class_init (IndicatorPowerDeviceClass *klass)
 
71
{
 
72
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
73
 
 
74
  g_type_class_add_private (klass, sizeof (IndicatorPowerDevicePrivate));
 
75
 
 
76
  object_class->dispose = indicator_power_device_dispose;
 
77
  object_class->finalize = indicator_power_device_finalize;
 
78
  object_class->set_property = set_property;
 
79
  object_class->get_property = get_property;
 
80
 
 
81
  properties[PROP_KIND] = g_param_spec_int (INDICATOR_POWER_DEVICE_KIND,
 
82
                                            "kind",
 
83
                                            "The device's UpDeviceKind",
 
84
                                            UP_DEVICE_KIND_UNKNOWN, UP_DEVICE_KIND_LAST,
 
85
                                            UP_DEVICE_KIND_UNKNOWN,
 
86
                                            G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
87
 
 
88
  properties[PROP_STATE] = g_param_spec_int (INDICATOR_POWER_DEVICE_STATE,
 
89
                                             "state",
 
90
                                             "The device's UpDeviceState",
 
91
                                             UP_DEVICE_STATE_UNKNOWN, UP_DEVICE_STATE_LAST,
 
92
                                             UP_DEVICE_STATE_UNKNOWN,
 
93
                                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
94
 
 
95
  properties[PROP_OBJECT_PATH] = g_param_spec_string (INDICATOR_POWER_DEVICE_OBJECT_PATH,
 
96
                                                      "object path",
 
97
                                                      "The device's DBus object path",
 
98
                                                      NULL,
 
99
                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
100
 
 
101
  properties[PROP_PERCENTAGE] = g_param_spec_double (INDICATOR_POWER_DEVICE_PERCENTAGE,
 
102
                                                     "percentage",
 
103
                                                     "percent charged",
 
104
                                                     0.0, 100.0,
 
105
                                                     0.0,
 
106
                                                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
107
 
 
108
  properties[PROP_TIME] = g_param_spec_uint64 (INDICATOR_POWER_DEVICE_TIME,
 
109
                                               "time",
 
110
                                               "time left",
 
111
                                               0, G_MAXUINT64,
 
112
                                               0,
 
113
                                               G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
114
 
 
115
  g_object_class_install_properties (object_class, N_PROPERTIES, properties);
 
116
}
 
117
 
 
118
/* Initialize an instance */
 
119
static void
 
120
indicator_power_device_init (IndicatorPowerDevice *self)
 
121
{
 
122
  IndicatorPowerDevicePrivate * priv;
 
123
 
 
124
  priv = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_POWER_DEVICE_TYPE,
 
125
                                            IndicatorPowerDevicePrivate);
 
126
  priv->kind = UP_DEVICE_KIND_UNKNOWN;
 
127
  priv->state = UP_DEVICE_STATE_UNKNOWN;
 
128
  priv->object_path = NULL;
 
129
  priv->percentage = 0.0;
 
130
  priv->time = 0;
 
131
 
 
132
  self->priv = priv;
 
133
}
 
134
 
 
135
static void
 
136
indicator_power_device_dispose (GObject *object)
 
137
{
 
138
  G_OBJECT_CLASS (indicator_power_device_parent_class)->dispose (object);
 
139
}
 
140
 
 
141
static void
 
142
indicator_power_device_finalize (GObject *object)
 
143
{
 
144
  IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(object);
 
145
  IndicatorPowerDevicePrivate * priv = self->priv;
 
146
 
 
147
  g_clear_pointer (&priv->object_path, g_free);
 
148
 
 
149
  G_OBJECT_CLASS (indicator_power_device_parent_class)->finalize (object);
 
150
}
 
151
 
 
152
/***
 
153
****
 
154
***/
 
155
 
 
156
static void
 
157
get_property (GObject * o, guint  prop_id, GValue * value, GParamSpec * pspec)
 
158
{
 
159
  IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(o);
 
160
  IndicatorPowerDevicePrivate * priv = self->priv;
 
161
 
 
162
  switch (prop_id)
 
163
    {
 
164
      case PROP_KIND:
 
165
        g_value_set_int (value, priv->kind);
 
166
        break;
 
167
 
 
168
      case PROP_STATE:
 
169
        g_value_set_int (value, priv->state);
 
170
        break;
 
171
 
 
172
      case PROP_OBJECT_PATH:
 
173
        g_value_set_string (value, priv->object_path);
 
174
        break;
 
175
 
 
176
      case PROP_PERCENTAGE:
 
177
        g_value_set_double (value, priv->percentage);
 
178
        break;
 
179
 
 
180
      case PROP_TIME:
 
181
        g_value_set_uint64 (value, priv->time);
 
182
        break;
 
183
 
 
184
      default:
 
185
        G_OBJECT_WARN_INVALID_PROPERTY_ID(o, prop_id, pspec);
 
186
        break;
 
187
    }
 
188
}
 
189
 
 
190
static void
 
191
set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * pspec)
 
192
{
 
193
  IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(o);
 
194
  IndicatorPowerDevicePrivate * priv = self->priv;
 
195
 
 
196
  switch (prop_id)
 
197
    {
 
198
      case PROP_KIND:
 
199
        priv->kind = g_value_get_int (value);
 
200
        break;
 
201
 
 
202
      case PROP_STATE:
 
203
        priv->state = g_value_get_int (value);
 
204
        break;
 
205
 
 
206
      case PROP_OBJECT_PATH:
 
207
        g_free (priv->object_path);
 
208
        priv->object_path = g_value_dup_string (value);
 
209
        break;
 
210
 
 
211
      case PROP_PERCENTAGE:
 
212
        priv->percentage = g_value_get_double (value);
 
213
        break;
 
214
 
 
215
      case PROP_TIME:
 
216
        priv->time = g_value_get_uint64(value);
 
217
        break;
 
218
 
 
219
      default:
 
220
        G_OBJECT_WARN_INVALID_PROPERTY_ID(o, prop_id, pspec);
 
221
        break;
 
222
    }
 
223
}
 
224
 
 
225
/***
 
226
****  Accessors
 
227
***/
 
228
 
 
229
UpDeviceKind
 
230
indicator_power_device_get_kind  (const IndicatorPowerDevice * device)
 
231
{
 
232
  /* LCOV_EXCL_START */
 
233
  g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), UP_DEVICE_KIND_UNKNOWN);
 
234
  /* LCOV_EXCL_STOP */
 
235
 
 
236
  return device->priv->kind;
 
237
}
 
238
 
 
239
UpDeviceState
 
240
indicator_power_device_get_state (const IndicatorPowerDevice * device)
 
241
{
 
242
  /* LCOV_EXCL_START */
 
243
  g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), UP_DEVICE_STATE_UNKNOWN);
 
244
  /* LCOV_EXCL_STOP */
 
245
 
 
246
  return device->priv->state;
 
247
}
 
248
 
 
249
const gchar *
 
250
indicator_power_device_get_object_path (const IndicatorPowerDevice * device)
 
251
{
 
252
  /* LCOV_EXCL_START */
 
253
  g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), NULL);
 
254
  /* LCOV_EXCL_STOP */
 
255
 
 
256
  return device->priv->object_path;
 
257
}
 
258
 
 
259
gdouble
 
260
indicator_power_device_get_percentage (const IndicatorPowerDevice * device)
 
261
{
 
262
  /* LCOV_EXCL_START */
 
263
  g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), 0.0);
 
264
  /* LCOV_EXCL_STOP */
 
265
 
 
266
  return device->priv->percentage;
 
267
}
 
268
 
 
269
time_t
 
270
indicator_power_device_get_time (const IndicatorPowerDevice * device)
 
271
{
 
272
  /* LCOV_EXCL_START */
 
273
  g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), (time_t)0);
 
274
  /* LCOV_EXCL_STOP */
 
275
 
 
276
  return device->priv->time;
 
277
}
 
278
 
 
279
/***
 
280
****
 
281
****
 
282
***/
 
283
 
 
284
static const gchar *
 
285
get_device_icon_suffix (gdouble percentage)
 
286
{
 
287
  if (percentage >= 60) return "full";
 
288
  if (percentage >= 30) return "good";
 
289
  if (percentage >= 10) return "low";
 
290
  return "caution";
 
291
}
 
292
 
 
293
static const gchar *
 
294
get_device_icon_index (gdouble percentage)
 
295
{
 
296
  if (percentage >= 90) return "100";
 
297
  if (percentage >= 70) return "080";
 
298
  if (percentage >= 50) return "060";
 
299
  if (percentage >= 30) return "040";
 
300
  if (percentage >= 10) return "020";
 
301
  return "000";
 
302
}
 
303
 
 
304
/**
 
305
  indicator_power_device_get_icon_names:
 
306
  @device: #IndicatorPowerDevice from which to generate the icon names
 
307
 
 
308
  This function's logic differs from GSD's power plugin in some ways:
 
309
 
 
310
  1. All charging batteries use the same icon regardless of progress.
 
311
  <https://bugs.launchpad.net/indicator-power/+bug/824629/comments/7>
 
312
 
 
313
  2. For discharging batteries, we decide whether or not to use the 'caution'
 
314
  icon based on whether or not we have <= 30 minutes remaining, rather than
 
315
  looking at the battery's percentage left.
 
316
  <https://bugs.launchpad.net/indicator-power/+bug/743823>
 
317
 
 
318
  See also indicator_power_device_get_gicon().
 
319
 
 
320
  Return value: (array zero-terminated=1) (transfer full):
 
321
  A GStrv of icon names suitable for passing to g_themed_icon_new_from_names().
 
322
  Free with g_strfreev() when done.
 
323
*/
 
324
GStrv
 
325
indicator_power_device_get_icon_names (const IndicatorPowerDevice * device)
 
326
{
 
327
  const gchar *suffix_str;
 
328
  const gchar *index_str;
 
329
 
 
330
  /* LCOV_EXCL_START */
 
331
  g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), NULL);
 
332
  /* LCOV_EXCL_STOP */
 
333
 
 
334
  gdouble percentage = indicator_power_device_get_percentage (device);
 
335
  const UpDeviceKind kind = indicator_power_device_get_kind (device);
 
336
  const UpDeviceState state = indicator_power_device_get_state (device);
 
337
  const gchar * kind_str = kind_str = up_device_kind_to_string (kind);
 
338
 
 
339
  GPtrArray * names = g_ptr_array_new ();
 
340
 
 
341
  if (kind == UP_DEVICE_KIND_LINE_POWER)
 
342
    {
 
343
      g_ptr_array_add (names, g_strdup("ac-adapter-symbolic"));
 
344
      g_ptr_array_add (names, g_strdup("ac-adapter"));
 
345
    }
 
346
  else if (kind == UP_DEVICE_KIND_MONITOR)
 
347
    {
 
348
      g_ptr_array_add (names, g_strdup("gpm-monitor-symbolic"));
 
349
      g_ptr_array_add (names, g_strdup("gpm-monitor"));
 
350
    }
 
351
  else switch (state)
 
352
    {
 
353
      case UP_DEVICE_STATE_EMPTY:
 
354
        g_ptr_array_add (names, g_strdup("battery-empty-symbolic"));
 
355
        g_ptr_array_add (names, g_strdup_printf("gpm-%s-empty", kind_str));
 
356
        g_ptr_array_add (names, g_strdup_printf("gpm-%s-000", kind_str));
 
357
        g_ptr_array_add (names, g_strdup("battery-empty"));
 
358
        break;
 
359
 
 
360
      case UP_DEVICE_STATE_FULLY_CHARGED:
 
361
        g_ptr_array_add (names, g_strdup("battery-full-charged-symbolic"));
 
362
        g_ptr_array_add (names, g_strdup("battery-full-charging-symbolic"));
 
363
        g_ptr_array_add (names, g_strdup_printf("gpm-%s-full", kind_str));
 
364
        g_ptr_array_add (names, g_strdup_printf("gpm-%s-100", kind_str));
 
365
        g_ptr_array_add (names, g_strdup("battery-full-charged"));
 
366
        g_ptr_array_add (names, g_strdup("battery-full-charging"));
 
367
        break;
 
368
 
 
369
      case UP_DEVICE_STATE_CHARGING:
 
370
      case UP_DEVICE_STATE_PENDING_CHARGE:
 
371
        /* When charging, always use the same icon regardless of percentage.
 
372
           <http://bugs.launchpad.net/indicator-power/+bug/824629> */
 
373
        percentage = 0;
 
374
 
 
375
        suffix_str = get_device_icon_suffix (percentage);
 
376
        index_str = get_device_icon_index (percentage);
 
377
        g_ptr_array_add (names, g_strdup_printf ("battery-%s-charging-symbolic", suffix_str));
 
378
        g_ptr_array_add (names, g_strdup_printf ("gpm-%s-%s-charging", kind_str, index_str));
 
379
        g_ptr_array_add (names, g_strdup_printf ("battery-%s-charging", suffix_str));
 
380
        break;
 
381
 
 
382
      case UP_DEVICE_STATE_DISCHARGING:
 
383
      case UP_DEVICE_STATE_PENDING_DISCHARGE:
 
384
        /* Don't show the caution/red icons unless we have <=30 min left.
 
385
           <https://bugs.launchpad.net/indicator-power/+bug/743823>
 
386
           Themes use the caution color when the percentage is 0% or 20%,
 
387
           so if we have >30 min left, use 30% as the icon's percentage floor */
 
388
        if (indicator_power_device_get_time (device) > (30*60))
 
389
          percentage = MAX(percentage, 30);
 
390
 
 
391
        suffix_str = get_device_icon_suffix (percentage);
 
392
        index_str = get_device_icon_index (percentage);
 
393
        g_ptr_array_add (names, g_strdup_printf ("battery-%s-symbolic", suffix_str));
 
394
        g_ptr_array_add (names, g_strdup_printf ("gpm-%s-%s", kind_str, index_str));
 
395
        g_ptr_array_add (names, g_strdup_printf ("battery-%s", suffix_str));
 
396
        break;
 
397
 
 
398
      default:
 
399
        g_ptr_array_add (names, g_strdup("battery-missing-symbolic"));
 
400
        g_ptr_array_add (names, g_strdup("gpm-battery-missing"));
 
401
        g_ptr_array_add (names, g_strdup("battery-missing"));
 
402
    }
 
403
 
 
404
    g_ptr_array_add (names, NULL); /* terminates the strv */
 
405
    return (GStrv) g_ptr_array_free (names, FALSE);
 
406
}
 
407
 
 
408
/**
 
409
  indicator_power_device_get_gicon:
 
410
  @device: #IndicatorPowerDevice to generate the icon names from
 
411
 
 
412
  A convenience function to call g_themed_icon_new_from_names()
 
413
  with the names returned by indicator_power_device_get_icon_names()
 
414
 
 
415
  Return value: (transfer full): A themed GIcon
 
416
*/
 
417
GIcon *
 
418
indicator_power_device_get_gicon (const IndicatorPowerDevice * device)
 
419
{
 
420
  GStrv names = indicator_power_device_get_icon_names (device);
 
421
  GIcon * icon = g_themed_icon_new_from_names (names, -1);
 
422
  g_strfreev (names);
 
423
  return icon;
 
424
}
 
425
 
 
426
/***
 
427
****
 
428
***/
 
429
 
 
430
static void
 
431
get_timestring (guint64   time_secs,
 
432
                gchar   **short_timestring,
 
433
                gchar   **detailed_timestring)
 
434
{
 
435
  gint  hours;
 
436
  gint  minutes;
 
437
 
 
438
  /* Add 0.5 to do rounding */
 
439
  minutes = (int) ( ( time_secs / 60.0 ) + 0.5 );
 
440
 
 
441
  if (minutes == 0)
 
442
    {
 
443
      *short_timestring = g_strdup (_("Unknown time"));
 
444
      *detailed_timestring = g_strdup (_("Unknown time"));
 
445
 
 
446
      return;
 
447
    }
 
448
 
 
449
  if (minutes < 60)
 
450
    {
 
451
      *short_timestring = g_strdup_printf ("0:%.2i", minutes);
 
452
      *detailed_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%i minute",
 
453
                                              "%i minutes",
 
454
                                              minutes), minutes);
 
455
      return;
 
456
    }
 
457
 
 
458
  hours = minutes / 60;
 
459
  minutes = minutes % 60;
 
460
 
 
461
  *short_timestring = g_strdup_printf ("%i:%.2i", hours, minutes);
 
462
 
 
463
  if (minutes == 0)
 
464
    {
 
465
      *detailed_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, 
 
466
                                              "%i hour",
 
467
                                              "%i hours",
 
468
                                              hours), hours);
 
469
    }
 
470
  else
 
471
    {
 
472
      /* TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes"
 
473
       * Swap order with "%2$s %2$i %1$s %1$i if needed */
 
474
      *detailed_timestring = g_strdup_printf (_("%i %s %i %s"),
 
475
                                              hours, g_dngettext (GETTEXT_PACKAGE, "hour", "hours", hours),
 
476
                                              minutes, g_dngettext (GETTEXT_PACKAGE, "minute", "minutes", minutes));
 
477
    }
 
478
}
 
479
 
 
480
static const gchar *
 
481
device_kind_to_localised_string (UpDeviceKind kind)
 
482
{
 
483
  const gchar *text = NULL;
 
484
 
 
485
  switch (kind) {
 
486
    case UP_DEVICE_KIND_LINE_POWER:
 
487
      /* TRANSLATORS: system power cord */
 
488
      text = _("AC Adapter");
 
489
      break;
 
490
    case UP_DEVICE_KIND_BATTERY:
 
491
      /* TRANSLATORS: laptop primary battery */
 
492
      text = _("Battery");
 
493
      break;
 
494
    case UP_DEVICE_KIND_UPS:
 
495
      /* TRANSLATORS: battery-backed AC power source */
 
496
      text = _("UPS");
 
497
      break;
 
498
    case UP_DEVICE_KIND_MONITOR:
 
499
      /* TRANSLATORS: a monitor is a device to measure voltage and current */
 
500
      text = _("Monitor");
 
501
      break;
 
502
    case UP_DEVICE_KIND_MOUSE:
 
503
      /* TRANSLATORS: wireless mice with internal batteries */
 
504
      text = _("Mouse");
 
505
      break;
 
506
    case UP_DEVICE_KIND_KEYBOARD:
 
507
      /* TRANSLATORS: wireless keyboard with internal battery */
 
508
      text = _("Keyboard");
 
509
      break;
 
510
    case UP_DEVICE_KIND_PDA:
 
511
      /* TRANSLATORS: portable device */
 
512
      text = _("PDA");
 
513
      break;
 
514
    case UP_DEVICE_KIND_PHONE:
 
515
      /* TRANSLATORS: cell phone (mobile...) */
 
516
      text = _("Cell phone");
 
517
      break;
 
518
    case UP_DEVICE_KIND_MEDIA_PLAYER:
 
519
      /* TRANSLATORS: media player, mp3 etc */
 
520
      text = _("Media player");
 
521
      break;
 
522
    case UP_DEVICE_KIND_TABLET:
 
523
      /* TRANSLATORS: tablet device */
 
524
      text = _("Tablet");
 
525
      break;
 
526
    case UP_DEVICE_KIND_COMPUTER:
 
527
      /* TRANSLATORS: tablet device */
 
528
      text = _("Computer");
 
529
      break;
 
530
    default:
 
531
      g_warning ("enum unrecognised: %i", kind);
 
532
      text = up_device_kind_to_string (kind);
 
533
    }
 
534
 
 
535
  return text;
 
536
}
 
537
 
 
538
void
 
539
indicator_power_device_get_time_details (const IndicatorPowerDevice * device,
 
540
                                         gchar ** short_details,
 
541
                                         gchar ** details,
 
542
                                         gchar ** accessible_name)
 
543
{
 
544
  if (!INDICATOR_IS_POWER_DEVICE(device))
 
545
    {
 
546
      *short_details = NULL;
 
547
      *details = NULL;
 
548
      *accessible_name = NULL;
 
549
      g_warning ("%s: %p is not an IndicatorPowerDevice", G_STRFUNC, device);
 
550
      return;
 
551
    }
 
552
 
 
553
  const time_t time = indicator_power_device_get_time (device);
 
554
  const UpDeviceState state = indicator_power_device_get_state (device);
 
555
  const gdouble percentage = indicator_power_device_get_percentage (device);
 
556
  const UpDeviceKind kind = indicator_power_device_get_kind (device);
 
557
  const gchar * device_name = device_kind_to_localised_string (kind);
 
558
 
 
559
  if (time > 0)
 
560
    {
 
561
      gchar *short_timestring = NULL;
 
562
      gchar *detailed_timestring = NULL;
 
563
 
 
564
      get_timestring (time,
 
565
                      &short_timestring,
 
566
                      &detailed_timestring);
 
567
 
 
568
      if (state == UP_DEVICE_STATE_CHARGING)
 
569
        {
 
570
          /* TRANSLATORS: %2 is a time string, e.g. "1 hour 5 minutes" */
 
571
          *accessible_name = g_strdup_printf (_("%s (%s to charge (%.0lf%%))"), device_name, detailed_timestring, percentage);
 
572
          *details = g_strdup_printf (_("%s (%s to charge)"), device_name, short_timestring);
 
573
          *short_details = g_strdup_printf ("(%s)", short_timestring);
 
574
        }
 
575
      else if ((state == UP_DEVICE_STATE_DISCHARGING) && (time > (60*60*12)))
 
576
        {
 
577
          *accessible_name = g_strdup_printf (_("%s"), device_name);
 
578
          *details = g_strdup_printf (_("%s"), device_name);
 
579
          *short_details = g_strdup (short_timestring);
 
580
        }
 
581
      else
 
582
        {
 
583
          /* TRANSLATORS: %2 is a time string, e.g. "1 hour 5 minutes" */
 
584
          *accessible_name = g_strdup_printf (_("%s (%s left (%.0lf%%))"), device_name, detailed_timestring, percentage);
 
585
          *details = g_strdup_printf (_("%s (%s left)"), device_name, short_timestring);
 
586
          *short_details = g_strdup (short_timestring);
 
587
        }
 
588
 
 
589
      g_free (short_timestring);
 
590
      g_free (detailed_timestring);
 
591
    }
 
592
  else if (state == UP_DEVICE_STATE_FULLY_CHARGED)
 
593
    {
 
594
      *details = g_strdup_printf (_("%s (charged)"), device_name);
 
595
      *accessible_name = g_strdup (*details);
 
596
      *short_details = g_strdup ("");
 
597
    }
 
598
  else if (percentage > 0)
 
599
    {
 
600
      /* TRANSLATORS: %2 is a percentage value. Note: this string is only
 
601
       * used when we don't have a time value */
 
602
      *details = g_strdup_printf (_("%s (%.0lf%%)"), device_name, percentage);
 
603
      *accessible_name = g_strdup (*details);
 
604
      *short_details = g_strdup_printf (_("(%.0lf%%)"), percentage);
 
605
    }
 
606
  else if (kind == UP_DEVICE_KIND_LINE_POWER)
 
607
    {
 
608
      *details         = g_strdup (device_name);
 
609
      *accessible_name = g_strdup (device_name);
 
610
      *short_details   = g_strdup (device_name);
 
611
    }
 
612
  else
 
613
    {
 
614
      *details = g_strdup_printf (_("%s (not present)"), device_name);
 
615
      *accessible_name = g_strdup (*details);
 
616
      *short_details = g_strdup (_("(not present)"));
 
617
    }
 
618
}
 
619
 
 
620
/***
 
621
****  Instantiation
 
622
***/
 
623
 
 
624
IndicatorPowerDevice *
 
625
indicator_power_device_new (const gchar * object_path,
 
626
                            UpDeviceKind  kind,
 
627
                            gdouble percentage,
 
628
                            UpDeviceState state,
 
629
                            time_t timestamp)
 
630
{
 
631
  GObject * o = g_object_new (INDICATOR_POWER_DEVICE_TYPE,
 
632
    INDICATOR_POWER_DEVICE_KIND, kind,
 
633
    INDICATOR_POWER_DEVICE_STATE, state,
 
634
    INDICATOR_POWER_DEVICE_OBJECT_PATH, object_path,
 
635
    INDICATOR_POWER_DEVICE_PERCENTAGE, percentage,
 
636
    INDICATOR_POWER_DEVICE_TIME, (guint64)timestamp,
 
637
    NULL);
 
638
  return INDICATOR_POWER_DEVICE(o);
 
639
}
 
640
 
 
641
IndicatorPowerDevice *
 
642
indicator_power_device_new_from_variant (GVariant * v)
 
643
{
 
644
  g_return_val_if_fail (g_variant_is_of_type (v, G_VARIANT_TYPE("(susdut)")), NULL);
 
645
 
 
646
  UpDeviceKind kind = UP_DEVICE_KIND_UNKNOWN;
 
647
  UpDeviceState state = UP_DEVICE_STATE_UNKNOWN;
 
648
  const gchar * icon = NULL;
 
649
  const gchar * object_path = NULL;
 
650
  gdouble percentage = 0;
 
651
  guint64 time = 0;
 
652
 
 
653
  g_variant_get (v, "(&su&sdut)",
 
654
                 &object_path,
 
655
                 &kind,
 
656
                 &icon,
 
657
                 &percentage,
 
658
                 &state,
 
659
                 &time);
 
660
 
 
661
  return indicator_power_device_new (object_path,
 
662
                                     kind,
 
663
                                     percentage,
 
664
                                     state,
 
665
                                     time);
 
666
}