Numerous GUI enhancements.
authorJohn Darrington <john@darrington.wattle.id.au>
Fri, 30 Mar 2007 23:39:32 +0000 (23:39 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Fri, 30 Mar 2007 23:39:32 +0000 (23:39 +0000)
29 files changed:
glade/ChangeLog [new file with mode: 0644]
glade/automake.mk
glade/dialog.c
glade/icons/16x16/psppire-buttonbox.png [new file with mode: 0644]
glade/icons/16x16/psppire-dialog.png [new file with mode: 0644]
glade/icons/16x16/psppire-keypad.png [new file with mode: 0644]
glade/icons/16x16/psppire-selector.png [new file with mode: 0644]
glade/icons/22x22/psppire-buttonbox.png [new file with mode: 0644]
glade/icons/22x22/psppire-dialog.png [new file with mode: 0644]
glade/icons/22x22/psppire-keypad.png [new file with mode: 0644]
glade/icons/22x22/psppire-selector.png [new file with mode: 0644]
glade/psppire.xml
po/de.po
po/pspp.pot
src/ui/gui/ChangeLog
src/ui/gui/automake.mk
src/ui/gui/data-editor.c
src/ui/gui/data-editor.glade
src/ui/gui/data-editor.h
src/ui/gui/dialog-common.c [new file with mode: 0644]
src/ui/gui/dialog-common.h [new file with mode: 0644]
src/ui/gui/psppire-keypad.c [new file with mode: 0644]
src/ui/gui/psppire-keypad.h [new file with mode: 0644]
src/ui/gui/psppire-selector.c
src/ui/gui/psppire-selector.h
src/ui/gui/psppire.glade
src/ui/gui/split-file-dialog.c [new file with mode: 0644]
src/ui/gui/split-file-dialog.h [new file with mode: 0644]
src/ui/gui/transpose-dialog.c

diff --git a/glade/ChangeLog b/glade/ChangeLog
new file mode 100644 (file)
index 0000000..d7d4677
--- /dev/null
@@ -0,0 +1,6 @@
+Sat Mar 31 07:09:33 WST 2007 John Darrington <john@darrington.wattle.id.au>
+       
+  * Added icons directory and its contents.
+
+  * Re-wrote psppire.xml to work with glade 3.2.0, and to know about the
+    keypad widget. 
index 5d5a65839b9c5397136cc8cd320aa8ad96631a46..e9af9aeb49e290ac627f78ea17de1808441c6d24 100644 (file)
@@ -4,18 +4,35 @@ module_LTLIBRARIES = libglade-psppire.la
 
 moduledir = `pkg-config --variable=moduledir libgladeui-1.0`
 catalogdir = `pkg-config --variable=catalogdir libgladeui-1.0`
+pixmapdir = `pkg-config --variable=pixmapdir libgladeui-1.0`
+
+small_pixmapdir = $(pixmapdir)/16x16
+large_pixmapdir = $(pixmapdir)/22x22
 
 libglade_psppire_la_SOURCES = \
        glade/dialog.c \
        glade/bbox.c \
        glade/selector.c \
-       src/ui/gui/psppire-dialog.c \
        src/ui/gui/psppire-buttonbox.c \
+       src/ui/gui/psppire-dialog.c \
+       src/ui/gui/psppire-keypad.c \
        src/ui/gui/psppire-selector.c
 
 nodist_catalog_DATA = \
        glade/psppire.xml
 
+nodist_small_pixmap_DATA = \
+       glade/icons/16x16/psppire-buttonbox.png \
+       glade/icons/16x16/psppire-dialog.png \
+       glade/icons/16x16/psppire-keypad.png \
+       glade/icons/16x16/psppire-selector.png 
+
+nodist_large_pixmap_DATA = \
+       glade/icons/22x22/psppire-buttonbox.png \
+       glade/icons/22x22/psppire-dialog.png \
+       glade/icons/22x22/psppire-keypad.png \
+       glade/icons/16x16/psppire-selector.png 
+
 
 libglade_psppire_la_CFLAGS = $(GLADE_UI_CFLAGS) $(GLADE_CFLAGS) \
-       -I src/ui/gui
+       -I src/ui/gui -DDEBUGGING
index ab38c706e57715de5b7cdb7bce516face99658b0..ac6f2a22c0a2c8489ce61bb04c2dbefea0d0dc64 100644 (file)
@@ -4,6 +4,7 @@
 #include "psppire-dialog.h"
 
 #include <glade-gtk.h>
+#include <assert.h>
 
 
 void GLADEGTK_API
@@ -26,7 +27,7 @@ glade_psppire_dialog_post_create (GladeWidgetAdaptor *adaptor,
 
   if (reason == GLADE_CREATE_USER)
     {
-      /* HIG complient border-width defaults on dialogs */
+      /* HIG compliant border-width defaults on dialogs */
       glade_widget_property_set (widget, "border-width", 5);
     }
 
@@ -44,17 +45,12 @@ glade_psppire_dialog_post_create (GladeWidgetAdaptor *adaptor,
   if (reason == GLADE_CREATE_USER)
     {
 
-      /* HIG complient spacing defaults on dialogs */
+      /* HIG compliant spacing defaults on dialogs */
       glade_widget_property_set (box_widget, "spacing", 2);
 
       glade_widget_property_set (box_widget, "size", 2);
 
     }
-
-
-  /* set a reasonable default size for a dialog */
-  gtk_window_set_default_size (GTK_WINDOW (dialog), 320, 260);
-
 }
 
 
@@ -86,6 +82,8 @@ glade_psppire_dialog_set_property (GladeWidgetAdaptor *adaptor,
           id);
 #endif
 
+  assert (  GWA_GET_CLASS (GTK_TYPE_WINDOW)->set_property );
+
   GWA_GET_CLASS (GTK_TYPE_WINDOW)->set_property (adaptor, object,
                                                 id, value);
 }
diff --git a/glade/icons/16x16/psppire-buttonbox.png b/glade/icons/16x16/psppire-buttonbox.png
new file mode 100644 (file)
index 0000000..d37d4df
Binary files /dev/null and b/glade/icons/16x16/psppire-buttonbox.png differ
diff --git a/glade/icons/16x16/psppire-dialog.png b/glade/icons/16x16/psppire-dialog.png
new file mode 100644 (file)
index 0000000..0d5cf63
Binary files /dev/null and b/glade/icons/16x16/psppire-dialog.png differ
diff --git a/glade/icons/16x16/psppire-keypad.png b/glade/icons/16x16/psppire-keypad.png
new file mode 100644 (file)
index 0000000..be9f749
Binary files /dev/null and b/glade/icons/16x16/psppire-keypad.png differ
diff --git a/glade/icons/16x16/psppire-selector.png b/glade/icons/16x16/psppire-selector.png
new file mode 100644 (file)
index 0000000..d4fe2f2
Binary files /dev/null and b/glade/icons/16x16/psppire-selector.png differ
diff --git a/glade/icons/22x22/psppire-buttonbox.png b/glade/icons/22x22/psppire-buttonbox.png
new file mode 100644 (file)
index 0000000..f241e68
Binary files /dev/null and b/glade/icons/22x22/psppire-buttonbox.png differ
diff --git a/glade/icons/22x22/psppire-dialog.png b/glade/icons/22x22/psppire-dialog.png
new file mode 100644 (file)
index 0000000..575ebf5
Binary files /dev/null and b/glade/icons/22x22/psppire-dialog.png differ
diff --git a/glade/icons/22x22/psppire-keypad.png b/glade/icons/22x22/psppire-keypad.png
new file mode 100644 (file)
index 0000000..be61044
Binary files /dev/null and b/glade/icons/22x22/psppire-keypad.png differ
diff --git a/glade/icons/22x22/psppire-selector.png b/glade/icons/22x22/psppire-selector.png
new file mode 100644 (file)
index 0000000..ea13309
Binary files /dev/null and b/glade/icons/22x22/psppire-selector.png differ
index da6f0137967c6df74208f2d06b297233a977d4d4..45902b56eb285a558c4168912248e72bee202730 100644 (file)
+<?xml version="1.0" encoding="UTF-8"?>
 <glade-catalog name="psppire" library="glade-psppire">
 
-  <init-function>my_catalog_init</init-function>
-
   <glade-widget-classes>
 
-    <glade-widget-class toplevel="True" name="PsppireDialog" generic-name="psppire-dialog" title="Psppire Dialog Box">
-      <post-create-function>glade_psppire_dialog_post_create</post-create-function>
-      <get-internal-child-function>glade_psppire_dialog_get_internal_child</get-internal-child-function>
+    <glade-widget-class name="PsppireDialog" 
+                       generic-name="psppire-dialog" 
+                       toplevel="True" 
+                       default-width="320"
+                       default-height="260"
+                       title="Dialog Box">
+
+     <post-create-function>glade_psppire_dialog_post_create</post-create-function>
+     <get-internal-child-function>glade_psppire_dialog_get_internal_child</get-internal-child-function>
+
+     <get-children-function>glade_psppire_dialog_get_children</get-children-function>
+
+
+     <properties>
+        <property id="accept-focus"         disabled="True" />
+        <property id="allow-grow"           disabled="True" />
+        <property id="allow-shrink"         disabled="True" />
+        <property id="decorated"            disabled="True" />
+       <property id="default-height"       disabled="True" />
+       <property id="default-width"        disabled="True" />
+       <property id="deletable"            disabled="True" />
+       <property id="destroy-with-parent"  disabled="True" />
+       <property id="focus-on-map"         disabled="True" />
+       <property id="gravity"              disabled="True" />
+       <property id="has-toplevel-focus"   disabled="True" />
+       <property id="icon"                 disabled="True" />
+       <property id="icon-name"            disabled="True" />
+       <property id="is-active"            disabled="True" />
+
+       <property id="resizable"            disabled="True" />
+       <property id="role"                 disabled="True" />
+       <property id="screen"               disabled="True" />
+       <property id="skip-pager-hint"      disabled="True" />
+       <property id="skip-taskbar-hint"    disabled="True" />
+       <property id="transient-for"        disabled="True" />
+       <property id="type"                 disabled="True" />
+       <property id="type-hint"            disabled="True" />
+       <property id="urgency-hint"         disabled="True" />
+       <property id="window-position"      disabled="True" />
+
+       <property id="child"                disabled="True" />
+        <property id="resize-mode"          disabled="True" />
+       <property id="border-width"         disabled="True" />
+
+
+       <property id="modal" ignore="True" default="True" />
+       
+    </properties>
 
-      <get-children-function>glade_psppire_dialog_get_children</get-children-function>
+    </glade-widget-class>
 
 
-      <set-property-function>glade_psppire_dialog_set_property</set-property-function>
+    <glade-widget-class name="PsppireButtonBox" generic-name="psppire-buttonbox" title="Psppire Button Box">
 
-      <properties>
-       <property optional-default="False" optional="True" id="default-width" 
-       default="0"/>
-       <property optional-default="False" optional="True" id="default-height" 
-       default="0"/>
-       <property id="has-separator" default="False"/>
+      <post-create-function>glade_psppire_button_box_post_create</post-create-function>
+      <get-children-function>glade_psppire_button_box_get_children</get-children-function>
 
-      </properties>
+      <get-internal-child-function>glade_psppire_button_box_get_internal_child</get-internal-child-function>
 
-    </glade-widget-class>
+    <properties>
+      <property id="child"                disabled="True" />
+    </properties>
 
+    <packing-defaults>
+      <parent-class name="GtkHBox">
+       <child-property id="expand" default="False"/>
+       <child-property id="fill" default="False"/>
+       <child-property id="pack-type" default="GTK_PACK_END"/>
+      </parent-class>
+    </packing-defaults>
 
-    <glade-widget-class name="PsppireButtonBox" generic-name="psppire-buttonbox" title="Psppire Button Box">
+    </glade-widget-class>
 
-          <post-create-function>glade_psppire_button_box_post_create</post-create-function>
-          <get-children-function>glade_psppire_button_box_get_children</get-children-function>
 
-      <get-internal-child-function>glade_psppire_button_box_get_internal_child</get-internal-child-function>
 
-      <set-property-function>glade_psppire_button_box_set_property</set-property-function>
+    <glade-widget-class name="PsppireKeypad" 
+                        get-type-function="psppire_keypad_get_type" 
+                       generic-name="psppire-keypad" 
+                       fixed="True"
+                       title="Keypad">
 
 
-          <packing-defaults>
-           <parent-class name="GtkHBox">
-             <child-property id="expand" default="False"/>
-             <child-property id="fill" default="False"/>
-             <child-property id="pack-type" default="GTK_PACK_END"/>
-           </parent-class>
-          </packing-defaults>
+    <properties>
+       <property id="child"       disabled="True"/>
+       <property id="homogeneous" disabled="True"/>
+       <property id="n-columns"   disabled="True"/>
+       <property id="n-rows"      disabled="True"/>
+     </properties>
+  
     </glade-widget-class>
 
 
-    <glade-widget-class name="PsppireSelector" generic-name="psppire-selector" title="Psppire Selector Button">
+    <glade-widget-class name="PsppireSelector" generic-name="psppire-selector" title="Selector Button">
 
-          <post-create-function>glade_psppire_selector_post_create</post-create-function>
-          <get-children-function>glade_psppire_selector_get_children</get-children-function>
+      <post-create-function>glade_psppire_selector_post_create</post-create-function>
+      <get-children-function>glade_psppire_selector_get_children</get-children-function>
 
       <get-internal-child-function>glade_psppire_selector_get_internal_child</get-internal-child-function>
 
-      <set-property-function>glade_psppire_selector_set_property</set-property-function>
+
+     <properties>
+       <property id="child"           disabled="True"/>
+       <property id="label"           disabled="True"/>
+        <property id="focus-on-click"  disabled="True"/>
+        <property id="image"           disabled="True"/>
+        <property id="image-position"  disabled="True"/>
+        <property id="label"           disabled="True"/>
+        <property id="relief"          disabled="True"/>
+        <property id="use-stock"       disabled="True"/>
+        <property id="use-underline"   disabled="True"/>
+        <property id="xalign"          disabled="True"/>
+        <property id="yalign"          disabled="True"/>
+        <property id="resize-mode"     disabled="True"/>
+
+       <property id="orientation">
+         <displayable-values>
+           <value id="PSPPIRE_SOURCE_BEFORE_DEST" 
+              name="Source Before Destination"></value>
+           <value id="PSPPIRE_AFTER_BEFORE_DEST"  
+              name="Source After Destination"></value>
+           <value id="PSPPIRE_ABOVE_BEFORE_DEST"  
+              name="Source Above Destination"></value>
+           <value id="PSPPIRE_BELOW_BEFORE_DEST"  
+              name="Source Below Destination"></value>
+         </displayable-values>
+       </property>
+
+     </properties>
 
     </glade-widget-class>
 
 
+
   </glade-widget-classes>
 
-  <glade-widget-group name="psppire-widgets" title="PSPPIRE Specific Widgets">
-    <glade-widget-class-ref name="PsppireDialog"/>
-    <glade-widget-class-ref name="PsppireButtonBox"/>
-    <glade-widget-class-ref name="PsppireSelector"/>
-  </glade-widget-group>
+ <glade-widget-group name="psppire" title="Psppire">
+  <glade-widget-class-ref name="PsppireDialog"/>
+  <glade-widget-class-ref name="PsppireButtonBox"/>
+  <glade-widget-class-ref name="PsppireKeypad"/>
+  <glade-widget-class-ref name="PsppireSelector"/>
+ </glade-widget-group>
 
-</glade-catalog>
 
+</glade-catalog>
index 0ac19a438fefbae5a2ad411c972989fdb6256755..f894269d2000765f1f46f61a4c2e8026f55ff793 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PSPP 0.4.2\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2007-03-25 18:00+0800\n"
+"POT-Creation-Date: 2007-03-26 18:17+0800\n"
 "PO-Revision-Date: 2006-05-26 17:49+0800\n"
 "Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
 "Language-Team: German <pspp-dev@gnu.org>\n"
@@ -4134,105 +4134,105 @@ msgstr ""
 msgid "Style of bevel around the custom entry button"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:160
+#: src/ui/gui/data-editor.c:159
 #, fuzzy
 msgid "Weights"
 msgstr "Rechts"
 
-#: src/ui/gui/data-editor.c:161
+#: src/ui/gui/data-editor.c:160
 msgid "Weight cases by variable"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:170 src/ui/gui/data-editor.glade:294
+#: src/ui/gui/data-editor.c:169 src/ui/gui/data-editor.glade:294
 msgid "Transpose"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:171
+#: src/ui/gui/data-editor.c:170
 msgid "Transpose the cases with the variables"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:495
+#: src/ui/gui/data-editor.c:494
 msgid "Font Selection"
 msgstr "Schriftwahlung"
 
-#: src/ui/gui/data-editor.c:673
+#: src/ui/gui/data-editor.c:672
 msgid "No Split"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:681
+#: src/ui/gui/data-editor.c:680
 #, fuzzy
 msgid "Split by "
 msgstr "Alle Datei"
 
-#: src/ui/gui/data-editor.c:706
+#: src/ui/gui/data-editor.c:705
 msgid "Filter off"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:719
+#: src/ui/gui/data-editor.c:718
 #, c-format
 msgid "Filter by %s"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:737
+#: src/ui/gui/data-editor.c:736
 msgid "Weights off"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:750
+#: src/ui/gui/data-editor.c:749
 #, c-format
 msgid "Weight by %s"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:773 src/ui/gui/data-editor.c:984
+#: src/ui/gui/data-editor.c:772 src/ui/gui/data-editor.c:983
 #: src/ui/gui/data-editor.glade:414
 msgid "Open"
 msgstr "Öffen"
 
-#: src/ui/gui/data-editor.c:774
+#: src/ui/gui/data-editor.c:773
 msgid "Open a data file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:782 src/ui/gui/data-editor.c:889
+#: src/ui/gui/data-editor.c:781 src/ui/gui/data-editor.c:888
 #: src/ui/gui/data-editor.glade:424
 msgid "Save"
 msgstr "Speichen"
 
-#: src/ui/gui/data-editor.c:783 src/ui/gui/data-editor.c:793
+#: src/ui/gui/data-editor.c:782 src/ui/gui/data-editor.c:792
 #, fuzzy
 msgid "Save data to file"
 msgstr "Speichern unter"
 
-#: src/ui/gui/data-editor.c:792
+#: src/ui/gui/data-editor.c:791
 #, fuzzy
 msgid "Save As"
 msgstr "Speichern unter"
 
-#: src/ui/gui/data-editor.c:801
+#: src/ui/gui/data-editor.c:800
 msgid "New"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:802
+#: src/ui/gui/data-editor.c:801
 msgid "New data file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:897 src/ui/gui/data-editor.c:992
+#: src/ui/gui/data-editor.c:896 src/ui/gui/data-editor.c:991
 msgid "System Files (*.sav)"
 msgstr "Systemedatein (*.sav)"
 
-#: src/ui/gui/data-editor.c:903 src/ui/gui/data-editor.c:998
+#: src/ui/gui/data-editor.c:902 src/ui/gui/data-editor.c:997
 msgid "Portable Files (*.por) "
 msgstr "Tragbardatein (*.por)"
 
-#: src/ui/gui/data-editor.c:909 src/ui/gui/data-editor.c:1004
-#: src/ui/gui/syntax-editor.c:141 src/ui/gui/syntax-editor.c:525
+#: src/ui/gui/data-editor.c:908 src/ui/gui/data-editor.c:1003
+#: src/ui/gui/syntax-editor.c:141 src/ui/gui/syntax-editor.c:524
 msgid "All Files"
 msgstr "Alle Datei"
 
-#: src/ui/gui/data-editor.c:917
+#: src/ui/gui/data-editor.c:916
 #, fuzzy
 msgid "System File"
 msgstr "Systemedatein (*.sav)"
 
-#: src/ui/gui/data-editor.c:922
+#: src/ui/gui/data-editor.c:921
 #, fuzzy
 msgid "Portable File"
 msgstr "Tragbardatein (*.por)"
@@ -4537,7 +4537,7 @@ msgid "Sort Order"
 msgstr ""
 
 #: src/ui/gui/dict-display.c:92 src/ui/gui/sort-cases-dialog.c:339
-#: src/ui/gui/transpose-dialog.c:124
+#: src/ui/gui/transpose-dialog.c:123
 msgid "Var"
 msgstr ""
 
@@ -4677,12 +4677,12 @@ msgstr ""
 msgid "Save Syntax"
 msgstr "Speichern unter"
 
-#: src/ui/gui/syntax-editor.c:135 src/ui/gui/syntax-editor.c:519
+#: src/ui/gui/syntax-editor.c:135 src/ui/gui/syntax-editor.c:518
 #, fuzzy
 msgid "Syntax Files (*.sps) "
 msgstr "Systemedatein (*.sav)"
 
-#: src/ui/gui/syntax-editor.c:511
+#: src/ui/gui/syntax-editor.c:510
 msgid "Open Syntax"
 msgstr ""
 
@@ -4759,22 +4759,22 @@ msgstr "Ordinalwert"
 msgid "Scale"
 msgstr "Skalwert"
 
-#: src/ui/gui/window-manager.c:139
+#: src/ui/gui/window-manager.c:141
 #, fuzzy, c-format
 msgid "Syntax%d"
 msgstr "Speichern unter"
 
-#: src/ui/gui/window-manager.c:140 src/ui/gui/window-manager.c:171
+#: src/ui/gui/window-manager.c:142 src/ui/gui/window-manager.c:173
 #, fuzzy, c-format
 msgid "%s --- PSPP Syntax Editor"
 msgstr "PSPP Dateiaufbereiter"
 
-#: src/ui/gui/window-manager.c:143
+#: src/ui/gui/window-manager.c:145
 #, fuzzy, c-format
 msgid "Untitled%d"
 msgstr "Unbetitelt"
 
-#: src/ui/gui/window-manager.c:144 src/ui/gui/window-manager.c:174
+#: src/ui/gui/window-manager.c:146 src/ui/gui/window-manager.c:176
 #, fuzzy, c-format
 msgid "%s --- PSPP Data Editor"
 msgstr "PSPP Dateiaufbereiter"
index e51a7d0c24e484e74f962422b30d1186a2967806..81f892fe26ea11470c49a95f00ebf3c24eee5823 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2007-03-25 18:00+0800\n"
+"POT-Creation-Date: 2007-03-26 18:17+0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -4128,100 +4128,100 @@ msgstr ""
 msgid "Style of bevel around the custom entry button"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:160
+#: src/ui/gui/data-editor.c:159
 msgid "Weights"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:161
+#: src/ui/gui/data-editor.c:160
 msgid "Weight cases by variable"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:170 src/ui/gui/data-editor.glade:294
+#: src/ui/gui/data-editor.c:169 src/ui/gui/data-editor.glade:294
 msgid "Transpose"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:171
+#: src/ui/gui/data-editor.c:170
 msgid "Transpose the cases with the variables"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:495
+#: src/ui/gui/data-editor.c:494
 msgid "Font Selection"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:673
+#: src/ui/gui/data-editor.c:672
 msgid "No Split"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:681
+#: src/ui/gui/data-editor.c:680
 msgid "Split by "
 msgstr ""
 
-#: src/ui/gui/data-editor.c:706
+#: src/ui/gui/data-editor.c:705
 msgid "Filter off"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:719
+#: src/ui/gui/data-editor.c:718
 #, c-format
 msgid "Filter by %s"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:737
+#: src/ui/gui/data-editor.c:736
 msgid "Weights off"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:750
+#: src/ui/gui/data-editor.c:749
 #, c-format
 msgid "Weight by %s"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:773 src/ui/gui/data-editor.c:984
+#: src/ui/gui/data-editor.c:772 src/ui/gui/data-editor.c:983
 #: src/ui/gui/data-editor.glade:414
 msgid "Open"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:774
+#: src/ui/gui/data-editor.c:773
 msgid "Open a data file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:782 src/ui/gui/data-editor.c:889
+#: src/ui/gui/data-editor.c:781 src/ui/gui/data-editor.c:888
 #: src/ui/gui/data-editor.glade:424
 msgid "Save"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:783 src/ui/gui/data-editor.c:793
+#: src/ui/gui/data-editor.c:782 src/ui/gui/data-editor.c:792
 msgid "Save data to file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:792
+#: src/ui/gui/data-editor.c:791
 msgid "Save As"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:801
+#: src/ui/gui/data-editor.c:800
 msgid "New"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:802
+#: src/ui/gui/data-editor.c:801
 msgid "New data file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:897 src/ui/gui/data-editor.c:992
+#: src/ui/gui/data-editor.c:896 src/ui/gui/data-editor.c:991
 msgid "System Files (*.sav)"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:903 src/ui/gui/data-editor.c:998
+#: src/ui/gui/data-editor.c:902 src/ui/gui/data-editor.c:997
 msgid "Portable Files (*.por) "
 msgstr ""
 
-#: src/ui/gui/data-editor.c:909 src/ui/gui/data-editor.c:1004
-#: src/ui/gui/syntax-editor.c:141 src/ui/gui/syntax-editor.c:525
+#: src/ui/gui/data-editor.c:908 src/ui/gui/data-editor.c:1003
+#: src/ui/gui/syntax-editor.c:141 src/ui/gui/syntax-editor.c:524
 msgid "All Files"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:917
+#: src/ui/gui/data-editor.c:916
 msgid "System File"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:922
+#: src/ui/gui/data-editor.c:921
 msgid "Portable File"
 msgstr ""
 
@@ -4515,7 +4515,7 @@ msgid "Sort Order"
 msgstr ""
 
 #: src/ui/gui/dict-display.c:92 src/ui/gui/sort-cases-dialog.c:339
-#: src/ui/gui/transpose-dialog.c:124
+#: src/ui/gui/transpose-dialog.c:123
 msgid "Var"
 msgstr ""
 
@@ -4649,11 +4649,11 @@ msgstr ""
 msgid "Save Syntax"
 msgstr ""
 
-#: src/ui/gui/syntax-editor.c:135 src/ui/gui/syntax-editor.c:519
+#: src/ui/gui/syntax-editor.c:135 src/ui/gui/syntax-editor.c:518
 msgid "Syntax Files (*.sps) "
 msgstr ""
 
-#: src/ui/gui/syntax-editor.c:511
+#: src/ui/gui/syntax-editor.c:510
 msgid "Open Syntax"
 msgstr ""
 
@@ -4729,22 +4729,22 @@ msgstr ""
 msgid "Scale"
 msgstr ""
 
-#: src/ui/gui/window-manager.c:139
+#: src/ui/gui/window-manager.c:141
 #, c-format
 msgid "Syntax%d"
 msgstr ""
 
-#: src/ui/gui/window-manager.c:140 src/ui/gui/window-manager.c:171
+#: src/ui/gui/window-manager.c:142 src/ui/gui/window-manager.c:173
 #, c-format
 msgid "%s --- PSPP Syntax Editor"
 msgstr ""
 
-#: src/ui/gui/window-manager.c:143
+#: src/ui/gui/window-manager.c:145
 #, c-format
 msgid "Untitled%d"
 msgstr ""
 
-#: src/ui/gui/window-manager.c:144 src/ui/gui/window-manager.c:174
+#: src/ui/gui/window-manager.c:146 src/ui/gui/window-manager.c:176
 #, c-format
 msgid "%s --- PSPP Data Editor"
 msgstr ""
index 9a4a95cea4e5f9ba96b5f1b746eba42e4fe58df9..03d6a8ee428b12ac9c8773a218772a12f8305173 100644 (file)
@@ -1,3 +1,20 @@
+2007-03-31   John Darrington <john@darrington.wattle.id.au>
+       
+       * data-editor.c: Added hooks for the split-file-dialog
+
+       * psppire.glade: Added the split file dialog box.
+       
+       * split-file-dialog.c split-file-dialog.h: New files.
+       
+       * dialog-common.c dialog-common.h: New files containing functions 
+       which seem to be used a lot in dialog box implementations. 
+
+       * psppire-keypad.c psppire-keypad.h: New files.  Implements keypad
+       thingumy widget.  
+
+       * psppire-selector.c: Made the orientation of the arrow a property
+       of the widget, so that it can be selected from glade.
+
 2007-03-18  Ben Pfaff  <blp@gnu.org>
 
        * syntax-editor-source.c (close): Rename do_close to avoid naming
index 3777672a2def0a8704e549b80e575e84064802a1..18ba45a00b5a4b2dbddf14d949bc3f4121af2951 100644 (file)
@@ -70,6 +70,8 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/data-sheet.h \
        src/ui/gui/data-editor.c \
        src/ui/gui/data-editor.h \
+       src/ui/gui/dialog-common.c \
+       src/ui/gui/dialog-common.h \
        src/ui/gui/dict-display.c \
        src/ui/gui/dict-display.h \
        src/ui/gui/flexifile-factory.h \
@@ -81,22 +83,26 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/helper.h \
        src/ui/gui/missing-val-dialog.c \
        src/ui/gui/missing-val-dialog.h \
+       src/ui/gui/psppire-buttonbox.c \
+       src/ui/gui/psppire-buttonbox.h \
        src/ui/gui/psppire-case-file.c \
        src/ui/gui/psppire-case-file.h \
        src/ui/gui/psppire-data-store.c \
        src/ui/gui/psppire-data-store.h \
-       src/ui/gui/psppire-dict.c \
-       src/ui/gui/psppire-dict.h \
        src/ui/gui/psppire-dialog.c \
        src/ui/gui/psppire-dialog.h \
-       src/ui/gui/psppire-buttonbox.c \
-       src/ui/gui/psppire-buttonbox.h \
+       src/ui/gui/psppire-dict.c \
+       src/ui/gui/psppire-dict.h \
+       src/ui/gui/psppire-keypad.c \
+       src/ui/gui/psppire-keypad.h \
        src/ui/gui/psppire-selector.c \
        src/ui/gui/psppire-selector.h \
        src/ui/gui/psppire-var-store.c \
        src/ui/gui/psppire-var-store.h \
        src/ui/gui/sort-cases-dialog.c \
        src/ui/gui/sort-cases-dialog.h \
+       src/ui/gui/split-file-dialog.c \
+       src/ui/gui/split-file-dialog.h \
        src/ui/gui/syntax-editor.c \
        src/ui/gui/syntax-editor.h \
        src/ui/gui/syntax-editor-source.c \
index c46cfa7a388a8df9f425e4f904c1d94bd8a83cef..d0433c6483c5153c57db4bbce4d7ccb8bedfca9b 100644 (file)
@@ -32,6 +32,7 @@
 #include "psppire-dialog.h"
 #include "psppire-selector.h"
 #include "weight-cases-dialog.h"
+#include "split-file-dialog.h"
 #include "transpose-dialog.h"
 #include "dict-display.h"
 
@@ -175,6 +176,18 @@ new_data_editor (void)
                    G_CALLBACK (transpose_dialog), de);
 
 
