Provide wrapper for gtk_menu_popup_at_pointer.
[pspp] / src / ui / gui / psppire-selector.c
index 17e173b5a59117d17ff7e7021aff66a0f7d62f93..b4c3335d18b771ff9fc659cd1c10a6d9e4cb0a68 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007, 2009, 2010, 2012 Free Software Foundation
+   Copyright (C) 2007, 2009, 2010, 2012, 2015 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
@@ -19,7 +19,7 @@
   This module provides a widget, PsppireSelector derived from
   GtkButton.
 
-  It contains a GtkArrow, and is used for selecting objects from a
+  It contains a GtkImage (to indicate the arrow), and is used for selecting objects from a
   GtkTreeView and putting them into a destination widget (often
   another GtkTreeView).  Typically this is used in psppire for
   selecting variables, thus:
@@ -111,7 +111,7 @@ psppire_selector_get_type (void)
       static const GTypeInfo psppire_selector_info =
       {
        sizeof (PsppireSelectorClass),
-       (GBaseInitFunc) NULL, 
+       (GBaseInitFunc) NULL,
         (GBaseFinalizeFunc) NULL,
        (GClassInitFunc)psppire_selector_class_init,
        (GClassFinalizeFunc) NULL,
@@ -133,8 +133,6 @@ static GObjectClass * parent_class = NULL;
 
 
 
-#define SELECTOR_DEBUGGING 0
-
 static void
 dump_hash_entry (gpointer key, gpointer value, gpointer obj)
 {
@@ -151,7 +149,7 @@ dump_hash_entry (gpointer key, gpointer value, gpointer obj)
 }
 
 /* This function is for debugging only */
-void 
+void
 psppire_selector_show_map (PsppireSelector *obj)
 {
   PsppireSelectorClass *class = g_type_class_peek (PSPPIRE_SELECTOR_TYPE);
@@ -189,7 +187,7 @@ psppire_selector_dispose (GObject *obj)
 
       sel->source_litem = NULL;
     }
-  
+
   g_object_unref (sel->dest);
   g_object_unref (sel->source);
 
@@ -213,9 +211,6 @@ static void on_click (GtkButton *b);
 static void on_realize (GtkWidget *selector);
 
 
-static void update_subjects (PsppireSelector *selector);
-
-
 static void
 psppire_selector_set_property (GObject         *object,
                               guint            prop_id,
@@ -232,15 +227,15 @@ psppire_selector_set_property (GObject         *object,
       break;
     case PROP_PRIMARY:
       selector->primary_requested = TRUE;
-      update_subjects (selector);
+      psppire_selector_update_subjects (selector);
       break;
     case PROP_SOURCE_WIDGET:
       selector->source = g_value_dup_object (value);
-      update_subjects (selector);
+      psppire_selector_update_subjects (selector);
       break;
     case PROP_DEST_WIDGET:
       selector->dest = g_value_dup_object (value);
-      update_subjects (selector);
+      psppire_selector_update_subjects (selector);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -297,14 +292,14 @@ psppire_selector_class_init (PsppireSelectorClass *class)
                          FALSE,
                          G_PARAM_READWRITE);
 
-  GParamSpec *source_widget_spec = 
+  GParamSpec *source_widget_spec =
     g_param_spec_object ("source-widget",
                         "Source Widget",
                         "The widget to be used as the source for this selector",
                         GTK_TYPE_WIDGET,
                         G_PARAM_READWRITE);
 
-  GParamSpec *dest_widget_spec = 
+  GParamSpec *dest_widget_spec =
     g_param_spec_object ("dest-widget",
                         "Destination Widget",
                         "The widget to be used as the destination for this selector",
@@ -416,7 +411,7 @@ on_realize (GtkWidget *w)
       if ( selector->row_activate_id )
        g_signal_handler_disconnect (selector->source, selector->row_activate_id);
 
-      selector->row_activate_id =  
+      selector->row_activate_id =
        g_signal_connect (selector->source, "row-activated", G_CALLBACK (on_row_activate), selector);
     }
 
@@ -425,7 +420,7 @@ on_realize (GtkWidget *w)
   if ( selector->source_select_id )
     g_signal_handler_disconnect (selection, selector->source_select_id);
 
-  selector->source_select_id = 
+  selector->source_select_id =
     g_signal_connect (selection, "changed", G_CALLBACK (on_source_select), selector);
 }
 
@@ -439,8 +434,7 @@ psppire_selector_init (PsppireSelector *selector)
   selector->allow_selection = NULL;
   selector->filter = NULL;
 
-  selector->arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE);
-
+  selector->arrow = gtk_image_new_from_icon_name ("pan-start-symbolic", GTK_ICON_SIZE_BUTTON);
 
   gtk_container_add (GTK_CONTAINER (selector), selector->arrow);
 
@@ -479,16 +473,16 @@ set_direction (PsppireSelector *selector, enum psppire_selector_dir d)
       switch (selector->orientation)
        {
        case   PSPPIRE_SELECT_SOURCE_BEFORE_DEST:
-         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_RIGHT, NULL);
+         g_object_set (selector->arrow, "icon-name", "pan-end-symbolic", NULL);
          break;
        case   PSPPIRE_SELECT_SOURCE_AFTER_DEST:
-         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_LEFT, NULL);
+         g_object_set (selector->arrow, "icon-name", "pan-start-symbolic", NULL);
          break;
        case   PSPPIRE_SELECT_SOURCE_ABOVE_DEST:
