Use a standard icon here.
[dhcpcd-ui] / src / dhcpcd-gtk / prefs.c
index 7bf4868dcaf841aa4419bf87e8c0b458bf70912f..603521c89e029dff41327e4d1f5cace70aad39d8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * dhcpcd-gtk
- * Copyright 2009-2012 Roy Marples <roy@marples.name>
+ * Copyright 2009-2014 Roy Marples <roy@marples.name>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,6 +25,7 @@
  */
 
 #include <sys/types.h>
+#include <arpa/inet.h>
 #include <net/if.h>
 
 #include <errno.h>
 
 static GtkWidget *dialog, *blocks, *names, *controls, *clear, *rebind;
 static GtkWidget *autoconf, *address, *router, *dns_servers, *dns_search;
-static DHCPCD_CONFIG *config;
+static DHCPCD_OPTION *config;
 static char *block, *name;
 static DHCPCD_IF *iface;
+static char **ifaces;
 
 static void
-show_config(DHCPCD_CONFIG *conf)
+config_err_dialog(DHCPCD_CONNECTION *con, bool writing, const char *txt)
+{
+       GtkWidget *edialog;
+       char *t;
+
+       t = g_strconcat(_(writing ? "Error saving" : "Error reading"), " ",
+           dhcpcd_cffile(con), "\n\n", txt, NULL);
+       edialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
+           GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", t);
+       gtk_window_set_title(GTK_WINDOW(edialog), _("Config error"));
+       gtk_dialog_run(GTK_DIALOG(edialog));
+       gtk_widget_destroy(edialog);
+       g_free(t);
+}
+
+static void
+show_config(DHCPCD_OPTION *conf)
 {
        const char *val;
        bool autocnf;
@@ -81,25 +99,31 @@ combo_active_text(GtkWidget *widget)
 }
 
 static bool
-set_option(DHCPCD_CONFIG **conf, bool s, const char *opt, const char *val,
+set_option(DHCPCD_OPTION **conf, bool s, const char *opt, const char *val,
        bool *ret)
 {
-       bool r;
 
-       if (s)
-               r = dhcpcd_config_set_static(conf, opt, val);
-       else
-               r = dhcpcd_config_set(conf, opt, val);
-       if (r)
-               return true;
-       g_error("libdhcpcd: %s", strerror(errno));
+       if (s) {
+               if (!dhcpcd_config_set_static(conf, opt, val))
+                       g_critical("dhcpcd_config_set_static: %s",
+                           strerror(errno));
+               else
+                       return true;
+       } else {
+               if (!dhcpcd_config_set(conf, opt, val))
+                       g_critical("dhcpcd_config_set: %s",
+                           strerror(errno));
+               else
+                       return true;
+       }
+
        if (ret)
                *ret = false;
        return false;
 }
 
 static bool
-make_config(DHCPCD_CONFIG **conf)
+make_config(DHCPCD_OPTION **conf)
 {
        const char *val, ns[] = "";
        bool a, ret;
@@ -115,25 +139,42 @@ make_config(DHCPCD_CONFIG **conf)
                set_option(conf, false, "inform", a ? val : NULL, &ret);
                set_option(conf, true, "ip_address=", a ? NULL : val, &ret);
        }
-       
+
        val = gtk_entry_get_text(GTK_ENTRY(router));
        if (a && *val == '\0')
                val = NULL;
        set_option(conf, true, "routers=", val, &ret);
-       
+
        val = gtk_entry_get_text(GTK_ENTRY(dns_servers));
        if (a && *val == '\0')
                val = NULL;
        set_option(conf, true, "domain_name_servers=", val, &ret);
-       
+
        val = gtk_entry_get_text(GTK_ENTRY(dns_search));
        if (a && *val == '\0')
                val = NULL;
        set_option(conf, true, "domain_search=", val, &ret);
-       
+
        return ret;
 }
 
