Blame src/libnm-gtk/nm-mobile-wizard.c

Packit fabffb
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
Packit fabffb
/* NetworkManager Connection editor -- Connection editor for NetworkManager
Packit fabffb
 *
Packit fabffb
 * Dan Williams <dcbw@redhat.com>
Packit fabffb
 *
Packit fabffb
 * This program is free software; you can redistribute it and/or modify
Packit fabffb
 * it under the terms of the GNU General Public License as published by
Packit fabffb
 * the Free Software Foundation; either version 2 of the License, or
Packit fabffb
 * (at your option) any later version.
Packit fabffb
 *
Packit fabffb
 * This program is distributed in the hope that it will be useful,
Packit fabffb
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit fabffb
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit fabffb
 * GNU General Public License for more details.
Packit fabffb
 *
Packit fabffb
 * You should have received a copy of the GNU General Public License along
Packit fabffb
 * with this program; if not, write to the Free Software Foundation, Inc.,
Packit fabffb
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit fabffb
 *
Packit fabffb
 * (C) Copyright 2008 - 2017 Red Hat, Inc.
Packit fabffb
 */
Packit fabffb
Packit fabffb
#include "nm-default.h"
Packit fabffb
Packit fabffb
#include <stdlib.h>
Packit fabffb
Packit fabffb
#include <NetworkManager.h>
Packit fabffb
#include <nm-setting-gsm.h>
Packit fabffb
#include <nm-setting-cdma.h>
Packit fabffb
#include <nm-client.h>
Packit fabffb
#include <nm-device-modem.h>
Packit fabffb
Packit fabffb
#include "nm-mobile-wizard.h"
Packit fabffb
#include "nm-mobile-providers.h"
Packit fabffb
#include "nm-ui-utils.h"
Packit fabffb
#include "utils.h"
Packit fabffb
Packit fabffb
#define DEVICE_TAG "device"
Packit fabffb
#define TYPE_TAG "setting-type"
Packit fabffb
Packit fabffb
static NMACountryInfo *get_selected_country (NMAMobileWizard *self);
Packit fabffb
static NMAMobileProvider *get_selected_provider (NMAMobileWizard *self);
Packit fabffb
static NMAMobileFamily get_provider_unlisted_type (NMAMobileWizard *self);
Packit fabffb
static NMAMobileAccessMethod *get_selected_method (NMAMobileWizard *self, gboolean *manual);
Packit fabffb
Packit fabffb
struct NMAMobileWizard {
Packit fabffb
	GtkWidget *assistant;
Packit fabffb
	NMAMobileWizardCallback callback;
Packit fabffb
	gpointer user_data;
Packit fabffb
	NMAMobileProvidersDatabase *mobile_providers_database;
Packit fabffb
	NMAMobileFamily family;
Packit fabffb
	gboolean initial_family;
Packit fabffb
	gboolean will_connect_after;
Packit fabffb
Packit fabffb
	/* Intro page */
Packit fabffb
	GtkWidget *dev_combo;
Packit fabffb
	GtkTreeStore *dev_store;
Packit fabffb
	char *dev_desc;
Packit fabffb
	NMClient *client;
Packit fabffb
Packit fabffb
	/* Country page */
Packit fabffb
	guint32 country_idx;
Packit fabffb
	NMACountryInfo *country;
Packit fabffb
	GtkWidget *country_page;
Packit fabffb
	GtkWidget *country_view;
Packit fabffb
	GtkTreeStore *country_store;
Packit fabffb
	GtkTreeModelSort *country_sort;
Packit fabffb
	guint32 country_focus_id;
Packit fabffb
Packit fabffb
	/* Providers page */
Packit fabffb
	guint32 providers_idx;
Packit fabffb
	GtkWidget *providers_page;
Packit fabffb
	GtkWidget *providers_view;
Packit fabffb
	GtkTreeStore *providers_store;
Packit fabffb
	GtkTreeModelSort *providers_sort;
Packit fabffb
	guint32 providers_focus_id;
Packit fabffb
	GtkWidget *providers_view_radio;
Packit fabffb
Packit fabffb
	GtkWidget *provider_unlisted_radio;
Packit fabffb
	GtkWidget *provider_unlisted_entry;
Packit fabffb
	GtkWidget *provider_unlisted_type_combo;
Packit fabffb
Packit fabffb
	gboolean provider_only_cdma;
Packit fabffb
Packit fabffb
	/* Plan page */
Packit fabffb
	guint32 plan_idx;
Packit fabffb
	GtkWidget *plan_page;
Packit fabffb
	GtkWidget *plan_combo;
Packit fabffb
	GtkTreeStore *plan_store;
Packit fabffb
	guint32 plan_focus_id;
Packit fabffb
Packit fabffb
	GtkWidget *plan_unlisted_entry;
Packit fabffb
Packit fabffb
	/* Confirm page */
Packit fabffb
	GtkWidget *confirm_page;
Packit fabffb
	GtkWidget *confirm_provider;
Packit fabffb
	GtkWidget *confirm_plan;
Packit fabffb
	GtkWidget *confirm_apn;
Packit fabffb
	GtkWidget *confirm_plan_label;
Packit fabffb
	GtkWidget *confirm_device;
Packit fabffb
	GtkWidget *confirm_device_label;
Packit fabffb
	guint32 confirm_idx;
Packit fabffb
};
Packit fabffb
Packit fabffb
static void
Packit fabffb
assistant_closed (GtkButton *button, gpointer user_data)
Packit fabffb
{
Packit fabffb
	NMAMobileWizard *self = user_data;
Packit fabffb
	NMAMobileProvider *provider;
Packit fabffb
	NMAMobileAccessMethod *method;
Packit fabffb
	NMAMobileWizardAccessMethod *wiz_method;
Packit fabffb
	NMAMobileFamily family = self->family;
Packit fabffb
Packit fabffb
	wiz_method = g_malloc0 (sizeof (NMAMobileWizardAccessMethod));
Packit fabffb
Packit fabffb
	provider = get_selected_provider (self);
Packit fabffb
	if (!provider) {
Packit fabffb
		if (family == NMA_MOBILE_FAMILY_UNKNOWN)
Packit fabffb
			family = get_provider_unlisted_type (self);
Packit fabffb
Packit fabffb
		wiz_method->provider_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->provider_unlisted_entry)));
Packit fabffb
		if (family == NMA_MOBILE_FAMILY_3GPP)
Packit fabffb
			wiz_method->gsm_apn = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->plan_unlisted_entry)));
Packit fabffb
	} else {
Packit fabffb
		gboolean manual = FALSE;
Packit fabffb
Packit fabffb
		wiz_method->provider_name = g_strdup (nma_mobile_provider_get_name (provider));
Packit fabffb
		method = get_selected_method (self, &manual);
Packit fabffb
		if (method) {
Packit fabffb
			family = nma_mobile_access_method_get_family (method);
Packit fabffb
			wiz_method->plan_name = g_strdup (nma_mobile_access_method_get_name (method));
Packit fabffb
			wiz_method->username = g_strdup (nma_mobile_access_method_get_username (method));
Packit fabffb
			wiz_method->password = g_strdup (nma_mobile_access_method_get_password (method));
Packit fabffb
			if (family == NMA_MOBILE_FAMILY_3GPP)
Packit fabffb
				wiz_method->gsm_apn = g_strdup (nma_mobile_access_method_get_3gpp_apn (method));
Packit fabffb
		} else {
Packit fabffb
			if (self->provider_only_cdma) {
Packit fabffb
				GSList *methods;
Packit fabffb
Packit fabffb
				family = NMA_MOBILE_FAMILY_CDMA;
Packit fabffb
Packit fabffb
				methods = nma_mobile_provider_get_methods (provider);
Packit fabffb
				/* Take username and password from the first (only) method for CDMA only provider */
Packit fabffb
				if (methods) {
Packit fabffb
					method = methods->data;
Packit fabffb
					wiz_method->username = g_strdup (nma_mobile_access_method_get_username (method));
Packit fabffb
					wiz_method->password = g_strdup (nma_mobile_access_method_get_password (method));
Packit fabffb
				}
Packit fabffb
			} else {
Packit fabffb
				family = NMA_MOBILE_FAMILY_3GPP;
Packit fabffb
				wiz_method->gsm_apn = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->plan_unlisted_entry)));
Packit fabffb
			}
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
Packit fabffb
	switch (family) {
Packit fabffb
	case NMA_MOBILE_FAMILY_3GPP:
Packit fabffb
		wiz_method->devtype = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
Packit fabffb
		break;
Packit fabffb
	case NMA_MOBILE_FAMILY_CDMA:
Packit fabffb
		wiz_method->devtype = NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO;
Packit fabffb
		break;
Packit fabffb
	default:
Packit fabffb
		g_assert_not_reached ();
Packit fabffb
		break;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	(*(self->callback)) (self, FALSE, wiz_method, self->user_data);
Packit fabffb
Packit fabffb
	if (provider)
Packit fabffb
		nma_mobile_provider_unref (provider);
Packit fabffb
	g_free (wiz_method->provider_name);
Packit fabffb
	g_free (wiz_method->plan_name);
Packit fabffb
	g_free (wiz_method->username);
Packit fabffb
	g_free (wiz_method->password);
Packit fabffb
	g_free (wiz_method->gsm_apn);
Packit fabffb
	g_free (wiz_method);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
assistant_cancel (GtkButton *button, gpointer user_data)
Packit fabffb
{
Packit fabffb
	NMAMobileWizard *self = user_data;
Packit fabffb
Packit fabffb
	(*(self->callback)) (self, TRUE, NULL, self->user_data);
Packit fabffb
}
Packit fabffb
Packit fabffb
/**********************************************************/
Packit fabffb
/* Confirm page */
Packit fabffb
/**********************************************************/
Packit fabffb
Packit fabffb
static void
Packit fabffb
confirm_setup (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkWidget *vbox, *label, *alignment, *pbox;
Packit fabffb
Packit fabffb
	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit fabffb
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
Packit fabffb
	label = gtk_label_new (_("Your mobile broadband connection is configured with the following settings:"));
Packit fabffb
	gtk_widget_set_size_request (label, 500, -1);
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);
Packit fabffb
Packit fabffb
	/* Device */
Packit fabffb
	self->confirm_device_label = gtk_label_new (_("Your Device:"));
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (self->confirm_device_label), 0, 0.5);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), self->confirm_device_label, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	alignment = gtk_alignment_new (0, 0.5, 0, 0);
Packit fabffb
	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 12, 25, 0);
