diff --git a/panels/common/gnome-control-center.rules.in b/panels/common/gnome-control-center.rules.in index 22cf785e0971682339c9fc7a059a905952938b60..8532d1e33c99b5143944826d691768d77ad04e9c 100644 --- a/panels/common/gnome-control-center.rules.in +++ b/panels/common/gnome-control-center.rules.in @@ -2,6 +2,7 @@ polkit.addRule(function(action, subject) { if ((action.id == "org.freedesktop.locale1.set-locale" || action.id == "org.freedesktop.locale1.set-keyboard" || action.id == "org.freedesktop.ModemManager1.Device.Control" || + action.id == "org.freedesktop.ModemManager1.Modem.SetPrimarySimSlot" || action.id == "org.freedesktop.hostname1.set-static-hostname" || action.id == "org.freedesktop.hostname1.set-hostname" || action.id == "org.gnome.controlcenter.datetime.configure") && diff --git a/panels/wwan/cc-wwan-device-page.blp b/panels/wwan/cc-wwan-device-page.blp index 8d3ce1de9bbb4a515ccd82c5ca2f2b04c0caa26a..1fe297cab15bde34153613aaa1257693be86cf6f 100644 --- a/panels/wwan/cc-wwan-device-page.blp +++ b/panels/wwan/cc-wwan-device-page.blp @@ -122,6 +122,13 @@ template $CcWwanDevicePage: Box { show-arrow: true; title: _("M_odem Details"); } + + Adw.ComboRow sim_slot_row { + use-underline: true; + title: _("Primary S_IM Slot"); + + model: StringList sim_slot_string_list {}; + } } } }; diff --git a/panels/wwan/cc-wwan-device-page.c b/panels/wwan/cc-wwan-device-page.c index 36b4766a10f1aa9049356ef95dd5a5721c69b2c5..6fbbc6f76716223e80d1959e9418ca6b15f9ab9b 100644 --- a/panels/wwan/cc-wwan-device-page.c +++ b/panels/wwan/cc-wwan-device-page.c @@ -70,6 +70,8 @@ struct _CcWwanDevicePage CcListRow *network_name_row; GtkListBox *network_settings_list; CcListRow *sim_lock_row; + AdwComboRow *sim_slot_row; + GtkStringList *sim_slot_string_list; GtkButton *unlock_button; AdwToastOverlay *toast_overlay; @@ -77,11 +79,13 @@ struct _CcWwanDevicePage CcWwanDevice *device; CcWwanData *wwan_data; GDBusProxy *wwan_proxy; + GCancellable *cancellable; GtkWindow *apn_dialog; GtkWindow *network_mode_dialog; GtkWindow *network_dialog; GtkWindow *sim_lock_dialog; + GtkWindow *sim_slot_dialog; gint sim_index; /* Set if a change is triggered in a signal’s callback, @@ -125,7 +129,7 @@ wwan_device_page_handle_data_row (CcWwanDevicePage *self, else cc_wwan_data_set_roaming_enabled (self->wwan_data, active); - cc_wwan_data_save_settings (self->wwan_data, NULL, NULL, NULL); + cc_wwan_data_save_settings (self->wwan_data, self->cancellable, NULL, NULL); } static gboolean @@ -174,7 +178,7 @@ cc_wwan_device_page_new_prompt (CcWwanDevicePage *self, const gchar *message = NULL; guint num; - prompt = GCR_PROMPT (gcr_system_prompt_open (-1, NULL, &error)); + prompt = GCR_PROMPT (gcr_system_prompt_open (-1, self->cancellable, &error)); if (error) { @@ -268,7 +272,7 @@ wwan_device_unlock_clicked_cb (CcWwanDevicePage *self) warning = _("PUK code should be an 8 digit number"); while (password && !cc_wwan_device_pin_valid (password, lock)) { - password = gcr_prompt_password (prompt, NULL, &error); + password = gcr_prompt_password (prompt, self->cancellable, &error); gcr_prompt_set_warning (prompt, warning); } @@ -296,7 +300,7 @@ wwan_device_unlock_clicked_cb (CcWwanDevicePage *self) warning = _("PIN code should be a 4-8 digit number"); while (password && !cc_wwan_device_pin_valid (password, MM_MODEM_LOCK_SIM_PIN)) { - password = gcr_prompt_password (prompt, NULL, &error); + password = gcr_prompt_password (prompt, self->cancellable, &error); gcr_prompt_set_warning (prompt, warning); } @@ -316,13 +320,13 @@ wwan_device_unlock_clicked_cb (CcWwanDevicePage *self) if (lock == MM_MODEM_LOCK_SIM_PIN) cc_wwan_device_send_pin (self->device, pin, - NULL, /* cancellable */ + self->cancellable, cc_wwan_device_page_unlocked_cb, self); else if (lock == MM_MODEM_LOCK_SIM_PUK) { cc_wwan_device_send_puk (self->device, puk, pin, - NULL, /* Cancellable */ + self->cancellable, cc_wwan_device_page_unlocked_cb, self); } @@ -408,6 +412,10 @@ wwan_advanced_settings_activated_cb (CcWwanDevicePage *self, { wwan_data_show_apn_dialog (self); } + else if (GTK_WIDGET (row) == GTK_WIDGET (self->sim_slot_row)) + { + /* NOP handling sim_slot_row, since it is a combo row. */ + } else { g_return_if_reached (); @@ -478,6 +486,52 @@ cc_wwan_locks_changed_cb (CcWwanDevicePage *self) cc_wwan_device_page_update (self); } +static void +wwan_device_set_primary_sim_slot_cb (CcWwanDevicePage *self) +{ + guint primary_slot = adw_combo_row_get_selected (self->sim_slot_row); + + cc_wwan_device_set_primary_sim_slot (self->device, primary_slot + 1, self->cancellable); + g_debug ("Setting primary sim slot to %d", primary_slot); +} + +static void +cc_wwan_update_sim_slots_row (CcWwanDevicePage *self) +{ + g_autoptr(GPtrArray) sim_slots = cc_wwan_device_get_sim_slots (self->device, self->cancellable); + int i; + + /* There's nothing the user can do if we get zero slots. Hide the row. */ + gtk_widget_set_visible (GTK_WIDGET (self->sim_slot_row), sim_slots->len > 0); + + for (i = 0; i < sim_slots->len; i++) { + MMSim *sim = g_ptr_array_index (sim_slots, i); + g_autofree gchar *slot_state = NULL; + g_autofree gchar *sim_label = NULL; + + /* Empty slot - no SIM card inserted */ + if (sim == NULL) + slot_state = g_strdup_printf ("[%s]", _("Empty")); + else { + const gchar *operator_name = mm_sim_get_operator_name (sim); + if (operator_name) + slot_state = g_strdup_printf ("[%s]", operator_name); + else + slot_state = g_strdup (""); + } + + /* Translators: This refers to a sim slot in a modem. + * For example: "Slot 1 [Operator Name]", "Slot 1" or "Slot 2 [Empty]". + * Notice that all variations above are valid. Sometimes "Operator Name" + * will be ommitted.*/ + sim_label = g_strdup_printf (_("Slot %d %s"), i+1, slot_state); + gtk_string_list_append (self->sim_slot_string_list, sim_label); + } + + adw_combo_row_set_selected (self->sim_slot_row, + cc_wwan_device_get_primary_sim_slot (self->device) - 1); +} + static void cc_wwan_device_page_set_property (GObject *object, guint prop_id, @@ -524,6 +578,9 @@ cc_wwan_device_page_constructed (GObject *object) cc_wwan_device_page_update (self); cc_wwan_locks_changed_cb (self); + cc_wwan_update_sim_slots_row (self); + + g_signal_connect_swapped (self->sim_slot_row, "notify::selected", (GCallback)wwan_device_set_primary_sim_slot_cb, self); } static void @@ -535,7 +592,11 @@ cc_wwan_device_page_dispose (GObject *object) g_clear_pointer (&self->network_mode_dialog, gtk_window_destroy); g_clear_pointer (&self->network_dialog, gtk_window_destroy); g_clear_pointer (&self->sim_lock_dialog, gtk_window_destroy); + g_clear_pointer (&self->sim_slot_dialog, gtk_window_destroy); + g_cancellable_cancel (self->cancellable); + + g_clear_object (&self->cancellable); g_clear_object (&self->wwan_proxy); g_clear_object (&self->device); @@ -577,6 +638,8 @@ cc_wwan_device_page_class_init (CcWwanDevicePageClass *klass) gtk_widget_class_bind_template_child (widget_class, CcWwanDevicePage, network_name_row); gtk_widget_class_bind_template_child (widget_class, CcWwanDevicePage, network_settings_list); gtk_widget_class_bind_template_child (widget_class, CcWwanDevicePage, sim_lock_row); + gtk_widget_class_bind_template_child (widget_class, CcWwanDevicePage, sim_slot_row); + gtk_widget_class_bind_template_child (widget_class, CcWwanDevicePage, sim_slot_string_list); gtk_widget_class_bind_template_child (widget_class, CcWwanDevicePage, unlock_button); gtk_widget_class_bind_template_callback (widget_class, wwan_device_unlock_clicked_cb); @@ -589,6 +652,8 @@ static void cc_wwan_device_page_init (CcWwanDevicePage *self) { gtk_widget_init_template (GTK_WIDGET (self)); + + self->cancellable = g_cancellable_new (); } static void diff --git a/panels/wwan/cc-wwan-device.c b/panels/wwan/cc-wwan-device.c index 26092b6bcdc18ef37e7c9f751a05f7421f02bac8..e04433e1c78303d021b5605ffbac59307a6ada79 100644 --- a/panels/wwan/cc-wwan-device.c +++ b/panels/wwan/cc-wwan-device.c @@ -90,6 +90,37 @@ enum { static GParamSpec *properties[N_PROPS]; +void +cc_wwan_device_set_primary_sim_slot (CcWwanDevice *self, guint sim_slot, GCancellable *cancellable) +{ + GError *error = NULL; + + mm_modem_set_primary_sim_slot_sync (self->modem, sim_slot, cancellable, &error); + + if (error) + g_warning ("Error:%s", error->message); +} + +guint +cc_wwan_device_get_primary_sim_slot (CcWwanDevice *self) +{ + return mm_modem_get_primary_sim_slot (self->modem); +} + +GPtrArray * +cc_wwan_device_get_sim_slots (CcWwanDevice *self, GCancellable *cancellable) +{ + GError *error = NULL; + GPtrArray *sim_slots; + + sim_slots = mm_modem_list_sim_slots_sync (self->modem, cancellable, &error); + + if (error) + g_warning ("Error:%s", error->message); + + return sim_slots; +} + static void cc_wwan_device_state_changed_cb (CcWwanDevice *self) { diff --git a/panels/wwan/cc-wwan-device.h b/panels/wwan/cc-wwan-device.h index e484bcf30f2f8cb3c2b692eb39c7600f2423569f..938cb70f23517eeb3eea05d928675d612143a9e1 100644 --- a/panels/wwan/cc-wwan-device.h +++ b/panels/wwan/cc-wwan-device.h @@ -148,5 +148,11 @@ const gchar *cc_wwan_device_get_path (CcWwanDevice *self CcWwanData *cc_wwan_device_get_data (CcWwanDevice *self); gboolean cc_wwan_device_pin_valid (const gchar *password, MMModemLock lock); +GPtrArray *cc_wwan_device_get_sim_slots (CcWwanDevice *self, + GCancellable *cancellable); +void cc_wwan_device_set_primary_sim_slot (CcWwanDevice *self, + guint sim_slot, + GCancellable *cancellable); +guint cc_wwan_device_get_primary_sim_slot (CcWwanDevice *self); G_END_DECLS diff --git a/panels/wwan/cc-wwan-panel.blp b/panels/wwan/cc-wwan-panel.blp index edff62d4f1c9e6593da2c241f9b3886ab9806bcb..14a5c6fb2652b41dc7163ea353deeacb7aa89cdc 100644 --- a/panels/wwan/cc-wwan-panel.blp +++ b/panels/wwan/cc-wwan-panel.blp @@ -67,6 +67,15 @@ template $CcWwanPanel: $CcPanel { }; } + StackPage { + name: "loading-page"; + + child: Adw.StatusPage { + title: _("Loading Devices"); + child: Adw.Spinner {}; + }; + } + StackPage { name: "device-settings"; diff --git a/panels/wwan/cc-wwan-panel.c b/panels/wwan/cc-wwan-panel.c index 3ba2bc46cb2a6756195b61f081cf2c13634fc3d2..bee916ee9346b91a7a390215bbc372cad5e3bdb6 100644 --- a/panels/wwan/cc-wwan-panel.c +++ b/panels/wwan/cc-wwan-panel.c @@ -370,6 +370,8 @@ cc_wwan_panel_add_device (CcWwanPanel *self, cc_wwan_device_page_set_sim_index (device_page, n_items); gtk_stack_add_titled (self->devices_stack, GTK_WIDGET (device_page), stack_name, operator_name); + + gtk_stack_set_visible_child_name (self->main_stack, "device-settings"); } static void @@ -560,6 +562,8 @@ wwan_panel_device_removed_cb (CcWwanPanel *self, gtk_revealer_set_reveal_child (self->multi_device_revealer, g_list_model_get_n_items (G_LIST_MODEL (self->devices)) > 1); + + gtk_stack_set_visible_child_name (self->main_stack, "loading-page"); } static GPtrArray * @@ -830,8 +834,5 @@ cc_wwan_panel_static_init_func (void) g_debug ("Monitoring ModemManager for WWAN devices"); - g_signal_connect (mm_manager, "object-added", G_CALLBACK (wwan_update_panel_visibility), NULL); - g_signal_connect (mm_manager, "object-removed", G_CALLBACK (wwan_update_panel_visibility), NULL); - wwan_update_panel_visibility (mm_manager); }