+
+  de->invoke_split_file_dialog =
+    gtk_action_new ("split-file-dialog",
+                   _("Split"),
+                   _("Split the active file"),
+                   "pspp-split-file");
+
+
+  g_signal_connect (de->invoke_split_file_dialog, "activate",
+                   G_CALLBACK (split_file_dialog), de);
+
+
   e->window = GTK_WINDOW (get_widget_assert (de->xml, "data_editor"));
 
   g_signal_connect_swapped (get_widget_assert (de->xml,"file_new_data"),
@@ -227,6 +240,11 @@ new_data_editor (void)
                            get_widget_assert (de->xml, "data_transpose")
                            );
 
+  gtk_action_connect_proxy (de->invoke_split_file_dialog,
+                           get_widget_assert (de->xml, "data_split-file")
+                           );
+
+
   g_signal_connect (get_widget_assert (de->xml,"help_about"),
                    "activate",
                    G_CALLBACK (about_new),
@@ -317,6 +335,10 @@ new_data_editor (void)
                            get_widget_assert (de->xml, "button-weight-cases")
                            );
 
+  gtk_action_connect_proxy (de->invoke_split_file_dialog,
+                           get_widget_assert (de->xml, "button-split-file")
+                           );
+
   g_signal_connect (get_widget_assert (de->xml, "file_quit"),
                    "activate",
                    G_CALLBACK (file_quit), de);