Packit fabffb
	self->confirm_device = gtk_label_new (NULL);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (alignment), self->confirm_device);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	/* Provider */
Packit fabffb
	label = gtk_label_new (_("Your Provider:"));
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	alignment = gtk_alignment_new (0, 0.5, 0, 0);
Packit fabffb
	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 12, 25, 0);
Packit fabffb
	self->confirm_provider = gtk_label_new (NULL);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (alignment), self->confirm_provider);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	/* Plan and APN */
Packit fabffb
	self->confirm_plan_label = gtk_label_new (_("Your Plan:"));
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (self->confirm_plan_label), 0, 0.5);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), self->confirm_plan_label, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	alignment = gtk_alignment_new (0, 0.5, 0, 0);
Packit fabffb
	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 25, 0);
Packit fabffb
	pbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (alignment), pbox);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	self->confirm_plan = gtk_label_new (NULL);
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (self->confirm_plan), 0, 0.5);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (pbox), self->confirm_plan, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	self->confirm_apn = gtk_label_new (NULL);
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (self->confirm_apn), 0, 0.5);
Packit fabffb
	gtk_misc_set_padding (GTK_MISC (self->confirm_apn), 0, 6);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (pbox), self->confirm_apn, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	if (self->will_connect_after) {
Packit fabffb
		alignment = gtk_alignment_new (0, 0.5, 1, 0);
Packit fabffb
		label = gtk_label_new (_("A connection will now be made to your mobile broadband provider using the settings you selected. If the connection fails or you cannot access network resources, double-check your settings. To modify your mobile broadband connection settings, choose “Network Connections” from the System → Preferences menu."));
Packit fabffb
		gtk_widget_set_size_request (label, 500, -1);
Packit fabffb
		gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
		gtk_misc_set_padding (GTK_MISC (label), 0, 6);
Packit fabffb
		gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
Packit fabffb
		gtk_label_set_max_width_chars (GTK_LABEL (label), 60);
Packit fabffb
		gtk_container_add (GTK_CONTAINER (alignment), label);
Packit fabffb
		gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 6);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	gtk_widget_show_all (vbox);
Packit fabffb
	self->confirm_idx = gtk_assistant_append_page (GTK_ASSISTANT (self->assistant), vbox);
Packit fabffb
	gtk_assistant_set_page_title (GTK_ASSISTANT (self->assistant),
Packit fabffb
	                              vbox, _("Confirm Mobile Broadband Settings"));
Packit fabffb
Packit fabffb
	gtk_assistant_set_page_complete (GTK_ASSISTANT (self->assistant), vbox, TRUE);
Packit fabffb
	gtk_assistant_set_page_type (GTK_ASSISTANT (self->assistant), vbox, GTK_ASSISTANT_PAGE_CONFIRM);
Packit fabffb
Packit fabffb
	self->confirm_page = vbox;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
confirm_prepare (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	NMAMobileProvider *provider = NULL;
Packit fabffb
	NMAMobileAccessMethod *method = NULL;
Packit fabffb
	NMACountryInfo *country_info;
Packit fabffb
	gboolean manual = FALSE;
Packit fabffb
	GString *str;
Packit fabffb
Packit fabffb
	country_info = get_selected_country (self);
Packit fabffb
	provider = get_selected_provider (self);
Packit fabffb
	if (provider)
Packit fabffb
		method = get_selected_method (self, &manual);
Packit fabffb
Packit fabffb
	/* Provider */
Packit fabffb
	str = g_string_new (NULL);
Packit fabffb
	if (provider) {
Packit fabffb
		g_string_append (str, nma_mobile_provider_get_name (provider));
Packit fabffb
		nma_mobile_provider_unref (provider);
Packit fabffb
	} else {
Packit fabffb
		const char *unlisted_provider;
Packit fabffb
Packit fabffb
		unlisted_provider = gtk_entry_get_text (GTK_ENTRY (self->provider_unlisted_entry));
Packit fabffb
		g_string_append (str, unlisted_provider);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (country_info) {
Packit fabffb
		g_string_append_printf (str, ", %s", nma_country_info_get_country_name (country_info));
Packit fabffb
		nma_country_info_unref (country_info);
Packit fabffb
	}
Packit fabffb
	gtk_label_set_text (GTK_LABEL (self->confirm_provider), str->str);
Packit fabffb
	g_string_free (str, TRUE);
Packit fabffb
Packit fabffb
	if (self->dev_desc)
Packit fabffb
		gtk_label_set_text (GTK_LABEL (self->confirm_device), self->dev_desc);
Packit fabffb
	else {
Packit fabffb
		gtk_widget_hide (self->confirm_device_label);
Packit fabffb
		gtk_widget_hide (self->confirm_device);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (self->provider_only_cdma) {
Packit fabffb
		gtk_widget_hide (self->confirm_plan_label);
Packit fabffb
		gtk_widget_hide (self->confirm_plan);
Packit fabffb
		gtk_widget_hide (self->confirm_apn);
Packit fabffb
	} else {
Packit fabffb
		const char *apn = NULL;
Packit fabffb
Packit fabffb
		/* Plan */
Packit fabffb
		gtk_widget_show (self->confirm_plan_label);
Packit fabffb
		gtk_widget_show (self->confirm_plan);
Packit fabffb
		gtk_widget_show (self->confirm_apn);
Packit fabffb
Packit fabffb
		if (method) {
Packit fabffb
			gtk_label_set_text (GTK_LABEL (self->confirm_plan), nma_mobile_access_method_get_name (method));
Packit fabffb
			apn = nma_mobile_access_method_get_3gpp_apn (method);
Packit fabffb
		} else {
Packit fabffb
			gtk_label_set_text (GTK_LABEL (self->confirm_plan), _("Unlisted"));
Packit fabffb
			apn = gtk_entry_get_text (GTK_ENTRY (self->plan_unlisted_entry));
Packit fabffb
		}
Packit fabffb
Packit fabffb
		str = g_string_new (NULL);
Packit fabffb
		g_string_append_printf (str, "APN: %s", apn);
Packit fabffb
		gtk_label_set_markup (GTK_LABEL (self->confirm_apn), str->str);
Packit fabffb
		g_string_free (str, TRUE);
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
/**********************************************************/
Packit fabffb
/* Plan page */
Packit fabffb
/**********************************************************/
Packit fabffb
Packit fabffb
#define PLAN_COL_NAME 0
Packit fabffb
#define PLAN_COL_METHOD 1
Packit fabffb
#define PLAN_COL_MANUAL 2
Packit fabffb
Packit fabffb
static NMAMobileAccessMethod *
Packit fabffb
get_selected_method (NMAMobileWizard *self, gboolean *manual)
Packit fabffb
{
Packit fabffb
	GtkTreeModel *model;
Packit fabffb
	NMAMobileAccessMethod *method = NULL;
Packit fabffb
	GtkTreeIter iter;
Packit fabffb
	gboolean is_manual = FALSE;
Packit fabffb
Packit fabffb
	if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self->plan_combo), &iter))
Packit fabffb
		return NULL;
Packit fabffb
Packit fabffb
	model = gtk_combo_box_get_model (GTK_COMBO_BOX (self->plan_combo));
Packit fabffb
	if (!model)
Packit fabffb
		return NULL;
Packit fabffb
Packit fabffb
	gtk_tree_model_get (model, &iter,
Packit fabffb
	                    PLAN_COL_METHOD, &method,
Packit fabffb
	                    PLAN_COL_MANUAL, &is_manual,
Packit fabffb
	                    -1);
Packit fabffb
	if (is_manual) {
Packit fabffb
		if (manual)
Packit fabffb
			*manual = is_manual;
Packit fabffb
		if (method)
Packit fabffb
			nma_mobile_access_method_unref (method);
Packit fabffb
		method = NULL;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	return method;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
plan_update_complete (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkAssistant *assistant = GTK_ASSISTANT (self->assistant);
Packit fabffb
	gboolean is_manual = FALSE;
Packit fabffb
	NMAMobileAccessMethod *method;
Packit fabffb
Packit fabffb
	method = get_selected_method (self, &is_manual);
Packit fabffb
	if (method) {
Packit fabffb
		gtk_assistant_set_page_complete (assistant, self->plan_page, TRUE);
Packit fabffb
		nma_mobile_access_method_unref (method);
Packit fabffb
	} else {
Packit fabffb
		const char *manual_apn;
Packit fabffb
Packit fabffb
		manual_apn = gtk_entry_get_text (GTK_ENTRY (self->plan_unlisted_entry));
Packit fabffb
		gtk_assistant_set_page_complete (assistant, self->plan_page,
Packit fabffb
		                                 (manual_apn && strlen (manual_apn)));
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
plan_combo_changed (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	NMAMobileAccessMethod *method = NULL;
Packit fabffb
	gboolean is_manual = FALSE;
Packit fabffb
Packit fabffb
	method = get_selected_method (self, &is_manual);
Packit fabffb
	if (method) {
Packit fabffb
		gtk_entry_set_text (GTK_ENTRY (self->plan_unlisted_entry), nma_mobile_access_method_get_3gpp_apn (method));
Packit fabffb
		gtk_widget_set_sensitive (self->plan_unlisted_entry, FALSE);
Packit fabffb
	} else {
Packit fabffb
		gtk_entry_set_text (GTK_ENTRY (self->plan_unlisted_entry), "");
Packit fabffb
		gtk_widget_set_sensitive (self->plan_unlisted_entry, TRUE);
Packit fabffb
		gtk_widget_grab_focus (self->plan_unlisted_entry);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (method)
Packit fabffb
		nma_mobile_access_method_unref (method);
Packit fabffb
Packit fabffb
	plan_update_complete (self);
Packit fabffb
}
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
plan_row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
Packit fabffb
{
Packit fabffb
	NMAMobileAccessMethod *method = NULL;
Packit fabffb
	gboolean is_manual = FALSE;
Packit fabffb
	gboolean draw_separator = FALSE;
Packit fabffb
Packit fabffb
	gtk_tree_model_get (model, iter,
Packit fabffb
	                    PLAN_COL_METHOD, &method,
Packit fabffb
	                    PLAN_COL_MANUAL, &is_manual,
Packit fabffb
	                    -1);
Packit fabffb
	if (!method && !is_manual)
Packit fabffb
		draw_separator = TRUE;
Packit fabffb
	if (method)
Packit fabffb
		nma_mobile_access_method_unref (method);
Packit fabffb
	return draw_separator;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
apn_filter_cb (GtkEditable *editable,
Packit fabffb
               gchar *text,
Packit fabffb
               gint length,
Packit fabffb
               gint *position,
Packit fabffb
               gpointer user_data)
Packit fabffb
{
Packit fabffb
	utils_filter_editable_on_insert_text (editable,
Packit fabffb
	                                      text, length, position, user_data,
Packit fabffb
	                                      utils_char_is_ascii_apn,
Packit fabffb
	                                      apn_filter_cb);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
plan_setup (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkWidget *vbox, *label, *alignment, *hbox, *image;
Packit fabffb
	GtkCellRenderer *renderer;
Packit fabffb
Packit fabffb
	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit fabffb
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
Packit fabffb
Packit fabffb
	label = gtk_label_new_with_mnemonic (_("_Select your plan:"));
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	self->plan_store = gtk_tree_store_new (3, G_TYPE_STRING, NMA_TYPE_MOBILE_ACCESS_METHOD, G_TYPE_BOOLEAN);
Packit fabffb
Packit fabffb
	self->plan_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (self->plan_store));
Packit fabffb
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->plan_combo);
Packit fabffb
	gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (self->plan_combo),
Packit fabffb
	                                      plan_row_separator_func,
Packit fabffb
	                                      NULL,
Packit fabffb
	                                      NULL);
Packit fabffb
Packit fabffb
	renderer = gtk_cell_renderer_text_new ();
Packit fabffb
	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->plan_combo), renderer, TRUE);
Packit fabffb
	gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (self->plan_combo), renderer, "text", PLAN_COL_NAME);
Packit fabffb
Packit fabffb
	g_signal_connect_swapped (self->plan_combo, "changed", G_CALLBACK (plan_combo_changed), self);
Packit fabffb
Packit fabffb
	alignment = gtk_alignment_new (0, 0.5, 0.5, 0);
Packit fabffb
	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 12, 0, 0);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (alignment), self->plan_combo);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	label = gtk_label_new_with_mnemonic (_("Selected plan _APN (Access Point Name):"));
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	self->plan_unlisted_entry = gtk_entry_new ();
Packit fabffb
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->plan_unlisted_entry);
Packit fabffb
	gtk_entry_set_max_length (GTK_ENTRY (self->plan_unlisted_entry), 64);
