Added custom psppire-selector widget.
authorJohn Darrington <john@darrington.wattle.id.au>
Fri, 26 Jan 2007 07:35:02 +0000 (07:35 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Fri, 26 Jan 2007 07:35:02 +0000 (07:35 +0000)
Added Transpose Dialog.
Reimplemented Weight Cases dialog.

29 files changed:
glade.patch
glade/automake.mk
glade/psppire.xml
glade/selector.c [new file with mode: 0644]
src/data/dictionary.c
src/data/variable.h
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/dict-display.c [new file with mode: 0644]
src/ui/gui/dict-display.h [new file with mode: 0644]
src/ui/gui/glade-register.c
src/ui/gui/helper.c
src/ui/gui/psppire-case-file.c
src/ui/gui/psppire-dict.c
src/ui/gui/psppire-dict.h
src/ui/gui/psppire-object.c [deleted file]
src/ui/gui/psppire-object.h [deleted file]
src/ui/gui/psppire-selector.c [new file with mode: 0644]
src/ui/gui/psppire-selector.h [new file with mode: 0644]
src/ui/gui/psppire-var-select.c [deleted file]
src/ui/gui/psppire-var-select.h [deleted file]
src/ui/gui/psppire.glade
src/ui/gui/transpose-dialog.c [new file with mode: 0644]
src/ui/gui/transpose-dialog.h [new file with mode: 0644]
src/ui/gui/weight-cases-dialog.c
src/ui/gui/weight-cases-dialog.h

index d4a01e7c1f330086b53fd0d16e0a8451cc852732..9081dae7a1a4c390d04c304a16f34847ecd4ecb4 100644 (file)
 This patch mitigates a bug in glade-2, which silently deletes stock_ids, which 
 it thinks are not valid.   You may have to apply this patch after editing 
-data-editor.glade with glade-2.  Glade-3 is another story and might give 
-problems of its own.
---- src/ui/gui/data-editor.glade,old   2006-12-31 07:29:39.000000000 +0900
-+++ src/ui/gui/data-editor.glade       2006-12-31 07:30:04.000000000 +0900
-@@ -653,6 +653,7 @@
-                 <property name="visible">True</property>
-                 <property name="sensitive">False</property>
-                 <property name="tooltip" translatable="yes">Variables</property>
-+                  <property name="stock_id">pspp-goto-variable</property>
-                 <property name="label" translatable="yes"></property>
-                 <property name="use_underline">True</property>
-                 <property name="visible_horizontal">True</property>
-@@ -712,6 +713,7 @@
-                 <property name="visible">True</property>
-                 <property name="sensitive">False</property>
-                 <property name="tooltip" translatable="yes">Insert Case</property>
-+                  <property name="stock_id">pspp-insert-case</property>
-                 <property name="label" translatable="yes"></property>
-                 <property name="use_underline">True</property>
-                 <property name="visible_horizontal">True</property>
-@@ -730,6 +732,7 @@
-                 <property name="visible">True</property>
-                 <property name="sensitive">False</property>
-                 <property name="tooltip" translatable="yes">Insert Variable</property>
-+                  <property name="stock_id">pspp-insert-variable</property>
-                 <property name="label" translatable="yes"></property>
-                 <property name="use_underline">True</property>
-                 <property name="visible_horizontal">True</property>
-@@ -760,6 +763,7 @@
-                 <property name="visible">True</property>
-                 <property name="sensitive">False</property>
-                 <property name="tooltip" translatable="yes">Split File</property>
-+                  <property name="stock_id">pspp-split-file</property>
-                 <property name="label" translatable="yes"></property>
-                 <property name="use_underline">True</property>
-                 <property name="visible_horizontal">True</property>
-@@ -777,6 +781,7 @@
-                 <property name="visible">True</property>
-                 <property name="sensitive">False</property>
-                 <property name="tooltip" translatable="yes">Weight Cases</property>
-+                  <property name="stock_id">pspp-weight-cases</property>
-                 <property name="label" translatable="yes"></property>
-                 <property name="use_underline">True</property>
-                 <property name="visible_horizontal">True</property>
-@@ -794,6 +799,7 @@
-                 <property name="visible">True</property>
-                 <property name="sensitive">False</property>
-                 <property name="tooltip" translatable="yes">Select Cases</property>
-+                  <property name="stock_id">pspp-select-cases</property>
-                 <property name="label" translatable="yes"></property>
-                 <property name="use_underline">True</property>
-                 <property name="visible_horizontal">True</property>
-@@ -823,6 +829,7 @@
-               <widget class="GtkToggleToolButton" id="togglebutton-value-labels">
-                 <property name="visible">True</property>
-                 <property name="tooltip" translatable="yes">Value Labels</property>
-+                  <property name="stock_id">pspp-value-labels</property>
-                 <property name="label" translatable="yes"></property>
-                 <property name="use_underline">True</property>
-                 <property name="visible_horizontal">True</property>
+data-editor.glade with glade-3.
+--- src/ui/gui/data-editor.glade,bad   2007-01-26 16:15:32.000000000 +0900
++++ src/ui/gui/data-editor.glade       2007-01-26 16:16:18.000000000 +0900
+@@ -506,7 +506,7 @@
+                     <property name="sensitive">False</property>
+                     <property name="tooltip" translatable="yes">Variables</property>
+                     <property name="use_underline">True</property>
+-                    <property name="stock_id">gtk-missing-image</property>
++                    <property name="stock_id">pspp-goto-variable</property>
+                   </widget>
+                   <packing>
+                     <property name="expand">False</property>
+@@ -547,7 +547,7 @@
+                     <property name="sensitive">False</property>
+                     <property name="tooltip" translatable="yes">Insert Case</property>
+                     <property name="use_underline">True</property>
+-                    <property name="stock_id">gtk-missing-image</property>
++                    <property name="stock_id">pspp-insert-case</property>
+                     <signal name="clicked" handler="on_insert_case_clicked"/>
+                   </widget>
+                   <packing>
+@@ -560,7 +560,7 @@
+                     <property name="sensitive">False</property>
+                     <property name="tooltip" translatable="yes">Insert Variable</property>
+                     <property name="use_underline">True</property>
+-                    <property name="stock_id">gtk-missing-image</property>
++                    <property name="stock_id">pspp-insert-variable</property>
+                   </widget>
+                   <packing>
+                     <property name="expand">False</property>
+@@ -581,7 +581,7 @@
+                     <property name="sensitive">False</property>
+                     <property name="tooltip" translatable="yes">Split File</property>
+                     <property name="use_underline">True</property>
+-                    <property name="stock_id">gtk-missing-image</property>
++                    <property name="stock_id">pspp-split-file</property>
+                   </widget>
+                   <packing>
+                     <property name="expand">False</property>
+@@ -592,7 +592,7 @@
+                     <property name="visible">True</property>
+                     <property name="tooltip" translatable="yes">Weight Cases</property>
+                     <property name="use_underline">True</property>
+-                    <property name="stock_id">gtk-missing-image</property>
++                    <property name="stock_id">pspp-weight-cases</property>
+                   </widget>
+                   <packing>
+                     <property name="expand">False</property>
+@@ -604,7 +604,7 @@
+                     <property name="sensitive">False</property>
+                     <property name="tooltip" translatable="yes">Select Cases</property>
+                     <property name="use_underline">True</property>
+-                    <property name="stock_id">gtk-missing-image</property>
++                    <property name="stock_id">pspp-select-cases</property>
+                   </widget>
+                   <packing>
+                     <property name="expand">False</property>
+@@ -624,7 +624,7 @@
+                     <property name="visible">True</property>
+                     <property name="tooltip" translatable="yes">Value Labels</property>
+                     <property name="use_underline">True</property>
+-                    <property name="stock_id">gtk-missing-image</property>
++                    <property name="stock_id">pspp-value-labels</property>
+                     <signal name="toggled" handler="on_togglebutton_value_labels_toggled"/>
+                   </widget>
+                   <packing>
+@@ -667,25 +667,25 @@
+                     <property name="n_rows">1</property>
+                     <property name="n_columns">2</property>
+                     <child>
+-                      <widget class="GtkEntry" id="entry4">
++                      <widget class="GtkEntry" id="cell_ref_entry">
+                         <property name="visible">True</property>
+-                        <property name="can_focus">True</property>
++                        <property name="sensitive">False</property>
++                        <property name="editable">False</property>
++                        <property name="width_chars">25</property>
+                       </widget>
+                       <packing>
+-                        <property name="left_attach">1</property>
+-                        <property name="right_attach">2</property>
++                        <property name="x_options">GTK_FILL</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+                     <child>
+-                      <widget class="GtkEntry" id="cell_ref_entry">
++                      <widget class="GtkEntry" id="entry4">
+                         <property name="visible">True</property>
+-                        <property name="sensitive">False</property>
+-                        <property name="editable">False</property>
+-                        <property name="width_chars">25</property>
++                        <property name="can_focus">True</property>
+                       </widget>
+                       <packing>
+-                        <property name="x_options">GTK_FILL</property>
++                        <property name="left_attach">1</property>
++                        <property name="right_attach">2</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+@@ -1216,63 +1216,63 @@
+                 <property name="column_spacing">2</property>
+                 <property name="row_spacing">1</property>
+                 <child>
+-                  <widget class="GtkLabel" id="decimals_label">
++                  <widget class="GtkHBox" id="hbox2">
+                     <property name="visible">True</property>
+-                    <property name="xalign">0</property>
+-                    <property name="label" translatable="yes">Decimal Places:</property>
++                    <child>
++                      <widget class="GtkLabel" id="width_label">
++                        <property name="visible">True</property>
++                        <property name="label" translatable="yes">Width:</property>
+                     <property name="justify">GTK_JUSTIFY_RIGHT</property>
+                   </widget>
+                   <packing>
+-                    <property name="top_attach">1</property>
+-                    <property name="bottom_attach">2</property>
++                        <property name="expand">False</property>
++                        <property name="fill">False</property>
++                        <property name="pack_type">GTK_PACK_END</property>
++                      </packing>
++                    </child>
++                  </widget>
++                  <packing>
+                     <property name="x_options">GTK_FILL</property>
+-                    <property name="y_options"></property>
++                    <property name="y_options">GTK_FILL</property>
+                   </packing>
+                 </child>
+                 <child>
+-                  <widget class="GtkEntry" id="width_entry">
++                  <widget class="GtkEntry" id="decimals_entry">
+                     <property name="width_request">25</property>
++                    <property name="visible">True</property>
+                     <property name="can_focus">True</property>
+                   </widget>
+                   <packing>
+                     <property name="left_attach">1</property>
+                     <property name="right_attach">2</property>
++                    <property name="top_attach">1</property>
++                    <property name="bottom_attach">2</property>
+                     <property name="y_options"></property>
+                   </packing>
+                 </child>
+                 <child>
+-                  <widget class="GtkEntry" id="decimals_entry">
++                  <widget class="GtkEntry" id="width_entry">
+                     <property name="width_request">25</property>
+-                    <property name="visible">True</property>
+                     <property name="can_focus">True</property>
+                   </widget>
+                   <packing>
+                     <property name="left_attach">1</property>
+                     <property name="right_attach">2</property>
+-                    <property name="top_attach">1</property>
+-                    <property name="bottom_attach">2</property>
+                     <property name="y_options"></property>
+                   </packing>
+                 </child>
+                 <child>
+-                  <widget class="GtkHBox" id="hbox2">
+-                    <property name="visible">True</property>
+-                    <child>
+-                      <widget class="GtkLabel" id="width_label">
++                  <widget class="GtkLabel" id="decimals_label">
+                         <property name="visible">True</property>
+-                        <property name="label" translatable="yes">Width:</property>
++                    <property name="xalign">0</property>
++                    <property name="label" translatable="yes">Decimal Places:</property>
+                         <property name="justify">GTK_JUSTIFY_RIGHT</property>
+                       </widget>
+                       <packing>
+-                        <property name="expand">False</property>
+-                        <property name="fill">False</property>
+-                        <property name="pack_type">GTK_PACK_END</property>
+-                      </packing>
+-                    </child>
+-                  </widget>
+-                  <packing>
++                    <property name="top_attach">1</property>
++                    <property name="bottom_attach">2</property>
+                     <property name="x_options">GTK_FILL</property>
+-                    <property name="y_options">GTK_FILL</property>
++                    <property name="y_options"></property>
+                   </packing>
+                 </child>
+               </widget>
+@@ -1360,50 +1360,28 @@
+                     <property name="n_columns">2</property>
+                     <property name="row_spacing">5</property>
+                     <child>
+-                      <widget class="GtkVButtonBox" id="vbuttonbox2">
+-                        <property name="visible">True</property>
+-                        <property name="border_width">5</property>
+-                        <child>
+-                          <widget class="GtkButton" id="val_labs_add">
+-                            <property name="visible">True</property>
+-                            <property name="sensitive">False</property>
+-                            <property name="can_focus">True</property>
+-                            <property name="can_default">True</property>
+-                            <property name="label">gtk-add</property>
+-                            <property name="use_stock">True</property>
+-                          </widget>
+-                        </child>
+-                        <child>
+-                          <widget class="GtkButton" id="val_labs_change">
++                      <widget class="GtkScrolledWindow" id="scrolledwindow3">
+                             <property name="visible">True</property>
+-                            <property name="sensitive">False</property>
+                             <property name="can_focus">True</property>
+-                            <property name="can_default">True</property>
+-                            <property name="label">gtk-apply</property>
+-                            <property name="use_stock">True</property>
+-                          </widget>
+-                          <packing>
+-                            <property name="position">1</property>
+-                          </packing>
+-                        </child>
++                        <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
++                        <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
++                        <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+                         <child>
+-                          <widget class="GtkButton" id="val_labs_remove">
++                          <widget class="GtkTreeView" id="treeview1">
+                             <property name="visible">True</property>
+-                            <property name="sensitive">False</property>
+                             <property name="can_focus">True</property>
+-                            <property name="can_default">True</property>
+-                            <property name="label">gtk-remove</property>
+-                            <property name="use_stock">True</property>
++                            <property name="headers_visible">False</property>
++                            <property name="enable_search">False</property>
+                           </widget>
+-                          <packing>
+-                            <property name="position">2</property>
+-                          </packing>
+                         </child>
+                       </widget>
+                       <packing>
++                        <property name="left_attach">1</property>
++                        <property name="right_attach">2</property>
+                         <property name="top_attach">1</property>
+                         <property name="bottom_attach">2</property>
+                         <property name="x_options">GTK_FILL</property>
++                        <property name="y_options">GTK_FILL</property>
+                       </packing>
+                     </child>
+                     <child>
+@@ -1415,27 +1393,26 @@
+                         <property name="column_spacing">5</property>
+                         <property name="row_spacing">4</property>
+                         <child>
+-                          <widget class="GtkLabel" id="label5">
++                          <widget class="GtkHBox" id="hbox4">
+                             <property name="visible">True</property>
+-                            <property name="xalign">0</property>
+-                            <property name="label" translatable="yes">Value:</property>
++                            <child>
++                              <widget class="GtkEntry" id="value_entry">
++                                <property name="width_request">85</property>
++                                <property name="visible">True</property>
++                                <property name="can_focus">True</property>
+                           </widget>
+                           <packing>
+-                            <property name="x_options">GTK_FILL</property>
+-                            <property name="y_options"></property>
++                                <property name="expand">False</property>
++                                <property name="fill">False</property>
++                                <property name="padding">1</property>
+                           </packing>
+                         </child>
+-                        <child>
+-                          <widget class="GtkLabel" id="label6">
+-                            <property name="visible">True</property>
+-                            <property name="xalign">0</property>
+-                            <property name="label" translatable="yes">Value Label:</property>
+                           </widget>
+                           <packing>
+-                            <property name="top_attach">1</property>
+-                            <property name="bottom_attach">2</property>
++                            <property name="left_attach">1</property>
++                            <property name="right_attach">2</property>
+                             <property name="x_options">GTK_FILL</property>
+-                            <property name="y_options"></property>
++                            <property name="y_options">GTK_FILL</property>
+                           </packing>
+                         </child>
+                         <child>
+@@ -1452,26 +1429,27 @@
+                           </packing>
+                         </child>
+                         <child>
+-                          <widget class="GtkHBox" id="hbox4">
+-                            <property name="visible">True</property>
+-                            <child>
+-                              <widget class="GtkEntry" id="value_entry">
+-                                <property name="width_request">85</property>
++                          <widget class="GtkLabel" id="label6">
+                                 <property name="visible">True</property>
+-                                <property name="can_focus">True</property>
++                            <property name="xalign">0</property>
++                            <property name="label" translatable="yes">Value Label:</property>
+                               </widget>
+                               <packing>
+-                                <property name="expand">False</property>
+-                                <property name="fill">False</property>
+-                                <property name="padding">1</property>
++                            <property name="top_attach">1</property>
++                            <property name="bottom_attach">2</property>
++                            <property name="x_options">GTK_FILL</property>
++                            <property name="y_options"></property>
+                               </packing>
+                             </child>
++                        <child>
++                          <widget class="GtkLabel" id="label5">
++                            <property name="visible">True</property>
++                            <property name="xalign">0</property>
++                            <property name="label" translatable="yes">Value:</property>
+                           </widget>
+                           <packing>
+-                            <property name="left_attach">1</property>
+-                            <property name="right_attach">2</property>
+                             <property name="x_options">GTK_FILL</property>
+-                            <property name="y_options">GTK_FILL</property>
++                            <property name="y_options"></property>
+                           </packing>
+                         </child>
+                       </widget>
+@@ -1481,28 +1459,50 @@
+                       </packing>
+                     </child>
+                     <child>
+-                      <widget class="GtkScrolledWindow" id="scrolledwindow3">
++                      <widget class="GtkVButtonBox" id="vbuttonbox2">
++                        <property name="visible">True</property>
++                        <property name="border_width">5</property>
++                        <child>
++                          <widget class="GtkButton" id="val_labs_add">
+                         <property name="visible">True</property>
++                            <property name="sensitive">False</property>
+                         <property name="can_focus">True</property>
+-                        <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+-                        <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+-                        <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
++                            <property name="can_default">True</property>
++                            <property name="label">gtk-add</property>
++                            <property name="use_stock">True</property>
++                          </widget>
++                        </child>
+                         <child>
+-                          <widget class="GtkTreeView" id="treeview1">
++                          <widget class="GtkButton" id="val_labs_change">
+                             <property name="visible">True</property>
++                            <property name="sensitive">False</property>
+                             <property name="can_focus">True</property>
+-                            <property name="headers_visible">False</property>
+-                            <property name="enable_search">False</property>
++                            <property name="can_default">True</property>
++                            <property name="label">gtk-apply</property>
++                            <property name="use_stock">True</property>
+                           </widget>
++                          <packing>
++                            <property name="position">1</property>
++                          </packing>
++                        </child>
++                        <child>
++                          <widget class="GtkButton" id="val_labs_remove">
++                            <property name="visible">True</property>
++                            <property name="sensitive">False</property>
++                            <property name="can_focus">True</property>
++                            <property name="can_default">True</property>
++                            <property name="label">gtk-remove</property>
++                            <property name="use_stock">True</property>
++                          </widget>
++                          <packing>
++                            <property name="position">2</property>
++                          </packing>
+                         </child>
+                       </widget>
+                       <packing>
+-                        <property name="left_attach">1</property>
+-                        <property name="right_attach">2</property>
+                         <property name="top_attach">1</property>
+                         <property name="bottom_attach">2</property>
+                         <property name="x_options">GTK_FILL</property>
+-                        <property name="y_options">GTK_FILL</property>
+                       </packing>
+                     </child>
+                   </widget>
+@@ -1590,64 +1590,68 @@
+         <property name="n_rows">2</property>
+         <property name="n_columns">2</property>
+         <child>
+-          <widget class="GtkVButtonBox" id="vbuttonbox5">
++          <widget class="GtkVBox" id="vbox7">
+             <property name="visible">True</property>
+-            <property name="border_width">5</property>
+-            <property name="spacing">5</property>
+-            <property name="layout_style">GTK_BUTTONBOX_START</property>
+             <child>
+-              <widget class="GtkButton" id="missing_val_ok">
++              <widget class="GtkRadioButton" id="range_missing">
+                 <property name="visible">True</property>
+                 <property name="can_focus">True</property>
+-                <property name="can_default">True</property>
+-                <property name="label">gtk-ok</property>
+-                <property name="use_stock">True</property>
+-                <signal name="clicked" handler="gtk_widget_hide" object="val_labs_dialog"/>
++                <property name="label" translatable="yes">_Range plus one optional discrete missing value</property>
++                <property name="use_underline">True</property>
++                <property name="focus_on_click">False</property>
++                <property name="draw_indicator">True</property>
++                <property name="group">no_missing</property>
+               </widget>
++              <packing>
++                <property name="expand">False</property>
++                <property name="fill">False</property>
++              </packing>
+             </child>
+             <child>
+-              <widget class="GtkButton" id="missing_val_cancel">
++              <widget class="GtkVBox" id="vbox8">
+                 <property name="visible">True</property>
+-                <property name="can_focus">True</property>
+-                <property name="can_default">True</property>
+-                <property name="label">gtk-cancel</property>
+-                <property name="use_stock">True</property>
+-                <signal name="clicked" handler="gtk_widget_hide" object="val_labs_dialog"/>
++                <property name="spacing">5</property>
++                <child>
++                  <widget class="GtkHBox" id="hbox7">
++                    <property name="visible">True</property>
++                    <child>
++                      <widget class="GtkHBox" id="hbox8">
++                        <property name="visible">True</property>
++                        <child>
++                          <widget class="GtkLabel" id="label11">
++                            <property name="visible">True</property>
++                            <property name="label" translatable="yes">_Low:</property>
++                            <property name="use_underline">True</property>
++                            <property name="mnemonic_widget">mv-low</property>
+               </widget>
+               <packing>
+-                <property name="position">1</property>
++                            <property name="expand">False</property>
++                            <property name="fill">False</property>
++                            <property name="padding">20</property>
+               </packing>
+             </child>
+             <child>
+-              <widget class="GtkButton" id="help_button_missing_values">
++                          <widget class="GtkEntry" id="mv-low">
++                            <property name="width_request">75</property>
+                 <property name="visible">True</property>
+                 <property name="can_focus">True</property>
+-                <property name="can_default">True</property>
+-                <property name="label">gtk-help</property>
+-                <property name="use_stock">True</property>
+               </widget>
+               <packing>
+-                <property name="position">2</property>
++                            <property name="expand">False</property>
++                            <property name="position">1</property>
+               </packing>
+             </child>
+           </widget>
+-          <packing>
+-            <property name="left_attach">1</property>
+-            <property name="right_attach">2</property>
+-          </packing>
+         </child>
+         <child>
+-          <widget class="GtkVBox" id="vbox5">
++                      <widget class="GtkHBox" id="hbox9">
+             <property name="visible">True</property>
+-            <property name="spacing">12</property>
+             <child>
+-              <widget class="GtkRadioButton" id="no_missing">
++                          <widget class="GtkLabel" id="label12">
+                 <property name="visible">True</property>
+-                <property name="can_focus">True</property>
+-                <property name="label" translatable="yes">_No missing values</property>
++                            <property name="label" translatable="yes">_High:</property>
+                 <property name="use_underline">True</property>
+-                <property name="active">True</property>
+-                <property name="draw_indicator">True</property>
++                            <property name="mnemonic_widget">mv-high</property>
+               </widget>
+               <packing>
+                 <property name="expand">False</property>
+@@ -1655,97 +1659,102 @@
+               </packing>
+             </child>
+             <child>
+-              <widget class="GtkVBox" id="vbox6">
+-                <property name="visible">True</property>
+-                <child>
+-                  <widget class="GtkRadioButton" id="discrete_missing">
++                          <widget class="GtkEntry" id="mv-high">
++                            <property name="width_request">75</property>
+                     <property name="visible">True</property>
+                     <property name="can_focus">True</property>
+-                    <property name="label" translatable="yes">_Discrete missing values</property>
+-                    <property name="use_underline">True</property>
+-                    <property name="focus_on_click">False</property>
+-                    <property name="draw_indicator">True</property>
+-                    <property name="group">no_missing</property>
+                   </widget>
+                   <packing>
+-                    <property name="expand">False</property>
++                            <property name="padding">5</property>
++                            <property name="position">1</property>
++                          </packing>
++                        </child>
++                      </widget>
++                      <packing>
+                     <property name="fill">False</property>
++                        <property name="padding">20</property>
++                        <property name="position">1</property>
+                   </packing>
+                 </child>
+                 <child>
+-                  <widget class="GtkHBox" id="hbox10">
+-                    <property name="visible">True</property>
++                      <placeholder/>
++                    </child>
+                     <child>
+-                      <widget class="GtkHBox" id="hbox5">
++                      <placeholder/>
++                    </child>
++                  </widget>
++                </child>
++                <child>
++                  <widget class="GtkHBox" id="hbox6">
+                         <property name="visible">True</property>
+-                        <property name="border_width">5</property>
+-                        <property name="spacing">5</property>
+-                        <property name="homogeneous">True</property>
+                         <child>
+-                          <widget class="GtkEntry" id="mv0">
+-                            <property name="width_request">75</property>
++                      <widget class="GtkLabel" id="label10">
+                             <property name="visible">True</property>
+-                            <property name="can_focus">True</property>
++                        <property name="label" translatable="yes">Di_screte value:</property>
++                        <property name="use_underline">True</property>
++                        <property name="mnemonic_widget">mv-discrete</property>
+                           </widget>
+                           <packing>
+                             <property name="expand">False</property>
+                             <property name="fill">False</property>
++                        <property name="padding">20</property>
+                           </packing>
+                         </child>
+                         <child>
+-                          <widget class="GtkEntry" id="mv1">
++                      <widget class="GtkEntry" id="mv-discrete">
+                             <property name="width_request">75</property>
+                             <property name="visible">True</property>
+                             <property name="can_focus">True</property>
+                           </widget>
+                           <packing>
+                             <property name="expand">False</property>
+-                            <property name="fill">False</property>
+                             <property name="position">1</property>
+                           </packing>
+                         </child>
+-                        <child>
+-                          <widget class="GtkEntry" id="mv2">
+-                            <property name="width_request">75</property>
+-                            <property name="visible">True</property>
+-                            <property name="can_focus">True</property>
+                           </widget>
+                           <packing>
+-                            <property name="expand">False</property>
+-                            <property name="fill">False</property>
+-                            <property name="position">2</property>
++                    <property name="position">1</property>
+                           </packing>
+                         </child>
+                       </widget>
+                       <packing>
+-                        <property name="padding">20</property>
++                <property name="position">1</property>
+                       </packing>
+                     </child>
+                   </widget>
+                   <packing>
+-                    <property name="position">1</property>
++            <property name="right_attach">2</property>
++            <property name="top_attach">1</property>
++            <property name="bottom_attach">2</property>
++            <property name="x_options">GTK_FILL</property>
+                   </packing>
+                 </child>
++        <child>
++          <widget class="GtkVBox" id="vbox5">
++            <property name="visible">True</property>
++            <property name="spacing">12</property>
++            <child>
++              <widget class="GtkRadioButton" id="no_missing">
++                <property name="visible">True</property>
++                <property name="can_focus">True</property>
++                <property name="label" translatable="yes">_No missing values</property>
++                <property name="use_underline">True</property>
++                <property name="active">True</property>
++                <property name="draw_indicator">True</property>
+               </widget>
+               <packing>
+                 <property name="expand">False</property>
+                 <property name="fill">False</property>
+-                <property name="position">1</property>
+-              </packing>
+-            </child>
+-          </widget>
+-          <packing>
+-            <property name="y_options">GTK_FILL</property>
+           </packing>
+         </child>
+         <child>
+-          <widget class="GtkVBox" id="vbox7">
++              <widget class="GtkVBox" id="vbox6">
+             <property name="visible">True</property>
+             <child>
+-              <widget class="GtkRadioButton" id="range_missing">
++                  <widget class="GtkRadioButton" id="discrete_missing">
+                 <property name="visible">True</property>
+                 <property name="can_focus">True</property>
+-                <property name="label" translatable="yes">_Range plus one optional discrete missing value</property>
++                    <property name="label" translatable="yes">_Discrete missing values</property>
+                 <property name="use_underline">True</property>
+                 <property name="focus_on_click">False</property>
+                 <property name="draw_indicator">True</property>
+@@ -1757,125 +1766,116 @@
+               </packing>
+             </child>
+             <child>
+-              <widget class="GtkVBox" id="vbox8">
+-                <property name="visible">True</property>
+-                <property name="spacing">5</property>
+-                <child>
+-                  <widget class="GtkHBox" id="hbox7">
++                  <widget class="GtkHBox" id="hbox10">
+                     <property name="visible">True</property>
+                     <child>
+-                      <widget class="GtkHBox" id="hbox8">
++                      <widget class="GtkHBox" id="hbox5">
+                         <property name="visible">True</property>
++                        <property name="border_width">5</property>
++                        <property name="spacing">5</property>
++                        <property name="homogeneous">True</property>
+                         <child>
+-                          <widget class="GtkLabel" id="label11">
++                          <widget class="GtkEntry" id="mv0">
++                            <property name="width_request">75</property>
+                             <property name="visible">True</property>
+-                            <property name="label" translatable="yes">_Low:</property>
+-                            <property name="use_underline">True</property>
+-                            <property name="mnemonic_widget">mv-low</property>
++                            <property name="can_focus">True</property>
+                           </widget>
+                           <packing>
+                             <property name="expand">False</property>
+                             <property name="fill">False</property>
+-                            <property name="padding">20</property>
+                           </packing>
+                         </child>
+                         <child>
+-                          <widget class="GtkEntry" id="mv-low">
++                          <widget class="GtkEntry" id="mv1">
+                             <property name="width_request">75</property>
+                             <property name="visible">True</property>
+                             <property name="can_focus">True</property>
+                           </widget>
+                           <packing>
+                             <property name="expand">False</property>
++                            <property name="fill">False</property>
+                             <property name="position">1</property>
+                           </packing>
+                         </child>
+-                      </widget>
+-                    </child>
+-                    <child>
+-                      <widget class="GtkHBox" id="hbox9">
+-                        <property name="visible">True</property>
+                         <child>
+-                          <widget class="GtkLabel" id="label12">
++                          <widget class="GtkEntry" id="mv2">
++                            <property name="width_request">75</property>
+                             <property name="visible">True</property>
+-                            <property name="label" translatable="yes">_High:</property>
+-                            <property name="use_underline">True</property>
+-                            <property name="mnemonic_widget">mv-high</property>
++                            <property name="can_focus">True</property>
+                           </widget>
+                           <packing>
+                             <property name="expand">False</property>
+                             <property name="fill">False</property>
++                            <property name="position">2</property>
++                          </packing>
++                        </child>
++                      </widget>
++                      <packing>
++                        <property name="padding">20</property>
+                           </packing>
+                         </child>
+-                        <child>
+-                          <widget class="GtkEntry" id="mv-high">
+-                            <property name="width_request">75</property>
+-                            <property name="visible">True</property>
+-                            <property name="can_focus">True</property>
+                           </widget>
+                           <packing>
+-                            <property name="padding">5</property>
+                             <property name="position">1</property>
+                           </packing>
+                         </child>
+                       </widget>
+                       <packing>
++                <property name="expand">False</property>
+                         <property name="fill">False</property>
+-                        <property name="padding">20</property>
+                         <property name="position">1</property>
+                       </packing>
+                     </child>
+-                    <child>
+-                      <placeholder/>
+-                    </child>
+-                    <child>
+-                      <placeholder/>
+-                    </child>
+                   </widget>
++          <packing>
++            <property name="y_options">GTK_FILL</property>
++          </packing>
+                 </child>
+                 <child>
+-                  <widget class="GtkHBox" id="hbox6">
++          <widget class="GtkVButtonBox" id="vbuttonbox5">
+                     <property name="visible">True</property>
++            <property name="border_width">5</property>
++            <property name="spacing">5</property>
++            <property name="layout_style">GTK_BUTTONBOX_START</property>
+                     <child>
+-                      <widget class="GtkLabel" id="label10">
++              <widget class="GtkButton" id="missing_val_ok">
+                         <property name="visible">True</property>
+-                        <property name="label" translatable="yes">Di_screte value:</property>
+-                        <property name="use_underline">True</property>
+-                        <property name="mnemonic_widget">mv-discrete</property>
++                <property name="can_focus">True</property>
++                <property name="can_default">True</property>
++                <property name="label">gtk-ok</property>
++                <property name="use_stock">True</property>
++                <signal name="clicked" handler="gtk_widget_hide" object="val_labs_dialog"/>
+                       </widget>
+-                      <packing>
+-                        <property name="expand">False</property>
+-                        <property name="fill">False</property>
+-                        <property name="padding">20</property>
+-                      </packing>
+                     </child>
+                     <child>
+-                      <widget class="GtkEntry" id="mv-discrete">
+-                        <property name="width_request">75</property>
++              <widget class="GtkButton" id="missing_val_cancel">
+                         <property name="visible">True</property>
+                         <property name="can_focus">True</property>
+-                      </widget>
+-                      <packing>
+-                        <property name="expand">False</property>
+-                        <property name="position">1</property>
+-                      </packing>
+-                    </child>
++                <property name="can_default">True</property>
++                <property name="label">gtk-cancel</property>
++                <property name="use_stock">True</property>
++                <signal name="clicked" handler="gtk_widget_hide" object="val_labs_dialog"/>
+                   </widget>
+                   <packing>
+                     <property name="position">1</property>
+                   </packing>
+                 </child>
++            <child>
++              <widget class="GtkButton" id="help_button_missing_values">
++                <property name="visible">True</property>
++                <property name="can_focus">True</property>
++                <property name="can_default">True</property>
++                <property name="label">gtk-help</property>
++                <property name="use_stock">True</property>
+               </widget>
+               <packing>
+-                <property name="position">1</property>
++                <property name="position">2</property>
+               </packing>
+             </child>
+           </widget>
+           <packing>
++            <property name="left_attach">1</property>
+             <property name="right_attach">2</property>
+-            <property name="top_attach">1</property>
+-            <property name="bottom_attach">2</property>
+-            <property name="x_options">GTK_FILL</property>
+           </packing>
+         </child>
+       </widget>
index 144cb6da76b985eea32ab254e97afc6a3433228d..5d5a65839b9c5397136cc8cd320aa8ad96631a46 100644 (file)
@@ -8,8 +8,10 @@ catalogdir = `pkg-config --variable=catalogdir libgladeui-1.0`
 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-buttonbox.c \
+       src/ui/gui/psppire-selector.c
 
 nodist_catalog_DATA = \
        glade/psppire.xml
index 10960e5c4cef086d1ad4de9b6c48dda9d20b9eef..da6f0137967c6df74208f2d06b297233a977d4d4 100644 (file)
@@ -19,6 +19,7 @@
        <property optional-default="False" optional="True" id="default-height" 
        default="0"/>
        <property id="has-separator" default="False"/>
+
       </properties>
 
     </glade-widget-class>
           </packing-defaults>
     </glade-widget-class>
 
+
+    <glade-widget-class name="PsppireSelector" generic-name="psppire-selector" title="Psppire Selector Button">
+
+          <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>
+
+    </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-catalog>
diff --git a/glade/selector.c b/glade/selector.c
new file mode 100644 (file)
index 0000000..bd85f44
--- /dev/null
@@ -0,0 +1,74 @@
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "psppire-selector.h"
+
+#include <glade-gtk.h>
+
+
+void GLADEGTK_API
+glade_psppire_selector_post_create (GladeWidgetAdaptor *adaptor,
+                                   GObject            *object,
+                                   GladeCreateReason   reason)
+{
+  GladeWidget *widget ;
+
+  PsppireSelector *selector = PSPPIRE_SELECTOR (object);
+
+  g_return_if_fail (PSPPIRE_IS_SELECTOR (selector));
+
+  widget = glade_widget_get_from_gobject (GTK_WIDGET (selector));
+  if (!widget)
+    return;
+
+  if (reason == GLADE_CREATE_USER)
+    {
+      /* HIG complient border-width defaults on selectors */
+      glade_widget_property_set (widget, "border-width", 5);
+    }
+}
+
+
+GtkWidget *
+glade_psppire_selector_get_internal_child (GladeWidgetAdaptor  *adaptor,
+                                        PsppireSelector       *selector,
+                                        const gchar         *name)
+{
+#if DEBUGGING
+  g_print ("%s\n", __FUNCTION__);
+#endif
+  return GTK_WIDGET (selector);
+}
+
+
+
+void
+glade_psppire_selector_set_property (GladeWidgetAdaptor *adaptor,
+                                  GObject            *object,
+                                  const gchar        *id,
+                                  const GValue       *value)
+{
+#if DEBUGGING
+  g_print ("%s(%p) Type=\"%s\" Id=\"%s\"\n", __FUNCTION__, object,
+          G_OBJECT_TYPE_NAME( object ),
+          id);
+#endif
+
+  GWA_GET_CLASS (GTK_TYPE_WINDOW)->set_property (adaptor, object,
+                                                id, value);
+}
+
+
+
+GList *
+glade_psppire_selector_get_children (GladeWidgetAdaptor  *adaptor,
+                                  PsppireSelector  *selector)
+{
+  GList *list = NULL;
+
+  g_return_val_if_fail (PSPPIRE_IS_SELECTOR (selector), NULL);
+
+  list = glade_util_container_get_all_children (GTK_CONTAINER (selector));
+
+  return list;
+}
index d38ed5fc1326d15f8d75e565c3bc77c9034f0fbe..0dadb959d371d5d0624f4dca21ff5d7c54d0a4ed 100644 (file)
@@ -352,9 +352,16 @@ dict_clone_var_assert (struct dictionary *d, const struct variable *old_var,
 struct variable *
 dict_lookup_var (const struct dictionary *d, const char *name)
 {
-  struct variable *target = var_create (name, 0);
-  struct variable *result = hsh_find (d->name_tab, target);
+  struct variable *target ;
+  struct variable *result ;
+
+  if ( ! var_is_valid_name (name, false))
+    return NULL;
+
+  target = var_create (name, 0);
+  result = hsh_find (d->name_tab, target);
   var_destroy (target);
+
   return result;
 }
 
index 88d9b5a78bc96dcafa54ddaa0ced42b3d2e76156..e487ac51185e9dc2d0ddcc41b64bf307f75ea57a 100644 (file)
@@ -61,6 +61,9 @@ unsigned hash_var_ptr_by_name (const void *, const void *);
 enum var_type var_get_type (const struct variable *);
 int var_get_width (const struct variable *);
 void var_set_width (struct variable *, int width);
+
+typedef bool var_predicate_func (const struct variable *);
+
 bool var_is_numeric (const struct variable *);
 bool var_is_alpha (const struct variable *);
 bool var_is_short_string (const struct variable *);
index 0b9592ee6f0f12fdd2666eb38590b894c7f1b4b6..5b0dbec41b0c036fd73fd287555415aa0685cb9f 100644 (file)
@@ -1,3 +1,21 @@
+Fri Jan 26 15:51:34 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-var-select.c psppire-var-select.h : Deleted.
+
+       * psppire-selector.c psppire-selector.h : New files.
+
+       * transpose-dialog.c transpose-dialog.h : New files.
+
+       * psppire-dict.c psppire-dict.h : Added missing GtkTreeModel 
+       interface functions.
+
+       * weight-cases-dialog.c weight-cases-dialog.h : Re-implemented, 
+       using new PsppireSelector widget.
+
+       * dict-display.c dict-display.h : New files.
+
+       * psppire-object.c psppire-object.h : Deleted.  Seemed like a good idea at the time.
+
 Tue Jan 23 21:10:01 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
        * helper.c helper.h: New function execute_syntax.
index 11a27925ddba9c5a7663ac36d1f448f4acd87144..6f6fa3c52c7ea2e5e67339bcd4d816803165f442 100644 (file)
@@ -62,6 +62,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/dict-display.c \
+       src/ui/gui/dict-display.h \
        src/ui/gui/flexifile-factory.h \
        src/ui/gui/flexifile-factory.c \
        src/ui/gui/message-dialog.c \
@@ -81,18 +83,18 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/psppire-dialog.h \
        src/ui/gui/psppire-buttonbox.c \
        src/ui/gui/psppire-buttonbox.h \
-       src/ui/gui/psppire-object.c \
-       src/ui/gui/psppire-object.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/psppire-var-select.h \
-       src/ui/gui/psppire-var-select.c \
        src/ui/gui/sort-cases-dialog.c \
        src/ui/gui/sort-cases-dialog.h \
        src/ui/gui/syntax-editor.c \
        src/ui/gui/syntax-editor.h \
        src/ui/gui/syntax-editor-source.c \
        src/ui/gui/syntax-editor-source.h \
+       src/ui/gui/transpose-dialog.c \
+       src/ui/gui/transpose-dialog.h \
        src/ui/gui/val-labs-dialog.c \
        src/ui/gui/val-labs-dialog.h \
        src/ui/gui/var-sheet.c \
index 07588770146b130d9ac1bea33fe61c11f3465b72..0d60b9cd7dcb842164c6a9b2fd6608504572ed45 100644 (file)
 #include "helper.h"
 #include "about.h"
 #include "psppire-dialog.h"
-#include "psppire-var-select.h"
+#include "psppire-selector.h"
+#include "weight-cases-dialog.h"
+#include "transpose-dialog.h"
+#include "dict-display.h"
 
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
@@ -43,8 +46,6 @@
 #include "psppire-data-store.h"
 #include "psppire-var-store.h"
 
-#include "weight-cases-dialog.h"
-
 static void register_data_editor_actions (struct data_editor *de);
 
 static void insert_variable (GtkCheckMenuItem *m, gpointer data);
@@ -111,8 +112,6 @@ disable_edit_clear (GtkWidget *w, gint x, gint y, gpointer data)
   return FALSE;
 }
 
-static void weight_cases_dialog (GObject *o, gpointer data);
-
 
 /*
   Create a new data editor.
@@ -159,10 +158,21 @@ new_data_editor (void)
                    _("Weight cases by variable"),
                    "pspp-weight-cases");
 
-
   g_signal_connect (de->invoke_weight_cases_dialog, "activate",
                    G_CALLBACK (weight_cases_dialog), de);
 
+
+  de->invoke_transpose_dialog =
+    gtk_action_new ("transpose-dialog",
+                   _("Transpose"),
+                   _("Transpose the cases with the variables"),
+                   NULL);
+
+
+  g_signal_connect (de->invoke_transpose_dialog, "activate",
+                   G_CALLBACK (transpose_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"),
@@ -211,6 +221,9 @@ new_data_editor (void)
                            get_widget_assert (de->xml, "data_weight-cases")
                            );
 
+  gtk_action_connect_proxy (de->invoke_transpose_dialog,
+                           get_widget_assert (de->xml, "data_transpose")
+                           );
 
   g_signal_connect (get_widget_assert (de->xml,"help_about"),
                    "activate",
@@ -739,90 +752,6 @@ on_weight_change (GObject *o, gint weight_index, gpointer data)
     }
 }
 
-static void
-weight_cases_dialog (GObject *o, gpointer data)
-{
-  gint response;
-  struct data_editor *de = data;
-  GtkSheet *var_sheet =
-    GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
-
-
-  GladeXML *xml = glade_xml_new (PKGDATADIR "/psppire.glade",
-                                "weight-cases-dialog", NULL);
-
-
-  GtkWidget *treeview =  get_widget_assert (xml, "treeview");
-  GtkWidget *entry =  get_widget_assert (xml, "entry1");
-
-
-  PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet));
-
-  PsppireVarSelect *select = psppire_var_select_new (treeview,
-                                                    entry, vs->dict);
-
-
-  PsppireDialog *dialog = create_weight_dialog (select, xml);
-
-  response = psppire_dialog_run (dialog);
-
-  g_object_unref (xml);
-
-  switch (response)
-    {
-    case GTK_RESPONSE_OK:
-    {
-      struct getl_interface *sss ;
-      const GList *list = psppire_var_select_get_variables (select);
-
-      g_assert ( g_list_length ((GList *)list) <= 1 );
-
-      if ( list == NULL)
-         {
-           sss = create_syntax_string_source ("WEIGHT OFF.");
-         }
-      else
-       {
-         struct variable *var = list->data;
-
-           sss = create_syntax_string_source ("WEIGHT BY %s.\n",
-                                              var_get_name (var));
-         }
-
-       execute_syntax (sss);
-       }
-      break;
-    case PSPPIRE_RESPONSE_PASTE:
-      {
-       struct syntax_editor *se =  (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       const GList *list = psppire_var_select_get_variables (select);
-
-       g_assert ( g_list_length ((GList *)list) <= 1 );
-
-       if ( list == NULL)
-         {
-           gtk_text_buffer_insert_at_cursor (se->buffer, "WEIGHT OFF.", -1);
-         }
-       else
-         {
-           struct variable *var = list->data;
-
-           gchar *text = g_strdup_printf ("WEIGHT BY %s.",
-                                          var_get_name (var));
-
-           gtk_text_buffer_insert_at_cursor (se->buffer,
-                                             text, -1);
-
-           g_free (text);
-         }
-      }
-      break;
-    default:
-      break;
-    }
-}
-
 
 
 \f
index 11ba2eb9648782210c1ad70c80bbfe34ac3b6c46..6ce94bb253f32669f7cc01f6ac62e9f22f7e206b 100644 (file)
@@ -74,7 +74,6 @@
                     <child>
                       <widget class="GtkImageMenuItem" id="file_save">
                         <property name="visible">True</property>
-                        <property name="sensitive">True</property>
                         <property name="label">gtk-save</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
@@ -83,7 +82,6 @@
                     <child>
                       <widget class="GtkImageMenuItem" id="file_save_as">
                         <property name="visible">True</property>
-                        <property name="sensitive">True</property>
                         <property name="label">gtk-save-as</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
                       </widget>
                     </child>
                     <child>
-                      <widget class="GtkMenuItem" id="transpose1">
+                      <widget class="GtkMenuItem" id="data_transpose">
                         <property name="visible">True</property>
                         <property name="sensitive">False</property>
                         <property name="label" translatable="yes">Transpose</property>
                     <child>
                       <widget class="GtkMenuItem" id="data_weight-cases">
                         <property name="visible">True</property>
-                        <property name="sensitive">True</property>
                         <property name="label" translatable="yes">Weight Cases</property>
                         <property name="use_underline">True</property>
                       </widget>
                 <child>
                   <widget class="GtkToolButton" id="button-open">
                     <property name="visible">True</property>
-                    <property name="sensitive">True</property>
                     <property name="tooltip" translatable="yes">Open</property>
                     <property name="stock_id">gtk-open</property>
                   </widget>
                 <child>
                   <widget class="GtkToolButton" id="button-save">
                     <property name="visible">True</property>
-                    <property name="sensitive">True</property>
                     <property name="tooltip" translatable="yes">Save</property>
                     <property name="stock_id">gtk-save</property>
                     <signal name="clicked" handler="on_save1_activate"/>
                 <child>
                   <widget class="GtkToolButton" id="button-weight-cases">
                     <property name="visible">True</property>
-                    <property name="sensitive">True</property>
                     <property name="tooltip" translatable="yes">Weight Cases</property>
                     <property name="use_underline">True</property>
                     <property name="stock_id">pspp-weight-cases</property>
index 67302fa9d5cb82ee199320e6978ee4ccafac8c75..7100e34eb87baa167bc2b238c9d5d650e5672749 100644 (file)
@@ -35,6 +35,7 @@ struct data_editor
   GtkAction *action_data_save;
 
   GtkAction *invoke_weight_cases_dialog;
+  GtkAction *invoke_transpose_dialog;
 
   GladeXML *xml;
 
diff --git a/src/ui/gui/dict-display.c b/src/ui/gui/dict-display.c
new file mode 100644 (file)
index 0000000..68b7b8d
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+   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 <gettext.h>
+#include <gtk/gtk.h>
+
+#include "dict-display.h"
+
+#include "psppire-dict.h"
+#include "helper.h"
+#include <data/variable.h>
+
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+
+/* A GtkTreeModelFilterVisibleFunc to filter lines in the treeview */
+static gboolean
+filter_variables (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
+{
+  var_predicate_func *predicate = data;
+  struct variable *var;
+  PsppireDict *dict = PSPPIRE_DICT (model);
+
+  GtkTreePath *path = gtk_tree_model_get_path (model, iter);
+
+  gint *idx = gtk_tree_path_get_indices (path);
+
+  var =  psppire_dict_get_variable (dict, *idx);
+
+  gtk_tree_path_free (path);
+
+  return predicate (var);
+}
+
+/* Sets up TREEVIEW to display the variables of DICT.
+   MODE is the selection mode for TREEVIEW.
+   PREDICATE determines which variables should be visible, or NULL if
+   all are to be visible.
+ */
+void
+attach_dictionary_to_treeview (GtkTreeView *treeview, PsppireDict *dict,
+                              GtkSelectionMode mode,
+                              var_predicate_func *predicate
+                              )
+{
+  GtkTreeViewColumn *col;
+
+  GtkTreeSelection *selection =
+    gtk_tree_view_get_selection (treeview);
+
+  GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+  GtkTreeModel *model ;
+
+  if ( predicate )
+    {
+      model = gtk_tree_model_filter_new (GTK_TREE_MODEL (dict),
+                                         NULL);
+
+      gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (model),
+                                             filter_variables,
+                                             predicate,
+                                             NULL);
+    }
+  else
+    {
+      model = GTK_TREE_MODEL (dict);
+    }
+
+  gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), model);
+
+
+
+  col = gtk_tree_view_column_new_with_attributes (_("Var"),
+                                                 renderer,
+                                                 "text",
+                                                 0,
+                                                 NULL);
+
+  /* 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 (treeview, col);
+
+  gtk_tree_selection_set_mode (selection, mode);
+}
+
+
+void
+insert_source_row_into_entry (GtkTreeIter iter,
+                             GtkWidget *dest,
+                             GtkTreeModel *model
+                             )
+{
+  GtkTreePath *path;
+  PsppireDict *dict;
+  gint *idx;
+  struct variable *var;
+  GtkTreeIter dict_iter;
+  gchar *name;
+
+  g_return_if_fail (GTK_IS_ENTRY(dest));
+
+
+  if ( GTK_IS_TREE_MODEL_FILTER (model))
+    {
+      dict = PSPPIRE_DICT (gtk_tree_model_filter_get_model
+                          (GTK_TREE_MODEL_FILTER(model)));
+      gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER
+                                                       (model),
+                                                       &dict_iter, &iter);
+    }
+  else
+    {
+      dict = PSPPIRE_DICT (model);
+      dict_iter = iter;
+    }
+
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (dict), &dict_iter);
+
+  idx = gtk_tree_path_get_indices (path);
+
+  var =  psppire_dict_get_variable (dict, *idx);
+
+  gtk_tree_path_free (path);
+
+  name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL);
+  gtk_entry_set_text (GTK_ENTRY (dest),  name);
+  g_free (name);
+}
+
+
+
+void
+insert_source_row_into_tree_view (GtkTreeIter iter,
+                                 GtkWidget *dest,
+                                 GtkTreeModel *model
+                                 )
+{
+  GtkTreePath *path;
+  GtkTreeIter dest_iter;
+  GtkTreeIter dict_iter;
+  gint *row ;
+  GtkTreeModel *destmodel = gtk_tree_view_get_model ( GTK_TREE_VIEW (dest));
+
+  PsppireDict *dict;
+
+  if ( GTK_IS_TREE_MODEL_FILTER (model))
+    {
+      dict = PSPPIRE_DICT (gtk_tree_model_filter_get_model
+                          (GTK_TREE_MODEL_FILTER(model)));
+      gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER
+                                                       (model),
+                                                       &dict_iter, &iter);
+    }
+  else
+    {
+      dict = PSPPIRE_DICT (model);
+      dict_iter = iter;
+    }
+
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (dict), &dict_iter);
+
+  row = gtk_tree_path_get_indices (path);
+
+  gtk_list_store_append (GTK_LIST_STORE (destmodel),  &dest_iter);
+  gtk_list_store_set (GTK_LIST_STORE (destmodel), &dest_iter, 0, *row, -1);
+
+  gtk_tree_path_free (path);
+}
+
+
+gboolean
+is_currently_in_entry (GtkTreeModel *model, GtkTreeIter *iter,
+                      PsppireSelector *selector)
+{
+  gboolean result;
+  gchar *name;
+  GtkTreeIter dict_iter;
+  PsppireDict *dict;
+  struct variable *var;
+  gint dict_index;
+  gint *indeces;
+  GtkTreePath *path;
+  const gchar *text =   gtk_entry_get_text (GTK_ENTRY (selector->dest));
+
+
+  if ( GTK_IS_TREE_MODEL_FILTER (model))
+    {
+      dict = PSPPIRE_DICT (gtk_tree_model_filter_get_model
+                          (GTK_TREE_MODEL_FILTER(model)));
+      gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER
+                                                       (model),
+                                                       &dict_iter, iter);
+    }
+  else
+    {
+      dict = PSPPIRE_DICT (model);
+      dict_iter = *iter;
+    }
+
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL(dict),
+                                 &dict_iter);
+
+  indeces = gtk_tree_path_get_indices (path);
+
+  dict_index = indeces [0];
+
+  var = psppire_dict_get_variable (dict, dict_index);
+
+  gtk_tree_path_free (path);
+
+  name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL);
+  result = ( 0 == strcmp (text, name));
+  g_free (name);
+
+  return result;
+}
+
+
diff --git a/src/ui/gui/dict-display.h b/src/ui/gui/dict-display.h
new file mode 100644 (file)
index 0000000..71479ba
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+   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. */
+
+
+/* This module provides various functions necessary for displaying a
+   dictionary in  GTK widgets.
+*/
+
+#include <gtk/gtk.h>
+
+#include "psppire-selector.h"
+#include "psppire-dict.h"
+#include <data/variable.h>
+
+/* Sets up TREEVIEW to display the variables of DICT.
+   MODE is the selection mode for TREEVIEW.
+   PREDICATE determines which variables should be visible, or NULL if
+   all are to be visible.
+ */
+void attach_dictionary_to_treeview (GtkTreeView *treeview, PsppireDict *dict,
+                                   GtkSelectionMode mode,
+                                   var_predicate_func *predicate
+                                   );
+
+
+/* A SelectItemsFunc function for GtkTreeView widgets */
+void insert_source_row_into_tree_view (GtkTreeIter source_iter,
+                                      GtkWidget *dest,
+                                      GtkTreeModel *source_model
+                                      );
+
+
+/* A SelectItemsFunc function for GtkEntry widgets */
+void insert_source_row_into_entry (GtkTreeIter source_iter,
+                                  GtkWidget *dest,
+                                  GtkTreeModel *source_model
+                                  );
+
+
+
+/* A FilterItemsFunc function for GtkEntry widgets */
+gboolean is_currently_in_entry (GtkTreeModel *model, GtkTreeIter *iter,
+                               PsppireSelector *selector);
index b4b3a5b9e940ad4d702e26f5b596f64ab96fd2f9..3c2882385e23ccfb9dabd06614f85c76a1e6a336 100644 (file)
@@ -1,6 +1,7 @@
 #include <glade/glade-build.h>
 #include "psppire-dialog.h"
 #include "psppire-buttonbox.h"