index ffca70121dc24bf39faab6fa543a0b01e2e3fb00..2d06312a9122221da22b4eccb9627c3e8f3c3e41 100644 (file)
                       </widget>
                     </child>
                     <child>
-                      <widget class="GtkMenuItem" id="split_file1">
+                      <widget class="GtkMenuItem" id="data_split-file">
                         <property name="visible">True</property>
-                        <property name="sensitive">False</property>
                         <property name="label" translatable="yes">Split File</property>
                         <property name="use_underline">True</property>
                       </widget>
                 <child>
                   <widget class="GtkToolButton" id="button-split-file">
                     <property name="visible">True</property>
-                    <property name="sensitive">False</property>
                     <property name="tooltip" translatable="yes">Split File</property>
                     <property name="use_underline">True</property>
                     <property name="stock_id">pspp-split-file</property>
index 7100e34eb87baa167bc2b238c9d5d650e5672749..e16e713bd2d2073b1e3a9c1876ff269f6d9c69ea 100644 (file)
@@ -36,6 +36,7 @@ struct data_editor
 
   GtkAction *invoke_weight_cases_dialog;
   GtkAction *invoke_transpose_dialog;
+  GtkAction *invoke_split_file_dialog;
 
   GladeXML *xml;
 
diff --git a/src/ui/gui/dialog-common.c b/src/ui/gui/dialog-common.c
new file mode 100644 (file)
index 0000000..42e2fbd
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+    PSPPIRE --- A Graphical User Interface for PSPP
+    Copyright (C) 2007  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
+    the Free Software Foundation; either version 2 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, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+*/
+
+#include <config.h>
+#include "dialog-common.h"
+
+gint
+append_variable_names (GString *string,
+                      PsppireDict *dict, GtkTreeView *treeview)
+{
+  gint n_vars = 0;
+  GtkTreeIter iter;
+
+  GtkTreeModel *list_store =
+    gtk_tree_view_get_model (treeview);
+
+  if ( gtk_tree_model_get_iter_first (list_store, &iter) )
+    {
+      do
+       {
+         GValue value = {0};
+         struct variable *var;
+         GtkTreePath *path = gtk_tree_model_get_path (list_store, &iter);
+
+         gtk_tree_model_get_value (list_store, &iter, 0, &value);
+
+         var = psppire_dict_get_variable (dict, g_value_get_int (&value));
+         g_value_unset (&value);
+
+         g_string_append (string, " ");
+         g_string_append (string, var_get_name (var));
+
+         gtk_tree_path_free (path);
+         n_vars++;
+       }
+      while (gtk_tree_model_iter_next (list_store, &iter));
+    }
+
+  return n_vars;
+}
+
+
+
+struct variable *
+get_selected_variable (GtkTreeModel *treemodel,
+                      GtkTreeIter *iter,
+                      PsppireDict *dict)
+{
+  struct variable *var;
+  GValue value = {0};
+
+  GtkTreePath *path = gtk_tree_model_get_path (treemodel, iter);
+
+  gtk_tree_model_get_value (treemodel, iter, 0, &value);
+
+  gtk_tree_path_free (path);
+
+  var =  psppire_dict_get_variable (dict, g_value_get_int (&value));
+
+  g_value_unset (&value);
+
+  return var;
+}
+
+
+
+
+/* A (*GtkTreeCellDataFunc) function.
+   This function expects TREEMODEL to hold G_TYPE_INT.  The ints it holds
+   are the indices of the variables in the dictionary, which DATA points to.
+   It renders the name of the variable into CELL.
+*/
+void
+cell_var_name (GtkTreeViewColumn *tree_column,
+              GtkCellRenderer *cell,
+              GtkTreeModel *tree_model,
+              GtkTreeIter *iter,
+              gpointer data)
+{
+  PsppireDict *dict = data;
+  struct variable *var;
+  gchar *name;
+
+  var = get_selected_variable (tree_model, iter, dict);
+
+  name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL);
+  g_object_set (cell, "text", name, NULL);
+  g_free (name);
+}
+
+
+
+/* Set a model for DEST, which is an GtkListStore of g_int's
+   whose values are the indices into DICT */
+void
+set_dest_model (GtkTreeView *dest, PsppireDict *dict)
+{
+  GtkTreeViewColumn *col;
+  GtkListStore *dest_list = gtk_list_store_new (1, G_TYPE_INT);
+  GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+
+  gtk_tree_view_set_model (GTK_TREE_VIEW (dest), GTK_TREE_MODEL (dest_list));
+
+  col = gtk_tree_view_column_new_with_attributes ("Var",
+                                                 renderer,
+                                                 "text",
+                                                 0,
+                                                 NULL);
+
+  gtk_tree_view_column_set_cell_data_func (col, renderer,
+                                          cell_var_name,
+                                          dict, 0);
+
+  /* FIXME: make this a value in terms of character widths */
+  g_object_set (col, "min-width",  100, NULL);
+
+  gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
+
+  gtk_tree_view_append_column (GTK_TREE_VIEW(dest), col);
+}
+
diff --git a/src/ui/gui/dialog-common.h b/src/ui/gui/dialog-common.h
new file mode 100644 (file)
index 0000000..d6ee950
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+    PSPPIRE --- A Graphical User Interface for PSPP
+    Copyright (C) 2007  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
+    the Free Software Foundation; either version 2 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, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA. */
+
+
+/* Some common routines used in the implementation of dialog boxes */
+
+
+#ifndef DIALOG_COMMON_H
+#define DIALOG_COMMON_H
+
+#include <gtk/gtk.h>
+#include "psppire-dict.h"
+
+/* Append the names of selected variables to STRING.
+   TREEVIEW is the treeview containing the variables.
+   DICT is the dictionary for those variables.
+*/
+gint append_variable_names (GString *, PsppireDict *, GtkTreeView *);
+
+
+/* Returns the variable currently selected by the iterator
+   pointing to TREEMODEL */
+struct variable * get_selected_variable (GtkTreeModel *treemodel,
+                                        GtkTreeIter *iter,
+                                        PsppireDict *dict);
+
+
+
+/* A (*GtkTreeCellDataFunc) function.
+   This function expects TREEMODEL to hold G_TYPE_INT.  The ints it holds
+   are the indices of the variables in the dictionary, which DATA points to.
+   It renders the name of the variable into CELL.
+*/
+void cell_var_name (GtkTreeViewColumn *tree_column,
+                   GtkCellRenderer *cell,
+                   GtkTreeModel *tree_model,
+                   GtkTreeIter *iter,
+                   gpointer data);
+
+
+/* Set a model for DEST, which is an GtkListStore of g_int's
+   whose values are the indices into DICT */
+void set_dest_model (GtkTreeView *dest, PsppireDict *dict);
+
+
+#endif
diff --git a/src/ui/gui/psppire-keypad.c b/src/ui/gui/psppire-keypad.c
new file mode 100644 (file)
index 0000000..af0e592
--- /dev/null
@@ -0,0 +1,454 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#include <gtk/gtksignal.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtklabel.h>
+#include <gdk/gdkkeysyms.h>
+#include "psppire-keypad.h"
+
+enum {
+  INSERT_SYNTAX,
+  n_SIGNALS
+};
+
+static void psppire_keypad_class_init          (PsppireKeypadClass *klass);
+static void psppire_keypad_init                (PsppireKeypad      *kp);
+
+static guint keypad_signals[n_SIGNALS] = { 0 };
+
+GType
+psppire_keypad_get_type (void)
+{
+  static GType kp_type = 0;
+
+  if (!kp_type)
+    {
+      static const GTypeInfo kp_info =
+      {
+       sizeof (PsppireKeypadClass),
+       NULL, /* base_init */
+        NULL, /* base_finalize */
+       (GClassInitFunc) psppire_keypad_class_init,
+        NULL, /* class_finalize */
+       NULL, /* class_data */
+        sizeof (PsppireKeypad),
+       0,
+       (GInstanceInitFunc) psppire_keypad_init,
+      };
+
+      kp_type = g_type_register_static (GTK_TYPE_EVENT_BOX, "PsppireKeypad",
+                                       &kp_info, 0);
+    }
+
+  return kp_type;
+}
+
+static GObjectClass * parent_class = NULL;
+
+static void
+psppire_keypad_dispose (GObject *obj)
+{
+  PsppireKeypad *kp = (PsppireKeypad *)obj;
+
+  if (kp->dispose_has_run)
+    return;
+
+  /* Make sure dispose does not run twice. */
+  kp->dispose_has_run = TRUE;
+
+  g_hash_table_unref (kp->frag_table);
+
+  /* Chain up to the parent class */
+  G_OBJECT_CLASS (parent_class)->dispose (obj);
+}
+
+static void
+psppire_keypad_finalize (GObject *obj)
+{
+   /* Chain up to the parent class */
+   G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
+psppire_keypad_class_init (PsppireKeypadClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class->dispose = psppire_keypad_dispose;
+  gobject_class->finalize = psppire_keypad_finalize;
+
+  keypad_signals[INSERT_SYNTAX] = g_signal_new ("insert-syntax",
+                                        G_TYPE_FROM_CLASS (klass),
+                                        G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                                        G_STRUCT_OFFSET (PsppireKeypadClass,
+                                                         keypad),
+                                         NULL,
+                                         NULL,
+                                        g_cclosure_marshal_VOID__STRING,
+                                         G_TYPE_NONE, 1,
+                                        G_TYPE_STRING);
+}
+
+
+/*
+   These are the strings that will be arguments to
+   the emitted signals.
+   The order of these must correspond
+   to the order of the button declarations
+*/
+static const char *keypad_insert_text[] = {
+  "0",  "1",  "2", "3", "4", "5", "6", "7", "8", "9",
+  ".", "+", "-", "*", "**", "/", "=", "<>", "<", "<=",
+  ">", ">=", "&", "|", "~", "(", ")"
+};
+
+
+/* Callback for any button click.
+   Emits the "insert-syntax" signal for the keypad,
+   with the string corresponding to the clicked button.
+*/
+static void
+button_click (GtkButton *b, PsppireKeypad *kp)
+{
+  const gchar *s = g_hash_table_lookup (kp->frag_table, b);
+
+  g_signal_emit (kp, keypad_signals [INSERT_SYNTAX], 0, s);
+}
+
+static const gint cols = 6;
+static const gint rows = 5;
+
+
+
+/* Add BUTTON to KP.  The top-left corner at X1,Y1, the
+   botton-right corner at X2,Y2 */
+static void
+add_button (PsppireKeypad *kp, GtkWidget **button,
+           gint x1, gint x2,
+           gint y1, gint y2)
+{
+  g_object_set (G_OBJECT (*button), "focus-on-click", FALSE, NULL);
+
+  gtk_table_attach_defaults (GTK_TABLE (kp->table),
+                            *button,
+                            x1, x2,
+                            y1, y2);
+
+  gtk_widget_set_size_request (*button,
+                              30 * rows / (float) cols,
+                              30 * cols / (float) rows);
+
+  g_hash_table_insert (kp->frag_table, *button,
+                      (void *) keypad_insert_text[(button - &kp->digit[0])] );
+
+  g_signal_connect (*button, "clicked",
+                   G_CALLBACK (button_click), kp);
+
+  gtk_widget_show (*button);
+}
+
+
+/* Return  a  new button with CODE as the unicode character for its label */
+static inline GtkWidget *
+button_new_from_unicode (gunichar code)
+{
+  char s[6] = {0,0,0,0,0,0};
+
+  g_unichar_to_utf8 (code, s);
+
+  return gtk_button_new_with_label (s);
+}
+
+
+/* Callback which occurs when the mouse enters the widget.
+   It sets or unsets the focus.
+*/
+static gboolean
+enter_leave_notify (GtkWidget   *widget,
+      GdkEventCrossing *event,
+      gpointer     user_data)
+{
+  /* Do nothing if we're just moving between the widget and
+     its children */
+ if (event->detail == GDK_NOTIFY_INFERIOR)
+   return FALSE;
+
+ if (event->type == GDK_ENTER_NOTIFY)
+   gtk_widget_grab_focus (widget);
+
+ if (event->type == GDK_LEAVE_NOTIFY)
+   GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
+
+ return FALSE;
+}
+
+static gboolean
+key_release_callback (GtkWidget   *widget,
+                     GdkEventKey *event,
+                     gpointer     user_data)
+{
+  if ( ! (GTK_WIDGET_FLAGS (widget) & GTK_HAS_FOCUS) )
+    return FALSE;
+
+  switch (event->keyval)
+    {
+    case '(':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "(");
+      break;
+    case ')':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, ")");
+      break;
+    case '>':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, ">");
+      break;
+    case '<':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "<");
+      break;
+    case GDK_KP_Equal :
+    case '=':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "=");
+      break;
+    case GDK_KP_Multiply :
+    case '*':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "*");
+      break;
+    case GDK_KP_Add :
+    case '+':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "+");
+      break;
+    case GDK_KP_Subtract :
+    case '-':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "-");
+      break;
+    case GDK_KP_Decimal :
+    case '.':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, ".");
+      break;
+    case GDK_KP_Divide :
+    case '/':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "/");
+      break;
+    case GDK_KP_0 :
+    case '0':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "0");
+      break;
+    case GDK_KP_1 :
+    case '1':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "1");
+      break;
+    case GDK_KP_2 :
+    case '2':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "2");
+      break;
+    case GDK_KP_3 :
+    case '3':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "3");
+      break;
+    case GDK_KP_4 :
+    case '4':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "4");
+      break;
+    case GDK_KP_5 :
+    case '5':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "5");
+      break;
+    case GDK_KP_6 :
+    case '6':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "6");
+      break;
+    case GDK_KP_7 :
+    case '7':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "7");
+      break;
+    case GDK_KP_8 :
+    case '8':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "8");
+      break;
+    case GDK_KP_9 :
+    case '9':
+      g_signal_emit (widget, keypad_signals [INSERT_SYNTAX], 0, "9");
+      break;
+     default:
+       break;
+    };
+
+  return FALSE;
+}
+
+
+static void
+psppire_keypad_init (PsppireKeypad *kp)
+{
+  gint i;
+  const int digit_voffset = 0;
+  const int digit_hoffset = 3;
+
+  GTK_WIDGET_SET_FLAGS (kp, GTK_CAN_FOCUS);
+  GTK_WIDGET_UNSET_FLAGS (kp, GTK_HAS_FOCUS);
+
+  kp->dispose_has_run = FALSE;
+
+  g_signal_connect (kp, "enter-notify-event", G_CALLBACK (enter_leave_notify),
+                   NULL);
+
+  g_signal_connect (kp, "leave-notify-event", G_CALLBACK (enter_leave_notify),
+                   NULL);
+
+  g_signal_connect (kp, "key-release-event", G_CALLBACK (key_release_callback),
+                   NULL);
+
+  kp->frag_table = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+  kp->table = gtk_table_new (rows, cols, TRUE);
+
+  /* Buttons for the digits */
+  for (i = 0; i < 10; i++)
+    {
+      int j = i - 1;
+      char buf[5];
+      snprintf (buf, 5, "%d", i);
+      kp->digit[i] = gtk_button_new_with_label (buf);
+
+      if ( i == 0 )
+       add_button (kp, &kp->digit[i],
+                   digit_hoffset + 0, digit_hoffset + 2,
+                   digit_voffset + 3, digit_voffset + 4);
+      else
+       add_button (kp, &kp->digit[i],
+                   digit_hoffset + j % 3, digit_hoffset + j % 3 + 1,
+                   digit_voffset + 2 - (j / 3),
+                   digit_voffset + 2 - (j / 3) + 1);
+    }
+
+  /* ... all the other buttons */
+
+  kp->dot = button_new_from_unicode (0xB7);     /* MIDDLE DOT */
+  add_button (kp, &kp->dot, digit_hoffset + 2,
+             digit_hoffset + 3,
+             digit_voffset + 3,
+             digit_voffset + 4);
+
+  kp->plus  = gtk_button_new_with_label ("+");
+  add_button (kp, &kp->plus, 0, 1,
+             0,1);
+
+  kp->minus = button_new_from_unicode (0x2212); /* MINUS SIGN */
+  add_button (kp, &kp->minus, 0, 1,
+             1,2);
+
+  kp->star  = button_new_from_unicode (0xD7);   /* MULTIPLICATION SIGN */
+  add_button (kp, &kp->star, 0, 1,
+             2,3);
+
+  kp->slash = button_new_from_unicode (0xF7);   /* DIVISION SIGN */
+  add_button (kp, &kp->slash, 0, 1,
+             3,4);
+
+  {
+    GtkWidget *label;
+    char *markup =
+      g_markup_printf_escaped ("<span style=\"italic\">x<sup>y</sup></span>");
+
+    label = gtk_label_new ("**");
+    gtk_label_set_markup (GTK_LABEL (label), markup);
+    g_free (markup);
+
+    kp->star_star = gtk_button_new ();
+    gtk_container_add (GTK_CONTAINER (kp->star_star), label);
+
+    add_button (kp, &kp->star_star,
+               0, 1,
+               4, 5);
+  }
+
+
+  kp->gt = button_new_from_unicode (0x3E); /* GREATER-THAN SIGN*/
+  add_button (kp, &kp->gt, 2, 3,
+             0,1);
+
+  kp->lt = button_new_from_unicode (0x3C); /* LESS-THAN SIGN*/
+  add_button (kp, &kp->lt, 1, 2,
+             0,1);
+
+  kp->ge = button_new_from_unicode (0x2265); /* GREATER-THAN OR EQUAL */
+  add_button (kp, &kp->ge, 2, 3,
+             1,2);
+
+  kp->le = button_new_from_unicode (0x2264); /* LESS-THAN OR EQUAL */
+  add_button (kp, &kp->le, 1, 2,
+             1,2);
+
+  kp->neq = button_new_from_unicode (0x2260); /* NOT EQUAL */
+  add_button (kp, &kp->neq, 2, 3,
+             2,3);
+
+  kp->eq = gtk_button_new_with_label ("=");
+  add_button (kp, &kp->eq, 1, 2,
+             2,3);
+
+  kp->parentheses = gtk_button_new_with_label ("()");
+  add_button (kp, &kp->parentheses, 2, 3,
+             4,5);
+
+
+  kp->delete = gtk_button_new_with_label ("Delete");
+  add_button (kp, &kp->delete, 3, 6,
+             4,5);
+
+
+
+  kp->and = button_new_from_unicode (0x2227); /* LOGICAL AND */
+  add_button (kp, &kp->and, 1, 2,
+             3,4);
+
+
+  kp->or = button_new_from_unicode (0x2228); /* LOGICAL OR */
+  add_button (kp, &kp->or, 2, 3,
+             3,4);
+
+
+  kp->not = button_new_from_unicode (0xAC); /* NOT SIGN */
+  add_button (kp, &kp->not, 1, 2,
+             4,5);
+
+
+
+  g_object_set (G_OBJECT (kp->table), "row-spacing", 5, NULL);
+  g_object_set (G_OBJECT (kp->table), "column-spacing", 5, NULL);
+
+  gtk_container_add (GTK_CONTAINER (kp), kp->table);
+  gtk_widget_show (kp->table);
+
+  gtk_widget_add_events (GTK_WIDGET (kp),
+       GDK_KEY_RELEASE_MASK  |
+       GDK_LEAVE_NOTIFY_MASK |
+       GDK_ENTER_NOTIFY_MASK |
+        GDK_FOCUS_CHANGE_MASK);
+
+}
+
+
+GtkWidget*
+psppire_keypad_new (void)
+{
+  return GTK_WIDGET (g_object_new (psppire_keypad_get_type (), NULL));
+}
diff --git a/src/ui/gui/psppire-keypad.h b/src/ui/gui/psppire-keypad.h
new file mode 100644 (file)
index 0000000..340696c
--- /dev/null
@@ -0,0 +1,117 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+/*
+ This module implements a keypad widget, similar to that dipicted
+ below:
+
+ +---+---+---+---+---+
+ |                  |
+ | +   <   7   8   9 |
+ +                  +
+ |                  |
+ | -   >   4   5   6 |
+ +                  +
+ |                  |
+ | *  <=   1   2   3 |
+ +                  +
+ |                          |
+ | /  >=     0            . |
+ +                  +
+ | y  !=   =   (   ) |
+ |x                 |
+ +---+---+---+---+---+
+
+ It's intended for dialog boxes which produce PSPP syntax.  Thus,
+ a "insert-syntax" signal is emitted whenever a key is clicked.
+ The signal supports the following callback:
+
+ void insert_syntax (Keypad *kp, const char *syntax, gpointer user_data);
+
+*/
+
+#ifndef __PSPPIRE_KEYPAD_H__
+#define __PSPPIRE_KEYPAD_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkeventbox.h>
+
+
+G_BEGIN_DECLS
+
+#define PSPPIRE_KEYPAD_TYPE            (psppire_keypad_get_type ())
+#define PSPPIRE_KEYPAD(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_KEYPAD_TYPE, Psppire_Keypad))
+#define PSPPIRE_KEYPAD_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PSPPIRE_KEYPAD_TYPE, Psppire_KeypadClass))
+#define PSPPIRE_IS_KEYPAD(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_KEYPAD_TYPE))
+#define PSPPIRE_IS_KEYPAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_KEYPAD_TYPE))
+
+
+typedef struct _PsppireKeypad       PsppireKeypad;
+typedef struct _PsppireKeypadClass  PsppireKeypadClass;
+
+/* All members are private. */
+struct _PsppireKeypad
+{
+  GtkEventBox parent;
+
+  /* Hash of syntax fragments indexed by pointer to widget (button) */
+  GHashTable *frag_table;
+  GtkWidget *table;
+
+  /* The order of everything here is important */
+  GtkWidget *digit[10];
+  GtkWidget *dot;
+  GtkWidget *plus;
+  GtkWidget *minus;
+  GtkWidget *star;
+  GtkWidget *star_star;
+  GtkWidget *slash;
+  GtkWidget *eq;
+  GtkWidget *neq;
+  GtkWidget *lt;
+  GtkWidget *le;
+  GtkWidget *gt;
+  GtkWidget *ge;
+  GtkWidget *and;
+  GtkWidget *or;
+  GtkWidget *not;
+
+
+  GtkWidget *parentheses;
+  GtkWidget *delete;
+
+
+  gboolean dispose_has_run;
+};
+
+
+struct _PsppireKeypadClass
+{
+  GtkTableClass parent_class;
+  void (*keypad)(PsppireKeypad*);
+};
+
+
+GType          psppire_keypad_get_type        (void);
+GtkWidget*     psppire_keypad_new             (void);
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_KEYPAD_H__ */
index 453fee8ca006d8aba5d1db4b928da0cef973d46a..68d8270db805f83193637485b581b4bb3e7b0ee4 100644 (file)
@@ -75,6 +75,10 @@ static void psppire_selector_base_init     (PsppireSelectorClass *class);
 static void psppire_selector_class_init    (PsppireSelectorClass *class);
 static void psppire_selector_init          (PsppireSelector      *selector);
 