Packit fabffb
	g_signal_connect (self->plan_unlisted_entry, "insert-text", G_CALLBACK (apn_filter_cb), self);
Packit fabffb
	g_signal_connect_swapped (self->plan_unlisted_entry, "changed", G_CALLBACK (plan_update_complete), self);
Packit fabffb
Packit fabffb
	alignment = gtk_alignment_new (0, 0.5, 0.5, 0);
Packit fabffb
	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 24, 0, 0);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (alignment), self->plan_unlisted_entry);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
Packit fabffb
	image = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_DIALOG);
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	label = gtk_label_new (_("Warning: Selecting an incorrect plan may result in billing issues for your broadband account or may prevent connectivity.\n\nIf you are unsure of your plan please ask your provider for your plan’s APN."));
Packit fabffb
	gtk_widget_set_size_request (label, 500, -1);
Packit fabffb
	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
Packit fabffb
	gtk_label_set_max_width_chars (GTK_LABEL (label), 60);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	self->plan_idx = gtk_assistant_append_page (GTK_ASSISTANT (self->assistant), vbox);
Packit fabffb
	gtk_assistant_set_page_title (GTK_ASSISTANT (self->assistant), vbox, _("Choose your Billing Plan"));
Packit fabffb
	gtk_assistant_set_page_type (GTK_ASSISTANT (self->assistant), vbox, GTK_ASSISTANT_PAGE_CONTENT);
Packit fabffb
	gtk_widget_show_all (vbox);
Packit fabffb
Packit fabffb
	self->plan_page = vbox;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
plan_prepare (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	NMAMobileProvider *provider;
Packit fabffb
	GtkTreeIter method_iter;
Packit fabffb
Packit fabffb
	gtk_tree_store_clear (self->plan_store);
Packit fabffb
Packit fabffb
	provider = get_selected_provider (self);
Packit fabffb
	if (provider) {
Packit fabffb
		GSList *iter;
Packit fabffb
		guint32 count = 0;
Packit fabffb
Packit fabffb
		for (iter = nma_mobile_provider_get_methods (provider); iter; iter = g_slist_next (iter)) {
Packit fabffb
			NMAMobileAccessMethod *method = iter->data;
Packit fabffb
Packit fabffb
			if (   (self->family != NMA_MOBILE_FAMILY_UNKNOWN)
Packit fabffb
			    && (nma_mobile_access_method_get_family (method) != self->family))
Packit fabffb
				continue;
Packit fabffb
Packit fabffb
			gtk_tree_store_append (GTK_TREE_STORE (self->plan_store), &method_iter, NULL);
Packit fabffb
			gtk_tree_store_set (GTK_TREE_STORE (self->plan_store),
Packit fabffb
			                    &method_iter,
Packit fabffb
			                    PLAN_COL_NAME,
Packit fabffb
			                    nma_mobile_access_method_get_name (method),
Packit fabffb
			                    PLAN_COL_METHOD,
Packit fabffb
			                    method,
Packit fabffb
			                    -1);
Packit fabffb
			count++;
Packit fabffb
		}
Packit fabffb
		nma_mobile_provider_unref (provider);
Packit fabffb
Packit fabffb
		/* Draw the separator */
Packit fabffb
		if (count)
Packit fabffb
			gtk_tree_store_append (GTK_TREE_STORE (self->plan_store), &method_iter, NULL);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* Add the "My plan is not listed..." item */
Packit fabffb
	gtk_tree_store_append (GTK_TREE_STORE (self->plan_store), &method_iter, NULL);
Packit fabffb
	gtk_tree_store_set (GTK_TREE_STORE (self->plan_store),
Packit fabffb
	                    &method_iter,
Packit fabffb
	                    PLAN_COL_NAME,
Packit fabffb
	                    _("My plan is not listed…"),
Packit fabffb
	                    PLAN_COL_MANUAL,
Packit fabffb
	                    TRUE,
Packit fabffb
	                    -1);
Packit fabffb
Packit fabffb
	/* Select the first item by default if nothing is yet selected */
Packit fabffb
	if (gtk_combo_box_get_active (GTK_COMBO_BOX (self->plan_combo)) < 0)
Packit fabffb
		gtk_combo_box_set_active (GTK_COMBO_BOX (self->plan_combo), 0);
Packit fabffb
Packit fabffb
	plan_combo_changed (self);
Packit fabffb
}
Packit fabffb
Packit fabffb
/**********************************************************/
Packit fabffb
/* Providers page */
Packit fabffb
/**********************************************************/
Packit fabffb
Packit fabffb
#define PROVIDER_COL_NAME 0
Packit fabffb
#define PROVIDER_COL_PROVIDER 1
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
providers_search_func (GtkTreeModel *model,
Packit fabffb
                       gint column,
Packit fabffb
                       const char *key,
Packit fabffb
                       GtkTreeIter *iter,
Packit fabffb
                       gpointer search_data)
Packit fabffb
{
Packit fabffb
	gboolean unmatched = TRUE;
Packit fabffb
	char *provider = NULL;
Packit fabffb
Packit fabffb
	if (!key)
Packit fabffb
		return TRUE;
Packit fabffb
Packit fabffb
	gtk_tree_model_get (model, iter, column, &provider, -1);
Packit fabffb
	if (!provider)
Packit fabffb
		return TRUE;
Packit fabffb
Packit fabffb
	unmatched = !!g_ascii_strncasecmp (provider, key, strlen (key));
Packit fabffb
	g_free (provider);
Packit fabffb
	return unmatched;
Packit fabffb
}
Packit fabffb
Packit fabffb
static NMAMobileProvider *
Packit fabffb
get_selected_provider (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkTreeSelection *selection;
Packit fabffb
	GtkTreeModel *model = NULL;
Packit fabffb
	GtkTreeIter iter;
Packit fabffb
	NMAMobileProvider *provider = NULL;
Packit fabffb
Packit fabffb
	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->providers_view_radio)))
Packit fabffb
		return NULL;
Packit fabffb
Packit fabffb
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->providers_view));
Packit fabffb
	g_assert (selection);
Packit fabffb
Packit fabffb
	if (!gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter))
Packit fabffb
		return NULL;
Packit fabffb
Packit fabffb
	gtk_tree_model_get (model, &iter, PROVIDER_COL_PROVIDER, &provider, -1);
Packit fabffb
	return provider;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
providers_update_complete (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkAssistant *assistant = GTK_ASSISTANT (self->assistant);
Packit fabffb
	gboolean use_view;
Packit fabffb
Packit fabffb
	use_view = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->providers_view_radio));
