New interface PsppireSelectDestWidget.
[pspp-builds.git] / src / ui / gui / psppire-selector.c
index 367502b6ea219dca40b1aaeb07bb65a806996de4..83fe2d82792a04fb34425b3f0f5a221dde2238fb 100644 (file)
@@ -60,8 +60,8 @@
 
 #include "psppire-dictview.h"
 #include "psppire-var-view.h"
-
-
+#include "psppire-dict.h"
+#include "psppire-select-dest.h"
 
 #include <gtk/gtksignal.h>
 #include <gtk/gtkbutton.h>
@@ -221,8 +221,6 @@ psppire_selector_get_property (GObject         *object,
     };
 }
 
-
-
 static void
 psppire_selector_class_init (PsppireSelectorClass *class)
 {
@@ -299,6 +297,8 @@ psppire_selector_class_init (PsppireSelectorClass *class)
                  g_cclosure_marshal_VOID__VOID,
                  G_TYPE_NONE,
                  0);
+
+  class->default_selection_funcs = g_hash_table_new (g_direct_hash, g_direct_equal);
 }
 
 
@@ -320,6 +320,7 @@ psppire_selector_base_finalize(PsppireSelectorClass *class,
                                gpointer class_data)
 {
   g_hash_table_destroy (class->source_hash);
+  g_hash_table_destroy (class->default_selection_funcs);
 }
 
 /* Callback for when the source treeview is activated (double clicked) */
@@ -364,6 +365,9 @@ on_realize (PsppireSelector *selector)
 
   GList *list = g_hash_table_lookup (class->source_hash, selector->source);
 
+  if ( NULL == list)
+    return;
+
   if ( g_list_first (list)->data == selector)
     {
       if ( selector->row_activate_id )
@@ -647,31 +651,20 @@ on_activate (PsppireSelector *selector, gpointer data)
 }
 
 static gboolean
-permissive_filter (GtkTreeModel *model, GtkTreeIter *iter,
-                PsppireSelector *selector)
-{
-  return FALSE;
-}
-
-/* Default visibility filter for GtkTreeView DEST widget */
-static gboolean
-is_item_in_dest (GtkTreeModel *model, GtkTreeIter *iter,
-                PsppireSelector *selector)
+is_item_in_dest (GtkTreeModel *model, GtkTreeIter *iter, PsppireSelector *selector)
 {
-  GtkTreeModel *dest_model;
-  GtkTreeIter dest_iter;
+  gboolean result = FALSE;
   GtkTreeIter source_iter;
-  gint index;
-  GtkTreePath *path ;
   GtkTreeModel *source_model;
+  GValue value = {0};
 
-  if ( GTK_IS_TREE_MODEL_FILTER (model) )
+  if (GTK_IS_TREE_MODEL_FILTER (model))
     {
       source_model = gtk_tree_model_filter_get_model
        (GTK_TREE_MODEL_FILTER (model));
 
       gtk_tree_model_filter_convert_iter_to_child_iter
-       ( GTK_TREE_MODEL_FILTER (model),  &source_iter,  iter  );
+       (GTK_TREE_MODEL_FILTER (model),  &source_iter, iter);
     }
   else
     {
@@ -679,40 +672,17 @@ is_item_in_dest (GtkTreeModel *model, GtkTreeIter *iter,
       source_iter = *iter;
     }
 
-  dest_model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector->dest));
-
-  path = gtk_tree_model_get_path (source_model, &source_iter);
-
-  index = *gtk_tree_path_get_indices (path);
+  gtk_tree_model_get_value (source_model, &source_iter, DICT_TVM_COL_VAR, &value);
 
-  gtk_tree_path_free (path);
-
-  if ( ! gtk_tree_model_get_iter_first (dest_model, &dest_iter) )
-    return FALSE;
-
-  do
-    {
-      int x;
-      GValue value = {0};
-      GValue int_value = {0};
-      gtk_tree_model_get_value (dest_model, &dest_iter, 0, &value);
+  result = psppire_select_dest_widget_contains_var (PSPPIRE_SELECT_DEST_WIDGET (selector->dest),
+                                                   &value);
 
-      g_value_init (&int_value, G_TYPE_INT);
+  g_value_unset (&value);
 
-      g_value_transform (&value, &int_value);
-
-      x = g_value_get_int (&int_value);
+  return result;
+}
 