+
+static void set_direction (PsppireSelector *, enum psppire_selector_dir);
+
+
 enum  {SELECTED,    /* Emitted when an item is inserted into dest */
        DE_SELECTED, /* Emitted when an item is removed from dest */
        n_SIGNALS};
@@ -116,11 +120,76 @@ psppire_selector_finalize (GObject *object)
 {
 }
 
+/* Properties */
+enum
+{
+  PROP_0,
+  PROP_ORIENTATION
+};
+
+
+static void
+psppire_selector_set_property (GObject         *object,
+                              guint            prop_id,
+                              const GValue    *value,
+                              GParamSpec      *pspec)
+{
+  PsppireSelector *selector = PSPPIRE_SELECTOR (object);
+
+  switch (prop_id)
+    {
+    case PROP_ORIENTATION:
+      selector->orientation = g_value_get_enum (value);
+      set_direction (selector, selector->direction);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    };
+}
+
+
+static void
+psppire_selector_get_property (GObject         *object,
+                              guint            prop_id,
+                              GValue          *value,
+                              GParamSpec      *pspec)
+{
+  PsppireSelector *selector = PSPPIRE_SELECTOR (object);
+
+  switch (prop_id)
+    {
+    case PROP_ORIENTATION:
+      g_value_set_enum (value, selector->orientation);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    };
+}
+
 
 
 static void
 psppire_selector_class_init (PsppireSelectorClass *class)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  GParamSpec *orientation_spec =
