Merge branch 'master' into output fc11-i386-build61 fc11-x64-build58 lenny-x64-build82 sid-i386-build128
authorJohn Darrington <john@darrington.wattle.id.au>
Fri, 18 Dec 2009 19:34:12 +0000 (20:34 +0100)
committerJohn Darrington <john@darrington.wattle.id.au>
Fri, 18 Dec 2009 19:34:12 +0000 (20:34 +0100)
Conflicts:

NEWS
configure.ac
src/output/charts/dummy-chart.c

1  2 
NEWS
configure.ac
perl-module/lib/PSPP.pm
src/language/stats/correlations.c
src/language/stats/roc.c
src/language/stats/t-test.q
src/ui/gui/automake.mk
src/ui/gui/find-dialog.c
src/ui/gui/psppire.c

diff --combined NEWS
index 24f1d4a80cce1218ebbb91c2785bd6cdc79f0aea,149d1deadbad2b44269d9a6b787ac9ed9ed10c80..ab21afde986538b1ac362b74cedc3191f243112f
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,19 -1,10 +1,19 @@@
  PSPP NEWS -- history of user-visible changes.
 -Time-stamp: <2009-10-06 20:46:21 blp>
 +Time-stamp: <2009-12-05 20:39:07 blp>
  Copyright (C) 1996-9, 2000, 2008, 2009 Free Software Foundation, Inc.
  See the end for copying conditions.
  
  Please send PSPP bug reports to bug-gnu-pspp@gnu.org.
  
 +Changes from 0.7.2 to 0.7.3:
 +
 + * Charts are now produced with Cairo and Pango, instead of libplot.
 +   Without them, the new graphing features will not work.  If you do
 +   not have Cairo and Pango installed, you must run `configure' with
 +   --without-cairo.
 +
 + * The PostScript driver has been removed.
 +
  Changes from 0.7.1 to 0.7.2:
  
   * Updated Perl module interface.
@@@ -63,8 -54,7 +63,7 @@@ Changes from 0.6.2-pre6 to 0.7.0
  
    * A tutorial chapter has been added to the user manual.
  
- Changes from 0.6.1 to 0.6.2-pre6:
+ Changes from 0.6.1 to 0.6.2
  
    * New translations:
  
@@@ -86,6 -76,8 +85,8 @@@
  
    * Build fixes and changes:
  
+     - Fix build with GTK+ 2.17.4 and later.
      - Make running "make" after running "configure" with different
        settings reliably rebuild version.c.
  
  
      - Fix writing corrupted .sav files on Windows.
  
+     - Fix writing variable labels longer than 252 bytes to save files.
+       Thanks to Robert Westlund for reporting this bug.
      - Fix writing corrupted .por files (bug #26034).
  
      - Fix reading .por files whose initial lines are not padded out
diff --combined configure.ac
index 499128b3c5e524aa46f2abb650cf5c43f4b642f4,1ef538bca60ae2c120a433df8aca080f616e5963..1dc8e55896a723ffe50322b9beec0353eda0a116
@@@ -2,7 -2,7 +2,7 @@@ dnl Process this file with autoconf to 
  
  dnl Initialize.
  AC_PREREQ(2.60)
 -AC_INIT([pspp],[0.7.2],[bug-gnu-pspp@gnu.org])
 +AC_INIT([pspp],[0.7.3],[bug-gnu-pspp@gnu.org])
  AC_CONFIG_HEADERS([config.h])
  AM_INIT_AUTOMAKE
  
@@@ -40,39 -40,28 +40,40 @@@ f
  dnl Checks for libraries.
  AC_SYS_LARGEFILE
  AC_SEARCH_LIBS([sin], [m])
 -PSPP_LIBPLOT
+ AC_SEARCH_LIBS([dcgettext], [intl])
  PSPP_LC_PAPER
 -AM_CONDITIONAL(WITHCHARTS, test x"$with_libplot" != x"no")
  
  
  AC_ARG_VAR([PSPP_LDFLAGS], [linker flags to be used for linking the pspp binary only])
  AC_ARG_VAR([PSPPIRE_LDFLAGS], [linker flags to be used for linking the psppire binary only])
  
 -
 -AC_ARG_WITH(
 -  gui, 
 -  [AS_HELP_STRING([--without-gui], [don't build the PSPPIRE gui])])
 -
 -required_gtk_version=2.12
 -
 -if test x"$with_gui" != x"no" ; then 
 -  PKG_CHECK_MODULES(GTK, gtk+-2.0 >= $required_gtk_version,,
 -    [PSPP_REQUIRED_PREREQ([gtk+ 2.0 v$required_gtk_version or later (or use --without-gui)])])
 +# Support for Cairo and Pango.
 +AC_ARG_WITH([cairo],
 +  [AS_HELP_STRING(
 +    [--without-cairo], 
 +    [Don't build support for charts (using Cairo and Pango);
 +     implies --without-gui])],
 +  [], [with_cairo=yes])
 +AM_CONDITIONAL([HAVE_CAIRO], [test "$with_cairo" != no])
 +if test "$with_cairo" != no; then
 +  PKG_CHECK_MODULES([CAIRO], [cairo >= 1.5 pango >= 1.20 pangocairo], 
 +    [CPPFLAGS="$CPPFLAGS $CAIRO_CFLAGS"
 +     AC_DEFINE([HAVE_CAIRO], 1, 
 +       [Define to 1 if Cairo and Pango are available.])],
 +    [PSPP_REQUIRED_PREREQ([cairo 1.5 or later and pango 1.20 or later (or use --without-cairo)])])
  fi
 -AM_CONDITIONAL(WITHGUI, test x"$with_gui" != x"no")
  
 +# Support for GUI.
 +AC_ARG_WITH([gui], 
 +  [AS_HELP_STRING([--without-gui], 
 +                  [Don't build the PSPPIRE GUI (using GTK+)])],
 +  [], [with_gui=yes])
 +AM_CONDITIONAL([HAVE_GUI], 
 +               [test "$with_cairo" != no && test "$with_gui" != "no"])
 +if test "$with_cairo" != no && test "$with_gui" != "no"; then
 +  PKG_CHECK_MODULES([GTK], [gtk+-2.0 >= 2.12], [],
 +    [PSPP_REQUIRED_PREREQ([gtk+ 2.0 version 2.12 or later (or use --without-gui)])])
 +fi
  
  dnl Checks needed for psql reader
  
diff --combined perl-module/lib/PSPP.pm
index c6b059826f0c870b5082634a4351f9dd7b833dc1,2dccd10a36973e560e8be7d267b92f9bdb918ac1..fd2f5a5f5d579ae20f933248af74088524d15c43
@@@ -21,7 -21,7 +21,7 @@@ None by default
  
  =cut
  BEGIN {
 -      $PSPP::VERSION='0.7.2';
 +      $PSPP::VERSION='0.7.3';
        require XSLoader;
        XSLoader::load('PSPP', $PSPP::VERSION);
  }
@@@ -197,7 -197,7 +197,7 @@@ package PSPP::Var
  =head3 new ($dict, $name, %input_fmt)
  
  Creates and returns a new variable in the dictionary C<dict>.  The 
- new variable will have the name C<name>.
+ new variable will have the name C<name>.  C<name> must be a valid UTF8 string.
  The input format is set by the C<input_fmt> parameter 
  (See L</PSPP::Fmt>).
  By default, the write and print formats are the same as the input format.
@@@ -226,7 -226,7 +226,7 @@@ sub ne
  
  =head3 set_label ($label)
  
- Sets the variable label to C<label>.
+ Sets the variable label to C<label>, which must be a valid UTF8 string.
  
  
  =cut
@@@ -322,6 -322,7 +322,7 @@@ Removes all value labels from the varia
  =head3 add_value_label ($key, $label)
  
  Adds the value label C<label> to the variable for the value C<key>.
+ C<label> must be a valid UTF8 string.
  On error the subroutine returns zero.
  
  =head3 add_value_labels (@array)
@@@ -348,7 -349,7 +349,7 @@@ sub add_value_label
  
  =pod
  
- =head3 set_value_labels ($key, $value)
+ =head3 set_value_labels ($key, $label)
  
  C<Set_value_labels> is identical to calling L</clear_value_labels>
  followed by L</add_value_labels>.
@@@ -414,6 -415,7 +415,7 @@@ On error, undef is returned
  Appends a case to the system file.
  C<Case> is an array of scalars, each of which are the values of 
  the variables in the dictionary corresponding to the system file.
+ If the case contains strings, then the strings must be UTF8 encoded.
  The special value C<PSPP::SYSMIS> may be used to indicate that a value
  is system missing.
  If the array contains less elements than variables in the dictionary,
@@@ -522,7 -524,7 +524,7 @@@ values retrieved from a reader
  
  Returns a scalar containing a string representing C<value> formatted according 
  to the print format of C<variable>.
- In the most common ussage,  C<value> should be a value of C<variable>.
+ In the most common usage,  C<value> should be a value of C<variable>.
  
  
  =head3 PSPP::value_is_missing ($value, $variable)
index ad90ef409051f47d12d8fcc2e48f5280fadf75aa,605609a7d68cc559e42cc605cf2543f49e9a441d..c575205ccf2e8b8858e06383854e13f340baaf98
@@@ -18,6 -18,7 +18,7 @@@
  
  #include <libpspp/assertion.h>
  #include <math/covariance.h>
+ #include <math/correlation.h>
  #include <math/design-matrix.h>
  #include <gsl/gsl_matrix.h>
  #include <data/casegrouper.h>
  #define N_(msgid) msgid
  
  
- static double
- significance_of_correlation (double rho, double w)
- {
-   double t = w - 2;
-   t /= 1 - MIN (1, pow2 (rho));
-   t = sqrt (t);
-   t *= rho;
-   
-   if (t > 0)
-     return  gsl_cdf_tdist_Q (t, w - 2);
-   else
-     return  gsl_cdf_tdist_P (t, w - 2);
- }
  struct corr
  {
    size_t n_vars_total;
@@@ -108,9 -94,9 +94,9 @@@ output_descriptives (const struct corr 
    const int heading_columns = 1;
    const int heading_rows = 1;
  
 -  struct tab_table *t = tab_create (nc, nr, 0);
 +  struct tab_table *t = tab_create (nc, nr);
    tab_title (t, _("Descriptive Statistics"));
 -  tab_dim (t, tab_natural_dimensions, NULL);
 +  tab_dim (t, tab_natural_dimensions, NULL, NULL);
  
    tab_headers (t, heading_columns, 0, heading_rows, 0);
  
@@@ -203,9 -189,9 +189,9 @@@ output_correlation (const struct corr *
    /* One header row */
    nr += heading_rows;
  
 -  t = tab_create (nc, nr, 0);
 +  t = tab_create (nc, nr);
    tab_title (t, _("Correlations"));
 -  tab_dim (t, tab_natural_dimensions, NULL);
 +  tab_dim (t, tab_natural_dimensions, NULL, NULL);
  
    tab_headers (t, heading_columns, 0, heading_rows, 0);
  
  }
  
  
- static gsl_matrix *
- correlation_from_covariance (const gsl_matrix *cv, const gsl_matrix *v)
- {
-   size_t i, j;
-   gsl_matrix *corr = gsl_matrix_calloc (cv->size1, cv->size2);
-   
-   for (i = 0 ; i < cv->size1; ++i)
-     {
-       for (j = 0 ; j < cv->size2; ++j)
-       {
-         double rho = gsl_matrix_get (cv, i, j);
-         
-         rho /= sqrt (gsl_matrix_get (v, i, j))
-           * 
-           sqrt (gsl_matrix_get (v, j, i));
-         
-         gsl_matrix_set (corr, i, j, rho);
-       }
-     }
-   
-   return corr;
- }
  static void
  run_corr (struct casereader *r, const struct corr_opts *opts, const struct corr *corr)
  {
diff --combined src/language/stats/roc.c
index 1d21a4f6a1221ed6b83f3c2bbb8d4e25c457c95a,86aee1f9d1f5e6a9662f1a605ebf560db52b19b7..1f2691d8919e01eac157688d053f218c426581af
@@@ -16,8 -16,6 +16,8 @@@
  
  #include <config.h>
  
 +#include <language/stats/roc.h>
 +
  #include <data/procedure.h>
  #include <language/lexer/variable-parser.h>
  #include <language/lexer/value-parser.h>
@@@ -38,8 -36,8 +38,8 @@@
  #include <gsl/gsl_cdf.h>
  #include <output/table.h>
  
 -#include <output/charts/plot-chart.h>
 -#include <output/charts/cartesian.h>
 +#include <output/chart.h>
 +#include <output/charts/roc-chart.h>
  
  #include "gettext.h"
  #define _(msgid) gettext (msgid)
@@@ -114,6 -112,7 +114,7 @@@ cmd_roc (struct lexer *lexer, struct da
        goto error;
      }
  
+   value_init (&roc.state_value, var_get_width (roc.state_var));
    parse_value (lexer, &roc.state_value, var_get_width (roc.state_var));
  
  
    if ( ! run_roc (ds, &roc)) 
      goto error;
  
+   value_destroy (&roc.state_value, var_get_width (roc.state_var));
    free (roc.vars);
    return CMD_SUCCESS;
  
   error:
+   value_destroy (&roc.state_value, var_get_width (roc.state_var));
    free (roc.vars);
    return CMD_FAILURE;
  }
@@@ -385,6 -386,13 +388,6 @@@ struct roc_stat
    double max;
  };
  
 -#define CUTPOINT 0
 -#define TP 1
 -#define FN 2
 -#define TN 3
 -#define FP 4
 -
 -
  /* 
     Return a new casereader based upon CUTPOINT_RDR.
     The number of "positive" cases are placed into
@@@ -410,7 -418,7 +413,7 @@@ accumulate_counts (struct casereader *c
    for ( ; (cpc = casereader_read (r) ); case_unref (cpc))
      {
        struct ccase *new_case;
 -      const double cp = case_data_idx (cpc, CUTPOINT)->f;
 +      const double cp = case_data_idx (cpc, ROC_CUTPOINT)->f;
  
        assert (cp != SYSMIS);
  
@@@ -574,7 -582,7 +577,7 @@@ process_positive_group (const struct va
    return process_group (var, reader, gt, dict, &rs->n1,
                        &rs->cutpoint_rdr,
                        ge,
 -                      TP, FN);
 +                      ROC_TP, ROC_FN);
  }
  
  /*
@@@ -592,7 -600,7 +595,7 @@@ process_negative_group (const struct va
    return process_group (var, reader, lt, dict, &rs->n2,
                        &rs->cutpoint_rdr,
                        lt,
 -                      TN, FP);
 +                      ROC_TN, ROC_FP);
  }
  
  
@@@ -603,11 -611,11 +606,11 @@@ append_cutpoint (struct casewriter *wri
  {
    struct ccase *cc = case_create (casewriter_get_proto (writer));
  
 -  case_data_rw_idx (cc, CUTPOINT)->f = cutpoint;
 -  case_data_rw_idx (cc, TP)->f = 0;
 -  case_data_rw_idx (cc, FN)->f = 0;
 -  case_data_rw_idx (cc, TN)->f = 0;
 -  case_data_rw_idx (cc, FP)->f = 0;
 +  case_data_rw_idx (cc, ROC_CUTPOINT)->f = cutpoint;
 +  case_data_rw_idx (cc, ROC_TP)->f = 0;
 +  case_data_rw_idx (cc, ROC_FN)->f = 0;
 +  case_data_rw_idx (cc, ROC_TN)->f = 0;
 +  case_data_rw_idx (cc, ROC_FP)->f = 0;
  
    casewriter_write (writer, cc);
  }
  
  /* 
     Create and initialise the rs[x].cutpoint_rdr casereaders.  That is, the readers will
 -   be created with width 5, ready to take the values (cutpoint, TP, FN, TN, FP), and the
 +   be created with width 5, ready to take the values (cutpoint, ROC_TP, ROC_FN, ROC_TN, ROC_FP), and the
     reader will be populated with its final number of cases.
 -   However on exit from this function, only CUTPOINT entries will be set to their final
 +   However on exit from this function, only ROC_CUTPOINT entries will be set to their final
     value.  The other entries will be initialised to zero.
  */
  static void
@@@ -629,13 -637,13 +632,13 @@@ prepare_cutpoints (struct cmd_roc *roc
    struct caseproto *proto = caseproto_create ();
  
    struct subcase ordering;
 -  subcase_init (&ordering, CUTPOINT, 0, SC_ASCEND);
 +  subcase_init (&ordering, ROC_CUTPOINT, 0, SC_ASCEND);
  
    proto = caseproto_add_width (proto, 0); /* cutpoint */
 -  proto = caseproto_add_width (proto, 0); /* TP */
 -  proto = caseproto_add_width (proto, 0); /* FN */
 -  proto = caseproto_add_width (proto, 0); /* TN */
 -  proto = caseproto_add_width (proto, 0); /* FP */
 +  proto = caseproto_add_width (proto, 0); /* ROC_TP */
 +  proto = caseproto_add_width (proto, 0); /* ROC_FN */
 +  proto = caseproto_add_width (proto, 0); /* ROC_TN */
 +  proto = caseproto_add_width (proto, 0); /* ROC_FP */
  
    for (i = 0 ; i < roc->n_vars; ++i)
      {
@@@ -927,7 -935,7 +930,7 @@@ show_auc  (struct roc_state *rs, const 
    const int n_fields = roc->print_se ? 5 : 1;
    const int n_cols = roc->n_vars > 1 ? n_fields + 1: n_fields;
    const int n_rows = 2 + roc->n_vars;
 -  struct tab_table *tbl = tab_create (n_cols, n_rows, 0);
 +  struct tab_table *tbl = tab_create (n_cols, n_rows);
  
    if ( roc->n_vars > 1)
      tab_title (tbl, _("Area Under the Curve"));
  
    tab_headers (tbl, n_cols - n_fields, 0, 1, 0);
  
 -  tab_dim (tbl, tab_natural_dimensions, NULL);
 +  tab_dim (tbl, tab_natural_dimensions, NULL, NULL);
  
    tab_text (tbl, n_cols - n_fields, 1, TAT_TITLE, _("Area"));
  
@@@ -1022,13 -1030,13 +1025,13 @@@ show_summary (const struct cmd_roc *roc
  {
    const int n_cols = 3;
    const int n_rows = 4;
 -  struct tab_table *tbl = tab_create (n_cols, n_rows, 0);
 +  struct tab_table *tbl = tab_create (n_cols, n_rows);
  
    tab_title (tbl, _("Case Summary"));
  
    tab_headers (tbl, 1, 0, 2, 0);
  
 -  tab_dim (tbl, tab_natural_dimensions, NULL);
 +  tab_dim (tbl, tab_natural_dimensions, NULL, NULL);
  
    tab_box (tbl,
           TAL_2, TAL_2,
@@@ -1080,7 -1088,7 +1083,7 @@@ show_coords (struct roc_state *rs, cons
    for (i = 0; i < roc->n_vars; ++i)
      n_rows += casereader_count_cases (rs[i].cutpoint_rdr);
  
 -  tbl = tab_create (n_cols, n_rows, 0);
 +  tbl = tab_create (n_cols, n_rows);
  
    if ( roc->n_vars > 1)
      tab_title (tbl, _("Coordinates of the Curve"));
  
    tab_headers (tbl, 1, 0, 1, 0);
  
 -  tab_dim (tbl, tab_natural_dimensions, NULL);
 +  tab_dim (tbl, tab_natural_dimensions, NULL, NULL);
  
    tab_hline (tbl, TAL_2, 0, n_cols - 1, 1);
  
        for (; (cc = casereader_read (r)) != NULL;
           case_unref (cc), x++)
        {
 -        const double se = case_data_idx (cc, TP)->f /
 +        const double se = case_data_idx (cc, ROC_TP)->f /
            (
 -           case_data_idx (cc, TP)->f
 +           case_data_idx (cc, ROC_TP)->f
             +
 -           case_data_idx (cc, FN)->f
 +           case_data_idx (cc, ROC_FN)->f
             );
  
 -        const double sp = case_data_idx (cc, TN)->f /
 +        const double sp = case_data_idx (cc, ROC_TN)->f /
            (
 -           case_data_idx (cc, TN)->f
 +           case_data_idx (cc, ROC_TN)->f
             +
 -           case_data_idx (cc, FP)->f
 +           case_data_idx (cc, ROC_FP)->f
             );
  
 -        tab_double (tbl, n_cols - 3, x, 0, case_data_idx (cc, CUTPOINT)->f,
 +        tab_double (tbl, n_cols - 3, x, 0, case_data_idx (cc, ROC_CUTPOINT)->f,
                      var_get_print_format (roc->vars[i]));
  
          tab_double (tbl, n_cols - 2, x, 0, se, NULL);
  }
  
  
 -static void
 -draw_roc (struct roc_state *rs, const struct cmd_roc *roc)
 -{
 -  int i;
 -
 -  struct chart *roc_chart = chart_create ();
 -
 -  chart_write_title (roc_chart, _("ROC Curve"));
 -  chart_write_xlabel (roc_chart, _("1 - Specificity"));
 -  chart_write_ylabel (roc_chart, _("Sensitivity"));
 -
 -  chart_write_xscale (roc_chart, 0, 1, 5);
 -  chart_write_yscale (roc_chart, 0, 1, 5);
 -
 -  if ( roc->reference )
 -    {
 -      chart_line (roc_chart, 1.0, 0,
 -                0.0, 1.0,
 -                CHART_DIM_X);
 -    }
 -
 -  for (i = 0; i < roc->n_vars; ++i)
 -    {
 -      struct ccase *cc;
 -      struct casereader *r = casereader_clone (rs[i].cutpoint_rdr);
 -
 -      chart_vector_start (roc_chart, var_get_name (roc->vars[i]));
 -      for (; (cc = casereader_read (r)) != NULL;
 -         case_unref (cc))
 -      {
 -        double se = case_data_idx (cc, TP)->f;
 -        double sp = case_data_idx (cc, TN)->f;
 -
 -        se /= case_data_idx (cc, FN)->f +
 -          case_data_idx (cc, TP)->f ;
 -
 -        sp /= case_data_idx (cc, TN)->f +
 -          case_data_idx (cc, FP)->f ;
 -
 -        chart_vector (roc_chart, 1 - sp, se);
 -      }
 -      chart_vector_end (roc_chart);
 -      casereader_destroy (r);
 -    }
 -
 -  chart_write_legend (roc_chart);
 -
 -  chart_submit (roc_chart);
 -}
 -
 -
  static void
  output_roc (struct roc_state *rs, const struct cmd_roc *roc)
  {
    show_summary (roc);
  
    if ( roc->curve )
 -    draw_roc (rs, roc);
 +    {
 +      struct roc_chart *rc;
 +      size_t i;
 +
 +      rc = roc_chart_create (roc->reference);
 +      for (i = 0; i < roc->n_vars; i++)
 +        roc_chart_add_var (rc, var_get_name (roc->vars[i]),
 +                           rs[i].cutpoint_rdr);
 +      chart_submit (roc_chart_get_chart (rc));
 +    }
  
    show_auc (rs, roc);
  
 -
    if ( roc->print_coords )
      show_coords (rs, roc);
  }
index d417d31c0d26e944b9548756e05e2baf1ea178ad,8f23cefd4afa54c8be6cfebe7031128a913e3616..a483bd9e35f2dea56afd12eb16ab6905725120aa
@@@ -43,6 -43,7 +43,7 @@@
  #include <libpspp/taint.h>
  #include <math/group-proc.h>
  #include <math/levene.h>
+ #include <math/correlation.h>
  #include <output/manager.h>
  #include <output/table.h>
  #include <data/format.h>
@@@ -476,13 -477,13 +477,13 @@@ static voi
  ssbox_base_init (struct ssbox *this, int cols, int rows)
  {
    this->finalize = ssbox_base_finalize;
 -  this->t = tab_create (cols, rows, 0);
 +  this->t = tab_create (cols, rows);
  
 -  tab_columns (this->t, SOM_COL_DOWN, 1);
 +  tab_columns (this->t, SOM_COL_DOWN);
    tab_headers (this->t, 0, 0, 1, 0);
    tab_box (this->t, TAL_2, TAL_2, TAL_0, TAL_1, 0, 0, cols - 1, rows - 1);
    tab_hline (this->t, TAL_2, 0, cols- 1, 1);
 -  tab_dim (this->t, tab_natural_dimensions, NULL);
 +  tab_dim (this->t, tab_natural_dimensions, NULL, NULL);
  }
  \f
  /* ssbox implementations. */
@@@ -1068,11 -1069,11 +1069,11 @@@ trbox_base_init (struct trbox *self, si
    const size_t rows = 3 + data_rows;
  
    self->finalize = trbox_base_finalize;
 -  self->t = tab_create (cols, rows, 0);
 +  self->t = tab_create (cols, rows);
    tab_headers (self->t, 0, 0, 3, 0);
    tab_box (self->t, TAL_2, TAL_2, TAL_0, TAL_0, 0, 0, cols - 1, rows - 1);
    tab_hline (self->t, TAL_2, 0, cols- 1, 3);
 -  tab_dim (self->t, tab_natural_dimensions, NULL);
 +  tab_dim (self->t, tab_natural_dimensions, NULL, NULL);
  }
  
  /* Base finalizer for the trbox */
@@@ -1092,14 -1093,14 +1093,14 @@@ pscbox (struct t_test_proc *proc
  
    struct tab_table *table;
  
 -  table = tab_create (cols, rows, 0);
 +  table = tab_create (cols, rows);
  
 -  tab_columns (table, SOM_COL_DOWN, 1);
 +  tab_columns (table, SOM_COL_DOWN);
    tab_headers (table, 0, 0, 1, 0);
    tab_box (table, TAL_2, TAL_2, TAL_0, TAL_1, 0, 0, cols - 1, rows - 1);
    tab_hline (table, TAL_2, 0, cols - 1, 1);
    tab_vline (table, TAL_2, 2, 0, rows - 1);
 -  tab_dim (table, tab_natural_dimensions, NULL);
 +  tab_dim (table, tab_natural_dimensions, NULL, NULL);
    tab_title (table, _("Paired Samples Correlations"));
  
    /* column headings */
    for (i = 0; i < proc->n_pairs; i++)
      {
        struct pair *pair = &proc->pairs[i];
-       double df = pair->n - 2;
-       double p, q;
-       /* corr2 will mathematically always be in the range [0, 1.0].  Inaccurate
-          calculations sometimes cause it to be slightly greater than 1.0, so
-          force it into the correct range to avoid NaN from sqrt(). */
-       double corr2 = MIN (1.0, pow2 (pair->correlation));
-       double correlation_t = pair->correlation * sqrt (df) / sqrt (1 - corr2);
  
        /* row headings */
        tab_text_format (table, 0, i + 1, TAB_LEFT | TAT_TITLE,
        tab_double (table, 2, i + 1, TAB_RIGHT, pair->n, &proc->weight_format);
        tab_double (table, 3, i + 1, TAB_RIGHT, pair->correlation, NULL);
  
-       p = gsl_cdf_tdist_P (correlation_t, df);
-       q = gsl_cdf_tdist_Q (correlation_t, df);
-       tab_double (table, 4, i + 1, TAB_RIGHT,
-                  2.0 * (correlation_t > 0 ? q : p), NULL);
+       tab_double (table, 4, i + 1, TAB_RIGHT, 
+                 2.0 * significance_of_correlation (pair->correlation, pair->n), NULL);
      }
  
    tab_submit (table);
diff --combined src/ui/gui/automake.mk
index 05f362194cc207442d902d3b63fcd6d18adeb4f6,b7d60a78edca7e250444598eb672aba525b63727..3fbf46520d2137e18d934c86f16e0ce4b1f553c4
@@@ -26,7 -26,6 +26,7 @@@ src_ui_gui_psppire_LDADD = 
        src/libpspp.la \
        src/libpspp-core.la \
        $(GTK_LIBS) \
 +      $(CAIRO_LIBS) \
        $(LIBINTL)
  
  src_ui_gui_psppiredir = $(pkgdatadir)
@@@ -55,6 -54,7 +55,7 @@@ UNINSTALL_DATA_HOOKS += uninstall-icon
  
  
  UI_FILES = \
+       src/ui/gui/correlation.ui \
        src/ui/gui/crosstabs.ui \
        src/ui/gui/descriptives.ui \
        src/ui/gui/examine.ui \
        src/ui/gui/oneway.ui \
        src/ui/gui/psppire.ui \
        src/ui/gui/rank.ui \
+       src/ui/gui/sort.ui \
        src/ui/gui/recode.ui \
        src/ui/gui/regression.ui \
        src/ui/gui/reliability.ui \
+       src/ui/gui/roc.ui \
        src/ui/gui/t-test.ui \
        src/ui/gui/text-data-import.ui \
        src/ui/gui/var-sheet-dialogs.ui \
@@@ -113,6 -115,8 +116,8 @@@ src_ui_gui_psppire_SOURCES = 
        src/ui/gui/comments-dialog.h \
        src/ui/gui/compute-dialog.c \
        src/ui/gui/compute-dialog.h \
+       src/ui/gui/correlation-dialog.c \
+       src/ui/gui/correlation-dialog.h \
        src/ui/gui/crosstabs-dialog.c \
        src/ui/gui/crosstabs-dialog.h \
        src/ui/gui/customentry.c \
        src/ui/gui/psppire-keypad.h \
        src/ui/gui/psppire-output-window.c \
        src/ui/gui/psppire-output-window.h \
+       src/ui/gui/psppire-var-view.c \
+       src/ui/gui/psppire-var-view.h \
        src/ui/gui/psppire-selector.h \
+       src/ui/gui/psppire-select-dest.c \
+       src/ui/gui/psppire-select-dest.h \
        src/ui/gui/psppire-syntax-window.c \
        src/ui/gui/psppire-syntax-window.h \
        src/ui/gui/psppire-var-ptr.c \
        src/ui/gui/regression-dialog.h \
        src/ui/gui/reliability-dialog.c \
        src/ui/gui/reliability-dialog.h \
+       src/ui/gui/roc-dialog.c \
+       src/ui/gui/roc-dialog.h \
        src/ui/gui/select-cases-dialog.c \
        src/ui/gui/select-cases-dialog.h \
        src/ui/gui/sort-cases-dialog.c \
diff --combined src/ui/gui/find-dialog.c
index 0c16bfa8140c0a78f4036c2c2ef2e3eeadb5023a,40e91bc0179f1f801a8d22086725735f5810af48..2319fb9f50fac2231169692fe837e395186af8a7
@@@ -34,7 -34,6 +34,7 @@@ which match particular strings *
  #include <ctype.h>
  #include <sys/types.h>
  #include <regex.h>
 +#include <libpspp/cast.h>
  #include <libpspp/message.h>
  
  #include <gtk/gtk.h>
@@@ -243,17 -242,13 +243,13 @@@ find_dialog (GObject *o, gpointer data
    gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
  
  
-   g_object_set (source, "dictionary", fd.dict,
+   g_object_set (source, "model", fd.dict,
        "selection-mode", GTK_SELECTION_SINGLE,
        NULL);
  
-   psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector),
-                                source,
-                                fd.variable_entry,
-                                insert_source_row_into_entry,
-                                is_currently_in_entry,
-                                NULL
-                                );
+   psppire_selector_set_filter_func (PSPPIRE_SELECTOR (selector),
+                                   is_currently_in_entry);
  
    g_signal_connect (dialog, "refresh", G_CALLBACK (refresh),  &fd);
  
@@@ -571,8 -566,7 +567,8 @@@ regexp_label_compare (const struct comp
  static void
  regexp_destroy (struct comparator *cmptr)
  {
 -  struct regexp_comparator *rec = (struct regexp_comparator *) cmptr;
 +  struct regexp_comparator *rec
 +    = UP_CAST (cmptr, struct regexp_comparator, parent);
  
    regfree (&rec->re);
  }
  static void
  cmptr_value_destroy (struct comparator *cmptr)
  {
 -  struct value_comparator *vc = (struct value_comparator *) cmptr;
 +  struct value_comparator *vc
 +    = UP_CAST (cmptr, struct value_comparator, parent);
    value_destroy (&vc->pattern, var_get_width (cmptr->var));
  }
  
@@@ -590,7 -583,7 +586,7 @@@ static struct comparator 
  value_comparator_create (const struct variable *var, const PsppireDict *dict, const char *target)
  {
    struct value_comparator *vc = xzalloc (sizeof (*vc));
 -  struct comparator *cmptr = (struct comparator *) vc;
 +  struct comparator *cmptr = &vc->parent;
  
    cmptr->flags = 0;
    cmptr->var = var;
@@@ -609,7 -602,7 +605,7 @@@ string_comparator_create (const struct 
                          enum string_cmp_flags flags)
  {
    struct string_comparator *ssc = xzalloc (sizeof (*ssc));
 -  struct comparator *cmptr = (struct comparator *) ssc;
 +  struct comparator *cmptr = &ssc->parent;
  
    cmptr->flags = flags;
    cmptr->var = var;
@@@ -632,7 -625,7 +628,7 @@@ regexp_comparator_create (const struct 
  {
    int code;
    struct regexp_comparator *rec = xzalloc (sizeof (*rec));
 -  struct comparator *cmptr = (struct comparator *) rec;
 +  struct comparator *cmptr = &rec->parent;
  
    cmptr->flags = flags;
    cmptr->var = var;
diff --combined src/ui/gui/psppire.c
index 961998d9266a8ab4da61fd4f102109606c46cc6d,8491851383f4405805bbf71d0a35d5e172500b29..3f6d49a65db2aec01fdef067d502954707484d8a
@@@ -47,6 -47,9 +47,9 @@@
  
  #include <gtk/gtk.h>
  #include "psppire-dict.h"
+ #include "dict-display.h"
+ #include "psppire-selector.h"
+ #include "psppire-var-view.h"
  #include "psppire-var-store.h"
  #include "psppire-data-store.h"
  #include "executor.h"
@@@ -120,7 -123,25 +123,7 @@@ initialize (struct command_line_process
  
    create_icon_factory ();
  
 -  {
 -    const char *filename = output_file_name ();
 -
 -    struct string config_string;
 -
 -    ds_init_empty (&config_string);
 -
 -    ds_put_format (&config_string,
 -                 "gui:ascii:screen:squeeze=on headers=off top-margin=0 "
 -                 "bottom-margin=0 paginate=off length=auto width=auto "
 -                 "emphasis=none "
 -                 "output-file=\"%s\" append=yes", filename);
 -
 -    outp_configure_driver_line (ds_ss (&config_string));
 -
 -    unlink (filename);
 -
 -    ds_destroy (&config_string);
 -  }
 +  psppire_output_window_setup ();
  
    journal_enable ();
    textdomain (PACKAGE);
  
    the_recent_mgr = gtk_recent_manager_get_default ();
  
+   psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry);
+   psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view);
+   psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view);
    the_data_window = psppire_data_window_new ();
  
    command_line_processor_replace_aux (clp, &post_init_argp, the_source_stream);
@@@ -320,3 -345,16 +327,3 @@@ parse_non_options (int key, char *arg, 
  
  
  const struct argp non_option_argp = {NULL, parse_non_options, 0, 0, 0, 0, 0};
 -
 -
 -const char *
 -output_file_name (void)
 -{
 -  const char *dir = default_output_path ();
 -  static char *filename = NULL;
 -
 -  if ( NULL == filename )
 -    filename = xasprintf ("%s%s", dir, OUTPUT_FILE_NAME);
 -
 -  return filename;
 -}