pspp-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pspp-cvs] pspp/src/ui/gui ChangeLog compute-dialog.c desc...


From: John Darrington
Subject: [Pspp-cvs] pspp/src/ui/gui ChangeLog compute-dialog.c desc...
Date: Sun, 07 Oct 2007 00:25:03 +0000

CVSROOT:        /sources/pspp
Module name:    pspp
Changes by:     John Darrington <jmd>   07/10/07 00:25:03

Modified files:
        src/ui/gui     : ChangeLog compute-dialog.c 
                         descriptives-dialog.c psppire-buttonbox.c 
                         psppire-dialog.c psppire-dialog.h 

Log message:
        Added feature to make OK and PASTE buttons insensitive until the dialog 
box
        contains valid data.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/ChangeLog?cvsroot=pspp&r1=1.92&r2=1.93
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/compute-dialog.c?cvsroot=pspp&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/descriptives-dialog.c?cvsroot=pspp&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/psppire-buttonbox.c?cvsroot=pspp&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/psppire-dialog.c?cvsroot=pspp&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/psppire-dialog.h?cvsroot=pspp&r1=1.7&r2=1.8

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/pspp/pspp/src/ui/gui/ChangeLog,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -b -r1.92 -r1.93
--- ChangeLog   4 Oct 2007 02:41:53 -0000       1.92
+++ ChangeLog   7 Oct 2007 00:25:03 -0000       1.93
@@ -1,3 +1,17 @@
+2007-10-06  John Darrington <address@hidden>
+       
+       * psppire-dialog.c psppire-dialog.h: Added a predicate function
+       member to indicate when a dialog's state is (not) valid. Added a
+       signal "validity-changed" which gets emitted whenever this
+       predicate changes. 
+
+       * psppire-buttonbox.c: Connect to the toplevel window's
+       "validity-changed" signal (assuming it happens to be a
+       PsppireDialog) and set the OK, PASTE, GOTO and CONTINUE buttons
+       according.y. 
+
+       * descriptives-dialog.c compute-dialog.c: Add a validity predicate.
+
 2007-10-04  John Darrington <address@hidden>
 
        * compute-dialog.c goto-case-dialog.c main.c psppire-keypad.c: Added 

Index: compute-dialog.c
===================================================================
RCS file: /sources/pspp/pspp/src/ui/gui/compute-dialog.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- compute-dialog.c    4 Oct 2007 02:41:54 -0000       1.10
+++ compute-dialog.c    7 Oct 2007 00:25:03 -0000       1.11
@@ -327,6 +327,28 @@
     }
 }
 
+
+/* Return TRUE if the dialog box's widgets' state are such that clicking OK
+   might not result in erroneous syntax being generated */
+static gboolean
+contents_plausible (gpointer data)
+{
+  struct compute_dialog *cd = data;
+
+  GtkWidget *target      = get_widget_assert (cd->xml, "compute-entry1");
+  GtkWidget *syntax_area = get_widget_assert (cd->xml, "compute-textview1");
+  GtkTextBuffer *buffer  =
+    gtk_text_view_get_buffer (GTK_TEXT_VIEW (syntax_area));
+
+  if ( 0 == strcmp ("", gtk_entry_get_text (GTK_ENTRY (target))))
+    return FALSE;
+
+  if ( gtk_text_buffer_get_char_count (buffer) == 0 )
+    return FALSE;
+
+  return TRUE;
+}
+
 /* Pops up the Compute dialog box */
 void
 compute_dialog (GObject *o, gpointer data)
@@ -359,6 +381,7 @@
 
   vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet));
 
+
   scd.dict = vs->dict;
   scd.use_type = FALSE;
 
@@ -389,6 +412,9 @@
 
   scd.xml = xml;
 
+  psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog),
+                                     contents_plausible, &scd);
+
   g_signal_connect (target, "changed", G_CALLBACK (on_target_change), &scd);
 
   g_signal_connect (dialog, "refresh", G_CALLBACK (refresh),  &scd);

Index: descriptives-dialog.c
===================================================================
RCS file: /sources/pspp/pspp/src/ui/gui/descriptives-dialog.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- descriptives-dialog.c       6 Oct 2007 04:24:34 -0000       1.1
+++ descriptives-dialog.c       7 Oct 2007 00:25:03 -0000       1.2
@@ -287,6 +287,20 @@
   gtk_tree_view_append_column (treeview, col);
 }
 
+
+/* Dialog is valid iff at least one variable has been selected */
+static gboolean
+dialog_state_valid (gpointer data)
+{
+  struct descriptives_dialog *dd = data;
+
+  GtkTreeModel *vars = gtk_tree_view_get_model (dd->stat_vars);
+
+  GtkTreeIter notused;
+
+  return gtk_tree_model_get_iter_first (vars, &notused);
+}
+
 /* Pops up the Descriptives dialog box */
 void
 descriptives_dialog (GObject *o, gpointer data)