+    g_param_spec_enum ("orientation",
+                      "Orientation",
+                      "Where the selector is relative to its subjects",
+                      G_TYPE_PSPPIRE_SELECTOR_ORIENTATION,
+                      PSPPIRE_SELECT_SOURCE_BEFORE_DEST /* default value */,
+                      G_PARAM_CONSTRUCT_ONLY |G_PARAM_READWRITE);
+
+
+  object_class->set_property = psppire_selector_set_property;
+  object_class->get_property = psppire_selector_get_property;
+
+  g_object_class_install_property (object_class,
+                                   PROP_ORIENTATION,
+                                   orientation_spec);
+
   signals [SELECTED] =
     g_signal_new ("selected",
                  G_TYPE_FROM_CLASS (class),
@@ -140,8 +209,6 @@ psppire_selector_class_init (PsppireSelectorClass *class)
                  g_cclosure_marshal_VOID__VOID,
                  G_TYPE_NONE,
                  0);
-
-
 }
 
 
@@ -196,9 +263,48 @@ set_direction (PsppireSelector *selector, enum psppire_selector_dir d)
   /* FIXME: Need to reverse the arrow direction if an RTL locale is in
      effect */
   if ( d == PSPPIRE_SELECTOR_SOURCE_TO_DEST )
-    g_object_set (selector->arrow, "arrow-type", GTK_ARROW_RIGHT, NULL);
+    {
+      switch (selector->orientation)
+       {
+       case   PSPPIRE_SELECT_SOURCE_BEFORE_DEST:
+         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_RIGHT, NULL);
+         break;
+       case   PSPPIRE_SELECT_SOURCE_AFTER_DEST:
+         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_LEFT, NULL);
+         break;
+       case   PSPPIRE_SELECT_SOURCE_ABOVE_DEST:
+         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_DOWN, NULL);
+         break;
+       case   PSPPIRE_SELECT_SOURCE_BELOW_DEST:
+         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_UP, NULL);
+         break;
+       default:
+         g_assert_not_reached ();
+         break;
+       };
+    }
   else