Packit fabffb
	if (use_view) {
Packit fabffb
		NMAMobileProvider *provider;
Packit fabffb
Packit fabffb
		provider = get_selected_provider (self);
Packit fabffb
		gtk_assistant_set_page_complete (assistant, self->providers_page, !!provider);
Packit fabffb
		if (provider)
Packit fabffb
			nma_mobile_provider_unref (provider);
Packit fabffb
	} else {
Packit fabffb
		const char *manual_provider;
Packit fabffb
Packit fabffb
		manual_provider = gtk_entry_get_text (GTK_ENTRY (self->provider_unlisted_entry));
Packit fabffb
		gtk_assistant_set_page_complete (assistant, self->providers_page,
Packit fabffb
		                                 (manual_provider && strlen (manual_provider)));
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
focus_providers_view (gpointer user_data)
Packit fabffb
{
Packit fabffb
	NMAMobileWizard *self = user_data;
Packit fabffb
Packit fabffb
	self->providers_focus_id = 0;
Packit fabffb
	gtk_widget_grab_focus (self->providers_view);
Packit fabffb
	return FALSE;
Packit fabffb
}
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
focus_provider_unlisted_entry (gpointer user_data)
Packit fabffb
{
Packit fabffb
	NMAMobileWizard *self = user_data;
Packit fabffb
Packit fabffb
	self->providers_focus_id = 0;
Packit fabffb
	gtk_widget_grab_focus (self->provider_unlisted_entry);
Packit fabffb
	return FALSE;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
providers_radio_toggled (GtkToggleButton *button, gpointer user_data)
Packit fabffb
{
Packit fabffb
	NMAMobileWizard *self = user_data;
Packit fabffb
	gboolean use_view;
Packit fabffb
Packit fabffb
	use_view = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->providers_view_radio));
Packit fabffb
	if (use_view) {
Packit fabffb
		if (!self->providers_focus_id)
Packit fabffb
			self->providers_focus_id = g_idle_add (focus_providers_view, self);
Packit fabffb
		gtk_widget_set_sensitive (self->providers_view, TRUE);
Packit fabffb
		gtk_widget_set_sensitive (self->provider_unlisted_entry, FALSE);
Packit fabffb
		gtk_widget_set_sensitive (self->provider_unlisted_type_combo, FALSE);
Packit fabffb
	} else {
Packit fabffb
		if (!self->providers_focus_id)
Packit fabffb
			self->providers_focus_id = g_idle_add (focus_provider_unlisted_entry, self);
Packit fabffb
		gtk_widget_set_sensitive (self->providers_view, FALSE);
Packit fabffb
		gtk_widget_set_sensitive (self->provider_unlisted_entry, TRUE);
Packit fabffb
		gtk_widget_set_sensitive (self->provider_unlisted_type_combo, TRUE);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	providers_update_complete (self);
Packit fabffb
}
Packit fabffb
Packit fabffb
static NMAMobileFamily
Packit fabffb
get_provider_unlisted_type (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	switch (gtk_combo_box_get_active (GTK_COMBO_BOX (self->provider_unlisted_type_combo))) {
Packit fabffb
	case 0:
Packit fabffb
		return NMA_MOBILE_FAMILY_3GPP;
Packit fabffb
	case 1:
Packit fabffb
		return NMA_MOBILE_FAMILY_CDMA;
Packit fabffb
	default:
Packit fabffb
		return NMA_MOBILE_FAMILY_UNKNOWN;
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
providers_setup (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkWidget *vbox, *scroll, *alignment, *unlisted_grid, *label;
Packit fabffb
	GtkCellRenderer *renderer;
Packit fabffb
	GtkTreeViewColumn *column;
Packit fabffb
	GtkTreeSelection *selection;
Packit fabffb
Packit fabffb
	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit fabffb
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
Packit fabffb
Packit fabffb
	self->providers_view_radio = gtk_radio_button_new_with_mnemonic (NULL, _("Select your provider from a _list:"));
Packit fabffb
	g_signal_connect (self->providers_view_radio, "toggled", G_CALLBACK (providers_radio_toggled), self);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), self->providers_view_radio, FALSE, TRUE, 0);
Packit fabffb
Packit fabffb
	self->providers_store = gtk_tree_store_new (2, G_TYPE_STRING, NMA_TYPE_MOBILE_PROVIDER);
Packit fabffb
Packit fabffb
	self->providers_sort = GTK_TREE_MODEL_SORT (gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->providers_store)));
Packit fabffb
	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self->providers_sort),
Packit fabffb
	                                      PROVIDER_COL_NAME, GTK_SORT_ASCENDING);
Packit fabffb
Packit fabffb
	self->providers_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->providers_sort));
Packit fabffb
Packit fabffb
	renderer = gtk_cell_renderer_text_new ();
Packit fabffb
	column = gtk_tree_view_column_new_with_attributes (_("Provider"),
Packit fabffb
	                                                   renderer,
Packit fabffb
	                                                   "text", PROVIDER_COL_NAME,
Packit fabffb
	                                                   NULL);
Packit fabffb
	gtk_tree_view_append_column (GTK_TREE_VIEW (self->providers_view), column);
Packit fabffb
	gtk_tree_view_column_set_clickable (column, TRUE);
Packit fabffb
Packit fabffb
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->providers_view));
Packit fabffb
	g_assert (selection);
Packit fabffb
	g_signal_connect_swapped (selection, "changed", G_CALLBACK (providers_update_complete), self);
Packit fabffb
Packit fabffb
	scroll = gtk_scrolled_window_new (NULL, NULL);
Packit fabffb
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
Packit fabffb
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
Packit fabffb
	                                GTK_POLICY_NEVER,
Packit fabffb
	                                GTK_POLICY_AUTOMATIC);
Packit fabffb
	gtk_widget_set_size_request (scroll, -1, 140);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (scroll), self->providers_view);
Packit fabffb
Packit fabffb
	alignment = gtk_alignment_new (0, 0, 1, 1);
Packit fabffb
	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 12, 25, 0);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (alignment), scroll);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), alignment, TRUE, TRUE, 0);
Packit fabffb
Packit fabffb
	self->provider_unlisted_radio = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (self->providers_view_radio),
Packit fabffb
	                                            _("I can’t find my provider and I wish to enter it _manually:"));
Packit fabffb
	g_signal_connect (self->providers_view_radio, "toggled", G_CALLBACK (providers_radio_toggled), self);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), self->provider_unlisted_radio, FALSE, TRUE, 0);
Packit fabffb
Packit fabffb
	alignment = gtk_alignment_new (0, 0, 0, 0);
Packit fabffb
	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 15, 0);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
	unlisted_grid = gtk_grid_new ();
Packit fabffb
	gtk_grid_set_row_spacing (GTK_GRID (unlisted_grid), 12);
Packit fabffb
	gtk_grid_set_column_spacing (GTK_GRID (unlisted_grid), 12);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (alignment), unlisted_grid);
Packit fabffb
Packit fabffb
	label = gtk_label_new (_("Provider:"));
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
Packit fabffb
	gtk_grid_attach (GTK_GRID (unlisted_grid), label, 0, 0, 1, 1);
Packit fabffb
Packit fabffb
	self->provider_unlisted_entry = gtk_entry_new ();
Packit fabffb
	gtk_entry_set_width_chars (GTK_ENTRY (self->provider_unlisted_entry), 40);
Packit fabffb
	g_signal_connect_swapped (self->provider_unlisted_entry, "changed", G_CALLBACK (providers_update_complete), self);
Packit fabffb
Packit fabffb
	alignment = gtk_alignment_new (0, 0.5, 0.66, 0);
Packit fabffb
	gtk_widget_set_hexpand (alignment, TRUE);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (alignment), self->provider_unlisted_entry);
Packit fabffb
	gtk_grid_attach (GTK_GRID (unlisted_grid), alignment,
Packit fabffb
	                 1, 0, 1, 1);
Packit fabffb
Packit fabffb
	self->provider_unlisted_type_combo = gtk_combo_box_text_new ();
Packit fabffb
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->provider_unlisted_type_combo);
Packit fabffb
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->provider_unlisted_type_combo),
Packit fabffb
	                           _("My provider uses GSM technology (GPRS, EDGE, UMTS, HSPA)"));
Packit fabffb
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->provider_unlisted_type_combo),
Packit fabffb
	                           _("My provider uses CDMA technology (1xRTT, EVDO)"));
Packit fabffb
	gtk_combo_box_set_active (GTK_COMBO_BOX (self->provider_unlisted_type_combo), 0);
Packit fabffb
Packit fabffb
	gtk_grid_attach (GTK_GRID (unlisted_grid), self->provider_unlisted_type_combo,
Packit fabffb
	                 1, 1, 1, 1);
Packit fabffb
Packit fabffb
	/* Only show the CDMA/GSM combo if we don't know the device type */
Packit fabffb
	if (self->family != NMA_MOBILE_FAMILY_UNKNOWN)
Packit fabffb
		gtk_widget_hide (self->provider_unlisted_type_combo);
Packit fabffb
Packit fabffb
	self->providers_idx = gtk_assistant_append_page (GTK_ASSISTANT (self->assistant), vbox);
Packit fabffb
	gtk_assistant_set_page_title (GTK_ASSISTANT (self->assistant), vbox, _("Choose your Provider"));
Packit fabffb
	gtk_assistant_set_page_type (GTK_ASSISTANT (self->assistant), vbox, GTK_ASSISTANT_PAGE_CONTENT);
Packit fabffb
	gtk_widget_show_all (vbox);
Packit fabffb
Packit fabffb
	self->providers_page = vbox;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
providers_prepare (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkTreeSelection *selection;
Packit fabffb
	NMACountryInfo *country_info;
Packit fabffb
	GSList *piter;
Packit fabffb
Packit fabffb
	gtk_tree_store_clear (self->providers_store);
Packit fabffb
Packit fabffb
	country_info = get_selected_country (self);
Packit fabffb
	if (!country_info) {
Packit fabffb
		/* Unlisted country */
Packit fabffb
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->provider_unlisted_radio), TRUE);
Packit fabffb
		gtk_widget_set_sensitive (GTK_WIDGET (self->providers_view_radio), FALSE);
Packit fabffb
		goto done;
Packit fabffb
	}
Packit fabffb
	gtk_widget_set_sensitive (GTK_WIDGET (self->providers_view_radio), TRUE);
