? Syntax1.sps
? callbacks.patch
? cb.patch
? libtool
? pspp.list
? vg.5331
? src/ui/gui/.libs
? src/ui/gui/libpsppire.la
? src/ui/gui/src_ui_gui_libpsppire_la-glade-register.lo
Index: src/data/ChangeLog
===================================================================
RCS file: /sources/pspp/pspp/src/data/ChangeLog,v
retrieving revision 1.96
diff -b -w -U3 -r1.96 ChangeLog
--- src/data/ChangeLog	3 Jan 2007 02:03:18 -0000	1.96
+++ src/data/ChangeLog	6 Jan 2007 23:38:47 -0000
@@ -1,7 +1,17 @@
+Sun Jan  7 08:33:04 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+	* dictionary.c dictionary.h : Added callbacks for change of filter and 
+	split variables.  Refactored some code to ensure that callbacks get
+	invoked when appropriate.
+
+	* procedure.c (proc_cancel_temporary_transformations): Make sure that 
+	replace_dict callback occurs when permanent_dict replaces the current
+	dictionary.
+
 Wed Jan  3 11:02:11 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
-	* dictionary.c dictionary.h : Added callback for when the weight variable
-	of a dictionary changes.
+	* dictionary.c dictionary.h : Added callback for when the weight 
+	variable of a dictionary changes.
 
 Mon Jan  1 10:36:26 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
Index: src/data/dictionary.c
===================================================================
RCS file: /sources/pspp/pspp/src/data/dictionary.c,v
retrieving revision 1.28
diff -b -w -U3 -r1.28 dictionary.c
--- src/data/dictionary.c	3 Jan 2007 02:03:18 -0000	1.28
+++ src/data/dictionary.c	6 Jan 2007 23:38:48 -0000
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2007 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
@@ -81,7 +81,6 @@
   dict->cb_data = callback_data;
 }
 
-
 /* Shallow copy the callbacks from SRC to DEST */
 void
 dict_copy_callbacks (struct dictionary *dest,
@@ -97,21 +96,8 @@
 {
   struct dictionary *d = xzalloc (sizeof *d);
 
-  d->var = NULL;
-  d->var_cnt = d->var_cap = 0;
   d->name_tab = hsh_create (8, compare_vars_by_name, hash_var_by_name,
                             NULL, NULL);
-  d->next_value_idx = 0;
-  d->split = NULL;
-  d->split_cnt = 0;
-  d->weight = NULL;
-  d->filter = NULL;
-  d->case_limit = 0;
-  d->label = NULL;
-  d->documents = NULL;
-  d->vector = NULL;
-  d->vector_cnt = 0;
-
   return d;
 }
 
@@ -145,10 +131,10 @@
     }
 
   if (s->weight != NULL)
-    d->weight = dict_lookup_var_assert (d, var_get_name (s->weight));
+    dict_set_weight (d, dict_lookup_var_assert (d, var_get_name (s->weight)));
 
   if (s->filter != NULL)
-    d->filter = dict_lookup_var_assert (d, var_get_name (s->filter));
+    dict_set_filter (d, dict_lookup_var_assert (d, var_get_name (s->filter)));
 
   d->case_limit = s->case_limit;
   dict_set_label (d, dict_get_label (s));
@@ -186,11 +172,9 @@
   d->var_cnt = d->var_cap = 0;
   hsh_clear (d->name_tab);
   d->next_value_idx = 0;
-  free (d->split);
-  d->split = NULL;
-  d->split_cnt = 0;
-  d->weight = NULL;
-  d->filter = NULL;
+  dict_set_split_vars (d, NULL, 0);
+  dict_set_weight (d, NULL);
+  dict_set_filter (d, NULL);
   d->case_limit = 0;
   free (d->label);
   d->label = NULL;