-    g_object_set (selector->arrow, "arrow-type", GTK_ARROW_LEFT, NULL);
+    {
+      switch (selector->orientation)
+       {
+       case   PSPPIRE_SELECT_SOURCE_BEFORE_DEST:
+         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_LEFT, NULL);
+         break;
+       case   PSPPIRE_SELECT_SOURCE_AFTER_DEST:
+         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_RIGHT, NULL);
+         break;
+       case   PSPPIRE_SELECT_SOURCE_ABOVE_DEST:
+         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_UP, NULL);
+         break;
+       case   PSPPIRE_SELECT_SOURCE_BELOW_DEST:
+         g_object_set (selector->arrow, "arrow-type", GTK_ARROW_DOWN, NULL);
+         break;
+       default:
+         g_assert_not_reached ();
+         break;
+       };
+
+    }
 }
 
 /* Callback for when the source selection changes */
@@ -597,3 +703,22 @@ psppire_selector_set_subjects (PsppireSelector *selector,
 
   selector->select_items = select_func;
 }
+
+
+
+GType
+psppire_selector_orientation_get_type (void)
+{
+  static GType etype = 0;
+  if (etype == 0) {
+    static const GEnumValue values[] = {
+      { PSPPIRE_SELECT_SOURCE_BEFORE_DEST, "PSPPIRE_SELECT_SOURCE_BEFORE_DEST", "source before destination" },
+      { PSPPIRE_SELECT_SOURCE_AFTER_DEST, "PSPPIRE_SELECT_SOURCE_AFTER_DEST", "source after destination" },
+      { PSPPIRE_SELECT_SOURCE_ABOVE_DEST, "PSPPIRE_SELECT_SOURCE_ABOVE_DEST", "source above destination" },
+      { PSPPIRE_SELECT_SOURCE_BELOW_DEST, "PSPPIRE_SELECT_SOURCE_BELOW_DEST", "source below destination" },
+      { 0, NULL, NULL }
+    };
+    etype = g_enum_register_static (g_intern_static_string ("PsppireSelectorOrientation"), values);
+  }
+  return etype;
+}
index 7ba88a96af881c9bdc96328840a892e78d1cc7a4..072139107ccc7325aeef48fb5210e6b2554964ff 100644 (file)
@@ -80,6 +80,8 @@ struct _PsppireSelector
   GtkWidget *dest;
 
 
+  gint orientation;
+
   GtkTreeModelFilter *filtered_source;
 
   SelectItemsFunc *select_items;
@@ -102,6 +104,22 @@ void       psppire_selector_set_subjects    (PsppireSelector *,
                                             GtkWidget *,
                                             SelectItemsFunc *,
                                             FilterItemsFunc * );
+
+GType psppire_selector_orientation_get_type (void) G_GNUC_CONST;
+
+
+typedef enum {
+  PSPPIRE_SELECT_SOURCE_BEFORE_DEST,
+  PSPPIRE_SELECT_SOURCE_AFTER_DEST,
+  PSPPIRE_SELECT_SOURCE_ABOVE_DEST,
+  PSPPIRE_SELECT_SOURCE_BELOW_DEST
+} PsppireSelectorOrientation;
+
+#define G_TYPE_PSPPIRE_SELECTOR_ORIENTATION \
+  (psppire_selector_orientation_get_type())
+
+
+
 G_END_DECLS
 
 #endif /* __PSPPIRE_SELECTOR_H__ */
index 0a4e6dfab3fec7619a0092371b298181d41fe393..356d02ff03eb1af62eb1c182999c86e8b5989828 100644 (file)
@@ -4,6 +4,8 @@
 <glade-interface>
   <requires lib="psppire"/>
   <widget class="GtkAboutDialog" id="aboutdialog1">
+    <property name="modal">True</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
     <property name="name">PSPPire</property>
     <property name="copyright">Free Software Foundation</property>
     <property name="comments" translatable="yes">This is pre-alpha software.  Use at your own risk.</property>
     </child>
   </widget>
   <widget class="PsppireDialog" id="weight-cases-dialog">
-    <property name="border_width">5</property>
-    <property name="title">Weight Case</property>
-    <property name="default_width">363</property>
-    <property name="default_height">188</property>
+    <property name="title">Weight Cases</property>
+    <property name="modal">True</property>
     <child internal-child="hbox">
       <widget class="GtkHBox" id="dialog-hbox1">
         <property name="visible">True</property>
@@ -84,8 +84,7 @@
                         <property name="visible">True</property>
                         <property name="border_width">5</property>
                         <child>
-                          <widget class="GtkRadioButton" 
-                               id="weight-cases-radiobutton1">
+                          <widget class="GtkRadioButton" id="weight-cases-radiobutton1">
                             <property name="visible">True</property>
                             <property name="label" translatable="yes">Do not weight cases</property>
                             <property name="focus_on_click">False</property>
     </child>
   </widget>
   <widget class="PsppireDialog" id="transpose-dialog">
-    <property name="border_width">5</property>
-    <property name="title">Transpose</property>
-    <property name="default_width">407</property>
-    <property name="default_height">225</property>
+    <property name="modal">True</property>
     <child internal-child="hbox">
       <widget class="GtkHBox" id="dialog-hbox2">
         <property name="visible">True</property>
       </widget>
     </child>
   </widget>