Packit fabffb
Packit fabffb
	for (piter = nma_country_info_get_providers (country_info);
Packit fabffb
	     piter;
Packit fabffb
	     piter = g_slist_next (piter)) {
Packit fabffb
		NMAMobileProvider *provider = piter->data;
Packit fabffb
		GtkTreeIter provider_iter;
Packit fabffb
Packit fabffb
		/* Ignore providers that don't match the current device type */
Packit fabffb
		if (self->family != NMA_MOBILE_FAMILY_UNKNOWN) {
Packit fabffb
			GSList *miter;
Packit fabffb
			guint32 count = 0;
Packit fabffb
Packit fabffb
			for (miter = nma_mobile_provider_get_methods (provider); miter; miter = g_slist_next (miter)) {
Packit fabffb
				NMAMobileAccessMethod *method = miter->data;
Packit fabffb
Packit fabffb
				if (self->family == nma_mobile_access_method_get_family (method))
Packit fabffb
					count++;
Packit fabffb
			}
Packit fabffb
Packit fabffb
			if (!count)
Packit fabffb
				continue;
Packit fabffb
		}
Packit fabffb
Packit fabffb
		gtk_tree_store_append (GTK_TREE_STORE (self->providers_store), &provider_iter, NULL);
Packit fabffb
		gtk_tree_store_set (GTK_TREE_STORE (self->providers_store),
Packit fabffb
		                    &provider_iter,
Packit fabffb
		                    PROVIDER_COL_NAME,
Packit fabffb
		                    nma_mobile_provider_get_name (provider),
Packit fabffb
		                    PROVIDER_COL_PROVIDER,
Packit fabffb
		                    provider,
Packit fabffb
		                    -1);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	nma_country_info_unref (country_info);
Packit fabffb
Packit fabffb
	g_object_set (G_OBJECT (self->providers_view), "enable-search", TRUE, NULL);
Packit fabffb
Packit fabffb
	gtk_tree_view_set_search_column (GTK_TREE_VIEW (self->providers_view), PROVIDER_COL_NAME);
Packit fabffb
	gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->providers_view),
Packit fabffb
	                                     providers_search_func, self, NULL);
Packit fabffb
Packit fabffb
	/* If no row has focus yet, focus the first row so that the user can start
Packit fabffb
	 * incremental search without clicking.
Packit fabffb
	 */
Packit fabffb
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->providers_view));
Packit fabffb
	g_assert (selection);
Packit fabffb
	if (!gtk_tree_selection_count_selected_rows (selection)) {
Packit fabffb
		GtkTreeIter first_iter;
Packit fabffb
		GtkTreePath *first_path;
Packit fabffb
Packit fabffb
		if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->providers_sort), &first_iter)) {
Packit fabffb
			first_path = gtk_tree_model_get_path (GTK_TREE_MODEL (self->providers_sort), &first_iter);
Packit fabffb
			if (first_path) {
Packit fabffb
				gtk_tree_selection_select_path (selection, first_path);
Packit fabffb
				gtk_tree_path_free (first_path);
Packit fabffb
			}
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
Packit fabffb
done:
Packit fabffb
	providers_radio_toggled (NULL, self);
Packit fabffb
Packit fabffb
	/* Initial completeness state */
Packit fabffb
	providers_update_complete (self);
Packit fabffb
Packit fabffb
	/* If there's already a selected device, hide the GSM/CDMA radios */
Packit fabffb
	if (self->family != NMA_MOBILE_FAMILY_UNKNOWN)
Packit fabffb
		gtk_widget_hide (self->provider_unlisted_type_combo);
Packit fabffb
	else
Packit fabffb
		gtk_widget_show (self->provider_unlisted_type_combo);
Packit fabffb
}
Packit fabffb
Packit fabffb
/**********************************************************/
Packit fabffb
/* Country page */
Packit fabffb
/**********************************************************/
Packit fabffb
Packit fabffb
#define COUNTRIES_COL_NAME 0
Packit fabffb
#define COUNTRIES_COL_INFO 1
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
country_search_func (GtkTreeModel *model,
Packit fabffb
                     gint column,
Packit fabffb
                     const char *key,
Packit fabffb
                     GtkTreeIter *iter,
Packit fabffb
                     gpointer search_data)
Packit fabffb
{
Packit fabffb
	gboolean unmatched = TRUE;
Packit fabffb
	char *country = NULL;
Packit fabffb
Packit fabffb
	if (!key)
Packit fabffb
		return TRUE;
Packit fabffb
Packit fabffb
	gtk_tree_model_get (model, iter, column, &country, -1);
Packit fabffb
	if (!country)
Packit fabffb
		return TRUE;
Packit fabffb
Packit fabffb
	unmatched = !!g_ascii_strncasecmp (country, key, strlen (key));
Packit fabffb
	g_free (country);
Packit fabffb
	return unmatched;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
add_one_country (gpointer key, gpointer value, gpointer user_data)
Packit fabffb
{
Packit fabffb
	NMAMobileWizard *self = user_data;
Packit fabffb
	NMACountryInfo *country_info = value;
Packit fabffb
	GtkTreeIter country_iter;
Packit fabffb
	GtkTreePath *country_path, *country_view_path;
Packit fabffb
Packit fabffb
	g_assert (key);
Packit fabffb
Packit fabffb
	gtk_tree_store_append (GTK_TREE_STORE (self->country_store), &country_iter, NULL);
Packit fabffb
	gtk_tree_store_set (GTK_TREE_STORE (self->country_store),
Packit fabffb
	                    &country_iter,
Packit fabffb
	                    COUNTRIES_COL_NAME,
Packit fabffb
	                    nma_country_info_get_country_name (country_info),
Packit fabffb
	                    COUNTRIES_COL_INFO,
Packit fabffb
	                    country_info,
Packit fabffb
	                    -1);
Packit fabffb
Packit fabffb
	/* If this country is the same country as the user's current locale,
Packit fabffb
	 * select it by default.
Packit fabffb
	 */
Packit fabffb
	if (self->country != country_info)
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	country_path = gtk_tree_model_get_path (GTK_TREE_MODEL (self->country_store), &country_iter);
Packit fabffb
	if (!country_path)
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	country_view_path = gtk_tree_model_sort_convert_child_path_to_path (self->country_sort, country_path);
Packit fabffb
	if (country_view_path) {
Packit fabffb
		GtkTreeSelection *selection;
Packit fabffb
Packit fabffb
		gtk_tree_view_expand_row (GTK_TREE_VIEW (self->country_view), country_view_path, TRUE);
Packit fabffb
Packit fabffb
		selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->country_view));
Packit fabffb
		g_assert (selection);
Packit fabffb
		gtk_tree_selection_select_path (selection, country_view_path);
Packit fabffb
		gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (self->country_view),
Packit fabffb
		                              country_view_path, NULL, TRUE, 0, 0);
Packit fabffb
		gtk_tree_path_free (country_view_path);
Packit fabffb
	}
Packit fabffb
	gtk_tree_path_free (country_path);
Packit fabffb
}
Packit fabffb
Packit fabffb
NMACountryInfo *
Packit fabffb
get_selected_country (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkTreeSelection *selection;
Packit fabffb
	GtkTreeModel *model = NULL;
Packit fabffb
	GtkTreeIter iter;
Packit fabffb
	NMACountryInfo *country_info = NULL;
Packit fabffb
Packit fabffb
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->country_view));
Packit fabffb
	g_assert (selection);
Packit fabffb
Packit fabffb
	if (!gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter))
Packit fabffb
		return NULL;
Packit fabffb
Packit fabffb
	gtk_tree_model_get (model, &iter, COUNTRIES_COL_INFO, &country_info, -1);
Packit fabffb
	return country_info;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
country_update_complete (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	NMACountryInfo *country_info;
Packit fabffb
Packit fabffb
	country_info = get_selected_country (self);
Packit fabffb
	gtk_assistant_set_page_complete (GTK_ASSISTANT (self->assistant),
Packit fabffb
	                                 self->country_page,
Packit fabffb
	                                 (!!country_info));
Packit fabffb
	if (country_info)
Packit fabffb
		nma_country_info_unref (country_info);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
country_update_continue (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	gtk_assistant_set_page_complete (GTK_ASSISTANT (self->assistant),
Packit fabffb
	                                 self->country_page,
Packit fabffb
	                                 TRUE);
Packit fabffb
Packit fabffb
	gtk_assistant_next_page (GTK_ASSISTANT (self->assistant));
Packit fabffb
}
Packit fabffb
Packit fabffb
static gint
Packit fabffb
country_sort_func (GtkTreeModel *model,
Packit fabffb
                   GtkTreeIter *a,
Packit fabffb
                   GtkTreeIter *b,
Packit fabffb
                   gpointer user_data)
Packit fabffb
{
Packit fabffb
	char *a_str = NULL, *b_str = NULL;
Packit fabffb
	NMACountryInfo *a_country_info = NULL, *b_country_info = NULL;
Packit fabffb
	gint ret = 0;
Packit fabffb
Packit fabffb
	gtk_tree_model_get (model, a, COUNTRIES_COL_NAME, &a_str, COUNTRIES_COL_INFO, &a_country_info, -1);
Packit fabffb
	gtk_tree_model_get (model, b, COUNTRIES_COL_NAME, &b_str, COUNTRIES_COL_INFO, &b_country_info, -1);
Packit fabffb
Packit fabffb
	if (!a_country_info) {
Packit fabffb
		ret = -1;
Packit fabffb
		goto out;
Packit fabffb
	} else if (!b_country_info) {
Packit fabffb
		ret = 1;
Packit fabffb
		goto out;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (a_str && !b_str)
Packit fabffb
		ret = -1;
Packit fabffb
	else if (!a_str && b_str)
Packit fabffb
		ret = 1;
Packit fabffb
	else if (!a_str && !b_str)
Packit fabffb
		ret = 0;
Packit fabffb
	else
Packit fabffb
		ret = g_utf8_collate (a_str, b_str);
Packit fabffb
Packit fabffb
out:
Packit fabffb
	if (a_country_info)
Packit fabffb
		nma_country_info_unref (a_country_info);
Packit fabffb
	if (b_country_info)
Packit fabffb
		nma_country_info_unref (b_country_info);
Packit fabffb
	g_free (a_str);
Packit fabffb
	g_free (b_str);
Packit fabffb
	return ret;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
country_setup (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkWidget *vbox, *label, *scroll, *alignment;
Packit fabffb
	GtkCellRenderer *renderer;
Packit fabffb
	GtkTreeViewColumn *column;
Packit fabffb
	GtkTreeSelection *selection;
Packit fabffb
	GtkTreeIter unlisted_iter;
Packit fabffb
Packit fabffb
	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit fabffb
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
Packit fabffb
	label = gtk_label_new (_("Country or Region List:"));
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
Packit fabffb
Packit fabffb
	self->country_store = gtk_tree_store_new (2, G_TYPE_STRING, NMA_TYPE_COUNTRY_INFO);
Packit fabffb
Packit fabffb
	self->country_sort = GTK_TREE_MODEL_SORT (gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->country_store)));
Packit fabffb
	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self->country_sort),
Packit fabffb
	                                      COUNTRIES_COL_NAME, GTK_SORT_ASCENDING);
