Reimplement the variable info dialog.
authorJohn Darrington <john@darrington.wattle.id.au>
Sun, 20 Dec 2020 21:38:28 +0000 (22:38 +0100)
committerJohn Darrington <john@darrington.wattle.id.au>
Sun, 20 Dec 2020 09:43:55 +0000 (10:43 +0100)
Instead of using a rendered output fragment, display the information
in Gtk+ widgets.

src/ui/gui/automake.mk
src/ui/gui/psppire-dialog-action-var-info.c
src/ui/gui/psppire-dialog-action-var-info.h
src/ui/gui/psppire-var-info.c [new file with mode: 0644]
src/ui/gui/psppire-var-info.h [new file with mode: 0644]
src/ui/gui/psppire.xml
src/ui/gui/variable-info.ui
src/ui/gui/widgets.c

index ad44170170f7546b271ab3279bfd16065523b6a6..d08ab7bfcf3d5b61a667ee212b0f40048e0837a3 100644 (file)
@@ -332,6 +332,8 @@ src_ui_gui_libwidgets_essential_la_SOURCES = \
        src/ui/gui/psppire-text-file.h \
        src/ui/gui/psppire-val-chooser.c \
        src/ui/gui/psppire-val-chooser.h \
+       src/ui/gui/psppire-var-info.c \
+       src/ui/gui/psppire-var-info.h \
        src/ui/gui/psppire-var-ptr.c \
        src/ui/gui/psppire-var-ptr.h \
        src/ui/gui/psppire-var-view.c \
index 0c5aebb3041e8a264c7e1d1f74cb669548856664..570ce4ada68d54a40b00745517b2fb65fc609829 100644 (file)
@@ -1,6 +1,6 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007, 2009, 2010, 2011, 2012, 2013, 2014, 2016  Free Software Foundation
-
+   Copyright (C) 2007, 2009, 2010, 2011, 2012, 2013, 2014, 2016,
+   2020  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
@@ -124,21 +124,9 @@ populate_output (GtkTreeSelection *selection, gpointer data)
   psppire_dict_view_get_selected_variables (PSPPIRE_DICT_VIEW (treeview),
                                             &vars, &n_vars);
 
-  if (n_vars > 0)
-    {
-      PsppireDataWindow *dw;
-
-      g_object_get (act, "top-level", &dw, NULL);
-
-      psppire_output_view_clear (act->output);
+  g_return_if_fail (n_vars <= 1);
 
-      output_engine_push ();
-      psppire_output_view_register_driver (act->output);
-      g_free (execute_syntax_string (
-                dw, generate_syntax__ (&act->parent,
-                                       "DISPLAY DICTIONARY /VARIABLES=")));
-      output_engine_pop ();
-    }
+  g_object_set (act->var_info, "variable", n_vars > 0 ? vars[0] : NULL, NULL);
 }
 
 
@@ -173,9 +161,7 @@ psppire_dialog_action_var_info_activate (PsppireDialogAction *a, GVariant *param
 
   GtkBuilder *xml = builder_new ("variable-info.ui");
 
-  act->output =
-    psppire_output_view_new (GTK_LAYOUT (get_widget_assert (xml, "layout1")),
-                            NULL);
+  act->var_info = get_widget_assert (xml, "var-info0");
 
   pda->dialog = get_widget_assert (xml, "variable-info-dialog");
   pda->source = get_widget_assert (xml, "treeview2");
index 6ea20b20c99301087c6d0663b9d46d85ca0d739c..ef72e7789a86a12c8b7823c381748a0b4fa3e8c1 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2012, 2013, 2014  Free Software Foundation
+   Copyright (C) 2012, 2013, 2014, 2020  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
@@ -60,8 +60,7 @@ struct _PsppireDialogActionVarInfo
   /*< private >*/
   gboolean dispose_has_run ;
 
-  GtkWidget *variables;               /* Treeview of selected variables. */
-  struct psppire_output_view *output; /* Manages output layout. */
+  GtkWidget *var_info;
 };
 
 