+#include "psppire-selector.h"
 
 GLADE_MODULE_CHECK_INIT
 
@@ -28,6 +29,10 @@ glade_module_register_widgets (void)
   glade_register_widget (PSPPIRE_BUTTONBOX_TYPE, NULL,
                         glade_standard_build_children,
                         NULL);
+
+  glade_register_widget (PSPPIRE_SELECTOR_TYPE, NULL,
+                        glade_standard_build_children,
+                        NULL);
 }
 
 
index e14ab06ad76a5a7d0ebc39ef5b2f70a941de1016..bd6e2198f4efc7ca276dc2b04cc79645e4338534 100644 (file)
@@ -90,8 +90,9 @@ get_widget_assert (GladeXML *xml, const gchar *name)
   return w;
 }
 
-/* Converts a string in the pspp locale to utf-8 */
-char *
+/* Converts a string in the pspp locale to utf-8.
+   The return value must be freed when no longer required*/
+gchar *
 pspp_locale_to_utf8 (const gchar *text, gssize len, GError **err)
 {
   return recode_string (CONV_PSPP_TO_UTF8, text, len);
index fda121605a467dee5c5089c2a302780857554a6f..ec50b1525b74d516de207ddd4e8a33277cdb06a8 100644 (file)
@@ -21,7 +21,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-#include "psppire-object.h"
 #include "psppire-case-file.h"
 
 #include <gtksheet/gtkextra-marshal.h>
@@ -75,7 +74,7 @@ psppire_case_file_get_type (void)
        (GInstanceInitFunc) psppire_case_file_init,
       };
 
