diff --git a/plugins/dummy/calls-dummy-provider.c b/plugins/dummy/calls-dummy-provider.c index eac9ece..debbde8 100644 --- a/plugins/dummy/calls-dummy-provider.c +++ b/plugins/dummy/calls-dummy-provider.c @@ -35,7 +35,7 @@ struct _CallsDummyProvider { CallsProvider parent_instance; - GList *origins; + GListStore *origins; }; static void calls_dummy_provider_message_source_interface_init (CallsMessageSourceInterface *iface); @@ -61,13 +61,15 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED static gboolean usr1_handler (CallsDummyProvider *self) { - CallsDummyOrigin *origin; + GListModel *model; + g_autoptr(CallsDummyOrigin) origin = NULL; - g_return_val_if_fail (self->origins != NULL, FALSE); + model = G_LIST_MODEL (self->origins); + g_return_val_if_fail (g_list_model_get_n_items (model) > 0, FALSE); g_debug ("Received SIGUSR1, adding new incoming call"); - origin = CALLS_DUMMY_ORIGIN (self->origins->data); + origin = g_list_model_get_item (model, 0); calls_dummy_origin_create_inbound (origin, "0987654321"); return TRUE; @@ -85,12 +87,12 @@ calls_dummy_provider_get_status (CallsProvider *provider) return "Normal"; } -static GList * +static GListModel * calls_dummy_provider_get_origins (CallsProvider *provider) { CallsDummyProvider *self = CALLS_DUMMY_PROVIDER (provider); - return g_list_copy (self->origins); + return G_LIST_MODEL (self->origins); } static void @@ -111,19 +113,10 @@ constructed (GObject *object) static void dispose (GObject *object) { - gpointer origin; - GList *next; CallsDummyProvider *self = CALLS_DUMMY_PROVIDER (object); - while (self->origins != NULL) { - origin = self->origins->data; - next = self->origins->next; - g_list_free_1 (self->origins); - self->origins = next; - - g_signal_emit_by_name (self, "origin-removed", origin); - g_object_unref (origin); - } + g_list_store_remove_all (self->origins); + g_clear_object (&self->origins); G_OBJECT_CLASS (calls_dummy_provider_parent_class)->dispose (object); } @@ -153,6 +146,7 @@ calls_dummy_provider_message_source_interface_init (CallsMessageSourceInterface static void calls_dummy_provider_init (CallsDummyProvider *self) { + self->origins = g_list_store_new (CALLS_TYPE_DUMMY_ORIGIN); } @@ -161,9 +155,7 @@ calls_dummy_provider_add_origin (CallsDummyProvider *self, const gchar *name) { CallsDummyOrigin *origin = calls_dummy_origin_new (name); - self->origins = g_list_append (self->origins, origin); - - g_signal_emit_by_name (CALLS_PROVIDER (self), "origin-added", CALLS_ORIGIN (origin)); + g_list_store_append (self->origins, origin); } diff --git a/plugins/mm/calls-mm-origin.c b/plugins/mm/calls-mm-origin.c index f911cf9..d31ec29 100644 --- a/plugins/mm/calls-mm-origin.c +++ b/plugins/mm/calls-mm-origin.c @@ -869,3 +869,18 @@ calls_mm_origin_new (MMObject *mm_obj) "mm-object", mm_obj, NULL); } + +gboolean +calls_mm_origin_matches (CallsMMOrigin *self, + MMObject *mm_obj) +{ + g_return_val_if_fail (CALLS_IS_MM_ORIGIN (self), FALSE); + g_return_val_if_fail (MM_IS_OBJECT (mm_obj), FALSE); + + if (self->mm_obj) + return g_strcmp0 (mm_object_get_path (mm_obj), + mm_object_get_path (self->mm_obj)) == 0; + + return FALSE; +} + diff --git a/plugins/mm/calls-mm-origin.h b/plugins/mm/calls-mm-origin.h index daee945..527ff88 100644 --- a/plugins/mm/calls-mm-origin.h +++ b/plugins/mm/calls-mm-origin.h @@ -35,6 +35,8 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (CallsMMOrigin, calls_mm_origin, CALLS, MM_ORIGIN, GObject); CallsMMOrigin *calls_mm_origin_new (MMObject *modem); +gboolean calls_mm_origin_matches (CallsMMOrigin *self, + MMObject *modem); G_END_DECLS diff --git a/plugins/mm/calls-mm-provider.c b/plugins/mm/calls-mm-provider.c index c257c8a..dc6a375 100644 --- a/plugins/mm/calls-mm-provider.c +++ b/plugins/mm/calls-mm-provider.c @@ -42,8 +42,8 @@ struct _CallsMMProvider guint watch_id; /** ModemManager object proxy */ MMManager *mm; - /** Map of D-Bus object paths to origins */ - GHashTable *origins; + /* A list of CallsOrigins */ + GListStore *origins; }; static void calls_mm_provider_message_source_interface_init (CallsMessageSourceInterface *iface); @@ -78,7 +78,7 @@ update_status (CallsMMProvider *self) { s = _("ModemManager unavailable"); } - else if (g_hash_table_size (self->origins) == 0) + else if (g_list_model_get_n_items (G_LIST_MODEL (self->origins)) == 0) { s = _("No voice-capable modem available"); } @@ -91,6 +91,32 @@ update_status (CallsMMProvider *self) } +gboolean +mm_provider_contains (CallsMMProvider *self, + MMObject *mm_obj) +{ + GListModel *model; + guint n_items; + + g_assert (CALLS_IS_MM_PROVIDER (self)); + g_assert (MM_OBJECT (mm_obj)); + + model = G_LIST_MODEL (self->origins); + n_items = g_list_model_get_n_items (model); + + for (guint i = 0; i < n_items; i++) + { + g_autoptr(CallsMMOrigin) origin = NULL; + + origin = g_list_model_get_item (model, i); + + if (calls_mm_origin_matches (origin, mm_obj)) + return TRUE; + } + + return FALSE; +} + static void add_origin (CallsMMProvider *self, GDBusObject *object) @@ -99,8 +125,9 @@ add_origin (CallsMMProvider *self, CallsMMOrigin *origin; const gchar *path; + mm_obj = MM_OBJECT (object); path = g_dbus_object_get_object_path (object); - if (g_hash_table_contains (self->origins, path)) + if (mm_provider_contains (self, mm_obj)) { g_warning ("New voice interface on existing" " origin with path `%s'", path); @@ -111,16 +138,10 @@ add_origin (CallsMMProvider *self, path); g_assert (MM_IS_OBJECT (object)); - mm_obj = MM_OBJECT (object); origin = calls_mm_origin_new (mm_obj); + g_list_store_append (self->origins, origin); - g_hash_table_insert (self->origins, - mm_object_dup_path (mm_obj), - origin); - - g_signal_emit_by_name (CALLS_PROVIDER (self), - "origin-added", origin); update_status (self); } @@ -151,24 +172,25 @@ remove_modem_object (CallsMMProvider *self, const gchar *path, GDBusObject *object) { - gpointer *origin; + GListModel *model; + guint n_items; - origin = g_hash_table_lookup (self->origins, path); - if (!origin) - { - return; - } + model = G_LIST_MODEL (self->origins); + n_items = g_list_model_get_n_items (model); - g_assert (CALLS_IS_ORIGIN (origin)); + for (guint i = 0; i < n_items; i++) { + g_autoptr (CallsMMOrigin) origin = NULL; - g_object_ref (origin); - g_hash_table_remove (self->origins, path); + origin = g_list_model_get_item (model, i); - g_signal_emit_by_name (CALLS_PROVIDER (self), - "origin-removed", CALLS_ORIGIN (origin)); - g_object_unref (origin); + if (calls_mm_origin_matches (origin, MM_OBJECT (object))) + { + g_list_store_remove (self->origins, i); + update_status (self); - update_status (self); + break; + } + } } @@ -299,35 +321,13 @@ mm_appeared_cb (GDBusConnection *connection, } -static void -clear_dbus (CallsMMProvider *self) -{ - GList *paths, *node; - gpointer origin; - - paths = g_hash_table_get_keys (self->origins); - - for (node = paths; node != NULL; node = node->next) - { - g_hash_table_steal_extended (self->origins, node->data, NULL, &origin); - g_signal_emit_by_name (CALLS_PROVIDER (self), - "origin-removed", CALLS_ORIGIN (origin)); - g_object_unref (origin); - } - - g_list_free_full (paths, g_free); - - g_clear_object (&self->mm); -} - - void mm_vanished_cb (GDBusConnection *connection, const gchar *name, CallsMMProvider *self) { g_debug ("ModemManager vanished from D-Bus"); - clear_dbus (self); + g_list_store_remove_all (self->origins); update_status (self); } @@ -346,12 +346,12 @@ calls_mm_provider_get_status (CallsProvider *provider) return self->status; } -static GList * +static GListModel * calls_mm_provider_get_origins (CallsProvider *provider) { CallsMMProvider *self = CALLS_MM_PROVIDER (provider); - return g_hash_table_get_values (self->origins); + return G_LIST_MODEL (self->origins); } static void @@ -384,7 +384,7 @@ dispose (GObject *object) self->watch_id = 0; } - clear_dbus (self); + g_list_store_remove_all (self->origins); G_OBJECT_CLASS (calls_mm_provider_parent_class)->dispose (object); } @@ -395,7 +395,7 @@ finalize (GObject *object) { CallsMMProvider *self = CALLS_MM_PROVIDER (object); - g_hash_table_unref (self->origins); + g_object_unref (self->origins); g_free (self->status); G_OBJECT_CLASS (calls_mm_provider_parent_class)->finalize (object); @@ -433,8 +433,7 @@ static void calls_mm_provider_init (CallsMMProvider *self) { self->status = g_strdup (_("Initialised")); - self->origins = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_object_unref); + self->origins = g_list_store_new (CALLS_TYPE_MM_ORIGIN); } diff --git a/plugins/ofono/calls-ofono-origin.c b/plugins/ofono/calls-ofono-origin.c index 5eafc39..8e3fb00 100644 --- a/plugins/ofono/calls-ofono-origin.c +++ b/plugins/ofono/calls-ofono-origin.c @@ -110,6 +110,18 @@ calls_ofono_origin_new (GDBOModem *modem) NULL); } +gboolean +calls_ofono_origin_matches (CallsOfonoOrigin *self, + const char *path) +{ + g_return_val_if_fail (CALLS_IS_OFONO_ORIGIN (self), FALSE); + g_return_val_if_fail (path, FALSE); + + if (!self->modem) + return FALSE; + + return g_strcmp0 (g_dbus_proxy_get_object_path (G_DBUS_PROXY (self->modem)), path) == 0; +} static void set_property (GObject *object, diff --git a/plugins/ofono/calls-ofono-origin.h b/plugins/ofono/calls-ofono-origin.h index 2e3c30f..c21007d 100644 --- a/plugins/ofono/calls-ofono-origin.h +++ b/plugins/ofono/calls-ofono-origin.h @@ -36,6 +36,8 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (CallsOfonoOrigin, calls_ofono_origin, CALLS, OFONO_ORIGIN, GObject); CallsOfonoOrigin *calls_ofono_origin_new (GDBOModem *modem); +gboolean calls_ofono_origin_matches (CallsOfonoOrigin *self, + const char *path); G_END_DECLS diff --git a/plugins/ofono/calls-ofono-provider.c b/plugins/ofono/calls-ofono-provider.c index 98aef1b..e78fd15 100644 --- a/plugins/ofono/calls-ofono-provider.c +++ b/plugins/ofono/calls-ofono-provider.c @@ -45,8 +45,8 @@ struct _CallsOfonoProvider GDBOManager *manager; /** Map of D-Bus object paths to a struct CallsModemData */ GHashTable *modems; - /** Map of D-Bus object paths to Origins */ - GHashTable *origins; + /* A list of CallsOrigins */ + GListStore *origins; }; @@ -59,47 +59,37 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED calls_ofono_provider_message_source_interface_init)) -static void -add_origin_to_list (const gchar *path, - CallsOfonoOrigin *origin, - GList **list) +gboolean +ofono_find_origin_index (CallsOfonoProvider *self, + const char *path, + guint *index) { - *list = g_list_prepend (*list, origin); + GListModel *model; + guint n_items; + + g_assert (CALLS_IS_OFONO_PROVIDER (self)); + + model = G_LIST_MODEL (self->origins); + n_items = g_list_model_get_n_items (model); + + for (guint i = 0; i < n_items; i++) + { + g_autoptr(CallsOfonoOrigin) origin = NULL; + + origin = g_list_model_get_item (model, i); + + if (calls_ofono_origin_matches (origin, path)) + { + if (index) + *index = i; + + return TRUE; + } + } + + return FALSE; } - -static void -add_origin (CallsOfonoProvider *self, - const gchar *path, - GDBOModem *modem) -{ - CallsOfonoOrigin *origin; - - g_debug ("Adding oFono Origin with path `%s'", path); - - origin = calls_ofono_origin_new (modem); - g_hash_table_insert (self->origins, g_strdup(path), origin); - - g_signal_emit_by_name (CALLS_PROVIDER (self), - "origin-added", origin); -} - - -static void -remove_origin (CallsOfonoProvider *self, - const gchar *path, - CallsOfonoOrigin *origin) -{ - g_debug ("Removing oFono Origin with path `%s'", path); - - g_signal_emit_by_name (CALLS_PROVIDER (self), - "origin-removed", origin); - - g_hash_table_remove (self->origins, path); - g_object_unref (origin); -} - - static gboolean object_array_includes (GVariantIter *iter, const gchar *needle) @@ -129,7 +119,8 @@ modem_check_ifaces (CallsOfonoProvider *self, gboolean voice; GVariantIter *iter = NULL; const gchar *path; - CallsOfonoOrigin *origin; + guint index; + gboolean has_origin; g_variant_get (ifaces, "as", &iter); @@ -137,15 +128,20 @@ modem_check_ifaces (CallsOfonoProvider *self, (iter, "org.ofono.VoiceCallManager"); path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (modem)); - origin = g_hash_table_lookup (self->origins, path); - if (voice && !origin) + has_origin = ofono_find_origin_index (self, path, &index); + if (voice && !has_origin) { - add_origin (self, path, modem); + g_autoptr(CallsOfonoOrigin) origin = NULL; + + g_debug ("Adding oFono Origin with path `%s'", path); + + origin = calls_ofono_origin_new (modem); + g_list_store_append (self->origins, origin); } - else if (!voice && origin) + else if (!voice && has_origin) { - remove_origin (self, path, origin); + g_list_store_remove (self->origins, index); } } @@ -297,15 +293,12 @@ modem_removed_cb (GDBOManager *manager, const gchar *path, CallsOfonoProvider *self) { - CallsOfonoOrigin *origin; + guint index; g_debug ("Removing modem `%s'", path); - origin = g_hash_table_lookup (self->origins, path); - if (origin) - { - remove_origin (self, path, origin); - } + if (ofono_find_origin_index (self, path, &index)) + g_list_store_remove (self->origins, index); g_hash_table_remove (self->modems, path); @@ -365,16 +358,12 @@ calls_ofono_provider_get_status (CallsProvider *provider) return ""; } -static GList * +static GListModel * calls_ofono_provider_get_origins (CallsProvider *provider) { CallsOfonoProvider *self = CALLS_OFONO_PROVIDER (provider); - GList *list = NULL; - g_hash_table_foreach (self->origins, - (GHFunc)add_origin_to_list, &list); - - return g_list_reverse (list); + return G_LIST_MODEL (self->origins); } @@ -436,7 +425,7 @@ finalize (GObject *object) { CallsOfonoProvider *self = CALLS_OFONO_PROVIDER (object); - g_hash_table_unref (self->origins); + g_object_unref (self->origins); g_hash_table_unref (self->modems); G_OBJECT_CLASS (calls_ofono_provider_parent_class)->finalize (object); @@ -476,8 +465,7 @@ calls_ofono_provider_init (CallsOfonoProvider *self) { self->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - self->origins = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); + self->origins = g_list_store_new (CALLS_TYPE_OFONO_ORIGIN); } diff --git a/src/calls-manager.c b/src/calls-manager.c index 364908b..883bdd9 100644 --- a/src/calls-manager.c +++ b/src/calls-manager.c @@ -55,8 +55,6 @@ static GParamSpec *props[PROP_LAST_PROP]; enum { - SIGNAL_ORIGIN_ADD, - SIGNAL_ORIGIN_REMOVE, SIGNAL_CALL_ADD, SIGNAL_CALL_REMOVE, /* TODO: currently this event isn't emitted since the plugins don't give use @@ -205,7 +203,6 @@ add_origin (CallsManager *self, CallsOrigin *origin, CallsProvider *provider) calls_origin_foreach_call(origin, (CallsOriginForeachCallFunc)add_call, self); set_state (self, CALLS_MANAGER_STATE_READY); - g_signal_emit (self, signals[SIGNAL_ORIGIN_ADD], 0, origin); } static void @@ -217,7 +214,7 @@ remove_call_cb (gpointer self, CallsCall *call, CallsOrigin *origin) static void remove_origin (CallsManager *self, CallsOrigin *origin, CallsProvider *provider) { - g_autoptr (GList) origins = NULL; + GListModel *origins; g_return_if_fail (CALLS_IS_ORIGIN (origin)); @@ -229,10 +226,8 @@ remove_origin (CallsManager *self, CallsOrigin *origin, CallsProvider *provider) calls_manager_set_default_origin (self, NULL); origins = calls_manager_get_origins (self); - if (origins == NULL) - set_state (self, CALLS_MANAGER_STATE_NO_ORIGIN); - - g_signal_emit (self, signals[SIGNAL_ORIGIN_REMOVE], 0, origin); + if (!origins || g_list_model_get_n_items (origins) == 0) + set_state (self, CALLS_MANAGER_STATE_NO_ORIGIN); } static void @@ -240,29 +235,59 @@ remove_provider (CallsManager *self) { PeasEngine *engine = peas_engine_get_default (); PeasPluginInfo *plugin = peas_engine_get_plugin_info (engine, self->provider_name); - g_autoptr (GList) origins = NULL; - GList *o; + GListModel *origins; + guint n_items; g_debug ("Remove provider: %s", calls_provider_get_name (self->provider)); g_signal_handlers_disconnect_by_data (self->provider, self); origins = calls_provider_get_origins (self->provider); + g_signal_handlers_disconnect_by_data (origins, self); + n_items = g_list_model_get_n_items (origins); - for (o = origins; o != NULL; o = o->next) + for (guint i = 0; i < n_items; i++) { - remove_origin (self, o->data, self->provider); + g_autoptr(CallsOrigin) origin = NULL; + + origin = g_list_model_get_item (origins, i); + remove_origin (self, origin, self->provider); } g_clear_pointer (&self->provider_name, g_free); peas_engine_unload_plugin (engine, plugin); + g_clear_object (&self->provider); set_state (self, CALLS_MANAGER_STATE_NO_PROVIDER); } +static void +origin_items_changed_cb (CallsManager *self) +{ + GListModel *origins; + guint n_items; + + g_assert (CALLS_IS_MANAGER (self)); + + origins = calls_provider_get_origins (self->provider); + n_items = g_list_model_get_n_items (origins); + + if (n_items) + set_state (self, CALLS_MANAGER_STATE_READY); + else + set_state (self, CALLS_MANAGER_STATE_NO_ORIGIN); + + for (guint i = 0; i < n_items; i++) + { + g_autoptr(CallsOrigin) origin = NULL; + + origin = g_list_model_get_item (origins, i); + add_origin (self, origin, self->provider); + } +} + static void add_provider (CallsManager *self, const gchar *name) { - g_autoptr (GList) origins = NULL; - GList *o; + GListModel *origins; /* We could eventually enable more then one provider, but for now let's use only one */ @@ -279,17 +304,17 @@ add_provider (CallsManager *self, const gchar *name) return; } - set_state (self, CALLS_MANAGER_STATE_NO_ORIGIN); + if (g_strcmp0 (name, "dummy") == 0) + set_state (self, CALLS_MANAGER_STATE_READY); + else + set_state (self, CALLS_MANAGER_STATE_NO_ORIGIN); origins = calls_provider_get_origins (self->provider); - g_signal_connect_swapped (self->provider, "origin-added", G_CALLBACK (add_origin), self); - g_signal_connect_swapped (self->provider, "origin-removed", G_CALLBACK (remove_origin), self); - - for (o = origins; o != NULL; o = o->next) - { - add_origin (self, o->data, self->provider); - } + g_signal_connect_object (origins, "items-changed", + G_CALLBACK (origin_items_changed_cb), self, + G_CONNECT_SWAPPED); + origin_items_changed_cb (self); self->provider_name = g_strdup (name); } @@ -366,26 +391,6 @@ calls_manager_class_init (CallsManagerClass *klass) object_class->set_property = calls_manager_set_property; object_class->finalize = calls_manager_finalize; - signals[SIGNAL_ORIGIN_ADD] = - g_signal_new ("origin-add", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, - 1, - CALLS_TYPE_ORIGIN); - - signals[SIGNAL_ORIGIN_REMOVE] = - g_signal_new ("origin-remove", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, - 1, - CALLS_TYPE_ORIGIN); - signals[SIGNAL_CALL_ADD] = g_signal_new ("call-add", G_TYPE_FROM_CLASS (klass), @@ -548,7 +553,7 @@ calls_manager_get_state (CallsManager *self) return self->state; } -GList * +GListModel * calls_manager_get_origins (CallsManager *self) { g_return_val_if_fail (CALLS_IS_MANAGER (self), NULL); @@ -562,16 +567,23 @@ calls_manager_get_origins (CallsManager *self) GList * calls_manager_get_calls (CallsManager *self) { - g_autoptr (GList) origins = NULL; + GListModel *origins = NULL; g_autoptr (GList) calls = NULL; - GList *o; + guint n_items = 0; g_return_val_if_fail (CALLS_IS_MANAGER (self), NULL); origins = calls_manager_get_origins (self); + if (origins) + n_items = g_list_model_get_n_items (origins); - for (o = origins; o != NULL; o = o->next) - calls = g_list_concat (calls, calls_origin_get_calls (o->data)); + for (guint i = 0; i < n_items; i++) + { + g_autoptr(CallsOrigin) origin = NULL; + + origin = g_list_model_get_item (origins, i); + calls = g_list_concat (calls, calls_origin_get_calls (origin)); + } return g_steal_pointer (&calls); } diff --git a/src/calls-manager.h b/src/calls-manager.h index dd21eac..534d398 100644 --- a/src/calls-manager.h +++ b/src/calls-manager.h @@ -54,7 +54,7 @@ void calls_manager_set_provider (CallsManager *self, const gchar *name); CallsProvider *calls_manager_get_real_provider (CallsManager *self); CallsManagerState calls_manager_get_state (CallsManager *self); -GList *calls_manager_get_origins (CallsManager *self); +GListModel *calls_manager_get_origins (CallsManager *self); GList *calls_manager_get_calls (CallsManager *self); void calls_manager_dial (CallsManager *self, CallsOrigin *origin, diff --git a/src/calls-new-call-box.c b/src/calls-new-call-box.c index 0378835..2f14d4c 100644 --- a/src/calls-new-call-box.c +++ b/src/calls-new-call-box.c @@ -35,8 +35,8 @@ struct _CallsNewCallBox { GtkBox parent_instance; - GtkListStore *origin_store; - GtkComboBox *origin_box; + GtkListBox *origin_list_box; + HdyComboRow *origin_list; GtkButton *backspace; HdyKeypad *keypad; GtkButton *dial; @@ -48,30 +48,20 @@ struct _CallsNewCallBox G_DEFINE_TYPE (CallsNewCallBox, calls_new_call_box, GTK_TYPE_BOX); -enum { - ORIGIN_STORE_COLUMN_NAME, - ORIGIN_STORE_COLUMN_ORIGIN -}; - - static CallsOrigin * get_origin (CallsNewCallBox *self) { - GtkTreeIter iter; - gboolean ok; - CallsOrigin *origin; + g_autoptr(CallsOrigin) origin = NULL; + GListModel *model; + int index = -1; - ok = gtk_combo_box_get_active_iter (self->origin_box, &iter); - if (!ok) - { - return NULL; - } + model = hdy_combo_row_get_model (self->origin_list); - gtk_tree_model_get (GTK_TREE_MODEL (self->origin_store), - &iter, - ORIGIN_STORE_COLUMN_ORIGIN, &origin, - -1); - g_assert (CALLS_IS_ORIGIN (origin)); + if (model) + index = hdy_combo_row_get_selected_index (self->origin_list); + + if (model && index >= 0) + origin = g_list_model_get_item (model, index); return origin; } @@ -170,120 +160,70 @@ dial_queued (CallsNewCallBox *self) g_list_foreach (self->dial_queue, (GFunc)dial_queued_cb, origin); - g_object_unref (origin); clear_dial_queue (self); } -void -update_origin_box (CallsNewCallBox *self) +char * +get_origin_name (gpointer item, + gpointer user_data) { - GtkTreeModel *origin_store = GTK_TREE_MODEL (self->origin_store); - GtkTreeIter iter; + g_assert (CALLS_IS_ORIGIN (item)); - if (!gtk_tree_model_get_iter_first (origin_store, &iter)) - { - gtk_widget_hide (GTK_WIDGET (self->origin_box)); - gtk_widget_set_sensitive (GTK_WIDGET (self->dial), FALSE); - return; - } + return g_strdup (calls_origin_get_name (item)); +} - /* We know there is at least one origin. */ +static void +origin_count_changed_cb (CallsNewCallBox *self) +{ + GListModel *origins; + guint n_items = 0; - gtk_widget_set_sensitive (GTK_WIDGET (self->dial), TRUE); + g_assert (CALLS_IS_NEW_CALL_BOX (self)); - if (!gtk_tree_model_iter_next (origin_store, &iter)) - { - gtk_combo_box_set_active (self->origin_box, 0); - gtk_widget_hide (GTK_WIDGET (self->origin_box)); - } + origins = calls_manager_get_origins (calls_manager_get_default ()); + n_items = g_list_model_get_n_items (origins); + + gtk_widget_set_visible (GTK_WIDGET (self->origin_list_box), n_items > 1); + gtk_widget_set_sensitive (GTK_WIDGET (self->dial), n_items > 0); + + if (n_items) + hdy_combo_row_bind_name_model (self->origin_list, origins, + get_origin_name, self, NULL); else - { - /* We know there are multiple origins. */ + hdy_combo_row_bind_name_model (self->origin_list, + NULL, NULL, NULL, NULL); - if (gtk_combo_box_get_active (self->origin_box) < 0) - { - gtk_combo_box_set_active (self->origin_box, 0); - } - - /* We know there are multiple origins and one is selected. */ - - gtk_widget_show (GTK_WIDGET (self->origin_box)); - } + if (n_items) + hdy_combo_row_set_selected_index (self->origin_list, 0); dial_queued (self); } - static void -add_origin (CallsNewCallBox *self, CallsOrigin *origin) +provider_changed_cb (CallsNewCallBox *self) { - GtkTreeIter iter; + GListModel *origins; - gtk_list_store_append (self->origin_store, &iter); - gtk_list_store_set (self->origin_store, &iter, - ORIGIN_STORE_COLUMN_NAME, calls_origin_get_name (origin), - ORIGIN_STORE_COLUMN_ORIGIN, G_OBJECT (origin), - -1); + g_assert (CALLS_IS_NEW_CALL_BOX (self)); - update_origin_box (self); + origins = calls_manager_get_origins (calls_manager_get_default ()); + g_signal_connect_object (origins, "items-changed", + G_CALLBACK (origin_count_changed_cb), self, + G_CONNECT_SWAPPED); } - -static void -remove_origin (CallsNewCallBox *self, CallsOrigin *origin) -{ - GtkTreeIter iter; - gboolean ok; - - ok = calls_list_store_find (self->origin_store, origin, - ORIGIN_STORE_COLUMN_ORIGIN, &iter); - g_return_if_fail (ok); - - gtk_list_store_remove (self->origin_store, &iter); - - update_origin_box (self); -} - - -static void -remove_origins (CallsNewCallBox *self) -{ - GtkTreeModel *model = GTK_TREE_MODEL (self->origin_store); - GtkTreeIter iter; - - while (gtk_tree_model_get_iter_first (model, &iter)) - { - gtk_list_store_remove (self->origin_store, &iter); - } -} - - static void calls_new_call_box_init (CallsNewCallBox *self) { - g_autoptr (GList) origins = NULL; - GList *o; - gtk_widget_init_template (GTK_WIDGET (self)); g_signal_connect_swapped (calls_manager_get_default (), - "origin-add", - G_CALLBACK (add_origin), + "notify::provider", + G_CALLBACK (provider_changed_cb), self); - - g_signal_connect_swapped (calls_manager_get_default (), - "origin-remove", - G_CALLBACK (remove_origin), - self); - - origins = calls_manager_get_origins (calls_manager_get_default ()); - for (o = origins; o != NULL; o = o->next) { - add_origin (self, o->data); - } - - update_origin_box (self); + provider_changed_cb (self); } @@ -294,11 +234,6 @@ dispose (GObject *object) clear_dial_queue (self); - if (self->origin_store) - { - remove_origins (self); - } - if (self->long_press_back_gesture != NULL) g_object_unref (self->long_press_back_gesture); @@ -315,8 +250,8 @@ calls_new_call_box_class_init (CallsNewCallBoxClass *klass) object_class->dispose = dispose; gtk_widget_class_set_template_from_resource (widget_class, "/sm/puri/calls/ui/new-call-box.ui"); - gtk_widget_class_bind_template_child (widget_class, CallsNewCallBox, origin_store); - gtk_widget_class_bind_template_child (widget_class, CallsNewCallBox, origin_box); + gtk_widget_class_bind_template_child (widget_class, CallsNewCallBox, origin_list_box); + gtk_widget_class_bind_template_child (widget_class, CallsNewCallBox, origin_list); gtk_widget_class_bind_template_child (widget_class, CallsNewCallBox, backspace); gtk_widget_class_bind_template_child (widget_class, CallsNewCallBox, long_press_back_gesture); gtk_widget_class_bind_template_child (widget_class, CallsNewCallBox, keypad); @@ -354,7 +289,6 @@ calls_new_call_box_dial (CallsNewCallBox *self, } calls_origin_dial (origin, target); - g_object_unref (origin); } void diff --git a/src/calls-provider.c b/src/calls-provider.c index b71f7f6..2eb8c5d 100644 --- a/src/calls-provider.c +++ b/src/calls-provider.c @@ -58,13 +58,6 @@ enum { static GParamSpec *props[PROP_LAST_PROP]; -enum { - SIGNAL_ORIGIN_ADDED, - SIGNAL_ORIGIN_REMOVED, - SIGNAL_LAST_SIGNAL, -}; -static guint signals [SIGNAL_LAST_SIGNAL]; - static void calls_provider_get_property (GObject *object, guint prop_id, @@ -99,20 +92,6 @@ calls_provider_class_init (CallsProviderClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, PROP_LAST_PROP, props); - - signals[SIGNAL_ORIGIN_ADDED] = - g_signal_new ("origin-added", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, CALLS_TYPE_ORIGIN); - - signals[SIGNAL_ORIGIN_REMOVED] = - g_signal_new ("origin-removed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, CALLS_TYPE_ORIGIN); } static void @@ -151,10 +130,9 @@ calls_provider_get_status (CallsProvider *self) * * Get the list of #CallsOrigin interfaces offered by this provider. * - * Returns: A newly-allocated GList of objects implementing - * #CallsOrigin or NULL if there was an error. + * Returns: (transfer none): A #GListModel of origins */ -GList * +GListModel * calls_provider_get_origins (CallsProvider *self) { g_return_val_if_fail (CALLS_IS_PROVIDER (self), NULL); diff --git a/src/calls-provider.h b/src/calls-provider.h index fdd8afb..0288d94 100644 --- a/src/calls-provider.h +++ b/src/calls-provider.h @@ -46,13 +46,13 @@ struct _CallsProviderClass const char *(*get_name) (CallsProvider *self); const char *(*get_status) (CallsProvider *self); - GList *(*get_origins) (CallsProvider *self); + GListModel *(*get_origins) (CallsProvider *self); }; const char *calls_provider_get_name (CallsProvider *self); const char *calls_provider_get_status (CallsProvider *self); -GList *calls_provider_get_origins (CallsProvider *self); +GListModel *calls_provider_get_origins (CallsProvider *self); G_END_DECLS diff --git a/src/ui/new-call-box.ui b/src/ui/new-call-box.ui index 1cd8126..df23261 100644 --- a/src/ui/new-call-box.ui +++ b/src/ui/new-call-box.ui @@ -21,26 +21,19 @@ vertical center True + - - False - origin_store - 0 - 8 - True + True + none - - - 0 - + + True + - - False - True - + True diff --git a/tests/setup-origin.c b/tests/setup-origin.c index cd927dc..e7d0c11 100644 --- a/tests/setup-origin.c +++ b/tests/setup-origin.c @@ -11,7 +11,7 @@ void test_dummy_origin_set_up (OriginFixture *fixture, gconstpointer user_data) { - GList *origins; + GListModel *origins; test_dummy_provider_set_up (&fixture->parent, user_data); @@ -20,8 +20,7 @@ test_dummy_origin_set_up (OriginFixture *fixture, origins = calls_provider_get_origins (CALLS_PROVIDER (fixture->parent.dummy_provider)); - fixture->dummy_origin = CALLS_DUMMY_ORIGIN (origins->data); - g_list_free (origins); + fixture->dummy_origin = g_list_model_get_item (origins, 0); } diff --git a/tests/test-manager.c b/tests/test-manager.c index b0256c6..1a1de90 100644 --- a/tests/test-manager.c +++ b/tests/test-manager.c @@ -9,21 +9,8 @@ #include #include -gint origin_count = 0; CallsCall *test_call = NULL; -static void -origin_add_cb (CallsManager *manager) -{ - origin_count++; -} - -static void -origin_remove_cb (CallsManager *manager) -{ - origin_count--; -} - static void call_add_cb (CallsManager *manager, CallsCall *call) { @@ -54,36 +41,32 @@ static void test_calls_manager_dummy_provider () { g_autoptr (CallsManager) manager = calls_manager_new (); - g_autoptr (GList) origins = NULL; - gint no_origins = 0; + GListModel *origins; CallsOrigin *origin; g_assert (CALLS_IS_MANAGER (manager)); - origin_count = 0; - g_signal_connect (manager, "origin-remove", G_CALLBACK (origin_remove_cb), NULL); - g_signal_connect (manager, "origin-add", G_CALLBACK (origin_add_cb), NULL); - g_assert_null (calls_manager_get_provider (manager)); g_assert (calls_manager_get_state (manager) == CALLS_MANAGER_STATE_NO_PROVIDER); + g_assert_null (calls_manager_get_origins (manager)); calls_manager_set_provider (manager, "dummy"); g_assert_cmpstr (calls_manager_get_provider (manager), ==, "dummy"); g_assert (calls_manager_get_state (manager) == CALLS_MANAGER_STATE_READY); + g_assert_nonnull (calls_manager_get_origins (manager)); origins = calls_manager_get_origins (manager); - no_origins = g_list_length (origins); - g_assert_cmpint (origin_count, ==, no_origins); g_assert_nonnull (calls_manager_get_origins (manager)); + g_assert_true (g_list_model_get_n_items (origins) > 0); g_assert_null (calls_manager_get_calls (manager)); g_assert_null (calls_manager_get_default_origin (manager)); test_call = NULL; - if (no_origins > 0) { + if (g_list_model_get_n_items (origins) > 0) { g_signal_connect (manager, "call-add", G_CALLBACK (call_add_cb), NULL); g_signal_connect (manager, "call-remove", G_CALLBACK (call_remove_cb), NULL); - origin = CALLS_ORIGIN (g_list_first (origins)->data); + origin = g_list_model_get_item (origins, 0); g_assert (CALLS_IS_ORIGIN (origin)); calls_manager_set_default_origin (manager, origin); @@ -101,8 +84,8 @@ test_calls_manager_dummy_provider () /* Unload the provider */ calls_manager_set_provider (manager, NULL); - g_assert_cmpint (origin_count, ==, 0); g_assert_null (test_call); + g_assert_null (calls_manager_get_origins (manager)); g_assert (calls_manager_get_state (manager) == CALLS_MANAGER_STATE_NO_PROVIDER); } diff --git a/tests/test-provider.c b/tests/test-provider.c index 6c16ae7..16f3f56 100644 --- a/tests/test-provider.c +++ b/tests/test-provider.c @@ -41,12 +41,11 @@ static void test_dummy_provider_origins (ProviderFixture *fixture, gconstpointer user_data) { - GList *origins; + GListModel *origins; origins = calls_provider_get_origins (CALLS_PROVIDER (fixture->dummy_provider)); - g_assert_cmpuint (g_list_length (origins), ==, 1); - g_list_free (origins); + g_assert_cmpuint (g_list_model_get_n_items (origins), ==, 1); }