/* * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * $Id$ */ #include "language-editor.h" #include "ephy-gui.h" #include "eel-gconf-extensions.h" #include "ephy-debug.h" #include #include #include #include #include #include #include #include #include #include #include enum { COL_DESCRIPTION, COL_DATA }; enum { TREEVIEW_PROP, ADD_PROP, REMOVE_PROP, LANGUAGE_PROP }; static const EphyDialogProperty properties [] = { { "languages_treeview", NULL, PT_NORMAL, 0 }, { "add_button", NULL, PT_NORMAL, 0 }, { "remove_button", NULL, PT_NORMAL, 0 }, { "languages_combo", NULL, PT_NORMAL, 0 }, { NULL } }; #define EPHY_LANGUAGE_EDITOR_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_LANGUAGE_EDITOR, LanguageEditorPrivate)) struct LanguageEditorPrivate { GtkWidget *treeview; GtkTreeModel *model; }; static void language_editor_class_init (LanguageEditorClass *klass); static void language_editor_init (LanguageEditor *ge); /* Glade callbacks */ void language_editor_close_button_cb (GtkWidget *button, EphyDialog *dialog); enum { CHANGED, LAST_SIGNAL }; static gint signals[LAST_SIGNAL]; static GObjectClass *parent_class = NULL; GType language_editor_get_type (void) { static GType type = 0; if (type == 0) { static const GTypeInfo our_info = { sizeof (LanguageEditorClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc) language_editor_class_init, NULL, NULL, /* class_data */ sizeof (LanguageEditor), 0, /* n_preallocs */ (GInstanceInitFunc) language_editor_init }; type = g_type_register_static (EPHY_TYPE_DIALOG, "LanguageEditor", &our_info, 0); } return type; } static void language_editor_class_init (LanguageEditorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); signals[CHANGED] = g_signal_new ("list-changed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (LanguageEditorClass, list_changed), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); g_type_class_add_private (object_class, sizeof(LanguageEditorPrivate)); } static void language_editor_update_pref (LanguageEditor *editor) { GtkTreeIter iter; GSList *codes = NULL; if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (editor->priv->model), &iter)) { return; } do { GValue value = {0, }; gtk_tree_model_get_value (GTK_TREE_MODEL (editor->priv->model), &iter, COL_DATA, &value); codes = g_slist_append (codes, g_value_dup_string (&value)); g_value_unset (&value); } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (editor->priv->model), &iter)); g_signal_emit (editor, signals[CHANGED], 0, codes); g_slist_foreach (codes, (GFunc) g_free, NULL); g_slist_free (codes); } static void language_editor_add_button_clicked_cb (GtkButton *button, LanguageEditor *editor) { GtkWidget *combo; GtkTreeModel *model; GtkTreeIter iter; char *code = NULL, *desc = NULL; int index; combo = ephy_dialog_get_control (EPHY_DIALOG (editor), properties[LANGUAGE_PROP].id); model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); index = gtk_combo_box_get_active (GTK_COMBO_BOX (combo)); if (gtk_tree_model_iter_nth_child (model, &iter, NULL, index)) { gtk_tree_model_get (model, &iter, 0, &desc, 1, &code, -1); language_editor_add (editor, code, desc); g_free (desc); g_free (code); } language_editor_update_pref (editor); } static void language_editor_remove_button_clicked_cb (GtkButton *button, LanguageEditor *editor) { GList *llist, *rlist = NULL, *l, *r; GtkTreeIter iter; GtkTreeSelection *selection; GtkTreeModel *model; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(editor->priv->treeview)); llist = gtk_tree_selection_get_selected_rows (selection, &model); for (l = llist;l != NULL; l = l->next) { rlist = g_list_prepend (rlist, gtk_tree_row_reference_new (model, (GtkTreePath *)l->data)); } for (r = rlist; r != NULL; r = r->next) { GtkTreePath *path; path = gtk_tree_row_reference_get_path ((GtkTreeRowReference *)r->data); gtk_tree_model_get_iter (model, &iter, path); gtk_list_store_remove (GTK_LIST_STORE (model), &iter); gtk_tree_row_reference_free ((GtkTreeRowReference *)r->data); gtk_tree_path_free (path); } g_list_foreach (llist, (GFunc)gtk_tree_path_free, NULL); g_list_free (llist); g_list_free (rlist); language_editor_update_pref (editor); } static void language_editor_treeview_drag_end_cb (GtkWidget *widget, GdkDragContext *context, LanguageEditor *editor) { language_editor_update_pref (editor); } static void language_editor_set_view (LanguageEditor *ge, GtkWidget *treeview, GtkWidget *add_button, GtkWidget *remove_button) { GtkTreeViewColumn *column; GtkCellRenderer *renderer; GtkListStore *liststore; GtkTreeSelection *selection; ge->priv->treeview = treeview; gtk_tree_view_set_reorderable (GTK_TREE_VIEW(ge->priv->treeview), TRUE); liststore = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); ge->priv->model = GTK_TREE_MODEL (liststore); gtk_tree_view_set_model (GTK_TREE_VIEW(ge->priv->treeview), ge->priv->model); g_object_unref (ge->priv->model); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(ge->priv->treeview), FALSE); renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(ge->priv->treeview), 0, "Language", renderer, "text", 0, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW(ge->priv->treeview), 0); gtk_tree_view_column_set_resizable (column, TRUE); gtk_tree_view_column_set_sort_column_id (column, COL_DESCRIPTION); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(ge->priv->treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); /* Connect treeview signals */ g_signal_connect (G_OBJECT (ge->priv->treeview), "drag_end", G_CALLBACK (language_editor_treeview_drag_end_cb), ge); /* Connect buttons signals */ g_signal_connect (G_OBJECT (add_button), "clicked", G_CALLBACK (language_editor_add_button_clicked_cb), ge); g_signal_connect (G_OBJECT (remove_button), "clicked", G_CALLBACK (language_editor_remove_button_clicked_cb), ge); } static void language_editor_init (LanguageEditor *le) { GtkWidget *treeview; GtkWidget *add_button; GtkWidget *remove_button; le->priv = EPHY_LANGUAGE_EDITOR_GET_PRIVATE (le); ephy_dialog_construct (EPHY_DIALOG(le), properties, "prefs-dialog.glade", "languages_dialog"); treeview = ephy_dialog_get_control (EPHY_DIALOG(le), properties[TREEVIEW_PROP].id); add_button = ephy_dialog_get_control (EPHY_DIALOG(le), properties[ADD_PROP].id); remove_button = ephy_dialog_get_control (EPHY_DIALOG(le), properties[REMOVE_PROP].id); language_editor_set_view (le, treeview, add_button, remove_button); } LanguageEditor * language_editor_new (GtkWidget *parent) { return EPHY_LANGUAGE_EDITOR (g_object_new (EPHY_TYPE_LANGUAGE_EDITOR, "parent-window", parent, NULL)); } void language_editor_set_model (LanguageEditor *editor, GtkTreeModel *model) { GtkWidget *combo; GtkCellRenderer *renderer; combo = ephy_dialog_get_control (EPHY_DIALOG (editor), properties[LANGUAGE_PROP].id); gtk_combo_box_set_model (GTK_COMBO_BOX (combo), model); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", COL_DESCRIPTION, NULL); ephy_dialog_set_data_column (EPHY_DIALOG (editor), properties[LANGUAGE_PROP].id, COL_DATA); gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); } void language_editor_add (LanguageEditor *editor, const char *code, const char *desc) { GtkTreeIter iter; g_return_if_fail (code != NULL && desc != NULL); /* first check that the code isn't already in the list */ if (gtk_tree_model_get_iter_first (editor->priv->model, &iter)) { do { char *c; gtk_tree_model_get (editor->priv->model, &iter, COL_DATA, &c, -1); if (c && strcmp (code, c) == 0) { /* already in list, no need to add again */ g_free (c); return; } g_free (c); } while (gtk_tree_model_iter_next (editor->priv->model, &iter)); } gtk_list_store_append (GTK_LIST_STORE (editor->priv->model), &iter); gtk_list_store_set (GTK_LIST_STORE (editor->priv->model), &iter, COL_DESCRIPTION, desc, COL_DATA, code, -1); } void language_editor_close_button_cb (GtkWidget *button, EphyDialog *dialog) { g_object_unref (dialog); }