-      object_type = g_type_register_static (G_TYPE_PSPPIRE_OBJECT, "PsppireCaseFile",
+      object_type = g_type_register_static (G_TYPE_OBJECT, "PsppireCaseFile",
                                            &object_info, 0);
     }
 
index b4503125609fa8a941741f096c9f6f78b32f457d..42025f2dc7598fe50f9cdb5dcff30f816ab14952 100644 (file)
@@ -1,21 +1,21 @@
 /*
-    PSPPIRE --- A Graphical User Interface for PSPP
-    Copyright (C) 2004, 2006, 2007  Free Software Foundation
+  PSPPIRE --- A Graphical User Interface for PSPP
+  Copyright (C) 2004, 2006, 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 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.
+  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. */
+  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 <string.h>
@@ -24,7 +24,6 @@
 #include <gtk/gtk.h>
 #include <gtksheet/gtkextra-marshal.h>
 
-#include "psppire-object.h"
 #include "psppire-dict.h"
 #include <data/format.h>
 #include <data/dictionary.h>
@@ -32,6 +31,7 @@
 #include <data/value-labels.h>
 #include <data/variable.h>
 
+#include "helper.h"
 #include "message-dialog.h"
 
 /* --- prototypes --- */
@@ -86,12 +86,12 @@ psppire_dict_get_type (void)
        NULL
       };
 
