X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-acr.c;h=82f9aa2c16231969454ec16583e0d8671d69830a;hb=ceaed4a17cb3b0a14c89f10b72a636f94af97e7a;hp=0de169c2dc41647ff78d8acb2fdac6c28a0f7b78;hpb=7751519f5ca0b6106fe3d611010a70804677ab86;p=pspp diff --git a/src/ui/gui/psppire-acr.c b/src/ui/gui/psppire-acr.c index 0de169c2dc..82f9aa2c16 100644 --- a/src/ui/gui/psppire-acr.c +++ b/src/ui/gui/psppire-acr.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007, 2012 Free Software Foundation, Inc. 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 @@ -14,68 +14,150 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ + +/* + This widget is a GtkBox which looks roughly like: + + +-----------------------------+ + |+------------+ +----------+ | + || Add | | | | + |+------------+ | | | + | | | | + |+------------+ | | | + || Edit | | | | + |+------------+ | | | + | | | | + |+------------+ | | | + || Remove | | | | + |+------------+ +----------+ | + +-----------------------------+ + +*/ + +#include #include #include "psppire-acr.h" +#include "helper.h" -static void psppire_acr_init (PsppireAcr *); +#include "gettext.h" +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid -enum { - COLUMN_DOUBLE, - n_COLUMNS -}; +G_DEFINE_TYPE (PsppireAcr, psppire_acr, GTK_TYPE_BOX); + +static void +psppire_acr_dispose (GObject *obj) +{ + PsppireAcr *acr = PSPPIRE_ACR (obj); + if (acr->dispose_has_run) + return; + acr->dispose_has_run = TRUE; -GType -psppire_acr_get_type (void) + psppire_acr_set_model (acr, NULL); + + G_OBJECT_CLASS (psppire_acr_parent_class)->dispose (obj); +} + +static void +psppire_acr_class_init (PsppireAcrClass *class) { - static GType acr_type = 0; + G_OBJECT_CLASS (class)->dispose = psppire_acr_dispose; +} - if (!acr_type) - { - static const GTypeInfo acr_info = - { - sizeof (PsppireAcrClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - NULL, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PsppireAcr), - 0, - (GInstanceInitFunc) psppire_acr_init, - }; - - acr_type = g_type_register_static (GTK_TYPE_HBOX, "PsppireAcr", - &acr_info, 0); - } +static gboolean row_is_selected (const PsppireAcr *acr); + + +static gboolean +value_from_entry (gint col, GValue *val, gpointer data) +{ + GtkEntry *entry = data; + const gchar *text = gtk_entry_get_text (entry); + gdouble x = g_strtod (text, 0); + + g_value_init (val, G_TYPE_DOUBLE); + g_value_set_double (val, x); - return acr_type; + return TRUE; } + +/* Returns true, if there's text in the entry */ +static gboolean +entry_not_empty (gpointer data) +{ + GtkEntry *entry = data; + + const char *text = gtk_entry_get_text (entry); + + return !g_str_equal (text, ""); +} + + static void -on_add_button_clicked (PsppireAcr *acr) +clear_entry (gpointer data) { - GtkTreeIter iter; - gdouble x; + GtkEntry *entry = data; + gtk_entry_set_text (entry, ""); +} + + +static void +on_entry_change (GtkEntry *entry, PsppireAcr *acr) +{ + gtk_widget_set_sensitive (acr->add_button, acr->enabled (entry)); + + gtk_widget_set_sensitive (acr->change_button, acr->enabled (entry) + && row_is_selected (acr)); +} + +void +psppire_acr_set_entry (PsppireAcr *acr, GtkEntry *entry) +{ + acr->get_value = value_from_entry; + acr->get_value_data = entry; + acr->enabled = entry_not_empty; + acr->enabled_data = entry; + acr->update = clear_entry; + acr->update_data = entry; + + g_signal_connect (entry, "changed", G_CALLBACK (on_entry_change), acr); +} - const gchar *text = gtk_entry_get_text (acr->entry); - x = g_strtod (text, 0); +/* Callback for when the Add button is clicked. + It appends an item to the list. */ +static void +on_add_button_clicked (PsppireAcr *acr) +{ + gint i; + GtkTreeIter iter; gtk_list_store_append (acr->list_store, &iter); - gtk_list_store_set (acr->list_store, &iter, - COLUMN_DOUBLE, x, - -1); + for (i = 0 ; + i < gtk_tree_model_get_n_columns (GTK_TREE_MODEL (acr->list_store)); + ++i) + { + static GValue value; + if (! acr->get_value (i, &value, acr->get_value_data)) + continue; + + gtk_list_store_set_value (acr->list_store, &iter, + i, &value); + g_value_unset (&value); + } - gtk_entry_set_text (acr->entry, ""); + if (acr->update) acr->update (acr->update_data); } + +/* Callback for when the Changed button is clicked. + It replaces the currently selected entry. */ static void on_change_button_clicked (PsppireAcr *acr) { - const gchar *text; - GValue value = {0}; + gint i; GtkTreeModel *model = GTK_TREE_MODEL (acr->list_store); GList *l= @@ -88,16 +170,28 @@ on_change_button_clicked (PsppireAcr *acr) gtk_tree_model_get_iter (model, &iter, path); - text = gtk_entry_get_text (acr->entry); + for (i = 0 ; + i < gtk_tree_model_get_n_columns (GTK_TREE_MODEL (acr->list_store)); + ++i) + { + static GValue value; + if (! acr->get_value (i, &value, acr->get_value_data)) + continue; - g_value_init (&value, G_TYPE_DOUBLE); - g_value_set_double (&value, g_strtod (text, NULL)); - gtk_list_store_set_value (acr->list_store, &iter, 0, &value); + gtk_list_store_set_value (acr->list_store, &iter, + i, &value); + g_value_unset (&value); + } - g_list_foreach (l, (GFunc) gtk_tree_path_free, NULL); + g_list_foreach (l, (GFunc) (void (*)(void)) gtk_tree_path_free, NULL); g_list_free (l); + + if (acr->update) acr->update (acr->update_data); } + +/* Callback for when the remove button is clicked. + It deletes the currently selected entry. */ static void on_remove_button_clicked (PsppireAcr *acr) { @@ -115,19 +209,14 @@ on_remove_button_clicked (PsppireAcr *acr) gtk_list_store_remove (acr->list_store, &iter); - g_list_foreach (l, (GFunc) gtk_tree_path_free, NULL); + g_list_foreach (l, (GFunc) (void (*)(void)) gtk_tree_path_free, NULL); g_list_free (l); } +/* Returns true if there is a row currently selected. + False otherwise. */ static gboolean -value_present (const PsppireAcr *acr) -{ - const char *text = gtk_entry_get_text (acr->entry); - return !g_str_equal (text, ""); -} - -static gboolean -row_is_selected (PsppireAcr *acr) +row_is_selected (const PsppireAcr *acr) { gboolean result; GtkTreeModel *model = GTK_TREE_MODEL (acr->list_store); @@ -136,13 +225,15 @@ row_is_selected (PsppireAcr *acr) result = (l != NULL); - g_list_foreach (l, (GFunc) gtk_tree_path_free, NULL); + g_list_foreach (l, (GFunc) (void (*)(void)) gtk_tree_path_free, NULL); g_list_free (l); return result; } +/* Callback which occurs when an item in the treeview + is selected */ static void on_select (GtkTreeSelection *selection, gpointer data) { @@ -151,31 +242,50 @@ on_select (GtkTreeSelection *selection, gpointer data) gtk_widget_set_sensitive (acr->remove_button, row_is_selected (acr)); gtk_widget_set_sensitive (acr->change_button, - row_is_selected (acr) && value_present (acr)); + row_is_selected (acr) + ); } +void +psppire_acr_set_enabled (PsppireAcr *acr, gboolean status) +{ + + gtk_widget_set_sensitive (acr->add_button, status); + + gtk_widget_set_sensitive (acr->change_button, status + && row_is_selected (acr)); +} static void psppire_acr_init (PsppireAcr *acr) { - GtkWidget *bb = gtk_vbutton_box_new (); + GtkWidget *bb = gtk_button_box_new (GTK_ORIENTATION_VERTICAL); GtkWidget *sw = gtk_scrolled_window_new (NULL, NULL); + acr->dispose_has_run = FALSE; + + gtk_orientable_set_orientation (GTK_ORIENTABLE (acr), GTK_ORIENTATION_HORIZONTAL); + acr->tv = GTK_TREE_VIEW (gtk_tree_view_new ()); - acr->add_button = gtk_button_new_from_stock (GTK_STOCK_ADD); - acr->change_button = gtk_button_new_from_stock (GTK_STOCK_EDIT); - acr->remove_button = gtk_button_new_from_stock (GTK_STOCK_REMOVE); + acr->add_button = gtk_button_new_with_label (_("Add")); + acr->change_button = gtk_button_new_with_label (_("Edit")); + acr->remove_button = gtk_button_new_with_label (_("Remove")); + + acr->get_value = NULL; + acr->get_value_data = NULL; + acr->enabled = NULL; + acr->update = NULL; gtk_widget_set_sensitive (acr->change_button, FALSE); gtk_widget_set_sensitive (acr->remove_button, FALSE); gtk_widget_set_sensitive (acr->add_button, FALSE); - gtk_box_pack_start_defaults (GTK_BOX (bb), acr->add_button); - gtk_box_pack_start_defaults (GTK_BOX (bb), acr->change_button); - gtk_box_pack_start_defaults (GTK_BOX (bb), acr->remove_button); + psppire_box_pack_start_defaults (GTK_BOX (bb), acr->add_button); + psppire_box_pack_start_defaults (GTK_BOX (bb), acr->change_button); + psppire_box_pack_start_defaults (GTK_BOX (bb), acr->remove_button); gtk_box_pack_start (GTK_BOX (acr), bb, FALSE, TRUE, 5); @@ -215,19 +325,16 @@ psppire_acr_init (PsppireAcr *acr) gtk_widget_show_all (sw); { - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("header", - renderer, - "text", COLUMN_DOUBLE, - NULL); + GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); + GtkTreeViewColumn *column = + gtk_tree_view_column_new_with_attributes ("value", + renderer, + "text", 0, + NULL); gtk_tree_view_append_column (acr->tv, column); } - acr->entry = NULL; } @@ -237,29 +344,18 @@ psppire_acr_new (void) return GTK_WIDGET (g_object_new (psppire_acr_get_type (), NULL)); } -static void -on_entry_change (GtkEntry *entry, PsppireAcr *acr) -{ - gtk_widget_set_sensitive (acr->add_button, value_present (acr)); - - gtk_widget_set_sensitive (acr->change_button, value_present (acr) - && row_is_selected (acr)); -} - -void -psppire_acr_set_entry (PsppireAcr *acr, GtkEntry *entry) -{ - acr->entry = entry; - - g_signal_connect (entry, "changed", G_CALLBACK (on_entry_change), acr); -} - -/* Set the widget's treemodel */ +/* Set the widget's treemodel to LISTSTORE. LISTSTORE ownership is not + transferred. */ void psppire_acr_set_model (PsppireAcr *acr, GtkListStore *liststore) { + if (acr->list_store) + g_object_unref (acr->list_store); + if (liststore) + g_object_ref (liststore); + acr->list_store = liststore; gtk_tree_view_set_model (GTK_TREE_VIEW (acr->tv), @@ -267,3 +363,19 @@ psppire_acr_set_model (PsppireAcr *acr, GtkListStore *liststore) gtk_widget_set_sensitive (GTK_WIDGET (acr), liststore != NULL); } + + +void +psppire_acr_set_enable_func (PsppireAcr *acr, EnabledFunc func, gpointer p) +{ + acr->enabled = func; + acr->enabled_data = p; +} + +void +psppire_acr_set_get_value_func (PsppireAcr *acr, + GetValueFunc getvalue, gpointer data) +{ + acr->get_value_data = data; + acr->get_value = getvalue; +}