1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2
/* NetworkManager Connection editor -- Connection editor for NetworkManager
4
* Dan Williams <dcbw@redhat.com>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License along
17
* with this program; if not, write to the Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
* (C) Copyright 2008 - 2012 Red Hat, Inc.
29
#include <glib/gi18n.h>
33
#include <NetworkManager.h>
34
#include <nm-setting-gsm.h>
35
#include <nm-setting-cdma.h>
36
#include <nm-client.h>
37
#include <nm-device-modem.h>
39
#include "nm-mobile-wizard.h"
40
#include "nmn-mobile-providers.h"
43
#define DEVICE_TAG "device"
44
#define TYPE_TAG "setting-type"
46
static char *get_selected_country (NMAMobileWizard *self, gboolean *unlisted);
47
static NmnMobileProvider *get_selected_provider (NMAMobileWizard *self);
48
static NmnMobileAccessMethodType get_provider_unlisted_type (NMAMobileWizard *self);
49
static NmnMobileAccessMethod *get_selected_method (NMAMobileWizard *self, gboolean *manual);
51
struct NMAMobileWizard {
53
NMAMobileWizardCallback callback;
55
GHashTable *providers;
56
GHashTable *country_codes;
57
NmnMobileAccessMethodType method_type;
58
gboolean initial_method_type;
59
gboolean will_connect_after;
63
GtkTreeStore *dev_store;
70
GtkWidget *country_page;
71
GtkWidget *country_view;
72
GtkTreeStore *country_store;
73
GtkTreeModelSort *country_sort;
74
guint32 country_focus_id;
77
guint32 providers_idx;
78
GtkWidget *providers_page;
79
GtkWidget *providers_view;
80
GtkTreeStore *providers_store;
81
GtkTreeModelSort *providers_sort;
82
guint32 providers_focus_id;
83
GtkWidget *providers_view_radio;
85
GtkWidget *provider_unlisted_radio;
86
GtkWidget *provider_unlisted_entry;
87
GtkWidget *provider_unlisted_type_combo;
89
gboolean provider_only_cdma;
94
GtkWidget *plan_combo;
95
GtkTreeStore *plan_store;
96
guint32 plan_focus_id;
98
GtkWidget *plan_unlisted_entry;
101
GtkWidget *confirm_page;
102
GtkWidget *confirm_provider;
103
GtkWidget *confirm_plan;
104
GtkWidget *confirm_apn;
105
GtkWidget *confirm_plan_label;
106
GtkWidget *confirm_device;
107
GtkWidget *confirm_device_label;
112
assistant_closed (GtkButton *button, gpointer user_data)
114
NMAMobileWizard *self = user_data;
115
NmnMobileProvider *provider;
116
NmnMobileAccessMethod *method;
117
NMAMobileWizardAccessMethod *wiz_method;
118
NmnMobileAccessMethodType method_type = self->method_type;
120
wiz_method = g_malloc0 (sizeof (NMAMobileWizardAccessMethod));
122
provider = get_selected_provider (self);
124
if (method_type == NMN_MOBILE_ACCESS_METHOD_TYPE_UNKNOWN)
125
method_type = get_provider_unlisted_type (self);
127
wiz_method->provider_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->provider_unlisted_entry)));
128
if (method_type == NMN_MOBILE_ACCESS_METHOD_TYPE_GSM)
129
wiz_method->gsm_apn = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->plan_unlisted_entry)));
131
gboolean manual = FALSE;
133
wiz_method->provider_name = g_strdup (provider->name);
134
method = get_selected_method (self, &manual);
137
wiz_method->plan_name = g_strdup (method->name);
138
method_type = method->type;
139
if (method_type == NMN_MOBILE_ACCESS_METHOD_TYPE_GSM)
140
wiz_method->gsm_apn = g_strdup (method->gsm_apn);
141
wiz_method->username = method->username ? g_strdup (method->username) : NULL;
142
wiz_method->password = method->password ? g_strdup (method->password) : NULL;
144
if (self->provider_only_cdma) {
145
method_type = NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA;
146
/* Take username and password from the first (only) method for CDMA only provider */
147
if (provider->methods) {
148
method = provider->methods->data;
149
wiz_method->username = method->username ? g_strdup (method->username) : NULL;
150
wiz_method->password = method->password ? g_strdup (method->password) : NULL;
154
method_type = NMN_MOBILE_ACCESS_METHOD_TYPE_GSM;
155
wiz_method->gsm_apn = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->plan_unlisted_entry)));
160
switch (method_type) {
161
case NMN_MOBILE_ACCESS_METHOD_TYPE_GSM:
162
wiz_method->devtype = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
164
case NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA:
165
wiz_method->devtype = NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO;
168
g_assert_not_reached ();
172
(*(self->callback)) (self, FALSE, wiz_method, self->user_data);
174
g_free (wiz_method->provider_name);
175
g_free (wiz_method->plan_name);
176
g_free (wiz_method->username);
177
g_free (wiz_method->password);
178
g_free (wiz_method->gsm_apn);
183
assistant_cancel (GtkButton *button, gpointer user_data)
185
NMAMobileWizard *self = user_data;
187
(*(self->callback)) (self, TRUE, NULL, self->user_data);
190
/**********************************************************/
192
/**********************************************************/
195
confirm_setup (NMAMobileWizard *self)
197
GtkWidget *vbox, *label, *alignment, *pbox;
199
#if GTK_CHECK_VERSION(3,1,6)
200
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
202
vbox = gtk_vbox_new (FALSE, 6);
204
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
205
label = gtk_label_new (_("Your mobile broadband connection is configured with the following settings:"));
206
gtk_widget_set_size_request (label, 500, -1);
207
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
208
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
209
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);
212
self->confirm_device_label = gtk_label_new (_("Your Device:"));
213
gtk_misc_set_alignment (GTK_MISC (self->confirm_device_label), 0, 0.5);
214
gtk_box_pack_start (GTK_BOX (vbox), self->confirm_device_label, FALSE, FALSE, 0);
216
alignment = gtk_alignment_new (0, 0.5, 0, 0);
217
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 12, 25, 0);
218
self->confirm_device = gtk_label_new (NULL);
219
gtk_container_add (GTK_CONTAINER (alignment), self->confirm_device);
220
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
223
label = gtk_label_new (_("Your Provider:"));
224
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
225
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
227
alignment = gtk_alignment_new (0, 0.5, 0, 0);
228
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 12, 25, 0);
229
self->confirm_provider = gtk_label_new (NULL);
230
gtk_container_add (GTK_CONTAINER (alignment), self->confirm_provider);
231
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
234
self->confirm_plan_label = gtk_label_new (_("Your Plan:"));
235
gtk_misc_set_alignment (GTK_MISC (self->confirm_plan_label), 0, 0.5);
236
gtk_box_pack_start (GTK_BOX (vbox), self->confirm_plan_label, FALSE, FALSE, 0);
238
alignment = gtk_alignment_new (0, 0.5, 0, 0);
239
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 25, 0);
240
#if GTK_CHECK_VERSION(3,1,6)
241
pbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
243
pbox = gtk_vbox_new (FALSE, 0);
245
gtk_container_add (GTK_CONTAINER (alignment), pbox);
246
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
248
self->confirm_plan = gtk_label_new (NULL);
249
gtk_misc_set_alignment (GTK_MISC (self->confirm_plan), 0, 0.5);
250
gtk_box_pack_start (GTK_BOX (pbox), self->confirm_plan, FALSE, FALSE, 0);
252
self->confirm_apn = gtk_label_new (NULL);
253
gtk_misc_set_alignment (GTK_MISC (self->confirm_apn), 0, 0.5);
254
gtk_misc_set_padding (GTK_MISC (self->confirm_apn), 0, 6);
255
gtk_box_pack_start (GTK_BOX (pbox), self->confirm_apn, FALSE, FALSE, 0);
257
if (self->will_connect_after) {
258
alignment = gtk_alignment_new (0, 0.5, 1, 0);
259
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."));
260
gtk_widget_set_size_request (label, 500, -1);
261
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
262
gtk_misc_set_padding (GTK_MISC (label), 0, 6);
263
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
264
gtk_container_add (GTK_CONTAINER (alignment), label);
265
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 6);
268
gtk_widget_show_all (vbox);
269
self->confirm_idx = gtk_assistant_append_page (GTK_ASSISTANT (self->assistant), vbox);
270
gtk_assistant_set_page_title (GTK_ASSISTANT (self->assistant),
271
vbox, _("Confirm Mobile Broadband Settings"));
273
gtk_assistant_set_page_complete (GTK_ASSISTANT (self->assistant), vbox, TRUE);
274
gtk_assistant_set_page_type (GTK_ASSISTANT (self->assistant), vbox, GTK_ASSISTANT_PAGE_CONFIRM);
276
self->confirm_page = vbox;
280
confirm_prepare (NMAMobileWizard *self)
282
NmnMobileProvider *provider = NULL;
283
NmnMobileAccessMethod *method = NULL;
284
char *country = NULL;
285
gboolean manual = FALSE;
288
country = get_selected_country (self, NULL);
289
provider = get_selected_provider (self);
291
method = get_selected_method (self, &manual);
294
str = g_string_new (NULL);
296
g_string_append (str, provider->name);
298
const char *unlisted_provider;
300
unlisted_provider = gtk_entry_get_text (GTK_ENTRY (self->provider_unlisted_entry));
301
g_string_append (str, unlisted_provider);
305
g_string_append_printf (str, ", %s", country);
306
gtk_label_set_text (GTK_LABEL (self->confirm_provider), str->str);
307
g_string_free (str, TRUE);
310
gtk_label_set_text (GTK_LABEL (self->confirm_device), self->dev_desc);
312
gtk_widget_hide (self->confirm_device_label);
313
gtk_widget_hide (self->confirm_device);
316
if (self->provider_only_cdma) {
317
gtk_widget_hide (self->confirm_plan_label);
318
gtk_widget_hide (self->confirm_plan);
319
gtk_widget_hide (self->confirm_apn);
321
const char *apn = NULL;
324
gtk_widget_show (self->confirm_plan_label);
325
gtk_widget_show (self->confirm_plan);
326
gtk_widget_show (self->confirm_apn);
329
gtk_label_set_text (GTK_LABEL (self->confirm_plan), method->name);
330
apn = method->gsm_apn;
332
gtk_label_set_text (GTK_LABEL (self->confirm_plan), _("Unlisted"));
333
apn = gtk_entry_get_text (GTK_ENTRY (self->plan_unlisted_entry));
336
str = g_string_new (NULL);
337
g_string_append_printf (str, "<span color=\"#999999\">APN: %s</span>", apn);
338
gtk_label_set_markup (GTK_LABEL (self->confirm_apn), str->str);
339
g_string_free (str, TRUE);
343
/**********************************************************/
345
/**********************************************************/
347
#define PLAN_COL_NAME 0
348
#define PLAN_COL_METHOD 1
349
#define PLAN_COL_MANUAL 2
351
static NmnMobileAccessMethod *
352
get_selected_method (NMAMobileWizard *self, gboolean *manual)
355
NmnMobileAccessMethod *method = NULL;
357
gboolean is_manual = FALSE;
359
if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self->plan_combo), &iter))
362
model = gtk_combo_box_get_model (GTK_COMBO_BOX (self->plan_combo));
366
gtk_tree_model_get (model, &iter,
367
PLAN_COL_METHOD, &method,
368
PLAN_COL_MANUAL, &is_manual,
374
nmn_mobile_access_method_unref (method);
382
plan_update_complete (NMAMobileWizard *self)
384
GtkAssistant *assistant = GTK_ASSISTANT (self->assistant);
385
gboolean is_manual = FALSE;
386
NmnMobileAccessMethod *method;
388
method = get_selected_method (self, &is_manual);
390
gtk_assistant_set_page_complete (assistant, self->plan_page, TRUE);
391
nmn_mobile_access_method_unref (method);
393
const char *manual_apn;
395
manual_apn = gtk_entry_get_text (GTK_ENTRY (self->plan_unlisted_entry));
396
gtk_assistant_set_page_complete (assistant, self->plan_page,
397
(manual_apn && strlen (manual_apn)));
402
plan_combo_changed (NMAMobileWizard *self)
404
NmnMobileAccessMethod *method = NULL;
405
gboolean is_manual = FALSE;
407
method = get_selected_method (self, &is_manual);
409
gtk_entry_set_text (GTK_ENTRY (self->plan_unlisted_entry), method->gsm_apn);
410
gtk_widget_set_sensitive (self->plan_unlisted_entry, FALSE);
412
gtk_entry_set_text (GTK_ENTRY (self->plan_unlisted_entry), "");
413
gtk_widget_set_sensitive (self->plan_unlisted_entry, TRUE);
414
gtk_widget_grab_focus (self->plan_unlisted_entry);
418
nmn_mobile_access_method_unref (method);
420
plan_update_complete (self);
424
plan_row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
426
NmnMobileAccessMethod *method = NULL;
427
gboolean is_manual = FALSE;
428
gboolean draw_separator = FALSE;
430
gtk_tree_model_get (model, iter,
431
PLAN_COL_METHOD, &method,
432
PLAN_COL_MANUAL, &is_manual,
434
if (!method && !is_manual)
435
draw_separator = TRUE;
437
nmn_mobile_access_method_unref (method);
438
return draw_separator;
442
apn_filter_cb (GtkEntry * entry,
448
GtkEditable *editable = GTK_EDITABLE (entry);
450
gchar *result = g_new0 (gchar, length);
452
for (i = 0; i < length; i++) {
453
if ( isalnum (text[i])
457
result[count++] = text[i];
461
g_signal_handlers_block_by_func (G_OBJECT (editable),
462
G_CALLBACK (apn_filter_cb),
464
gtk_editable_insert_text (editable, result, count, position);
465
g_signal_handlers_unblock_by_func (G_OBJECT (editable),
466
G_CALLBACK (apn_filter_cb),
470
g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
475
plan_setup (NMAMobileWizard *self)
477
GtkWidget *vbox, *label, *alignment, *hbox, *image;
478
GtkCellRenderer *renderer;
480
#if GTK_CHECK_VERSION(3,1,6)
481
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
483
vbox = gtk_vbox_new (FALSE, 6);
485
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
487
label = gtk_label_new_with_mnemonic (_("_Select your plan:"));
488
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
489
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
491
self->plan_store = gtk_tree_store_new (3, G_TYPE_STRING, NMN_TYPE_MOBILE_ACCESS_METHOD, G_TYPE_BOOLEAN);
493
self->plan_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (self->plan_store));
494
gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->plan_combo);
495
gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (self->plan_combo),
496
plan_row_separator_func,
500
renderer = gtk_cell_renderer_text_new ();
501
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->plan_combo), renderer, TRUE);
502
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (self->plan_combo), renderer, "text", PLAN_COL_NAME);
504
g_signal_connect_swapped (self->plan_combo, "changed", G_CALLBACK (plan_combo_changed), self);
506
alignment = gtk_alignment_new (0, 0.5, 0.5, 0);
507
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 12, 0, 0);
508
gtk_container_add (GTK_CONTAINER (alignment), self->plan_combo);
509
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
511
label = gtk_label_new_with_mnemonic (_("Selected plan _APN (Access Point Name):"));
512
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
513
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
515
self->plan_unlisted_entry = gtk_entry_new ();
516
gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->plan_unlisted_entry);
517
gtk_entry_set_max_length (GTK_ENTRY (self->plan_unlisted_entry), 64);
518
g_signal_connect (self->plan_unlisted_entry, "insert-text", G_CALLBACK (apn_filter_cb), self);
519
g_signal_connect_swapped (self->plan_unlisted_entry, "changed", G_CALLBACK (plan_update_complete), self);
521
alignment = gtk_alignment_new (0, 0.5, 0.5, 0);
522
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 24, 0, 0);
523
gtk_container_add (GTK_CONTAINER (alignment), self->plan_unlisted_entry);
524
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
526
#if GTK_CHECK_VERSION(3,1,6)
527
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
529
hbox = gtk_hbox_new (FALSE, 6);
531
image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
532
gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
533
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
535
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."));
536
gtk_widget_set_size_request (label, 500, -1);
537
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
538
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
539
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
541
self->plan_idx = gtk_assistant_append_page (GTK_ASSISTANT (self->assistant), vbox);
542
gtk_assistant_set_page_title (GTK_ASSISTANT (self->assistant), vbox, _("Choose your Billing Plan"));
543
gtk_assistant_set_page_type (GTK_ASSISTANT (self->assistant), vbox, GTK_ASSISTANT_PAGE_CONTENT);
544
gtk_widget_show_all (vbox);
546
self->plan_page = vbox;
550
plan_prepare (NMAMobileWizard *self)
552
NmnMobileProvider *provider;
553
GtkTreeIter method_iter;
555
gtk_tree_store_clear (self->plan_store);
557
provider = get_selected_provider (self);
562
for (iter = provider->methods; iter; iter = g_slist_next (iter)) {
563
NmnMobileAccessMethod *method = iter->data;
565
if ( (self->method_type != NMN_MOBILE_ACCESS_METHOD_TYPE_UNKNOWN)
566
&& (method->type != self->method_type))
569
gtk_tree_store_append (GTK_TREE_STORE (self->plan_store), &method_iter, NULL);
570
gtk_tree_store_set (GTK_TREE_STORE (self->plan_store),
580
/* Draw the separator */
582
gtk_tree_store_append (GTK_TREE_STORE (self->plan_store), &method_iter, NULL);
585
/* Add the "My plan is not listed..." item */
586
gtk_tree_store_append (GTK_TREE_STORE (self->plan_store), &method_iter, NULL);
587
gtk_tree_store_set (GTK_TREE_STORE (self->plan_store),
590
_("My plan is not listed..."),
595
/* Select the first item by default if nothing is yet selected */
596
if (gtk_combo_box_get_active (GTK_COMBO_BOX (self->plan_combo)) < 0)
597
gtk_combo_box_set_active (GTK_COMBO_BOX (self->plan_combo), 0);
599
plan_combo_changed (self);
602
/**********************************************************/
604
/**********************************************************/
606
#define PROVIDER_COL_NAME 0
607
#define PROVIDER_COL_PROVIDER 1
610
providers_search_func (GtkTreeModel *model,
614
gpointer search_data)
616
gboolean unmatched = TRUE;
617
char *provider = NULL;
622
gtk_tree_model_get (model, iter, column, &provider, -1);
626
unmatched = !!g_ascii_strncasecmp (provider, key, strlen (key));
631
static NmnMobileProvider *
632
get_selected_provider (NMAMobileWizard *self)
634
GtkTreeSelection *selection;
635
GtkTreeModel *model = NULL;
637
NmnMobileProvider *provider = NULL;
639
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->providers_view_radio)))
642
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->providers_view));
643
g_assert (selection);
645
if (!gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter))
648
gtk_tree_model_get (model, &iter, PROVIDER_COL_PROVIDER, &provider, -1);
653
providers_update_complete (NMAMobileWizard *self)
655
GtkAssistant *assistant = GTK_ASSISTANT (self->assistant);
658
use_view = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->providers_view_radio));
660
NmnMobileProvider *provider;
662
provider = get_selected_provider (self);
663
gtk_assistant_set_page_complete (assistant, self->providers_page, !!provider);
665
nmn_mobile_provider_unref (provider);
667
const char *manual_provider;
669
manual_provider = gtk_entry_get_text (GTK_ENTRY (self->provider_unlisted_entry));
670
gtk_assistant_set_page_complete (assistant, self->providers_page,
671
(manual_provider && strlen (manual_provider)));
676
focus_providers_view (gpointer user_data)
678
NMAMobileWizard *self = user_data;
680
self->providers_focus_id = 0;
681
gtk_widget_grab_focus (self->providers_view);
686
focus_provider_unlisted_entry (gpointer user_data)
688
NMAMobileWizard *self = user_data;
690
self->providers_focus_id = 0;
691
gtk_widget_grab_focus (self->provider_unlisted_entry);
696
providers_radio_toggled (GtkToggleButton *button, gpointer user_data)
698
NMAMobileWizard *self = user_data;
701
use_view = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->providers_view_radio));
703
if (!self->providers_focus_id)
704
self->providers_focus_id = g_idle_add (focus_providers_view, self);
705
gtk_widget_set_sensitive (self->providers_view, TRUE);
706
gtk_widget_set_sensitive (self->provider_unlisted_entry, FALSE);
707
gtk_widget_set_sensitive (self->provider_unlisted_type_combo, FALSE);
709
if (!self->providers_focus_id)
710
self->providers_focus_id = g_idle_add (focus_provider_unlisted_entry, self);
711
gtk_widget_set_sensitive (self->providers_view, FALSE);
712
gtk_widget_set_sensitive (self->provider_unlisted_entry, TRUE);
713
gtk_widget_set_sensitive (self->provider_unlisted_type_combo, TRUE);
716
providers_update_complete (self);
719
static NmnMobileAccessMethodType
720
get_provider_unlisted_type (NMAMobileWizard *self)
722
switch (gtk_combo_box_get_active (GTK_COMBO_BOX (self->provider_unlisted_type_combo))) {
724
return NMN_MOBILE_ACCESS_METHOD_TYPE_GSM;
726
return NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA;
728
return NMN_MOBILE_ACCESS_METHOD_TYPE_UNKNOWN;
733
providers_setup (NMAMobileWizard *self)
735
GtkWidget *vbox, *scroll, *alignment, *unlisted_table, *label;
736
GtkCellRenderer *renderer;
737
GtkTreeViewColumn *column;
738
GtkTreeSelection *selection;
740
#if GTK_CHECK_VERSION(3,1,6)
741
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
743
vbox = gtk_vbox_new (FALSE, 6);
745
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
747
self->providers_view_radio = gtk_radio_button_new_with_mnemonic (NULL, _("Select your provider from a _list:"));
748
g_signal_connect (self->providers_view_radio, "toggled", G_CALLBACK (providers_radio_toggled), self);
749
gtk_box_pack_start (GTK_BOX (vbox), self->providers_view_radio, FALSE, TRUE, 0);
751
self->providers_store = gtk_tree_store_new (2, G_TYPE_STRING, NMN_TYPE_MOBILE_PROVIDER);
753
self->providers_sort = GTK_TREE_MODEL_SORT (gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->providers_store)));
754
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self->providers_sort),
755
PROVIDER_COL_NAME, GTK_SORT_ASCENDING);
757
self->providers_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->providers_sort));
759
renderer = gtk_cell_renderer_text_new ();
760
column = gtk_tree_view_column_new_with_attributes (_("Provider"),
762
"text", PROVIDER_COL_NAME,
764
gtk_tree_view_append_column (GTK_TREE_VIEW (self->providers_view), column);
765
gtk_tree_view_column_set_clickable (column, TRUE);
767
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->providers_view));
768
g_assert (selection);
769
g_signal_connect_swapped (selection, "changed", G_CALLBACK (providers_update_complete), self);
771
scroll = gtk_scrolled_window_new (NULL, NULL);
772
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
773
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
775
GTK_POLICY_AUTOMATIC);
776
gtk_widget_set_size_request (scroll, -1, 140);
777
gtk_container_add (GTK_CONTAINER (scroll), self->providers_view);
779
alignment = gtk_alignment_new (0, 0, 1, 1);
780
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 12, 25, 0);
781
gtk_container_add (GTK_CONTAINER (alignment), scroll);
782
gtk_box_pack_start (GTK_BOX (vbox), alignment, TRUE, TRUE, 0);
784
self->provider_unlisted_radio = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (self->providers_view_radio),
785
_("I can't find my provider and I wish to enter it _manually:"));
786
g_signal_connect (self->providers_view_radio, "toggled", G_CALLBACK (providers_radio_toggled), self);
787
gtk_box_pack_start (GTK_BOX (vbox), self->provider_unlisted_radio, FALSE, TRUE, 0);
789
alignment = gtk_alignment_new (0, 0, 0, 0);
790
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 15, 0);
791
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
793
unlisted_table = gtk_table_new (2, 2, FALSE);
794
gtk_container_add (GTK_CONTAINER (alignment), unlisted_table);
796
label = gtk_label_new (_("Provider:"));
797
gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
798
gtk_table_attach (GTK_TABLE (unlisted_table), label, 0, 1, 0, 1, 0, 0, 6, 6);
800
self->provider_unlisted_entry = gtk_entry_new ();
801
gtk_entry_set_width_chars (GTK_ENTRY (self->provider_unlisted_entry), 40);
802
g_signal_connect_swapped (self->provider_unlisted_entry, "changed", G_CALLBACK (providers_update_complete), self);
804
alignment = gtk_alignment_new (0, 0.5, 0.66, 0);
805
gtk_container_add (GTK_CONTAINER (alignment), self->provider_unlisted_entry);
806
gtk_table_attach (GTK_TABLE (unlisted_table), alignment,
807
1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 6, 6);
809
#if GTK_CHECK_VERSION(2,23,0)
810
self->provider_unlisted_type_combo = gtk_combo_box_text_new ();
812
self->provider_unlisted_type_combo = gtk_combo_box_new_text ();
814
gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->provider_unlisted_type_combo);
815
#if GTK_CHECK_VERSION(2,23,0)
816
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->provider_unlisted_type_combo),
818
gtk_combo_box_append_text (GTK_COMBO_BOX (self->provider_unlisted_type_combo),
820
_("My provider uses GSM technology (GPRS, EDGE, UMTS, HSPA)"));
821
#if GTK_CHECK_VERSION(2,23,0)
822
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->provider_unlisted_type_combo),
824
gtk_combo_box_append_text (GTK_COMBO_BOX (self->provider_unlisted_type_combo),
826
_("My provider uses CDMA technology (1xRTT, EVDO)"));
827
gtk_combo_box_set_active (GTK_COMBO_BOX (self->provider_unlisted_type_combo), 0);
829
gtk_table_attach (GTK_TABLE (unlisted_table), self->provider_unlisted_type_combo,
830
1, 2, 1, 2, 0, 0, 6, 6);
832
/* Only show the CDMA/GSM combo if we don't know the device type */
833
if (self->method_type != NMN_MOBILE_ACCESS_METHOD_TYPE_UNKNOWN)
834
gtk_widget_hide (self->provider_unlisted_type_combo);
836
self->providers_idx = gtk_assistant_append_page (GTK_ASSISTANT (self->assistant), vbox);
837
gtk_assistant_set_page_title (GTK_ASSISTANT (self->assistant), vbox, _("Choose your Provider"));
838
gtk_assistant_set_page_type (GTK_ASSISTANT (self->assistant), vbox, GTK_ASSISTANT_PAGE_CONTENT);
839
gtk_widget_show_all (vbox);
841
self->providers_page = vbox;
845
providers_prepare (NMAMobileWizard *self)
847
GtkTreeSelection *selection;
848
GSList *providers, *piter;
851
gtk_tree_store_clear (self->providers_store);
853
country = get_selected_country (self, NULL);
855
/* Unlisted country */
856
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->provider_unlisted_radio), TRUE);
857
gtk_widget_set_sensitive (GTK_WIDGET (self->providers_view_radio), FALSE);
860
gtk_widget_set_sensitive (GTK_WIDGET (self->providers_view_radio), TRUE);
862
providers = g_hash_table_lookup (self->providers, country);
865
for (piter = providers; piter; piter = g_slist_next (piter)) {
866
NmnMobileProvider *provider = piter->data;
867
GtkTreeIter provider_iter;
869
/* Ignore providers that don't match the current device type */
870
if (self->method_type != NMN_MOBILE_ACCESS_METHOD_TYPE_UNKNOWN) {
874
for (miter = provider->methods; miter; miter = g_slist_next (miter)) {
875
NmnMobileAccessMethod *method = miter->data;
877
if (self->method_type == method->type)
885
gtk_tree_store_append (GTK_TREE_STORE (self->providers_store), &provider_iter, NULL);
886
gtk_tree_store_set (GTK_TREE_STORE (self->providers_store),
890
PROVIDER_COL_PROVIDER,
895
g_object_set (G_OBJECT (self->providers_view), "enable-search", TRUE, NULL);
897
gtk_tree_view_set_search_column (GTK_TREE_VIEW (self->providers_view), PROVIDER_COL_NAME);
898
gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->providers_view),
899
providers_search_func, self, NULL);
901
/* If no row has focus yet, focus the first row so that the user can start
902
* incremental search without clicking.
904
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->providers_view));
905
g_assert (selection);
906
if (!gtk_tree_selection_count_selected_rows (selection)) {
907
GtkTreeIter first_iter;
908
GtkTreePath *first_path;
910
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->providers_sort), &first_iter)) {
911
first_path = gtk_tree_model_get_path (GTK_TREE_MODEL (self->providers_sort), &first_iter);
913
gtk_tree_selection_select_path (selection, first_path);
914
gtk_tree_path_free (first_path);
920
providers_radio_toggled (NULL, self);
922
/* Initial completeness state */
923
providers_update_complete (self);
925
/* If there's already a selected device, hide the GSM/CDMA radios */
926
if (self->method_type != NMN_MOBILE_ACCESS_METHOD_TYPE_UNKNOWN)
927
gtk_widget_hide (self->provider_unlisted_type_combo);
929
gtk_widget_show (self->provider_unlisted_type_combo);
932
/**********************************************************/
934
/**********************************************************/
937
country_search_func (GtkTreeModel *model,
941
gpointer search_data)
943
gboolean unmatched = TRUE;
944
char *country = NULL;
949
gtk_tree_model_get (model, iter, column, &country, -1);
953
unmatched = !!g_ascii_strncasecmp (country, key, strlen (key));
959
add_one_country (gpointer key, gpointer value, gpointer user_data)
961
NMAMobileWizard *self = user_data;
962
GtkTreeIter country_iter;
963
GtkTreePath *country_path, *country_view_path;
967
gtk_tree_store_append (GTK_TREE_STORE (self->country_store), &country_iter, NULL);
968
gtk_tree_store_set (GTK_TREE_STORE (self->country_store), &country_iter, 0, key, -1);
970
/* If this country is the same country as the user's current locale,
971
* select it by default.
973
if (!self->country || g_ascii_strcasecmp (self->country, key))
976
country_path = gtk_tree_model_get_path (GTK_TREE_MODEL (self->country_store), &country_iter);
980
country_view_path = gtk_tree_model_sort_convert_child_path_to_path (self->country_sort, country_path);
981
if (country_view_path) {
982
GtkTreeSelection *selection;
984
gtk_tree_view_expand_row (GTK_TREE_VIEW (self->country_view), country_view_path, TRUE);
986
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->country_view));
987
g_assert (selection);
988
gtk_tree_selection_select_path (selection, country_view_path);
989
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (self->country_view),
990
country_view_path, NULL, TRUE, 0, 0);
991
gtk_tree_path_free (country_view_path);
993
gtk_tree_path_free (country_path);
997
get_selected_country (NMAMobileWizard *self, gboolean *out_unlisted)
999
GtkTreeSelection *selection;
1000
GtkTreeModel *model = NULL;
1002
char *country = NULL;
1003
gboolean unlisted = FALSE;
1005
if (!self->country_codes)
1008
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->country_view));
1009
g_assert (selection);
1011
if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) {
1012
gtk_tree_model_get (model, &iter, 0, &country, 1, &unlisted, -1);
1017
*out_unlisted = unlisted;
1025
country_update_complete (NMAMobileWizard *self)
1027
char *country = NULL;
1028
gboolean unlisted = FALSE;
1030
country = get_selected_country (self, &unlisted);
1031
gtk_assistant_set_page_complete (GTK_ASSISTANT (self->assistant),
1033
(!!country || unlisted));
1038
country_sort_func (GtkTreeModel *model,
1043
char *a_str = NULL, *b_str = NULL;
1044
gboolean a_def = FALSE, b_def = FALSE;
1047
gtk_tree_model_get (model, a, 0, &a_str, 1, &a_def, -1);
1048
gtk_tree_model_get (model, b, 0, &b_str, 1, &b_def, -1);
1058
if (a_str && !b_str)
1060
else if (!a_str && b_str)
1062
else if (!a_str && !b_str)
1065
ret = g_utf8_collate (a_str, b_str);
1074
country_setup (NMAMobileWizard *self)
1076
GtkWidget *vbox, *label, *scroll, *alignment;
1077
GtkCellRenderer *renderer;
1078
GtkTreeViewColumn *column;
1079
GtkTreeSelection *selection;
1080
GtkTreeIter unlisted_iter;
1082
#if GTK_CHECK_VERSION(3,1,6)
1083
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1085
vbox = gtk_vbox_new (FALSE, 6);
1087
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
1088
label = gtk_label_new (_("Country or Region List:"));
1089
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1090
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
1092
self->country_store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1094
self->country_sort = GTK_TREE_MODEL_SORT (gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->country_store)));
1095
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self->country_sort), 0, GTK_SORT_ASCENDING);
1097
self->country_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->country_sort));
1099
renderer = gtk_cell_renderer_text_new ();
1100
column = gtk_tree_view_column_new_with_attributes (_("Country or region"), renderer, "text", 0, NULL);
1101
gtk_tree_view_append_column (GTK_TREE_VIEW (self->country_view), column);
1102
gtk_tree_view_column_set_clickable (column, TRUE);
1104
/* My country is not listed... */
1105
gtk_tree_store_append (GTK_TREE_STORE (self->country_store), &unlisted_iter, NULL);
1106
gtk_tree_store_set (GTK_TREE_STORE (self->country_store), &unlisted_iter,
1107
0, _("My country is not listed"),
1110
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (self->country_sort),
1116
/* Add the rest of the providers */
1117
if (self->providers)
1118
g_hash_table_foreach (self->providers, add_one_country, self);
1119
g_object_set (G_OBJECT (self->country_view), "enable-search", TRUE, NULL);
1121
/* If no row has focus yet, focus the first row so that the user can start
1122
* incremental search without clicking.
1124
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->country_view));
1125
g_assert (selection);
1126
if (!gtk_tree_selection_count_selected_rows (selection)) {
1127
GtkTreeIter first_iter;
1128
GtkTreePath *first_path;
1130
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->country_sort), &first_iter)) {
1131
first_path = gtk_tree_model_get_path (GTK_TREE_MODEL (self->country_sort), &first_iter);
1133
gtk_tree_selection_select_path (selection, first_path);
1134
gtk_tree_path_free (first_path);
1139
g_signal_connect_swapped (selection, "changed", G_CALLBACK (country_update_complete), self);
1141
scroll = gtk_scrolled_window_new (NULL, NULL);
1142
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
1143
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
1145
GTK_POLICY_AUTOMATIC);
1146
gtk_container_add (GTK_CONTAINER (scroll), self->country_view);
1148
alignment = gtk_alignment_new (0, 0, 1, 1);
1149
gtk_container_add (GTK_CONTAINER (alignment), scroll);
1150
gtk_box_pack_start (GTK_BOX (vbox), alignment, TRUE, TRUE, 6);
1152
self->country_idx = gtk_assistant_append_page (GTK_ASSISTANT (self->assistant), vbox);
1153
gtk_assistant_set_page_title (GTK_ASSISTANT (self->assistant), vbox, _("Choose your Provider's Country or Region"));
1154
gtk_assistant_set_page_type (GTK_ASSISTANT (self->assistant), vbox, GTK_ASSISTANT_PAGE_CONTENT);
1155
gtk_assistant_set_page_complete (GTK_ASSISTANT (self->assistant), vbox, TRUE);
1156
gtk_widget_show_all (vbox);
1158
self->country_page = vbox;
1160
/* Initial completeness state */
1161
country_update_complete (self);
1165
focus_country_view (gpointer user_data)
1167
NMAMobileWizard *self = user_data;
1169
self->country_focus_id = 0;
1170
gtk_widget_grab_focus (self->country_view);
1175
country_prepare (NMAMobileWizard *self)
1177
gtk_tree_view_set_search_column (GTK_TREE_VIEW (self->country_view), 0);
1178
gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->country_view), country_search_func, self, NULL);
1180
if (!self->country_focus_id)
1181
self->country_focus_id = g_idle_add (focus_country_view, self);
1183
country_update_complete (self);
1186
/**********************************************************/
1188
/**********************************************************/
1190
#define INTRO_COL_NAME 0
1191
#define INTRO_COL_DEVICE 1
1192
#define INTRO_COL_SEPARATOR 2
1195
__intro_device_added (NMAMobileWizard *self, NMDevice *device, gboolean select_it)
1198
const char *desc = utils_get_device_description (device);
1199
NMDeviceModemCapabilities caps;
1201
if (!NM_IS_DEVICE_MODEM (device))
1204
caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
1205
if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) {
1207
desc = _("Installed GSM device");
1208
} else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) {
1210
desc = _("Installed CDMA device");
1214
gtk_tree_store_append (GTK_TREE_STORE (self->dev_store), &iter, NULL);
1215
gtk_tree_store_set (GTK_TREE_STORE (self->dev_store),
1217
INTRO_COL_NAME, desc,
1218
INTRO_COL_DEVICE, device,
1221
/* Select the device just added */
1223
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->dev_combo), &iter);
1225
gtk_widget_set_sensitive (self->dev_combo, TRUE);
1230
intro_device_added_cb (NMClient *client, NMDevice *device, NMAMobileWizard *self)
1232
__intro_device_added (self, device, TRUE);
1236
intro_device_removed_cb (NMClient *client, NMDevice *device, NMAMobileWizard *self)
1239
gboolean have_device = FALSE, removed = FALSE;
1241
if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->dev_store), &iter))
1245
NMDevice *candidate = NULL;
1247
gtk_tree_model_get (GTK_TREE_MODEL (self->dev_store), &iter,
1248
INTRO_COL_DEVICE, &candidate, -1);
1250
if (candidate == device) {
1251
gtk_tree_store_remove (GTK_TREE_STORE (self->dev_store), &iter);
1254
g_object_unref (candidate);
1256
} while (!removed && gtk_tree_model_iter_next (GTK_TREE_MODEL (self->dev_store), &iter));
1258
/* There's already a selected device item; nothing more to do */
1259
if (gtk_combo_box_get_active (GTK_COMBO_BOX (self->dev_combo)) > 1)
1262
/* If there are no more devices, select the "Any" item and disable the
1263
* combo box. If there is no selected item and there is at least one device
1264
* item, select the first one.
1266
if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->dev_store), &iter))
1270
NMDevice *candidate = NULL;
1272
gtk_tree_model_get (GTK_TREE_MODEL (self->dev_store), &iter,
1273
INTRO_COL_DEVICE, &candidate, -1);
1276
g_object_unref (candidate);
1278
} while (!have_device && gtk_tree_model_iter_next (GTK_TREE_MODEL (self->dev_store), &iter));
1281
/* Iter should point to the last device item in the combo */
1282
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->dev_combo), &iter);
1284
gtk_combo_box_set_active (GTK_COMBO_BOX (self->dev_combo), 0);
1285
gtk_widget_set_sensitive (self->dev_combo, FALSE);
1290
intro_add_initial_devices (NMAMobileWizard *self)
1292
const GPtrArray *devices;
1293
gboolean selected_first = FALSE;
1296
devices = nm_client_get_devices (self->client);
1297
for (i = 0; devices && (i < devices->len); i++) {
1298
if (__intro_device_added (self, g_ptr_array_index (devices, i), !selected_first)) {
1299
if (selected_first == FALSE)
1300
selected_first = TRUE;
1304
/* Otherwise the "Any device" item */
1305
if (!selected_first) {
1306
/* Select the first device item by default */
1307
gtk_combo_box_set_active (GTK_COMBO_BOX (self->dev_combo), 0);
1308
gtk_widget_set_sensitive (self->dev_combo, FALSE);
1313
intro_remove_all_devices (NMAMobileWizard *self)
1315
gtk_tree_store_clear (self->dev_store);
1317
/* Select the "Any device" item */
1318
gtk_combo_box_set_active (GTK_COMBO_BOX (self->dev_combo), 0);
1319
gtk_widget_set_sensitive (self->dev_combo, FALSE);
1323
intro_manager_running_cb (NMClient *client, GParamSpec *pspec, NMAMobileWizard *self)
1325
if (nm_client_get_manager_running (client))
1326
intro_add_initial_devices (self);
1328
intro_remove_all_devices (self);
1332
intro_row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
1334
gboolean separator = FALSE;
1335
gtk_tree_model_get (model, iter, INTRO_COL_SEPARATOR, &separator, -1);
1340
intro_combo_changed (NMAMobileWizard *self)
1343
NMDevice *selected = NULL;
1344
NMDeviceModemCapabilities caps;
1346
g_free (self->dev_desc);
1347
self->dev_desc = NULL;
1349
if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self->dev_combo), &iter))
1352
gtk_tree_model_get (GTK_TREE_MODEL (self->dev_store), &iter,
1353
INTRO_COL_DEVICE, &selected, -1);
1355
self->dev_desc = g_strdup (utils_get_device_description (selected));
1356
caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (selected));
1357
if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
1358
self->method_type = NMN_MOBILE_ACCESS_METHOD_TYPE_GSM;
1359
else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
1360
self->method_type = NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA;
1362
g_warning ("%s: unknown modem capabilities 0x%X", __func__, caps);
1364
g_object_unref (selected);
1369
intro_setup (NMAMobileWizard *self)
1371
GtkWidget *vbox, *label, *alignment, *info_vbox;
1372
GtkCellRenderer *renderer;
1375
#if GTK_CHECK_VERSION(3,1,6)
1376
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1378
vbox = gtk_vbox_new (FALSE, 6);
1380
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
1382
label = gtk_label_new (_("This assistant helps you easily set up a mobile broadband connection to a cellular (3G) network."));
1383
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1384
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
1385
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 6);
1387
label = gtk_label_new (_("You will need the following information:"));
1388
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1389
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
1390
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 6);
1392
alignment = gtk_alignment_new (0, 0, 1, 0);
1393
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 25, 25, 0);
1394
#if GTK_CHECK_VERSION(3,1,6)
1395
info_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1397
info_vbox = gtk_vbox_new (FALSE, 6);
1399
gtk_container_add (GTK_CONTAINER (alignment), info_vbox);
1400
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 6);
1402
s = g_strdup_printf ("• %s", _("Your broadband provider's name"));
1403
label = gtk_label_new (s);
1405
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1406
gtk_box_pack_start (GTK_BOX (info_vbox), label, FALSE, TRUE, 0);
1408
s = g_strdup_printf ("• %s", _("Your broadband billing plan name"));
1409
label = gtk_label_new (s);
1411
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1412
gtk_box_pack_start (GTK_BOX (info_vbox), label, FALSE, TRUE, 0);
1414
s = g_strdup_printf ("• %s", _("(in some cases) Your broadband billing plan APN (Access Point Name)"));
1415
label = gtk_label_new (s);
1417
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1418
gtk_box_pack_start (GTK_BOX (info_vbox), label, FALSE, TRUE, 0);
1420
/* Device combo; only built if the wizard's caller didn't pass one in */
1421
if (!self->initial_method_type) {
1424
self->client = nm_client_new ();
1425
g_signal_connect (self->client, "device-added",
1426
G_CALLBACK (intro_device_added_cb), self);
1427
g_signal_connect (self->client, "device-removed",
1428
G_CALLBACK (intro_device_removed_cb), self);
1429
g_signal_connect (self->client, "notify::manager-running",
1430
G_CALLBACK (intro_manager_running_cb), self);
1432
self->dev_store = gtk_tree_store_new (3, G_TYPE_STRING, NM_TYPE_DEVICE, G_TYPE_BOOLEAN);
1433
self->dev_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (self->dev_store));
1434
gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (self->dev_combo),
1435
intro_row_separator_func, NULL, NULL);
1437
renderer = gtk_cell_renderer_text_new ();
1438
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->dev_combo), renderer, TRUE);
1439
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (self->dev_combo), renderer, "text", INTRO_COL_NAME);
1441
label = gtk_label_new_with_mnemonic (_("Create a connection for _this mobile broadband device:"));
1442
gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->dev_combo);
1443
gtk_misc_set_alignment (GTK_MISC (label), 0, 1);
1444
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
1446
alignment = gtk_alignment_new (0, 0, 0.5, 0);
1447
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 25, 0);
1448
gtk_container_add (GTK_CONTAINER (alignment), self->dev_combo);
1449
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
1451
g_signal_connect_swapped (self->dev_combo, "changed", G_CALLBACK (intro_combo_changed), self);
1454
gtk_tree_store_append (GTK_TREE_STORE (self->dev_store), &iter, NULL);
1455
gtk_tree_store_set (GTK_TREE_STORE (self->dev_store), &iter,
1456
INTRO_COL_NAME, _("Any device"), -1);
1459
gtk_tree_store_append (GTK_TREE_STORE (self->dev_store), &iter, NULL);
1460
gtk_tree_store_set (GTK_TREE_STORE (self->dev_store), &iter,
1461
INTRO_COL_SEPARATOR, TRUE, -1);
1463
intro_add_initial_devices (self);
1466
gtk_widget_show_all (vbox);
1467
gtk_assistant_append_page (GTK_ASSISTANT (self->assistant), vbox);
1468
gtk_assistant_set_page_title (GTK_ASSISTANT (self->assistant),
1469
vbox, _("Set up a Mobile Broadband Connection"));
1471
gtk_assistant_set_page_complete (GTK_ASSISTANT (self->assistant), vbox, TRUE);
1472
gtk_assistant_set_page_type (GTK_ASSISTANT (self->assistant), vbox, GTK_ASSISTANT_PAGE_INTRO);
1475
/**********************************************************/
1476
/* General assistant stuff */
1477
/**********************************************************/
1480
remove_provider_focus_idle (NMAMobileWizard *self)
1482
if (self->providers_focus_id) {
1483
g_source_remove (self->providers_focus_id);
1484
self->providers_focus_id = 0;
1489
remove_country_focus_idle (NMAMobileWizard *self)
1491
if (self->country_focus_id) {
1492
g_source_remove (self->country_focus_id);
1493
self->country_focus_id = 0;
1498
assistant_prepare (GtkAssistant *assistant, GtkWidget *page, gpointer user_data)
1500
NMAMobileWizard *self = user_data;
1502
if (page != self->providers_page)
1503
remove_provider_focus_idle (self);
1504
if (page != self->country_page)
1505
remove_country_focus_idle (self);
1507
if (page == self->country_page)
1508
country_prepare (self);
1509
else if (page == self->providers_page)
1510
providers_prepare (self);
1511
else if (page == self->plan_page)
1512
plan_prepare (self);
1513
else if (page == self->confirm_page)
1514
confirm_prepare (self);
1518
forward_func (gint current_page, gpointer user_data)
1520
NMAMobileWizard *self = user_data;
1522
if (current_page == self->providers_idx) {
1523
NmnMobileAccessMethodType method_type = self->method_type;
1525
/* If the provider is unlisted, we can skip ahead of the user's
1526
* access technology is CDMA.
1528
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->provider_unlisted_radio))) {
1529
if (method_type == NMN_MOBILE_ACCESS_METHOD_TYPE_UNKNOWN)
1530
method_type = get_provider_unlisted_type (self);
1532
/* Or, if the provider is only CDMA, then we can also skip ahead */
1533
NmnMobileProvider *provider;
1535
gboolean gsm = FALSE, cdma = FALSE;
1537
provider = get_selected_provider (self);
1539
for (iter = provider->methods; iter; iter = g_slist_next (iter)) {
1540
NmnMobileAccessMethod *method = iter->data;
1542
if (method->type == NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA)
1544
else if (method->type == NMN_MOBILE_ACCESS_METHOD_TYPE_GSM)
1547
nmn_mobile_provider_unref (provider);
1550
method_type = NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA;
1554
/* Skip to the confirm page if we know its CDMA */
1555
if (method_type == NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA) {
1556
self->provider_only_cdma = TRUE;
1557
return self->confirm_idx;
1559
self->provider_only_cdma = FALSE;
1562
return current_page + 1;
1566
get_country_from_locale (void)
1568
char *p, *m, *cc, *lang;
1570
lang = getenv ("LC_ALL");
1572
lang = getenv ("LANG");
1576
p = strchr (lang, '_');
1577
if (!p || !strlen (p)) {
1582
p = cc = g_strdup (++p);
1583
m = strchr (cc, '.');
1588
*p = g_ascii_toupper (*p);
1596
nma_mobile_wizard_new (GtkWindow *parent,
1597
GtkWindowGroup *window_group,
1598
NMDeviceModemCapabilities modem_caps,
1599
gboolean will_connect_after,
1600
NMAMobileWizardCallback cb,
1603
NMAMobileWizard *self;
1606
self = g_malloc0 (sizeof (NMAMobileWizard));
1607
g_return_val_if_fail (self != NULL, NULL);
1609
self->providers = nmn_mobile_providers_parse (&(self->country_codes));
1610
if (!self->providers || !self->country_codes) {
1611
nma_mobile_wizard_destroy (self);
1615
cc = get_country_from_locale ();
1617
self->country = g_hash_table_lookup (self->country_codes, cc);
1620
self->will_connect_after = will_connect_after;
1621
self->callback = cb;
1622
self->user_data = user_data;
1623
if (modem_caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
1624
self->method_type = NMN_MOBILE_ACCESS_METHOD_TYPE_GSM;
1625
else if (modem_caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
1626
self->method_type = NMN_MOBILE_ACCESS_METHOD_TYPE_CDMA;
1627
if (self->method_type)
1628
self->initial_method_type = TRUE; /* Skip device selection */
1630
self->assistant = gtk_assistant_new ();
1631
gtk_assistant_set_forward_page_func (GTK_ASSISTANT (self->assistant),
1632
forward_func, self, NULL);
1633
gtk_window_set_title (GTK_WINDOW (self->assistant), _("New Mobile Broadband Connection"));
1634
gtk_window_set_position (GTK_WINDOW (self->assistant), GTK_WIN_POS_CENTER_ALWAYS);
1637
country_setup (self);
1638
providers_setup (self);
1640
confirm_setup (self);
1642
g_signal_connect (self->assistant, "close", G_CALLBACK (assistant_closed), self);
1643
g_signal_connect (self->assistant, "cancel", G_CALLBACK (assistant_cancel), self);
1644
g_signal_connect (self->assistant, "prepare", G_CALLBACK (assistant_prepare), self);
1646
/* Run the wizard */
1648
gtk_window_set_transient_for (GTK_WINDOW (self->assistant), parent);
1649
gtk_window_set_modal (GTK_WINDOW (self->assistant), TRUE);
1650
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (self->assistant), TRUE);
1651
gtk_window_set_type_hint (GTK_WINDOW (self->assistant), GDK_WINDOW_TYPE_HINT_DIALOG);
1654
gtk_window_group_add_window (window_group, GTK_WINDOW (self->assistant));
1660
nma_mobile_wizard_present (NMAMobileWizard *self)
1662
g_return_if_fail (self != NULL);
1664
gtk_window_present (GTK_WINDOW (self->assistant));
1665
gtk_widget_show_all (self->assistant);
1669
nma_mobile_wizard_destroy (NMAMobileWizard *self)
1671
g_return_if_fail (self != NULL);
1673
g_free (self->dev_desc);
1675
if (self->assistant) {
1676
gtk_widget_hide (self->assistant);
1677
gtk_widget_destroy (self->assistant);
1681
g_object_unref (self->client);
1683
remove_provider_focus_idle (self);
1684
remove_country_focus_idle (self);
1686
if (self->providers)
1687
g_hash_table_destroy (self->providers);
1689
if (self->country_codes)
1690
g_hash_table_destroy (self->country_codes);