-      object_type = g_type_register_static (G_TYPE_PSPPIRE_OBJECT,
+      object_type = g_type_register_static (G_TYPE_OBJECT,
                                            "PsppireDict",
                                            &object_info, 0);
 
       g_type_add_interface_static (object_type, GTK_TYPE_TREE_MODEL,
-                                 &tree_model_info);
+                                  &tree_model_info);
 
 
     }
@@ -302,14 +302,14 @@ auto_generate_var_name (PsppireDict *dict)
 
 /* Insert a new variable at posn IDX, with the name NAME.
    If NAME is null, then a name will be automatically assigned.
- */
+*/
 void
 psppire_dict_insert_variable (PsppireDict *d, gint idx, const gchar *name)
 {
   struct variable *var ;
   g_return_if_fail (idx >= 0);
   g_return_if_fail (d);
-  g_return_if_fail (G_IS_PSPPIRE_DICT (d));
+  g_return_if_fail (PSPPIRE_IS_DICT (d));
 
   if ( ! name )
     name = auto_generate_var_name (d);
@@ -326,7 +326,7 @@ psppire_dict_delete_variables (PsppireDict *d, gint first, gint n)
   gint idx;
   g_return_if_fail (d);
   g_return_if_fail (d->dict);
-  g_return_if_fail (G_IS_PSPPIRE_DICT (d));
+  g_return_if_fail (PSPPIRE_IS_DICT (d));
 
   for (idx = 0 ; idx < n ; ++idx )
     {
@@ -348,7 +348,7 @@ psppire_dict_set_name (PsppireDict* d, gint idx, const gchar *name)
 {
   struct variable *var;
   g_assert (d);
-  g_assert (G_IS_PSPPIRE_DICT (d));
+  g_assert (PSPPIRE_IS_DICT (d));
 
 
   if ( idx < dict_get_var_cnt (d->dict))
@@ -422,10 +422,10 @@ psppire_dict_clear (PsppireDict *d)
 */
 gboolean
 psppire_dict_check_name (const PsppireDict *dict,
-                    const gchar *name, gboolean report)
+                        const gchar *name, gboolean report)
 {
   if ( ! var_is_valid_name (name, report ) )
-      return FALSE;
+    return FALSE;
 
   if (psppire_dict_lookup_var (dict, name))
     {
@@ -461,8 +461,8 @@ psppire_dict_resize_variable (PsppireDict *d, const struct variable *pv,
   fv = var_get_case_index (pv);
 
   g_signal_emit (d, signals [VARIABLE_RESIZED], 0,
-               fv + old_size,
-               new_size - old_size );
+                fv + old_size,
+                new_size - old_size );
 }
 
 
@@ -488,6 +488,19 @@ static void tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter,
 static gboolean tree_model_nth_child (GtkTreeModel *model, GtkTreeIter *iter,
                                      GtkTreeIter *parent, gint n);
 
+static gint tree_model_n_children (GtkTreeModel *tree_model,
+                                  GtkTreeIter  *iter);
+
+static gboolean tree_model_iter_children (GtkTreeModel *,
+                                         GtkTreeIter *,
+                                         GtkTreeIter *);
+
+static gboolean tree_model_iter_parent (GtkTreeModel *tree_model,
+                                       GtkTreeIter *iter,
+                                       GtkTreeIter *child);
+
+static gboolean tree_model_iter_has_child  (GtkTreeModel *tree_model,
+                                           GtkTreeIter  *iter);
 
 static void
 dictionary_tree_model_init (GtkTreeModelIface *iface)
@@ -500,17 +513,32 @@ dictionary_tree_model_init (GtkTreeModelIface *iface)
   iface->get_path = tree_model_get_path;
   iface->get_value = tree_model_get_value;
 
-  iface->iter_children = 0;
-  iface->iter_has_child =0;
-  iface->iter_n_children =0;
+  iface->iter_children = tree_model_iter_children ;
+  iface->iter_has_child = tree_model_iter_has_child ;
+  iface->iter_n_children = tree_model_n_children ;
   iface->iter_nth_child = tree_model_nth_child ;
-  iface->iter_parent =0;
+  iface->iter_parent = tree_model_iter_parent ;
+}
+
+static gboolean
+tree_model_iter_has_child  (GtkTreeModel *tree_model,
+                           GtkTreeIter  *iter)
+{
+  return FALSE;
+}
+
+static gboolean
+tree_model_iter_parent (GtkTreeModel *tree_model,
+                       GtkTreeIter *iter,
+                       GtkTreeIter *child)
+{
+  return TRUE;
 }
 
 static GtkTreeModelFlags
 tree_model_get_flags (GtkTreeModel *model)
 {
-  g_return_val_if_fail (G_IS_PSPPIRE_DICT (model), (GtkTreeModelFlags) 0);
+  g_return_val_if_fail (PSPPIRE_IS_DICT (model), (GtkTreeModelFlags) 0);
 
   return GTK_TREE_MODEL_LIST_ONLY;
 }
@@ -525,7 +553,7 @@ tree_model_n_columns (GtkTreeModel *model)
 static GType
 tree_model_column_type (GtkTreeModel *model, gint index)
 {
-  g_return_val_if_fail (G_IS_PSPPIRE_DICT (model), (GType) 0);
+  g_return_val_if_fail (PSPPIRE_IS_DICT (model), (GType) 0);
 
   switch (index)
     {
@@ -549,7 +577,7 @@ tree_model_get_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path)
 {
   gint *indices, depth;
   gint n;
-  struct variable *variable;
+  struct variable *var;
 
   PsppireDict *dict = PSPPIRE_DICT (model);
 
@@ -560,17 +588,21 @@ tree_model_get_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path)
 
   g_return_val_if_fail (depth == 1, FALSE);
 
-  n = indices[0];
+  n = indices [0];
 
   if ( n < 0 || n >= psppire_dict_get_var_cnt (dict))
-    return FALSE;
+    {
+      iter->stamp = 0;
+      iter->user_data = NULL;
+      return FALSE;
+    }
 
-  variable = dict_get_var (dict->dict, n);
+  var = psppire_dict_get_variable (dict, n);
 
-  g_assert (var_get_dict_index (variable) == n);
+  g_assert (var_get_dict_index (var) == n);
 
   iter->stamp = dict->stamp;
-  iter->user_data = variable;
+  iter->user_data = var;
 
   return TRUE;
 }
@@ -580,7 +612,7 @@ static gboolean
 tree_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter)
 {
   PsppireDict *dict = PSPPIRE_DICT (model);
-  struct variable *variable;
+  struct variable *var;
   gint idx;
 
   g_return_val_if_fail (iter->stamp == dict->stamp, FALSE);
@@ -588,18 +620,22 @@ tree_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter)
   if ( iter == NULL || iter->user_data == NULL)
     return FALSE;
 
-  variable = (struct variable *) iter->user_data;
+  var = iter->user_data;
 
-  idx = var_get_dict_index (variable);
+  idx = var_get_dict_index (var);
 
   if ( idx + 1 >= psppire_dict_get_var_cnt (dict))
-    return FALSE;
+    {
+      iter->user_data = NULL;
+      iter->stamp = 0;
+      return FALSE;
+    }
 
-  variable = psppire_dict_get_variable (dict, idx + 1);
+  var = psppire_dict_get_variable (dict, idx + 1);
 
-  g_assert (var_get_dict_index (variable) == idx + 1);
+  g_assert (var_get_dict_index (var) == idx + 1);
 
-  iter->user_data = variable;
+  iter->user_data = var;
 
   return TRUE;
 }