+  <widget class="PsppireDialog" id="split-file-dialog">
+    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+    <property name="title">Split File</property>
+    <property name="modal">True</property>
+    <child internal-child="hbox">
+      <widget class="GtkHBox" id="dialog-hbox3">
+        <property name="visible">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="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="vbox6">
+            <property name="visible">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <child>
+              <widget class="GtkHBox" id="hbox5">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <child>
+                  <widget class="GtkFrame" id="frame5">
+                    <property name="visible">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="label_xalign">0</property>
+                    <property name="shadow_type">GTK_SHADOW_IN</property>
+                    <child>
+                      <widget class="GtkScrolledWindow" id="scrolledwindow3">
+                        <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="hscrollbar_policy">GTK_POLICY_NEVER</property>
+                        <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <child>
+                          <widget class="GtkTreeView" id="split-file-dict-treeview">
+                            <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="headers_visible">False</property>
+                            <property name="fixed_height_mode">True</property>
+                            <property name="show_expanders">False</property>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <placeholder/>
+                      <packing>
+                        <property name="type">label_item</property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkVBox" id="vbox7">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <child>
+                      <widget class="GtkVButtonBox" id="vbuttonbox2">
+                        <property name="visible">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="layout_style">GTK_BUTTONBOX_SPREAD</property>
+                        <child>
+                          <widget class="GtkRadioButton" id="split-radiobutton0">
+                            <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="label" translatable="yes">Analyse all cases.  Do not create groups.</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkRadioButton" id="split-radiobutton1">
+                            <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="label" translatable="yes">Compare groups.</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">split-radiobutton0</property>
+                          </widget>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkRadioButton" id="split-radiobutton2">
+                            <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="label" translatable="yes">Organise output by groups.</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">split-radiobutton0</property>
+                          </widget>
+                          <packing>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkHBox" id="hbox6">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <child>
+                          <widget class="GtkAlignment" id="alignment1">
+                            <property name="visible">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="yscale">0.5</property>
+                            <child>
+                              <widget class="PsppireSelector" id="split-file-selector">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">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="border_width">5</property>
+                              </widget>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="padding">18</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkVBox" id="vbox8">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <child>
+                              <widget class="GtkLabel" id="label5">
+                                <property name="visible">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="xalign">0</property>
+                                <property name="label" translatable="yes">Groups based on:</property>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkFrame" id="frame4">
+                                <property name="visible">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="label_xalign">0</property>
+                                <property name="label_yalign">0</property>
+                                <property name="shadow_type">GTK_SHADOW_IN</property>
+                                <child>
+                                  <widget class="GtkScrolledWindow" id="scrolledwindow4">
+                                    <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="hscrollbar_policy">GTK_POLICY_NEVER</property>
+                                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                                    <child>
+                                      <widget class="GtkTreeView" id="split-file-grouping-vars">
+                                        <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="headers_visible">False</property>
+                                        <property name="fixed_height_mode">True</property>
+                                        <property name="show_expanders">False</property>
+                                      </widget>
+                                    </child>
+                                  </widget>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                  <packing>
+                                    <property name="type">label_item</property>
+                                  </packing>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkVButtonBox" id="vbuttonbox1">
+                        <property name="visible">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="homogeneous">True</property>
+                        <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
+                        <child>
+                          <widget class="GtkRadioButton" id="split-radiobutton3">
+                            <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="label" translatable="yes">Sort the file by grouping variables.</property>
+                            <property name="use_underline">True</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkRadioButton" id="split-radiobutton4">
+                            <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="label" translatable="yes">File is already sorted.</property>
+                            <property name="use_underline">True</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">split-radiobutton3</property>
+                          </widget>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="padding">5</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkHSeparator" id="hseparator1">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox7">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <child>
+                  <widget class="GtkLabel" id="label6">
+                    <property name="visible">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="xalign">1</property>
+                    <property name="label" translatable="yes">Current Status : </property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label7">
+                    <property name="visible">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="xalign">0</property>
+                    <property name="label" translatable="yes">Analysis by groups is off</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </widget>
+        </child>
+        <child>
+          <widget class="PsppireButtonBox" id="psppire-buttonbox3">
+            <property name="visible">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="border_width">5</property>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+  <widget class="GtkWindow" id="window1">
+    <property name="visible">True</property>
+    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+    <child>
+      <widget class="GtkVBox" id="vbox9">
+        <property name="visible">True</property>
+        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+        <child>
+          <widget class="GtkHBox" id="hbox8">
+            <property name="visible">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="spacing">5</property>
+            <child>
+              <widget class="GtkFrame" id="frame7">
+                <property name="visible">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="label_xalign">0</property>
+                <property name="shadow_type">GTK_SHADOW_IN</property>
+                <child>
+                  <widget class="GtkScrolledWindow" id="scrolledwindow5">
+                    <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="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <child>
+                      <widget class="GtkTreeView" id="treeview1">
+                        <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="headers_visible">False</property>
+                        <property name="fixed_height_mode">True</property>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <placeholder/>
+                  <packing>
+                    <property name="type">label_item</property>
+                  </packing>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox10">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <child>
+                  <widget class="GtkFrame" id="Select">
+                    <property name="visible">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="label_xalign">0</property>
+                    <child>
+                      <widget class="GtkAlignment" id="alignment3">
+                        <property name="visible">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="left_padding">12</property>
+                        <child>
+                          <widget class="GtkVButtonBox" id="vbuttonbox3">
+                            <property name="visible">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="layout_style">GTK_BUTTONBOX_SPREAD</property>
+                            <child>
+                              <widget class="GtkRadioButton" id="radiobutton1">
+                                <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="label" translatable="yes">All Cases</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                              </widget>
+                            </child>
+                            <child>
+                              <widget class="GtkRadioButton" id="radiobutton3">
+                                <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="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <property name="group">radiobutton1</property>
+                                <child>
+                                  <widget class="GtkVBox" id="vbox11">
+                                    <property name="visible">True</property>
+                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                    <child>
+                                      <widget class="GtkLabel" id="label9">
+                                        <property name="visible">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="label" translatable="yes">If condition is satisfied</property>
+                                      </widget>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkHBox" id="hbox9">
+                                        <property name="visible">True</property>
+                                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                        <child>
+                                          <widget class="GtkAlignment" id="alignment4">
+                                            <property name="visible">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="xalign">0</property>
+                                            <property name="xscale">0</property>
+                                            <child>
+                                              <widget class="GtkButton" id="button1">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">True</property>
+                                                <property name="receives_default">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="label" translatable="yes">If...</property>
+                                              </widget>
+                                            </child>
+                                          </widget>
+                                        </child>
+                                      </widget>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">False</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </widget>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkRadioButton" id="radiobutton4">
+                                <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="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <property name="group">radiobutton1</property>
+                                <child>
+                                  <widget class="GtkVBox" id="vbox13">
+                                    <property name="visible">True</property>
+                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                    <child>
+                                      <widget class="GtkLabel" id="label10">
+                                        <property name="visible">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="xalign">0</property>
+                                        <property name="label" translatable="yes">Random Sample of cases</property>
+                                      </widget>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkHBox" id="hbox10">
+                                        <property name="visible">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="spacing">5</property>
+                                        <child>
+                                          <widget class="GtkButton" id="button2">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">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="label" translatable="yes">Sample...</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">False</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <widget class="GtkLabel" id="label11">
+                                            <property name="visible">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="label" translatable="yes">Approximately 23% of cases</property>
+                                            <property name="single_line_mode">True</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </widget>
+                                      <packing>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </widget>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkRadioButton" id="radiobutton7">
+                                <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="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <property name="group">radiobutton1</property>
+                                <child>
+                                  <widget class="GtkVBox" id="vbox14">
+                                    <property name="visible">True</property>
+                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                    <child>
+                                      <widget class="GtkLabel" id="label12">
+                                        <property name="visible">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="label" translatable="yes">Based on time or case range</property>
+                                      </widget>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkHBox" id="hbox11">
+                                        <property name="visible">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="spacing">5</property>
+                                        <child>
+                                          <widget class="GtkButton" id="button3">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">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="label" translatable="yes">Range...</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">False</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <widget class="GtkLabel" id="label13">
+                                            <property name="visible">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="label" translatable="yes">2 thru 3</property>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </widget>
+                                      <packing>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </widget>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="position">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkRadioButton" id="radiobutton8">
+                                <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="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <property name="group">radiobutton1</property>
+                                <child>
+                                  <widget class="GtkVBox" id="vbox15">
+                                    <property name="visible">True</property>
+                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                    <child>
+                                      <widget class="GtkLabel" id="label14">
+                                        <property name="visible">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="xalign">0</property>
+                                        <property name="label" translatable="yes">Use filter variable</property>
+                                      </widget>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkHBox" id="hbox12">
+                                        <property name="visible">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="spacing">5</property>
+                                        <child>
+                                          <widget class="PsppireSelector" id="psppire-selector1">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">True</property>
+                                            <property name="style"></property>
+                                            <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">5</property>
+                                          </widget>
+                                        </child>
+                                        <child>
+                                          <widget class="GtkEntry" id="entry1">
+                                            <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>
+                                          </widget>
+                                          <packing>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </widget>
+                                      <packing>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </widget>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="position">4</property>
+                              </packing>
+                            </child>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="Select">
+                        <property name="visible">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="label" translatable="yes">Select</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="type">label_item</property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkFrame" id="frame6">
+                    <property name="visible">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="label_xalign">0</property>
+                    <child>
+                      <widget class="GtkAlignment" id="alignment2">
+                        <property name="visible">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="left_padding">12</property>
+                        <child>
+                          <widget class="GtkHButtonBox" id="hbuttonbox1">
+                            <property name="visible">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="layout_style">GTK_BUTTONBOX_SPREAD</property>
+                            <child>
+                              <widget class="GtkRadioButton" id="radiobutton5">
+                                <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="label" translatable="yes">Filtered</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                              </widget>
+                            </child>
+                            <child>
+                              <widget class="GtkRadioButton" id="radiobutton6">
+                                <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="label" translatable="yes">Deleted</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <property name="group">radiobutton5</property>
+                              </widget>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label8">
+                        <property name="visible">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="label" translatable="yes">Unselected Cases Are</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="type">label_item</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+        </child>
+        <child>
+          <widget class="GtkHBox" id="hbox13">
+            <property name="visible">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <child>
+              <widget class="GtkLabel" id="label15">
+                <property name="visible">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="xalign">1</property>
+                <property name="label" translatable="yes">Curent Status : </property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label16">
+                <property name="visible">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="xalign">0</property>
+                <property name="label" translatable="yes">Do not filter cases</property>
+              </widget>
+              <packing>
+                <property name="pack_type">GTK_PACK_END</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkHButtonBox" id="hbuttonbox2">
+            <property name="visible">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="layout_style">GTK_BUTTONBOX_SPREAD</property>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
 </glade-interface>