diff --git a/src/ui/gui/psppire-var-info.c b/src/ui/gui/psppire-var-info.c
new file mode 100644 (file)
index 0000000..f69dc6d
--- /dev/null
@@ -0,0 +1,248 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2020 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 published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <gtk/gtk.h>
+
+#include "psppire-var-info.h"
+#include "data/value-labels.h"
+#include "data/variable.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+G_DEFINE_TYPE (PsppireVarInfo, psppire_var_info, GTK_TYPE_GRID);
+
+static void
+psppire_var_info_dispose (GObject *obj)
+{
+  PsppireVarInfo *var_info = PSPPIRE_VAR_INFO (obj);
+
+  if (var_info->dispose_has_run)
+    return;
+  var_info->dispose_has_run = TRUE;
+
+  G_OBJECT_CLASS (psppire_var_info_parent_class)->dispose (obj);
+}
+
+static const char *field_labels[n_VAR_INFO] =
+  {
+   N_("Name"),
+   N_("Label"),
+   N_("Position"),
+   N_("Measurement Level"),
+   N_("Role"),
+   N_("Width"),
+   N_("Alignment"),
+   N_("Print Format"),
+   N_("Write Format"),
+   N_("Missing Values"),
+   N_("Value Labels")
+  };
+
+
+void
+psppire_var_info_init (PsppireVarInfo *var_info)
+{
+  g_object_set (var_info,
+                "row-spacing", 3,
+                "column-spacing", 3,
+                "margin", 5,
+                NULL);
+
+  for (int r = 0; r < n_VAR_INFO; ++r)
+    {
+      GtkWidget *label = gtk_label_new (gettext (field_labels[r]));
+      g_object_set (label,
+                    "halign", GTK_ALIGN_START,
+                    NULL);
+
+      gtk_grid_attach (GTK_GRID (var_info), label, 0, r, 1, 1);
+      gtk_widget_show (label);
+
+      if (r >= n_VAR_INFO - 1)
+        break;
+
+      var_info->entry[r] = gtk_entry_new ();
+
+      g_object_set (var_info->entry[r],
+                    "visible", TRUE,
+                    "double-buffered", FALSE,
+                    "hexpand", TRUE,
+                    "editable", FALSE,
+                    NULL);
+
+      gtk_grid_attach (GTK_GRID (var_info), var_info->entry[r], 1, r, 1, 1);
+    }
+
+  var_info->combo = gtk_combo_box_text_new_with_entry ();
+  GtkWidget *entry = gtk_bin_get_child (GTK_BIN (var_info->combo));
+  g_object_set (entry, "editable", FALSE, NULL);
+  gtk_widget_show (var_info->combo);
+
+  gtk_grid_attach (GTK_GRID (var_info), var_info->combo, 1, n_VAR_INFO - 1, 1, 1);
+}
+
+GtkWidget*
+psppire_var_info_new (void)
+{
+  return GTK_WIDGET (g_object_new (psppire_var_info_get_type (), NULL));
+}
+
+
+enum
+  {
+    PROP_0,
+    PROP_VARIABLE,
+  };
+
+static void
+__set_property (GObject      *object,
+                guint         prop_id,
+                const GValue *value,
+                GParamSpec   *pspec)
+{
+  PsppireVarInfo *var_info = PSPPIRE_VAR_INFO (object);
+
+  switch (prop_id)
+    {
+    case PROP_VARIABLE:
+      {
+        gtk_combo_box_text_remove_all (GTK_COMBO_BOX_TEXT (var_info->combo));
+        gtk_combo_box_set_active  (GTK_COMBO_BOX (var_info->combo), 0);
+        GtkWidget *entry = gtk_bin_get_child (GTK_BIN (var_info->combo));
+        gtk_entry_set_text (GTK_ENTRY (entry), "");
+
+        const struct variable *var = g_value_get_pointer (value);
+        if (var == NULL)
+          {
+            for (int i = 0; i < n_VAR_INFO - 1; ++i)
+              {
+                gtk_entry_set_text (GTK_ENTRY (var_info->entry[i]), "");
+              }
+            gtk_combo_box_set_active  (GTK_COMBO_BOX (var_info->combo), -1);
+            return;
+          }
+
+        char *str = NULL;
+        gtk_entry_set_text (GTK_ENTRY (var_info->entry[VAR_INFO_NAME]),
+                            var_get_name (var));
+
+        str = g_strdup_printf ("%ld", var_get_dict_index (var));
+        gtk_entry_set_text (GTK_ENTRY (var_info->entry[VAR_INFO_POSITION]),
+                            str);
+        g_free (str);
+
+        const char *label = var_get_label (var);
+        gtk_entry_set_text (GTK_ENTRY (var_info->entry[VAR_INFO_LABEL]),
+                            label ? label : "");
+
+        str = g_strdup_printf ("%d", var_get_width (var));
+        gtk_entry_set_text (GTK_ENTRY (var_info->entry[VAR_INFO_WIDTH]),
+                            str);
+        g_free (str);
+
+        gtk_entry_set_text (GTK_ENTRY (var_info->entry[VAR_INFO_MEASUREMENT_LEVEL]),
+                            measure_to_string (var_get_measure (var)));
+
+        gtk_entry_set_text (GTK_ENTRY (var_info->entry[VAR_INFO_ROLE]),
+                            var_role_to_string (var_get_role (var)));
+
+        gtk_entry_set_text (GTK_ENTRY (var_info->entry[VAR_INFO_ALIGNMENT]),
+                            alignment_to_string (var_get_alignment (var)));
+
+        const struct fmt_spec *pf = var_get_print_format (var);
+        char xx[FMT_STRING_LEN_MAX + 1];
+        gtk_entry_set_text (GTK_ENTRY (var_info->entry[VAR_INFO_PRINT_FORMAT]),
+                            fmt_to_string (pf, xx));
+
+        const struct fmt_spec *wf = var_get_write_format (var);
+        gtk_entry_set_text (GTK_ENTRY (var_info->entry[VAR_INFO_WRITE_FORMAT]),
+                            fmt_to_string (wf, xx));
+
+        const struct missing_values *mv = var_get_missing_values (var);
+        str = mv_to_string (mv, "UTF-8");
+        gtk_entry_set_text (GTK_ENTRY (var_info->entry[VAR_INFO_MISSING_VALUES]),
+                            str ? str : "");
+        g_free (str);
+
+        const struct val_labs *vls = var_get_value_labels (var);
+        if (vls)
+          {
+            for (const struct val_lab *vl = val_labs_first (vls);
+                 vl;
+                 vl = val_labs_next (vls, vl))
+              {
+                if (vl)
+                  {
+                    struct string text;
+                    ds_init_empty (&text);
+
+                    const char *l = val_lab_get_label (vl);
+                    const union value *v = val_lab_get_value (vl);
+
+                    var_append_value_name__ (var, v, SETTINGS_VALUE_SHOW_VALUE, &text);
+                    ds_put_cstr (&text, ": ");
+                    ds_put_cstr (&text, l);
+
+                    gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (var_info->combo), ds_cstr (&text));
+                    gtk_combo_box_set_active  (GTK_COMBO_BOX (var_info->combo), 0);
+                  }
+              }
+          }
+      }
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+__get_property (GObject      *object,
+                guint         prop_id,
+                GValue       *value,
+                GParamSpec   *pspec)
+{
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+static void
+psppire_var_info_class_init (PsppireVarInfoClass *class)
+{
+
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+
+  gobject_class->set_property = __set_property;
+  gobject_class->get_property = __get_property;
+  gobject_class->dispose = psppire_var_info_dispose;
+
+  g_object_class_install_property (gobject_class, PROP_VARIABLE,
+                                   g_param_spec_pointer
+                                   ("variable",
+                                    "Variable",
+                                    "The variable whose parameters are to be displayed",
+                                    G_PARAM_WRITABLE));
+}
diff --git a/src/ui/gui/psppire-var-info.h b/src/ui/gui/psppire-var-info.h
new file mode 100644 (file)
index 0000000..6353a00
--- /dev/null
@@ -0,0 +1,76 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2020 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 published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#ifndef __PSPPIRE_VAR_INFO_H__
+#define __PSPPIRE_VAR_INFO_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+
+G_BEGIN_DECLS
+
+#define PSPPIRE_VAR_INFO_TYPE            (psppire_var_info_get_type ())
+#define PSPPIRE_VAR_INFO(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_VAR_INFO_TYPE, PsppireVarInfo))
+#define PSPPIRE_VAR_INFO_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PSPPIRE_VAR_INFO_TYPE, PsppireVarInfoClass))
+#define PSPPIRE_IS_VAR_INFO(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_VAR_INFO_TYPE))
+#define PSPPIRE_IS_VAR_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_VAR_INFO_TYPE))
+
+enum
+    {
+     VAR_INFO_NAME,
+     VAR_INFO_LABEL,
+     VAR_INFO_POSITION,
+     VAR_INFO_MEASUREMENT_LEVEL,
+     VAR_INFO_ROLE,
+     VAR_INFO_WIDTH,
+     VAR_INFO_ALIGNMENT,
+     VAR_INFO_PRINT_FORMAT,
+     VAR_INFO_WRITE_FORMAT,
+     VAR_INFO_MISSING_VALUES,
+     VAR_INFO_VALUE_LABELS,
+     n_VAR_INFO
+    };
+
+typedef struct _PsppireVarInfo       PsppireVarInfo;
+typedef struct _PsppireVarInfoClass  PsppireVarInfoClass;
+
+struct _PsppireVarInfo
+{
+  GtkGrid parent;
+
+  gboolean dispose_has_run;
+
+  GtkWidget *entry[n_VAR_INFO - 1];
+  GtkWidget *combo;
+};
+
+
+struct _PsppireVarInfoClass
+{
+  GtkGridClass parent_class;
+};
+
+
+
+GType       psppire_var_info_get_type        (void);
+GtkWidget*  psppire_var_info_new             (void);
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_VAR_INFO_H__ */
index 3c0d43a64e3ba7c953b8bf99f9b9e8cadde4645c..d2b7cc020fa825bddbcb83e14a5505bb40117a70 100644 (file)
@@ -14,7 +14,9 @@
     <glade-widget-class name="PsppireValChooser"    generic-name="val-chooser" title="Psppire Value Chooser"/>
     <glade-widget-class name="PsppireVarView"   generic-name="var-view" title="Psppire Variable View"/>
     <glade-widget-class name="PsppireVariableSheet" generic-name="variable-sheet" title="Psppire Variable Sheet"/>
+    <glade-widget-class name="PsppireVarInfo"   generic-name="var-info" title="Psppire Variable Info"/>
     <glade-widget-class name="SswSheet" generic-name="variable-sheet" title="Spread Sheet"/>
+
   </glade-widget-classes>
 
   <glade-widget-group name="psppire" title="Psppire">
@@ -29,6 +31,7 @@
     <glade-widget-class-ref name="PsppireValChooser"/>
     <glade-widget-class-ref name="PsppireVarView"/>
     <glade-widget-class-ref name="PsppireVariableSheet"/>
+    <glade-widget-class-ref name="PsppireVarInfo"/>
     <glade-widget-class-ref name="SswSheet"/>
   </glade-widget-group>
 
index 3bd22477c470c588dc70731a474fb93119adbc01..6476eec40a79fe2dd84d72b3b4f2fffe1deef64b 100644 (file)
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
 <!-- PSPP - a program for statistical analysis. -->
 <!-- Copyright (C) 2017 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 published by -->
 <!-- the Free Software Foundation, either version 3 of the License, or -->
 <!-- (at your option) any later version. -->
-
 <!-- This program is distributed in the hope that it will be useful, -->
 <!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
 <!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -->
 <!-- GNU General Public License for more details. -->
-
 <!-- You should have received a copy of the GNU General Public License -->
 <!-- along with this program.  If not, see <http://www.gnu.org/licenses/>. -->
-
-<!-- Generated with glade 3.18.3 -->
 <interface>
   <requires lib="gtk+" version="3.22"/>
   <requires lib="psppire" version="2054.22072"/>
     <property name="title" translatable="yes">Variables</property>
     <property name="modal">True</property>
     <property name="slidable">True</property>
-    <property name="help-page">Variable-Attributes</property>
+    <property name="help_page">Variable-Attributes</property>
+    <child>
+      <placeholder/>
+    </child>
     <child>
       <object class="GtkPaned" id="dialog-hbox2">
         <property name="visible">True</property>
-        <property name="orientation">horizontal</property>
         <property name="can_focus">False</property>
         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
         <child>
@@ -46,7 +44,6 @@
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                 <property name="border_width">0</property>
                 <property name="headers_visible">False</property>
-                <property name="reorderable">False</property>
                 <property name="fixed_height_mode">True</property>
                 <child internal-child="selection">
                   <object class="GtkTreeSelection" id="psppire-dictview-selection1"/>
             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
             <property name="orientation">vertical</property>
             <property name="spacing">5</property>
+            <child>
+              <object class="PsppireVarInfo" id="var-info0">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
             <child>
               <object class="PsppireButtonBox" id="psppire-hbuttonbox4">
-                <property name="orientation">horizontal</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                 <property name="position">1</property>
               </packing>
             </child>
-            <child>
-              <object class="GtkScrolledWindow" id="scrolledwindow14">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="shadow_type">in</property>
-                <child>
-                  <object class="GtkLayout" id="layout1">
-                    <property name="height_request">200</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="padding">5</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
           </object>
           <packing>
             <property name="resize">True</property>
index 7b308c0e3f6b7ac348c0a49865dbdff11100223b..25aff745c4f9913dba123c3331b00b0986987890 100644 (file)
@@ -79,6 +79,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "psppire-value-entry.h"
 #include "psppire-data-sheet.h"
 #include "psppire-var-sheet-header.h"
+#include "psppire-var-info.h"
 #include "psppire-variable-sheet.h"
 #include <ssw-sheet.h>
 
@@ -224,6 +225,7 @@ preregister_widgets (void)
   psppire_data_sheet_get_type ();
   psppire_var_sheet_header_get_type ();
   psppire_variable_sheet_get_type ();
+  psppire_var_info_get_type ();
 
   preregister_actions ();
   preregister_misc ();