@@ -608,15 +644,15 @@ static GtkTreePath *
 tree_model_get_path (GtkTreeModel *model, GtkTreeIter *iter)
 {
   GtkTreePath *path;
-  struct variable *variable;
+  struct variable *var;
   PsppireDict *dict = PSPPIRE_DICT (model);
 
   g_return_val_if_fail (iter->stamp == dict->stamp, FALSE);
 
-  variable = (struct variable *) iter->user_data;
+  var = iter->user_data;
 
   path = gtk_tree_path_new ();
-  gtk_tree_path_append_index (path, var_get_dict_index (variable));
+  gtk_tree_path_append_index (path, var_get_dict_index (var));
 
   return path;
 }
@@ -624,24 +660,28 @@ tree_model_get_path (GtkTreeModel *model, GtkTreeIter *iter)
 
 static void
 tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter,
-                    gint column, GValue *value)
+                     gint column, GValue *value)
 {
-  struct variable *variable;
+  struct variable *var;
   PsppireDict *dict = PSPPIRE_DICT (model);
 
   g_return_if_fail (iter->stamp == dict->stamp);
 
-  variable = (struct variable *) iter->user_data;
+  var =  iter->user_data;
 
   switch (column)
     {
     case DICT_TVM_COL_NAME:
+      {
+      gchar *name = pspp_locale_to_utf8(var_get_name (var), -1, NULL);
       g_value_init (value, G_TYPE_STRING);
-      g_value_set_string (value, var_get_name (variable));
+      g_value_set_string (value, name);
+      g_free (name);
+      }
       break;
     case DICT_TVM_COL_VAR:
       g_value_init (value, G_TYPE_POINTER);
-      g_value_set_pointer (value, variable);
+      g_value_set_pointer (value, var);
       break;
     default:
       g_return_if_reached ();
@@ -649,13 +689,33 @@ tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter,
     }
 }
 