@@ -218,6 +202,10 @@
 {
   if (d != NULL)
     {
+      /* In general, we don't want callbacks occuring, if the dictionary
+	 is being destroyed */
+      d->callbacks  = NULL ;
+
       dict_clear (d);
       hsh_destroy (d->name_tab);
       free (d);
@@ -462,13 +450,14 @@
   /* Delete aux data. */
   var_clear_aux (v);
 
-  /* Remove V from splits, weight, filter variables. */
-  d->split_cnt = remove_equal (d->split, d->split_cnt, sizeof *d->split,
-                               &v, compare_var_ptrs, NULL);
+  dict_unset_split_var (d, v);
+
   if (d->weight == v)
-    d->weight = NULL;
+    dict_set_weight (d, NULL);
+
   if (d->filter == v)
-    d->filter = NULL;
+    dict_set_filter (d, NULL);
+
   dict_clear_vectors (d);
 
   /* Remove V from var array. */
@@ -763,6 +752,11 @@
   assert (v == NULL || dict_contains_var (d, v));
 
   d->filter = v;
+
+  if ( d->callbacks && d->callbacks->filter_changed )
+    d->callbacks->filter_changed (d,
+				  v ? var_get_dict_index (v) : -1,
+				  d->cb_data);
 }
 
 /* Returns the case limit for dictionary D, or zero if the number
@@ -1025,6 +1019,18 @@
   return d->split_cnt;
 }
 
+/* Removes variable V from the set of split variables in dictionary D */
+void
+dict_unset_split_var (struct dictionary *d,
+		      struct variable *v)
+{
+  d->split_cnt = remove_equal (d->split, d->split_cnt, sizeof *d->split,
+                               &v, compare_var_ptrs, NULL);
+
+  if ( d->callbacks &&  d->callbacks->split_changed )
+    d->callbacks->split_changed (d, d->cb_data);
+}
+
 /* Sets CNT split vars SPLIT in dictionary D. */
 void
 dict_set_split_vars (struct dictionary *d,
@@ -1036,6 +1042,9 @@
   d->split_cnt = cnt;
   d->split = xnrealloc (d->split, cnt, sizeof *d->split);
   memcpy (d->split, split, cnt * sizeof *d->split);
+
+  if ( d->callbacks &&  d->callbacks->split_changed )
+    d->callbacks->split_changed (d, d->cb_data);
 }
 
 /* Returns the file label for D, or a null pointer if D is
Index: src/data/dictionary.h
===================================================================
RCS file: /sources/pspp/pspp/src/data/dictionary.h,v
retrieving revision 1.10
diff -b -w -U3 -r1.10 dictionary.h
--- src/data/dictionary.h	3 Jan 2007 02:03:18 -0000	1.10
+++ src/data/dictionary.h	6 Jan 2007 23:38:48 -0000
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2007 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
@@ -33,6 +33,8 @@
   void (*var_deleted) (struct dictionary *, int, void *);
   void (*var_changed) (struct dictionary *, int, void *);
   void (*weight_changed) (struct dictionary *, int, void *);
+  void (*filter_changed) (struct dictionary *, int, void *);
+  void (*split_changed) (struct dictionary *, void *);
  };
 
 
@@ -112,6 +114,8 @@
 size_t dict_get_split_cnt (const struct dictionary *);
 void dict_set_split_vars (struct dictionary *,
                           struct variable *const *, size_t cnt);
+void dict_unset_split_var (struct dictionary *d,
+			   struct variable *v);
 
 const char *dict_get_label (const struct dictionary *);
 void dict_set_label (struct dictionary *, const char *);
@@ -134,5 +138,4 @@
 /* Called only from variable.c */
 void dict_var_changed (const struct variable *v);
 
-
 #endif /* dictionary.h */
Index: src/data/procedure.c
===================================================================
RCS file: /sources/pspp/pspp/src/data/procedure.c,v
retrieving revision 1.22
diff -b -w -U3 -r1.22 procedure.c
--- src/data/procedure.c	1 Jan 2007 01:44:33 -0000	1.22
+++ src/data/procedure.c	6 Jan 2007 23:38:48 -0000
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2007 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
@@ -801,6 +801,7 @@
       add_case_limit_trns (ds);
 
       ds->permanent_dict = dict_clone (ds->dict);
+
       trns_chain_finalize (ds->permanent_trns_chain);
       ds->temporary_trns_chain = ds->cur_trns_chain = trns_chain_create ();
     }
