Means Dialog: Fix issue where the wrong syntax was generated. 20140220030511/pspp
authorJohn Darrington <john@darrington.wattle.id.au>
Thu, 6 Feb 2014 20:50:11 +0000 (21:50 +0100)
committerJohn Darrington <john@darrington.wattle.id.au>
Wed, 19 Feb 2014 17:17:50 +0000 (18:17 +0100)
Addresses Bug #41433

NEWS
src/ui/gui/dict-display.c
src/ui/gui/dict-display.h
src/ui/gui/means.ui
src/ui/gui/psppire-dialog-action-means.c
src/ui/gui/psppire-means-layer.c
src/ui/gui/psppire-means-layer.h
src/ui/gui/psppire-selector.c
src/ui/gui/psppire.c

diff --git a/NEWS b/NEWS
index 51dc42cd1c5d82a390429e3d59fe73d3bda49bc5..6949019e585c26e5b0d736e4cf23d77a316e15e0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,8 @@ Changes since 0.8.2:
    - File|Display Data File Information|External File... now allows an
      encoding to be selected.
 
+   - A problem with the Means dialog has been resolved (bug #41433).
+
  * System file related improvements:
 
    - With ENCODING="DETECT", SYSFILE INFO can now help the user to
index 77da88bd98826c9791151af09edccc4de1d9b186..cb46ad5716eaf7bd2d6c2a90f243ba799332e2ef 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "psppire-dict.h"
 #include "psppire-dictview.h"
+#include "psppire-means-layer.h"
 #include "psppire-var-ptr.h"
 #include "psppire-var-view.h"
 #include "psppire-select-dest.h"
@@ -87,23 +88,22 @@ insert_source_row_into_entry (GtkTreeIter iter,
 }
 
 
-void
-insert_source_row_into_tree_view (GtkTreeIter iter,
-                                 GtkWidget *dest,
-                                 GtkTreeModel *model,
-                                 gpointer data
-                                 )
+
+static void
+insert_source_row_into_tree_model (GtkTreeIter source_iter,
+                                    GtkTreeModel *dest_model,
+                                    GtkTreeModel *source_model,
+                                    gpointer data)
 {
   GtkTreePath *path;
   GtkTreeIter dest_iter;
   GtkTreeIter dict_iter;
   gint *row ;
-  GtkTreeModel *destmodel = gtk_tree_view_get_model (GTK_TREE_VIEW (dest));
 
   const struct variable *var;
   GtkTreeModel *dict;
 
-  get_base_model (model, &iter, &dict, &dict_iter);
+  get_base_model (source_model, &source_iter, &dict, &dict_iter);
 
   path = gtk_tree_model_get_path (dict, &dict_iter);
 
@@ -111,15 +111,43 @@ insert_source_row_into_tree_view (GtkTreeIter iter,
 
   var = psppire_dict_get_variable (PSPPIRE_DICT (dict), *row);
 
-  gtk_list_store_append (GTK_LIST_STORE (destmodel),  &dest_iter);
+  gtk_list_store_append (GTK_LIST_STORE (dest_model),  &dest_iter);
 
-  gtk_list_store_set (GTK_LIST_STORE (destmodel), &dest_iter, 0, var, -1);
+  gtk_list_store_set (GTK_LIST_STORE (dest_model), &dest_iter, 0, var, -1);
 
   gtk_tree_path_free (path);
 }
 
 
 
+void
+insert_source_row_into_tree_view (GtkTreeIter iter,
+                                 GtkWidget *dest,
+                                 GtkTreeModel *model,
+                                 gpointer data)
+{
+  GtkTreeModel *destmodel = gtk_tree_view_get_model (GTK_TREE_VIEW (dest));
+
+  insert_source_row_into_tree_model (iter, destmodel, model, data);
+}
+
+
+void
+insert_source_row_into_layers (GtkTreeIter iter,
+                              GtkWidget *dest,
+                              GtkTreeModel *model,
+                              gpointer data)
+{
+  GtkTreeModel *destmodel = psppire_means_layer_get_model (PSPPIRE_MEANS_LAYER (dest));
+
+  insert_source_row_into_tree_model (iter, destmodel, model, data);
+
+  psppire_means_layer_update (PSPPIRE_MEANS_LAYER (dest));
+}
+
+
+
+
 gboolean
 is_currently_in_entry (GtkTreeModel *model, GtkTreeIter *iter,
                       PsppireSelector *selector)
index b3b395bb81a0d33fadcb5d410b2232e1f9157a93..6a086b7ada39306c9a324ea983a092510eda2ce3 100644 (file)
 void insert_source_row_into_tree_view (GtkTreeIter source_iter,
                                       GtkWidget *dest,
                                       GtkTreeModel *source_model,
-                                      gpointer data
-                                      );
+                                      gpointer data);
+
+
+/* A SelectItemsFunc function for PsppireMeansLayers widgets */
+void insert_source_row_into_layers (GtkTreeIter source_iter,
+                                   GtkWidget *dest,
+                                   GtkTreeModel *source_model,
+                                   gpointer data);
+
 
 /* A SelectItemsFunc function for GtkEntry widgets */
 void insert_source_row_into_entry (GtkTreeIter source_iter,
index f0c2138f2c0cc26f05aaaefd37ed05b489eb8e4c..a650a6bba93f1a8b02f454c1836e252b022bc7dd 100644 (file)
@@ -1,7 +1,7 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="psppire" version="2054.17080"/>
   <!-- interface-requires gtk+ 2.12 -->
+  <requires lib="psppire" version="2054.17080"/>
   <!-- interface-naming-policy project-wide -->
   <object class="PsppireDialog" id="means-dialog">
     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
-                <child>
-                  <object class="GtkAlignment" id="alignment19">
-                    <property name="visible">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="yalign">0.25</property>
-                    <property name="xscale">0</property>
-                    <property name="yscale">0</property>
-                    <child>
-                      <object class="PsppireSelector" id="stat-var-selector">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="border_width">5</property>
-                        <property name="source_widget">all-variables</property>
-                        <property name="dest_widget">stat-variables</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
                 <child>
                   <object class="GtkVPaned" id="vpaned1">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="orientation">vertical</property>
                     <child>
-                      <object class="GtkFrame" id="frame1">
+                      <object class="GtkHBox" id="hbox1">
                         <property name="visible">True</property>
-                        <property name="label_xalign">0</property>
-                        <property name="shadow_type">none</property>
                         <child>
-                          <object class="GtkAlignment" id="alignment2">
+                          <object class="GtkAlignment" id="alignment19">
                             <property name="visible">True</property>
-                            <property name="left_padding">12</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="yalign">0.25</property>
+                            <property name="xscale">0</property>
+                            <property name="yscale">0</property>
                             <child>
-                              <object class="GtkScrolledWindow" id="scrolledwindow17">
+                              <object class="PsppireSelector" id="stat-var-selector">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="hscrollbar_policy">never</property>
-                                <property name="vscrollbar_policy">automatic</property>
-                                <property name="shadow_type">etched-in</property>
+                                <property name="border_width">5</property>
+                                <property name="source_widget">all-variables</property>
+                                <property name="dest_widget">stat-variables</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkFrame" id="frame1">
+                            <property name="visible">True</property>
+                            <property name="label_xalign">0</property>
+                            <property name="shadow_type">none</property>
+                            <child>
+                              <object class="GtkAlignment" id="alignment2">
+                                <property name="visible">True</property>
+                                <property name="left_padding">12</property>
                                 <child>
-                                  <object class="PsppireVarView" id="stat-variables">
+                                  <object class="GtkScrolledWindow" id="scrolledwindow17">
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
                                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                    <property name="headers_visible">False</property>
-                                    <property name="headers_clickable">False</property>
+                                    <property name="hscrollbar_policy">never</property>
+                                    <property name="vscrollbar_policy">automatic</property>
+                                    <property name="shadow_type">etched-in</property>
+                                    <child>
+                                      <object class="PsppireVarView" id="stat-variables">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                        <property name="headers_visible">False</property>
+                                        <property name="headers_clickable">False</property>
+                                      </object>
+                                    </child>
                                   </object>
                                 </child>
                               </object>
                             </child>
+                            <child type="label">
+                              <object class="GtkLabel" id="label1">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">_Dependent List:</property>
+                                <property name="use_markup">True</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">stat-variables</property>
+                              </object>
+                            </child>
                           </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel" id="label1">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">_Dependent List:</property>
-                            <property name="use_markup">True</property>
-                            <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">stat-variables</property>
-                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
                         </child>
                       </object>
                       <packing>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkFrame" id="frame2">
+                      <object class="GtkHBox" id="hbox2">
                         <property name="visible">True</property>
-                        <property name="label_xalign">0</property>
-                        <property name="shadow_type">none</property>
                         <child>
-                          <object class="GtkAlignment" id="alignment3">
+                          <object class="GtkAlignment" id="alignment4">
                             <property name="visible">True</property>
-                            <property name="left_padding">12</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="yalign">0.25</property>
+                            <property name="xscale">0</property>
+                            <property name="yscale">0</property>
                             <child>
-                              <placeholder/>
+                              <object class="PsppireSelector" id="layer-selector">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="border_width">5</property>
+                                <property name="source_widget">all-variables</property>
+                              </object>
                             </child>
                           </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
                         </child>
-                        <child type="label">
-                          <object class="GtkLabel" id="label2">
+                        <child>
+                          <object class="GtkFrame" id="frame2">
                             <property name="visible">True</property>
-                            <property name="label" translatable="yes">_Independent List:</property>
-                            <property name="use_underline">True</property>
+                            <property name="label_xalign">0</property>
+                            <property name="shadow_type">none</property>
+                            <child>
+                              <object class="GtkAlignment" id="alignment3">
+                                <property name="visible">True</property>
+                                <property name="left_padding">12</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                              </object>
+                            </child>
+                            <child type="label">
+                              <object class="GtkLabel" id="label2">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">_Independent List:</property>
+                                <property name="use_underline">True</property>
+                              </object>
+                            </child>
                           </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
                         </child>
                       </object>
                       <packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="position">2</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
               </object>
index 81e9bb905216d1f414840d7b365b7ff118def8cf..807d3fc38b9c6c9709c04884b4e279eebbfa0527 100644 (file)
@@ -100,6 +100,8 @@ psppire_dialog_action_means_activate (GtkAction *a)
   GtkBuilder *xml = builder_new ("means.ui");
 
   GtkWidget *vb =   get_widget_assert   (xml, "alignment3");
+  GtkWidget *selector = get_widget_assert   (xml, "layer-selector");
+  
   act->layer = psppire_means_layer_new ();
   gtk_container_add (GTK_CONTAINER (vb), act->layer);
   gtk_widget_show (act->layer);
@@ -112,7 +114,10 @@ psppire_dialog_action_means_activate (GtkAction *a)
                "predicate", var_is_numeric,
                NULL);
 
-  psppire_means_layer_set_source (PSPPIRE_MEANS_LAYER (act->layer), pda->source);
+  g_object_set (selector,
+               "dest-widget", act->layer,
+               NULL);
+
 
   psppire_dialog_action_set_valid_predicate (pda, (void *) dialog_state_valid);
   psppire_dialog_action_set_refresh (pda, dialog_refresh);
index a9b1139f18c6be631c82e73996c0baa0ffbdb747..8046b00765e2a42d6371fa1a96f71bf462c80820 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2012  Free Software Foundation
+   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
@@ -17,7 +17,6 @@
 #include <config.h>
 
 #include "psppire-means-layer.h"
-#include "psppire-selector.h"
 #include "psppire-var-view.h"
 
 #include <gtk/gtk.h>
@@ -62,8 +61,31 @@ psppire_means_layer_class_init    (PsppireMeansLayerClass *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
-update (PsppireMeansLayer *ml)
+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;
 
@@ -77,29 +99,34 @@ update (PsppireMeansLayer *ml)
   g_free (l);
 
   gtk_widget_set_sensitive (ml->back, ml->current_layer > 0);
-  gtk_widget_set_sensitive (ml->forward,
-                           psppire_var_view_get_iter_first (PSPPIRE_VAR_VIEW (ml->var_view),
-                                                            NULL));
+
+  {
+    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)
 {
-  ml->current_layer++;
-  if (ml->current_layer >= ml->n_layers)
+  if (ml->current_layer + 1 >= ml->n_layers)
     {
-      GtkTreeModel *tm;
       psppire_var_view_clear (PSPPIRE_VAR_VIEW (ml->var_view));
-      tm = gtk_tree_view_get_model (GTK_TREE_VIEW (ml->var_view));
-      g_ptr_array_add (ml->layer, tm);
-      g_object_ref (tm);
-      ml->n_layers = ml->current_layer + 1;      
+      add_new_layer (ml);
+      ml->n_layers = ml->current_layer + 2;
     }
   else
     {
-      GtkTreeModel *tm = g_ptr_array_index (ml->layer, ml->current_layer);
+      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
@@ -111,8 +138,23 @@ on_back (PsppireMeansLayer *ml)
 
   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)
@@ -126,7 +168,6 @@ psppire_means_layer_init  (PsppireMeansLayer      *ml)
   ml->forward = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
   ml->back = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
   ml->var_view = psppire_var_view_new ();
-  ml->selector = psppire_selector_new ();
   ml->label = gtk_label_new ("");
 
   g_signal_connect_swapped (ml->forward, "clicked", G_CALLBACK (on_forward),
@@ -134,9 +175,6 @@ psppire_means_layer_init  (PsppireMeansLayer      *ml)
 
   g_signal_connect_swapped (ml->back, "clicked", G_CALLBACK (on_back), ml);
 
-  g_signal_connect_swapped (ml->selector, "selected", G_CALLBACK (update), ml);
-  g_signal_connect_swapped (ml->selector, "de-selected", G_CALLBACK (update),
-                           ml);
 
   g_object_set (ml->var_view, "headers-visible", FALSE, NULL);
   g_object_set (sw,
@@ -144,32 +182,20 @@ psppire_means_layer_init  (PsppireMeansLayer      *ml)
                "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
                NULL);
 
-  g_object_set (ml->selector, "dest-widget", ml->var_view, NULL);
-  g_signal_connect_swapped (ml->var_view, "notify::model", G_CALLBACK (update), ml);
+  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), alignment, FALSE, FALSE, 5);
-  gtk_container_add (GTK_CONTAINER (alignment), ml->selector);
   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);
 
-
-
-  ml->n_layers = 1;
-  ml->current_layer = 0;
-  ml->layer = g_ptr_array_new_full (3, g_object_unref);
-
-  /* Add a model and take a reference to it */
-  g_ptr_array_add (ml->layer, gtk_tree_view_get_model (GTK_TREE_VIEW (ml->var_view)));
-  g_object_ref (g_ptr_array_index (ml->layer, ml->current_layer));
-
-  update (ml);
+  psppire_means_layer_clear (ml);
 
   gtk_widget_show_all (hbox_upper);
   gtk_widget_show_all (hbox_lower);
@@ -182,24 +208,18 @@ psppire_means_layer_new (void)
 }
 
 