Packit fabffb
Packit fabffb
	self->country_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->country_sort));
Packit fabffb
Packit fabffb
	renderer = gtk_cell_renderer_text_new ();
Packit fabffb
	column = gtk_tree_view_column_new_with_attributes (_("Country or region"),
Packit fabffb
	                                                   renderer,
Packit fabffb
	                                                   "text", COUNTRIES_COL_NAME,
Packit fabffb
	                                                   NULL);
Packit fabffb
	gtk_tree_view_append_column (GTK_TREE_VIEW (self->country_view), column);
Packit fabffb
	gtk_tree_view_column_set_clickable (column, TRUE);
Packit fabffb
Packit fabffb
	/* My country is not listed... */
Packit fabffb
	gtk_tree_store_append (GTK_TREE_STORE (self->country_store), &unlisted_iter, NULL);
Packit fabffb
	gtk_tree_store_set (GTK_TREE_STORE (self->country_store), &unlisted_iter,
Packit fabffb
	                    PROVIDER_COL_NAME, _("My country is not listed"),
Packit fabffb
	                    PROVIDER_COL_PROVIDER, NULL,
Packit fabffb
	                    -1);
Packit fabffb
	gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (self->country_sort),
Packit fabffb
	                                 COUNTRIES_COL_NAME,
Packit fabffb
	                                 country_sort_func,
Packit fabffb
	                                 NULL,
Packit fabffb
	                                 NULL);
Packit fabffb
Packit fabffb
	/* Add the rest of the providers */
Packit fabffb
	if (self->mobile_providers_database) {
Packit fabffb
		GHashTable *countries;
Packit fabffb
Packit fabffb
		countries = nma_mobile_providers_database_get_countries (self->mobile_providers_database);
Packit fabffb
		g_hash_table_foreach (countries, add_one_country, self);
Packit fabffb
	}
Packit fabffb
	g_object_set (G_OBJECT (self->country_view), "enable-search", TRUE, NULL);
Packit fabffb
Packit fabffb
	/* If no row has focus yet, focus the first row so that the user can start
Packit fabffb
	 * incremental search without clicking.
Packit fabffb
	 */
Packit fabffb
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->country_view));
Packit fabffb
	g_assert (selection);
Packit fabffb
	if (!gtk_tree_selection_count_selected_rows (selection)) {
Packit fabffb
		GtkTreeIter first_iter;
Packit fabffb
		GtkTreePath *first_path;
Packit fabffb
Packit fabffb
		if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->country_sort), &first_iter)) {
Packit fabffb
			first_path = gtk_tree_model_get_path (GTK_TREE_MODEL (self->country_sort), &first_iter);
Packit fabffb
			if (first_path) {
Packit fabffb
				gtk_tree_selection_select_path (selection, first_path);
Packit fabffb
				gtk_tree_path_free (first_path);
Packit fabffb
			}
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
Packit fabffb
	g_signal_connect_swapped (selection, "changed", G_CALLBACK (country_update_complete), self);
Packit fabffb
Packit fabffb
	scroll = gtk_scrolled_window_new (NULL, NULL);
Packit fabffb
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
Packit fabffb
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
Packit fabffb
	                                GTK_POLICY_NEVER,
Packit fabffb
	                                GTK_POLICY_AUTOMATIC);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (scroll), self->country_view);
Packit fabffb
Packit fabffb
	alignment = gtk_alignment_new (0, 0, 1, 1);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (alignment), scroll);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), alignment, TRUE, TRUE, 6);
Packit fabffb
Packit fabffb
	self->country_idx = gtk_assistant_append_page (GTK_ASSISTANT (self->assistant), vbox);
Packit fabffb
	gtk_assistant_set_page_title (GTK_ASSISTANT (self->assistant), vbox, _("Choose your Provider’s Country or Region"));
Packit fabffb
	gtk_assistant_set_page_type (GTK_ASSISTANT (self->assistant), vbox, GTK_ASSISTANT_PAGE_CONTENT);
Packit fabffb
	gtk_assistant_set_page_complete (GTK_ASSISTANT (self->assistant), vbox, TRUE);
Packit fabffb
	gtk_widget_show_all (vbox);
Packit fabffb
Packit fabffb
	self->country_page = vbox;
Packit fabffb
Packit fabffb
	/* If the user presses the ENTER key after selecting the country, continue to the next page */
Packit fabffb
	g_signal_connect_swapped (self->country_view, "row-activated", G_CALLBACK (country_update_continue), self);
Packit fabffb
Packit fabffb
	/* Initial completeness state */
Packit fabffb
	country_update_complete (self);
Packit fabffb
}
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
focus_country_view (gpointer user_data)
Packit fabffb
{
Packit fabffb
	NMAMobileWizard *self = user_data;
Packit fabffb
Packit fabffb
	self->country_focus_id = 0;
Packit fabffb
	gtk_widget_grab_focus (self->country_view);
Packit fabffb
	return FALSE;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
country_prepare (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	gtk_tree_view_set_search_column (GTK_TREE_VIEW (self->country_view), COUNTRIES_COL_NAME);
Packit fabffb
	gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->country_view), country_search_func, self, NULL);
Packit fabffb
Packit fabffb
	if (!self->country_focus_id)
Packit fabffb
		self->country_focus_id = g_idle_add (focus_country_view, self);
Packit fabffb
Packit fabffb
	country_update_complete (self);
Packit fabffb
}
Packit fabffb
Packit fabffb
/**********************************************************/
Packit fabffb
/* Intro page */
Packit fabffb
/**********************************************************/
Packit fabffb
Packit fabffb
#define INTRO_COL_NAME 0
Packit fabffb
#define INTRO_COL_DEVICE 1
Packit fabffb
#define INTRO_COL_SEPARATOR 2
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
__intro_device_added (NMAMobileWizard *self, NMDevice *device, gboolean select_it)
Packit fabffb
{
Packit fabffb
	GtkTreeIter iter;
Packit fabffb
	const char *desc = nma_utils_get_device_description (device);
Packit fabffb
	NMDeviceModemCapabilities caps;
Packit fabffb
Packit fabffb
	if (!NM_IS_DEVICE_MODEM (device))
Packit fabffb
		return FALSE;
Packit fabffb
Packit fabffb
	caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
Packit fabffb
	if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) {
Packit fabffb
		if (!desc)
Packit fabffb
			desc = _("Installed GSM device");
Packit fabffb
	} else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) {
Packit fabffb
		if (!desc)
Packit fabffb
			desc = _("Installed CDMA device");
Packit fabffb
	} else
Packit fabffb
		return FALSE;
Packit fabffb
Packit fabffb
	gtk_tree_store_append (GTK_TREE_STORE (self->dev_store), &iter, NULL);
Packit fabffb
	gtk_tree_store_set (GTK_TREE_STORE (self->dev_store),
Packit fabffb
	                    &iter,
Packit fabffb
	                    INTRO_COL_NAME, desc,
Packit fabffb
	                    INTRO_COL_DEVICE, device,
Packit fabffb
	                    -1);
Packit fabffb
Packit fabffb
	/* Select the device just added */
Packit fabffb
	if (select_it)
Packit fabffb
		gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->dev_combo), &iter);
Packit fabffb
Packit fabffb
	gtk_widget_set_sensitive (self->dev_combo, TRUE);
Packit fabffb
	return TRUE;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
intro_device_added_cb (NMClient *client, NMDevice *device, NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	__intro_device_added (self, device, TRUE);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
intro_device_removed_cb (NMClient *client, NMDevice *device, NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkTreeIter iter;
Packit fabffb
	gboolean have_device = FALSE, removed = FALSE;
Packit fabffb
Packit fabffb
	if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->dev_store), &iter))
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	do {
Packit fabffb
		NMDevice *candidate = NULL;
Packit fabffb
Packit fabffb
		gtk_tree_model_get (GTK_TREE_MODEL (self->dev_store), &iter,
Packit fabffb
		                    INTRO_COL_DEVICE, &candidate, -1);
Packit fabffb
		if (candidate) {
Packit fabffb
			if (candidate == device) {
Packit fabffb
				gtk_tree_store_remove (GTK_TREE_STORE (self->dev_store), &iter);
Packit fabffb
				removed = TRUE;
Packit fabffb
			}
Packit fabffb
			g_object_unref (candidate);
Packit fabffb
		}
Packit fabffb
	} while (!removed && gtk_tree_model_iter_next (GTK_TREE_MODEL (self->dev_store), &iter));
Packit fabffb
Packit fabffb
	/* There's already a selected device item; nothing more to do */
Packit fabffb
	if (gtk_combo_box_get_active (GTK_COMBO_BOX (self->dev_combo)) > 1)
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	/* If there are no more devices, select the "Any" item and disable the
Packit fabffb
	 * combo box.  If there is no selected item and there is at least one device
Packit fabffb
	 * item, select the first one.
Packit fabffb
	 */
