/* PSPPIRE - a graphical user interface for PSPP. Copyright (C) 2012, 2014 Free Software Foundation 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 3 of the License, 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, see . */ #include #include "psppire-means-layer.h" #include "psppire-var-view.h" #include #include "gettext.h" #define _(msgid) gettext (msgid) #define N_(msgid) msgid static void psppire_means_layer_class_init (PsppireMeansLayerClass *class); static void psppire_means_layer_init (PsppireMeansLayer *window); G_DEFINE_TYPE (PsppireMeansLayer, psppire_means_layer, GTK_TYPE_BOX); static GObjectClass *parent_class = NULL; static void psppire_means_layer_dispose (GObject *obj) { PsppireMeansLayer *w = PSPPIRE_MEANS_LAYER (obj); if (w->dispose_has_run) return; /* Make sure dispose does not run twice. */ w->dispose_has_run = TRUE; g_ptr_array_unref (w->layer); /* Chain up to the parent class */ G_OBJECT_CLASS (parent_class)->dispose (obj); } static void psppire_means_layer_class_init (PsppireMeansLayerClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); parent_class = g_type_class_peek_parent (class); object_class->dispose = psppire_means_layer_dispose; } static void refresh_view (PsppireMeansLayer *ml) { GtkTreeModel *tm; g_return_if_fail (ml->current_layer >= 0); tm = g_ptr_array_index (ml->layer, ml->current_layer); gtk_tree_view_set_model (GTK_TREE_VIEW (ml->var_view), tm); } static void add_new_layer (PsppireMeansLayer *ml) { /* Add a model and take a reference to it */ GtkTreeModel *tm = gtk_tree_view_get_model (GTK_TREE_VIEW (ml->var_view)); g_ptr_array_add (ml->layer, tm); g_signal_connect_swapped (tm, "row-inserted", G_CALLBACK (refresh_view), ml); g_object_ref (tm); } void psppire_means_layer_update (PsppireMeansLayer *ml) { gchar *l; if (!gtk_widget_get_realized (GTK_WIDGET (ml))) return; l = g_strdup_printf (_("Layer %d of %d"), ml->current_layer + 1, ml->n_layers); gtk_label_set_text (GTK_LABEL (ml->label), l); g_free (l); gtk_widget_set_sensitive (ml->back, ml->current_layer > 0); { GtkTreeIter dummy; GtkTreeModel *tm = g_ptr_array_index (ml->layer, ml->current_layer); g_return_if_fail (GTK_IS_TREE_MODEL (tm)); gtk_widget_set_sensitive (ml->forward, gtk_tree_model_get_iter_first (tm, &dummy)); } } static void on_forward (PsppireMeansLayer *ml) { if (ml->current_layer + 1 >= ml->n_layers) { psppire_var_view_clear (PSPPIRE_VAR_VIEW (ml->var_view)); add_new_layer (ml); ml->n_layers = ml->current_layer + 2; } else { GtkTreeModel *tm = g_ptr_array_index (ml->layer, ml->current_layer + 1); gtk_tree_view_set_model (GTK_TREE_VIEW (ml->var_view), tm); } ml->current_layer++; psppire_means_layer_update (ml); } static void on_back (PsppireMeansLayer *ml) { GtkTreeModel *tm; g_return_if_fail (ml->current_layer > 0); ml->current_layer--; tm = g_ptr_array_index (ml->layer, ml->current_layer); gtk_tree_view_set_model (GTK_TREE_VIEW (ml->var_view), tm); psppire_means_layer_update (ml); } void psppire_means_layer_clear (PsppireMeansLayer *ml) { psppire_var_view_clear (PSPPIRE_VAR_VIEW (ml->var_view)); ml->n_layers = 1; ml->current_layer = 0; ml->layer = g_ptr_array_new_full (3, g_object_unref); add_new_layer (ml); psppire_means_layer_update (ml); } static void psppire_means_layer_init (PsppireMeansLayer *ml) { GtkWidget *hbox_upper = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5); GtkWidget *hbox_lower = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5); GtkWidget *sw = gtk_scrolled_window_new (NULL, NULL); gtk_orientable_set_orientation (GTK_ORIENTABLE (ml), GTK_ORIENTATION_VERTICAL); ml->dispose_has_run = FALSE; ml->forward = gtk_button_new_with_label (_("Forward")); ml->back = gtk_button_new_with_label (_("Back")); ml->var_view = psppire_var_view_new (); ml->label = gtk_label_new (""); g_signal_connect_swapped (ml->forward, "clicked", G_CALLBACK (on_forward), ml); g_signal_connect_swapped (ml->back, "clicked", G_CALLBACK (on_back), ml); g_object_set (ml->var_view, "headers-visible", FALSE, NULL); g_object_set (sw, "shadow-type", GTK_SHADOW_ETCHED_IN, "hscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL); g_signal_connect_swapped (ml->var_view, "notify::model", G_CALLBACK (psppire_means_layer_update), ml); gtk_box_pack_start (GTK_BOX (hbox_upper), ml->back, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (hbox_upper), ml->label, TRUE, FALSE, 5); gtk_box_pack_start (GTK_BOX (hbox_upper), ml->forward, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (hbox_lower), sw, TRUE, TRUE, 5); gtk_container_add (GTK_CONTAINER (sw), ml->var_view); gtk_box_pack_start (GTK_BOX (ml), hbox_upper, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (ml), hbox_lower, TRUE, TRUE, 5); psppire_means_layer_clear (ml); gtk_widget_show_all (hbox_upper); gtk_widget_show_all (hbox_lower); } GtkWidget * psppire_means_layer_new (void) { return GTK_WIDGET (g_object_new (psppire_means_layer_get_type (), NULL)); } GtkTreeModel * psppire_means_layer_get_model_n (PsppireMeansLayer *ml, gint n) { return g_ptr_array_index (ml->layer, n); } GtkTreeModel * psppire_means_layer_get_model (PsppireMeansLayer *ml) { return g_ptr_array_index (ml->layer, ml->current_layer); }