+static gboolean
+tree_model_iter_children (GtkTreeModel *tree_model,
+                         GtkTreeIter *iter,
+                         GtkTreeIter *parent)
+{
+  return FALSE;
+}
+
+static gint
+tree_model_n_children (GtkTreeModel *model,
+                      GtkTreeIter  *iter)
+{
+  PsppireDict *dict = PSPPIRE_DICT (model);
+
+  if ( iter == NULL )
+    return psppire_dict_get_var_cnt (dict);
+
+  return 0;
+}
 
 static gboolean
 tree_model_nth_child (GtkTreeModel *model, GtkTreeIter *iter,
-                    GtkTreeIter *parent, gint n)
+                     GtkTreeIter *parent, gint n)
 {
   PsppireDict *dict;
-  g_return_val_if_fail (G_IS_PSPPIRE_DICT (model), FALSE);
+
+  g_return_val_if_fail (PSPPIRE_IS_DICT (model), FALSE);
 
   dict = PSPPIRE_DICT (model);
 
@@ -671,7 +731,6 @@ tree_model_nth_child (GtkTreeModel *model, GtkTreeIter *iter,
   if ( !iter->user_data)
     return FALSE;
 
-
   return TRUE;
 }
 
index 42a13c635244fd0908b1f0252048bf656ec0cfb4..f070bfeb25af4c85c6dd1564041a9939bf535eb0 100644 (file)
@@ -36,8 +36,8 @@ G_BEGIN_DECLS
 #define G_TYPE_PSPPIRE_DICT              (psppire_dict_get_type ())
 #define PSPPIRE_DICT(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_DICT, PsppireDict))
 #define PSPPIRE_DICT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_DICT, PsppireDictClass))
-#define G_IS_PSPPIRE_DICT(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_DICT))
-#define G_IS_PSPPIRE_DICT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_DICT))
+#define PSPPIRE_IS_DICT(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_DICT))
+#define PSPPIRE_IS_DICT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_DICT))
 #define PSPPIRE_DICT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_DICT, PsppireDictClass))
 
 
diff --git a/src/ui/gui/psppire-object.c b/src/ui/gui/psppire-object.c
deleted file mode 100644 (file)
index 8674f61..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-    PSPPIRE --- A Graphical User Interface for PSPP
-    Copyright (C) 2004  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 <string.h>
-#include <stdlib.h>
-
-#include "psppire-object.h"
-
-
-/* --- prototypes --- */
-static void psppire_object_class_init  (PsppireObjectClass     *class);
-static void psppire_object_init        (PsppireObject          *accel_group);
-static void psppire_object_finalize    (GObject                *object);
-
-
-/* --- variables --- */
-static GObjectClass     *parent_class = NULL;
-
-
-/* --- functions --- */
-/**
- * psppire_object_get_type:
- * @returns: the type ID for accelerator groups.
- */
-GType
-psppire_object_get_type (void)
-{
-  static GType object_type = 0;
-
-  if (!object_type)
-    {
-      static const GTypeInfo object_info = {
-       sizeof (PsppireObjectClass),
-       (GBaseInitFunc) NULL,
-       (GBaseFinalizeFunc) NULL,
-       (GClassInitFunc) psppire_object_class_init,
-       NULL,   /* class_finalize */
-       NULL,   /* class_data */
-       sizeof (PsppireObject),
-       0,      /* n_preallocs */
-       (GInstanceInitFunc) psppire_object_init,
-      };
-
-      object_type = g_type_register_static (G_TYPE_OBJECT, "PsppireObject",
-                                           &object_info, G_TYPE_FLAG_ABSTRACT);
-    }
-
-  return object_type;
-}
-
-static guint signal_changed = 0 ;
-
-static void
-psppire_object_class_init (PsppireObjectClass *class)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-  parent_class = g_type_class_peek_parent (class);
-
-  object_class->finalize = psppire_object_finalize;
-
-   signal_changed =
-     g_signal_new ("changed",
-                  G_OBJECT_CLASS_TYPE (class),
-                  G_SIGNAL_RUN_FIRST,
-                  0,
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__VOID,
-                  G_TYPE_NONE, 0);
-
-}
-
-static void
-psppire_object_finalize (GObject *object)
-{
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-psppire_object_init (PsppireObject *psppire_object)
-{
-
-}
-
-/**
- * psppire_object_new:
- * @returns: a new #PsppireObject object
- *
- * Creates a new #PsppireObject.
- */
-PsppireObject*
-psppire_object_new (void)
-{
-  return g_object_new (G_TYPE_PSPPIRE_OBJECT, NULL);
-}
diff --git a/src/ui/gui/psppire-object.h b/src/ui/gui/psppire-object.h
deleted file mode 100644 (file)
index 240efb3..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-    PSPPIRE --- A Graphical User Interface for PSPP
-    Copyright (C) 2004  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 __PSPPIRE_OBJECT_H__
-#define __PSPPIRE_OBJECT_H__
-
-#include <glib-object.h>
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-
-/* --- type macros --- */
-#define G_TYPE_PSPPIRE_OBJECT              (psppire_object_get_type ())
-#define PSPPIRE_OBJECT(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_OBJECT, PsppireObject))
-#define PSPPIRE_OBJECT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_OBJECT, PsppireObjectClass))
-#define G_IS_PSPPIRE_OBJECT(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_OBJECT))
-#define G_IS_PSPPIRE_OBJECT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_OBJECT))
-#define PSPPIRE_OBJECT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_OBJECT, PsppireObjectClass))
-
-
-
-/* --- typedefs & structures --- */
-typedef struct _PsppireObject     PsppireObject;
-typedef struct _PsppireObjectClass PsppireObjectClass;
-
-
-struct _PsppireObject
-{
-  GObject             parent;
-};
-
-struct _PsppireObjectClass
-{
-  GObjectClass parent_class;
-
-};
-
-
-/* -- PsppireObject --- */
-GType          psppire_object_get_type (void);
-PsppireObject*      psppire_object_new (void);
-
-G_END_DECLS
-
-#endif /* __PSPPIRE_OBJECT_H__ */
diff --git a/src/ui/gui/psppire-selector.c b/src/ui/gui/psppire-selector.c
new file mode 100644 (file)
index 0000000..753a9dc
--- /dev/null
@@ -0,0 +1,598 @@
+/*
+   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. */
+
+/*
+  This module provides a widget, PsppireSelector derived from
+  GtkButton.
+
+  It contains a GtkArrow, and is used for selecting objects from a
+  GtkTreeView and putting them into a destination widget (often
+  another GtkTreeView).  Typically this is used in psppire for
+  selecting variables, thus:
+
+
+  +----------------------------------------------------------+
+  |                                                         |
+  |    Source Widget                       Dest Widget      |
+  |   +----------------+                        +----------------+  |
+  |   |        Variable0      |                 | Variable2      |  |
+  |   |        Variable1      |                 |                |  |
+  |   | Variable3      |                |                |  |
+  |   |                       |    Selector     |                |  |
+  |   |                       |                 |                |  |
+  |   |                       |    +------+     |                |  |
+  |   |                       |    | |\   |     |                |  |
+  |   |                       |    | | \  |     |                |  |
+  |   |                       |    | | /  |     |                |  |
+  |   |                       |    | |/   |     |                |  |
+  |   |                       |    +------+     |                |  |
+  |   |                       |                 |                |  |
+  |   |                       |                 |                |  |
+  |   |                       |                 |                |  |
+  |   |                       |                 |                |  |
+  |   +----------------+                +----------------+  |
+  |                                                         |
+  +----------------------------------------------------------+
+
+  The Source Widget is always a GtkTreeView.  The Dest Widget may be a
+  GtkTreeView or a GtkEntry (other destination widgets may be
+  supported in the future).
+
+  Widgets may be source to more than one PsppireSelector.
+*/
+
+
+#include <config.h>
+
+#include <gtk/gtksignal.h>
+#include <gtk/gtkbutton.h>
+
+#include "psppire-selector.h"
+
+#include <gtk/gtktreeview.h>
+#include <gtk/gtktreeselection.h>
+#include <gtk/gtkwidget.h>
+
+static void psppire_selector_base_finalize (PsppireSelectorClass *, gpointer);
+static void psppire_selector_base_init     (PsppireSelectorClass *class);
+static void psppire_selector_class_init    (PsppireSelectorClass *class);
+static void psppire_selector_init          (PsppireSelector      *selector);
+
+enum  {SELECTED,    /* Emitted when an item is inserted into dest */
+       DE_SELECTED, /* Emitted when an item is removed from dest */
+       n_SIGNALS};
+
+static guint signals [n_SIGNALS];
+
+
+GType
+psppire_selector_get_type (void)
+{
+  static GType psppire_selector_type = 0;
+
+  if (!psppire_selector_type)
+    {
+      static const GTypeInfo psppire_selector_info =
+      {
+       sizeof (PsppireSelectorClass),
+       (GBaseInitFunc) psppire_selector_base_init,
+        (GBaseFinalizeFunc) psppire_selector_base_finalize,
+       (GClassInitFunc)psppire_selector_class_init,
+       (GClassFinalizeFunc) NULL,
+       NULL,
+        sizeof (PsppireSelector),
+       0,
+       (GInstanceInitFunc) psppire_selector_init,
+      };
+
+      psppire_selector_type =
+       g_type_register_static (GTK_TYPE_BUTTON, "PsppireSelector",
+                               &psppire_selector_info, 0);
+    }
+
+  return psppire_selector_type;
+}
+
+
+static void
+psppire_selector_finalize (GObject *object)
+{
+}
+
+
+
+static void
+psppire_selector_class_init (PsppireSelectorClass *class)
+{
+  signals [SELECTED] =
+    g_signal_new ("selected",
+                 G_TYPE_FROM_CLASS (class),
+                 G_SIGNAL_RUN_FIRST,
+                 0,
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE,
+                 0);
+
+  signals [DE_SELECTED] =
+    g_signal_new ("de-selected",
+                 G_TYPE_FROM_CLASS (class),
+                 G_SIGNAL_RUN_FIRST,
+                 0,
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE,
+                 0);
+
+
+}
+
+
+static void
+psppire_selector_base_init (PsppireSelectorClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = psppire_selector_finalize;
+
+  class->source_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+}
+
+
+
+static void
+psppire_selector_base_finalize(PsppireSelectorClass *class,
+                               gpointer class_data)
+{
+  g_hash_table_destroy (class->source_hash);
+}
+
+
+static void
+psppire_selector_init (PsppireSelector *selector)
+{
+  selector->arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE);
+  selector->filtered_source = NULL;
+
+  gtk_container_add (GTK_CONTAINER (selector), selector->arrow);
+
+  gtk_widget_show (selector->arrow);
+
+  /* FIXME: This shouldn't be necessary, but Glade interfaces seem to
+     need it. */
+  gtk_widget_show (GTK_WIDGET (selector));
+}
+
+
+GtkWidget*
+psppire_selector_new (void)
+{
+  return GTK_WIDGET (g_object_new (psppire_selector_get_type (), NULL));
+}
+
+
+static void
+set_direction (PsppireSelector *selector, enum psppire_selector_dir d)
+{
+  selector->direction = 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);
+  else
+    g_object_set (selector->arrow, "arrow-type", GTK_ARROW_LEFT, NULL);
+}
+
+/* Callback for when the source selection changes */
+static void
+on_source_select (GtkTreeSelection *treeselection, gpointer data)
+{
+  PsppireSelector *selector = data;
+
+  set_direction (selector, PSPPIRE_SELECTOR_SOURCE_TO_DEST);
+
+  if ( GTK_IS_ENTRY (selector->dest) )
+    {
+      gtk_widget_set_sensitive (GTK_WIDGET (selector),
+                               gtk_tree_selection_count_selected_rows
+                               (treeselection) <= 1 );
+    }
+}
+
+/* Callback for when the destination treeview selection changes */
+static void
+on_dest_treeview_select (GtkTreeSelection *treeselection, gpointer data)
+{
+  PsppireSelector *selector = data;
+
+  set_direction (selector, PSPPIRE_SELECTOR_DEST_TO_SOURCE);
+}
+
+/* Callback for source deselection, when the dest is GtkEntry */
+static void
+de_select_selection_entry (PsppireSelector *selector)
+{
+  gtk_entry_set_text (GTK_ENTRY (selector->dest), "");
+}
+
+/* Callback for source deselection, when the dest is GtkTreeView */
+static void
+de_select_selection_tree_view (PsppireSelector *selector)
+{
+  GList *item;
+
+  GtkTreeSelection* selection =
+    gtk_tree_view_get_selection ( GTK_TREE_VIEW (selector->dest));
+
+  GtkTreeModel *model =
+    gtk_tree_view_get_model (GTK_TREE_VIEW (selector->dest));
+
+  GList *selected_rows =
+    gtk_tree_selection_get_selected_rows (selection, NULL);
+
+  g_return_if_fail (selector->select_items);
+
+  /* Convert paths to RowRefs */
+  for (item = g_list_first (selected_rows);
+       item != NULL;
+       item = g_list_next (item))
+    {
+      GtkTreeRowReference* rowref;
+      GtkTreePath *path  = item->data;
+
+      rowref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), path);
+
+      item->data = rowref ;
+      gtk_tree_path_free (path);
+    }
+
+  /* Remove each selected row from the dest widget */
+  for (item = g_list_first (selected_rows);
+       item != NULL;
+       item = g_list_next (item))
+    {
+      GtkTreeIter iter;
+      GtkTreeRowReference *rr = item->data;
+
+      GtkTreePath *path = gtk_tree_row_reference_get_path (rr);
+
+      gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+
+      gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+
+      gtk_tree_path_free (path);
+    }
+
+  /* Delete list of RowRefs and its contents */
+  g_list_foreach (selected_rows, (GFunc) gtk_tree_row_reference_free, NULL);
+  g_list_free (selected_rows);
+}
+
+
+/* Removes something from the DEST widget */
+static void
+de_select_selection (PsppireSelector *selector)
+{
+  if ( GTK_IS_TREE_VIEW (selector->dest ) )
+    de_select_selection_tree_view (selector);
+
+  else if ( GTK_IS_ENTRY (selector->dest))
+    de_select_selection_entry (selector);
+
+  else
+    g_assert_not_reached ();
+
+  gtk_tree_model_filter_refilter (selector->filtered_source);
+
+  g_signal_emit (selector, signals [DE_SELECTED], 0);
+}
+
+
+/* Puts something into the DEST widget */
+static void
+select_selection (PsppireSelector *selector)
+{
+  GList *item ;
+  GtkTreeSelection* selection =
+    gtk_tree_view_get_selection ( GTK_TREE_VIEW (selector->source));
+
+  GList *selected_rows =
+    gtk_tree_selection_get_selected_rows (selection, NULL);
+
+  GtkTreeModel *childmodel  = gtk_tree_model_filter_get_model
+    (selector->filtered_source);
+
+  g_return_if_fail (selector->select_items);
+
+
+  for (item = g_list_first (selected_rows);
+       item != NULL;
+       item = g_list_next (item))
+    {
+      GtkTreeIter child_iter;
+      GtkTreeIter iter;
+      GtkTreePath *path  = item->data;
+
+      gtk_tree_model_get_iter (GTK_TREE_MODEL (selector->filtered_source),
+                              &iter, path);
+
+      gtk_tree_model_filter_convert_iter_to_child_iter
+       (selector->filtered_source,
+        &child_iter,
+        &iter);
+
+      selector->select_items (child_iter,
+                             selector->dest,
+                             childmodel);
+    }
+
+  g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
+  g_list_free (selected_rows);
+
+  gtk_tree_model_filter_refilter (selector->filtered_source);
+
+  g_signal_emit (selector, signals [SELECTED], 0);
+}
+
+/* Callback fro then the source treeview is activated (double clicked) */
+static void
+on_row_activate (GtkTreeView       *tree_view,
+                GtkTreePath       *path,
+                GtkTreeViewColumn *column,
+                gpointer           data)
+{
+  PsppireSelector *selector  = data;
+
+  select_selection (selector);
+}
+
+/* Callback for when the selector button is clicked */
+static void
+on_click (PsppireSelector *selector, gpointer data)
+{
+  switch (selector->direction)
+    {
+    case PSPPIRE_SELECTOR_SOURCE_TO_DEST:
+      select_selection (selector);
+      break;
+    case PSPPIRE_SELECTOR_DEST_TO_SOURCE:
+      de_select_selection (selector);
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+}
+
+/* Default visibility filter for GtkTreeView DEST widget */
+static gboolean
+is_item_in_dest (GtkTreeModel *model, GtkTreeIter *iter,
+                PsppireSelector *selector)
+{
+  GtkTreeModel *dest_model;
+  GtkTreeIter dest_iter;
+  GtkTreeIter source_iter;
+  gint index;
+  GtkTreePath *path ;
+  GtkTreeModel *source_model;
+
+  if ( GTK_IS_TREE_MODEL_FILTER (model) )
+    {
+      source_model = gtk_tree_model_filter_get_model
+       (GTK_TREE_MODEL_FILTER (model));
+
+      gtk_tree_model_filter_convert_iter_to_child_iter
+       ( GTK_TREE_MODEL_FILTER (model),  &source_iter,  iter  );
+    }
+  else
+    {
+      source_model = model;
+      source_iter = *iter;
+    }
+
+  dest_model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector->dest));
+
+  path = gtk_tree_model_get_path (source_model, &source_iter);
+
+  index = *gtk_tree_path_get_indices (path);
+
+  gtk_tree_path_free (path);
+
+  if ( ! gtk_tree_model_get_iter_first (dest_model, &dest_iter) )
+    return FALSE;
+
+  do
+    {
+      GValue value = {0};
+      gtk_tree_model_get_value (dest_model, &dest_iter, 0, &value);
+
+      if ( g_value_get_int (&value) == index)
+       return TRUE;
+    }
+  while (gtk_tree_model_iter_next (dest_model, &dest_iter));
+
+  return FALSE;
+}
+
+/* Visibility function for items in the SOURCE widget.
+   Returns TRUE iff *all* the selectors for which SOURCE is associated
+   are visible */
+static gboolean
+is_source_item_visible (GtkTreeModel *childmodel,
+                       GtkTreeIter *iter, gpointer data)
+{
+  PsppireSelector *selector = data;
+  PsppireSelectorClass *class = g_type_class_peek (PSPPIRE_SELECTOR_TYPE);
+
+  GList *list = NULL;
+
+  list = g_hash_table_lookup (class->source_hash, selector->source);
+
+  while (list)
+    {
+      PsppireSelector *selector = list->data;
+
+      if ( selector->filter (childmodel, iter, selector))
+         return FALSE;
+
+      list = list->next;
+    }
+
+
+  return TRUE;
+}
+
+/* set the source widget to SOURCE */
+static void
+set_tree_view_source (PsppireSelector *selector,
+                     GtkTreeView *source)
+{
+  GtkTreeSelection* selection ;
+  GList *list = NULL;
+
+  PsppireSelectorClass *class = g_type_class_peek (PSPPIRE_SELECTOR_TYPE);
+
+  if ( ! (list = g_hash_table_lookup (class->source_hash, source)))
+    {
+      selector->filtered_source =
+       GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new
+                              (gtk_tree_view_get_model (source),  NULL));
+
+      gtk_tree_view_set_model (source, NULL);
+
+      gtk_tree_view_set_model (source,
+                              GTK_TREE_MODEL (selector->filtered_source));
+
+      list = g_list_append (list, selector);
+      g_hash_table_insert (class->source_hash, source, list);
+
+
+      gtk_tree_model_filter_set_visible_func (selector->filtered_source,
+                                             is_source_item_visible,
+                                             selector,
+                                             NULL);
+    }
+  else
+    {  /* Append this selector to the list and push the <source,list>
+         pair onto the hash table */
+
+      selector->filtered_source = GTK_TREE_MODEL_FILTER (
+       gtk_tree_view_get_model (source));
+
+      list = g_list_append (list, selector);
+      g_hash_table_replace (class->source_hash, source, list);
+    }
+
+  selection = gtk_tree_view_get_selection (source);
+
+  g_signal_connect (source, "row-activated", G_CALLBACK (on_row_activate),
+                   selector);
+
+  g_signal_connect (selection, "changed", G_CALLBACK (on_source_select),
+                   selector);
+}
+
+
+/* Set the destination widget to DEST */
+static void
+set_tree_view_dest (PsppireSelector *selector,
+                   GtkTreeView *dest)
+{
+  GtkTreeSelection* selection = gtk_tree_view_get_selection (dest);
+
+  gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+
+  g_signal_connect (selection, "changed", G_CALLBACK (on_dest_treeview_select),
+                   selector);
+}
+
+/* Callback for when the DEST GtkEntry is activated (Enter is pressed) */
+static void
+on_entry_activate (GtkEntry *w, gpointer data)
+{
+  PsppireSelector * selector = data;
+
+  gtk_tree_model_filter_refilter (selector->filtered_source);
+}
+
+/* Callback for when the DEST GtkEntry is selected (clicked) */
+static gboolean
+on_entry_dest_select (GtkWidget *widget, GdkEventFocus *event, gpointer data)
+{
+  PsppireSelector * selector = data;
+
+  set_direction (selector, PSPPIRE_SELECTOR_DEST_TO_SOURCE);
+
+  return FALSE;
+}
+
+/* Set DEST to be the destination GtkEntry widget */
+static void
+set_entry_dest (PsppireSelector *selector,
+               GtkEntry *dest)
+{
+  g_signal_connect (dest, "activate", G_CALLBACK (on_entry_activate),
+                   selector);
+
+  g_signal_connect (dest, "focus-in-event", G_CALLBACK (on_entry_dest_select),
+                   selector);
+}
+
+
+/* Set SOURCE and DEST for this selector, and
+   set SELECT_FUNC and FILTER_FUNC */
+void
+psppire_selector_set_subjects (PsppireSelector *selector,
+                              GtkWidget *source,
+                              GtkWidget *dest,
+                              SelectItemsFunc *select_func,
+                              FilterItemsFunc *filter_func )
+{
+  selector->filter = filter_func ;
+
+  selector->source = source;
+  selector->dest = dest;
+
+  if ( filter_func == NULL)
+    {
+      if  (GTK_IS_TREE_VIEW (dest))
+       selector->filter = is_item_in_dest;
+    }
+
+  g_signal_connect (selector, "clicked", G_CALLBACK (on_click), NULL);
+
+  if ( GTK_IS_TREE_VIEW (source))
+    set_tree_view_source (selector, GTK_TREE_VIEW (source) );
+  else
+    g_error ("Unsupported source widget: %s", G_OBJECT_TYPE_NAME (source));
+
+  g_assert ( GTK_IS_TREE_MODEL_FILTER (selector->filtered_source));
+
+  if  ( GTK_IS_TREE_VIEW (dest))
+    set_tree_view_dest (selector, GTK_TREE_VIEW (dest));
+
+  else if ( GTK_IS_ENTRY (dest))
+    set_entry_dest (selector, GTK_ENTRY (dest));
+
+  else
+    g_error ("Unsupported destination widget: %s", G_OBJECT_TYPE_NAME (dest));
+
+  selector->select_items = select_func;
+}
diff --git a/src/ui/gui/psppire-selector.h b/src/ui/gui/psppire-selector.h
new file mode 100644 (file)
index 0000000..7ba88a9
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+   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 __PSPPIRE_SELECTOR_H__
+#define __PSPPIRE_SELECTOR_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkarrow.h>
+#include <gtk/gtktreemodel.h>
+#include <gtk/gtktreemodelfilter.h>
+
+G_BEGIN_DECLS
+
+#define PSPPIRE_SELECTOR_TYPE            (psppire_selector_get_type ())
+#define PSPPIRE_SELECTOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_SELECTOR_TYPE, PsppireSelector))
+#define PSPPIRE_SELECTOR_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), \
+    PSPPIRE_SELECTOR_TYPE, PsppireSelectorClass))
+#define PSPPIRE_IS_SELECTOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+    PSPPIRE_SELECTOR_TYPE))
+#define PSPPIRE_IS_SELECTOR_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+    PSPPIRE_SELECTOR_TYPE))
+
+
+typedef struct _PsppireSelector       PsppireSelector;
+typedef struct _PsppireSelectorClass  PsppireSelectorClass;
+
+
+/* Function for appending selected items to the destination widget */
+typedef void SelectItemsFunc (GtkTreeIter iter,
+                             GtkWidget *dest,
+                             GtkTreeModel *source_model);
+
+
+/* Function to determine whether an item in MODEL, pointed to by ITER
+   is currently selected.
+
+   Returns TRUE if the item is currently selected, FALSE otherwise.
+ */
+typedef gboolean FilterItemsFunc (GtkTreeModel *model,
+                                 GtkTreeIter *iter,
+                                 PsppireSelector *selector);
+
+enum psppire_selector_dir
+  {
+    PSPPIRE_SELECTOR_SOURCE_TO_DEST,
+    PSPPIRE_SELECTOR_DEST_TO_SOURCE
+  };
+
+
+struct _PsppireSelector
+{
+  GtkButton parent;
+
+  /* <private> */
+  GtkWidget *arrow;
+
+  enum psppire_selector_dir direction;
+  GtkWidget *source;
+  GtkWidget *dest;
+
+
+  GtkTreeModelFilter *filtered_source;
+
+  SelectItemsFunc *select_items;
+  FilterItemsFunc *filter;
+};
+
+struct _PsppireSelectorClass
+{
+  GtkButtonClass parent_class;
+
+  /* This is a hash of Lists of FilterItemsFunc pointers, keyed by address of
+     the source widget */
+  GHashTable *source_hash;
+};
+
+GType      psppire_selector_get_type        (void);
+GtkWidget* psppire_selector_new             (void);
+void       psppire_selector_set_subjects    (PsppireSelector *,
+                                            GtkWidget *,
+                                            GtkWidget *,
+                                            SelectItemsFunc *,
+                                            FilterItemsFunc * );
+G_END_DECLS
+
+#endif /* __PSPPIRE_SELECTOR_H__ */
diff --git a/src/ui/gui/psppire-var-select.c b/src/ui/gui/psppire-var-select.c
deleted file mode 100644 (file)
index b4c32b6..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
-    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 "psppire-var-select.h"
-#include "psppire-object.h"
-
-#include "psppire-dict.h"
-
-#include <gettext.h>
-
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-
-/* This object is an attempt to abstract a situation commonly found in PSPP
-   dialogs, where two widgets (typically GtkTreeViews) contain a list
-   of variables,  and the variables may be selected by the user and
-   transfered to between the widgets, in preparation for some
-   operation.
-
-   Currently it assumes that the first widget is  GtkTreeView and the
-   second is a GtkEntry (as required for the Weight Cases dialog).
-   It needs to be generalized further to make  it useful.
-*/
-
-static void setup_dictionary_treeview (GtkTreeView *,
-                                      const PsppireDict *,
-                                      GtkSelectionMode);
-
-
-/* --- prototypes --- */
-static void psppire_var_select_class_init (PsppireVarSelectClass *);
-static void psppire_var_select_init         (PsppireVarSelect *);
-static void psppire_var_select_finalize   (GObject *);
-
-
-enum  {VARIABLE_SELECTED,
-       DESELECT_ALL,
-       n_SIGNALS};
-
-static guint signals [n_SIGNALS];
-
-
-/* --- variables --- */
-static GObjectClass     *parent_class = NULL;
-
-/* --- functions --- */
-/**
- * psppire_var_select_get_type:
- * @returns: the type ID for accelerator groups.
- */
-GType
-psppire_var_select_get_type (void)
-{
-  static GType object_type = 0;
-
-  if (!object_type)
-    {
-      static const GTypeInfo object_info = {
-       sizeof (PsppireVarSelectClass),
-       (GBaseInitFunc) NULL,
-       (GBaseFinalizeFunc) NULL,
-       (GClassInitFunc) psppire_var_select_class_init,
-       NULL,   /* class_finalize */
-       NULL,   /* class_data */
-       sizeof (PsppireVarSelect),
-       0,      /* n_preallocs */
-       (GInstanceInitFunc) psppire_var_select_init,
-      };
-
-      object_type = g_type_register_static (G_TYPE_PSPPIRE_OBJECT,
-                                           "PsppireVarSelect",
-                                           &object_info, 0);
-    }
-
-  return object_type;
-}
-
-
-static void
-psppire_var_select_class_init (PsppireVarSelectClass *class)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-  parent_class = g_type_class_peek_parent (class);
-
-
-  signals [VARIABLE_SELECTED] =
-    g_signal_new ("variable_selected",
-                 G_TYPE_FROM_CLASS (class),
-                 G_SIGNAL_RUN_FIRST,
-                 0,
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__INT,
-                 G_TYPE_NONE,
-                 1,
-                 G_TYPE_INT);
-
-
-  signals [DESELECT_ALL] =
-    g_signal_new ("deselect_all",
-                 G_TYPE_FROM_CLASS (class),
-                 G_SIGNAL_RUN_FIRST,
-                 0,
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__VOID,
-                 G_TYPE_NONE,
-                 0);
-
-  object_class->finalize = psppire_var_select_finalize;
-}
-
-static void
-psppire_var_select_finalize (GObject *object)
-{
-  PsppireVarSelect *vs = PSPPIRE_VAR_SELECT (object);
-
-  g_list_free (vs->list);
-
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-psppire_var_select_init (PsppireVarSelect *vs)
-{
-  vs->list = NULL;
-  vs->mode = GTK_SELECTION_SINGLE;
-}
-
-/* Return list of all the currently selected variables */
-const GList *
-psppire_var_select_get_variables (PsppireVarSelect *vs)
-{
-  return vs->list;
-}
-
-
-static void
-add_variable_to_selection (PsppireVarSelect *vs, struct variable *var)
-{
-  gtk_entry_set_text (GTK_ENTRY (vs->dest), var_get_name (var) );
-
-  if ( vs->mode == GTK_SELECTION_SINGLE)
-    {
-      g_list_free (vs->list);
-      vs->list = NULL;
-    }
-  vs->list = g_list_append (vs->list, var);
-
-  g_signal_emit (vs, signals [VARIABLE_SELECTED], 0, var_get_dict_index (var));
-}
-
-
-/* Add VAR to the list of selected variables */
-void
-psppire_var_select_set_variable (PsppireVarSelect *vs,
-                                struct variable *var)
-{
-  add_variable_to_selection (vs, var);
-}
-
-
-static void
-on_source_activate (GtkTreeView       *tree_view,
-                   GtkTreePath       *path,
-                   GtkTreeViewColumn *column,
-                   gpointer           user_data)
-
-{
-  PsppireVarSelect *vs = user_data;
-  GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
-
-  GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
-
-  GList *list = gtk_tree_selection_get_selected_rows (selection, &model);
-
-  while (list)
-    {
-      struct variable *var;
-      GtkTreeIter iter;
-      GtkTreePath *path = list->data;
-
-      gtk_tree_model_get_iter (model, &iter, path);
-
-      gtk_tree_model_get (model, &iter, DICT_TVM_COL_VAR, &var, -1);
-
-      add_variable_to_selection (vs, var);
-
-      list = list->next;
-    }
-}
-
-
-/**
- * psppire_var_select_new:
- * @returns: a new #PsppireVarSelect object
- *
- * Creates a new #PsppireVarSelect.
- */
-PsppireVarSelect*
-psppire_var_select_new (GtkWidget *source, GtkWidget *dest,
-                       const PsppireDict *dict)
-{
-  PsppireVarSelect *vs
-    = g_object_new (G_TYPE_PSPPIRE_VAR_SELECT, NULL);
-
-  GtkTreeSelection *src_selection;
-
-  vs->source = source;
-  vs->dest = dest;
-  vs->dict = dict;
-
-
-  setup_dictionary_treeview ( GTK_TREE_VIEW (source),
-                             vs->dict, vs->mode);
-
-
-  src_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (vs->source));
-
-  g_signal_connect (source, "row-activated",
-                   G_CALLBACK (on_source_activate), vs);
-
-  return vs;
-}
-
-void
-psppire_var_select_deselect_all (PsppireVarSelect *vs)
-{
-  g_list_free (vs->list);
-  vs->list = NULL;
-
-  gtk_entry_set_text ( GTK_ENTRY(vs->dest), "");
-
-  g_signal_emit (vs, signals [DESELECT_ALL], 0);
-}
-
-
-static void
-setup_dictionary_treeview (GtkTreeView *treeview, const PsppireDict *dict,
-                          GtkSelectionMode mode)
-{
-  /* Set up the dictionary treeview */
-  GtkTreeViewColumn *col;
-
-  GtkTreeSelection *selection =
-    gtk_tree_view_get_selection (treeview);
-
-  GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
-
-
-  gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (dict));
-
-  col = gtk_tree_view_column_new_with_attributes (_("Var"),
-                                                 renderer,
-                                                 "text",
-                                                 0,
-                                                 NULL);
-
-  /* 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 (treeview, col);
-
-  gtk_tree_selection_set_mode (selection, mode);
-}
-
-
-
-
diff --git a/src/ui/gui/psppire-var-select.h b/src/ui/gui/psppire-var-select.h
deleted file mode 100644 (file)
index b169b52..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-    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 __PSPPIRE_VAR_SELECT_H__
-#define __PSPPIRE_VAR_SELECT_H__
-
-
-#include <glib-object.h>
-#include <glib.h>
-
-#include <gtk/gtk.h>
-#include "psppire-dict.h"
-
-G_BEGIN_DECLS
-
-
-/* --- type macros --- */
-#define G_TYPE_PSPPIRE_VAR_SELECT              (psppire_var_select_get_type ())
-#define PSPPIRE_VAR_SELECT(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_VAR_SELECT, PsppireVarSelect))
-#define PSPPIRE_VAR_SELECT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_VAR_SELECT, PsppireVarSelectClass))
-#define G_IS_PSPPIRE_VAR_SELECT(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_VAR_SELECT))
-#define G_IS_PSPPIRE_VAR_SELECT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_VAR_SELECT))
-#define PSPPIRE_VAR_SELECT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_VAR_SELECT, PsppireVarSelectClass))
-
-
-
-/* --- typedefs & structures --- */
-typedef struct _PsppireVarSelect          PsppireVarSelect;
-typedef struct _PsppireVarSelectClass PsppireVarSelectClass;
-
-struct _PsppireVarSelect
-{
-  GObject             parent;
-  const PsppireDict   *dict;
-
-
-  /* <private> */
-  GtkSelectionMode    mode;
-  GtkWidget           *source;
-  GtkWidget           *dest;
-  GList               *list;
-};
-
-struct _PsppireVarSelectClass
-{
-  GObjectClass parent_class;
-};
-
-
-/* -- PsppireVarSelect --- */
-GType          psppire_var_select_get_type (void);
-
-
-PsppireVarSelect* psppire_var_select_new    (GtkWidget *,
-                                            GtkWidget *,
-                                            const PsppireDict *);
-
-/* Remove all variables from the selection */
-void         psppire_var_select_deselect_all  (PsppireVarSelect *);
-
-/* Return a list of all the currently selected variables */
-const GList *psppire_var_select_get_variables (PsppireVarSelect *);
-
-/* Append VAR to the list of selected variables */
-void         psppire_var_select_set_variable  (PsppireVarSelect *,
-                                              struct variable *var);
-
-G_END_DECLS
-
-#endif /* __PSPPIRE_VAR_SELECT_H__ */
index 80a4dfc201f2efcbc238a62274a26de7511de71f..0a4e6dfab3fec7619a0092371b298181d41fe393 100644 (file)
@@ -62,7 +62,7 @@
                 <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
                 <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
                 <child>