diff --git a/src/ui/gui/split-file-dialog.c b/src/ui/gui/split-file-dialog.c
new file mode 100644 (file)
index 0000000..35aaf70
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+    PSPPIRE --- A Graphical User Interface for PSPP
+    Copyright (C) 2007  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
+    the Free Software Foundation; either version 2 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, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA. */
+
+#include <config.h>
+
+#include "split-file-dialog.h"
+#include "psppire-selector.h"
+#include "psppire-dialog.h"
+#include "helper.h"
+#include "data-editor.h"
+#include "dict-display.h"
+#include <language/syntax-string-source.h>
+#include "syntax-editor.h"
+
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+
+#include "dialog-common.h"
+
+/* FIXME: These shouldn't be here */
+#include <gtksheet/gtksheet.h>
+#include "psppire-var-store.h"
+
+
+
+static gchar *
+generate_syntax (GladeXML *xml, PsppireDict *dict)
+{
+  gchar *text;
+  GtkWidget *off = get_widget_assert (xml, "split-radiobutton0");
+
+  GtkWidget *vars =
+    get_widget_assert (xml, "split-file-grouping-vars");
+
+  GString *string = g_string_new ("SPLIT FILE OFF.");
+
+  if ( ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (off)))
+    {
+      GString * varlist = g_string_sized_new (80);
+      GtkWidget *sort = get_widget_assert (xml, "split-radiobutton3");
+      GtkWidget *layered = get_widget_assert (xml, "split-radiobutton1");
+      gint n_vars = append_variable_names (varlist,
+                                          dict, GTK_TREE_VIEW (vars));
+
+      if ( n_vars > 0 )
+       {
+         g_string_assign (string, "");
+
+         if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(sort)))
+           {
+             g_string_append (string, "SORT CASES BY");
+             g_string_append (string, varlist->str);
+             g_string_append (string, ".\n");
+           }
+
+         g_string_append (string, "SPLIT FILE ");
+
+         if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (layered)))
+           g_string_append (string, "LAYERED ");
+         else
+           g_string_append (string, "SEPARATE ");
+
+         g_string_append (string, "BY ");
+         g_string_append (string, varlist->str);
+         g_string_append (string, ".");
+       }
+      g_string_free (varlist, TRUE);
+    }
+
+  text =  string->str;
+
+  g_string_free (string, FALSE);
+
+  return text;
+};
+
+
+static void
+on_off_toggled (GtkToggleButton *togglebutton,
+               gpointer         user_data)
+{
+  GladeXML *xml = user_data;
+  GtkWidget *dest =   get_widget_assert (xml, "split-file-grouping-vars");
+  GtkWidget *selector = get_widget_assert (xml, "split-file-selector");
+  GtkWidget *source = get_widget_assert (xml, "split-file-dict-treeview");
+  GtkWidget *button3 = get_widget_assert (xml, "split-radiobutton3");
+  GtkWidget *button4 = get_widget_assert (xml, "split-radiobutton4");
+
+  gboolean state = !gtk_toggle_button_get_active (togglebutton);
+
+  gtk_widget_set_sensitive (dest, state);
+  gtk_widget_set_sensitive (selector, state);
+  gtk_widget_set_sensitive (source, state);
+  gtk_widget_set_sensitive (button3, state);
+  gtk_widget_set_sensitive (button4, state);
+}
+
+static void
+refresh (GladeXML *xml)
+{
+  GtkWidget *off = get_widget_assert (xml, "split-radiobutton0");
+
+  g_print ("%s\n", __FUNCTION__);
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(off), TRUE);
+  gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON(off));
+}
+
+
+
+/* Pops up the Weight Cases dialog box */
+void
+split_file_dialog (GObject *o, gpointer data)
+{
+  gint response;
+  struct data_editor *de = data;
+  PsppireDict *dict;
+
+  GladeXML *xml = XML_NEW ("psppire.glade");
+
+  GtkWidget *dialog = get_widget_assert   (xml, "split-file-dialog");
+  GtkWidget *source = get_widget_assert   (xml, "split-file-dict-treeview");
+  GtkWidget *dest =   get_widget_assert   (xml, "split-file-grouping-vars");
+  GtkWidget *selector = get_widget_assert (xml, "split-file-selector");
+  GtkWidget *on_off = get_widget_assert   (xml, "split-radiobutton0");
+
+  GtkSheet *var_sheet =
+    GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
+
+  PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet));
+
+  dict = vs->dict;
+
+  attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
+                                vs->dict,
+                                GTK_SELECTION_MULTIPLE, NULL);
+
+
+  g_signal_connect (on_off, "toggled", G_CALLBACK(on_off_toggled),  xml);
+
+
+  set_dest_model (GTK_TREE_VIEW (dest), vs->dict);
+
+  psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector),
+                                source,
+                                dest,
+                                insert_source_row_into_tree_view,
+                                NULL);
+
+  refresh (xml);
+
+  response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
+
+
+  switch (response)
+    {
+    case GTK_RESPONSE_OK:
+      {
+       gchar *syntax = generate_syntax (xml, dict);
+       struct getl_interface *sss = create_syntax_string_source (syntax);
+       execute_syntax (sss);
+
+       g_free (syntax);
+      }
+      break;
+    case PSPPIRE_RESPONSE_PASTE:
+      {
+       gchar *syntax = generate_syntax (xml, dict);
+
+       struct syntax_editor *se =
+         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
+
+       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+
+       g_free (syntax);
+      }
+      break;
+    default:
+      break;
+    }
+
+  g_object_unref (xml);
+}
+
diff --git a/src/ui/gui/split-file-dialog.h b/src/ui/gui/split-file-dialog.h
new file mode 100644 (file)
index 0000000..72e1a19
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+    PSPPIRE --- A Graphical User Interface for PSPP
+    Copyright (C) 2007  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
+    the Free Software Foundation; either version 2 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, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA. */
+
+
+#ifndef SPLIT_FILE_DIALOG_H
+#define SPLIT_FILE_DIALOG_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+/* Pops up the Split File dialog box */
+void split_file_dialog (GObject *o, gpointer data);
+
+
+#endif
index 4a89ace5f65920089a8c2fbd56730dd324ffb8bc..14c1b3a208f81e72318ed7bcfad3b641d8a3b37e 100644 (file)
@@ -28,6 +28,8 @@
 #include <language/syntax-string-source.h>
 #include "syntax-editor.h"
 
+#include "dialog-common.h"
+
 #include <gtk/gtk.h>
 #include <glade/glade.h>
 
 #include "psppire-var-store.h"
 
 
-
-static struct variable *
-get_selected_variable (GtkTreeModel *treemodel,
-                      GtkTreeIter *iter,
-                      PsppireDict *dict)
-{
-  struct variable *var;
-  GValue value = {0};
-
-  GtkTreePath *path = gtk_tree_model_get_path (treemodel, iter);
-
-  gtk_tree_model_get_value (treemodel, iter, 0, &value);
-
-  gtk_tree_path_free (path);
-
-  var =  psppire_dict_get_variable (dict, g_value_get_int (&value));
-
-  g_value_unset (&value);
-
-  return var;
-}
-
-
-/* A (*GtkTreeCellDataFunc) function.
-   This function expects TREEMODEL to hold G_TYPE_INT.  The ints it holds
-   are the indices of the variables in the dictionary, which DATA points to.
-   It renders the name of the variable into CELL.
-*/
-static void
-cell_var_name (GtkTreeViewColumn *tree_column,
-              GtkCellRenderer *cell,
-              GtkTreeModel *tree_model,
-              GtkTreeIter *iter,
-              gpointer data)
-{
-  PsppireDict *dict = data;
-  struct variable *var;
-  gchar *name;
-
-  var = get_selected_variable (tree_model, iter, dict);
-
-  name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL);
-  g_object_set (cell, "text", name, NULL);
-  g_free (name);
-}
-
 static gchar * generate_syntax (PsppireDict *dict, GladeXML *xml);
 
 void
@@ -113,31 +69,8 @@ transpose_dialog (GObject *o, gpointer data)
   attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
                                 vs->dict,
                                 GTK_SELECTION_MULTIPLE, NULL);
-  {
-    GtkTreeViewColumn *col;
-    GtkListStore *dest_list = gtk_list_store_new (1, G_TYPE_INT);
-    GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
-
-    gtk_tree_view_set_model (GTK_TREE_VIEW (dest), GTK_TREE_MODEL (dest_list));
-
-    col = gtk_tree_view_column_new_with_attributes (_("Var"),
-                                                   renderer,
-                                                   "text",
-                                                   0,
-                                                   NULL);
-
-    gtk_tree_view_column_set_cell_data_func (col, renderer,
-                                            cell_var_name,
-                                            vs->dict, 0);
-
-    /* FIXME: make this a value in terms of character widths */
-    g_object_set (col, "min-width",  100, NULL);
-
-    gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
-
-    gtk_tree_view_append_column (GTK_TREE_VIEW(dest), col);
-  }
 
+  set_dest_model (GTK_TREE_VIEW (dest), vs->dict);
 
   psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector1),
                                 source, dest,
@@ -190,7 +123,6 @@ transpose_dialog (GObject *o, gpointer data)
 static gchar *
 generate_syntax (PsppireDict *dict, GladeXML *xml)
 {
-  GtkTreeIter iter;
   const gchar *text;
   GString *string = g_string_new ("FLIP");
   gchar *syntax ;
@@ -198,29 +130,9 @@ generate_syntax (PsppireDict *dict, GladeXML *xml)
   GtkWidget *dest = get_widget_assert (xml, "variables-treeview");
   GtkWidget *entry = get_widget_assert (xml, "new-name-entry");
 
-  GtkTreeModel *list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (dest));
-
-  if ( gtk_tree_model_get_iter_first (list_store, &iter) )
-    {
-      g_string_append (string, " /VARIABLES =");
-      do
-       {
-         GValue value = {0};
-         struct variable *var;
-         GtkTreePath *path = gtk_tree_model_get_path (list_store, &iter);
-
-         gtk_tree_model_get_value (list_store, &iter, 0, &value);
+  g_string_append (string, " /VARIABLES = ");
 
-         var = psppire_dict_get_variable (dict, g_value_get_int (&value));
-         g_value_unset (&value);
-
-         g_string_append (string, " ");
-         g_string_append (string, var_get_name (var));
-
-         gtk_tree_path_free (path);
-       }
-      while (gtk_tree_model_iter_next (list_store, &iter));
-    }
+  append_variable_names (string, dict, GTK_TREE_VIEW (dest));
 
   text = gtk_entry_get_text (GTK_ENTRY (entry));