LCOV - code coverage report
Current view: top level - src/libvalent/core - valent-extension.c (source / functions) Coverage Total Hit
Test: Code Coverage Lines: 92.0 % 225 207
Test Date: 2024-12-21 23:29:11 Functions: 100.0 % 27 27
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 63.6 % 110 70

             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-extension"
       5                 :             : 
       6                 :             : #include "config.h"
       7                 :             : 
       8                 :             : #include <gio/gio.h>
       9                 :             : #include <libpeas.h>
      10                 :             : 
      11                 :             : #include "valent-context.h"
      12                 :             : #include "valent-core-enums.h"
      13                 :             : #include "valent-object.h"
      14                 :             : #include "valent-resource.h"
      15                 :             : 
      16                 :             : #include "valent-extension.h"
      17                 :             : 
      18                 :             : 
      19                 :             : /**
      20                 :             :  * ValentExtension:
      21                 :             :  *
      22                 :             :  * An abstract base class for extensions.
      23                 :             :  *
      24                 :             :  * `ValentExtension` is a base class for extensions with conveniences for
      25                 :             :  * [iface@Gio.Action], [class@Gio.Settings] backed by [class@Valent.Context].
      26                 :             :  *
      27                 :             :  * ## Implementation Notes
      28                 :             :  *
      29                 :             :  * Implementations that also implement [iface@Gio.Initable] or
      30                 :             :  * [iface@Gio.AsyncInitable] are marked as `VALENT_PLUGIN_STATE_INACTIVE` during
      31                 :             :  * construction and must call [method@Valent.Extension.plugin_state_changed] to
      32                 :             :  * reflect the result of initialization.
      33                 :             :  *
      34                 :             :  * ## Plugin Actions
      35                 :             :  *
      36                 :             :  * `ValentExtension` implements the [iface@Gio.ActionGroup] and
      37                 :             :  * [iface@Gio.ActionMap] interfaces, providing a simple way for plugins to
      38                 :             :  * expose functions and states. Each [iface@Gio.Action] added to the action map
      39                 :             :  * will be included in the object action group with the plugin's module name as
      40                 :             :  * a prefix (eg. `share.uri`).
      41                 :             :  *
      42                 :             :  * ## `.plugin` File
      43                 :             :  *
      44                 :             :  * Implementations may define the extra fields in the `.plugin` file, to take
      45                 :             :  * advantage of core features in the base class.
      46                 :             :  *
      47                 :             :  * The field names are inferred from the GType name of the implementation, with
      48                 :             :  * `Valent` being stripped if present. For example `ValentDevicePlugin` becomes
      49                 :             :  * `X-DevicePluginSettings`, while `NameDevicePlugin` would become
      50                 :             :  * `X-NameDevicePluginSettings`.
      51                 :             :  *
      52                 :             :  * - Extension Category Field
      53                 :             :  *
      54                 :             :  *     A list of categories separated by semi-colons, serving as a hint for
      55                 :             :  *     organizational purposes. This should be in the form `Main;Additional;`,
      56                 :             :  *     with values from the freedesktop.org Desktop Menu Specification.
      57                 :             :  *
      58                 :             :  *     Field pattern: `X-<type name>Category`
      59                 :             :  *
      60                 :             :  * - [class@Gio.Settings] Schema Field
      61                 :             :  *
      62                 :             :  *     A [class@Gio.Settings] schema ID for the extensions's settings. See
      63                 :             :  *     [method@Valent.Context.get_plugin_settings] for more information.
      64                 :             :  *
      65                 :             :  *     Field pattern: `X-<type name>Settings`
      66                 :             :  *
      67                 :             :  * Since: 1.0
      68                 :             :  */
      69                 :             : 
      70                 :             : typedef struct
      71                 :             : {
      72                 :             :   PeasPluginInfo    *plugin_info;
      73                 :             :   ValentPluginState  plugin_state;
      74                 :             :   GError            *plugin_error;
      75                 :             : 
      76                 :             :   GHashTable        *actions;
      77                 :             :   ValentContext     *context;
      78                 :             :   GSettings         *settings;
      79                 :             : } ValentExtensionPrivate;
      80                 :             : 
      81                 :             : static void   g_action_group_iface_init (GActionGroupInterface *iface);
      82                 :             : static void   g_action_map_iface_init   (GActionMapInterface   *iface);
      83                 :             : 
      84   [ +  +  +  - ]:        6599 : G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ValentExtension, valent_extension, VALENT_TYPE_RESOURCE,
      85                 :             :                                   G_ADD_PRIVATE (ValentExtension)
      86                 :             :                                   G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_action_group_iface_init)
      87                 :             :                                   G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_MAP, g_action_map_iface_init))
      88                 :             : 
      89                 :             : typedef enum {
      90                 :             :   PROP_CONTEXT = 1,
      91                 :             :   PROP_PLUGIN_INFO,
      92                 :             :   PROP_PLUGIN_STATE,
      93                 :             :   PROP_SETTINGS,
      94                 :             : } ValentExtensionProperty;
      95                 :             : 
      96                 :             : static GParamSpec *properties[PROP_SETTINGS + 1] = { NULL, };
      97                 :             : 
      98                 :             : 
      99                 :             : /*
     100                 :             :  * GActionGroup
     101                 :             :  */
     102                 :             : static void
     103                 :           9 : valent_extension_activate_action (GActionGroup *action_group,
     104                 :             :                                   const char   *action_name,
     105                 :             :                                   GVariant     *parameter)
     106                 :             : {
     107                 :           9 :   ValentExtension *self = VALENT_EXTENSION (action_group);
     108                 :           9 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     109                 :           9 :   GAction *action;
     110                 :             : 
     111         [ +  - ]:           9 :   if ((action = g_hash_table_lookup (priv->actions, action_name)) != NULL)
     112                 :           9 :     g_action_activate (action, parameter);
     113                 :           9 : }
     114                 :             : 
     115                 :             : static void
     116                 :           1 : valent_extension_change_action_state (GActionGroup *action_group,
     117                 :             :                                       const char   *action_name,
     118                 :             :                                       GVariant     *value)
     119                 :             : {
     120                 :           1 :   ValentExtension *self = VALENT_EXTENSION (action_group);
     121                 :           1 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     122                 :           1 :   GAction *action;
     123                 :             : 
     124         [ +  - ]:           1 :   if ((action = g_hash_table_lookup (priv->actions, action_name)) != NULL)
     125                 :           1 :     g_action_change_state (action, value);
     126                 :           1 : }
     127                 :             : 
     128                 :             : static char **
     129                 :         212 : valent_extension_list_actions (GActionGroup *action_group)
     130                 :             : {
     131                 :         212 :   ValentExtension *self = VALENT_EXTENSION (action_group);
     132                 :         212 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     133                 :         424 :   g_auto (GStrv) actions = NULL;
     134                 :         212 :   GHashTableIter iter;
     135                 :         212 :   gpointer key;
     136                 :         212 :   unsigned int i = 0;
     137                 :             : 
     138         [ -  + ]:         212 :   actions = g_new0 (char *, g_hash_table_size (priv->actions) + 1);
     139                 :             : 
     140                 :         212 :   g_hash_table_iter_init (&iter, priv->actions);
     141                 :             : 
     142         [ +  + ]:         563 :   while (g_hash_table_iter_next (&iter, &key, NULL))
     143         [ -  + ]:         702 :     actions[i++] = g_strdup (key);
     144                 :             : 
     145                 :         212 :   return g_steal_pointer (&actions);
     146                 :             : }
     147                 :             : 
     148                 :             : static gboolean
     149                 :           2 : valent_extension_query_action (GActionGroup        *action_group,
     150                 :             :                                const char          *action_name,
     151                 :             :                                gboolean            *enabled,
     152                 :             :                                const GVariantType **parameter_type,
     153                 :             :                                const GVariantType **state_type,
     154                 :             :                                GVariant           **state_hint,
     155                 :             :                                GVariant           **state)
     156                 :             : {
     157                 :           2 :   ValentExtension *self = VALENT_EXTENSION (action_group);
     158                 :           2 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     159                 :           2 :   GAction *action;
     160                 :             : 
     161         [ +  - ]:           2 :   if ((action = g_hash_table_lookup (priv->actions, action_name)) == NULL)
     162                 :             :     return FALSE;
     163                 :             : 
     164         [ +  + ]:           2 :   if (enabled)
     165                 :           1 :     *enabled = g_action_get_enabled (action);
     166                 :             : 
     167         [ +  + ]:           2 :   if (parameter_type)
     168                 :           1 :     *parameter_type = g_action_get_parameter_type (action);
     169                 :             : 
     170         [ +  + ]:           2 :   if (state_type)
     171                 :           1 :     *state_type = g_action_get_state_type (action);
     172                 :             : 
     173         [ +  + ]:           2 :   if (state_hint)
     174                 :           1 :     *state_hint = g_action_get_state_hint (action);
     175                 :             : 
     176         [ +  - ]:           2 :   if (state)
     177                 :           2 :     *state = g_action_get_state (action);
     178                 :             : 
     179                 :             :   return TRUE;
     180                 :             : }
     181                 :             : 
     182                 :             : static void
     183                 :          58 : g_action_group_iface_init (GActionGroupInterface *iface)
     184                 :             : {
     185                 :          58 :   iface->activate_action = valent_extension_activate_action;
     186                 :          58 :   iface->change_action_state = valent_extension_change_action_state;
     187                 :          58 :   iface->list_actions = valent_extension_list_actions;
     188                 :          58 :   iface->query_action = valent_extension_query_action;
     189                 :          58 : }
     190                 :             : 
     191                 :             : /*
     192                 :             :  * GActionMap
     193                 :             :  */
     194                 :             : static void
     195                 :         605 : on_action_enabled_changed (GAction      *action,
     196                 :             :                            GParamSpec   *pspec,
     197                 :             :                            GActionGroup *action_group)
     198                 :             : {
     199                 :         605 :   g_action_group_action_enabled_changed (action_group,
     200                 :             :                                          g_action_get_name (action),
     201                 :             :                                          g_action_get_enabled (action));
     202                 :         605 : }
     203                 :             : 
     204                 :             : static void
     205                 :          25 : on_action_state_changed (GAction      *action,
     206                 :             :                          GParamSpec   *pspec,
     207                 :             :                          GActionGroup *action_group)
     208                 :             : {
     209                 :          50 :   g_autoptr (GVariant) value = NULL;
     210                 :             : 
     211                 :          25 :   value = g_action_get_state (action);
     212         [ +  - ]:          25 :   g_action_group_action_state_changed (action_group,
     213                 :             :                                        g_action_get_name (action),
     214                 :             :                                        value);
     215                 :          25 : }
     216                 :             : 
     217                 :             : static void
     218                 :         379 : valent_extension_disconnect_action (ValentExtension *self,
     219                 :             :                                     GAction         *action)
     220                 :             : {
     221                 :         379 :   g_signal_handlers_disconnect_by_func (action, on_action_enabled_changed, self);
     222                 :         379 :   g_signal_handlers_disconnect_by_func (action, on_action_state_changed, self);
     223                 :         379 : }
     224                 :             : 
     225                 :             : static GAction *
     226                 :         411 : valent_extension_lookup_action (GActionMap *action_map,
     227                 :             :                                 const char *action_name)
     228                 :             : {
     229                 :         411 :   ValentExtension *self = VALENT_EXTENSION (action_map);
     230                 :         411 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     231                 :             : 
     232                 :         411 :   return g_hash_table_lookup (priv->actions, action_name);
     233                 :             : }
     234                 :             : 
     235                 :             : static void
     236                 :         409 : valent_extension_add_action (GActionMap *action_map,
     237                 :             :                              GAction    *action)
     238                 :             : {
     239                 :         409 :   ValentExtension *self = VALENT_EXTENSION (action_map);
     240                 :         409 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     241                 :         409 :   const char *action_name;
     242                 :         409 :   GAction *replacing;
     243                 :             : 
     244                 :         409 :   action_name = g_action_get_name (action);
     245                 :             : 
     246         [ +  - ]:         409 :   if ((replacing = g_hash_table_lookup (priv->actions, action_name)) == action)
     247                 :             :     return;
     248                 :             : 
     249         [ -  + ]:         409 :   if (replacing != NULL)
     250                 :             :     {
     251                 :           0 :       g_action_group_action_removed (G_ACTION_GROUP (action_map), action_name);
     252                 :           0 :       valent_extension_disconnect_action (self, replacing);
     253                 :             :     }
     254                 :             : 
     255                 :         409 :   g_signal_connect_object (action,
     256                 :             :                            "notify::enabled",
     257                 :             :                            G_CALLBACK (on_action_enabled_changed),
     258                 :             :                            action_map, 0);
     259                 :             : 
     260         [ +  + ]:         409 :   if (g_action_get_state_type (action) != NULL)
     261                 :          36 :     g_signal_connect_object (action,
     262                 :             :                              "notify::state",
     263                 :             :                              G_CALLBACK (on_action_state_changed),
     264                 :             :                              action_map, 0);
     265                 :             : 
     266         [ -  + ]:         409 :   g_hash_table_replace (priv->actions,
     267                 :         409 :                         g_strdup (action_name),
     268                 :             :                         g_object_ref (action));
     269                 :         409 :   g_action_group_action_added (G_ACTION_GROUP (action_map), action_name);
     270                 :             : }
     271                 :             : 
     272                 :             : static void
     273                 :           1 : valent_extension_remove_action (GActionMap *action_map,
     274                 :             :                                 const char *action_name)
     275                 :             : {
     276                 :           1 :   ValentExtension *self = VALENT_EXTENSION (action_map);
     277                 :           1 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     278                 :           1 :   GAction *action;
     279                 :             : 
     280         [ +  - ]:           1 :   if ((action = g_hash_table_lookup (priv->actions, action_name)) != NULL)
     281                 :             :     {
     282                 :           1 :       g_action_group_action_removed (G_ACTION_GROUP (action_map), action_name);
     283                 :           1 :       valent_extension_disconnect_action (self, action);
     284                 :           1 :       g_hash_table_remove (priv->actions, action_name);
     285                 :             :     }
     286                 :           1 : }
     287                 :             : 
     288                 :             : static void
     289                 :          58 : g_action_map_iface_init (GActionMapInterface *iface)
     290                 :             : {
     291                 :          58 :   iface->add_action = valent_extension_add_action;
     292                 :          58 :   iface->lookup_action = valent_extension_lookup_action;
     293                 :          58 :   iface->remove_action = valent_extension_remove_action;
     294                 :          58 : }
     295                 :             : 
     296                 :             : /*
     297                 :             :  * ValentObject
     298                 :             :  */
     299                 :             : static void
     300                 :         591 : valent_extension_destroy (ValentObject *object)
     301                 :             : {
     302                 :         591 :   ValentExtension *self = VALENT_EXTENSION (object);
     303                 :         591 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     304                 :         591 :   GHashTableIter iter;
     305                 :         591 :   const char *action_name;
     306                 :         591 :   GAction *action;
     307                 :             : 
     308                 :         591 :   g_hash_table_iter_init (&iter, priv->actions);
     309         [ +  + ]:         969 :   while (g_hash_table_iter_next (&iter, (void **)&action_name, (void **)&action))
     310                 :             :     {
     311                 :         378 :       g_action_group_action_removed (G_ACTION_GROUP (self), action_name);
     312                 :         378 :       valent_extension_disconnect_action (self, action);
     313                 :         378 :       g_hash_table_iter_remove (&iter);
     314                 :             :     }
     315                 :             : 
     316                 :         591 :   valent_extension_plugin_state_changed (self, VALENT_PLUGIN_STATE_INACTIVE, NULL);
     317                 :             : 
     318                 :         591 :   VALENT_OBJECT_CLASS (valent_extension_parent_class)->destroy (object);
     319                 :         591 : }
     320                 :             : 
     321                 :             : /*
     322                 :             :  * GObject
     323                 :             :  */
     324                 :             : static void
     325                 :         332 : valent_extension_constructed (GObject *object)
     326                 :             : {
     327                 :         332 :   ValentExtension *self = VALENT_EXTENSION (object);
     328                 :         332 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     329                 :             : 
     330                 :         332 :   G_OBJECT_CLASS (valent_extension_parent_class)->constructed (object);
     331                 :             : 
     332                 :             :   /* If this is an extension with failable initialization, it is
     333                 :             :    * expected to update the state with the result.
     334                 :             :    */
     335   [ +  -  +  -  :         332 :   if (G_IS_INITABLE (object) || G_IS_ASYNC_INITABLE (object))
          +  -  +  -  +  
          -  +  -  +  -  
                   +  + ]
     336                 :          12 :     priv->plugin_state = VALENT_PLUGIN_STATE_INACTIVE;
     337                 :         332 : }
     338                 :             : static void
     339                 :         309 : valent_extension_finalize (GObject *object)
     340                 :             : {
     341                 :         309 :   ValentExtension *self = VALENT_EXTENSION (object);
     342                 :         309 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     343                 :             : 
     344                 :         309 :   g_clear_error (&priv->plugin_error);
     345         [ +  - ]:         309 :   g_clear_pointer (&priv->actions, g_hash_table_unref);
     346         [ +  + ]:         309 :   g_clear_object (&priv->context);
     347         [ +  + ]:         309 :   g_clear_object (&priv->plugin_info);
     348         [ +  + ]:         309 :   g_clear_object (&priv->settings);
     349                 :             : 
     350                 :         309 :   G_OBJECT_CLASS (valent_extension_parent_class)->finalize (object);
     351                 :         309 : }
     352                 :             : 
     353                 :             : static void
     354                 :           1 : valent_extension_get_property (GObject    *object,
     355                 :             :                                guint       prop_id,
     356                 :             :                                GValue     *value,
     357                 :             :                                GParamSpec *pspec)
     358                 :             : {
     359                 :           1 :   ValentExtension *self = VALENT_EXTENSION (object);
     360                 :           1 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     361                 :             : 
     362   [ +  -  -  -  :           1 :   switch ((ValentExtensionProperty)prop_id)
                      - ]
     363                 :             :     {
     364                 :           1 :     case PROP_CONTEXT:
     365                 :           1 :       g_value_set_object (value, valent_extension_get_context (self));
     366                 :           1 :       break;
     367                 :             : 
     368                 :           0 :     case PROP_PLUGIN_INFO:
     369                 :           0 :       g_value_set_object (value, priv->plugin_info);
     370                 :           0 :       break;
     371                 :             : 
     372                 :           0 :     case PROP_PLUGIN_STATE:
     373                 :           0 :       g_value_set_enum (value, priv->plugin_state);
     374                 :           0 :       break;
     375                 :             : 
     376                 :           0 :     case PROP_SETTINGS:
     377                 :           0 :       g_value_set_object (value, valent_extension_get_settings (self));
     378                 :           0 :       break;
     379                 :             : 
     380                 :           0 :     default:
     381                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     382                 :             :     }
     383                 :           1 : }
     384                 :             : 
     385                 :             : static void
     386                 :         664 : valent_extension_set_property (GObject      *object,
     387                 :             :                                guint         prop_id,
     388                 :             :                                const GValue *value,
     389                 :             :                                GParamSpec   *pspec)
     390                 :             : {
     391                 :         664 :   ValentExtension *self = VALENT_EXTENSION (object);
     392                 :         664 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     393                 :             : 
     394      [ +  +  - ]:         664 :   switch ((ValentExtensionProperty)prop_id)
     395                 :             :     {
     396                 :         332 :     case PROP_CONTEXT:
     397                 :         332 :       priv->context = g_value_dup_object (value);
     398                 :         332 :       break;
     399                 :             : 
     400                 :         332 :     case PROP_PLUGIN_INFO:
     401                 :         332 :       priv->plugin_info = g_value_dup_object (value);
     402                 :         332 :       break;
     403                 :             : 
     404                 :           0 :     case PROP_PLUGIN_STATE:
     405                 :             :     case PROP_SETTINGS:
     406                 :             :     default:
     407                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     408                 :             :     }
     409                 :         664 : }
     410                 :             : 
     411                 :             : static void
     412                 :          58 : valent_extension_class_init (ValentExtensionClass *klass)
     413                 :             : {
     414                 :          58 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     415                 :          58 :   ValentObjectClass *vobject_class = VALENT_OBJECT_CLASS (klass);
     416                 :             : 
     417                 :          58 :   object_class->constructed = valent_extension_constructed;
     418                 :          58 :   object_class->finalize = valent_extension_finalize;
     419                 :          58 :   object_class->get_property = valent_extension_get_property;
     420                 :          58 :   object_class->set_property = valent_extension_set_property;
     421                 :             : 
     422                 :          58 :   vobject_class->destroy = valent_extension_destroy;
     423                 :             : 
     424                 :             :   /**
     425                 :             :    * ValentExtension:context: (getter get_context)
     426                 :             :    *
     427                 :             :    * The [class@Valent.Device] this plugin is bound to.
     428                 :             :    *
     429                 :             :    * Since: 1.0
     430                 :             :    */
     431                 :         116 :   properties [PROP_CONTEXT] =
     432                 :          58 :     g_param_spec_object ("context", NULL, NULL,
     433                 :             :                          VALENT_TYPE_CONTEXT,
     434                 :             :                          (G_PARAM_READWRITE |
     435                 :             :                           G_PARAM_CONSTRUCT_ONLY |
     436                 :             :                           G_PARAM_EXPLICIT_NOTIFY |
     437                 :             :                           G_PARAM_STATIC_STRINGS));
     438                 :             : 
     439                 :             :   /**
     440                 :             :    * ValentExtension:plugin-info:
     441                 :             :    *
     442                 :             :    * The [class@Peas.PluginInfo] describing this plugin.
     443                 :             :    *
     444                 :             :    * Since: 1.0
     445                 :             :    */
     446                 :         116 :   properties [PROP_PLUGIN_INFO] =
     447                 :          58 :     g_param_spec_object ("plugin-info", NULL, NULL,
     448                 :             :                          PEAS_TYPE_PLUGIN_INFO,
     449                 :             :                          (G_PARAM_READWRITE |
     450                 :             :                           G_PARAM_CONSTRUCT_ONLY |
     451                 :             :                           G_PARAM_EXPLICIT_NOTIFY |
     452                 :             :                           G_PARAM_STATIC_STRINGS));
     453                 :             : 
     454                 :             :   /**
     455                 :             :    * ValentExtension:plugin-state:
     456                 :             :    *
     457                 :             :    * The [enum@Valent.PluginState] describing the state of the extension.
     458                 :             :    *
     459                 :             :    * Since: 1.0
     460                 :             :    */
     461                 :         116 :   properties [PROP_PLUGIN_STATE] =
     462                 :          58 :     g_param_spec_enum ("plugin-state", NULL, NULL,
     463                 :             :                        VALENT_TYPE_PLUGIN_STATE,
     464                 :             :                        VALENT_PLUGIN_STATE_ACTIVE,
     465                 :             :                        (G_PARAM_READABLE |
     466                 :             :                         G_PARAM_EXPLICIT_NOTIFY |
     467                 :             :                         G_PARAM_STATIC_STRINGS));
     468                 :             : 
     469                 :             :   /**
     470                 :             :    * ValentExtension:settings: (getter get_settings)
     471                 :             :    *
     472                 :             :    * The [class@Gio.Settings] for this plugin.
     473                 :             :    *
     474                 :             :    * Since: 1.0
     475                 :             :    */
     476                 :         116 :   properties [PROP_SETTINGS] =
     477                 :          58 :     g_param_spec_object ("settings", NULL, NULL,
     478                 :             :                          G_TYPE_SETTINGS,
     479                 :             :                          (G_PARAM_READABLE |
     480                 :             :                           G_PARAM_EXPLICIT_NOTIFY |
     481                 :             :                           G_PARAM_STATIC_STRINGS));
     482                 :             : 
     483                 :          58 :   g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
     484                 :          58 : }
     485                 :             : 
     486                 :             : static void
     487                 :         332 : valent_extension_init (ValentExtension *self)
     488                 :             : {
     489                 :         332 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (self);
     490                 :             : 
     491                 :         332 :   priv->actions = g_hash_table_new_full (g_str_hash,
     492                 :             :                                          g_str_equal,
     493                 :             :                                          g_free,
     494                 :             :                                          g_object_unref);
     495                 :         332 : }
     496                 :             : 
     497                 :             : /**
     498                 :             :  * valent_extension_get_context: (get-property context)
     499                 :             :  * @extension: a `ValentExtension`
     500                 :             :  *
     501                 :             :  * Get the settings for this plugin.
     502                 :             :  *
     503                 :             :  * Returns: (transfer none) (nullable): a `ValentContext`
     504                 :             :  *
     505                 :             :  * Since: 1.0
     506                 :             :  */
     507                 :             : ValentContext *
     508                 :          36 : valent_extension_get_context (ValentExtension *extension)
     509                 :             : {
     510                 :          36 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (extension);
     511                 :             : 
     512         [ +  - ]:          36 :   g_return_val_if_fail (VALENT_IS_EXTENSION (extension), NULL);
     513                 :             : 
     514         [ +  + ]:          36 :   if (priv->context == NULL)
     515                 :             :     {
     516                 :          16 :       ValentContext *context = NULL;
     517                 :          16 :       const char *module_name = NULL;
     518                 :             : 
     519                 :             :       /* FIXME: context = valent_object_get_context (priv->object); */
     520                 :          16 :       module_name = peas_plugin_info_get_module_name (priv->plugin_info);
     521                 :          16 :       priv->context = valent_context_new (context, "plugin", module_name);
     522                 :             :     }
     523                 :             : 
     524                 :          36 :   return priv->context;
     525                 :             : }
     526                 :             : 
     527                 :             : /**
     528                 :             :  * valent_extension_get_settings: (get-property settings)
     529                 :             :  * @extension: a `ValentExtension`
     530                 :             :  *
     531                 :             :  * Get the settings for this plugin.
     532                 :             :  *
     533                 :             :  * Returns: (transfer none) (nullable): a `GSettings`
     534                 :             :  *
     535                 :             :  * Since: 1.0
     536                 :             :  */
     537                 :             : GSettings *
     538                 :          89 : valent_extension_get_settings (ValentExtension *extension)
     539                 :             : {
     540                 :          89 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (extension);
     541                 :             : 
     542         [ +  - ]:          89 :   g_return_val_if_fail (VALENT_IS_EXTENSION (extension), NULL);
     543                 :             : 
     544         [ +  + ]:          89 :   if (priv->settings == NULL)
     545                 :             :     {
     546                 :          32 :       GType type_base = g_type_parent (G_OBJECT_TYPE (extension));
     547                 :          32 :       const char *type_name = g_type_name (type_base);
     548                 :          32 :       g_autofree char *key = NULL;
     549                 :             : 
     550   [ +  -  +  -  :          32 :       if (g_str_has_prefix (type_name, "Valent"))
                   +  - ]
     551                 :          32 :         key = g_strdup_printf ("X-%sSettings", &type_name[strlen ("Valent")]);
     552                 :             :       else
     553                 :           0 :         key = g_strdup_printf ("X-%sSettings", type_name);
     554                 :             : 
     555                 :          32 :       priv->settings = valent_context_get_plugin_settings (priv->context,
     556                 :             :                                                            priv->plugin_info,
     557                 :             :                                                            key);
     558                 :             :     }
     559                 :             : 
     560                 :          89 :   return priv->settings;
     561                 :             : }
     562                 :             : 
     563                 :             : /**
     564                 :             :  * valent_extension_plugin_state_check:
     565                 :             :  * @extension: a `ValentExtension`
     566                 :             :  * @error: (nullable): a `GError`
     567                 :             :  *
     568                 :             :  * Get the extension state, while propagating any errors that describe it.
     569                 :             :  *
     570                 :             :  * Returns: a `ValentPluginState`
     571                 :             :  *
     572                 :             :  * Since: 1.0
     573                 :             :  */
     574                 :             : ValentPluginState
     575                 :         116 : valent_extension_plugin_state_check (ValentExtension  *extension,
     576                 :             :                                      GError          **error)
     577                 :             : {
     578                 :         116 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (extension);
     579                 :             : 
     580         [ +  - ]:         116 :   g_return_val_if_fail (VALENT_IS_EXTENSION (extension), VALENT_PLUGIN_STATE_INACTIVE);
     581   [ +  +  -  + ]:         116 :   g_return_val_if_fail (error == NULL || *error == NULL, VALENT_PLUGIN_STATE_INACTIVE);
     582                 :             : 
     583   [ -  +  -  - ]:         116 :   if (priv->plugin_error != NULL && error != NULL)
     584                 :           0 :     *error = g_error_copy (priv->plugin_error);
     585                 :             : 
     586                 :         116 :   return priv->plugin_state;
     587                 :             : }
     588                 :             : 
     589                 :             : /**
     590                 :             :  * valent_extension_plugin_state_changed:
     591                 :             :  * @extension: a `ValentExtension`
     592                 :             :  * @state: a `ValentPluginState`
     593                 :             :  * @error: (nullable): a `GError`
     594                 :             :  *
     595                 :             :  * Emits [signal@GObject.Object::notify] for
     596                 :             :  * [property@Valent.Extension:plugin-state].
     597                 :             :  *
     598                 :             :  * Implementations should call this method to inform the managing object of
     599                 :             :  * changes to the state of the extension, especially unrecoverable errors.
     600                 :             :  *
     601                 :             :  * Since: 1.0
     602                 :             :  */
     603                 :             : void
     604                 :         603 : valent_extension_plugin_state_changed (ValentExtension   *extension,
     605                 :             :                                        ValentPluginState  state,
     606                 :             :                                        const GError      *error)
     607                 :             : {
     608                 :         603 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (extension);
     609                 :             : 
     610         [ +  - ]:         603 :   g_return_if_fail (VALENT_IS_EXTENSION (extension));
     611         [ -  + ]:         603 :   g_return_if_fail (state != VALENT_PLUGIN_STATE_ERROR || error != NULL);
     612                 :             : 
     613                 :         603 :   g_clear_error (&priv->plugin_error);
     614         [ -  + ]:         603 :   if (state == VALENT_PLUGIN_STATE_ERROR && error != NULL)
     615                 :           0 :     priv->plugin_error = g_error_copy (error);
     616                 :             : 
     617   [ +  +  -  + ]:         603 :   if (priv->plugin_state != state || priv->plugin_error != NULL)
     618                 :             :     {
     619                 :         316 :       priv->plugin_state = state;
     620                 :         316 :       valent_object_notify_by_pspec (VALENT_OBJECT (extension),
     621                 :             :                                      properties [PROP_PLUGIN_STATE]);
     622                 :             :     }
     623                 :             : }
     624                 :             : 
     625                 :             : /**
     626                 :             :  * valent_extension_toggle_actions:
     627                 :             :  * @extension: a `ValentExtension`
     628                 :             :  * @enabled: boolean
     629                 :             :  *
     630                 :             :  * Enable or disable all actions.
     631                 :             :  *
     632                 :             :  * Set the [property@Gio.Action:enabled] property of the actions for @extension to
     633                 :             :  * @enabled.
     634                 :             :  *
     635                 :             :  * Since: 1.0
     636                 :             :  */
     637                 :             : void
     638                 :         241 : valent_extension_toggle_actions (ValentExtension *extension,
     639                 :             :                                  gboolean         enabled)
     640                 :             : {
     641                 :         241 :   ValentExtensionPrivate *priv = valent_extension_get_instance_private (extension);
     642                 :         241 :   GHashTableIter iter;
     643                 :         241 :   GSimpleAction *action;
     644                 :             : 
     645         [ +  - ]:         241 :   g_return_if_fail (VALENT_IS_EXTENSION (extension));
     646                 :             : 
     647                 :         241 :   g_hash_table_iter_init (&iter, priv->actions);
     648                 :             : 
     649         [ +  + ]:         904 :   while (g_hash_table_iter_next (&iter, NULL, (void **)&action))
     650                 :         663 :     g_simple_action_set_enabled (action, enabled);
     651                 :             : }
     652                 :             : 
        

Generated by: LCOV version 2.0-1