+static bool
+write_config(DHCPCD_CONNECTION *con, DHCPCD_OPTION **conf)
+{
+
+       if (make_config(conf) &&
+           !dhcpcd_config_write(con, block, name, *conf))
+       {
+               const char *s;
+
+               s = strerror(errno);
+               g_warning("dhcpcd_config_write: %s", s);
+               config_err_dialog(con, true, s);
+               return false;
+       }
+       return true;
+}
+
 static GdkPixbuf *
 load_icon(const char *iname)
 {
@@ -170,24 +211,25 @@ static GSList *
 list_interfaces(DHCPCD_CONNECTION *con)
 {
        GSList *list;
-       DHCPCD_IF *i;
+       char **i;
 
        list = NULL;
-       for (i = dhcpcd_interfaces(con); i; i = i->next)
-               if (strcmp(i->type, "ipv4") == 0)
-                       list = g_slist_append(list, i->ifname);
+       dhcpcd_freev(ifaces);
+       ifaces = dhcpcd_interface_names_sorted(con);
+       for (i = ifaces; i && *i; i++)
+               list = g_slist_append(list, *i);
        return list;
 }
 
 static GSList *
-list_ssids(WI_SCAN *scans)
+list_ssids(WI_SCANS *scans)
 {
        GSList *list, *l;
        WI_SCAN *w;
        DHCPCD_WI_SCAN *wis;
 
        list = NULL;
-       for (w = scans; w; w = w->next) {
+       TAILQ_FOREACH(w, scans, next) {
                for (wis = w->scans; wis; wis = wis->next) {
                        for (l = list; l; l = l->next)
                                if (g_strcmp0((const char *)l->data,
@@ -214,8 +256,7 @@ blocks_on_change(GtkWidget *widget, gpointer data)
 
        con = (DHCPCD_CONNECTION *)data;
        if (name) {
-               if (make_config(&config))
-                       dhcpcd_config_save(con, block, name, config);
+               write_config(con, &config);
                dhcpcd_config_free(config);
                config = NULL;
                show_config(config);
@@ -226,22 +267,25 @@ blocks_on_change(GtkWidget *widget, gpointer data)
        block = combo_active_text(widget);
        store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(names)));
        gtk_list_store_clear(store);
-       list = dhcpcd_config_blocks_get(con, block);
-       
+       list = dhcpcd_config_blocks(con, block);
+
        if (g_strcmp0(block, "interface") == 0)
                new_names = list_interfaces(con);
        else
-               new_names = list_ssids(wi_scans);
+               new_names = list_ssids(&wi_scans);
 
        n = 0;
        for (l = new_names; l; l = l->next) {
                nn = (const char *)l->data;
-               for (lp = list; *lp; lp++)
-                       if (g_strcmp0(nn, *lp) == 0)
-                               break;
-               if (*lp)
-                       iname = "document-save";
-               else
+               if (list) {
+                       for (lp = list; *lp; lp++)
+                               if (g_strcmp0(nn, *lp) == 0)
+                                       break;
+                       if (*lp)
+                               iname = "document-save";
+                       else
+                               iname = "document-new";
+               } else
                        iname = "document-new";
                pb = load_icon(iname);
                gtk_list_store_append(store, &iter);
@@ -250,7 +294,7 @@ blocks_on_change(GtkWidget *widget, gpointer data)
                n++;
        }
 
-       for (lp = list; *lp; lp++) {
+       for (lp = list; lp && *lp; lp++) {
                for (l = new_names; l; l = l->next)
                        if (g_strcmp0((const char *)l->data, *lp) == 0)
                                break;
@@ -264,7 +308,7 @@ blocks_on_change(GtkWidget *widget, gpointer data)
        }
        gtk_widget_set_sensitive(names, n);
        g_slist_free(new_names);
-       g_strfreev(list);
+       dhcpcd_freev(list);
 }
 
 static void
@@ -275,8 +319,7 @@ names_on_change(_unused GtkWidget *widget, gpointer data)
 
        con = (DHCPCD_CONNECTION *)data;
        if (name) {
-               if (make_config(&config))
-                       dhcpcd_config_save(con, block, name, config);
+               write_config(con, &config);
                g_free(name);
        }
        name = combo_active_text(names);
@@ -290,11 +333,17 @@ names_on_change(_unused GtkWidget *widget, gpointer data)
                        }
        }
        gtk_widget_set_sensitive(address,
-           iface && (iface->flags & IFF_POINTOPOINT) == 0);
+           !iface || (iface->flags & IFF_POINTOPOINT) == 0);
        if (block && name) {
-               config = dhcpcd_config_load(con, block, name);
-               if (config == NULL && dhcpcd_error(con))
-                       g_error("libdhcpcd: %s", dhcpcd_error(con));
+               errno = 0;
+               config = dhcpcd_config_read(con, block, name);
+               if (config == NULL && errno) {
+                       const char *s;
+
+                       s = strerror(errno);
+                       g_warning("dhcpcd_config_read: %s", s);
+                       config_err_dialog(con, false, s);
+               }
        } else
                config = NULL;
        show_config(config);
@@ -328,13 +377,12 @@ valid_address(const char *val, bool allow_cidr)
                }
        }
        retval = inet_aton(addr, &in) == 0 ? false : true;
-       
+
 out:
        g_free(addr);
        return retval;
 }
 
