Update selector widgets on dialog activation.
[pspp] / src / ui / gui / psppire-dialog.c
index 9c854a699e66f153ef878cc8faa4867d780b3b33..918cae0ec1a1b305abe41383c6ad858c9b78e453 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007, 2010, 2011, 2012  Free Software Foundation
+   Copyright (C) 2007, 2010, 2011, 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
@@ -39,9 +39,26 @@ enum  {DIALOG_REFRESH,
 
 static guint signals [n_SIGNALS];
 
+static GObjectClass     *parent_class = NULL;
+
+static void
+psppire_dialog_finalize (GObject *object)
+{
+  PsppireDialog *dialog = PSPPIRE_DIALOG (object);
+
+  g_free (dialog->help_page);
 
-static void psppire_dialog_buildable_init (GtkBuildableIface *iface);
+  if (G_OBJECT_CLASS (parent_class)->finalize)
+    G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+psppire_dialog_base_init (PsppireDialogClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
 
+  object_class->finalize = psppire_dialog_finalize;
+}
 
 GType
 psppire_dialog_get_type (void)
@@ -53,7 +70,7 @@ psppire_dialog_get_type (void)
       static const GTypeInfo dialog_info =
       {
        sizeof (PsppireDialogClass),
-       NULL, /* base_init */
+       (GBaseInitFunc) psppire_dialog_base_init,
         NULL, /* base_finalize */
        (GClassInitFunc) psppire_dialog_class_init,
         NULL, /* class_finalize */
@@ -63,19 +80,8 @@ psppire_dialog_get_type (void)
        (GInstanceInitFunc) psppire_dialog_init,
       };
 
-      static const GInterfaceInfo buildable_info =
-      {
-       (GInterfaceInitFunc) psppire_dialog_buildable_init,
-       NULL,
-       NULL
-      };
-
       dialog_type = g_type_register_static (PSPPIRE_TYPE_WINDOW_BASE,
                                            "PsppireDialog", &dialog_info, 0);
-
-      g_type_add_interface_static (dialog_type,
-                                  GTK_TYPE_BUILDABLE,
-                                  &buildable_info);
     }
 
   return dialog_type;
@@ -83,15 +89,13 @@ psppire_dialog_get_type (void)
 
 
 
-static GObjectClass     *parent_class = NULL;
-
-
 /* Properties */
 enum
 {
   PROP_0,
   PROP_ORIENTATION,
-  PROP_SLIDING
+  PROP_SLIDING,
+  PROP_HELP_PAGE,
 };
 
 
@@ -105,62 +109,18 @@ psppire_dialog_get_property (GObject         *object,
 
   switch (prop_id)
     {
-    case PROP_ORIENTATION:
-      {
-       if ( GTK_IS_VBOX (dialog->box) || GTK_VPANED (dialog->box))
-         g_value_set_enum (value, PSPPIRE_VERTICAL);
-       else if ( GTK_IS_HBOX (dialog->box) || GTK_HPANED (dialog->box))
-         g_value_set_enum (value, PSPPIRE_HORIZONTAL);
-       else if ( GTK_IS_TABLE (dialog->box))
-         g_value_set_enum (value, PSPPIRE_TABULAR);
-      }
-      break;
     case PROP_SLIDING:
       g_value_set_boolean (value, dialog->slidable);
       break;
+    case PROP_HELP_PAGE:
+      g_value_set_string (value, dialog->help_page);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     };
 }
 
-
-static void
-dialog_set_container (PsppireDialog *dialog)
-{
-  if ( dialog->box != NULL)
-    {
-      gtk_container_remove (GTK_CONTAINER (dialog), dialog->box);
-    }
-
-  switch (dialog->orientation)
-    {
-    case PSPPIRE_HORIZONTAL:
-      if ( dialog->slidable)
-       dialog->box = gtk_hpaned_new();
-      else
-       dialog->box = gtk_hbox_new (FALSE, 5);
-      break;
-    case PSPPIRE_VERTICAL:
-      if ( dialog->slidable)
-       dialog->box = gtk_vpaned_new();
-      else
-       dialog->box = gtk_vbox_new (FALSE, 5);
-      break;
-    case PSPPIRE_TABULAR:
-      dialog->box = gtk_table_new (2, 3, FALSE);
-      g_object_set (dialog->box,
-                   "row-spacing", 5,
-                   "column-spacing", 5,
-                   NULL);
-      break;
-    }
-
-  gtk_widget_show_all (dialog->box);
-  gtk_container_add (GTK_CONTAINER (dialog), dialog->box);
-}
-
-
 static void
 psppire_dialog_set_property (GObject         *object,
                             guint            prop_id,
@@ -175,34 +135,29 @@ psppire_dialog_set_property (GObject         *object,
     case PROP_SLIDING:
       dialog->slidable = g_value_get_boolean (value);
       break;
-    case PROP_ORIENTATION:
-      dialog->orientation = g_value_get_enum (value);
+    case PROP_HELP_PAGE:
+      dialog->help_page = g_value_dup_string (value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     };
-
-  dialog_set_container (dialog);
 }
 
-
-static GParamSpec *orientation_spec ;
-
 static void
 psppire_dialog_class_init (PsppireDialogClass *class)
 {
   GObjectClass *object_class = (GObjectClass *) class;
 
   GParamSpec *sliding_spec ;
+  GParamSpec *help_page_spec ;
 
-  orientation_spec =
-    g_param_spec_enum ("orientation",
-                      "Orientation",
-                      "Which way widgets are packed",
-                      PSPPIRE_TYPE_ORIENTATION,
-                      PSPPIRE_HORIZONTAL /* default value */,
-                      G_PARAM_CONSTRUCT_ONLY |G_PARAM_READWRITE);
+  help_page_spec = 
+    g_param_spec_string ("help-page", 
+                        "Help Page",
+                        "The section of the manual to load when the Help button is clicked",
+                        NULL,
+                        G_PARAM_READWRITE);
 
   sliding_spec =
     g_param_spec_boolean ("slidable",
@@ -214,15 +169,15 @@ psppire_dialog_class_init (PsppireDialogClass *class)
   object_class->set_property = psppire_dialog_set_property;
   object_class->get_property = psppire_dialog_get_property;
 
-  g_object_class_install_property (object_class,
-                                   PROP_ORIENTATION,
-                                   orientation_spec);
-
-
   g_object_class_install_property (object_class,
                                    PROP_SLIDING,
                                    sliding_spec);
 
+  g_object_class_install_property (object_class,
+                                   PROP_HELP_PAGE,
+                                   help_page_spec);
+
+
   signals [DIALOG_REFRESH] =
     g_signal_new ("refresh",
                  G_TYPE_FROM_CLASS (class),
@@ -269,13 +224,9 @@ psppire_dialog_class_init (PsppireDialogClass *class)
                  1,
                  G_TYPE_STRING);
 
-
   parent_class = g_type_class_peek_parent (class);
 }
 
-
-
-
 static void
 close_dialog (GtkWidget *w, gpointer data)
 {
@@ -291,7 +242,6 @@ psppire_dialog_close (PsppireDialog *dialog)
   gtk_widget_hide (GTK_WIDGET (dialog));
 }
 
-
 static void
 delete_event_callback (GtkWidget *w, GdkEvent *e, gpointer data)
 {
@@ -302,22 +252,16 @@ delete_event_callback (GtkWidget *w, GdkEvent *e, gpointer data)
 static void
 psppire_dialog_init (PsppireDialog *dialog)
 {
-  GValue value = {0};
-  dialog->box = NULL;
   dialog->contents_are_valid = NULL;
   dialog->validity_data = NULL;
   dialog->contents_are_acceptable = NULL;
   dialog->acceptable_data = NULL;
   dialog->slidable = FALSE;
-
-  g_value_init (&value, orientation_spec->value_type);
-  g_param_value_set_default (orientation_spec, &value);
+  dialog->help_page = NULL;
 
   gtk_window_set_type_hint (GTK_WINDOW (dialog),
        GDK_WINDOW_TYPE_HINT_DIALOG);
 
-  g_value_unset (&value);
-
   g_signal_connect (dialog, "delete-event",
                    G_CALLBACK (delete_event_callback),
                    dialog);
@@ -328,7 +272,6 @@ psppire_dialog_init (PsppireDialog *dialog)
   g_object_set (dialog, "icon-name", "pspp", NULL);
 }
 
-
 GtkWidget*
 psppire_dialog_new (void)
 {
@@ -391,6 +334,8 @@ connect_notify_signal (GtkWidget *w, gpointer data)
       g_signal_connect_swapped (w, "de-selected",
                                G_CALLBACK (psppire_dialog_notify_change),
                                dialog);
+      
+      psppire_selector_update_subjects (PSPPIRE_SELECTOR (w));
     }
 
   if ( GTK_IS_EDITABLE (w))
@@ -427,19 +372,20 @@ connect_notify_signal (GtkWidget *w, gpointer data)
 
       if ( model)
        {
-      g_signal_connect_swapped (model, "row-changed",
-                               G_CALLBACK (psppire_dialog_notify_change),
-                               dialog);
+         g_signal_connect_swapped (model, "row-changed",
+                                   G_CALLBACK (psppire_dialog_notify_change),
+                                   dialog);
 
-      g_signal_connect_swapped (model, "row-deleted",
-                               G_CALLBACK (psppire_dialog_notify_change),
-                               dialog);
+         g_signal_connect_swapped (model, "row-deleted",
+                                   G_CALLBACK (psppire_dialog_notify_change),
+                                   dialog);
 
-      g_signal_connect_swapped (model, "row-inserted",
-                               G_CALLBACK (psppire_dialog_notify_change),
-                               dialog);
-       }
+         g_signal_connect_swapped (model, "row-inserted",
+                                   G_CALLBACK (psppire_dialog_notify_change),
+                                   dialog);
 
+       }
+      
       g_signal_connect_swapped (selection, "changed",
                                G_CALLBACK (psppire_dialog_notify_change),
                                dialog);
@@ -464,23 +410,23 @@ connect_notify_signal (GtkWidget *w, gpointer data)
 gint
 psppire_dialog_run (PsppireDialog *dialog)
 {
+  gchar *title = NULL;
+  g_object_get (dialog, "title", &title, NULL);
+
+  if (title == NULL)
+    g_warning ("PsppireDialog %s has no title", gtk_widget_get_name (GTK_WIDGET (dialog)));
+
   if ( dialog->contents_are_valid != NULL )
-    gtk_container_foreach (GTK_CONTAINER (dialog->box),
+    gtk_container_foreach (GTK_CONTAINER (gtk_bin_get_child(GTK_BIN(dialog))),
                           connect_notify_signal,
                           dialog);
 
   dialog->loop = g_main_loop_new (NULL, FALSE);
 
   gtk_widget_show (GTK_WIDGET (dialog));
+  psppire_dialog_notify_change (dialog);
 
-  if ( dialog->contents_are_valid != NULL)
-    g_signal_emit (dialog, signals [VALIDITY_CHANGED], 0, FALSE);
-
-  g_signal_emit (dialog, signals [DIALOG_REFRESH], 0);
-
-  gdk_threads_leave ();
   g_main_loop_run (dialog->loop);
-  gdk_threads_enter ();
 
   g_main_loop_unref (dialog->loop);
 
@@ -500,37 +446,15 @@ psppire_dialog_reload (PsppireDialog *dialog)
 void
 psppire_dialog_help (PsppireDialog *dialog)
 {
-  char *name = NULL;
-  g_object_get (dialog, "name", &name, NULL);
+  const char *page = NULL;
 
-  online_help (name);
-
-  g_signal_emit (dialog, signals [DIALOG_HELP], 0, name);
-}
+  g_object_get (dialog, "help-page", &page, NULL);
 
+  online_help (page);
 
-GType
-psppire_orientation_get_type (void)
-{
-  static GType etype = 0;
-  if (etype == 0)
-    {
-      static const GEnumValue values[] =
-       {
-         { PSPPIRE_HORIZONTAL, "PSPPIRE_HORIZONTAL", "Horizontal" },
-         { PSPPIRE_VERTICAL,   "PSPPIRE_VERTICAL",   "Vertical" },
-         { PSPPIRE_TABULAR,   "PSPPIRE_TABULAR",   "Tabular" },
-         { 0, NULL, NULL }
-       };
-
-      etype = g_enum_register_static
-       (g_intern_static_string ("PsppireOrientation"), values);
-
-    }
-  return etype;
+  g_signal_emit (dialog, signals [DIALOG_HELP], 0, page);
 }
 
-
 /* Sets a predicate function that is checked after each change that the user
    makes to the dialog's state.  If the predicate function returns false, then
    "OK" and other buttons that accept the dialog's settings will be
@@ -568,27 +492,3 @@ psppire_dialog_is_acceptable (const PsppireDialog *dialog)
   return (dialog->contents_are_acceptable == NULL
           || dialog->contents_are_acceptable (dialog->acceptable_data));
 }
-
-
-
-
-static GObject *
-get_internal_child    (GtkBuildable *buildable,
-                      GtkBuilder *builder,
-                      const gchar *childname)
-{
-  PsppireDialog *dialog = PSPPIRE_DIALOG (buildable);
-
-  if ( 0 == strcmp (childname, "hbox"))
-    return G_OBJECT (dialog->box);
-
-  return NULL;
-}
-
-
-
-static void
-psppire_dialog_buildable_init (GtkBuildableIface *iface)
-{
-  iface->get_internal_child = get_internal_child;
-}