17
17
* with this program; if not, write to the Free Software Foundation, Inc.,
18
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
* (C) Copyright 2008 - 2010 Red Hat, Inc.
20
* (C) Copyright 2008 - 2011 Red Hat, Inc.
23
25
#include <string.h>
25
27
#include <stdlib.h>
26
#include <arpa/inet.h>
28
29
#include <gtk/gtk.h>
30
#include <gdk/gdkkeysyms.h>
29
31
#include <glib/gi18n.h>
30
32
#include <sys/socket.h>
31
33
#include <netinet/in.h>
86
88
gboolean window_added;
88
90
/* Cached tree view entry for editing-canceled */
91
/* Used also for saving old value when switching between cells via mouse
92
* clicks - GTK3 produces neither editing-canceled nor editing-done for
94
char *last_edited; /* cell text */
95
char *last_path; /* row in treeview */
96
int last_column; /* column in treeview */
90
97
} CEPageIP6Private;
92
99
#define METHOD_COL_NAME 0
372
378
tmp_addr = nm_ip6_address_get_address (addr);
373
ignored = inet_ntop (AF_INET6, tmp_addr, &buf[0], sizeof (buf));
379
(void) inet_ntop (AF_INET6, tmp_addr, &buf[0], sizeof (buf));
374
380
gtk_list_store_set (store, &model_iter, COL_ADDRESS, buf, -1);
381
387
tmp_addr = nm_ip6_address_get_gateway (addr);
382
388
if (tmp_addr && !IN6_IS_ADDR_UNSPECIFIED (tmp_addr)) {
383
ignored = inet_ntop (AF_INET6, tmp_addr, &buf[0], sizeof (buf));
389
(void) inet_ntop (AF_INET6, tmp_addr, &buf[0], sizeof (buf));
384
390
gtk_list_store_set (store, &model_iter, COL_GATEWAY, buf, -1);
395
401
for (i = 0; i < nm_setting_ip6_config_get_num_dns (setting); i++) {
396
402
const struct in6_addr *tmp_addr;
397
403
char buf[INET6_ADDRSTRLEN + 1];
400
405
tmp_addr = nm_setting_ip6_config_get_dns (setting, i);
404
ignored = inet_ntop (AF_INET6, tmp_addr, &buf[0], sizeof (buf));
409
(void) inet_ntop (AF_INET6, tmp_addr, &buf[0], sizeof (buf));
406
411
g_string_append (string, ", ");
407
412
g_string_append (string, buf);
546
555
GtkTreeViewColumn *next_col;
557
/* Free auxiliary stuff */
548
558
g_free (priv->last_edited);
549
559
priv->last_edited = NULL;
560
g_free (priv->last_path);
561
priv->last_path = NULL;
562
priv->last_column = -1;
551
564
column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cell), "column"));
552
565
gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
556
569
column = (column >= COL_LAST) ? 0 : column + 1;
557
570
next_col = gtk_tree_view_get_column (priv->addr_list, column);
558
571
gtk_tree_view_set_cursor_on_cell (priv->addr_list, path, next_col, priv->addr_cells[column], TRUE);
559
gtk_widget_grab_focus (GTK_WIDGET (priv->addr_list));
561
573
gtk_tree_path_free (path);
562
574
ce_page_changed (CE_PAGE (self));
622
delete_text_cb (GtkEditable *editable,
627
CEPageIP6 *self = CE_PAGE_IP6 (user_data);
628
CEPageIP6Private *priv = CE_PAGE_IP6_GET_PRIVATE (self);
630
/* Keep last_edited up-to-date */
631
g_free (priv->last_edited);
632
priv->last_edited = g_strdup (gtk_editable_get_chars (editable, 0, -1));
636
cell_changed_cb (GtkEditable *editable,
641
#if GTK_CHECK_VERSION(3,0,0)
646
gboolean value_valid = FALSE;
647
const char *colorname = NULL;
649
cell_text = gtk_editable_get_chars (editable, 0, -1);
651
/* The Prefix column is 0..128 */
652
column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (user_data), "column"));
653
if (column == COL_PREFIX) {
657
prefix = strtoul (cell_text, &end, 10);
658
if (!end || *end || prefix == 0 || prefix > 128)
663
struct in6_addr tmp_addr;
665
if (inet_pton (AF_INET6, cell_text, &tmp_addr))
669
/* Change cell's background color while editing */
670
colorname = value_valid ? "lightgreen" : "red";
672
#if GTK_CHECK_VERSION(3,0,0)
673
gdk_rgba_parse (&rgba, colorname);
674
gtk_widget_override_background_color (GTK_WIDGET (editable), GTK_STATE_NORMAL, &rgba);
676
gdk_color_parse (colorname, &color);
677
gtk_widget_modify_base (GTK_WIDGET (editable), GTK_STATE_NORMAL, &color);
685
key_pressed_cb (GtkWidget *widget,
690
#define GDK_KEY_Tab GDK_Tab
693
/* Tab should behave the same way as Enter (finish editing) */
694
if (event->type == GDK_KEY_PRESS && event->key.keyval == GDK_KEY_Tab)
695
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget));
610
701
cell_editing_started (GtkCellRenderer *cell,
611
702
GtkCellEditable *editable,
612
703
const gchar *path,
715
/* Initialize last_path and last_column, last_edited is initialized when the cell is edited */
624
716
g_free (priv->last_edited);
625
717
priv->last_edited = NULL;
718
g_free (priv->last_path);
719
priv->last_path = g_strdup (path);
720
priv->last_column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cell), "column"));
627
722
/* Need to pass column # to the editable's insert-text function */
628
723
column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cell), "column"));
632
727
g_signal_connect (G_OBJECT (editable), "insert-text",
633
728
(GCallback) ip_address_filter_cb,
731
g_signal_connect_after (G_OBJECT (editable), "delete-text",
732
(GCallback) delete_text_cb,
735
/* Set up handler for value verifying and changing cell background */
736
g_signal_connect (G_OBJECT (editable), "changed",
737
(GCallback) cell_changed_cb,
740
/* Set up key pressed handler - need to handle Tab key */
741
g_signal_connect (G_OBJECT (editable), "key-press-event",
742
(GCallback) key_pressed_cb,
694
803
gtk_widget_show_all (dialog);
807
tree_view_button_pressed_cb (GtkWidget *widget,
811
CEPageIP6 *self = CE_PAGE_IP6 (user_data);
812
CEPageIP6Private *priv = CE_PAGE_IP6_GET_PRIVATE (self);
814
/* last_edited can be set e.g. when we get here by clicking an cell while
815
* editing another cell. GTK3 issue neither editing-canceled nor editing-done
816
* for cell renderer. Thus the previous cell value isn't saved. Store it now. */
817
if (priv->last_edited && priv->last_path) {
819
GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->addr_list));
820
GtkTreePath *last_treepath = gtk_tree_path_new_from_string (priv->last_path);
822
gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, last_treepath);
823
gtk_list_store_set (store, &iter, priv->last_column, priv->last_edited, -1);
824
gtk_tree_path_free (last_treepath);
826
g_free (priv->last_edited);
827
priv->last_edited = NULL;
828
g_free (priv->last_path);
829
priv->last_path = NULL;
830
priv->last_column = -1;
833
/* Ignore double clicks events. (They are issued after the single clicks, see GdkEventButton) */
834
if (event->type == GDK_2BUTTON_PRESS)
837
gtk_widget_grab_focus (GTK_WIDGET (priv->addr_list));
698
842
finish_setup (CEPageIP6 *self, gpointer unused, GError *error, gpointer user_data)
703
847
GtkTreeViewColumn *column;
704
848
GtkCellRenderer *renderer;
710
853
populate_ui (self);
713
store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->addr_list));
715
855
/* IP Address column */
716
856
renderer = gtk_cell_renderer_text_new ();
717
857
g_object_set (renderer, "editable", TRUE, NULL);
763
903
gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
764
904
gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
906
g_signal_connect (priv->addr_list, "button-press-event", G_CALLBACK (tree_view_button_pressed_cb), self);
766
908
gtk_widget_set_sensitive (GTK_WIDGET (priv->addr_add), TRUE);
767
909
gtk_widget_set_sensitive (GTK_WIDGET (priv->addr_delete), FALSE);