@@ -340,6 +354,9 @@
 
   g_signal_connect (dialog, "refresh", G_CALLBACK (refresh),  &scd);
 
+  psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog),
+                                     dialog_state_valid, &scd);
+
   response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
 
 

Index: psppire-buttonbox.c
===================================================================
RCS file: /sources/pspp/pspp/src/ui/gui/psppire-buttonbox.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- psppire-buttonbox.c 4 Oct 2007 02:41:54 -0000       1.9
+++ psppire-buttonbox.c 7 Oct 2007 00:25:03 -0000       1.10
@@ -225,6 +225,31 @@
 }
 
 
+
+static void
+on_validity_change (GtkWidget *toplevel, gboolean valid, gpointer data)
+{
+  PsppireButtonBox *bb = data;
+
+  /* Set the sensitivity of all the 'executive order' buttons */
+  gtk_widget_set_sensitive (GTK_WIDGET (bb->button[PSPPIRE_BUTTON_OK]), valid);
+  gtk_widget_set_sensitive (GTK_WIDGET (bb->button[PSPPIRE_BUTTON_PASTE]), 
valid);
+  gtk_widget_set_sensitive (GTK_WIDGET (bb->button[PSPPIRE_BUTTON_GOTO]), 
valid);
+  gtk_widget_set_sensitive (GTK_WIDGET (bb->button[PSPPIRE_BUTTON_CONTINUE]), 
valid);
+}
+
+static void
+on_realize (GtkWidget *buttonbox, gpointer data)
+{
+  GtkWidget *toplevel = gtk_widget_get_toplevel (buttonbox);
+
+  if ( PSPPIRE_IS_DIALOG (toplevel))
+    {
+      g_signal_connect (toplevel, "validity-changed",
+                       G_CALLBACK (on_validity_change), buttonbox);
+    }
+}
+
 static void
 psppire_button_box_init (PsppireButtonBox *bb)
 {
@@ -299,6 +324,8 @@
     g_value_unset (&value);
   }
 
+
+  g_signal_connect (bb, "realize", G_CALLBACK (on_realize), NULL);
 }
 
 

Index: psppire-dialog.c
===================================================================
RCS file: /sources/pspp/pspp/src/ui/gui/psppire-dialog.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- psppire-dialog.c    8 Jul 2007 10:49:31 -0000       1.8
+++ psppire-dialog.c    7 Oct 2007 00:25:03 -0000       1.9
@@ -20,12 +20,15 @@
 #include <gtk/gtk.h>
 #include <gtk/gtksignal.h>
 #include "psppire-dialog.h"
+#include "psppire-buttonbox.h"
+#include "psppire-selector.h"
 
 static void psppire_dialog_class_init          (PsppireDialogClass *);
 static void psppire_dialog_init                (PsppireDialog      *);
 
 
 enum  {DIALOG_REFRESH,
+       VALIDITY_CHANGED,
        n_SIGNALS};
 
 static guint signals [n_SIGNALS];
@@ -193,6 +196,18 @@
                  0);
 
 
+  signals [VALIDITY_CHANGED] =
+    g_signal_new ("validity-changed",
+                 G_TYPE_FROM_CLASS (class),
+                 G_SIGNAL_RUN_FIRST,
+                 0,
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__BOOLEAN,
+                 G_TYPE_NONE,
+                 1,
+                 G_TYPE_BOOLEAN);
+
+
   object_class->finalize = psppire_dialog_finalize;
 }
 
@@ -227,6 +242,8 @@
 {
   GValue value = {0};
   dialog->box = NULL;
+  dialog->contents_are_valid = NULL;
+  dialog->validity_data = NULL;
 
   g_value_init (&value, orientation_spec->value_type);
   g_param_value_set_default (orientation_spec, &value);
@@ -259,13 +276,121 @@
   return GTK_WIDGET (dialog) ;
 }
 