Packit fabffb
	if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->dev_store), &iter))
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	do {
Packit fabffb
		NMDevice *candidate = NULL;
Packit fabffb
Packit fabffb
		gtk_tree_model_get (GTK_TREE_MODEL (self->dev_store), &iter,
Packit fabffb
		                    INTRO_COL_DEVICE, &candidate, -1);
Packit fabffb
		if (candidate) {
Packit fabffb
			have_device = TRUE;
Packit fabffb
			g_object_unref (candidate);
Packit fabffb
		}
Packit fabffb
	} while (!have_device && gtk_tree_model_iter_next (GTK_TREE_MODEL (self->dev_store), &iter));
Packit fabffb
Packit fabffb
	if (have_device) {
Packit fabffb
		/* Iter should point to the last device item in the combo */
Packit fabffb
		gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->dev_combo), &iter);
Packit fabffb
	} else {
Packit fabffb
		gtk_combo_box_set_active (GTK_COMBO_BOX (self->dev_combo), 0);
Packit fabffb
		gtk_widget_set_sensitive (self->dev_combo, FALSE);
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
intro_add_initial_devices (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	const GPtrArray *devices;
Packit fabffb
	gboolean selected_first = FALSE;
Packit fabffb
	int i;
Packit fabffb
Packit fabffb
	devices = self->client ? nm_client_get_devices (self->client) : NULL;
Packit fabffb
	for (i = 0; devices && (i < devices->len); i++) {
Packit fabffb
		if (__intro_device_added (self, g_ptr_array_index (devices, i), !selected_first)) {
Packit fabffb
			if (selected_first == FALSE)
Packit fabffb
				selected_first = TRUE;
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* Otherwise the "Any device" item */
Packit fabffb
	if (!selected_first) {
Packit fabffb
		/* Select the first device item by default */
Packit fabffb
		gtk_combo_box_set_active (GTK_COMBO_BOX (self->dev_combo), 0);
Packit fabffb
		gtk_widget_set_sensitive (self->dev_combo, FALSE);
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
intro_remove_all_devices (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	gtk_tree_store_clear (self->dev_store);
Packit fabffb
Packit fabffb
	/* Select the "Any device" item */
Packit fabffb
	gtk_combo_box_set_active (GTK_COMBO_BOX (self->dev_combo), 0);
Packit fabffb
	gtk_widget_set_sensitive (self->dev_combo, FALSE);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
intro_manager_running_cb (NMClient *client, GParamSpec *pspec, NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	if (nm_client_get_manager_running (client))
Packit fabffb
		intro_add_initial_devices (self);
Packit fabffb
	else
Packit fabffb
		intro_remove_all_devices (self);
Packit fabffb
}
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
intro_row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
Packit fabffb
{
Packit fabffb
	gboolean separator = FALSE;
Packit fabffb
	gtk_tree_model_get (model, iter, INTRO_COL_SEPARATOR, &separator, -1);
Packit fabffb
	return separator;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
intro_combo_changed (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkTreeIter iter;
Packit fabffb
	NMDevice *selected = NULL;
Packit fabffb
	NMDeviceModemCapabilities caps;
Packit fabffb
Packit fabffb
	g_free (self->dev_desc);
Packit fabffb
	self->dev_desc = NULL;
Packit fabffb
Packit fabffb
	if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self->dev_combo), &iter))
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	gtk_tree_model_get (GTK_TREE_MODEL (self->dev_store), &iter,
Packit fabffb
	                    INTRO_COL_DEVICE, &selected, -1);
Packit fabffb
	if (selected) {
Packit fabffb
		self->dev_desc = g_strdup (nma_utils_get_device_description (selected));
Packit fabffb
		caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (selected));
Packit fabffb
		if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
Packit fabffb
			self->family = NMA_MOBILE_FAMILY_3GPP;
Packit fabffb
		else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
Packit fabffb
			self->family = NMA_MOBILE_FAMILY_CDMA;
Packit fabffb
		else
Packit fabffb
			g_warning ("%s: unknown modem capabilities 0x%X", __func__, caps);
Packit fabffb
Packit fabffb
		g_object_unref (selected);
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
intro_setup (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	GtkWidget *vbox, *label, *alignment, *info_vbox;
Packit fabffb
	GtkCellRenderer *renderer;
Packit fabffb
	char *s;
Packit fabffb
Packit fabffb
	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit fabffb
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
Packit fabffb
Packit fabffb
	label = gtk_label_new (_("This assistant helps you easily set up a mobile broadband connection to a cellular (3G) network."));
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
Packit fabffb
	gtk_label_set_max_width_chars (GTK_LABEL (label), 60);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 6);
Packit fabffb
Packit fabffb
	label = gtk_label_new (_("You will need the following information:"));
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 6);
Packit fabffb
Packit fabffb
	alignment = gtk_alignment_new (0, 0, 1, 0);
Packit fabffb
	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 25, 25, 0);
Packit fabffb
	info_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit fabffb
	gtk_container_add (GTK_CONTAINER (alignment), info_vbox);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 6);
Packit fabffb
Packit fabffb
	s = g_strdup_printf ("• %s", _("Your broadband provider’s name"));
Packit fabffb
	label = gtk_label_new (s);
Packit fabffb
	g_free (s);
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (info_vbox), label, FALSE, TRUE, 0);
Packit fabffb
Packit fabffb
	s = g_strdup_printf ("• %s", _("Your broadband billing plan name"));
Packit fabffb
	label = gtk_label_new (s);
Packit fabffb
	g_free (s);
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (info_vbox), label, FALSE, TRUE, 0);
Packit fabffb
Packit fabffb
	s = g_strdup_printf ("• %s", _("(in some cases) Your broadband billing plan APN (Access Point Name)"));
Packit fabffb
	label = gtk_label_new (s);
Packit fabffb
	g_free (s);
Packit fabffb
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (info_vbox), label, FALSE, TRUE, 0);
Packit fabffb
Packit fabffb
	/* Device combo; only built if the wizard's caller didn't pass one in */
Packit fabffb
	if (!self->initial_family) {
Packit fabffb
		GtkTreeIter iter;
Packit fabffb
Packit fabffb
		self->client = nm_client_new ();
Packit fabffb
		if (self->client) {
Packit fabffb
			g_signal_connect (self->client, "device-added",
Packit fabffb
			                  G_CALLBACK (intro_device_added_cb), self);
Packit fabffb
			g_signal_connect (self->client, "device-removed",
Packit fabffb
			                  G_CALLBACK (intro_device_removed_cb), self);
Packit fabffb
			g_signal_connect (self->client, "notify::manager-running",
Packit fabffb
			                  G_CALLBACK (intro_manager_running_cb), self);
Packit fabffb
		}
Packit fabffb
Packit fabffb
		self->dev_store = gtk_tree_store_new (3, G_TYPE_STRING, NM_TYPE_DEVICE, G_TYPE_BOOLEAN);
Packit fabffb
		self->dev_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (self->dev_store));
Packit fabffb
		gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (self->dev_combo),
Packit fabffb
		                                      intro_row_separator_func, NULL, NULL);
Packit fabffb
Packit fabffb
		renderer = gtk_cell_renderer_text_new ();
Packit fabffb
		gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->dev_combo), renderer, TRUE);
Packit fabffb
		gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (self->dev_combo), renderer, "text", INTRO_COL_NAME);
Packit fabffb
Packit fabffb
		label = gtk_label_new_with_mnemonic (_("Create a connection for _this mobile broadband device:"));
Packit fabffb
		gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->dev_combo);
Packit fabffb
		gtk_misc_set_alignment (GTK_MISC (label), 0, 1);
Packit fabffb
		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
		alignment = gtk_alignment_new (0, 0, 0.5, 0);
Packit fabffb
		gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 25, 0);
Packit fabffb
		gtk_container_add (GTK_CONTAINER (alignment), self->dev_combo);
Packit fabffb
		gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
Packit fabffb
Packit fabffb
		g_signal_connect_swapped (self->dev_combo, "changed", G_CALLBACK (intro_combo_changed), self);
Packit fabffb
Packit fabffb
		/* Any device */
Packit fabffb
		gtk_tree_store_append (GTK_TREE_STORE (self->dev_store), &iter, NULL);
Packit fabffb
		gtk_tree_store_set (GTK_TREE_STORE (self->dev_store), &iter,
Packit fabffb
		                    INTRO_COL_NAME, _("Any device"), -1);
Packit fabffb
Packit fabffb
		/* Separator */
Packit fabffb
		gtk_tree_store_append (GTK_TREE_STORE (self->dev_store), &iter, NULL);
Packit fabffb
		gtk_tree_store_set (GTK_TREE_STORE (self->dev_store), &iter,
Packit fabffb
		                    INTRO_COL_SEPARATOR, TRUE, -1);
Packit fabffb
Packit fabffb
		intro_add_initial_devices (self);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	gtk_widget_show_all (vbox);
Packit fabffb
	gtk_assistant_append_page (GTK_ASSISTANT (self->assistant), vbox);
Packit fabffb
	gtk_assistant_set_page_title (GTK_ASSISTANT (self->assistant),
Packit fabffb
	                              vbox, _("Set up a Mobile Broadband Connection"));
Packit fabffb
Packit fabffb
	gtk_assistant_set_page_complete (GTK_ASSISTANT (self->assistant), vbox, TRUE);
Packit fabffb
	gtk_assistant_set_page_type (GTK_ASSISTANT (self->assistant), vbox, GTK_ASSISTANT_PAGE_INTRO);