-                  <widget class="GtkTreeView" id="treeview">
+                  <widget class="GtkTreeView" id="weight-cases-treeview">
                     <property name="visible">True</property>
                     <property name="headers_visible">False</property>
                     <property name="fixed_height_mode">True</property>
@@ -84,7 +84,8 @@
                         <property name="visible">True</property>
                         <property name="border_width">5</property>
                         <child>
-                          <widget class="GtkRadioButton" id="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 class="GtkRadioButton" id="radiobutton2">
                             <property name="visible">True</property>
+                            <property name="sensitive">False</property>
                             <property name="label" translatable="yes">Weight cases by</property>
                             <property name="focus_on_click">False</property>
                             <property name="draw_indicator">True</property>
-                            <property name="group">radiobutton1</property>
+                            <property name="group">weight-cases-radiobutton1</property>
                           </widget>
                           <packing>
                             <property name="position">1</property>
                           <widget class="GtkHBox" id="hbox3">
                             <property name="visible">True</property>
                             <child>
-                              <widget class="GtkAlignment" id="alignment1">
-                                <property name="visible">True</property>
-                                <child>
-                                  <widget class="GtkAspectFrame" id="aspectframe1">
-                                    <property name="visible">True</property>
-                                    <property name="label_xalign">0</property>
-                                    <property name="shadow_type">GTK_SHADOW_NONE</property>
-                                    <child>
-                                      <widget class="GtkButton" id="button1">
-                                        <property name="width_request">40</property>
-                                        <property name="height_request">40</property>
-                                        <property name="visible">True</property>
-                                        <child>
-                                          <widget class="GtkArrow" id="arrow1">
-                                            <property name="visible">True</property>
-                                          </widget>
-                                        </child>
-                                      </widget>
-                                    </child>
-                                  </widget>
-                                </child>
+                              <widget class="PsppireSelector" id="weight-cases-selector">
+                                <property name="border_width">5</property>
                               </widget>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                              </packing>
                             </child>
                             <child>
                               <widget class="GtkVBox" id="vbox3">
                                   </widget>
                                 </child>
                                 <child>
