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

Generated by: LCOV version 2.0-1