-       
 static bool
 address_lost_focus(GtkEntry *entry)
 {
@@ -365,62 +413,69 @@ entry_lost_focus(GtkEntry *entry)
 }
 
 static void
-on_clear(_unused GtkObject *o, gpointer data)
+on_clear(_unused GtkWidget *o, gpointer data)
 {
        DHCPCD_CONNECTION *con;
 
        con = (DHCPCD_CONNECTION *)data;
        dhcpcd_config_free(config);
        config = NULL;
-       if (dhcpcd_config_save(con, block, name, config)) {
+       if (dhcpcd_config_write(con, block, name, config)) {
                set_name_active_icon("document-new");
                show_config(config);
-       }
+       } else
+               g_critical("dhcpcd_config_write: %s", strerror(errno));
 }
 
 static void
-on_rebind(_unused GtkWidget *widget, gpointer data)
+on_rebind(_unused GObject *widget, gpointer data)
 {
        DHCPCD_CONNECTION *con;
        DHCPCD_IF *i;
 
        con = (DHCPCD_CONNECTION *)data;
-       if (make_config(&config) &&
-           dhcpcd_config_save(con, block, name, config)) {
+       if (write_config(con, &config)) {
                set_name_active_icon(config == NULL ?
                    "document-new" : "document-save");
                show_config(config);
-               if (g_strcmp0(block, "interface") == 0)
-                       dhcpcd_rebind(con, iface);
-               else {
+               if (g_strcmp0(block, "interface") == 0) {
+                       if (dhcpcd_rebind(con, iface->ifname) == -1)
+                               g_critical("dhcpcd_rebind %s: %s",
+                                   iface->ifname, strerror(errno));
+               } else {
                        for (i = dhcpcd_interfaces(con); i; i = i->next) {
-                               if (g_strcmp0(i->ssid, name) == 0)
-                                       dhcpcd_rebind(con, i);
+                               if (g_strcmp0(i->ssid, name) == 0) {
+                                       if (dhcpcd_rebind(con, i->ifname) == -1)
+                                               g_critical(
+                                                   "dhcpcd_rebind %s: %s",
+                                                   i->ifname,
+                                                   strerror(errno));
+                               }
                        }
                }
-               if (dhcpcd_error(con))
-                       g_warning("libdhcpcd: %s", dhcpcd_error(con));
        }
 }
 
 static void
-on_destroy(_unused GtkObject *o, gpointer data)
+on_destroy(_unused GObject *o, gpointer data)
 {
+
        if (name != NULL) {
-               if (make_config(&config))
-                       dhcpcd_config_save((DHCPCD_CONNECTION *)data,
-                           block, name, config);
+               write_config((DHCPCD_CONNECTION *)data, &config);
                g_free(block);
                g_free(name);
                block = name = NULL;
        }
        dhcpcd_config_free(config);
        config = NULL;
+       dhcpcd_freev(ifaces);
+       ifaces = NULL;
        dialog = NULL;
+
 }
 
 static void
-dhcpcd_prefs_close(void)
+prefs_close(void)
 {
        if (dialog != NULL) {
                gtk_widget_destroy(dialog);
@@ -429,22 +484,34 @@ dhcpcd_prefs_close(void)
 }
 
 void
-dhcpcd_prefs_abort(void)
+prefs_abort(void)
 {
        g_free(name);
        name = NULL;
-       dhcpcd_prefs_close();
+       prefs_close();
+}
+
+#if GTK_MAJOR_VERSION == 2
+static GtkWidget *
+gtk_separator_new(GtkOrientation o)
+{
+
+       if (o == GTK_ORIENTATION_HORIZONTAL)
+               return gtk_hseparator_new();
+       else
+               return gtk_vseparator_new();
 }
+#endif
 
 void
-dhcpcd_prefs_show(DHCPCD_CONNECTION *con)
+prefs_show(DHCPCD_CONNECTION *con)
 {
        GtkWidget *dialog_vbox, *hbox, *vbox, *table, *w;
        GtkListStore *store;
        GtkTreeIter iter;
        GtkCellRenderer *rend;
        GdkPixbuf *pb;
-       
+
        if (dialog) {
                gtk_window_present(GTK_WINDOW(dialog));
                return;
@@ -460,16 +527,16 @@ dhcpcd_prefs_show(DHCPCD_CONNECTION *con)
        gtk_window_set_title(GTK_WINDOW(dialog), _("Network Preferences"));
        gtk_window_set_resizable(GTK_WINDOW(dialog), false);
        gtk_window_set_icon_name(GTK_WINDOW(dialog),
-           "network-transmit-receive");
+           "preferences-system-network");
        gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
        gtk_window_set_type_hint(GTK_WINDOW(dialog),
            GDK_WINDOW_TYPE_HINT_DIALOG);
 
-       dialog_vbox = gtk_vbox_new(false, 10);
+       dialog_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
        gtk_container_set_border_width(GTK_CONTAINER(dialog), 10);
        gtk_container_add(GTK_CONTAINER(dialog), dialog_vbox);
 
-       hbox = gtk_hbox_new(false, 0);
+       hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
        gtk_box_pack_start(GTK_BOX(dialog_vbox), hbox, false, false, 3);
        w = gtk_label_new("Configure:");
        gtk_box_pack_start(GTK_BOX(hbox), w, false, false, 3);
@@ -480,7 +547,7 @@ dhcpcd_prefs_show(DHCPCD_CONNECTION *con)
        g_object_unref(pb);
        pb = load_icon("network-wireless");
        gtk_list_store_append(store, &iter);
-       gtk_list_store_set(store, &iter, 0, pb, 1, "ssid", -1);
+       gtk_list_store_set(store, &iter, 0, pb, 1, "SSID", -1);
        g_object_unref(pb);
        blocks = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
        rend = gtk_cell_renderer_pixbuf_new();
@@ -508,13 +575,13 @@ dhcpcd_prefs_show(DHCPCD_CONNECTION *con)
            G_CALLBACK(blocks_on_change), con);
        g_signal_connect(G_OBJECT(names), "changed",
            G_CALLBACK(names_on_change), con);
-       
-       w = gtk_hseparator_new();
+
+       w = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
        gtk_box_pack_start(GTK_BOX(dialog_vbox), w, true, false, 3);
-       controls = gtk_vbox_new(false, 10);
+       controls = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
        gtk_widget_set_sensitive(controls, false);
        gtk_box_pack_start(GTK_BOX(dialog_vbox), controls, true, true, 0);
-       vbox = gtk_vbox_new(false, 3);
+       vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
        gtk_box_pack_start(GTK_BOX(controls), vbox, false, false, 0);
        autoconf = gtk_check_button_new_with_label(
                _("Automatically configure empty options"));
@@ -531,7 +598,7 @@ dhcpcd_prefs_show(DHCPCD_CONNECTION *con)
 #define attach_entry(a, b, c, d, e)                                          \
        gtk_table_attach(GTK_TABLE(table), a, b, c, d, e,                     \
            GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 3, 3);
-       
+
        w = gtk_label_new(_("IP Address:"));
        address = gtk_entry_new();
        gtk_entry_set_max_length(GTK_ENTRY(address), 18);
@@ -560,26 +627,26 @@ dhcpcd_prefs_show(DHCPCD_CONNECTION *con)
        attach_label(w, 0, 1, 4, 5);
        attach_entry(dns_search, 1, 2, 4, 5);
 
-       hbox = gtk_hbox_new(false, 10);
+       hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
        gtk_box_pack_start(GTK_BOX(dialog_vbox), hbox, true, true, 3);
        clear = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
        gtk_widget_set_sensitive(clear, false);
-       gtk_box_pack_start(GTK_BOX(hbox), clear, false, false, 0);
+       gtk_box_pack_start(GTK_BOX(hbox), clear, true, true, 0);
        g_signal_connect(G_OBJECT(clear), "clicked",
            G_CALLBACK(on_clear), con);
        rebind = gtk_button_new_with_mnemonic(_("_Rebind"));
        gtk_widget_set_sensitive(rebind, false);
-       w = gtk_image_new_from_stock(GTK_STOCK_EXECUTE,
+       w = gtk_image_new_from_icon_name("application-x-executable",
            GTK_ICON_SIZE_BUTTON);
        gtk_button_set_image(GTK_BUTTON(rebind), w);
-       gtk_box_pack_start(GTK_BOX(hbox), rebind, false, false, 0);
+       gtk_box_pack_start(GTK_BOX(hbox), rebind, true, true, 0);
        g_signal_connect(G_OBJECT(rebind), "clicked",
            G_CALLBACK(on_rebind), con);
        w = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
-       gtk_box_pack_end(GTK_BOX(hbox), w, false, false, 0);
+       gtk_box_pack_end(GTK_BOX(hbox), w, true, true, 0);
        g_signal_connect(G_OBJECT(w), "clicked",
-           G_CALLBACK(dhcpcd_prefs_close), NULL);
-       
+           G_CALLBACK(prefs_close), NULL);
+
        blocks_on_change(blocks, con);
        show_config(NULL);
        gtk_widget_show_all(dialog);