-      g_value_unset (&int_value);
-      g_value_unset (&value);
 
-      if ( x == index )
-       return TRUE;
-    }
-  while (gtk_tree_model_iter_next (dest_model, &dest_iter));
-
-  return FALSE;
-}
 
 /* Visibility function for items in the SOURCE widget.
    Returns TRUE iff *all* the selectors for which SOURCE is associated
@@ -747,7 +717,6 @@ static void
 set_tree_view_source (PsppireSelector *selector,
                      GtkTreeView *source)
 {
-
   GList *list = NULL;
 
   PsppireSelectorClass *class = g_type_class_peek (PSPPIRE_SELECTOR_TYPE);
@@ -786,8 +755,6 @@ set_tree_view_source (PsppireSelector *selector,
          g_hash_table_replace (class->source_hash, source, list);
        }
     }
-
-
 }
 
 
@@ -822,7 +789,7 @@ on_dest_data_delete (GtkTreeModel *tree_model,
 
 
 static void
-xxx (PsppireSelector *selector)
+on_dest_model_changed (PsppireSelector *selector)
 {
   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector->dest));
 
@@ -846,12 +813,12 @@ set_tree_view_dest (PsppireSelector *selector,
   g_signal_connect (selection, "changed", G_CALLBACK (on_dest_treeview_select),
                    selector);
 
-
+  on_dest_model_changed (selector);
   g_signal_connect_swapped (dest, "notify::model",
-                           G_CALLBACK (xxx), selector);
-
+                           G_CALLBACK (on_dest_model_changed), selector);
 }
 
+
 /* Callback which causes the filter to be refiltered.
    Called when the DEST GtkEntry is activated (Enter is pressed), or when it
    looses focus.
@@ -863,6 +830,7 @@ refilter (PsppireSelector *selector)
   return FALSE;
 }
 
+
 /* Callback for when the DEST GtkEntry is selected (clicked) */
 static gboolean
 on_entry_dest_select (GtkWidget *widget, GdkEventFocus *event, gpointer data)
@@ -876,7 +844,6 @@ on_entry_dest_select (GtkWidget *widget, GdkEventFocus *event, gpointer data)
 }
 
 
-
 /* Callback for when an item disappears from the source list.
    By implication, this means that the item has been inserted into the
    destination.
@@ -930,7 +897,7 @@ set_default_filter (PsppireSelector *selector)
   if ( selector->filter == NULL)
     {
       if  (GTK_IS_TREE_VIEW (selector->dest))
-       selector->filter = permissive_filter;
+       selector->filter = is_item_in_dest;
     }
 }
 
@@ -978,21 +945,36 @@ update_subjects (PsppireSelector *selector)
   else
     g_error ("Unsupported destination widget: %s", G_OBJECT_TYPE_NAME (selector->dest));
 
+
   /* FIXME: Remove this dependency */
   if ( PSPPIRE_IS_DICT_VIEW (selector->source) )
     {
-      if ( PSPPIRE_IS_VAR_VIEW (selector->dest))
-       psppire_selector_set_select_func (PSPPIRE_SELECTOR (selector),
-                                         insert_source_row_into_tree_view,
-                                         NULL);
-      else if (GTK_IS_ENTRY (selector->dest))
+      GObjectClass *class = G_OBJECT_GET_CLASS (selector);
+      GType type = G_OBJECT_TYPE (selector->dest);
+
+      SelectItemsFunc *func  = 
+       g_hash_table_lookup (PSPPIRE_SELECTOR_CLASS (class)->default_selection_funcs, (gpointer) type);
+
+      if ( func )
        psppire_selector_set_select_func (PSPPIRE_SELECTOR (selector),
-                                         insert_source_row_into_entry,
-                                         NULL);
+                                         func, NULL);
     }
+}
 
+
+void
+psppire_selector_set_default_selection_func (GType type, SelectItemsFunc *func)
+{
+  GObjectClass *class = g_type_class_ref (PSPPIRE_SELECTOR_TYPE);
+
+  g_hash_table_insert (PSPPIRE_SELECTOR_CLASS (class)->default_selection_funcs, (gpointer) type, func);
+
+  g_type_class_unref (class);
 }
 
+
+
+
 /* Set FILTER_FUNC for this selector */
 void
 psppire_selector_set_filter_func (PsppireSelector *selector,