-void
-psppire_means_layer_set_source (PsppireMeansLayer *ml, GtkWidget *w)
-{
-  g_object_set (ml->selector, "source-widget", w, NULL);
-}
 
 
-void
-psppire_means_layer_clear (PsppireMeansLayer *ml)
+GtkTreeModel *
+psppire_means_layer_get_model_n (PsppireMeansLayer *ml, gint n)
 {
-  ml->n_layers = 1;
-  ml->current_layer = 0;
-  psppire_var_view_clear (PSPPIRE_VAR_VIEW (ml->var_view));
+  return g_ptr_array_index (ml->layer, n);
 }
 
 
 GtkTreeModel *
-psppire_means_layer_get_model_n (PsppireMeansLayer *ml, gint n)
+psppire_means_layer_get_model (PsppireMeansLayer *ml)
 {
-  return g_ptr_array_index (ml->layer, n);
+  return g_ptr_array_index (ml->layer, ml->current_layer);
 }
+
index 7cd0f7b17f5abe4e23fd2c827fb08c5d870fc287..ecf019d80d67cc461a24f9f620c11b828d2a2c74 100644 (file)
@@ -64,7 +64,6 @@ struct _PsppireMeansLayer
   GtkWidget *label;
   GtkWidget *back;
   GtkWidget *forward;
