LCOV - code coverage report
Current view: top level - src/plugins/battery - valent-battery-gadget.c (source / functions) Hit Total Coverage
Test: Code Coverage Lines: 79 83 95.2 %
Date: 2023-06-06 02:20:50 Functions: 8 8 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 24 36 66.7 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-3.0-or-later
       2                 :            : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
       3                 :            : 
       4                 :            : #define G_LOG_DOMAIN "valent-battery-gadget"
       5                 :            : 
       6                 :            : #include "config.h"
       7                 :            : 
       8                 :            : #include <math.h>
       9                 :            : 
      10                 :            : #include <gtk/gtk.h>
      11                 :            : #include <glib/gi18n.h>
      12                 :            : #include <valent.h>
      13                 :            : 
      14                 :            : #include "valent-battery-gadget.h"
      15                 :            : 
      16                 :            : 
      17                 :            : struct _ValentBatteryGadget
      18                 :            : {
      19                 :            :   ValentDeviceGadget  parent_instance;
      20                 :            : 
      21                 :            :   GtkWidget          *button;
      22                 :            :   GtkWidget          *level_bar;
      23                 :            :   GtkWidget          *label;
      24                 :            : };
      25                 :            : 
      26   [ +  +  +  - ]:         20 : G_DEFINE_FINAL_TYPE (ValentBatteryGadget, valent_battery_gadget, VALENT_TYPE_DEVICE_GADGET)
      27                 :            : 
      28                 :            : 
      29                 :            : static void
      30                 :         11 : on_action_state_changed (GActionGroup        *action_group,
      31                 :            :                          const char          *action_name,
      32                 :            :                          GVariant            *value,
      33                 :            :                          ValentBatteryGadget *self)
      34                 :            : {
      35                 :         11 :   g_autofree char *label = NULL;
      36                 :         11 :   gboolean charging = FALSE;
      37                 :         11 :   gboolean is_present = FALSE;
      38                 :         11 :   double percentage = 0.0;
      39                 :         11 :   const char *icon_name;
      40                 :            : 
      41         [ +  - ]:         11 :   g_assert (VALENT_IS_BATTERY_GADGET (self));
      42                 :            : 
      43                 :         11 :   g_variant_lookup (value, "is-present", "b", &is_present);
      44                 :            : 
      45         [ +  + ]:         11 :   if (!is_present)
      46                 :            :     {
      47                 :          1 :       gtk_widget_set_visible (self->button, FALSE);
      48                 :          1 :       return;
      49                 :            :     }
      50                 :            : 
      51   [ +  -  -  + ]:         20 :   if (!g_variant_lookup (value, "percentage", "d", &percentage) ||
      52                 :         10 :       !g_variant_lookup (value, "charging", "b", &charging))
      53                 :            :     {
      54                 :          0 :       gtk_widget_set_visible (self->button, FALSE);
      55                 :          0 :       return;
      56                 :            :     }
      57                 :            : 
      58         [ -  + ]:         10 :   if (!g_variant_lookup (value, "icon-name", "&s", &icon_name))
      59                 :          0 :     icon_name = "battery-missing-symbolic";
      60                 :            : 
      61         [ +  + ]:         10 :   if (percentage >= 100.0)
      62                 :            :     {
      63                 :            :       /* TRANSLATORS: When the battery level is 100% */
      64         [ -  + ]:          1 :       label = g_strdup (_("Fully Charged"));
      65                 :            :     }
      66                 :            :   else
      67                 :            :     {
      68                 :          9 :       int64_t total_seconds = 0;
      69                 :          9 :       int64_t total_minutes;
      70                 :          9 :       int minutes;
      71                 :          9 :       int hours;
      72                 :            : 
      73         [ +  + ]:          9 :       if (charging)
      74                 :          5 :         g_variant_lookup (value, "time-to-full", "x", &total_seconds);
      75                 :            :       else
      76                 :          4 :         g_variant_lookup (value, "time-to-empty", "x", &total_seconds);
      77                 :            : 
      78         [ +  - ]:          9 :       if (total_seconds > 0)
      79                 :            :         {
      80                 :          9 :           total_minutes = floor (total_seconds / 60);
      81                 :          9 :           minutes = total_minutes % 60;
      82                 :          9 :           hours = floor (total_minutes / 60);
      83                 :            :         }
      84                 :            : 
      85         [ -  + ]:          9 :       if (total_seconds <= 0)
      86                 :            :         {
      87                 :            :           /* TRANSLATORS: This is <percentage> (Estimating…) */
      88                 :          0 :           label = g_strdup_printf (_("%g%% (Estimating…)"), percentage);
      89                 :            :         }
      90         [ +  + ]:          9 :       else if (charging)
      91                 :            :         {
      92                 :            :           /* TRANSLATORS: This is <percentage> (<hours>:<minutes> Until Full) */
      93                 :          5 :           label = g_strdup_printf (_("%g%% (%d∶%02d Until Full)"),
      94                 :            :                                    percentage, hours, minutes);
      95                 :            :         }
      96                 :            :       else
      97                 :            :         {
      98                 :            :           /* TRANSLATORS: This is <percentage> (<hours>:<minutes> Remaining) */
      99                 :          4 :           label = g_strdup_printf (_("%g%% (%d∶%02d Remaining)"),
     100                 :            :                                    percentage, hours, minutes);
     101                 :            :         }
     102                 :            :     }
     103                 :            : 
     104                 :         10 :   gtk_menu_button_set_icon_name (GTK_MENU_BUTTON (self->button), icon_name);
     105                 :            : 
     106                 :         10 :   gtk_level_bar_set_value (GTK_LEVEL_BAR (self->level_bar), percentage);
     107                 :         10 :   gtk_label_set_text (GTK_LABEL (self->label), label);
     108                 :            : 
     109         [ +  - ]:         10 :   if (g_action_group_get_action_enabled (action_group, action_name))
     110                 :         10 :     gtk_widget_set_visible (self->button, TRUE);
     111                 :            : }
     112                 :            : 
     113                 :            : static void
     114                 :          2 : on_action_enabled_changed (GActionGroup        *action_group,
     115                 :            :                            const char          *action_name,
     116                 :            :                            gboolean             enabled,
     117                 :            :                            ValentBatteryGadget *self)
     118                 :            : {
     119                 :          4 :   g_autoptr (GVariant) state = NULL;
     120                 :            : 
     121                 :          2 :   gtk_widget_set_visible (self->button, enabled);
     122                 :            : 
     123         [ +  + ]:          2 :   if (enabled)
     124                 :          1 :     state = g_action_group_get_action_state (action_group, action_name);
     125                 :            : 
     126         [ +  - ]:          1 :   if (state != NULL)
     127                 :          1 :     on_action_state_changed (action_group, action_name, state, self);
     128                 :          2 : }
     129                 :            : 
     130                 :            : /*
     131                 :            :  * GObject
     132                 :            :  */
     133                 :            : static void
     134                 :          1 : valent_battery_gadget_constructed (GObject *object)
     135                 :            : {
     136                 :          1 :   ValentBatteryGadget *self = VALENT_BATTERY_GADGET (object);
     137                 :          1 :   GActionGroup *action_group = NULL;
     138                 :          1 :   gboolean enabled = FALSE;
     139                 :            : 
     140                 :          1 :   g_object_get (object, "device", &action_group, NULL);
     141                 :          1 :   g_signal_connect_object (action_group,
     142                 :            :                            "action-state-changed::battery.state",
     143                 :            :                            G_CALLBACK (on_action_state_changed),
     144                 :            :                            self, 0);
     145                 :          1 :   g_signal_connect_object (action_group,
     146                 :            :                            "action-enabled-changed::battery.state",
     147                 :            :                            G_CALLBACK (on_action_enabled_changed),
     148                 :            :                            self, 0);
     149                 :            : 
     150                 :          1 :   enabled = g_action_group_get_action_enabled (action_group, "battery.state");
     151                 :          1 :   on_action_enabled_changed (action_group, "battery.state", enabled, self);
     152         [ +  - ]:          1 :   g_clear_object (&action_group);
     153                 :            : 
     154                 :          1 :   G_OBJECT_CLASS (valent_battery_gadget_parent_class)->constructed (object);
     155                 :          1 : }
     156                 :            : 
     157                 :            : static void
     158                 :          1 : valent_battery_gadget_dispose (GObject *object)
     159                 :            : {
     160                 :          1 :   ValentBatteryGadget *self = VALENT_BATTERY_GADGET (object);
     161                 :            : 
     162         [ +  - ]:          1 :   g_clear_pointer (&self->button, gtk_widget_unparent);
     163                 :            : 
     164                 :          1 :   G_OBJECT_CLASS (valent_battery_gadget_parent_class)->dispose (object);
     165                 :          1 : }
     166                 :            : 
     167                 :            : static void
     168                 :          3 : valent_battery_gadget_class_init (ValentBatteryGadgetClass *klass)
     169                 :            : {
     170                 :          3 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     171                 :            : 
     172                 :          3 :   object_class->constructed = valent_battery_gadget_constructed;
     173                 :          3 :   object_class->dispose = valent_battery_gadget_dispose;
     174                 :            : }
     175                 :            : 
     176                 :            : static void
     177                 :          1 : valent_battery_gadget_init (ValentBatteryGadget *self)
     178                 :            : {
     179                 :          1 :   GtkWidget *popover;
     180                 :          1 :   GtkWidget *box;
     181                 :            : 
     182                 :            :   /* Popover */
     183                 :          1 :   popover = g_object_new (GTK_TYPE_POPOVER,
     184                 :            :                           "autohide", TRUE,
     185                 :            :                           NULL);
     186                 :            : 
     187                 :          1 :   box = g_object_new (GTK_TYPE_BOX,
     188                 :            :                       "margin-top",    6,
     189                 :            :                       "margin-bottom", 6,
     190                 :            :                       "margin-start",  6,
     191                 :            :                       "margin-end",    6,
     192                 :            :                       "orientation",   GTK_ORIENTATION_VERTICAL,
     193                 :            :                       "spacing",       6,
     194                 :            :                       NULL);
     195                 :          1 :   gtk_popover_set_child (GTK_POPOVER (popover), box);
     196                 :            : 
     197                 :          1 :   self->label = gtk_label_new (NULL);
     198                 :          1 :   gtk_box_append (GTK_BOX (box), self->label);
     199                 :            : 
     200                 :          1 :   self->level_bar = g_object_new (GTK_TYPE_LEVEL_BAR,
     201                 :            :                                   "min-value",     0.0,
     202                 :            :                                   "max-value",     100.0,
     203                 :            :                                   "value",         42.0,
     204                 :            :                                   "width-request", 100,
     205                 :            :                                   "height-request", 3,
     206                 :            :                                   NULL);
     207                 :          1 :   gtk_box_append (GTK_BOX (box), self->level_bar);
     208                 :            : 
     209                 :            :   /* Button */
     210                 :          1 :   self->button = g_object_new (GTK_TYPE_MENU_BUTTON,
     211                 :            :                                "icon-name", "battery-missing-symbolic",
     212                 :            :                                "popover",   popover,
     213                 :            :                                "has-frame", FALSE,
     214                 :            :                                NULL);
     215                 :          1 :   gtk_widget_set_parent (self->button, GTK_WIDGET (self));
     216                 :          1 : }
     217                 :            : 

Generated by: LCOV version 1.14