Packit fabffb
}
Packit fabffb
Packit fabffb
/**********************************************************/
Packit fabffb
/* General assistant stuff */
Packit fabffb
/**********************************************************/
Packit fabffb
Packit fabffb
static void
Packit fabffb
remove_provider_focus_idle (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	if (self->providers_focus_id) {
Packit fabffb
		g_source_remove (self->providers_focus_id);
Packit fabffb
		self->providers_focus_id = 0;
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
remove_country_focus_idle (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	if (self->country_focus_id) {
Packit fabffb
		g_source_remove (self->country_focus_id);
Packit fabffb
		self->country_focus_id = 0;
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
assistant_prepare (GtkAssistant *assistant, GtkWidget *page, gpointer user_data)
Packit fabffb
{
Packit fabffb
	NMAMobileWizard *self = user_data;
Packit fabffb
Packit fabffb
	if (page != self->providers_page)
Packit fabffb
		remove_provider_focus_idle (self);
Packit fabffb
	if (page != self->country_page)
Packit fabffb
		remove_country_focus_idle (self);
Packit fabffb
Packit fabffb
	if (page == self->country_page)
Packit fabffb
		country_prepare (self);
Packit fabffb
	else if (page == self->providers_page)
Packit fabffb
		providers_prepare (self);
Packit fabffb
	else if (page == self->plan_page)
Packit fabffb
		plan_prepare (self);
Packit fabffb
	else if (page == self->confirm_page)
Packit fabffb
		confirm_prepare (self);
Packit fabffb
}
Packit fabffb
Packit fabffb
static gint
Packit fabffb
forward_func (gint current_page, gpointer user_data)
Packit fabffb
{
Packit fabffb
	NMAMobileWizard *self = user_data;
Packit fabffb
Packit fabffb
	if (current_page == self->providers_idx) {
Packit fabffb
		NMAMobileFamily family = self->family;
Packit fabffb
Packit fabffb
		/* If the provider is unlisted, we can skip ahead of the user's
Packit fabffb
		 * access technology is CDMA.
Packit fabffb
		 */
Packit fabffb
		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->provider_unlisted_radio))) {
Packit fabffb
			if (family == NMA_MOBILE_FAMILY_UNKNOWN)
Packit fabffb
				family = get_provider_unlisted_type (self);
Packit fabffb
		} else {
Packit fabffb
			/* Or, if the provider is only CDMA, then we can also skip ahead */
Packit fabffb
			NMAMobileProvider *provider;
Packit fabffb
			GSList *iter;
Packit fabffb
			gboolean gsm = FALSE, cdma = FALSE;
Packit fabffb
Packit fabffb
			provider = get_selected_provider (self);
Packit fabffb
			if (provider) {
Packit fabffb
				for (iter = nma_mobile_provider_get_methods (provider); iter; iter = g_slist_next (iter)) {
Packit fabffb
					NMAMobileAccessMethod *method = iter->data;
Packit fabffb
Packit fabffb
					if (nma_mobile_access_method_get_family (method) == NMA_MOBILE_FAMILY_CDMA)
Packit fabffb
						cdma = TRUE;
Packit fabffb
					else if (nma_mobile_access_method_get_family (method) == NMA_MOBILE_FAMILY_3GPP)
Packit fabffb
						gsm = TRUE;
Packit fabffb
				}
Packit fabffb
				nma_mobile_provider_unref (provider);
Packit fabffb
Packit fabffb
				if (cdma && !gsm)
Packit fabffb
					family = NMA_MOBILE_FAMILY_CDMA;
Packit fabffb
			}
Packit fabffb
		}
Packit fabffb
Packit fabffb
		/* Skip to the confirm page if we know its CDMA */
Packit fabffb
		if (family == NMA_MOBILE_FAMILY_CDMA) {
Packit fabffb
			self->provider_only_cdma = TRUE;
Packit fabffb
			return self->confirm_idx;
Packit fabffb
		} else
Packit fabffb
			self->provider_only_cdma = FALSE;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	return current_page + 1;
Packit fabffb
}
Packit fabffb
Packit fabffb
static char *
Packit fabffb
get_country_from_locale (void)
Packit fabffb
{
Packit fabffb
	char *p, *m, *cc, *lang;
Packit fabffb
Packit fabffb
	lang = getenv ("LC_ALL");
Packit fabffb
	if (!lang)
Packit fabffb
		lang = getenv ("LANG");
Packit fabffb
	if (!lang)
Packit fabffb
		return NULL;
Packit fabffb
Packit fabffb
	p = strchr (lang, '_');
Packit fabffb
	if (!p || !strlen (p)) {
Packit fabffb
		g_free (p);
Packit fabffb
		return NULL;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	p = cc = g_strdup (++p);
Packit fabffb
	m = strchr (cc, '.');
Packit fabffb
	if (m)
Packit fabffb
		*m = '\0';
Packit fabffb
Packit fabffb
	while (*p) {
Packit fabffb
		*p = g_ascii_toupper (*p);
Packit fabffb
		p++;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	return cc;
Packit fabffb
}
Packit fabffb
Packit fabffb
/**
Packit fabffb
 * nma_mobile_wizard_new: (skip)
Packit fabffb
 * @cb: (scope async):
Packit fabffb
 */
Packit fabffb
NMAMobileWizard *
Packit fabffb
nma_mobile_wizard_new (GtkWindow *parent,
Packit fabffb
                       GtkWindowGroup *window_group,
Packit fabffb
                       NMDeviceModemCapabilities modem_caps,
Packit fabffb
                       gboolean will_connect_after,
Packit fabffb
                       NMAMobileWizardCallback cb,
Packit fabffb
                       gpointer user_data)
Packit fabffb
{
Packit fabffb
	NMAMobileWizard *self;
Packit fabffb
	char *cc;
Packit fabffb
	GError *error = NULL;
Packit fabffb
Packit fabffb
	self = g_malloc0 (sizeof (NMAMobileWizard));
Packit fabffb
	g_return_val_if_fail (self != NULL, NULL);
Packit fabffb
Packit fabffb
	self->mobile_providers_database = nma_mobile_providers_database_new_sync (NULL, NULL, NULL, &error);
Packit fabffb
	if (!self->mobile_providers_database) {
Packit fabffb
		g_warning ("Cannot create mobile providers database: %s",
Packit fabffb
		           error->message);
Packit fabffb
		g_error_free (error);
Packit fabffb
		nma_mobile_wizard_destroy (self);
Packit fabffb
		return NULL;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	cc = get_country_from_locale ();
Packit fabffb
	if (cc) {
Packit fabffb
		self->country = nma_mobile_providers_database_lookup_country (self->mobile_providers_database, cc);
Packit fabffb
		g_free (cc);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	self->will_connect_after = will_connect_after;
Packit fabffb
	self->callback = cb;
Packit fabffb
	self->user_data = user_data;
Packit fabffb
	if (modem_caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
Packit fabffb
		self->family = NMA_MOBILE_FAMILY_3GPP;
Packit fabffb
	else if (modem_caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
Packit fabffb
		self->family = NMA_MOBILE_FAMILY_CDMA;
Packit fabffb
	if (self->family)
Packit fabffb
		self->initial_family = TRUE;  /* Skip device selection */
Packit fabffb
Packit fabffb
	self->assistant = gtk_assistant_new ();
Packit fabffb
	gtk_assistant_set_forward_page_func (GTK_ASSISTANT (self->assistant),
Packit fabffb
	                                     forward_func, self, NULL);
Packit fabffb
	gtk_window_set_title (GTK_WINDOW (self->assistant), _("New Mobile Broadband Connection"));
Packit fabffb
	gtk_window_set_position (GTK_WINDOW (self->assistant), GTK_WIN_POS_CENTER_ALWAYS);
Packit fabffb
Packit fabffb
	intro_setup (self);
Packit fabffb
	country_setup (self);
Packit fabffb
	providers_setup (self);
Packit fabffb
	plan_setup (self);
Packit fabffb
	confirm_setup (self);
Packit fabffb
Packit fabffb
	g_signal_connect (self->assistant, "close", G_CALLBACK (assistant_closed), self);
Packit fabffb
	g_signal_connect (self->assistant, "cancel", G_CALLBACK (assistant_cancel), self);
Packit fabffb
	g_signal_connect (self->assistant, "prepare", G_CALLBACK (assistant_prepare), self);
Packit fabffb
Packit fabffb
	/* Run the wizard */
Packit fabffb
	if (parent)
Packit fabffb
		gtk_window_set_transient_for (GTK_WINDOW (self->assistant), parent);
Packit fabffb
	gtk_window_set_modal (GTK_WINDOW (self->assistant), TRUE);
Packit fabffb
	gtk_window_set_skip_taskbar_hint (GTK_WINDOW (self->assistant), TRUE);
Packit fabffb
	gtk_window_set_type_hint (GTK_WINDOW (self->assistant), GDK_WINDOW_TYPE_HINT_DIALOG);
Packit fabffb
Packit fabffb
	if (window_group)
Packit fabffb
		gtk_window_group_add_window (window_group, GTK_WINDOW (self->assistant));
Packit fabffb
Packit fabffb
	return self;
Packit fabffb
}
Packit fabffb
Packit fabffb
void
Packit fabffb
nma_mobile_wizard_present (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	g_return_if_fail (self != NULL);
Packit fabffb
Packit fabffb
	gtk_window_present (GTK_WINDOW (self->assistant));
Packit fabffb
	gtk_widget_show_all (self->assistant);
Packit fabffb
}
Packit fabffb
Packit fabffb
void
Packit fabffb
nma_mobile_wizard_destroy (NMAMobileWizard *self)
Packit fabffb
{
Packit fabffb
	g_return_if_fail (self != NULL);
Packit fabffb
Packit fabffb
	g_free (self->dev_desc);
Packit fabffb
Packit fabffb
	if (self->assistant) {
Packit fabffb
		gtk_widget_hide (self->assistant);
Packit fabffb
		gtk_widget_destroy (self->assistant);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (self->client)
Packit fabffb
		g_object_unref (self->client);
Packit fabffb
Packit fabffb
	remove_provider_focus_idle (self);
Packit fabffb
	remove_country_focus_idle (self);
Packit fabffb
Packit fabffb
	if (self->mobile_providers_database)
Packit fabffb
		g_object_unref (self->mobile_providers_database);
Packit fabffb
Packit fabffb
	g_free (self);
Packit fabffb
}