-  GtkWidget *selector;
 };
 
 
@@ -77,11 +76,11 @@ GType      psppire_means_layer_get_type        (void);
 GType      psppire_means_layer_model_get_type        (void);
 GtkWidget * psppire_means_layer_new (void);
 
-void       psppire_means_layer_set_source (PsppireMeansLayer *ml, GtkWidget *w);
-
 void       psppire_means_layer_clear (PsppireMeansLayer *ml);
 GtkTreeModel *psppire_means_layer_get_model_n (PsppireMeansLayer *ml, gint n);
+GtkTreeModel *psppire_means_layer_get_model (PsppireMeansLayer *ml);
 
+void psppire_means_layer_update (PsppireMeansLayer *ml);
 
 G_END_DECLS
 
index 82e21399768a05548cef4fc7b59e25fa4acf8ae3..17e173b5a59117d17ff7e7021aff66a0f7d62f93 100644 (file)
@@ -59,9 +59,9 @@
 #include <config.h>
 
 #include "psppire-dictview.h"
-#include "psppire-var-view.h"
 #include "psppire-dict.h"
 #include "psppire-select-dest.h"
+#include "psppire-means-layer.h"
 
 #include <gtk/gtk.h>
 
@@ -530,6 +530,7 @@ on_dest_treeview_select (GtkTreeSelection *treeselection, gpointer data)
   set_direction (selector, PSPPIRE_SELECTOR_DEST_TO_SOURCE);
 }
 