-                                  <widget class="GtkEntry" id="entry1">
+                                  <widget class="GtkEntry" id="weight-cases-entry">
                                     <property name="visible">True</property>
                                   </widget>
                                   <packing>
       </widget>
     </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>
+    <child internal-child="hbox">
+      <widget class="GtkHBox" id="dialog-hbox2">
+        <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 | GDK_ENTER_NOTIFY_MASK</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkHBox" id="hbox4">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkFrame" id="frame3">
+                <property name="visible">True</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">GTK_SHADOW_IN</property>
+                <child>
+                  <widget class="GtkScrolledWindow" id="scrolledwindow1">
+                    <property name="visible">True</property>
+                    <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                    <child>
+                      <widget class="GtkTreeView" id="source-treeview">
+                        <property name="visible">True</property>
+                        <property name="headers_visible">False</property>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <placeholder/>
+                  <packing>
+                    <property name="type">label_item</property>
+                  </packing>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkTable" id="table1">
+                <property name="visible">True</property>
+                <property name="n_rows">2</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">5</property>
+                <property name="row_spacing">5</property>
+                <child>
+                  <widget class="GtkVBox" id="vbox5">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkLabel" id="label4">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Name Variable:</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkEntry" id="new-name-entry">
+                        <property name="visible">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkVBox" id="vbox4">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Variable(s):</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkFrame" id="frame2">
+                        <property name="visible">True</property>
+                        <property name="label_xalign">0</property>
+                        <property name="shadow_type">GTK_SHADOW_IN</property>
+                        <child>
+                          <widget class="GtkScrolledWindow" id="scrolledwindow2">
+                            <property name="visible">True</property>
+                            <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+                            <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                            <child>
+                              <widget class="GtkTreeView" id="variables-treeview">
+                                <property name="visible">True</property>
+                                <property name="headers_visible">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="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="PsppireSelector" id="psppire-selector3">
+                    <property name="border_width">5</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="x_options"></property>
+                    <property name="y_options">GTK_FILL</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="PsppireSelector" id="psppire-selector2">
+                    <property name="border_width">5</property>
+                  </widget>
+                  <packing>
+                    <property name="x_options"></property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+        </child>
+        <child>
+          <widget class="PsppireButtonBox" id="psppire-buttonbox2">
+            <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>
 </glade-interface>
diff --git a/src/ui/gui/transpose-dialog.c b/src/ui/gui/transpose-dialog.c
new file mode 100644 (file)
index 0000000..4691fff
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+    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 "transpose-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 <gettext.h>
+
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+
+/* FIXME: These shouldn't be here */
+#include <gtksheet/gtksheet.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
+transpose_dialog (GObject *o, gpointer data)
+{
+  gint response ;
+  struct data_editor *de = data;
+
+  GladeXML *xml = glade_xml_new (PKGDATADIR "/psppire.glade",
+                                "transpose-dialog", NULL);
+
+  GtkSheet *var_sheet =
+    GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
+
+  PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet));
+
+  GtkWidget *dialog = get_widget_assert (xml, "transpose-dialog");
+  GtkWidget *source = get_widget_assert (xml, "source-treeview");
+  GtkWidget *dest = get_widget_assert (xml, "variables-treeview");
+  GtkWidget *selector1 = get_widget_assert (xml, "psppire-selector2");
+  GtkWidget *selector2 = get_widget_assert (xml, "psppire-selector3");
+  GtkWidget *new_name_entry = get_widget_assert (xml, "new-name-entry");
+
+  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);
+  }
+
+
+  psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector1),
+                                source, dest,
+                                insert_source_row_into_tree_view,
+                                NULL);
+
+
+  psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector2),
+                                source, new_name_entry,
+                                insert_source_row_into_entry,
+                                is_currently_in_entry);
+
+
+  response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
+
+  switch (response)
+    {
+    case GTK_RESPONSE_OK:
+      {
+       gchar *syntax = generate_syntax (vs->dict, xml);
+       struct getl_interface *sss = create_syntax_string_source (syntax);
+       execute_syntax (sss);
+
+       g_free (syntax);
+      }
+      break;
+    case PSPPIRE_RESPONSE_PASTE:
+      {
+       gchar *syntax = generate_syntax (vs->dict, xml);
+
+       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);
+}
+
+
+  /*
+     FLIP /VARIABLES=var_list /NEWNAMES=var_name.
+  */
+static gchar *
+generate_syntax (PsppireDict *dict, GladeXML *xml)
+{
+  GtkTreeIter iter;
+  const gchar *text;
+  GString *string = g_string_new ("FLIP");
+  gchar *syntax ;
+
+  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);
+
+         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));
+    }
+
+  text = gtk_entry_get_text (GTK_ENTRY (entry));
+
+  if ( text)
+    g_string_append_printf (string, " /NEWNAME = %s", text);
+
+  g_string_append (string, ".");
+
+  syntax = string->str;
+
+  g_string_free (string, FALSE);
+
+  return syntax;
+}
diff --git a/src/ui/gui/transpose-dialog.h b/src/ui/gui/transpose-dialog.h
new file mode 100644 (file)
index 0000000..70266df
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+    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 TRANSPOSE_DIALOG_H
+#define TRANSPOSE_DIALOG_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+void transpose_dialog (GObject *o, gpointer data);
+
+
+#endif
index 50294de7fb72e039d1eab73760c583378a9d86c5..3eb1808dc7087c49a50cfa852c12ef607ad714c5 100644 (file)
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     02110-1301, USA. */
 
-
 #include <config.h>
 
-#include "psppire-var-select.h"
-#include <glade/glade.h>
-#include "helper.h"
-#include <gettext.h>
-
-#include "psppire-var-store.h"
 #include "weight-cases-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>
 
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
+/* FIXME: These shouldn't be here */
+#include <gtksheet/gtksheet.h>
+#include "psppire-var-store.h"
 
 static void
-refresh_var_select (PsppireVarSelect *vs)
+on_select (PsppireSelector *sel, gpointer data)
 {
-  struct variable *weight;
-
-  psppire_var_select_deselect_all (vs);
-
-  weight = psppire_dict_get_weight_variable (vs->dict);
+  GtkRadioButton *radiobutton2 = data;
 
-  if ( weight )
-    psppire_var_select_set_variable (vs, weight);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton2), TRUE);
 }
 
-
 static void
-on_refresh (GtkWidget *dialog, gpointer data)
+on_deselect (PsppireSelector *sel, gpointer data)
 {
-  refresh_var_select (data);
+  GtkRadioButton *radiobutton1 = data;
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton1), TRUE);
 }
 
 
 static void
-on_radiobutton_toggle (GtkToggleButton *button, gpointer data)
+on_toggle (GtkToggleButton *button, gpointer data)
 {
-  PsppireVarSelect *vs = data;
-  if ( gtk_toggle_button_get_active (button) )
-    {
-      psppire_var_select_deselect_all (vs);
-    }
+  GtkEntry *entry = data;
+  if ( gtk_toggle_button_get_active (button))
+    gtk_entry_set_text (entry, "");
 }
 
 
-/* Callback for when new variable is selected.
-   IDX is the dict index of the variable selected.
-   Updates the label and toggle buttons in the dialog box
-   to reflect this new selection. */
-static void
-select_var_callback (PsppireVarSelect *vs, gint idx, gpointer data)
-{
-  GladeXML * xml  = data;
 
-  GtkWidget *label =  get_widget_assert (xml, "weight-status-label");
 
-  GtkWidget *radiobutton2 =  get_widget_assert (xml, "radiobutton2");
+static gchar * generate_syntax (PsppireDict *, GtkEntry *);
 
-  struct variable *var = psppire_dict_get_variable (vs->dict, idx);
 
-  gtk_label_set_text (GTK_LABEL (label), var_get_name(var));
+/* Pops up the Weight Cases dialog box */
+void
+weight_cases_dialog (GObject *o, gpointer data)
+{
+  gint response;
+  struct data_editor *de = data;
+  PsppireDict *dict;
+  struct variable *var;
 
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton2), TRUE);
-}
+  GladeXML *xml = glade_xml_new (PKGDATADIR "/psppire.glade",
+                                "weight-cases-dialog", NULL);
 
+  GtkWidget *dialog = get_widget_assert (xml, "weight-cases-dialog");
+  GtkWidget *source = get_widget_assert (xml, "weight-cases-treeview");
+  GtkWidget *entry = get_widget_assert (xml, "weight-cases-entry");
+  GtkWidget *selector = get_widget_assert (xml, "weight-cases-selector");
+  GtkWidget *radiobutton1 = get_widget_assert (xml,
+                                              "weight-cases-radiobutton1");
+  GtkWidget *radiobutton2 = get_widget_assert (xml, "radiobutton2");
 
+  GtkSheet *var_sheet =
+    GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
 
-static void
-deselect_all (PsppireVarSelect *vs, gpointer data)
-{
-  GladeXML * xml  = data;
+  PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet));
 
-  GtkWidget *label =  get_widget_assert (xml, "weight-status-label");
+  dict = vs->dict;
 
-  GtkWidget *radiobutton1 =  get_widget_assert (xml, "radiobutton1");
+  g_signal_connect (radiobutton1, "toggled", G_CALLBACK (on_toggle), entry);
+  g_signal_connect (selector, "selected", G_CALLBACK (on_select),
+                   radiobutton2);
 
-  gtk_label_set_text (GTK_LABEL (label), _("Do not weight cases"));
+  g_signal_connect (selector, "de-selected", G_CALLBACK (on_deselect),
+                   radiobutton1);
 
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton1), TRUE);
-}
+  attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
+                                dict,
+                                GTK_SELECTION_SINGLE,
+                                var_is_numeric
+                                );
 
+  psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector),
+                                source,
+                                entry,
+                                insert_source_row_into_entry,
+                                is_currently_in_entry
+                                );
 
+  var = dict_get_weight (dict->dict);
+  if ( ! var )
+    gtk_entry_set_text (GTK_ENTRY (entry), "");
+  else
+    gtk_entry_set_text (GTK_ENTRY (entry), var_get_name (var));
 
-PsppireDialog *
-create_weight_dialog (PsppireVarSelect *select, GladeXML *xml)
-{
-  GtkWidget *dialog =  get_widget_assert (xml, "weight-cases-dialog");
-  GtkWidget *radiobutton1 =  get_widget_assert (xml, "radiobutton1");
+  g_signal_emit_by_name (entry, "activate");
+
+  response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
+
+  g_object_unref (xml);
+
+  switch (response)
+    {
+    case GTK_RESPONSE_OK:
+      {
+       gchar *syntax = generate_syntax (dict, GTK_ENTRY (entry));
+       struct getl_interface *sss = create_syntax_string_source (syntax);
+       execute_syntax (sss);
+
+       g_free (syntax);
+      }
+      break;
+    case PSPPIRE_RESPONSE_PASTE:
+      {
+       gchar *syntax = generate_syntax (dict, GTK_ENTRY (entry));
+
+       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_signal_connect (dialog, "refresh", G_CALLBACK (on_refresh), select);
 
-  g_signal_connect (select, "variable-selected",
-                   G_CALLBACK (select_var_callback), xml);
+static gchar *
+generate_syntax (PsppireDict *dict, GtkEntry *entry)
+{
+  gchar *syntax;
 
-  g_signal_connect (select, "deselect-all",
-                   G_CALLBACK (deselect_all), xml);
+  const gchar *text  = gtk_entry_get_text (entry);
 
-  g_signal_connect (radiobutton1, "toggled",
-                   G_CALLBACK (on_radiobutton_toggle),
-                   select);
+  struct variable *var = psppire_dict_lookup_var (dict, text);
 
-  refresh_var_select (select);
+  if ( var == NULL)
+    syntax = g_strdup ("WEIGHT OFF.");
+  else
+    syntax = g_strdup_printf ("WEIGHT BY %s.\n",
+                             var_get_name (var));
 
-  return PSPPIRE_DIALOG (dialog);
+  return syntax;
 }
index b193fef45eccd0e76930bd8d1a015bedaf007a9a..88a7af733978d61016e3ff5a460f47a844c9417e 100644 (file)
 #ifndef WEIGHT_CASES_DIALOG_H
 #define WEIGHT_CASES_DIALOG_H
 
-#include "psppire-dialog.h"
+#include <glib.h>
+#include <glib-object.h>
+
+/* Pops up the Weight Cases dialog box */
+void weight_cases_dialog (GObject *o, gpointer data);
 
-PsppireDialog * create_weight_dialog (PsppireVarSelect *, GladeXML *);
 
 #endif