-         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_DOWN, NULL);
+         g_object_set (selector->arrow, "icon-name", "pan-down-symbolic", NULL);
          break;
        case   PSPPIRE_SELECT_SOURCE_BELOW_DEST:
-         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_UP, NULL);
+         g_object_set (selector->arrow, "icon-name", "pan-up-symbolic", NULL);
          break;
        default:
          g_assert_not_reached ();
@@ -500,22 +494,21 @@ set_direction (PsppireSelector *selector, enum psppire_selector_dir d)
       switch (selector->orientation)
        {
        case   PSPPIRE_SELECT_SOURCE_BEFORE_DEST:
-         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_LEFT, NULL);
+         g_object_set (selector->arrow, "icon-name", "pan-start-symbolic", NULL);
          break;
        case   PSPPIRE_SELECT_SOURCE_AFTER_DEST:
-         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_RIGHT, NULL);
+         g_object_set (selector->arrow, "icon-name", "pan-end-symbolic", NULL);
          break;
        case   PSPPIRE_SELECT_SOURCE_ABOVE_DEST:
-         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_UP, NULL);
+         g_object_set (selector->arrow, "icon-name", "pan-up-symbolic", NULL);
          break;
        case   PSPPIRE_SELECT_SOURCE_BELOW_DEST:
-         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_DOWN, NULL);
+         g_object_set (selector->arrow, "icon-name", "pan-down-symbolic", NULL);
          break;
        default:
          g_assert_not_reached ();
          break;
        };
-
     }
 }
 
@@ -571,7 +564,7 @@ de_select_selection_tree_view (PsppireSelector *selector)
   de_select_tree_model (selection, model);
 }
 
-static void 
+static void
 de_select_tree_model (GtkTreeSelection *selection, GtkTreeModel *model)
 {
   GList *item;
@@ -671,7 +664,7 @@ select_selection (PsppireSelector *selector)
 
   g_return_if_fail (selector->select_items);
 
-  if (selector->allow_selection && 
+  if (selector->allow_selection &&
       ! selector->allow_selection (selector->source, selector->dest))
     return;
 
@@ -802,10 +795,10 @@ set_tree_view_source (PsppireSelector *selector)
   GList *list = NULL;
 
   PsppireSelectorClass *class = g_type_class_peek (PSPPIRE_SELECTOR_TYPE);
-  
+
   if ( ! (list = g_hash_table_lookup (class->source_hash, selector->source)))
     {
-      /* Base case:  This widget is currently not the source of 
+      /* Base case:  This widget is currently not the source of
         any selector.  Create a hash entry and make this selector
         the first selector in the list */
 
@@ -854,14 +847,14 @@ update_model (
   if (model && (model == g_object_get_data (G_OBJECT (source), "model-copy")))
     return;
 
-  if (model != NULL) 
-    {      
-      GtkTreeModel *new_model = gtk_tree_model_filter_new (model, NULL); 
+  if (model != NULL)
+    {
+      GtkTreeModel *new_model = gtk_tree_model_filter_new (model, NULL);
 
-      g_object_set_data (G_OBJECT (source), "model-copy", new_model);  
+      g_object_set_data (G_OBJECT (source), "model-copy", new_model);
 
       gtk_tree_view_set_model (source, new_model);
-  
+
       gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (new_model),
                                               is_source_item_visible,
                                               selector,
@@ -922,19 +915,19 @@ on_dest_model_changed (PsppireSelector *selector)
 {
   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector->dest));
 
-  if (model == NULL) 
+  if (model == NULL)
     return;
 
   g_signal_connect (model, "row-changed", G_CALLBACK (on_dest_data_change),
                    selector);
-  
+
   g_signal_connect (model, "row-deleted", G_CALLBACK (on_dest_data_delete),
                    selector);
 
   g_signal_connect (selector, "destroy", G_CALLBACK (remove_selector_handlers), model);
-  
+
   if ( selector->selecting ) return;
-  
+
   refilter (selector);
 }
 
@@ -1015,8 +1008,8 @@ set_default_filter (PsppireSelector *selector)
 }
 
 
-static void
-update_subjects (PsppireSelector *selector)
+void
+psppire_selector_update_subjects (PsppireSelector *selector)
 {
   if ( NULL == selector->dest )
     return;
@@ -1030,8 +1023,8 @@ update_subjects (PsppireSelector *selector)
     {
       set_tree_view_source (selector);
 
-      g_signal_connect (selector->source, "notify::model", 
-                              G_CALLBACK (update_model), selector); 
+      g_signal_connect (selector->source, "notify::model",
+                              G_CALLBACK (update_model), selector);
 
       update_model (GTK_TREE_VIEW (selector->source), 0, selector);
     }
@@ -1060,13 +1053,12 @@ update_subjects (PsppireSelector *selector)
     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_DICT_VIEW (selector->source) && selector->select_items == NULL)
     {
       GObjectClass *class = G_OBJECT_GET_CLASS (selector);
       GType type = G_OBJECT_TYPE (selector->dest);
 
-      SelectItemsFunc *func  = 
+      SelectItemsFunc *func  =
        g_hash_table_lookup (PSPPIRE_SELECTOR_CLASS (class)->default_selection_funcs, (gpointer) type);
 
       if ( func )