+
 /* Callback for source deselection, when the dest is GtkEntry */
 static void
 de_select_selection_entry (PsppireSelector *selector)
@@ -537,23 +538,47 @@ de_select_selection_entry (PsppireSelector *selector)
   gtk_entry_set_text (GTK_ENTRY (selector->dest), "");
 }
 
+
+static void  de_select_tree_model (GtkTreeSelection *selection, GtkTreeModel *model);
+
+/* Callback for source deselection, when the dest is PsppireMeansLayer */
+static void
+de_select_selection_means_layer (PsppireSelector *selector)
+{
+  PsppireMeansLayer *ml = PSPPIRE_MEANS_LAYER (selector->dest);
+  GtkTreeView *tv = GTK_TREE_VIEW (ml->var_view);
+  GtkTreeSelection *selection = gtk_tree_view_get_selection (tv);
+
+  GtkTreeModel *model = psppire_means_layer_get_model (ml);
+
+  g_return_if_fail (selector->select_items);
+
+  de_select_tree_model (selection, model);
+}
+
 /* Callback for source deselection, when the dest is GtkTreeView */
 static void
 de_select_selection_tree_view (PsppireSelector *selector)
 {
-  GList *item;
-
   GtkTreeSelection* selection =
     gtk_tree_view_get_selection ( GTK_TREE_VIEW (selector->dest));
 
   GtkTreeModel *model =
     gtk_tree_view_get_model (GTK_TREE_VIEW (selector->dest));
 
+  g_return_if_fail (selector->select_items);
+
+  de_select_tree_model (selection, model);
+}
+
+static void 
+de_select_tree_model (GtkTreeSelection *selection, GtkTreeModel *model)
+{
+  GList *item;
+
   GList *selected_rows =
     gtk_tree_selection_get_selected_rows (selection, NULL);
 
-  g_return_if_fail (selector->select_items);
-
   /* Convert paths to RowRefs */
   for (item = g_list_first (selected_rows);
        item != NULL;
@@ -616,6 +641,9 @@ de_select_selection (PsppireSelector *selector)
   else if ( GTK_IS_ENTRY (selector->dest))
     de_select_selection_entry (selector);
 
+  else if ( PSPPIRE_IS_MEANS_LAYER (selector->dest))
+    de_select_selection_means_layer (selector);
+
   else
     g_assert_not_reached ();
 
@@ -928,7 +956,18 @@ set_tree_view_dest (PsppireSelector *selector,
                            G_CALLBACK (on_dest_model_changed), selector);
 }
 
+static void
+set_layer_dest (PsppireSelector *selector,
+                   PsppireMeansLayer *dest)
+{
+  GtkTreeSelection* selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dest->var_view));
 
