From dd4a02aea2d966fbc1268428b8ccd1bfdf8a18cd Mon Sep 17 00:00:00 2001 From: Evangelos Ribeiro Tzaras Date: Wed, 26 Jan 2022 07:53:58 +0100 Subject: [PATCH] manager: Add per protocol dial actions These are enabled or disabled based on availability of suitable origins. Allows CallsCallRecordRows (GtkListBoxRows in the call history) to use protocol specific instead of global dial action. Closes #307 --- src/calls-manager.c | 100 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/src/calls-manager.c b/src/calls-manager.c index 5f67f78..f5ed10b 100644 --- a/src/calls-manager.c +++ b/src/calls-manager.c @@ -41,7 +41,7 @@ #include #include -static const char *protocols[] = { +static const char * const protocols[] = { "tel", "sip", "sips" @@ -56,6 +56,8 @@ struct _CallsManager GListStore *origins; /* origins_by_protocol maps protocol names to GListStore's of suitable origins */ GHashTable *origins_by_protocol; + /* dial_actions_by_protocol maps protocol names to GSimpleActions */ + GHashTable *dial_actions_by_protocol; CallsContactsProvider *contacts_provider; @@ -138,7 +140,68 @@ update_state (CallsManager *self) } -/* propagate any message from origins, providers, calls, etc */ +static CallsOrigin * +lookup_origin_by_id (CallsManager *self, + const char *origin_id) +{ + return NULL; +} + + +static void +on_dial_protocol_activated (GSimpleAction *action, + GVariant *parameter, + CallsManager *self) +{ + GApplication *application; + CallsOrigin *origin; + g_autofree char *target = NULL; + g_autofree char *origin_id = NULL; + + g_variant_get (parameter, "(ss)", &target, &origin_id); + origin = lookup_origin_by_id (self, origin_id); + + if (origin) { + calls_origin_dial (origin, target); + return; + } + + if (origin_id && *origin_id) + g_debug ("Origin ID '%s' given, but was not found for call to '%s'", + origin_id, target); + + /* fall back to the default action if we could not determine origin to place call from */ + application = g_application_get_default (); + if (!application) { + g_warning ("Could not get default application, cannot activate action '%s'", + g_action_get_name (G_ACTION (action))); + return; + } + + g_action_group_activate_action (G_ACTION_GROUP (application), + "dial", + g_variant_new_string (target)); +} + + +static void +update_protocol_dial_actions (CallsManager *self) +{ + g_assert (CALLS_IS_MANAGER (self)); + + for (guint i = 0; i < G_N_ELEMENTS (protocols); i++) { + GSimpleAction *action = g_hash_table_lookup (self->dial_actions_by_protocol, + protocols[i]); + GListModel *protocol_origin = g_hash_table_lookup (self->origins_by_protocol, + protocols[i]); + /* TODO take into account if origin is active: modem registered or VoIP account online */ + gboolean action_enabled = g_list_model_get_n_items (protocol_origin) > 0; + + g_simple_action_set_enabled (action, action_enabled); + } +} + + static void on_message (CallsMessageSource *source, const char *message, @@ -342,6 +405,8 @@ rebuild_origins_by_protocols (CallsManager *self) g_list_store_append (store, origin); } } + + update_protocol_dial_actions (self); } @@ -536,6 +601,7 @@ calls_manager_finalize (GObject *object) g_clear_pointer (&self->providers, g_hash_table_unref); g_clear_pointer (&self->origins_by_protocol, g_hash_table_unref); + g_clear_pointer (&self->dial_actions_by_protocol, g_hash_table_unref); G_OBJECT_CLASS (calls_manager_parent_class)->finalize (object); } @@ -626,6 +692,8 @@ calls_manager_class_init (CallsManagerClass *klass) static void calls_manager_init (CallsManager *self) { + g_autoptr (GVariantType) variant_type = NULL; + GApplication *application; PeasEngine *peas; const gchar *dir; @@ -647,6 +715,34 @@ calls_manager_init (CallsManager *self) origin_store); } + self->dial_actions_by_protocol = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); + + application = g_application_get_default (); + variant_type = g_variant_type_new ("(ss)"); + + for (guint i = 0; i < G_N_ELEMENTS (protocols); i++) { + g_autofree char *action_name = g_strdup_printf ("dial-%s", protocols[i]); + GSimpleAction *action = g_simple_action_new (action_name, variant_type); + g_signal_connect (action, + "activate", + G_CALLBACK (on_dial_protocol_activated), + self); + + g_hash_table_insert (self->dial_actions_by_protocol, + g_strdup (protocols[i]), + g_object_ref (action)); + + /* Enable action if there are suitable origins */ + g_simple_action_set_enabled (action, FALSE); + + /* application can be NULL when running tests */ + if (application) + g_action_map_add_action (G_ACTION_MAP (application), G_ACTION (action)); + } + self->origins = g_list_store_new (calls_origin_get_type ()); self->settings = calls_settings_new ();