+
+static void
+notify_change (PsppireDialog *dialog)
+{
+  if ( dialog->contents_are_valid )
+    {
+      gboolean valid = dialog->contents_are_valid (dialog->validity_data);
+
+      g_signal_emit (dialog, signals [VALIDITY_CHANGED], 0, valid);
+    }
+}
+
+
+/* Descend the widget tree, connecting appropriate signals to the
+   notify_change callback */
+static void
+connect_notify_signal (GtkWidget *w, gpointer data)
+{
+  PsppireDialog *dialog = data;
+
+  if ( PSPPIRE_IS_BUTTONBOX (w))
+    return;
+
+
+
+  if ( GTK_IS_CONTAINER (w))
+    {
+      gtk_container_foreach (GTK_CONTAINER (w),
+                            connect_notify_signal,
+                            dialog);
+    }
+
+
+  /* It's unfortunate that GTK+ doesn't have a generic
+     "user-modified-state-changed" signal.  Instead, we have to try and
+     predict what widgets and signals are likely to exist in our dialogs. */
+
+  if ( GTK_IS_TOGGLE_BUTTON (w))
+    {
+      g_signal_connect_swapped (w, "toggled", G_CALLBACK (notify_change),
+                               dialog);
+    }
+
+  if ( PSPPIRE_IS_SELECTOR (w))
+    {
+      g_signal_connect_swapped (w, "selected", G_CALLBACK (notify_change),
+                               dialog);
+
+      g_signal_connect_swapped (w, "de-selected", G_CALLBACK (notify_change),
+                               dialog);
+    }
+
+  if ( GTK_IS_EDITABLE (w))
+    {
+      g_signal_connect_swapped (w, "changed", G_CALLBACK (notify_change),
+                               dialog);
+    }
+
+  if ( GTK_IS_CELL_EDITABLE (w))
+    {
+      g_signal_connect_swapped (w, "editing-done", G_CALLBACK (notify_change),
+                               dialog);
+    }
+
+  if ( GTK_IS_TEXT_VIEW (w))
+    {
+      GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (w));
+
+      g_signal_connect_swapped (buffer, "changed", G_CALLBACK (notify_change),
+                               dialog);
+    }
+
+  if ( GTK_IS_TREE_VIEW (w))
+    {
+      gint i = 0;
+      GtkTreeView *tv = GTK_TREE_VIEW (w);
+      GtkTreeSelection *selection =
+       gtk_tree_view_get_selection (tv);
+      GtkTreeViewColumn *col;
+
+      g_signal_connect_swapped (selection, "changed",
+                               G_CALLBACK (notify_change), dialog);
+
+      while ((col = gtk_tree_view_get_column (tv, i++)))
+       {
+         GList *renderers = gtk_tree_view_column_get_cell_renderers (col);
+         GList *start = renderers;
+         while (renderers)
+           {
+             if ( GTK_IS_CELL_RENDERER_TOGGLE (renderers->data))
+               g_signal_connect_swapped (renderers->data, "toggled",
+                                         G_CALLBACK (notify_change), dialog);
+             renderers = renderers->next;
+           }
+         g_list_free (start);
+       }
+    }
+}
+
+
 gint
 psppire_dialog_run (PsppireDialog *dialog)
 {
+  if ( dialog->contents_are_valid != NULL )
+    gtk_container_foreach (GTK_CONTAINER (dialog->box),
+                          connect_notify_signal,
+                          dialog);
+
   dialog->loop = g_main_loop_new (NULL, FALSE);
 
   gtk_widget_show (GTK_WIDGET (dialog));
 
+  if ( dialog->contents_are_valid != NULL)
+    g_signal_emit (dialog, signals [VALIDITY_CHANGED], 0, FALSE);
+
   g_signal_emit (dialog, signals [DIALOG_REFRESH], 0);
 
   g_main_loop_run (dialog->loop);
@@ -302,3 +427,15 @@
     }
   return etype;
 }
+
+
+void
+psppire_dialog_set_valid_predicate (PsppireDialog *dialog,
+                                   ContentsAreValid contents_are_valid,
+                                   gpointer data)
+{
+  dialog->contents_are_valid = contents_are_valid;
+  dialog->validity_data = data;
+}
+
+

Index: psppire-dialog.h
===================================================================
RCS file: /sources/pspp/pspp/src/ui/gui/psppire-dialog.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- psppire-dialog.h    7 Jul 2007 06:14:28 -0000       1.7
+++ psppire-dialog.h    7 Oct 2007 00:25:03 -0000       1.8
@@ -40,6 +40,9 @@
 typedef struct _PsppireDialog       PsppireDialog;
 typedef struct _PsppireDialogClass  PsppireDialogClass;
 
+typedef gboolean (*ContentsAreValid) (gpointer);
+
+
 struct _PsppireDialog
 {
   GtkWindow window;
@@ -48,6 +51,9 @@
   /* Private */
   GMainLoop *loop;
   gint response;
+
+  ContentsAreValid contents_are_valid;
+  gpointer validity_data;
 };
 
 struct _PsppireDialogClass
@@ -55,11 +61,15 @@
   GtkWindowClass parent_class;
 };
 
+
 GType          psppire_dialog_get_type        (void);
 GtkWidget*     psppire_dialog_new             (void);
 void           psppire_dialog_reload          (PsppireDialog *);
 void           psppire_dialog_close           (PsppireDialog *);
 gint           psppire_dialog_run             (PsppireDialog *);
+void           psppire_dialog_set_valid_predicate (PsppireDialog *,
+                                                  ContentsAreValid,
+                                                  gpointer );
 
 
 GType psppire_orientation_get_type (void);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]