+  gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+
+
+  g_signal_connect (selection, "changed", G_CALLBACK (on_dest_treeview_select),
+                   selector);
+}
 
 
 /* Callback for when the DEST GtkEntry is selected (clicked) */
@@ -1005,10 +1044,14 @@ update_subjects (PsppireSelector *selector)
     {
       set_tree_view_dest (selector, GTK_TREE_VIEW (selector->dest));
     }
-
   else if ( GTK_IS_ENTRY (selector->dest))
-    set_entry_dest (selector, GTK_ENTRY (selector->dest));
-
+    {
+      set_entry_dest (selector, GTK_ENTRY (selector->dest));
+    }
+  else if (PSPPIRE_IS_MEANS_LAYER (selector->dest))
+    {
+      set_layer_dest (selector, PSPPIRE_MEANS_LAYER (selector->dest));
+    }
   else if (GTK_IS_TEXT_VIEW (selector->dest))
     {
       /* Nothing to be done */
@@ -1078,15 +1121,17 @@ GType
 psppire_selector_orientation_get_type (void)
 {
   static GType etype = 0;
-  if (etype == 0) {
-    static const GEnumValue values[] = {
-      { PSPPIRE_SELECT_SOURCE_BEFORE_DEST, "PSPPIRE_SELECT_SOURCE_BEFORE_DEST", "source before destination" },
-      { PSPPIRE_SELECT_SOURCE_AFTER_DEST, "PSPPIRE_SELECT_SOURCE_AFTER_DEST", "source after destination" },
-      { PSPPIRE_SELECT_SOURCE_ABOVE_DEST, "PSPPIRE_SELECT_SOURCE_ABOVE_DEST", "source above destination" },
-      { PSPPIRE_SELECT_SOURCE_BELOW_DEST, "PSPPIRE_SELECT_SOURCE_BELOW_DEST", "source below destination" },
-      { 0, NULL, NULL }
-    };
-    etype = g_enum_register_static (g_intern_static_string ("PsppireSelectorOrientation"), values);
-  }
+  if (etype == 0)
+    {
+      static const GEnumValue values[] =
+       {
+         { PSPPIRE_SELECT_SOURCE_BEFORE_DEST, "PSPPIRE_SELECT_SOURCE_BEFORE_DEST", "source before destination" },
+         { PSPPIRE_SELECT_SOURCE_AFTER_DEST, "PSPPIRE_SELECT_SOURCE_AFTER_DEST", "source after destination" },
+         { PSPPIRE_SELECT_SOURCE_ABOVE_DEST, "PSPPIRE_SELECT_SOURCE_ABOVE_DEST", "source above destination" },
+         { PSPPIRE_SELECT_SOURCE_BELOW_DEST, "PSPPIRE_SELECT_SOURCE_BELOW_DEST", "source below destination" },
+         { 0, NULL, NULL }
+       };
+      etype = g_enum_register_static (g_intern_static_string ("PsppireSelectorOrientation"), values);
+    }
   return etype;
 }
index a3f6a2aff67d9ebebafd0261c2d08ffb8968b96d..93f3f99f7b4ca40941549ce248950472fc05fcbf 100644 (file)
@@ -53,6 +53,7 @@
 #include "ui/gui/psppire-syntax-window.h"
 #include "ui/gui/psppire-selector.h"
 #include "ui/gui/psppire-var-view.h"
+#include "ui/gui/psppire-means-layer.h"
 #include "ui/gui/psppire-window-register.h"
 #include "ui/gui/widgets.h"
 #include "ui/source-init-opts.h"
@@ -95,9 +96,11 @@ initialize (const char *data_file)
   journal_init ();
   textdomain (PACKAGE);
 
+  /* FIXME: This should be implemented with a GtkInterface */
   psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
   psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
   psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
+  psppire_selector_set_default_selection_func (PSPPIRE_TYPE_MEANS_LAYER, insert_source_row_into_layers);
 
   if (data_file)
     {