@@ -836,13 +837,15 @@
 {
   if (proc_in_temporary_transformations (ds))
     {
-      dict_destroy (ds->dict);
-      ds->dict = ds->permanent_dict;
+      struct dictionary *old_dict = ds->dict;
+
+      dataset_set_dict (ds, ds->permanent_dict);
       ds->permanent_dict = NULL;
 
       trns_chain_destroy (ds->temporary_trns_chain);
       ds->temporary_trns_chain = NULL;
 
+      dict_destroy (old_dict);
       return true;
     }
   else
Index: src/language/xforms/select-if.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/select-if.c,v
retrieving revision 1.14
diff -b -w -U3 -r1.14 select-if.c
--- src/language/xforms/select-if.c	15 Dec 2006 00:16:03 -0000	1.14
+++ src/language/xforms/select-if.c	6 Jan 2007 23:38:48 -0000
@@ -95,12 +95,12 @@
 {
   struct dictionary *dict = dataset_dict (ds);
   if (lex_match_id (lexer, "OFF"))
-    dict_set_filter (dataset_dict (ds), NULL);
+    dict_set_filter (dict, NULL);
   else if (lex_token (lexer) == '.') 
     {
       msg (SW, _("Syntax error expecting OFF or BY.  "
                  "Turning off case filtering."));
-      dict_set_filter (dataset_dict (ds), NULL);
+      dict_set_filter (dict, NULL);
     }
   else
     {
Index: src/ui/gui/ChangeLog
===================================================================
RCS file: /sources/pspp/pspp/src/ui/gui/ChangeLog,v
retrieving revision 1.34
diff -b -w -U3 -r1.34 ChangeLog
--- src/ui/gui/ChangeLog	1 Jan 2007 01:44:33 -0000	1.34
+++ src/ui/gui/ChangeLog	6 Jan 2007 23:38:49 -0000
@@ -1,3 +1,11 @@
+Sun Jan  7 08:38:29 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+	* psppire-dict.c: Add FILTER_CHANGED and SPLIT_CHANGED signals 
+	corresponding to the callbacks in src/data/dictionary.c
+
+	* data-editor.c : Connect functions to the FILTER_CHANGED and 
+	SPLIT_CHANGED signals to update the status bar accordingly.
+
 Mon Jan  1 10:37:07 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
 	* psppire-case-file.c psppire-case-file.h: Changed the backend 
Index: src/ui/gui/data-editor.c
===================================================================
RCS file: /sources/pspp/pspp/src/ui/gui/data-editor.c,v
retrieving revision 1.10
diff -b -w -U3 -r1.10 data-editor.c
--- src/ui/gui/data-editor.c	4 Jan 2007 08:15:27 -0000	1.10
+++ src/ui/gui/data-editor.c	6 Jan 2007 23:38:49 -0000
@@ -59,8 +59,10 @@
 static void select_sheet (struct data_editor *de, guint page_num);
 
 
-/* Callback for when the dictionary changes its weights */
+/* Callback for when the dictionary changes properties*/
 static void on_weight_change (GObject *, gint, gpointer);
+static void on_filter_change (GObject *, gint, gpointer);
+static void on_split_change (PsppireDict *, gpointer);
 
 static void data_var_select (GtkNotebook *notebook,
 			    GtkNotebookPage *page,
@@ -136,6 +138,14 @@
 		    G_CALLBACK (on_weight_change),
 		    de);
 
+  g_signal_connect (vs->dict, "filter-changed",
+		    G_CALLBACK (on_filter_change),
+		    de);
+
+  g_signal_connect (vs->dict, "split-changed",
+		    G_CALLBACK (on_split_change),
+		    de);
+
   connect_help (de->xml);
 
   de->invoke_weight_cases_dialog =
@@ -672,6 +682,78 @@
   psppire_dict_insert_variable (vs->dict, posn, NULL);
 }
 
+/* Callback for when the dictionary changes its split variables */
+static void
+on_split_change (PsppireDict *dict, gpointer data)
+{
+  struct data_editor *de = data;
+
+  size_t n_split_vars = dict_get_split_cnt (dict->dict);
+
+  GtkWidget *split_status_area =
+    get_widget_assert (de->xml, "split-file-status-area");
+
+  if ( n_split_vars == 0 )
+    {
+      gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split"));
+    }
+  else
+    {
+      gint i;
+      GString *text;
+      GtkSheet *var_sheet =
+	GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
+
+      PsppireVarStore *vs = PSPPIRE_VAR_STORE
+	(gtk_sheet_get_model (var_sheet) );
+
+      struct variable *const * split_vars = dict_get_split_vars (dict->dict);
+
+      text = g_string_new (_("Split by "));
+
+      for (i = 0 ; i < n_split_vars - 1; ++i )
+	{
+	  g_string_append_printf (text, "%s, ", var_get_name (split_vars[i]));
+	}
+      g_string_append (text, var_get_name (split_vars[i]));
+
+      gtk_label_set_text (GTK_LABEL (split_status_area), text->str);
+
+      g_string_free (text, TRUE);
+    }
+}
+
+
+/* Callback for when the dictionary changes its filter variable */
+static void
+on_filter_change (GObject *o, gint filter_index, gpointer data)
+{
+  struct data_editor *de = data;
+  GtkWidget *filter_status_area =
+    get_widget_assert (de->xml, "filter-use-status-area");
+
+  if ( filter_index == -1 )
+    {
+      gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off"));
+    }
+  else
+    {
+      GtkSheet *var_sheet =
+	GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
+
+      PsppireVarStore *vs = PSPPIRE_VAR_STORE
+	(gtk_sheet_get_model (var_sheet) );
+
+      struct variable *var = psppire_dict_get_variable (vs->dict,
+							filter_index);
+
+      gchar *text = g_strdup_printf (_("Filter by %s"), var_get_name (var));
+
+      gtk_label_set_text (GTK_LABEL (filter_status_area), text);
+
+      g_free (text);
+    }
+}
 
 /* Callback for when the dictionary changes its weights */
 static void
Index: src/ui/gui/data-editor.glade
===================================================================
RCS file: /sources/pspp/pspp/src/ui/gui/data-editor.glade,v
retrieving revision 1.9
diff -b -w -U3 -r1.9 data-editor.glade
--- src/ui/gui/data-editor.glade	4 Jan 2007 08:15:27 -0000	1.9
+++ src/ui/gui/data-editor.glade	6 Jan 2007 23:38:50 -0000
@@ -880,6 +880,7 @@
                     <child>
                       <widget class="GtkLabel" id="filter-use-status-area">
                         <property name="visible">True</property>
+                        <property name="ellipsize">PANGO_ELLIPSIZE_START</property>
                         <property name="width_chars">10</property>
                         <property name="single_line_mode">True</property>
                       </widget>
@@ -931,6 +932,7 @@
                     <child>
                       <widget class="GtkLabel" id="split-file-status-area">
                         <property name="visible">True</property>
+                        <property name="ellipsize">PANGO_ELLIPSIZE_START</property>
                         <property name="width_chars">10</property>
                         <property name="single_line_mode">True</property>
                       </widget>
Index: src/ui/gui/psppire-dict.c
===================================================================
RCS file: /sources/pspp/pspp/src/ui/gui/psppire-dict.c,v
retrieving revision 1.22
diff -b -w -U3 -r1.22 psppire-dict.c
--- src/ui/gui/psppire-dict.c	4 Jan 2007 08:15:27 -0000	1.22
+++ src/ui/gui/psppire-dict.c	6 Jan 2007 23:38:50 -0000
@@ -1,6 +1,6 @@
 /*
     PSPPIRE --- A Graphical User Interface for PSPP
-    Copyright (C) 2004, 2006  Free Software Foundation
+    Copyright (C) 2004, 2006, 2007  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
@@ -50,12 +50,12 @@
        VARIABLE_INSERTED,
        VARIABLES_DELETED,
        WEIGHT_CHANGED,
+       FILTER_CHANGED,
+       SPLIT_CHANGED,
        n_SIGNALS};
 
 static guint signal[n_SIGNALS];
 
-#define CACHE_CHUNK 5
-
 /* --- functions --- */
 /**
  * psppire_dict_get_type:
@@ -170,6 +170,29 @@
 		  G_TYPE_NONE,
 		  1,
 		  G_TYPE_INT);
+
+
+  signal [FILTER_CHANGED] =
+    g_signal_new ("filter-changed",
+		  G_TYPE_FROM_CLASS (class),
+		  G_SIGNAL_RUN_FIRST,
+		  0,
+		  NULL, NULL,
+		  g_cclosure_marshal_VOID__INT,
+		  G_TYPE_NONE,
+		  1,
+		  G_TYPE_INT);
+
+
+  signal [SPLIT_CHANGED] =
+    g_signal_new ("split-changed",
+		  G_TYPE_FROM_CLASS (class),
+		  G_SIGNAL_RUN_FIRST,
+		  0,
+		  NULL, NULL,
+		  g_cclosure_marshal_VOID__VOID,
+		  G_TYPE_NONE,
+		  0);
 }
 
 static void
@@ -208,13 +231,27 @@
   g_signal_emit (pd, signal [WEIGHT_CHANGED], 0, idx);
 }
 
+static void
+filter_changed_callback (struct dictionary *d, int idx, void *pd)
+{
+  g_signal_emit (pd, signal [FILTER_CHANGED], 0, idx);
+}
+
+static void
+split_changed_callback (struct dictionary *d, void *pd)
+{
+  g_signal_emit (pd, signal [SPLIT_CHANGED], 0);
+}
+
 
 static const struct dict_callbacks gui_callbacks =
   {
     addcb,
     delcb,
     mutcb,
-    weight_changed_callback
+    weight_changed_callback,
+    filter_changed_callback,
+    split_changed_callback
   };
 
 static void
