Merge 'master' into 'psppsheet'. 20121202031952/pspp 20121203032039/pspp 20121204032004/pspp 20121205032030/pspp 20121206032021/pspp 20121207032036/pspp 20121208032040/pspp 20121209032019/pspp 20121210032023/pspp 20121211032038/pspp 20121212032028/pspp 20121213032029/pspp 20121214032036/pspp 20121215032028/pspp 20121216032020/pspp 20121217032038/pspp 20121218031957/pspp 20121219032034/pspp 20121220032031/pspp 20121221032037/pspp 20121222032032/pspp 20121223032002/pspp 20121225032008/pspp 20121226032016/pspp 20121227032003/pspp 20121228032058/pspp 20121229032201/pspp 20121230032128/pspp
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 2 Dec 2012 03:39:07 +0000 (19:39 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 2 Dec 2012 03:39:07 +0000 (19:39 -0800)
62 files changed:
NEWS
configure.ac
doc/invoking.texi
src/data/data-out.c
src/data/file-handle-def.h
src/language/data-io/data-list.c
src/language/data-io/data-parser.c
src/language/data-io/inpt-pgm.c
src/language/lexer/format-parser.c
src/language/stats/crosstabs.q
src/language/stats/descriptives.c
src/language/stats/npar.c
src/language/utilities/set.q
src/libpspp/assertion.h
src/math/histogram.c
src/output/ascii.c
src/output/cairo.c
src/output/csv.c
src/output/driver-provider.h
src/output/driver.c
src/output/html.c
src/output/journal.c
src/output/journal.h
src/output/measure.c
src/output/odt.c
src/ui/automake.mk
src/ui/debugger.c [deleted file]
src/ui/debugger.h [deleted file]
src/ui/gui/aggregate-dialog.c
src/ui/gui/automake.mk
src/ui/gui/binomial-dialog.c [deleted file]
src/ui/gui/binomial-dialog.h [deleted file]
src/ui/gui/chi-square-dialog.c
src/ui/gui/crosstabs-dialog.c [deleted file]
src/ui/gui/crosstabs-dialog.h [deleted file]
src/ui/gui/data-editor.ui
src/ui/gui/dialog-common.c
src/ui/gui/dialog-common.h
src/ui/gui/frequencies-dialog.c [deleted file]
src/ui/gui/frequencies-dialog.h [deleted file]
src/ui/gui/psppire-data-window.c
src/ui/gui/psppire-dialog-action-binomial.c [new file with mode: 0644]
src/ui/gui/psppire-dialog-action-binomial.h [new file with mode: 0644]
src/ui/gui/psppire-dialog-action-crosstabs.c [new file with mode: 0644]
src/ui/gui/psppire-dialog-action-crosstabs.h [new file with mode: 0644]
src/ui/gui/psppire-dialog-action-frequencies.c [new file with mode: 0644]
src/ui/gui/psppire-dialog-action-frequencies.h [new file with mode: 0644]
src/ui/gui/psppire-dialog-action-logistic.c
src/ui/gui/psppire-val-chooser.c
src/ui/gui/runs-dialog.c
src/ui/gui/select-cases-dialog.c
src/ui/gui/widgets.c
src/ui/terminal/main.c
tests/language/data-io/data-list.at
tests/language/expressions/evaluate.at
tests/language/lexer/variable-parser.at
tests/language/stats/crosstabs.at
tests/language/stats/descriptives.at
tests/language/stats/npar.at
tests/language/stats/rank.at
tests/output/charts.at
tests/ui/terminal/main.at

diff --git a/NEWS b/NEWS
index 5302e26542fe6beeec238473122727293a3f4767..e0910fe6e6b5c1b88b06818bf2189bcd52edff5d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -58,6 +58,9 @@ Changes from 0.6.2 to 0.7.9:
    - SET and SHOW no longer have ENDCMD, NULLINE, PROMPT, CPROMPT, and
      DPROMPT subcommands.  The defaults are now fixed values.
 
+   - SHOW now has a JOURNAL subcommand, to show the location of the
+     journal file.
+
    - VALUE LABELS can now assign value labels to long string
      variables.
 
index ec5ee2eae28e4cbb8ccec7ecf0e314d040411d20..d68192994084ef461d7df913596ff877dda1a74c 100644 (file)
@@ -324,7 +324,7 @@ AC_SUBST([SIZEOF_SIZE_T])
 
 AC_C_BIGENDIAN
 
-AC_CHECK_FUNCS([__setfpucw fork execl execlp isinf isnan finite getpid feholdexcept fpsetmask popen round])
+AC_CHECK_FUNCS([__setfpucw fork execl isinf isnan finite getpid feholdexcept fpsetmask popen round])
 
 AC_PROG_LN_S
 
index f327b1cc5ee15916d1b82c7cb27741cbda24a20e..24259a5808e2d0a101fbaf4acc58a1264319c334 100644 (file)
@@ -86,8 +86,9 @@ produce multiple output files, presumably in different formats.
 
 Use @samp{-} as @var{output-file} to write output to standard output.
 
-If no @option{-o} option is used, then @pspp{} writes output to standard
-output in plain text format.
+If no @option{-o} option is used, then @pspp{} writes text and CSV
+output to standard output and other kinds of output to whose name is
+based on the format, e.g.@: @file{pspp.pdf} for PDF output.
 
 @item @option{-O @var{option}=@var{value}}
 Sets an option for the output file configured by a preceding
index 10ca4ede77f9e4fbe742927ad80a9fce4471d444..94e72f668be641d81bedca51660e8716e5773c2b 100644 (file)
@@ -864,6 +864,7 @@ rounder_init (struct rounder *r, double number, int max_decimals)
   r->leading_zeros = strspn (r->string, "0.");
   r->leading_nines = strspn (r->string, "9.");
   r->integer_digits = strchr (r->string, '.') - r->string;
+  assert (r->integer_digits < 64);
   assert (r->integer_digits >= 0);
   r->negative = number < 0;
 }
index 9a60e7242383beb7c6fff28b3ec4b03dcb25365c..53e1bbfb6d6d6631b8bf0b6664b5f7d6585944ff 100644 (file)
@@ -55,7 +55,7 @@ struct fh_properties
     enum fh_mode mode;          /* File mode. */
     size_t record_width;        /* Length of fixed-format records. */
     size_t tab_width;           /* Tab width, 0=do not expand tabs. */
-    char *encoding;             /* Charset for contents. */
+    const char *encoding;       /* Charset for contents. */
   };
 
 void fh_init (void);
index 17c6032d252b97181864f43e4158900b071316fe..bc295a9aed7aa7939eb6f2f8141d82a4604d2053 100644 (file)
@@ -429,9 +429,28 @@ parse_free (struct lexer *lexer, struct dictionary *dict,
 
       if (lex_match (lexer, T_LPAREN))
        {
-         if (!parse_format_specifier (lexer, &input)
-              || !fmt_check_input (&input)
-              || !lex_force_match (lexer, T_RPAREN))
+          char type[FMT_TYPE_LEN_MAX + 1];
+
+         if (!parse_abstract_format_specifier (lexer, type, &input.w,
+                                                &input.d))
+            return NULL;
+          if (!fmt_from_name (type, &input.type))
+            {
+              msg (SE, _("Unknown format type `%s'."), type);
+              return NULL;
+            }
+
+          /* If no width was included, use the minimum width for the type.
+             This isn't quite right, because DATETIME by itself seems to become
+             DATETIME20 (see bug #30690), whereas this will become
+             DATETIME17.  The correct behavior is not documented. */
+          if (input.w == 0)
+            {
+              input.w = fmt_min_input_width (input.type);
+              input.d = 0;
+            }
+
+          if (!fmt_check_input (&input) || !lex_force_match (lexer, T_RPAREN))
             return NULL;
 
           /* As a special case, N format is treated as F format
index 1dc7c93f7778f9cc266f701a46634be448655e74..958326e48d4653cfbde6883f6b6f2a266dcded9a 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -455,7 +455,7 @@ cut_field (const struct data_parser *parser, struct dfm_reader *reader,
       /* Quoted field. */
       int quote = ss_get_byte (&p);
       if (!ss_get_until (&p, quote, field))
-        msg (SW, _("Quoted string extends beyond end of line."));
+        msg (DW, _("Quoted string extends beyond end of line."));
       if (parser->quote_escape && ss_first (p) == quote)
         {
           ds_assign_substring (tmp, *field);
@@ -464,7 +464,7 @@ cut_field (const struct data_parser *parser, struct dfm_reader *reader,
               struct substring ss;
               ds_put_byte (tmp, quote);
               if (!ss_get_until (&p, quote, &ss))
-                msg (SW, _("Quoted string extends beyond end of line."));
+                msg (DW, _("Quoted string extends beyond end of line."));
               ds_put_substring (tmp, ss);
             }
           *field = ds_ss (tmp);
@@ -473,10 +473,18 @@ cut_field (const struct data_parser *parser, struct dfm_reader *reader,
 
       /* Skip trailing soft separator and a single hard separator
          if present. */
-      ss_ltrim (&p, parser->soft_seps);
-      if (!ss_is_empty (p)
-          && ss_find_byte (parser->hard_seps, ss_first (p)) != SIZE_MAX)
-        ss_advance (&p, 1);
+      if (!ss_is_empty (p))
+        {
+          size_t n_seps = ss_ltrim (&p, parser->soft_seps);
+          if (!ss_is_empty (p)
+              && ss_find_byte (parser->hard_seps, ss_first (p)) != SIZE_MAX)
+            {
+              ss_advance (&p, 1);
+              n_seps++;
+            }
+          if (!n_seps)
+            msg (DW, _("Missing delimiter following quoted string."));
+        }
     }
   else
     {
@@ -542,7 +550,7 @@ parse_fixed (const struct data_parser *parser, struct dfm_reader *reader,
 
       if (dfm_eof (reader))
         {
-          msg (SW, _("Partial case of %d of %d records discarded."),
+          msg (DW, _("Partial case of %d of %d records discarded."),
                row - 1, parser->records_per_case);
           return false;
         }
@@ -599,7 +607,7 @@ parse_delimited_span (const struct data_parser *parser,
          if (dfm_eof (reader))
            {
              if (f > parser->fields)
-               msg (SW, _("Partial case discarded.  The first variable "
+               msg (DW, _("Partial case discarded.  The first variable "
                            "missing was %s."), f->name);
               ds_destroy (&tmp);
              return false;
@@ -641,7 +649,7 @@ parse_delimited_no_span (const struct data_parser *parser,
       if (!cut_field (parser, reader, &first_column, &last_column, &tmp, &s))
        {
          if (f < end - 1 && settings_get_undefined ())
-           msg (SW, _("Missing value(s) for all variables from %s onward.  "
+           msg (DW, _("Missing value(s) for all variables from %s onward.  "
                        "These will be filled with the system-missing value "
                        "or blanks, as appropriate."),
                 f->name);
@@ -661,7 +669,7 @@ parse_delimited_no_span (const struct data_parser *parser,
   s = dfm_get_record (reader);
   ss_ltrim (&s, parser->soft_seps);
   if (!ss_is_empty (s))
-    msg (SW, _("Record ends in data not part of any field."));
+    msg (DW, _("Record ends in data not part of any field."));
 
 exit:
   dfm_forward_record (reader);
index ccd53be04e4199913635d1568aa4af774459e36f..afeb832643f4cda772964aad6707652e07a9a0fe 100644 (file)
@@ -112,7 +112,9 @@ cmd_input_program (struct lexer *lexer, struct dataset *ds)
           emit_END_CASE (ds, inp);
           saw_END_CASE = true;
         }
-      else if (cmd_result_is_failure (result) && result != CMD_FAILURE)
+      else if (cmd_result_is_failure (result)
+               && result != CMD_FAILURE
+               && lex_get_error_mode (lexer) != LEX_ERROR_INTERACTIVE)
         {
           if (result == CMD_EOF)
             msg (SE, _("Unexpected end-of-file within INPUT PROGRAM."));
index 45a0b4b1e32d1c4cb473cfcdc810d3add3c52361..78af09da311e2d2af24f5c9a410e68311f6f769a 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -117,6 +117,13 @@ parse_format_specifier (struct lexer *lexer, struct fmt_spec *format)
       return false;
     }
 
+  if (format->w == 0 && !strchr (lex_tokcstr (lexer), '0'))
+    {
+      msg (SE, _("Format specifier `%s' lacks required width."),
+           lex_tokcstr (lexer));
+      return false;
+    }
+
   lex_get (lexer);
   return true;
 }
index 65e92091cda71760826a82c5bd36b46c5deaa2d3..67f585593950d3e39b6a457fede0da1a3499acee 100644 (file)
@@ -1519,14 +1519,13 @@ static void
 format_cell_entry (struct tab_table *table, int c, int r, double value,
                    char suffix, bool mark_missing, const struct dictionary *dict)
 {
-  const struct fmt_spec f = {FMT_F, 10, 1};
   union value v;
   char suffixes[3];
   int suffix_len;
   char *s;
 
   v.f = value;
-  s = data_out (&v, dict_get_encoding (dict), &f);
+  s = data_out (&v, dict_get_encoding (dict), settings_get_format ());
 
   suffix_len = 0;
   if (suffix != 0)
index 32a979d205fa413853c447c848f851f78b5f9752..54bc49d946a064bd3c4eee8ffdab962d611733c3 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2000, 2009-2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
 
 #include "data/casegrouper.h"
 #include "data/casereader.h"
+#include "data/casewriter.h"
 #include "data/dataset.h"
 #include "data/dictionary.h"
 #include "data/transformations.h"
@@ -74,6 +75,9 @@ struct dsc_trns
     size_t var_cnt;             /* Number of variables. */
     enum dsc_missing_type missing_type; /* Treatment of missing values. */
     enum mv_class exclude;      /* Classes of missing values to exclude. */
+    struct casereader *z_reader; /* Reader for count, mean, stddev. */
+    casenumber count;            /* Number left in this SPLIT FILE group.*/
+    bool ok;
   };
 
 /* Statistics.  Used as bit indexes, so must be 32 or fewer. */
@@ -160,6 +164,9 @@ struct dsc_proc
     unsigned long show_stats;   /* Statistics to display. */
     unsigned long calc_stats;   /* Statistics to calculate. */
     enum moment max_moment;     /* Highest moment needed for stats. */
+
+    /* Z scores. */
+    struct casewriter *z_writer; /* Mean and stddev per SPLIT FILE group. */
   };
 
 /* Parsing. */
@@ -213,6 +220,7 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
   dsc->sort_by_stat = DSC_NONE;
   dsc->sort_ascending = 1;
   dsc->show_stats = dsc->calc_stats = DEFAULT_STATS;
+  dsc->z_writer = NULL;
 
   /* Parse DESCRIPTIVES. */
   while (lex_token (lexer) != T_ENDCMD)
@@ -367,6 +375,8 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
   /* Construct z-score varnames, show translation table. */
   if (z_cnt || save_z_scores)
     {
+      struct caseproto *proto;
+
       if (save_z_scores)
         {
           int gen_cnt = 0;
@@ -386,6 +396,13 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
                 }
             }
         }
+
+      proto = caseproto_create ();
+      for (i = 0; i < 1 + 2 * z_cnt; i++)
+        proto = caseproto_add_width (proto, 0);
+      dsc->z_writer = autopaging_writer_create (proto);
+      caseproto_unref (proto);
+
       dump_z_table (dsc);
     }
 
@@ -475,6 +492,7 @@ free_dsc_proc (struct dsc_proc *dsc)
       free (dsc_var->z_name);
       moments_destroy (dsc_var->moments);
     }
+  casewriter_destroy (dsc->z_writer);
   free (dsc->vars);
   free (dsc);
 }
@@ -601,6 +619,36 @@ descriptives_trns_proc (void *trns_, struct ccase **c,
   const struct variable **vars;
   int all_sysmis = 0;
 
+  if (t->count <= 0)
+    {
+      struct ccase *z_case;
+
+      z_case = casereader_read (t->z_reader);
+      if (z_case)
+        {
+          size_t z_idx = 0;
+
+          t->count = case_num_idx (z_case, z_idx++);
+          for (z = t->z_scores; z < t->z_scores + t->z_score_cnt; z++)
+            {
+              z->mean = case_num_idx (z_case, z_idx++);
+              z->std_dev = case_num_idx (z_case, z_idx++);
+            }
+          case_unref (z_case);
+        }
+      else
+        {
+          if (t->ok)
+            {
+              msg (SE, _("Internal error processing Z scores"));
+              t->ok = false;
+            }
+          for (z = t->z_scores; z < t->z_scores + t->z_score_cnt; z++)
+            z->mean = z->std_dev = SYSMIS;
+        }
+    }
+  t->count--;
+
   if (t->missing_type == DSC_LISTWISE)
     {
       assert(t->vars);
@@ -635,11 +683,13 @@ static bool
 descriptives_trns_free (void *trns_)
 {
   struct dsc_trns *t = trns_;
+  bool ok = t->ok && !casereader_error (t->z_reader);
 
   free (t->z_scores);
+  casereader_destroy (t->z_reader);
   assert((t->missing_type != DSC_LISTWISE) ^ (t->vars != NULL));
   free (t->vars);
-  return true;
+  return ok;
 }
 
 /* Sets up a transformation to calculate Z scores. */
@@ -670,6 +720,10 @@ setup_z_trns (struct dsc_proc *dsc, struct dataset *ds)
       t->var_cnt = 0;
       t->vars = NULL;
     }
+  t->z_reader = casewriter_make_reader (dsc->z_writer);
+  t->count = 0;
+  t->ok = true;
+  dsc->z_writer = NULL;
 
   for (cnt = i = 0; i < dsc->var_cnt; i++)
     {
@@ -687,8 +741,6 @@ setup_z_trns (struct dsc_proc *dsc, struct dataset *ds)
           z = &t->z_scores[cnt++];
           z->src_var = dv->v;
           z->z_var = dst_var;
-          z->mean = dv->stats[DSC_MEAN];
-          z->std_dev = dv->stats[DSC_STDDEV];
        }
     }
 
@@ -707,7 +759,9 @@ calc_descriptives (struct dsc_proc *dsc, struct casereader *group,
                    struct dataset *ds)
 {
   struct casereader *pass1, *pass2;
+  casenumber count;
   struct ccase *c;
+  size_t z_idx;
   size_t i;
 
   c = casereader_peek (group, 0);
@@ -739,6 +793,7 @@ calc_descriptives (struct dsc_proc *dsc, struct casereader *group,
   dsc->valid = 0.;
 
   /* First pass to handle most of the work. */
+  count = 0;
   for (; (c = casereader_read (pass1)) != NULL; case_unref (c))
     {
       double weight = dict_get_case_weight (dataset_dict (ds), c, NULL);
@@ -771,6 +826,8 @@ calc_descriptives (struct dsc_proc *dsc, struct casereader *group,
           if (x > dv->max)
             dv->max = x;
         }
+
+      count++;
     }
   if (!casereader_destroy (pass1))
     {
@@ -806,6 +863,15 @@ calc_descriptives (struct dsc_proc *dsc, struct casereader *group,
     }
 
   /* Calculate results. */
+  if (dsc->z_writer)
+    {
+      c = case_create (casewriter_get_proto (dsc->z_writer));
+      z_idx = 0;
+      case_data_rw_idx (c, z_idx++)->f = count;
+    }
+  else
+    c = NULL;
+
   for (i = 0; i < dsc->var_cnt; i++)
     {
       struct dsc_var *dv = &dsc->vars[i];
@@ -839,8 +905,17 @@ calc_descriptives (struct dsc_proc *dsc, struct casereader *group,
       dv->stats[DSC_MAX] = dv->max == -DBL_MAX ? SYSMIS : dv->max;
       if (dsc->calc_stats & (1ul << DSC_SUM))
         dv->stats[DSC_SUM] = W * dv->stats[DSC_MEAN];
+
+      if (dv->z_name)
+        {
+          case_data_rw_idx (c, z_idx++)->f = dv->stats[DSC_MEAN];
+          case_data_rw_idx (c, z_idx++)->f = dv->stats[DSC_STDDEV];
+        }
     }
 
+  if (c != NULL)
+    casewriter_write (dsc->z_writer, c);
+
   /* Output results. */
   display (dsc);
 }
index af41b104731665e4adb4202d609de00fa8f77a7d..737c94e3d2a296dfd4f999dac4e822c5c08e5ea3 100644 (file)
@@ -945,7 +945,8 @@ npar_binomial (struct lexer *lexer, struct dataset *ds,
        {
          if (lex_match (lexer, T_LPAREN))
            {
-             lex_force_num (lexer);
+             if (! lex_force_num (lexer))
+               return 2;
              btp->category1 = lex_number (lexer);
              lex_get (lexer);
              if ( lex_match (lexer, T_COMMA))
index 243de30063c8b12332009d185ed02274c0a5bb06..e6e816a8b79ea57cfc5b21c4057efdbb458ac872 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -708,6 +708,14 @@ show_format (const struct dataset *ds UNUSED)
   return xstrdup (fmt_to_string (settings_get_format (), str));
 }
 
+static char *
+show_journal (const struct dataset *ds UNUSED)
+{
+  return (journal_is_enabled ()
+          ? xasprintf ("\"%s\"", journal_get_file_name ())
+          : xstrdup ("disabled"));
+}
+
 static char *
 show_length (const struct dataset *ds UNUSED)
 {
@@ -935,6 +943,7 @@ const struct show_sbc show_table[] =
     {"ENVIRONMENT", show_system},
     {"ERRORS", show_errors},
     {"FORMAT", show_format},
+    {"JOURNAL", show_journal},
     {"LENGTH", show_length},
     {"LOCALE", show_locale},
     {"MESSAGES", show_messages},
index 5b10d638abb2f7bf6cfcb7a87a3d77ca305b99c2..237710813d52ffaa1237f17e55ddbf981e0429e8 100644 (file)
@@ -36,3 +36,6 @@
 #else
 #define expensive_assert(EXPR) ((void) 0)
 #endif
+
+
+#define testing_assert(EXPR) do {if (settings_get_testing_mode ()) assert (EXPR); }  while (0);
index afc40013e02865f46f82549599f4f9cb84812706..b00067210f08676736d589660c9eb85f75216831 100644 (file)
@@ -21,6 +21,7 @@
 #include <gsl/gsl_histogram.h>
 #include <math.h>
 
+#include "data/settings.h"
 #include "libpspp/message.h"
 #include "libpspp/assertion.h"
 #include "libpspp/cast.h"
@@ -84,6 +85,10 @@ double get_slack (double limit, double half_bin_width, int *n_half_bins)
    ADJ_MIN and ADJ_MAX are locations of the adjusted values of MIN and MAX (the range will
    always be  equal or slightly larger).
    Returns the number of bins.
+
+   The "testing_assert" expressions in this function should be algebraically correct.
+   However, due to floating point rounding they could fail, especially when small numbers
+   are involved.  In normal use, therefore, testing_assert does nothing.
  */
 static int
 adjust_bin_ranges (double bin_width, double min, double max, double *adj_min, double *adj_max)
@@ -97,7 +102,7 @@ adjust_bin_ranges (double bin_width, double min, double max, double *adj_min, do
   double lower_slack =  get_slack (min, half_bin_width, &lower_limit);
   double upper_slack = -get_slack (max, half_bin_width, &upper_limit);
 
-  assert (max > min);
+  testing_assert (max > min);
 
   /* If min is negative, then lower_slack may be less than zero.
      In this case, the lower bound must be extended in the negative direction
@@ -108,7 +113,7 @@ adjust_bin_ranges (double bin_width, double min, double max, double *adj_min, do
       lower_limit--;
       lower_slack += half_bin_width;
     }
-  assert (lower_limit * half_bin_width <= min);
+  testing_assert (lower_limit * half_bin_width <= min);
 
   /* However, the upper bound must be extended regardless, because histogram bins
      span the range [lower, upper). In other words, the upper bound must be
@@ -116,7 +121,7 @@ adjust_bin_ranges (double bin_width, double min, double max, double *adj_min, do
   */
   upper_limit++;;
   upper_slack += half_bin_width;
-  assert (upper_limit * half_bin_width > max);
+  testing_assert (upper_limit * half_bin_width > max);
 
   /* The range must be an EVEN number of half bin_widths */
   if ( (upper_limit - lower_limit) % 2)
@@ -159,7 +164,7 @@ adjust_bin_ranges (double bin_width, double min, double max, double *adj_min, do
 
       if (upper_slack > lower_slack)
         {
-          assert (upper_slack > half_bin_width);
+          testing_assert (upper_slack > half_bin_width);
 
           /* Adjust the range to the left */
           lower_limit --;
@@ -169,7 +174,7 @@ adjust_bin_ranges (double bin_width, double min, double max, double *adj_min, do
         }
       else
         {
-          assert (lower_slack >= half_bin_width);
+          testing_assert (lower_slack >= half_bin_width);
 
           /* Adjust the range to the right */
           lower_limit ++;
@@ -197,8 +202,8 @@ adjust_bin_ranges (double bin_width, double min, double max, double *adj_min, do
   *adj_min = lower_limit * half_bin_width;
   *adj_max = upper_limit * half_bin_width;
 
-  assert (*adj_max > max);
-  assert (*adj_min <= min);
+  testing_assert (*adj_max > max);
+  testing_assert (*adj_min <= min);
 
   return (upper_limit - lower_limit) / 2.0;
 }
index 1688fd1bf1217c8e0df48109eb64df2f7a45f1d9..9614e6aef899d88353142f7f1827a7a9ad5462d1 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -593,9 +593,9 @@ ascii_submit (struct output_driver *driver,
 }
 
 const struct output_driver_factory txt_driver_factory =
-  { "txt", ascii_create };
+  { "txt", "-", ascii_create };
 const struct output_driver_factory list_driver_factory =
-  { "list", ascii_create };
+  { "list", "-", ascii_create };
 
 static const struct output_driver_class ascii_driver_class =
   {
index 954ae30f5448b40ecfb3bd0bd5691e9a8f9cd4d7..cd8f0b0e999decb2ae1434463885c045ae827600 100644 (file)
@@ -922,9 +922,12 @@ xr_draw_title (struct xr_driver *xr, const char *title,
   xr_draw_cell (xr, &cell, bb, bb);
 }
 \f
-struct output_driver_factory pdf_driver_factory = { "pdf", xr_pdf_create };
-struct output_driver_factory ps_driver_factory = { "ps", xr_ps_create };
-struct output_driver_factory svg_driver_factory = { "svg", xr_svg_create };
+struct output_driver_factory pdf_driver_factory =
+  { "pdf", "pspp.pdf", xr_pdf_create };
+struct output_driver_factory ps_driver_factory =
+  { "ps", "pspp.ps", xr_ps_create };
+struct output_driver_factory svg_driver_factory =
+  { "svg", "pspp.svg", xr_svg_create };
 
 static const struct output_driver_class cairo_driver_class =
 {
index c8619a9a7d403ebc84ebc55d9c307976a49b734b..b57eb7c2d04eb7cdfb0e478a771d0495288de362 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -255,7 +255,7 @@ csv_submit (struct output_driver *driver,
     }
 }
 
-struct output_driver_factory csv_driver_factory = { "csv", csv_create };
+struct output_driver_factory csv_driver_factory = { "csv", "-", csv_create };
 
 static const struct output_driver_class csv_driver_class =
   {
index df31637379b070cf3c5ddf5b90c4f9948f1f4b91..012a304e36ac46cf58dfcb66fc5533cbb8b81af3 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -80,6 +80,12 @@ struct output_driver_factory
     /* The file extension, without the leading dot, e.g. "pdf". */
     const char *extension;
 
+    /* The default file name, including extension.
+
+       If this is "-", that implies that by default output will be directed to
+       stdout. */
+    const char *default_file_name;
+
     /* Creates a new output driver of this class.  NAME and TYPE should be
        passed directly to output_driver_init.  Returns the new output driver if
        successful, otherwise a null pointer.
index acc58cf999cdd7b77d533f54edc9ce17db954550..f656845527f4603937ebd02d6698a37865b041cf 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -294,16 +294,23 @@ output_driver_create (struct string_map *options)
   char *file_name;
   char *format;
 
+  format = string_map_find_and_delete (options, "format");
   file_name = string_map_find_and_delete (options, "output-file");
-  if (file_name == NULL)
-    file_name = xstrdup ("-");
 
-  format = string_map_find_and_delete (options, "format");
   if (format == NULL)
     {
-      const char *extension = strrchr (file_name, '.');
-      format = xstrdup (extension != NULL ? extension + 1 : "");
+      if (file_name != NULL)
+        {
+          const char *extension = strrchr (file_name, '.');
+          format = xstrdup (extension != NULL ? extension + 1 : "");
+        }
+      else
+        format = xstrdup ("txt");
     }
+  f = find_factory (format);
+
+  if (file_name == NULL)
+    file_name = xstrdup (f->default_file_name);
 
   /* XXX should use parse_enum(). */
   device_string = string_map_find_and_delete (options, "device");
@@ -320,7 +327,6 @@ output_driver_create (struct string_map *options)
       device_type = default_device_type (file_name);
     }
 
-  f = find_factory (format);
   driver = f->create (file_name, device_type, options);
   if (driver != NULL)
     {
index 77d4195f30c2a2e5319a8192701736964c2feb51..29a44721d455ae3f0336e1f95d52610e9c5df1c1 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -477,7 +477,8 @@ html_output_table (struct html_driver *html, struct table_item *item)
   fputs ("</TABLE>\n\n", html->file);
 }
 
-struct output_driver_factory html_driver_factory = { "html", html_create };
+struct output_driver_factory html_driver_factory =
+  { "html", "pspp.html", html_create };
 
 static const struct output_driver_class html_driver_class =
   {
index 66c1b77534e98118ca7b300bb523d47b1d4b3493..2b5835052029dbfda9ecf19fb27702be354d9be8 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2010, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -87,11 +87,11 @@ journal_output (struct journal_driver *j, const char *s)
 {
   if (j->file == NULL)
     {
-      j->file = fopen (journal_file_name, "a");
+      j->file = fopen (journal_get_file_name (), "a");
       if (j->file == NULL)
         {
           error (0, errno, _("error opening output file `%s'"),
-                 journal_file_name);
+                 journal_get_file_name ());
           output_driver_destroy (&j->driver);
           return;
         }
@@ -144,13 +144,6 @@ journal_enable (void)
 {
   if (journal == NULL)
     {
-      /* If no journal file name is configured, use the default. */
-      if (journal_file_name == NULL)
-       {
-         const char *output_path = default_output_path ();
-         journal_file_name = xasprintf ("%s%s", output_path, "pspp.jnl");
-       }
-
       /* Create journal driver. */
       journal = xzalloc (sizeof *journal);
       output_driver_init (&journal->driver, &journal_class, "journal",
@@ -171,6 +164,13 @@ journal_disable (void)
     output_driver_destroy (&journal->driver);
 }
 
+/* Returns true if journaling is enabled, false otherwise. */
+bool
+journal_is_enabled (void)
+{
+  return journal != NULL;
+}
+
 /* Sets the name of the journal file to FILE_NAME. */
 void
 journal_set_file_name (const char *file_name)
@@ -179,3 +179,16 @@ journal_set_file_name (const char *file_name)
   free (journal_file_name);
   journal_file_name = xstrdup (file_name);
 }
+
+/* Returns the name of the journal file.  The caller must not modify or free
+   the returned string. */
+const char *
+journal_get_file_name (void)
+{
+  if (journal_file_name == NULL)
+    {
+      const char *output_path = default_output_path ();
+      journal_file_name = xasprintf ("%s%s", output_path, "pspp.jnl");
+    }
+  return journal_file_name;
+}
index 5051193a67ea3c7d03ed61be1fddfe0167273173..377152d5ce14cd6a3e3a82eeeb664ea5bc80f0e0 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -28,6 +28,8 @@
 
 void journal_enable (void);
 void journal_disable (void);
+bool journal_is_enabled (void);
 void journal_set_file_name (const char *);
+const char *journal_get_file_name (void);
 
 #endif /* output/journal.h */
index 14cd5dab9fdb56de6e263a4b4162a94df60dc4cb..60894f1cc25f81b3b21ae862ee646e0ac1d3c0ac 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "output/measure.h"
 
+#include <gl/c-strtod.h>
 #include <ctype.h>
 #include <errno.h>
 #if HAVE_LC_PAPER
@@ -50,7 +51,7 @@ measure_dimension (const char *dimen)
   char *tail;
 
   /* Number. */
-  raw = strtod (dimen, &tail);
+  raw = c_strtod (dimen, &tail);
   if (raw < 0.0)
     goto syntax_error;
 
@@ -150,7 +151,7 @@ parse_paper_size (const char *size, int *h, int *v)
   char *tail;
 
   /* Width. */
-  raw_h = strtod (size, &tail);
+  raw_h = c_strtod (size, &tail);
   if (raw_h <= 0.0)
     return false;
 
@@ -158,7 +159,7 @@ parse_paper_size (const char *size, int *h, int *v)
   tail += strspn (tail, CC_SPACES "x,");
 
   /* Length. */
-  raw_v = strtod (tail, &tail);
+  raw_v = c_strtod (tail, &tail);
   if (raw_v <= 0.0)
     return false;
 
index 686e7149c3b68b34002308e1147c3ebbd08eb756..a02506c1e9eeacbae9528aa663e55044e8194055 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -517,7 +517,8 @@ odt_submit (struct output_driver *driver,
     }
 }
 
-struct output_driver_factory odt_driver_factory = { "odt", odt_create };
+struct output_driver_factory odt_driver_factory =
+  { "odt", "pspp.odf", odt_create };
 
 static const struct output_driver_class odt_driver_class =
 {
index a4eeebf11cb48e50b639928d26abad1e2a1b0381..db634cee16c5b24daf2a2cb9c8bc180ce0c65764 100644 (file)
@@ -7,7 +7,6 @@ include $(top_srcdir)/src/ui/gui/automake.mk
 noinst_LTLIBRARIES += src/ui/libuicommon.la
 
 src_ui_libuicommon_la_SOURCES = \
-       src/ui/debugger.c src/ui/debugger.h \
        src/ui/source-init-opts.c src/ui/source-init-opts.h \
        src/ui/syntax-gen.c src/ui/syntax-gen.h
 
diff --git a/src/ui/debugger.c b/src/ui/debugger.c
deleted file mode 100644 (file)
index f3f6784..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* PSPP - a program for statistical analysis.
-   Copyright (C) 2006 Free Software Foundation, Inc.
-
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-
-#include "debugger.h"
-
-#if HAVE_FORK && HAVE_EXECLP
-#include <errno.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-
-/* Fork, start gdb and connect to the parent process.
-   If that happens successfully, then this function does not return,
-   but exits with EXIT_FAILURE. Otherwise it returns.
- */
-void
-connect_debugger (void)
-{
-  char pidstr[20];
-  pid_t pid;
-
-  snprintf (pidstr, 20, "%d", getpid ());
-  pid = fork ();
-  if ( pid  == -1 )
-    {
-      perror ("Cannot fork");
-      return ;
-    }
-  if ( pid == 0 )
-    {
-      /* child */
-      execlp ("gdb", "gdb", "-p", pidstr, NULL);
-      perror ("Cannot exec debugger");
-      exit (EXIT_FAILURE);
-    }
-  else
-    {
-      int status;
-      wait (&status);
-      if ( EXIT_SUCCESS != WEXITSTATUS (status) )
-       return ;
-    }
-
-  exit (EXIT_FAILURE);
-}
-
-#else /* !(HAVE_FORK && HAVE_EXECLP) */
-/* Don't know how to connect to gdb.
-   Just return.
- */
-void
-connect_debugger (void)
-{
-}
-#endif /* !(HAVE_FORK && HAVE_EXECLP) */
diff --git a/src/ui/debugger.h b/src/ui/debugger.h
deleted file mode 100644 (file)
index 321e6ca..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* PSPP - a program for statistical analysis.
-   Copyright (C) 2006 Free Software Foundation, Inc.
-
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef DEBUGGER_H
-#define DEBUGGER_H
-
-
-/* Fork, start gdb and connect to the parent process.
-   Exit with EXIT_FAILURE.
- */
-void connect_debugger (void) ;
-
-#endif
index a5c243a8e2de40c5fa4f80d5f581248f471807a0..8b54ed584afe84798b8475e46295bed1b66060fa 100644 (file)
@@ -93,15 +93,6 @@ struct aggregate
 static char * generate_syntax (const struct aggregate *rd);
 
 
-/* Makes widget W's sensitivity follow the active state of TOGGLE */
-static void
-sensitive_if_active (GtkToggleButton *toggle, GtkWidget *w)
-{
-  gboolean active = gtk_toggle_button_get_active (toggle);
-
-  gtk_widget_set_sensitive (w, active);
-}
-
 static void update_arguments (struct aggregate *agg);
 
 
@@ -577,7 +568,7 @@ aggregate_dialog (PsppireDataWindow *dw)
                                      dialog_state_valid, &fd);
 
   g_signal_connect (fd.filename_radiobutton, "toggled",
-                   G_CALLBACK (sensitive_if_active), fd.filename_box );
+                   G_CALLBACK (set_sensitivity_from_toggle), fd.filename_box );
 
   g_signal_connect_swapped (fd.filename_button, "clicked",
                    G_CALLBACK (choose_filename), &fd);
index ea1f06df8b3ba5b1beb87d8051d0a21f1035a3ca..8cba97018bd166cfb06f6dc6fcaa7ec3f6ace615 100644 (file)
@@ -163,8 +163,6 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/autorecode-dialog.h \
        src/ui/gui/aggregate-dialog.c \
        src/ui/gui/aggregate-dialog.h \
-       src/ui/gui/binomial-dialog.c \
-       src/ui/gui/binomial-dialog.h \
        src/ui/gui/builder-wrapper.c \
        src/ui/gui/builder-wrapper.h \
        src/ui/gui/checkbox-treeview.c \
@@ -177,8 +175,6 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/chi-square-dialog.h \
        src/ui/gui/count-dialog.c \
        src/ui/gui/count-dialog.h \
-       src/ui/gui/crosstabs-dialog.c \
-       src/ui/gui/crosstabs-dialog.h \
        src/ui/gui/dialog-common.c \
        src/ui/gui/dialog-common.h \
        src/ui/gui/dict-display.h \
@@ -189,8 +185,6 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/executor.h \
        src/ui/gui/find-dialog.c \
        src/ui/gui/find-dialog.h \
-       src/ui/gui/frequencies-dialog.c \
-       src/ui/gui/frequencies-dialog.h \
        src/ui/gui/goto-case-dialog.c \
        src/ui/gui/goto-case-dialog.h \
        src/ui/gui/helper.c \
@@ -225,14 +219,20 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/psppire-dialog.h \
        src/ui/gui/psppire-dialog-action.c \
        src/ui/gui/psppire-dialog-action.h \
+       src/ui/gui/psppire-dialog-action-binomial.c \
+       src/ui/gui/psppire-dialog-action-binomial.h \
        src/ui/gui/psppire-dialog-action-correlation.c \
        src/ui/gui/psppire-dialog-action-correlation.h \
+       src/ui/gui/psppire-dialog-action-crosstabs.c \
+       src/ui/gui/psppire-dialog-action-crosstabs.h \
        src/ui/gui/psppire-dialog-action-descriptives.c \
        src/ui/gui/psppire-dialog-action-descriptives.h \
        src/ui/gui/psppire-dialog-action-examine.c \
        src/ui/gui/psppire-dialog-action-examine.h \
        src/ui/gui/psppire-dialog-action-factor.c \
        src/ui/gui/psppire-dialog-action-factor.h \
+       src/ui/gui/psppire-dialog-action-frequencies.c \
+       src/ui/gui/psppire-dialog-action-frequencies.h \
        src/ui/gui/psppire-dialog-action-indep-samps.c \
        src/ui/gui/psppire-dialog-action-indep-samps.h \
        src/ui/gui/psppire-dialog-action-kmeans.c \
diff --git a/src/ui/gui/binomial-dialog.c b/src/ui/gui/binomial-dialog.c
deleted file mode 100644 (file)
index 90d9118..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2010, 2011, 2012  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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-
-#include "binomial-dialog.h"
-
-#include "psppire-dialog.h"
-#include "psppire-var-view.h"
-#include "psppire-acr.h"
-#include "dialog-common.h"
-
-#include "builder-wrapper.h"
-#include "executor.h"
-#include "helper.h"
-
-#include <gtk/gtk.h>
-
-struct binomial_dialog
-{
-  PsppireDict *dict;
-  GtkWidget *var_view;
-
-  GtkWidget *button1;
-
-  GtkWidget *prop_entry;
-
-  GtkWidget *cutpoint_button;
-  GtkWidget *cutpoint_entry;
-};
-
-static void
-set_sensitivity (GtkToggleButton *button, GtkWidget *w)
-{
-  gboolean state = gtk_toggle_button_get_active (button);
-  gtk_widget_set_sensitive (w, state);
-}
-
-
-static gboolean
-get_proportion (const struct binomial_dialog *bin_d, double *prop)
-{
-    const gchar *text = gtk_entry_get_text (GTK_ENTRY (bin_d->prop_entry));
-    gchar *endptr = NULL;
-     *prop = g_strtod (text, &endptr);
-
-    if (endptr == text)
-      return FALSE;
-
-    return TRUE; 
-}
-
-static gboolean
-dialog_state_valid (gpointer data)
-{
-  double prop;
-  struct binomial_dialog *bin_d = data;
-
-  GtkTreeModel *vars =
-    gtk_tree_view_get_model (GTK_TREE_VIEW (bin_d->var_view));
-
-  GtkTreeIter notused;
-
-  if ( !gtk_tree_model_get_iter_first (vars, &notused) )
-    return FALSE;
-
-  if ( ! get_proportion (bin_d, &prop))
-    return FALSE;
-
-  if (prop < 0 || prop > 1.0)
-    return FALSE;
-
-  return TRUE;
-}
-
-
-static void
-refresh (struct binomial_dialog *bin_d)
-{
-  GtkTreeModel *liststore =
-    gtk_tree_view_get_model (GTK_TREE_VIEW (bin_d->var_view));
-
-  gtk_list_store_clear (GTK_LIST_STORE (liststore));
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bin_d->button1), TRUE);
-
-  gtk_entry_set_text (GTK_ENTRY (bin_d->prop_entry), "0.5");
-
-  gtk_entry_set_text (GTK_ENTRY (bin_d->cutpoint_entry), "");
-}
-
-
-
-static char *
-generate_syntax (const struct binomial_dialog *scd)
-{
-  gchar *text;
-  double prop;
-  GString *string;
-
-  string = g_string_new ("NPAR TEST\n\t/BINOMIAL");
-
-  if ( get_proportion (scd, &prop))
-    g_string_append_printf (string, "(%g)", prop);
-
-  g_string_append (string, " =");
-
-  psppire_var_view_append_names (PSPPIRE_VAR_VIEW (scd->var_view), 0, string);
-
-  if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scd->cutpoint_button)))
-    {
-      const gchar *cutpoint = gtk_entry_get_text (GTK_ENTRY (scd->cutpoint_entry));
-      g_string_append_printf (string, "(%s)", cutpoint);
-    }
-
-  g_string_append (string, ".\n");
-
-  text = string->str;
-
-  g_string_free (string, FALSE);
-
-  return text;
-}
-
-
-
-/* Pops up the Chi-Square dialog box */
-void
-binomial_dialog (PsppireDataWindow *dw)
-{
-  gint response;
-
-  struct binomial_dialog bin_d;
-
-  GtkBuilder *xml = builder_new ("binomial.ui");
-
-  GtkWidget *dialog = get_widget_assert   (xml, "binomial-dialog");
-
-
-
-  GtkWidget *dict_view = get_widget_assert   (xml, "dict-view");
-
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (dw));
-
-  bin_d.var_view  = get_widget_assert (xml, "variables-treeview");
-  bin_d.button1   = get_widget_assert (xml, "radiobutton3");
-  bin_d.prop_entry = get_widget_assert (xml, "proportion-entry");
-
-  bin_d.cutpoint_entry =     get_widget_assert   (xml, "cutpoint-entry");
-  bin_d.cutpoint_button =    get_widget_assert   (xml, "radiobutton4");
-
-  g_object_get (dw->data_editor, "dictionary", &bin_d.dict, NULL);
-  g_object_set (dict_view,
-               "model", bin_d.dict, 
-               "predicate", var_is_numeric,
-               NULL);
-
-  g_signal_connect (bin_d.cutpoint_button, "toggled", G_CALLBACK (set_sensitivity),
-                   bin_d.cutpoint_entry);
-
-  g_signal_connect_swapped (dialog, "refresh", G_CALLBACK (refresh),  &bin_d);
-
-  psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog),
-                                     dialog_state_valid, &bin_d);
-
-  response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
-
-
-  switch (response)
-    {
-    case GTK_RESPONSE_OK:
-      g_free (execute_syntax_string (dw, generate_syntax (&bin_d)));
-      break;
-    case PSPPIRE_RESPONSE_PASTE:
-      g_free (paste_syntax_to_window (generate_syntax (&bin_d)));
-      break;
-    default:
-      break;
-    }
-
-  g_object_unref (xml);
-}
diff --git a/src/ui/gui/binomial-dialog.h b/src/ui/gui/binomial-dialog.h
deleted file mode 100644 (file)
index b50e444..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2010  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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef __BINOMIAL_DIALOG_H
-#define __BINOMIAL_DIALOG_H
-
-#include "psppire-data-window.h"
-
-void binomial_dialog (PsppireDataWindow * data);
-
-#endif
index 64a6356ce188f3d0356c3d6051102ddbe083f942..5d4cc4b431038ad00ab77e550214b605c308e9d1 100644 (file)
@@ -46,14 +46,6 @@ struct chisquare_dialog
   GtkListStore *expected_list;
 };
 
-static void
-set_sensitivity (GtkToggleButton *button, GtkWidget *w)
-{
-  gboolean state = gtk_toggle_button_get_active (button);
-  gtk_widget_set_sensitive (w, state);
-}
-
-
 static gboolean
 dialog_state_valid (gpointer data)
 {
@@ -198,14 +190,14 @@ chisquare_dialog (PsppireDataWindow *dw)
                NULL);
 
 
-  g_signal_connect (csd.range_button, "toggled", G_CALLBACK (set_sensitivity), 
+  g_signal_connect (csd.range_button, "toggled", G_CALLBACK (set_sensitivity_from_toggle), 
                    range_table);
 
 
-  g_signal_connect (csd.values_button, "toggled", G_CALLBACK (set_sensitivity), 
+  g_signal_connect (csd.values_button, "toggled", G_CALLBACK (set_sensitivity_from_toggle), 
                    values_acr);
 
-  g_signal_connect (csd.values_button, "toggled", G_CALLBACK (set_sensitivity), 
+  g_signal_connect (csd.values_button, "toggled", G_CALLBACK (set_sensitivity_from_toggle), 
                    expected_value_entry);
 
 
diff --git a/src/ui/gui/crosstabs-dialog.c b/src/ui/gui/crosstabs-dialog.c
deleted file mode 100644 (file)
index 3cb8218..0000000
+++ /dev/null
@@ -1,431 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2008, 2010, 2011, 2012  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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-
-#include "checkbox-treeview.h"
-#include "crosstabs-dialog.h"
-#include "psppire-var-view.h"
-
-#include <gtk/gtk.h>
-#include <stdlib.h>
-
-#include <ui/gui/psppire-data-window.h>
-#include <ui/gui/dialog-common.h>
-#include <ui/gui/dict-display.h>
-#include "executor.h"
-#include <ui/gui/psppire-dialog.h>
-#include <ui/gui/builder-wrapper.h>
-#include "helper.h"
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-
-#define CROSSTABS_STATS                         \
-  CS (CHISQ, N_("Chisq"))                       \
-  CS (PHI, N_("Phi"))                           \
-  CS (CC, N_("CC"))                             \
-  CS (LAMBDA, N_("Lambda"))                     \
-  CS (UC, N_("UC"))                             \
-  CS (BTAU, N_("BTau"))                         \
-  CS (CTAU, N_("CTau"))                         \
-  CS (RISK, N_("Risk"))                         \
-  CS (GAMMA, N_("Gamma"))                       \
-  CS (D, N_("D"))                               \
-  CS (KAPPA, N_("Kappa"))                       \
-  CS (ETA, N_("Eta"))                           \
-  CS (CORR, N_("Corr"))                         \
-  CS (STATS_NONE, N_("None"))
-
-#define CROSSTABS_CELLS                         \
-  CS (COUNT, N_("Count"))                       \
-  CS (ROW, N_("Row"))                           \
-  CS (COLUMN, N_("Column"))                     \
-  CS (TOTAL, N_("Total"))                       \
-  CS (EXPECTED, N_("Expected"))                 \
-  CS (RESIDUAL, N_("Residual"))                 \
-  CS (SRESIDUAL, N_("Std. Residual"))           \
-  CS (ASRESIDUAL, N_("Adjusted Std. Residual")) \
-  CS (CELLS_NONE, N_("None"))
-
-enum
-  {
-#define CS(NAME, LABEL) CS_##NAME,
-    CROSSTABS_STATS
-#undef CS
-    N_CROSSTABS_STATS
-  };
-
-enum
-  {
-#define CS(NAME, LABEL) CS_##NAME,
-    CROSSTABS_CELLS
-#undef CS
-    N_CROSSTABS_CELLS
-  };
-
-enum
-  {
-#define CS(NAME, LABEL) B_CS_##NAME = 1u << CS_##NAME,
-    CROSSTABS_STATS
-    CROSSTABS_CELLS
-#undef CS
-    B_CS_STATS_ALL = (1u << N_CROSSTABS_STATS) - 1,
-    B_CS_CELLS_ALL = (1u << N_CROSSTABS_CELLS) - 1,
-    B_CS_STATS_DEFAULT = B_CS_CHISQ,
-    B_CS_CELL_DEFAULT = B_CS_COUNT | B_CS_ROW | B_CS_COLUMN | B_CS_TOTAL,
-    B_CS_NONE
-  };
-
-static const struct checkbox_entry_item stats[] =
-  {
-#define CS(NAME, LABEL) {#NAME, LABEL},
-    CROSSTABS_STATS \
-    CS(NONE, N_("None"))
-#undef CS
-  };
-
-static const struct checkbox_entry_item cells[] =
-  {
-#define CS(NAME, LABEL) {#NAME, LABEL},
-    CROSSTABS_CELLS \
-    CS(NONE, N_("None"))
-#undef CS
-  };
-
-struct format_options
-{
-  gboolean avalue;
-  gboolean pivot;
-  gboolean table;
-};
-
-struct crosstabs_dialog
-{
-  GtkTreeView *row_vars;
-  GtkTreeView *col_vars;
-  PsppireDict *dict;
-
-  GtkToggleButton *table_button;
-  GtkToggleButton *pivot_button;
-
-  GtkWidget *format_dialog;
-  GtkWidget *cell_dialog;
-  GtkWidget *stat_dialog;
-
-  GtkToggleButton  *avalue;
-  GtkTreeModel *stat;
-  GtkTreeModel *cell;
-
-  GtkWidget *stat_view;
-  GtkWidget *cell_view;
-  struct format_options current_opts;
-};
-
-static void
-refresh (PsppireDialog *dialog, struct crosstabs_dialog *cd)
-{
-  GtkTreeModel *liststore = gtk_tree_view_get_model (cd->row_vars);
-  gtk_list_store_clear (GTK_LIST_STORE (liststore));
-  
-  liststore = gtk_tree_view_get_model (cd->col_vars);
-  gtk_list_store_clear (GTK_LIST_STORE (liststore));
-}
-static void
-on_format_clicked (struct crosstabs_dialog *cd)
-{
-  int ret;
-
-  if (cd->current_opts.avalue)
-    {
-      gtk_toggle_button_set_active (cd->avalue, TRUE);
-    }
-  if (cd->current_opts.table)
-    {
-      gtk_toggle_button_set_active (cd->table_button, TRUE);
-    }
-  if (cd->current_opts.pivot)
-    {
-      gtk_toggle_button_set_active (cd->pivot_button, TRUE);
-    }
-
-  ret = psppire_dialog_run (PSPPIRE_DIALOG (cd->format_dialog));
-
-  if ( ret == PSPPIRE_RESPONSE_CONTINUE )
-    {
-      cd->current_opts.avalue = (gtk_toggle_button_get_active (cd->avalue) == TRUE ) 
-       ? TRUE : FALSE;
-      cd->current_opts.table = (gtk_toggle_button_get_active (cd->table_button) == TRUE)
-       ? TRUE : FALSE;
-      cd->current_opts.pivot = (gtk_toggle_button_get_active (cd->pivot_button) == TRUE)
-       ? TRUE : FALSE;
-    }
-}
-
-static void
-on_statistics_clicked (struct crosstabs_dialog *cd)
-{
-  GtkListStore *liststore;
-  int ret;
-
-  liststore = clone_list_store (GTK_LIST_STORE (cd->stat));
-
-  ret = psppire_dialog_run (PSPPIRE_DIALOG (cd->stat_dialog));
-
-  if ( ret == PSPPIRE_RESPONSE_CONTINUE )
-    {
-      g_object_unref (liststore);
-    }
-  else
-    {
-      g_object_unref (cd->stat);
-      gtk_tree_view_set_model (GTK_TREE_VIEW (cd->stat_view) , GTK_TREE_MODEL (liststore));
-      cd->stat = GTK_TREE_MODEL (liststore);
-    }
-}
-static void
-on_cell_clicked (struct crosstabs_dialog *cd)
-{
-  GtkListStore *liststore;
-  int ret;
-
-  liststore = clone_list_store (GTK_LIST_STORE (cd->cell));
-
-  ret = psppire_dialog_run (PSPPIRE_DIALOG (cd->cell_dialog));
-
-  if ( ret == PSPPIRE_RESPONSE_CONTINUE )
-    {
-      g_object_unref (liststore);
-    }
-  else
-    {
-      g_object_unref (cd->cell);
-      gtk_tree_view_set_model (GTK_TREE_VIEW (cd->cell_view) , GTK_TREE_MODEL (liststore));
-      cd->cell = GTK_TREE_MODEL (liststore);
-    }
-}
-
-static char *
-generate_syntax (const struct crosstabs_dialog *cd)
-{
-  gint i;
-  int n;
-  guint selected;
-  GtkTreeIter iter;
-  gboolean ok;
-
-  gchar *text;
-  GString *string = g_string_new ("CROSSTABS");
-
-  g_string_append (string, "\n\t/TABLES=");
-  psppire_var_view_append_names (PSPPIRE_VAR_VIEW (cd->row_vars), 0, string);
-  g_string_append (string, "\tBY\t");
-  psppire_var_view_append_names (PSPPIRE_VAR_VIEW (cd->col_vars), 0, string);
-
-  g_string_append (string, "\n\t/FORMAT=");
-
-  if (cd->current_opts.avalue)
-    {
-      g_string_append (string, "AVALUE");
-    }
-  else 
-    {
-      g_string_append (string, "DVALUE");
-    }
-  g_string_append (string, " ");
-  if (cd->current_opts.table)
-    g_string_append (string, "TABLES");
-  else
-    g_string_append (string, "NOTABLES");
-  g_string_append (string, " ");
-
-  if (cd->current_opts.pivot)
-    g_string_append (string, "PIVOT");
-  else 
-    g_string_append (string, "NOPIVOT");
-
-  selected = 0;
-  for (i = 0, ok = gtk_tree_model_get_iter_first (cd->stat, &iter); ok; 
-       i++, ok = gtk_tree_model_iter_next (cd->stat, &iter))
-    {
-      gboolean toggled;
-      gtk_tree_model_get (cd->stat, &iter,
-                         CHECKBOX_COLUMN_SELECTED, &toggled, -1); 
-      if (toggled) 
-       selected |= 1u << i; 
-      else 
-       selected &= ~(1u << i);
-    }
-
-  if (!(selected & (1u << CS_STATS_NONE)))
-    {
-      if (selected)
-       {
-         g_string_append (string, "\n\t/STATISTICS=");
-         n = 0;
-         for (i = 0; i < N_CROSSTABS_STATS; i++)
-           if (selected & (1u << i))
-             {
-               if (n++)
-                 g_string_append (string, " ");
-               g_string_append (string, stats[i].name);
-             }
-       }
-    }
-
-  selected = 0;
-  for (i = 0, ok = gtk_tree_model_get_iter_first (cd->cell, &iter); ok; 
-       i++, ok = gtk_tree_model_iter_next (cd->cell, &iter))
-    {
-      gboolean toggled;
-      gtk_tree_model_get (cd->cell, &iter,
-                         CHECKBOX_COLUMN_SELECTED, &toggled, -1); 
-      if (toggled) 
-       selected |= 1u << i; 
-      else 
-       selected &= ~(1u << i);
-    }
-
-  g_string_append (string, "\n\t/CELLS=");
-  if (selected & (1u << CS_CELLS_NONE))
-    g_string_append (string, "NONE");
-  else
-    {
-      n = 0;
-      for (i = 0; i < N_CROSSTABS_CELLS; i++)
-       if (selected & (1u << i))
-         {
-           if (n++)
-             g_string_append (string, " ");
-           g_string_append (string, cells[i].name);
-         }
-    }
-  
-  g_string_append (string, ".\n");
-
-  text = string->str;
-
-  g_string_free (string, FALSE);
-
-  return text;
-}
-
-/* Dialog is valid iff at least one row and one column variable has
-   been selected. */
-static gboolean
-dialog_state_valid (gpointer data)
-{
-  struct crosstabs_dialog *cd = data;
-
-  GtkTreeModel *row_vars = gtk_tree_view_get_model (cd->row_vars);
-  GtkTreeModel *col_vars = gtk_tree_view_get_model (cd->col_vars);
-
-  GtkTreeIter notused;
-
-  return (gtk_tree_model_get_iter_first (row_vars, &notused) 
-    && gtk_tree_model_get_iter_first (col_vars, &notused));
-}
-
-/* Pops up the Crosstabs dialog box */
-void
-crosstabs_dialog (PsppireDataWindow *de)
-{
-  gint response;
-  struct crosstabs_dialog cd;
-
-  GtkBuilder *xml = builder_new ("crosstabs.ui");
-  PsppireDict *dict = NULL;
-
-
-  GtkWidget *dialog = get_widget_assert   (xml, "crosstabs-dialog");
-  GtkWidget *source = get_widget_assert   (xml, "dict-treeview");
-  GtkWidget *dest_rows =   get_widget_assert   (xml, "rows");
-  GtkWidget *dest_cols =   get_widget_assert   (xml, "cols");
-  GtkWidget *format_button = get_widget_assert (xml, "format-button");
-  GtkWidget *stat_button = get_widget_assert (xml, "stats-button");
-  GtkWidget *cell_button = get_widget_assert (xml, "cell-button");
-
-
-  cd.stat_view = get_widget_assert (xml, "stats-view");
-  cd.cell_view = get_widget_assert (xml, "cell-view");
-
-  put_checkbox_items_in_treeview (GTK_TREE_VIEW(cd.stat_view),
-                                 B_CS_STATS_DEFAULT,
-                                 N_CROSSTABS_STATS,
-                                 stats
-                                 );
-  put_checkbox_items_in_treeview (GTK_TREE_VIEW(cd.cell_view),
-                                 B_CS_CELL_DEFAULT,
-                                 N_CROSSTABS_CELLS,
-                                 cells
-                                 );
-
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
-
-  g_object_get (de->data_editor, "dictionary", &dict, NULL);
-  g_object_set (source, "model", dict, NULL);
-
-  cd.row_vars = GTK_TREE_VIEW (dest_rows);
-  cd.col_vars = GTK_TREE_VIEW (dest_cols);
-  g_object_get (de->data_editor, "dictionary", &cd.dict, NULL);
-  cd.format_dialog = get_widget_assert (xml, "format-dialog");
-  cd.table_button = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "print-tables"));
-  cd.pivot_button = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "pivot"));
-  cd.stat_dialog = get_widget_assert (xml, "stat-dialog");
-  cd.cell_dialog = get_widget_assert (xml, "cell-dialog");
-
-  cd.stat = gtk_tree_view_get_model (GTK_TREE_VIEW (cd.stat_view));
-  cd.cell = gtk_tree_view_get_model (GTK_TREE_VIEW (cd.cell_view));
-  cd.avalue = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "ascending"));
-  cd.current_opts.avalue = TRUE;
-  cd.current_opts.table = TRUE;
-  cd.current_opts.pivot = TRUE;
-
-  gtk_window_set_transient_for (GTK_WINDOW (cd.format_dialog), GTK_WINDOW (de));
-  gtk_window_set_transient_for (GTK_WINDOW (cd.cell_dialog), GTK_WINDOW (de));
-  gtk_window_set_transient_for (GTK_WINDOW (cd.stat_dialog), GTK_WINDOW (de));
-
-  g_signal_connect (dialog, "refresh", G_CALLBACK (refresh),  &cd);
-
-  psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog),
-                                     dialog_state_valid, &cd);
-
-  g_signal_connect_swapped (format_button, "clicked",
-                           G_CALLBACK (on_format_clicked),  &cd);
-  g_signal_connect_swapped (stat_button, "clicked",
-                           G_CALLBACK (on_statistics_clicked),  &cd);
-  g_signal_connect_swapped (cell_button, "clicked",
-                           G_CALLBACK (on_cell_clicked),  &cd);
-
-  response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
-
-
-  switch (response)
-    {
-    case GTK_RESPONSE_OK:
-      g_free (execute_syntax_string (de, generate_syntax (&cd)));
-      break;
-    case PSPPIRE_RESPONSE_PASTE:
-      g_free (paste_syntax_to_window (generate_syntax (&cd)));
-      break;
-    default:
-      break;
-    }
-
-  g_object_unref (xml);
-}
diff --git a/src/ui/gui/crosstabs-dialog.h b/src/ui/gui/crosstabs-dialog.h
deleted file mode 100644 (file)
index 65e4761..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2008, 2010  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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef __CROSSTABS_DIALOG_H
-#define __CROSSTABS_DIALOG_H
-
-#include "psppire-data-window.h"
-
-void crosstabs_dialog (PsppireDataWindow * data);
-
-#endif
index 491b94b1bc683dd533e7e84c1a66285799e6396b..0b1378e8422b557741bcaa9569ff0520b98112c4 100644 (file)
           </object>
         </child>
         <child>
-          <object class="GtkAction" id="analyze_frequencies">
-            <property name="name">analyze_frequencies</property>
+          <object class="PsppireDialogActionFrequencies" id="frequencies">
+            <property name="manager">uimanager1</property>
+            <property name="name">frequencies</property>
             <property name="label" translatable="yes">_Frequencies...</property>
           </object>
         </child>
           </object>
         </child>
         <child>
-          <object class="GtkAction" id="crosstabs">
+          <object class="PsppireDialogActionCrosstabs" id="crosstabs">
             <property name="name">crosstabs</property>
+            <property name="manager">uimanager1</property>
             <property name="label" translatable="yes">_Crosstabs...</property>
           </object>
         </child>
           </object>
         </child>
         <child>
-          <object class="GtkAction" id="binomial">
+          <object class="PsppireDialogActionBinomial" id="binomial">
             <property name="name">binomial</property>
+            <property name="manager">uimanager1</property>
             <property name="label" translatable="yes">_Binomial...</property>
           </object>
         </child>
         </menu>
         <menu action="analyze">
           <menu action="descriptive-statistics">
-            <menuitem action="analyze_frequencies"/>
+            <menuitem action="frequencies"/>
             <menuitem action="analyze_descriptives"/>
             <menuitem action="explore"/>
             <menuitem action="crosstabs"/>
index c61cb14a64a88ef4b3dba174f194277c5c552216..9e97923e3f977188d305e791d3f3ad9c1ad887cc 100644 (file)
@@ -165,3 +165,30 @@ numeric_only (GtkWidget *source, GtkWidget *dest)
   return retval;
 }
 
+/*
+  A pair of functions intended to be used as callbacks for the "toggled" signal
+  of a GtkToggleButton widget.  They make the sensitivity of W follow the status
+  of the togglebutton.
+*/
+void
+set_sensitivity_from_toggle (GtkToggleButton *togglebutton,  GtkWidget *w)
+{
+  gboolean active = gtk_toggle_button_get_active (togglebutton);
+
+  gtk_widget_set_sensitive (w, active);
+  if (active)
+    gtk_widget_grab_focus (w);
+}
+
+/* */
+void
+set_sensitivity_from_toggle_invert (GtkToggleButton *togglebutton,
+                                   GtkWidget *w)
+{
+  gboolean active = gtk_toggle_button_get_active (togglebutton);
+
+  gtk_widget_set_sensitive (w, !active);
+}
+
+
+
index 328904acfc9643fbf669cf6cd0f2f3451166d9c1..d32082477d80dee20ce4f857c2b767e5f2879e00 100644 (file)
@@ -54,5 +54,13 @@ gboolean homogeneous_types (GtkWidget *source, GtkWidget *dest);
 */
 gboolean numeric_only (GtkWidget *source, GtkWidget *dest);
 
+/*
+  A pair of functions intended to be used as callbacks for the "toggled" signal
+  of a GtkToggleButton widget.  They make the sensitivity of W follow the status
+  of the togglebutton.
+*/
+void set_sensitivity_from_toggle (GtkToggleButton *togglebutton,  GtkWidget *w);
+void set_sensitivity_from_toggle_invert (GtkToggleButton *togglebutton,  GtkWidget *w);
+
 
 #endif
diff --git a/src/ui/gui/frequencies-dialog.c b/src/ui/gui/frequencies-dialog.c
deleted file mode 100644 (file)
index 32871e0..0000000
+++ /dev/null
@@ -1,578 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007, 2010, 2011, 2012  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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-
-#include "checkbox-treeview.h"
-#include "frequencies-dialog.h"
-#include "psppire-var-view.h"
-
-#include <gtk/gtk.h>
-#include <stdlib.h>
-
-#include <ui/gui/psppire-data-window.h>
-#include <ui/gui/dialog-common.h>
-#include <ui/gui/dict-display.h>
-#include <ui/gui/builder-wrapper.h>
-#include <ui/gui/psppire-dialog.h>
-#include "executor.h"
-#include "helper.h"
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-
-#define FREQUENCY_STATS                       \
-  FS (MEAN, N_("Mean"))                         \
-  FS (STDDEV, N_("Standard deviation"))         \
-  FS (MINIMUM, N_("Minimum"))                   \
-  FS (MAXIMUM, N_("Maximum"))                   \
-  FS (SEMEAN, N_("Standard error of the mean")) \
-  FS (VARIANCE, N_("Variance"))                 \
-  FS (SKEWNESS, N_("Skewness"))                 \
-  FS (SESKEW, N_("Standard error of the skewness"))  \
-  FS (RANGE, N_("Range"))                       \
-  FS (MODE, N_("Mode"))                         \
-  FS (KURTOSIS, N_("Kurtosis"))                 \
-  FS (SEKURT, N_("Standard error of the kurtosis"))  \
-  FS (MEDIAN, N_("Median"))      \
-  FS (SUM, N_("Sum"))
-
-enum
-  {
-#define FS(NAME, LABEL) FS_##NAME,
-    FREQUENCY_STATS
-#undef FS
-    N_FREQUENCY_STATS
-  };
-
-enum
-  {
-#define FS(NAME, LABEL) B_FS_##NAME = 1u << FS_##NAME,
-    FREQUENCY_STATS
-#undef FS
-    B_FS_ALL = (1u << N_FREQUENCY_STATS) - 1,
-    B_FS_DEFAULT = B_FS_MEAN | B_FS_STDDEV | B_FS_MINIMUM | B_FS_MAXIMUM
-  };
-
-
-static const struct checkbox_entry_item stats[] =
-  {
-#define FS(NAME, LABEL) {#NAME, LABEL},
-    FREQUENCY_STATS
-#undef FS
-  };
-
-
-
-enum frq_order
-  {
-    FRQ_AVALUE,
-    FRQ_DVALUE,
-    FRQ_ACOUNT,
-    FRQ_DCOUNT
-  };
-
-enum frq_table
-  {
-    FRQ_TABLE,
-    FRQ_NOTABLE,
-    FRQ_LIMIT
-  };
-
-struct tables_options
-{
-  enum frq_order order;
-  enum frq_table table;
-  int limit;
-};
-
-enum frq_scale
-  {
-    FRQ_FREQ,
-    FRQ_PERCENT
-  };
-
-struct charts_options
-  {
-    bool use_min;
-    double min;
-    bool use_max;
-    double max;
-    bool draw_hist;
-    bool draw_normal;
-    enum frq_scale scale;
-    bool draw_pie;
-    bool pie_include_missing;
-  };
-
-struct frequencies_dialog
-{
-  /* Main dialog. */
-  GtkTreeView *stat_vars;
-  PsppireDict *dict;
-
-  GtkWidget *tables_button;
-  GtkWidget *charts_button;
-
-  GtkToggleButton *include_missing;
-
-  GtkTreeModel *stats;
-
-  /* Frequency Tables dialog. */
-  GtkWidget *tables_dialog;
-  struct tables_options tables_opts;
-
-  GtkToggleButton *always;
-  GtkToggleButton *never;
-  GtkToggleButton *limit;
-  GtkSpinButton *limit_spinbutton;
-
-  GtkToggleButton  *avalue;
-  GtkToggleButton  *dvalue;
-  GtkToggleButton  *afreq;
-  GtkToggleButton  *dfreq;
-
-  /* Charts dialog. */
-  GtkWidget *charts_dialog;
-  struct charts_options charts_opts;
-
-  GtkToggleButton *freqs;
-  GtkToggleButton *percents;
-
-  GtkToggleButton *min;
-  GtkSpinButton *min_spin;
-  GtkToggleButton *max;
-  GtkSpinButton *max_spin;
-
-  GtkToggleButton *hist;
-  GtkToggleButton *normal;
-
-  GtkToggleButton *pie;
-  GtkToggleButton *pie_include_missing;
-};
-
-static void
-refresh (PsppireDialog *dialog, struct frequencies_dialog *fd)
-{
-  GtkTreeIter iter;
-  size_t i;
-  bool ok;
-
-  GtkTreeModel *liststore = gtk_tree_view_get_model (fd->stat_vars);
-  gtk_list_store_clear (GTK_LIST_STORE (liststore));
-
-  for (i = 0, ok = gtk_tree_model_get_iter_first (fd->stats, &iter); ok;
-       i++, ok = gtk_tree_model_iter_next (fd->stats, &iter))
-    gtk_list_store_set (GTK_LIST_STORE (fd->stats), &iter,
-                       CHECKBOX_COLUMN_SELECTED,
-                        (B_FS_DEFAULT & (1u << i)) ? true : false, -1);
-}
-
-static char *
-generate_syntax (const struct frequencies_dialog *fd)
-{
-  GtkTreeIter iter;
-  gboolean ok;
-  gint i;
-  guint selected = 0;
-
-  gchar *text;
-  GString *string = g_string_new ("FREQUENCIES");
-
-  g_string_append (string, "\n\t/VARIABLES=");
-  psppire_var_view_append_names (PSPPIRE_VAR_VIEW (fd->stat_vars), 0, string);
-
-  g_string_append (string, "\n\t/FORMAT=");
-
-  switch (fd->tables_opts.order)
-    {
-    case FRQ_AVALUE:
-      g_string_append (string, "AVALUE");
-      break;
-    case FRQ_DVALUE:
-      g_string_append (string, "DVALUE");
-      break;
-    case FRQ_ACOUNT:
-      g_string_append (string, "AFREQ");
-      break;
-    case FRQ_DCOUNT:
-      g_string_append (string, "DFREQ");
-      break;
-    default:
-      g_assert_not_reached();
-    }
-
-  g_string_append (string, " ");
-
-  switch (fd->tables_opts.table)
-    {
-    case FRQ_TABLE:
-      g_string_append (string, "TABLE");
-      break;
-    case FRQ_NOTABLE:
-      g_string_append (string, "NOTABLE");
-      break;
-    case FRQ_LIMIT:
-      g_string_append_printf (string, "LIMIT (%d)", fd->tables_opts.limit);
-      break;
-    }
-
-
-  for (i = 0, ok = gtk_tree_model_get_iter_first (fd->stats, &iter); ok;
-       i++, ok = gtk_tree_model_iter_next (fd->stats, &iter))
-    {
-      gboolean toggled;
-      gtk_tree_model_get (fd->stats, &iter,
-                         CHECKBOX_COLUMN_SELECTED, &toggled, -1);
-      if (toggled)
-        selected |= 1u << i;
-    }
-
-  if (selected != B_FS_DEFAULT)
-    {
-      g_string_append (string, "\n\t/STATISTICS=");
-      if (selected == B_FS_ALL)
-        g_string_append (string, "ALL");
-      else if (selected == 0)
-        g_string_append (string, "NONE");
-      else
-        {
-          int n = 0;
-          if ((selected & B_FS_DEFAULT) == B_FS_DEFAULT)
-            {
-              g_string_append (string, "DEFAULT");
-              selected &= ~B_FS_DEFAULT;
-              n++;
-            }
-          for (i = 0; i < N_FREQUENCY_STATS; i++)
-            if (selected & (1u << i))
-              {
-                if (n++)
-                  g_string_append (string, " ");
-                g_string_append (string, stats[i].name);
-              }
-        }
-    }
-
-  if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->include_missing)))
-    g_string_append (string, "\n\t/MISSING=INCLUDE");
-
-  if (fd->charts_opts.draw_hist)
-    {
-      g_string_append (string, "\n\t/HISTOGRAM=");
-      g_string_append (string,
-                       fd->charts_opts.draw_normal ? "NORMAL" : "NONORMAL");
-
-      if (fd->charts_opts.scale == FRQ_PERCENT)
-        g_string_append (string, " PERCENT");
-
-      if (fd->charts_opts.use_min)
-        g_string_append_printf (string, " MIN(%.15g)", fd->charts_opts.min);
-      if (fd->charts_opts.use_max)
-        g_string_append_printf (string, " MAX(%.15g)", fd->charts_opts.max);
-    }
-
-  if (fd->charts_opts.draw_pie)
-    {
-      g_string_append (string, "\n\t/PIECHART=");
-
-      if (fd->charts_opts.pie_include_missing)
-        g_string_append (string, " MISSING");
-
-      if (fd->charts_opts.use_min)
-        g_string_append_printf (string, " MIN(%.15g)", fd->charts_opts.min);
-      if (fd->charts_opts.use_max)
-        g_string_append_printf (string, " MAX(%.15g)", fd->charts_opts.max);
-    }
-
-  g_string_append (string, ".\n");
-
-  text = string->str;
-
-  g_string_free (string, FALSE);
-
-  return text;
-}
-
-/* Dialog is valid iff at least one variable has been selected */
-static gboolean
-dialog_state_valid (gpointer data)
-{
-  struct frequencies_dialog *fd = data;
-
-  GtkTreeModel *vars = gtk_tree_view_get_model (fd->stat_vars);
-
-  GtkTreeIter notused;
-
-  return gtk_tree_model_get_iter_first (vars, &notused);
-}
-
-
-static void
-on_tables_clicked (struct frequencies_dialog *fd)
-{
-  int ret;
-
-  switch (fd->tables_opts.order)
-    {
-    case FRQ_AVALUE:
-      gtk_toggle_button_set_active (fd->avalue, TRUE);
-      break;
-    case FRQ_DVALUE:
-      gtk_toggle_button_set_active (fd->dvalue, TRUE);
-      break;
-    case FRQ_ACOUNT:
-      gtk_toggle_button_set_active (fd->afreq, TRUE);
-      break;
-    case FRQ_DCOUNT:
-      gtk_toggle_button_set_active (fd->dfreq, TRUE);
-      break;
-    };
-
-  switch (fd->tables_opts.table)
-    {
-    case FRQ_TABLE:
-      gtk_toggle_button_set_active (fd->always, TRUE);
-      break;
-    case FRQ_NOTABLE:
-      gtk_toggle_button_set_active (fd->never, TRUE);
-      break;
-    case FRQ_LIMIT:
-      gtk_toggle_button_set_active (fd->limit, TRUE);
-      break;
-    }
-  gtk_spin_button_set_value (fd->limit_spinbutton,
-                            fd->tables_opts.limit);
-  g_signal_emit_by_name (fd->limit, "toggled");
-
-  ret = psppire_dialog_run (PSPPIRE_DIALOG (fd->tables_dialog));
-
-  if ( ret == PSPPIRE_RESPONSE_CONTINUE )
-    {
-      if (gtk_toggle_button_get_active (fd->avalue))
-       fd->tables_opts.order = FRQ_AVALUE;
-      else if (gtk_toggle_button_get_active (fd->dvalue))
-       fd->tables_opts.order = FRQ_DVALUE;
-      else if (gtk_toggle_button_get_active (fd->afreq))
-       fd->tables_opts.order = FRQ_ACOUNT;
-      else if (gtk_toggle_button_get_active (fd->dfreq))
-       fd->tables_opts.order = FRQ_DCOUNT;
-
-      if (gtk_toggle_button_get_active (fd->always))
-        fd->tables_opts.table = FRQ_TABLE;
-      else if (gtk_toggle_button_get_active (fd->never))
-        fd->tables_opts.table = FRQ_NOTABLE;
-      else
-        fd->tables_opts.table = FRQ_LIMIT;
-
-      fd->tables_opts.limit = gtk_spin_button_get_value (fd->limit_spinbutton);
-    }
-}
-
-static void
-on_charts_clicked (struct frequencies_dialog *fd)
-{
-  int ret;
-
-  gtk_toggle_button_set_active (fd->min, fd->charts_opts.use_min);
-  gtk_spin_button_set_value (fd->min_spin, fd->charts_opts.min);
-  g_signal_emit_by_name (fd->min, "toggled");
-
-  gtk_toggle_button_set_active (fd->max, fd->charts_opts.use_max);
-  gtk_spin_button_set_value (fd->max_spin, fd->charts_opts.max);
-  g_signal_emit_by_name (fd->max, "toggled");
-
-  gtk_toggle_button_set_active (fd->hist, fd->charts_opts.draw_hist);
-  gtk_toggle_button_set_active (fd->normal, fd->charts_opts.draw_normal);
-  g_signal_emit_by_name (fd->hist, "toggled");
-
-  switch (fd->charts_opts.scale)
-    {
-    case FRQ_FREQ:
-      gtk_toggle_button_set_active (fd->freqs, TRUE);
-      break;
-    case FRQ_DVALUE:
-      gtk_toggle_button_set_active (fd->percents, TRUE);
-      break;
-    };
-
-
-  gtk_toggle_button_set_active (fd->pie, fd->charts_opts.draw_pie);
-  gtk_toggle_button_set_active (fd->pie_include_missing,
-                                fd->charts_opts.pie_include_missing);
-  g_signal_emit_by_name (fd->pie, "toggled");
-
-  ret = psppire_dialog_run (PSPPIRE_DIALOG (fd->charts_dialog));
-
-  if ( ret == PSPPIRE_RESPONSE_CONTINUE )
-    {
-      fd->charts_opts.use_min = gtk_toggle_button_get_active (fd->min);
-      fd->charts_opts.min = gtk_spin_button_get_value (fd->min_spin);
-
-      fd->charts_opts.use_max = gtk_toggle_button_get_active (fd->max);
-      fd->charts_opts.max = gtk_spin_button_get_value (fd->max_spin);
-
-      fd->charts_opts.draw_hist = gtk_toggle_button_get_active (fd->hist);
-      fd->charts_opts.draw_normal = gtk_toggle_button_get_active (fd->normal);
-      if (gtk_toggle_button_get_active (fd->freqs))
-       fd->charts_opts.scale = FRQ_FREQ;
-      else if (gtk_toggle_button_get_active (fd->percents))
-       fd->charts_opts.scale = FRQ_PERCENT;
-
-      fd->charts_opts.draw_pie = gtk_toggle_button_get_active (fd->pie);
-      fd->charts_opts.pie_include_missing
-        = gtk_toggle_button_get_active (fd->pie_include_missing);
-    }
-}
-
-
-/* Makes widget W's sensitivity follow the active state of TOGGLE */
-static void
-sensitive_if_active (GtkToggleButton *toggle, GtkWidget *w)
-{
-  gboolean active = gtk_toggle_button_get_active (toggle);
-
-  gtk_widget_set_sensitive (w, active);
-}
-
-/* Pops up the Frequencies dialog box */
-void
-frequencies_dialog (PsppireDataWindow *de)
-{
-  gint response;
-
-  struct frequencies_dialog fd;
-
-  GtkBuilder *xml = builder_new ("frequencies.ui");
-
-  GtkWidget *dialog = get_widget_assert   (xml, "frequencies-dialog");
-  GtkWidget *source = get_widget_assert   (xml, "dict-treeview");
-  GtkWidget *dest =   get_widget_assert   (xml, "var-treeview");
-  GtkWidget *tables_button = get_widget_assert (xml, "tables-button");
-  GtkWidget *charts_button = get_widget_assert (xml, "charts-button");
-  GtkWidget *stats_treeview = get_widget_assert (xml, "stats-treeview");
-
-  put_checkbox_items_in_treeview (GTK_TREE_VIEW(stats_treeview),
-                                 B_FS_DEFAULT,
-                                 N_FREQUENCY_STATS,
-                                 stats
-                                 );
-
-
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
-
-  g_object_get (de->data_editor, "dictionary", &fd.dict, NULL);
-  g_object_set (source, "model", fd.dict, NULL);
-
-  fd.stat_vars = GTK_TREE_VIEW (dest);
-  fd.tables_button = get_widget_assert (xml, "tables-button");
-  fd.charts_button = get_widget_assert (xml, "charts-button");
-
-  fd.include_missing = GTK_TOGGLE_BUTTON (
-    get_widget_assert (xml, "include_missing"));
-
-  fd.stats = gtk_tree_view_get_model (GTK_TREE_VIEW (stats_treeview));
-
-  /* Frequency Tables dialog. */
-  fd.tables_dialog = get_widget_assert (xml, "tables-dialog");
-  fd.tables_opts.order = FRQ_AVALUE;
-  fd.tables_opts.table = FRQ_TABLE;
-  fd.tables_opts.limit = 50;
-
-  fd.always = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "always"));
-  fd.never = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "never"));
-  fd.limit  = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "limit"));
-  fd.limit_spinbutton =
-    GTK_SPIN_BUTTON (get_widget_assert (xml, "limit-spin"));
-  g_signal_connect (fd.limit, "toggled",
-                   G_CALLBACK (sensitive_if_active), fd.limit_spinbutton);
-
-  fd.avalue = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "avalue"));
-  fd.dvalue = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "dvalue"));
-  fd.afreq  = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "afreq"));
-  fd.dfreq  = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "dfreq"));
-
-  gtk_window_set_transient_for (GTK_WINDOW (fd.tables_dialog),
-                                GTK_WINDOW (de));
-
-  /* Charts dialog. */
-  fd.charts_dialog = get_widget_assert (xml, "charts-dialog");
-  fd.charts_opts.use_min = false;
-  fd.charts_opts.min = 0;
-  fd.charts_opts.use_max = false;
-  fd.charts_opts.max = 100;
-  fd.charts_opts.draw_hist = false;
-  fd.charts_opts.draw_normal = false;
-  fd.charts_opts.scale = FRQ_FREQ;
-  fd.charts_opts.draw_pie = false;
-  fd.charts_opts.pie_include_missing = false;
-
-  fd.freqs = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "freqs"));
-  fd.percents = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "percents"));
-
-  fd.min = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "min"));
-  fd.min_spin = GTK_SPIN_BUTTON (get_widget_assert (xml, "min-spin"));
-  g_signal_connect (fd.min, "toggled",
-                   G_CALLBACK (sensitive_if_active), fd.min_spin);
-  fd.max = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "max"));
-  fd.max_spin = GTK_SPIN_BUTTON (get_widget_assert (xml, "max-spin"));
-  g_signal_connect (fd.max, "toggled",
-                   G_CALLBACK (sensitive_if_active), fd.max_spin);
-
-  fd.hist = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "hist"));
-  fd.normal = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "normal"));
-  g_signal_connect (fd.hist, "toggled",
-                   G_CALLBACK (sensitive_if_active), fd.normal);
-
-  fd.pie = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "pie"));
-  fd.pie_include_missing = GTK_TOGGLE_BUTTON (
-    get_widget_assert (xml, "pie-include-missing"));
-  g_signal_connect (fd.pie, "toggled",
-                   G_CALLBACK (sensitive_if_active), fd.pie_include_missing);
-
-  gtk_window_set_transient_for (GTK_WINDOW (fd.charts_dialog),
-                                GTK_WINDOW (de));
-
-  /* Main dialog. */
-  g_signal_connect (dialog, "refresh", G_CALLBACK (refresh),  &fd);
-
-  psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog),
-                                     dialog_state_valid, &fd);
-
-  g_signal_connect_swapped (tables_button, "clicked",
-                           G_CALLBACK (on_tables_clicked),  &fd);
-  g_signal_connect_swapped (charts_button, "clicked",
-                           G_CALLBACK (on_charts_clicked),  &fd);
-
-  response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
-
-
-  switch (response)
-    {
-    case GTK_RESPONSE_OK:
-      g_free (execute_syntax_string (de, generate_syntax (&fd)));
-      break;
-    case PSPPIRE_RESPONSE_PASTE:
-      g_free (paste_syntax_to_window (generate_syntax (&fd)));
-      break;
-    default:
-      break;
-    }
-
-  g_object_unref (xml);
-}
diff --git a/src/ui/gui/frequencies-dialog.h b/src/ui/gui/frequencies-dialog.h
deleted file mode 100644 (file)
index 5632ab5..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007, 2010  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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef __FREQUENCIES_DIALOG_H
-#define __FREQUENCIES_DIALOG_H
-
-#include "psppire-data-window.h"
-
-void frequencies_dialog (PsppireDataWindow * data);
-
-#endif
index ad967b3256c7578860236c8eed1e79cf9d2bbf1f..73c98b383efcd6624809471dffbdf12badcfc25d 100644 (file)
 #include "libpspp/str.h"
 #include "ui/gui/aggregate-dialog.h"
 #include "ui/gui/autorecode-dialog.h"
-#include "ui/gui/binomial-dialog.h"
 #include "ui/gui/builder-wrapper.h"
 #include "ui/gui/chi-square-dialog.h"
 #include "ui/gui/comments-dialog.h"
 #include "ui/gui/compute-dialog.h"
 #include "ui/gui/count-dialog.h"
-#include "ui/gui/crosstabs-dialog.h"
 #include "ui/gui/entry-dialog.h"
 #include "ui/gui/executor.h"
-#include "ui/gui/frequencies-dialog.h"
 #include "ui/gui/help-menu.h"
 #include "ui/gui/helper.h"
 #include "ui/gui/helper.h"
@@ -829,12 +826,24 @@ connect_action (PsppireDataWindow *dw, const char *action_name,
                                    GCallback handler)
 {
   GtkAction *action = get_action_assert (dw->builder, action_name);
+
   g_signal_connect_swapped (action, "activate", handler, dw);
 
   return action;
 }
 
+/* Only a data file with at least one variable can be saved. */
+static void
+enable_save (PsppireDataWindow *dw)
+{
+  gboolean enable = psppire_dict_get_var_cnt (dw->dict) > 0;
+
+  gtk_action_set_sensitive (get_action_assert (dw->builder, "file_save"),
+                            enable);
+  gtk_action_set_sensitive (get_action_assert (dw->builder, "file_save_as"),
+                            enable);
+}
+
 /* Initializes as much of a PsppireDataWindow as we can and must before the
    dataset has been set.
 
@@ -921,6 +930,13 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
                    G_CALLBACK (on_split_change),
                    de);
 
+  g_signal_connect_swapped (de->dict, "backend-changed",
+                            G_CALLBACK (enable_save), de);
+  g_signal_connect_swapped (de->dict, "variable-inserted",
+                            G_CALLBACK (enable_save), de);
+  g_signal_connect_swapped (de->dict, "variable-deleted",
+                            G_CALLBACK (enable_save), de);
+  enable_save (de);
 
   connect_action (de, "file_new_data", G_CALLBACK (create_data_window));
 
@@ -954,11 +970,8 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
   connect_action (de, "transform_count", G_CALLBACK (count_dialog));
   connect_action (de, "transform_recode-same", G_CALLBACK (recode_same_dialog));
   connect_action (de, "transform_recode-different", G_CALLBACK (recode_different_dialog));
-  connect_action (de, "analyze_frequencies", G_CALLBACK (frequencies_dialog));
-  connect_action (de, "crosstabs", G_CALLBACK (crosstabs_dialog));
   connect_action (de, "univariate", G_CALLBACK (univariate_dialog));
   connect_action (de, "chi-square", G_CALLBACK (chisquare_dialog));
-  connect_action (de, "binomial", G_CALLBACK (binomial_dialog));
   connect_action (de, "runs", G_CALLBACK (runs_dialog));
   connect_action (de, "ks-one-sample", G_CALLBACK (ks_one_sample_dialog));
   connect_action (de, "k-related-samples", G_CALLBACK (k_related_dialog));
diff --git a/src/ui/gui/psppire-dialog-action-binomial.c b/src/ui/gui/psppire-dialog-action-binomial.c
new file mode 100644 (file)
index 0000000..97a5f3c
--- /dev/null
@@ -0,0 +1,179 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2012  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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <config.h>
+
+#include "psppire-dialog-action-binomial.h"
+#include "psppire-value-entry.h"
+
+#include "dialog-common.h"
+#include "helper.h"
+#include <ui/syntax-gen.h>
+#include "psppire-var-view.h"
+
+#include "psppire-dialog.h"
+#include "builder-wrapper.h"
+#include "checkbox-treeview.h"
+#include "psppire-dict.h"
+#include "libpspp/str.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+
+static void
+psppire_dialog_action_binomial_class_init (PsppireDialogActionBinomialClass *class);
+
+G_DEFINE_TYPE (PsppireDialogActionBinomial, psppire_dialog_action_binomial, PSPPIRE_TYPE_DIALOG_ACTION);
+
+
+static gboolean
+get_proportion (PsppireDialogActionBinomial *act, double *prop)
+{
+    const gchar *text = gtk_entry_get_text (GTK_ENTRY (act->prop_entry));
+    gchar *endptr = NULL;
+     *prop = g_strtod (text, &endptr);
+
+    if (endptr == text)
+      return FALSE;
+
+    return TRUE; 
+}
+
+static gboolean
+dialog_state_valid (gpointer data)
+{
+  PsppireDialogActionBinomial *act = PSPPIRE_DIALOG_ACTION_BINOMIAL (data);
+  double prop;
+
+  GtkTreeModel *vars =
+    gtk_tree_view_get_model (GTK_TREE_VIEW (act->var_view));
+
+  GtkTreeIter notused;
+
+  if ( !gtk_tree_model_get_iter_first (vars, &notused) )
+    return FALSE;
+
+  if ( ! get_proportion (act, &prop))
+    return FALSE;
+
+  if (prop < 0 || prop > 1.0)
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+refresh (PsppireDialogAction *da)
+{
+  PsppireDialogActionBinomial *act = PSPPIRE_DIALOG_ACTION_BINOMIAL (da);
+  GtkTreeModel *liststore =
+    gtk_tree_view_get_model (GTK_TREE_VIEW (act->var_view));
+
+  gtk_list_store_clear (GTK_LIST_STORE (liststore));
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (act->button1), TRUE);
+
+  gtk_entry_set_text (GTK_ENTRY (act->prop_entry), "0.5");
+
+  gtk_entry_set_text (GTK_ENTRY (act->cutpoint_entry), "");
+}
+
+
+static void
+psppire_dialog_action_binomial_activate (GtkAction *a)
+{
+  PsppireDialogActionBinomial *act = PSPPIRE_DIALOG_ACTION_BINOMIAL (a);
+  PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (a);
+
+  GtkBuilder *xml = builder_new ("binomial.ui");
+
+  pda->dialog = get_widget_assert   (xml, "binomial-dialog");
+  pda->source = get_widget_assert   (xml, "dict-view");
+
+  act->var_view   = get_widget_assert (xml, "variables-treeview");
+  act->button1   = get_widget_assert (xml, "radiobutton3");
+  act->prop_entry = get_widget_assert (xml, "proportion-entry");
+
+  act->cutpoint_entry =     get_widget_assert   (xml, "cutpoint-entry");
+  act->cutpoint_button =    get_widget_assert   (xml, "radiobutton4");
+
+  g_object_unref (xml);
+
+
+  g_signal_connect (act->cutpoint_button, "toggled", G_CALLBACK (set_sensitivity_from_toggle),
+                   act->cutpoint_entry);
+
+  psppire_dialog_action_set_refresh (pda, refresh);
+
+  psppire_dialog_action_set_valid_predicate (pda,
+                                       dialog_state_valid);
+
+  if (PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_binomial_parent_class)->activate)
+    PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_binomial_parent_class)->activate (pda);
+}
+
+
+
+static char *
+generate_syntax (PsppireDialogAction *a)
+{
+  PsppireDialogActionBinomial *scd = PSPPIRE_DIALOG_ACTION_BINOMIAL (a);
+  gchar *text = NULL;
+
+  double prop;
+  GString *string = g_string_new ("NPAR TEST\n\t/BINOMIAL");
+
+  if ( get_proportion (scd, &prop))
+    g_string_append_printf (string, "(%g)", prop);
+
+  g_string_append (string, " =");
+
+  psppire_var_view_append_names (PSPPIRE_VAR_VIEW (scd->var_view), 0, string);
+
+  if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scd->cutpoint_button)))
+    {
+      const gchar *cutpoint = gtk_entry_get_text (GTK_ENTRY (scd->cutpoint_entry));
+      g_string_append_printf (string, "(%s)", cutpoint);
+    }
+
+  g_string_append (string, ".\n");
+
+  text = string->str;
+
+  g_string_free (string, FALSE);
+
+  return text;
+}
+
+static void
+psppire_dialog_action_binomial_class_init (PsppireDialogActionBinomialClass *class)
+{
+  GtkActionClass *action_class = GTK_ACTION_CLASS (class);
+
+  action_class->activate = psppire_dialog_action_binomial_activate;
+
+  PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
+}
+
+
+static void
+psppire_dialog_action_binomial_init (PsppireDialogActionBinomial *act)
+{
+}
+
diff --git a/src/ui/gui/psppire-dialog-action-binomial.h b/src/ui/gui/psppire-dialog-action-binomial.h
new file mode 100644 (file)
index 0000000..0541a40
--- /dev/null
@@ -0,0 +1,83 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2012  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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include "psppire-dialog-action.h"
+
+#ifndef __PSPPIRE_DIALOG_ACTION_BINOMIAL_H__
+#define __PSPPIRE_DIALOG_ACTION_BINOMIAL_H__
+
+G_BEGIN_DECLS
+
+
+#define PSPPIRE_TYPE_DIALOG_ACTION_BINOMIAL (psppire_dialog_action_binomial_get_type ())
+
+#define PSPPIRE_DIALOG_ACTION_BINOMIAL(obj)    \
+                     (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+                                                 PSPPIRE_TYPE_DIALOG_ACTION_BINOMIAL, PsppireDialogActionBinomial))
+
+#define PSPPIRE_DIALOG_ACTION_BINOMIAL_CLASS(klass) \
+                     (G_TYPE_CHECK_CLASS_CAST ((klass), \
+                                PSPPIRE_TYPE_DIALOG_ACTION_BINOMIAL, \
+                                 PsppireDialogActionBinomialClass))
+
+
+#define PSPPIRE_IS_DIALOG_ACTION_BINOMIAL(obj) \
+                    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_DIALOG_ACTION_BINOMIAL))
+
+#define PSPPIRE_IS_DIALOG_ACTION_BINOMIAL_CLASS(klass) \
+                     (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_TYPE_DIALOG_ACTION_BINOMIAL))
+
+
+#define PSPPIRE_DIALOG_ACTION_BINOMIAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+                                  PSPPIRE_TYPE_DIALOG_ACTION_BINOMIAL, \
+                                  PsppireDialogActionBinomialClass))
+
+typedef struct _PsppireDialogActionBinomial       PsppireDialogActionBinomial;
+typedef struct _PsppireDialogActionBinomialClass  PsppireDialogActionBinomialClass;
+
+
+struct _PsppireDialogActionBinomial
+{
+  PsppireDialogAction parent;
+
+  /*< private >*/
+  gboolean dispose_has_run ;
+
+
+  GtkWidget *var_view;
+  GtkWidget *button1;
+  GtkWidget *prop_entry;
+
+  GtkWidget *cutpoint_entry;
+  GtkWidget *cutpoint_button;
+};
+
+
+struct _PsppireDialogActionBinomialClass
+{
+  PsppireDialogActionClass parent_class;
+};
+
+
+GType psppire_dialog_action_binomial_get_type (void) ;
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_DIALOG_ACTION_BINOMIAL_H__ */
diff --git a/src/ui/gui/psppire-dialog-action-crosstabs.c b/src/ui/gui/psppire-dialog-action-crosstabs.c
new file mode 100644 (file)
index 0000000..2bc07c6
--- /dev/null
@@ -0,0 +1,395 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2012  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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <config.h>
+
+#include "psppire-dialog-action-crosstabs.h"
+#include "psppire-value-entry.h"
+
+#include "dialog-common.h"
+#include "helper.h"
+#include <ui/syntax-gen.h>
+#include "psppire-var-view.h"
+
+#include "psppire-dialog.h"
+#include "builder-wrapper.h"
+#include "checkbox-treeview.h"
+#include "psppire-dict.h"
+#include "libpspp/str.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+
+static void
+psppire_dialog_action_crosstabs_class_init (PsppireDialogActionCrosstabsClass *class);
+
+G_DEFINE_TYPE (PsppireDialogActionCrosstabs, psppire_dialog_action_crosstabs, PSPPIRE_TYPE_DIALOG_ACTION);
+
+static gboolean
+dialog_state_valid (gpointer data)
+{
+  PsppireDialogActionCrosstabs *cd = PSPPIRE_DIALOG_ACTION_CROSSTABS (data);
+
+  GtkTreeModel *row_vars = gtk_tree_view_get_model (GTK_TREE_VIEW (cd->dest_rows));
+  GtkTreeModel *col_vars = gtk_tree_view_get_model (GTK_TREE_VIEW (cd->dest_cols));
+
+  GtkTreeIter notused;
+
+  return (gtk_tree_model_get_iter_first (row_vars, &notused) 
+    && gtk_tree_model_get_iter_first (col_vars, &notused));
+}
+
+static void
+refresh (PsppireDialogAction *rd_)
+{
+  PsppireDialogActionCrosstabs *cd = PSPPIRE_DIALOG_ACTION_CROSSTABS (rd_);
+
+  GtkTreeModel *liststore = gtk_tree_view_get_model (GTK_TREE_VIEW (cd->dest_rows));
+  gtk_list_store_clear (GTK_LIST_STORE (liststore));
+  
+  liststore = gtk_tree_view_get_model (GTK_TREE_VIEW (cd->dest_cols));
+  gtk_list_store_clear (GTK_LIST_STORE (liststore));
+}
+
+#define CROSSTABS_STATS                         \
+  CS (CHISQ, N_("Chisq"))                       \
+  CS (PHI, N_("Phi"))                           \
+  CS (CC, N_("CC"))                             \
+  CS (LAMBDA, N_("Lambda"))                     \
+  CS (UC, N_("UC"))                             \
+  CS (BTAU, N_("BTau"))                         \
+  CS (CTAU, N_("CTau"))                         \
+  CS (RISK, N_("Risk"))                         \
+  CS (GAMMA, N_("Gamma"))                       \
+  CS (D, N_("D"))                               \
+  CS (KAPPA, N_("Kappa"))                       \
+  CS (ETA, N_("Eta"))                           \
+  CS (CORR, N_("Corr"))                         \
+  CS (STATS_NONE, N_("None"))
+
+
+#define CROSSTABS_CELLS                         \
+  CS (COUNT, N_("Count"))                       \
+  CS (ROW, N_("Row"))                           \
+  CS (COLUMN, N_("Column"))                     \
+  CS (TOTAL, N_("Total"))                       \
+  CS (EXPECTED, N_("Expected"))                 \
+  CS (RESIDUAL, N_("Residual"))                 \
+  CS (SRESIDUAL, N_("Std. Residual"))           \
+  CS (ASRESIDUAL, N_("Adjusted Std. Residual")) \
+  CS (CELLS_NONE, N_("None"))
+
+enum
+  {
+#define CS(NAME, LABEL) CS_##NAME,
+    CROSSTABS_STATS
+#undef CS
+    N_CROSSTABS_STATS
+  };
+
+enum
+  {
+#define CS(NAME, LABEL) CS_##NAME,
+    CROSSTABS_CELLS
+#undef CS
+    N_CROSSTABS_CELLS
+  };
+
+enum
+  {
+#define CS(NAME, LABEL) B_CS_##NAME = 1u << CS_##NAME,
+    CROSSTABS_STATS
+    CROSSTABS_CELLS
+#undef CS
+    B_CS_STATS_ALL = (1u << N_CROSSTABS_STATS) - 1,
+    B_CS_CELLS_ALL = (1u << N_CROSSTABS_CELLS) - 1,
+    B_CS_STATS_DEFAULT = B_CS_CHISQ,
+    B_CS_CELL_DEFAULT = B_CS_COUNT | B_CS_ROW | B_CS_COLUMN | B_CS_TOTAL,
+    B_CS_NONE
+  };
+
+static const struct checkbox_entry_item stats[] =
+  {
+#define CS(NAME, LABEL) {#NAME, LABEL},
+    CROSSTABS_STATS \
+    CS(NONE, N_("None"))
+#undef CS
+  };
+
+static const struct checkbox_entry_item cells[] =
+  {
+#define CS(NAME, LABEL) {#NAME, LABEL},
+    CROSSTABS_CELLS \
+    CS(NONE, N_("None"))
+#undef CS
+  };
+
+static void
+on_format_clicked (PsppireDialogActionCrosstabs *cd)
+{
+  int ret;
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->avalue_button), cd->format_options_avalue);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->table_button), cd->format_options_table);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->pivot_button), cd->format_options_pivot);
+
+  ret = psppire_dialog_run (PSPPIRE_DIALOG (cd->format_dialog));
+
+  if ( ret == PSPPIRE_RESPONSE_CONTINUE )
+    {
+      cd->format_options_avalue =
+       gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cd->avalue_button));
+
+      cd->format_options_table =
+       gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cd->table_button));
+
+      cd->format_options_pivot = 
+       gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cd->pivot_button));
+    }
+}
+
+static void
+on_cell_clicked (PsppireDialogActionCrosstabs *cd)
+{
+  GtkListStore *liststore = clone_list_store (GTK_LIST_STORE (cd->cell));
+
+  gint ret = psppire_dialog_run (PSPPIRE_DIALOG (cd->cell_dialog));
+
+  if ( ret == PSPPIRE_RESPONSE_CONTINUE )
+    {
+      g_object_unref (liststore);
+    }
+  else
+    {
+      gtk_tree_view_set_model (GTK_TREE_VIEW (cd->cell_view) , GTK_TREE_MODEL (liststore));
+      cd->cell = GTK_TREE_MODEL (liststore);
+    }
+}
+
+
+static void
+on_statistics_clicked (PsppireDialogActionCrosstabs *cd)
+{
+  GtkListStore *liststore = clone_list_store (GTK_LIST_STORE (cd->stat));
+
+  gint ret = psppire_dialog_run (PSPPIRE_DIALOG (cd->stat_dialog));
+
+  if ( ret == PSPPIRE_RESPONSE_CONTINUE )
+    {
+      g_object_unref (liststore);
+    }
+  else
+    {
+      gtk_tree_view_set_model (GTK_TREE_VIEW (cd->stat_view) , GTK_TREE_MODEL (liststore));
+      cd->stat = GTK_TREE_MODEL (liststore);
+    }
+}
+
+
+static void
+psppire_dialog_action_crosstabs_activate (GtkAction *a)
+{
+  PsppireDialogActionCrosstabs *act = PSPPIRE_DIALOG_ACTION_CROSSTABS (a);
+  PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (a);
+
+  GtkBuilder *xml = builder_new ("crosstabs.ui");
+
+  pda->dialog = get_widget_assert   (xml, "crosstabs-dialog");
+  pda->source = get_widget_assert   (xml, "dict-treeview");
+
+  act->dest_rows =   get_widget_assert   (xml, "rows");
+  act->dest_cols =   get_widget_assert   (xml, "cols");
+  act->format_button = get_widget_assert (xml, "format-button");
+  act->stat_button = get_widget_assert (xml, "stats-button");
+  act->cell_button = get_widget_assert (xml, "cell-button");
+  act->stat_view =   get_widget_assert (xml, "stats-view");
+  act->cell_view =   get_widget_assert (xml, "cell-view");
+  act->cell_dialog = get_widget_assert (xml, "cell-dialog");
+  act->stat_dialog = get_widget_assert (xml, "stat-dialog");
+  act->format_dialog = get_widget_assert (xml, "format-dialog");
+
+  act->avalue_button = get_widget_assert (xml, "ascending");
+  act->table_button = get_widget_assert (xml, "print-tables");
+  act->pivot_button = get_widget_assert (xml, "pivot");
+
+
+  g_object_unref (xml);
+
+  act->format_options_avalue = TRUE;
+  act->format_options_table = TRUE;
+  act->format_options_pivot = TRUE;
+
+  put_checkbox_items_in_treeview (GTK_TREE_VIEW (act->cell_view),
+                                 B_CS_CELL_DEFAULT,
+                                 N_CROSSTABS_CELLS,
+                                 cells
+                                 );
+
+  act->cell = gtk_tree_view_get_model (GTK_TREE_VIEW (act->cell_view));
+
+  put_checkbox_items_in_treeview (GTK_TREE_VIEW (act->stat_view),
+                                 B_CS_STATS_DEFAULT,
+                                 N_CROSSTABS_STATS,
+                                 stats
+                                 );
+
+  act->stat = gtk_tree_view_get_model (GTK_TREE_VIEW (act->stat_view));
+
+  psppire_dialog_action_set_refresh (pda, refresh);
+
+  psppire_dialog_action_set_valid_predicate (pda,
+                                       dialog_state_valid);
+
+  g_signal_connect_swapped (act->cell_button, "clicked",
+                           G_CALLBACK (on_cell_clicked), act);
+
+  g_signal_connect_swapped (act->stat_button, "clicked",
+                           G_CALLBACK (on_statistics_clicked), act);
+
+  g_signal_connect_swapped (act->format_button, "clicked",
+                           G_CALLBACK (on_format_clicked), act);
+
+
+  if (PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_crosstabs_parent_class)->activate)
+    PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_crosstabs_parent_class)->activate (pda);
+}
+
+
+
+static char *
+generate_syntax (PsppireDialogAction *a)
+{
+  PsppireDialogActionCrosstabs *cd = PSPPIRE_DIALOG_ACTION_CROSSTABS (a);
+  gchar *text = NULL;
+  int i, n;
+  guint selected;
+  GString *string = g_string_new ("CROSSTABS ");
+  gboolean ok;
+  GtkTreeIter iter;
+
+  g_string_append (string, "\n\t/TABLES=");
+  psppire_var_view_append_names (PSPPIRE_VAR_VIEW (cd->dest_rows), 0, string);
+  g_string_append (string, "\tBY\t");
+  psppire_var_view_append_names (PSPPIRE_VAR_VIEW (cd->dest_cols), 0, string);
+
+
+  g_string_append (string, "\n\t/FORMAT=");
+
+  if (cd->format_options_avalue)
+    g_string_append (string, "AVALUE");
+  else 
+    g_string_append (string, "DVALUE");
+  g_string_append (string, " ");
+
+  if (cd->format_options_table)
+    g_string_append (string, "TABLES");
+  else
+    g_string_append (string, "NOTABLES");
+  g_string_append (string, " ");
+
+  if (cd->format_options_pivot)
+    g_string_append (string, "PIVOT");
+  else 
+    g_string_append (string, "NOPIVOT");
+
+
+  selected = 0;
+  for (i = 0, ok = gtk_tree_model_get_iter_first (cd->stat, &iter); ok; 
+       i++, ok = gtk_tree_model_iter_next (cd->stat, &iter))
+    {
+      gboolean toggled;
+      gtk_tree_model_get (cd->stat, &iter,
+                         CHECKBOX_COLUMN_SELECTED, &toggled, -1); 
+      if (toggled) 
+       selected |= 1u << i; 
+      else 
+       selected &= ~(1u << i);
+    }
+
+  if (!(selected & (1u << CS_STATS_NONE)))
+    {
+      if (selected)
+       {
+         g_string_append (string, "\n\t/STATISTICS=");
+         n = 0;
+         for (i = 0; i < N_CROSSTABS_STATS; i++)
+           if (selected & (1u << i))
+             {
+               if (n++)
+                 g_string_append (string, " ");
+               g_string_append (string, stats[i].name);
+             }
+       }
+    }
+
+  selected = 0;
+  for (i = 0, ok = gtk_tree_model_get_iter_first (cd->cell, &iter); ok; 
+       i++, ok = gtk_tree_model_iter_next (cd->cell, &iter))
+    {
+      gboolean toggled;
+      gtk_tree_model_get (cd->cell, &iter,
+                         CHECKBOX_COLUMN_SELECTED, &toggled, -1); 
+      if (toggled) 
+       selected |= 1u << i; 
+      else 
+       selected &= ~(1u << i);
+    }
+
+
+
+  g_string_append (string, "\n\t/CELLS=");
+  if (selected & (1u << CS_CELLS_NONE))
+    g_string_append (string, "NONE");
+  else
+    {
+      n = 0;
+      for (i = 0; i < N_CROSSTABS_CELLS; i++)
+       if (selected & (1u << i))
+         {
+           if (n++)
+             g_string_append (string, " ");
+           g_string_append (string, cells[i].name);
+         }
+    }
+
+  g_string_append (string, ".\n");
+
+  text = string->str;
+
+  g_string_free (string, FALSE);
+
+  return text;
+}
+
+static void
+psppire_dialog_action_crosstabs_class_init (PsppireDialogActionCrosstabsClass *class)
+{
+  GtkActionClass *action_class = GTK_ACTION_CLASS (class);
+
+  action_class->activate = psppire_dialog_action_crosstabs_activate;
+
+  PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
+}
+
+
+static void
+psppire_dialog_action_crosstabs_init (PsppireDialogActionCrosstabs *act)
+{
+}
+
diff --git a/src/ui/gui/psppire-dialog-action-crosstabs.h b/src/ui/gui/psppire-dialog-action-crosstabs.h
new file mode 100644 (file)
index 0000000..ee8169a
--- /dev/null
@@ -0,0 +1,102 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2012  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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include "psppire-dialog-action.h"
+
+#ifndef __PSPPIRE_DIALOG_ACTION_CROSSTABS_H__
+#define __PSPPIRE_DIALOG_ACTION_CROSSTABS_H__
+
+G_BEGIN_DECLS
+
+
+#define PSPPIRE_TYPE_DIALOG_ACTION_CROSSTABS (psppire_dialog_action_crosstabs_get_type ())
+
+#define PSPPIRE_DIALOG_ACTION_CROSSTABS(obj)   \
+                     (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+                                                 PSPPIRE_TYPE_DIALOG_ACTION_CROSSTABS, PsppireDialogActionCrosstabs))
+
+#define PSPPIRE_DIALOG_ACTION_CROSSTABS_CLASS(klass) \
+                     (G_TYPE_CHECK_CLASS_CAST ((klass), \
+                                PSPPIRE_TYPE_DIALOG_ACTION_CROSSTABS, \
+                                 PsppireDialogActionCrosstabsClass))
+
+
+#define PSPPIRE_IS_DIALOG_ACTION_CROSSTABS(obj) \
+                    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_DIALOG_ACTION_CROSSTABS))
+
+#define PSPPIRE_IS_DIALOG_ACTION_CROSSTABS_CLASS(klass) \
+                     (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_TYPE_DIALOG_ACTION_CROSSTABS))
+
+
+#define PSPPIRE_DIALOG_ACTION_CROSSTABS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+                                  PSPPIRE_TYPE_DIALOG_ACTION_CROSSTABS, \
+                                  PsppireDialogActionCrosstabsClass))
+
+typedef struct _PsppireDialogActionCrosstabs       PsppireDialogActionCrosstabs;
+typedef struct _PsppireDialogActionCrosstabsClass  PsppireDialogActionCrosstabsClass;
+
+
+struct _PsppireDialogActionCrosstabs
+{
+  PsppireDialogAction parent;
+
+  /*< private >*/
+  gboolean dispose_has_run ;
+
+  GtkWidget *col_vars;
+  GtkWidget *row_vars;
+
+  GtkWidget *dest_rows; 
+  GtkWidget *dest_cols ;
+  GtkWidget *format_button ;
+  GtkWidget *stat_button ;
+  GtkWidget *cell_button ;
+
+  GtkWidget *stat_view ;
+
+  GtkWidget *cell_view ;
+  GtkTreeModel *cell ;
+  GtkWidget *cell_dialog ;
+  GtkTreeModel *stat;
+  GtkWidget *stat_dialog ;
+
+  gboolean format_options_avalue;
+  gboolean format_options_pivot;
+  gboolean format_options_table;
+
+  GtkWidget *table_button;
+  GtkWidget *pivot_button;
+
+  GtkWidget *format_dialog;
+  GtkWidget *avalue_button;
+};
+
+
+struct _PsppireDialogActionCrosstabsClass
+{
+  PsppireDialogActionClass parent_class;
+};
+
+
+GType psppire_dialog_action_crosstabs_get_type (void) ;
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_DIALOG_ACTION_CROSSTABS_H__ */
diff --git a/src/ui/gui/psppire-dialog-action-frequencies.c b/src/ui/gui/psppire-dialog-action-frequencies.c
new file mode 100644 (file)
index 0000000..b2ddd19
--- /dev/null
@@ -0,0 +1,486 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+Copyright (C) 2012  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 3 of the License, or
+  (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <config.h>
+
+#include "psppire-dialog-action-frequencies.h"
+#include "psppire-value-entry.h"
+
+#include "dialog-common.h"
+#include "helper.h"
+#include <ui/syntax-gen.h>
+#include "psppire-var-view.h"
+
+#include "psppire-dialog.h"
+#include "builder-wrapper.h"
+#include "checkbox-treeview.h"
+#include "psppire-dict.h"
+#include "libpspp/str.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+
+#define FREQUENCY_STATS                                        \
+  FS (MEAN, N_("Mean"))                                        \
+  FS (STDDEV, N_("Standard deviation"))                        \
+  FS (MINIMUM, N_("Minimum"))                          \
+  FS (MAXIMUM, N_("Maximum"))                          \
+  FS (SEMEAN, N_("Standard error of the mean"))                \
+  FS (VARIANCE, N_("Variance"))                                \
+  FS (SKEWNESS, N_("Skewness"))                                \
+  FS (SESKEW, N_("Standard error of the skewness"))    \
+  FS (RANGE, N_("Range"))                              \
+  FS (MODE, N_("Mode"))                                        \
+  FS (KURTOSIS, N_("Kurtosis"))                                \
+  FS (SEKURT, N_("Standard error of the kurtosis"))    \
+  FS (MEDIAN, N_("Median"))                            \
+  FS (SUM, N_("Sum"))
+
+
+
+enum
+{
+#define FS(NAME, LABEL) FS_##NAME,
+  FREQUENCY_STATS
+#undef FS
+  N_FREQUENCY_STATS
+};
+
+enum
+{
+#define FS(NAME, LABEL) B_FS_##NAME = 1u << FS_##NAME,
+  FREQUENCY_STATS
+#undef FS
+    B_FS_ALL = (1u << N_FREQUENCY_STATS) - 1,
+  B_FS_DEFAULT = B_FS_MEAN | B_FS_STDDEV | B_FS_MINIMUM | B_FS_MAXIMUM
+};
+
+
+static const struct checkbox_entry_item stats[] = {
+#define FS(NAME, LABEL) {#NAME, LABEL},
+  FREQUENCY_STATS
+#undef FS
+};
+
+
+static void
+on_tables_clicked (PsppireDialogActionFrequencies * fd)
+{
+  int ret;
+
+  switch (fd->tables_opts_order)
+    {
+    case FRQ_AVALUE:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->avalue), TRUE);
+      break;
+    case FRQ_DVALUE:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->dvalue), TRUE);
+      break;
+    case FRQ_ACOUNT:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->afreq), TRUE);
+      break;
+    case FRQ_DCOUNT:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->dfreq), TRUE);
+      break;
+    };
+
+  switch (fd->tables_opts_table)
+    {
+    case FRQ_TABLE:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->always), TRUE);
+      break;
+    case FRQ_NOTABLE:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->never), TRUE);
+      break;
+    case FRQ_LIMIT:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->limit), TRUE);
+      break;
+    }
+
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (fd->limit_spinbutton),
+                             fd->tables_opts_limit);
+
+  g_signal_emit_by_name (fd->limit, "toggled");
+
+  ret = psppire_dialog_run (PSPPIRE_DIALOG (fd->tables_dialog));
+
+  if (ret == PSPPIRE_RESPONSE_CONTINUE)
+    {
+      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->avalue)))
+        fd->tables_opts_order = FRQ_AVALUE;
+      else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->dvalue)))
+        fd->tables_opts_order = FRQ_DVALUE;
+      else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->afreq)))
+        fd->tables_opts_order = FRQ_ACOUNT;
+      else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->dfreq)))
+        fd->tables_opts_order = FRQ_DCOUNT;
+
+      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->always)))
+        fd->tables_opts_table = FRQ_TABLE;
+      else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->never)))
+        fd->tables_opts_table = FRQ_NOTABLE;
+      else
+        fd->tables_opts_table = FRQ_LIMIT;
+
+
+      fd->tables_opts_limit =
+        gtk_spin_button_get_value (GTK_SPIN_BUTTON (fd->limit_spinbutton));
+    }
+}
+
+
+static void
+on_charts_clicked (PsppireDialogActionFrequencies *fd)
+{
+  int ret;
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->min), fd->charts_opts_use_min);
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (fd->min_spin), fd->charts_opts_min);
+  g_signal_emit_by_name (fd->min, "toggled");
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->max), fd->charts_opts_use_max);
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (fd->max_spin), fd->charts_opts_max);
+  g_signal_emit_by_name (fd->max, "toggled");
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->hist), fd->charts_opts_draw_hist);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->normal), fd->charts_opts_draw_normal);
+  g_signal_emit_by_name (fd->hist, "toggled");
+
+  switch (fd->charts_opts_scale)
+    {
+    case FRQ_FREQ:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->freqs), TRUE);
+      break;
+    case FRQ_DVALUE:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->percents), TRUE);
+      break;
+    };
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->pie), fd->charts_opts_draw_pie);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->pie_include_missing),
+                                fd->charts_opts_pie_include_missing);
+
+  g_signal_emit_by_name (fd->pie, "toggled");
+
+  ret = psppire_dialog_run (PSPPIRE_DIALOG (fd->charts_dialog));
+
+  if ( ret == PSPPIRE_RESPONSE_CONTINUE )
+    {
+       fd->charts_opts_use_min = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->min));
+       fd->charts_opts_min = gtk_spin_button_get_value (GTK_SPIN_BUTTON (fd->min_spin));
+
+       fd->charts_opts_use_max = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->max));
+       fd->charts_opts_max = gtk_spin_button_get_value (GTK_SPIN_BUTTON (fd->max_spin));
+
+       fd->charts_opts_draw_hist = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->hist));
+       fd->charts_opts_draw_normal = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->normal));
+       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->freqs)))
+         fd->charts_opts_scale = FRQ_FREQ;
+       else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->percents)))
+         fd->charts_opts_scale = FRQ_PERCENT;
+
+       fd->charts_opts_draw_pie = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->pie));
+       fd->charts_opts_pie_include_missing
+          = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->pie_include_missing));
+    }
+}
+
+
+static void
+psppire_dialog_action_frequencies_class_init
+(PsppireDialogActionFrequenciesClass * class);
+
+G_DEFINE_TYPE (PsppireDialogActionFrequencies,
+               psppire_dialog_action_frequencies, PSPPIRE_TYPE_DIALOG_ACTION);
+
+static gboolean
+dialog_state_valid (gpointer data)
+{
+  PsppireDialogActionFrequencies *fd =
+    PSPPIRE_DIALOG_ACTION_FREQUENCIES (data);
+
+  GtkTreeModel *vars =
+    gtk_tree_view_get_model (GTK_TREE_VIEW (fd->stat_vars));
+
+  GtkTreeIter notused;
+
+  return gtk_tree_model_get_iter_first (vars, &notused);
+}
+
+static void
+refresh (PsppireDialogAction * fdx)
+{
+  PsppireDialogActionFrequencies *fd =
+    PSPPIRE_DIALOG_ACTION_FREQUENCIES (fdx);
+
+  GtkTreeIter iter;
+  size_t i;
+  bool ok;
+
+  GtkTreeModel *liststore =
+    gtk_tree_view_get_model (GTK_TREE_VIEW (fd->stat_vars));
+  gtk_list_store_clear (GTK_LIST_STORE (liststore));
+
+  for (i = 0, ok = gtk_tree_model_get_iter_first (fd->stats, &iter); ok;
+       i++, ok = gtk_tree_model_iter_next (fd->stats, &iter))
+    gtk_list_store_set (GTK_LIST_STORE (fd->stats), &iter,
+                        CHECKBOX_COLUMN_SELECTED,
+                        (B_FS_DEFAULT & (1u << i)) ? true : false, -1);
+}
+
+
+
+static void
+psppire_dialog_action_frequencies_activate (GtkAction * a)
+{
+  PsppireDialogActionFrequencies *act = PSPPIRE_DIALOG_ACTION_FREQUENCIES (a);
+  PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (a);
+
+  GtkBuilder *xml = builder_new ("frequencies.ui");
+
+  GtkWidget *stats_treeview = get_widget_assert (xml, "stats-treeview");
+  GtkWidget *tables_button = get_widget_assert (xml, "tables-button");
+  GtkWidget *charts_button = get_widget_assert (xml, "charts-button");
+
+  pda->dialog = get_widget_assert (xml, "frequencies-dialog");
+  pda->source = get_widget_assert (xml, "dict-treeview");
+
+  act->stat_vars = get_widget_assert (xml, "var-treeview");
+
+  put_checkbox_items_in_treeview (GTK_TREE_VIEW (stats_treeview),
+                                  B_FS_DEFAULT, N_FREQUENCY_STATS, stats);
+
+  act->stats = gtk_tree_view_get_model (GTK_TREE_VIEW (stats_treeview));
+
+  act->include_missing = get_widget_assert (xml, "include_missing");
+
+
+  act->tables_dialog = get_widget_assert (xml, "tables-dialog");
+  act->charts_dialog = get_widget_assert (xml, "charts-dialog");
+  act->always = get_widget_assert (xml, "always");
+  act->never = get_widget_assert (xml, "never");
+  act->limit = get_widget_assert (xml, "limit");
+  act->limit_spinbutton = get_widget_assert (xml, "limit-spin");
+
+  g_signal_connect (act->limit, "toggled",
+                    G_CALLBACK (set_sensitivity_from_toggle),
+                    act->limit_spinbutton);
+
+  act->avalue = get_widget_assert (xml, "avalue");
+  act->dvalue = get_widget_assert (xml, "dvalue");
+  act->afreq = get_widget_assert (xml, "afreq");
+  act->dfreq = get_widget_assert (xml, "dfreq");
+
+  act->charts_opts_use_min = false;
+  act->charts_opts_min = 0;
+  act->charts_opts_use_max = false;
+  act->charts_opts_max = 100;
+  act->charts_opts_draw_hist = false;
+  act->charts_opts_draw_normal = false;
+  act->charts_opts_scale = FRQ_FREQ;
+  act->charts_opts_draw_pie = false;
+  act->charts_opts_pie_include_missing = false;
+
+  act->freqs = get_widget_assert (xml, "freqs");
+  act->percents = get_widget_assert (xml, "percents");
+
+  act->min = get_widget_assert (xml, "min");
+  act->min_spin = get_widget_assert (xml, "min-spin");
+  g_signal_connect (act->min, "toggled",
+                   G_CALLBACK (set_sensitivity_from_toggle), act->min_spin);
+  act->max = get_widget_assert (xml, "max");
+  act->max_spin = get_widget_assert (xml, "max-spin");
+  g_signal_connect (act->max, "toggled",
+                   G_CALLBACK (set_sensitivity_from_toggle), act->max_spin);
+
+  act->hist = get_widget_assert (xml, "hist");
+  act->normal = get_widget_assert (xml, "normal");
+  g_signal_connect (act->hist, "toggled",
+                   G_CALLBACK (set_sensitivity_from_toggle), act->normal);
+
+  act->pie =  (get_widget_assert (xml, "pie"));
+  act->pie_include_missing = get_widget_assert (xml, "pie-include-missing");
+
+
+  g_object_unref (xml);
+
+
+  act->tables_opts_order = FRQ_AVALUE;
+  act->tables_opts_table = FRQ_TABLE;
+  act->tables_opts_limit = 50;
+
+  g_signal_connect_swapped (tables_button, "clicked",
+                           G_CALLBACK (on_tables_clicked),  act);
+
+  g_signal_connect_swapped (charts_button, "clicked",
+                           G_CALLBACK (on_charts_clicked),  act);
+
+  psppire_dialog_action_set_refresh (pda, refresh);
+
+  psppire_dialog_action_set_valid_predicate (pda, dialog_state_valid);
+
+  if (PSPPIRE_DIALOG_ACTION_CLASS
+      (psppire_dialog_action_frequencies_parent_class)->activate)
+    PSPPIRE_DIALOG_ACTION_CLASS
+      (psppire_dialog_action_frequencies_parent_class)->activate (pda);
+}
+
+static char *
+generate_syntax (PsppireDialogAction * a)
+{
+  PsppireDialogActionFrequencies *fd = PSPPIRE_DIALOG_ACTION_FREQUENCIES (a);
+  gchar *text = NULL;
+  gint i;
+  gboolean ok;
+  GtkTreeIter iter;
+  guint selected = 0;
+
+  GString *string = g_string_new ("FREQUENCIES");
+
+  g_string_append (string, "\n\t/VARIABLES=");
+  psppire_var_view_append_names (PSPPIRE_VAR_VIEW (fd->stat_vars), 0, string);
+
+  g_string_append (string, "\n\t/FORMAT=");
+
+  switch (fd->tables_opts_order)
+    {
+    case FRQ_AVALUE:
+      g_string_append (string, "AVALUE");
+      break;
+    case FRQ_DVALUE:
+      g_string_append (string, "DVALUE");
+      break;
+    case FRQ_ACOUNT:
+      g_string_append (string, "AFREQ");
+      break;
+    case FRQ_DCOUNT:
+      g_string_append (string, "DFREQ");
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+
+  g_string_append (string, " ");
+
+  switch (fd->tables_opts_table)
+    {
+    case FRQ_TABLE:
+      g_string_append (string, "TABLE");
+      break;
+    case FRQ_NOTABLE:
+      g_string_append (string, "NOTABLE");
+      break;
+    case FRQ_LIMIT:
+      g_string_append_printf (string, "LIMIT (%d)", fd->tables_opts_limit);
+      break;
+    }
+
+
+  for (i = 0, ok = gtk_tree_model_get_iter_first (fd->stats, &iter); ok;
+       i++, ok = gtk_tree_model_iter_next (fd->stats, &iter))
+    {
+      gboolean toggled;
+      gtk_tree_model_get (fd->stats, &iter,
+                          CHECKBOX_COLUMN_SELECTED, &toggled, -1);
+      if (toggled)
+        selected |= 1u << i;
+    }
+
+  if (selected != B_FS_DEFAULT)
+    {
+      g_string_append (string, "\n\t/STATISTICS=");
+      if (selected == B_FS_ALL)
+        g_string_append (string, "ALL");
+      else if (selected == 0)
+        g_string_append (string, "NONE");
+      else
+        {
+          int n = 0;
+          if ((selected & B_FS_DEFAULT) == B_FS_DEFAULT)
+            {
+              g_string_append (string, "DEFAULT");
+              selected &= ~B_FS_DEFAULT;
+              n++;
+            }
+          for (i = 0; i < N_FREQUENCY_STATS; i++)
+            if (selected & (1u << i))
+              {
+                if (n++)
+                  g_string_append (string, " ");
+                g_string_append (string, stats[i].name);
+              }
+        }
+    }
+
+  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->include_missing)))
+    g_string_append (string, "\n\t/MISSING=INCLUDE");
+
+
+  if (fd->charts_opts_draw_hist)
+    {
+      g_string_append (string, "\n\t/HISTOGRAM=");
+      g_string_append (string,
+                       fd->charts_opts_draw_normal ? "NORMAL" : "NONORMAL");
+
+      if (fd->charts_opts_scale == FRQ_PERCENT)
+        g_string_append (string, " PERCENT");
+
+      if (fd->charts_opts_use_min)
+        g_string_append_printf (string, " MIN(%.15g)", fd->charts_opts_min);
+      if (fd->charts_opts_use_max)
+        g_string_append_printf (string, " MAX(%.15g)", fd->charts_opts_max);
+    }
+
+  if (fd->charts_opts_draw_pie)
+    {
+      g_string_append (string, "\n\t/PIECHART=");
+
+      if (fd->charts_opts_pie_include_missing)
+        g_string_append (string, " MISSING");
+
+      if (fd->charts_opts_use_min)
+        g_string_append_printf (string, " MIN(%.15g)", fd->charts_opts_min);
+      if (fd->charts_opts_use_max)
+        g_string_append_printf (string, " MAX(%.15g)", fd->charts_opts_max);
+    }
+
+  g_string_append (string, ".\n");
+
+  text = string->str;
+
+  g_string_free (string, FALSE);
+
+  return text;
+}
+
+static void
+psppire_dialog_action_frequencies_class_init (PsppireDialogActionFrequenciesClass *class)
+{
+  GtkActionClass *action_class = GTK_ACTION_CLASS (class);
+
+  action_class->activate = psppire_dialog_action_frequencies_activate;
+
+  PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
+}
+
+
+static void
+psppire_dialog_action_frequencies_init (PsppireDialogActionFrequencies * act)
+{
+}
diff --git a/src/ui/gui/psppire-dialog-action-frequencies.h b/src/ui/gui/psppire-dialog-action-frequencies.h
new file mode 100644 (file)
index 0000000..ea80158
--- /dev/null
@@ -0,0 +1,151 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2012  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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include "psppire-dialog-action.h"
+
+#ifndef __PSPPIRE_DIALOG_ACTION_FREQUENCIES_H__
+#define __PSPPIRE_DIALOG_ACTION_FREQUENCIES_H__
+
+G_BEGIN_DECLS
+
+
+#define PSPPIRE_TYPE_DIALOG_ACTION_FREQUENCIES (psppire_dialog_action_frequencies_get_type ())
+
+#define PSPPIRE_DIALOG_ACTION_FREQUENCIES(obj) \
+                     (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+                                                 PSPPIRE_TYPE_DIALOG_ACTION_FREQUENCIES, \
+                                                  PsppireDialogActionFrequencies))
+
+#define PSPPIRE_DIALOG_ACTION_FREQUENCIES_CLASS(klass) \
+                     (G_TYPE_CHECK_CLASS_CAST ((klass), \
+                                PSPPIRE_TYPE_DIALOG_ACTION_FREQUENCIES, \
+                                 PsppireDialogActionFrequenciesClass))
+
+
+#define PSPPIRE_IS_DIALOG_ACTION_FREQUENCIES(obj) \
+                    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_DIALOG_ACTION_FREQUENCIES))
+
+#define PSPPIRE_IS_DIALOG_ACTION_FREQUENCIES_CLASS(klass) \
+                     (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_TYPE_DIALOG_ACTION_FREQUENCIES))
+
+
+#define PSPPIRE_DIALOG_ACTION_FREQUENCIES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+                                  PSPPIRE_TYPE_DIALOG_ACTION_FREQUENCIES, \
+                                  PsppireDialogActionFrequenciesClass))
+
+typedef struct _PsppireDialogActionFrequencies       PsppireDialogActionFrequencies;
+typedef struct _PsppireDialogActionFrequenciesClass  PsppireDialogActionFrequenciesClass;
+
+
+enum frq_scale
+  {
+    FRQ_FREQ,
+    FRQ_PERCENT
+  };
+
+enum frq_order
+  {
+    FRQ_AVALUE,
+    FRQ_DVALUE,
+    FRQ_ACOUNT,
+    FRQ_DCOUNT
+  };
+
+enum frq_table
+  {
+    FRQ_TABLE,
+    FRQ_NOTABLE,
+    FRQ_LIMIT
+  };
+
+
+struct _PsppireDialogActionFrequencies
+{
+  PsppireDialogAction parent;
+
+  /*< private >*/
+  gboolean dispose_has_run ;
+
+  GtkWidget *stat_vars;
+  GtkTreeModel *stats;
+
+  GtkWidget *include_missing;
+
+  enum frq_order tables_opts_order;
+  enum frq_table tables_opts_table;
+  gint tables_opts_limit;
+
+  GtkWidget * always;
+  GtkWidget * never;
+  GtkWidget * limit;
+  GtkWidget * limit_spinbutton;
+
+  GtkWidget * avalue;
+  GtkWidget * dvalue;
+  GtkWidget * afreq;
+  GtkWidget * dfreq;  
+
+  GtkWidget *tables_dialog;
+
+  /* Charts dialog */
+
+  GtkWidget *min;
+  GtkWidget *min_spin;
+  GtkWidget *max;
+  GtkWidget *max_spin;
+
+  GtkWidget *hist;
+  GtkWidget *normal;
+
+  gboolean charts_opts_use_min;
+  gdouble charts_opts_min;
+
+  gboolean charts_opts_use_max;
+  gdouble charts_opts_max;
+
+  gboolean charts_opts_draw_hist;
+  gboolean charts_opts_draw_normal;
+
+  gboolean charts_opts_draw_pie;
+  gboolean charts_opts_pie_include_missing;
+
+
+  enum frq_scale charts_opts_scale;
+
+  GtkWidget *freqs;
+  GtkWidget *percents;
+  GtkWidget *pie;
+  GtkWidget *pie_include_missing;
+
+  GtkWidget *charts_dialog;
+};
+
+
+struct _PsppireDialogActionFrequenciesClass
+{
+  PsppireDialogActionClass parent_class;
+};
+
+
+GType psppire_dialog_action_frequencies_get_type (void) ;
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_DIALOG_ACTION_FREQUENCIES_H__ */
index d93a2f5b0c5e85fd871f7d6a4e6452af119c33d0..0426931e85231e10ee2da445e3c6c5f831be9003 100644 (file)
@@ -41,16 +41,6 @@ psppire_dialog_action_logistic_class_init (PsppireDialogActionLogisticClass *cla
 
 G_DEFINE_TYPE (PsppireDialogActionLogistic, psppire_dialog_action_logistic, PSPPIRE_TYPE_DIALOG_ACTION);
 
-static void
-set_sensitivity_from_toggle (GtkToggleButton *togglebutton,  gpointer data)
-{
-  GtkWidget *w = data;
-  gboolean active = gtk_toggle_button_get_active (togglebutton);
-
-  gtk_widget_set_sensitive (w, active);
-}
-
-
 static gboolean
 dialog_state_valid (gpointer data)
 {
index 680e147b62c845424c5aeb83ca7c507ff4bbf539..01d694e27e7e2fc98808488e27d0c603aecbe05e 100644 (file)
@@ -17,6 +17,7 @@
 #include <config.h>
 
 #include <gtk/gtk.h>
+#include "dialog-common.h"
 #include "psppire-val-chooser.h"
 
 #include "libpspp/str.h"
@@ -334,14 +335,6 @@ static struct layout range_opt[n_VAL_CHOOSER_BUTTONS]=
     {N_("_All other values"),          NULL,         else_set   }
   };
 
-static void
-set_sensitivity_from_toggle (GtkToggleButton *togglebutton,  GtkWidget *w)
-{
-  gboolean active = gtk_toggle_button_get_active (togglebutton);
-
-  gtk_widget_set_sensitive (w, active);
-}
-
 static void
 psppire_val_chooser_init (PsppireValChooser *vr)
 {
index 7bc05f2422c711c2a3884aa340f791dc8d4dfc35..bfbfc834cbced0e92ca00a1701bd75ad2ae8b08f 100644 (file)
@@ -61,15 +61,6 @@ struct runs
 
 static char * generate_syntax (const struct runs *rd);
 
-/* Makes widget W's sensitivity follow the active state of TOGGLE */
-static void
-sensitive_if_active (GtkToggleButton *toggle, GtkWidget *w)
-{
-  gboolean active = gtk_toggle_button_get_active (toggle);
-
-  gtk_widget_set_sensitive (w, active);
-}
-
 static void
 refresh (struct runs *fd)
 {
@@ -151,7 +142,7 @@ runs_dialog (PsppireDataWindow *dw)
                NULL);
 
   g_signal_connect (fd.cb[CB_CUSTOM], "toggled",
-                   G_CALLBACK (sensitive_if_active), fd.entry);
+                   G_CALLBACK (set_sensitivity_from_toggle), fd.entry);
 
   psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog),
                                      dialog_state_valid, &fd);
index be0a957f6c46e3c6e15140358bfe55945cbfe654..c03906a6a8a2fedec3c5301864a9bf2224bd430b 100644 (file)
@@ -60,27 +60,6 @@ struct select_cases_dialog
 static gchar * generate_syntax (const struct select_cases_dialog *scd);
 
 
-static void
-set_sensitivity_from_toggle (GtkToggleButton *togglebutton,  gpointer data)
-{
-  GtkWidget *w = data;
-  gboolean active = gtk_toggle_button_get_active (togglebutton);
-
-  gtk_widget_set_sensitive (w, active);
-}
-
-static void
-set_sensitivity_from_toggle_invert (GtkToggleButton *togglebutton,
-                                   gpointer data)
-{
-  GtkWidget *w = data;
-  gboolean active = gtk_toggle_button_get_active (togglebutton);
-
-  gtk_widget_set_sensitive (w, !active);
-}
-
-
-
 static const gchar label1[]=N_("Approximately %3d%% of all cases.");
 static const gchar label2[]=N_("Exactly %3d cases from the first %3d cases.");
 
index 5d8351c44126858d772acb3aaa1260d07fb4e8b5..488656e9e6365173805a373c0fa64e03e6fe8ad6 100644 (file)
 #include "psppire-var-view.h"
 #include "psppire-val-chooser.h"
 
+#include "psppire-dialog-action-binomial.h"
 #include "psppire-dialog-action-correlation.h"
+#include "psppire-dialog-action-crosstabs.h"
 #include "psppire-dialog-action-descriptives.h"
 #include "psppire-dialog-action-examine.h"
 #include "psppire-dialog-action-factor.h"
+#include "psppire-dialog-action-frequencies.h"
 #include "psppire-dialog-action-indep-samps.h"
 #include "psppire-dialog-action-kmeans.h"
+#include "psppire-dialog-action-logistic.h"
 #include "psppire-dialog-action-means.h"
 #include "psppire-means-layer.h"
 #include "psppire-dialog-action-rank.h"
@@ -50,10 +54,13 @@ preregister_widgets (void)
   psppire_var_view_get_type ();
   psppire_value_entry_get_type ();
 
+  psppire_dialog_action_binomial_get_type ();
   psppire_dialog_action_correlation_get_type ();
+  psppire_dialog_action_crosstabs_get_type ();
   psppire_dialog_action_descriptives_get_type ();
   psppire_dialog_action_examine_get_type ();
   psppire_dialog_action_factor_get_type ();
+  psppire_dialog_action_frequencies_get_type ();
   psppire_dialog_action_logistic_get_type ();
   psppire_dialog_action_kmeans_get_type ();
   psppire_dialog_action_means_get_type ();
index a0ba84d898c29e09fb4246485a3991cc84b64dec..3f4139b85d377dc8b5dc3254a5c0d5e4a166df2f 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2000, 2006-2007, 2009-2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -49,7 +49,6 @@
 #include "math/random.h"
 #include "output/driver.h"
 #include "output/message-item.h"
-#include "ui/debugger.h"
 #include "ui/source-init-opts.h"
 #include "ui/terminal/terminal-opts.h"
 #include "ui/terminal/terminal-reader.h"
@@ -194,9 +193,6 @@ bug_handler(int sig)
      recurse. */
   signal (sig, SIG_DFL);
 
-#if DEBUGGING
-  connect_debugger ();
-#endif
   switch (sig)
     {
     case SIGABRT:
index b0582c6c47a7fd141395c41cc85a05a7aa22f958..4a59cf795ad80eecdecf1007c3e005a83009e415 100644 (file)
@@ -30,6 +30,7 @@ A,B,C
 ])
 AT_CLEANUP
 
+
 AT_SETUP([DATA LIST LIST with explicit delimiters])
 AT_DATA([data-list.pspp], [dnl
 data list list ('|','X') /A B C D.
@@ -255,3 +256,34 @@ AT_CHECK([cat write.txt], [0], [dnl
         1       12      123     1234    12345    .
 ])
 AT_CLEANUP
+
+AT_SETUP([DATA LIST FREE and LIST report missing delimiters])
+AT_DATA([data-list.sps], [dnl
+DATA LIST FREE NOTABLE/s (a10).
+LIST.
+BEGIN DATA.
+'y'z
+END DATA.
+])
+AT_CHECK([pspp -O format=csv data-list.sps], [0], [dnl
+data-list.sps:4: warning: Missing delimiter following quoted string.
+
+Table: Data List
+s
+y         @&t@
+z         @&t@
+])
+AT_CLEANUP
+
+AT_SETUP([DATA LIST FREE and LIST assume a width if omitted])
+AT_DATA([data-list.sps], [dnl
+DATA LIST FREE TABLE/s (a) d (datetime) f (f).
+])
+AT_CHECK([pspp -O format=csv data-list.sps], [0], [dnl
+Table: Reading free-form data from INLINE.
+Variable,Format
+s,A1
+d,DATETIME17.0
+f,F1.0
+])
+AT_CLEANUP
index e56a3a457e53c46d4a6905d95c8521c355891556..4512458afcee36b3b8ddc08e4d487d950a0d6c7a 100644 (file)
@@ -487,7 +487,7 @@ ANY(string, string[, string]...).]],
   [[any('a', 'a  ', 'b', 'c')], [true]],
   [[any('b   ', 'a', 'b', 'c')], [true]],
   [[any('c   ', 'a', 'b', 'c     ')], [true]],
-  [[any(a, 'b', 'c', 'd')], [error],
+  [[any(a10, 'b', 'c', 'd')], [error],
    [error: DEBUG EVALUATE: Function invocation any(format, string, string, string) does not match any known function.  Candidates are:
 ANY(number, number[, number]...)
 ANY(string, string[, string]...).]],
@@ -1740,7 +1740,42 @@ CHECK_EXPR_EVAL([datediff],
   [[datediff(date.mdy(7,18,2094), date.mdy(11,10,2038), 'quarters')], [222.00]],
   [[datediff(date.mdy(2,29,1904), date.mdy(2,29,1900), 'quarters')], [15.00]],
   [[datediff(date.mdy(2,29,1908), date.mdy(2,29,1904), 'quarters')], [16.00]],
-  [[datediff(date.mdy(2,28,1903), date.mdy(2,29,1900), 'quarters')], [11.00]])
+  [[datediff(date.mdy(2,28,1903), date.mdy(2,29,1900), 'quarters')], [11.00]],
+
+dnl time of day is significant for DATEDIFF
+  [[datediff(date.mdy(10,15,1910) + 234, date.mdy(10,10,1910) + 123, 'days')],
+    [5.00]],
+  [[datediff(date.mdy(10,15,1910) + 123, date.mdy(10,10,1910) + 234, 'days')],
+    [4.00]],
+  [[datediff(date.mdy(10,24,1910) + 234, date.mdy(10,10,1910) + 123, 'weeks')],
+    [2.00]],
+  [[datediff(date.mdy(10,24,1910) + 123, date.mdy(10,10,1910) + 234, 'weeks')],
+    [1.00]],
+  [[datediff(date.mdy(10,10,1910) + 234, date.mdy(5,10,1910) + 123, 'months')],
+    [5.00]],
+  [[datediff(date.mdy(10,10,1910) + 123, date.mdy(5,10,1910) + 234, 'months')],
+    [4.00]],
+  [[datediff(date.mdy(5,10,1919) + 234, date.mdy(5,10,1910) + 123, 'years')],
+    [9.00]],
+  [[datediff(date.mdy(5,10,1919) + 123, date.mdy(5,10,1910) + 234, 'years')],
+    [8.00]],
+
+  [[datediff(date.mdy(10,10,1910) + 123, date.mdy(10,15,1910) + 234, 'days')],
+    [-5.00]],
+  [[datediff(date.mdy(10,10,1910) + 234, date.mdy(10,15,1910) + 123, 'days')],
+    [-4.00]],
+  [[datediff(date.mdy(10,10,1910) + 123, date.mdy(10,24,1910) + 234, 'weeks')],
+    [-2.00]],
+  [[datediff(date.mdy(10,10,1910) + 234, date.mdy(10,24,1910) + 123, 'weeks')],
+    [-1.00]],
+  [[datediff(date.mdy(5,10,1910) + 123, date.mdy(10,10,1910) + 234, 'months')],
+    [-5.00]],
+  [[datediff(date.mdy(5,10,1910) + 234, date.mdy(10,10,1910) + 123, 'months')],
+    [-4.00]],
+  [[datediff(date.mdy(5,10,1910) + 123, date.mdy(5,10,1919) + 234, 'years')],
+    [-9.00]],
+  [[datediff(date.mdy(5,10,1910) + 234, date.mdy(5,10,1919) + 123, 'years')],
+    [-8.00]])
 
 CHECK_EXPR_EVAL([datesum],
 dnl DATESUM with non-leap year
@@ -1813,7 +1848,13 @@ dnl DATESUM with leap year
   [[ctime.days(datesum(date.mdy(6,10,1648), 1, 'hours') - date.mdy(6,10,1648))], [0.04]],
   [[ctime.days(datesum(date.mdy(6,30,1680), 2.5, 'hours') - date.mdy(6,30,1680))], [0.10]],
   [[ctime.days(datesum(date.mdy(6,19,1768), -4, 'hours') - date.mdy(6,19,1768))], [-0.17]],
-  [[ctime.days(datesum(date.mdy(8,2,1819), 5, 'hours') - date.mdy(8,2,1819))], [0.21]])
+  [[ctime.days(datesum(date.mdy(8,2,1819), 5, 'hours') - date.mdy(8,2,1819))], [0.21]],
+
+dnl DATESUM preserves time-of-day for units of days and longer.
+  [[ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'days') - (date.mdy(8,2,1819) + time.hms(1,2,3)))], [5.00]],
+  [[ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'weeks') - (date.mdy(8,2,1819) + time.hms(1,2,3)))], [35.00]],
+  [[ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'months') - (date.mdy(8,2,1819) + time.hms(1,2,3)))], [153.00]],
+  [[ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'years') - (date.mdy(8,2,1819) + time.hms(1,2,3)))], [1827.00]])
 
 CHECK_EXPR_EVAL([miscellaneous],
 dnl These test values are from Applied Statistics, Algorithm AS 310.
index f5aed6bdb64d9086f24af2ddcb11135c229af4b5..59609f0380d8908060a7deb2c5dad3e594576e4c 100644 (file)
@@ -38,13 +38,13 @@ X * Yabbadabbadoo,1,100.0%,0,0.0%,1,100.0%
 Table: X * Yabbadabbadoo [[count]].
 ,Yabbadabbadoo,,,,,,,
 X,1.00,2.00,3.00,4.00,5.00,6.00,7.00,Total
-1.00,.0,.0,.0,.0,.0,.0,.0,.0
-2.00,.0,.0,.0,.0,.0,.0,.0,.0
-3.00,.0,.0,.0,.0,.0,.0,.0,.0
-4.00,.0,.0,.0,.0,1.0,.0,.0,1.0
-5.00,.0,.0,.0,.0,.0,.0,.0,.0
-6.00,.0,.0,.0,.0,.0,.0,.0,.0
-7.00,.0,.0,.0,.0,.0,.0,.0,.0
-Total,.0,.0,.0,.0,1.0,.0,.0,1.0
+1.00,.00,.00,.00,.00,.00,.00,.00,.00
+2.00,.00,.00,.00,.00,.00,.00,.00,.00
+3.00,.00,.00,.00,.00,.00,.00,.00,.00
+4.00,.00,.00,.00,.00,1.00,.00,.00,1.00
+5.00,.00,.00,.00,.00,.00,.00,.00,.00
+6.00,.00,.00,.00,.00,.00,.00,.00,.00
+7.00,.00,.00,.00,.00,.00,.00,.00,.00
+Total,.00,.00,.00,.00,1.00,.00,.00,1.00
 ])
 AT_CLEANUP
index 1647e4bd6113bbb7ca5456a7b8885244890aa044..4492e9a25002be3cbc73a4a0a96bfa5fdb9b501e 100644 (file)
@@ -26,14 +26,14 @@ X * Y,1,100.0%,0,0.0%,1,100.0%
 Table: X * Y [count].
 ,Y,,,,,,,
 X,1.00,2.00,3.00,4.00,5.00,6.00,7.00,Total
-1.00,.0,.0,.0,.0,.0,.0,.0,.0
-2.00,.0,.0,.0,.0,.0,.0,.0,.0
-3.00,.0,.0,.0,.0,.0,.0,.0,.0
-4.00,.0,.0,.0,.0,1.0,.0,.0,1.0
-5.00,.0,.0,.0,.0,.0,.0,.0,.0
-6.00,.0,.0,.0,.0,.0,.0,.0,.0
-7.00,.0,.0,.0,.0,.0,.0,.0,.0
-Total,.0,.0,.0,.0,1.0,.0,.0,1.0
+1.00,.00,.00,.00,.00,.00,.00,.00,.00
+2.00,.00,.00,.00,.00,.00,.00,.00,.00
+3.00,.00,.00,.00,.00,.00,.00,.00,.00
+4.00,.00,.00,.00,.00,1.00,.00,.00,1.00
+5.00,.00,.00,.00,.00,.00,.00,.00,.00
+6.00,.00,.00,.00,.00,.00,.00,.00,.00
+7.00,.00,.00,.00,.00,.00,.00,.00,.00
+Total,.00,.00,.00,.00,1.00,.00,.00,1.00
 ]])
 AT_CLEANUP
 
@@ -59,9 +59,9 @@ Variable,Format
 x,F8.0
 y,A18
 
-"crosstabs.sps:4: warning: BEGIN DATA: Missing value(s) for all variables from x onward.  These will be filled with the system-missing value or blanks, as appropriate."
+"crosstabs.sps:4: warning: Missing value(s) for all variables from x onward.  These will be filled with the system-missing value or blanks, as appropriate."
 
-"crosstabs.sps:6: warning: BEGIN DATA: Missing value(s) for all variables from x onward.  These will be filled with the system-missing value or blanks, as appropriate."
+"crosstabs.sps:6: warning: Missing value(s) for all variables from x onward.  These will be filled with the system-missing value or blanks, as appropriate."
 
 Table: Summary.
 ,Cases,,,,,
@@ -72,10 +72,10 @@ x * y,4,66.7%,2,33.3%,6,100.0%
 Table: x * y [count].
 ,y,,,,
 x,one unity         ,three lots        ,two duality       ,zero none         ,Total
-1.00,1.0,.0,.0,1.0,2.0
-2.00,.0,.0,1.0,.0,1.0
-3.00,.0,1.0,.0,.0,1.0
-Total,1.0,1.0,1.0,1.0,4.0
+1.00,1.00,.00,.00,1.00,2.00
+2.00,.00,.00,1.00,.00,1.00
+3.00,.00,1.00,.00,.00,1.00
+Total,1.00,1.00,1.00,1.00,4.00
 ]])
 AT_CLEANUP
 
@@ -131,9 +131,9 @@ y * z,9,100.0%,0,0.0%,9,100.0%
 Table: y * z [count].
 ,z,,
 y,1,2,Total
-1,4.0,3.0,7.0
-2,1.0,1.0,2.0
-Total,5.0,4.0,9.0
+1,4.00,3.00,7.00
+2,1.00,1.00,2.00
+Total,5.00,4.00,9.00
 ]])
 AT_CLEANUP
 
@@ -168,10 +168,10 @@ x * y,4,100.0%,0,0.0%,4,100.0%
 Table: x * y [count].
 ,y,,
 x,1.00,2.00,Total
-2.00,.0,1.0,1.0
-3.00,1.0,.0,1.0
-4.00,1.0,1.0,2.0
-Total,2.0,2.0,4.0
+2.00,.00,1.00,1.00
+3.00,1.00,.00,1.00
+4.00,1.00,1.00,2.00
+Total,2.00,2.00,4.00
 
 Table: Chi-square tests.
 Statistic,Value,df,Asymp. Sig. (2-tailed)
@@ -220,18 +220,18 @@ v1 * v2,6,100.0%,0,0.0%,6,100.0%
 "Table: v1 * v2 [count, row %, column %, total %]."
 ,v2,,
 v1,e ,f ,Total
-c ,3.0,1.0,4.0
-,75.0%,25.0%,100.0%
-,75.0%,50.0%,66.7%
-,50.0%,16.7%,66.7%
-d ,1.0,1.0,2.0
-,50.0%,50.0%,100.0%
-,25.0%,50.0%,33.3%
-,16.7%,16.7%,33.3%
-Total,4.0,2.0,6.0
-,66.7%,33.3%,100.0%
-,100.0%,100.0%,100.0%
-,66.7%,33.3%,100.0%
+c ,3.00,1.00,4.00
+,75.00%,25.00%,100.00%
+,75.00%,50.00%,66.67%
+,50.00%,16.67%,66.67%
+d ,1.00,1.00,2.00
+,50.00%,50.00%,100.00%
+,25.00%,50.00%,33.33%
+,16.67%,16.67%,33.33%
+Total,4.00,2.00,6.00
+,66.67%,33.33%,100.00%
+,100.00%,100.00%,100.00%
+,66.67%,33.33%,100.00%
 
 Table: Chi-square tests.
 Statistic,Value,df,Asymp. Sig. (2-tailed),Exact Sig. (2-tailed),Exact Sig. (1-tailed)
@@ -253,18 +253,18 @@ v1 * v2,4,100.0%,0,0.0%,4,100.0%
 "Table: v1 * v2 [count, row %, column %, total %]."
 ,v2,,
 v1,e ,f ,Total
-c ,.0,1.0,1.0
-,.0%,100.0%,100.0%
-,.0%,33.3%,25.0%
-,.0%,25.0%,25.0%
-d ,1.0,2.0,3.0
-,33.3%,66.7%,100.0%
-,100.0%,66.7%,75.0%
-,25.0%,50.0%,75.0%
-Total,1.0,3.0,4.0
-,25.0%,75.0%,100.0%
-,100.0%,100.0%,100.0%
-,25.0%,75.0%,100.0%
+c ,.00,1.00,1.00
+,.00%,100.00%,100.00%
+,.00%,33.33%,25.00%
+,.00%,25.00%,25.00%
+d ,1.00,2.00,3.00
+,33.33%,66.67%,100.00%
+,100.00%,66.67%,75.00%
+,25.00%,50.00%,75.00%
+Total,1.00,3.00,4.00
+,25.00%,75.00%,100.00%
+,100.00%,100.00%,100.00%
+,25.00%,75.00%,100.00%
 
 Table: Chi-square tests.
 Statistic,Value,df,Asymp. Sig. (2-tailed),Exact Sig. (2-tailed),Exact Sig. (1-tailed)
@@ -329,17 +329,17 @@ x * y * z,9,100.0%,0,0.0%,9,100.0%
 Table: x * y * z [count].
 z,,y,,
 ,x,1,2,Total
-1,1,1.0,.0,1.0
-,3,1.0,.0,1.0
-,5,.0,1.0,1.0
-,7,1.0,.0,1.0
-,8,1.0,.0,1.0
-Total,,4.0,1.0,5.0
-2,2,.0,1.0,1.0
-,4,1.0,.0,1.0
-,6,1.0,.0,1.0
-,9,1.0,.0,1.0
-Total,,3.0,1.0,4.0
+1,1,1.00,.00,1.00
+,3,1.00,.00,1.00
+,5,.00,1.00,1.00
+,7,1.00,.00,1.00
+,8,1.00,.00,1.00
+Total,,4.00,1.00,5.00
+2,2,.00,1.00,1.00
+,4,1.00,.00,1.00
+,6,1.00,.00,1.00
+,9,1.00,.00,1.00
+Total,,3.00,1.00,4.00
 
 Table: Chi-square tests.
 z,Statistic,Value,df,Asymp. Sig. (2-tailed)
@@ -433,10 +433,10 @@ x * y,6,100.0%,0,0.0%,6,100.0%
 Table: x * y [count].
 ,y,,
 x,2.00,1.00,Total
-4.00,.0,1.0,1.0
-3.00,2.0,1.0,3.0
-2.00,2.0,.0,2.0
-Total,4.0,2.0,6.0
+4.00,.00,1.00,1.00
+3.00,2.00,1.00,3.00
+2.00,2.00,.00,2.00
+Total,4.00,2.00,6.00
 ]])
 AT_CLEANUP
 
index 9c6be8d38fe3d3225423c4dddaaa6a55a494763a..9cc7ca0515606fa4a6e1cacb041b2a892672d649 100644 (file)
@@ -185,3 +185,94 @@ Variable,N,Mean,Std Dev,Minimum,Maximum
 abc,6,3.00,.84,2.00,4.00
 ])
 AT_CLEANUP
+
+AT_SETUP([DESCRIPTIVES -- Z scores])
+AT_DATA([descriptives.sps], [dnl
+DATA LIST LIST NOTABLE /a b.
+BEGIN DATA.
+1 50
+2 60
+3 70
+END DATA.
+
+DESCRIPTIVES /VAR=a b /SAVE.
+LIST.
+])
+AT_CHECK([pspp -O format=csv descriptives.sps], [0], [dnl
+Table: Mapping of variables to corresponding Z-scores.
+Source,Target
+a,Za
+b,Zb
+
+Table: Valid cases = 3; cases with missing value(s) = 0.
+Variable,N,Mean,Std Dev,Minimum,Maximum
+a,3,2.00,1.00,1.00,3.00
+b,3,60.00,10.00,50.00,70.00
+
+Table: Data List
+a,b,Za,Zb
+1.00,50.00,-1.00,-1.00
+2.00,60.00,.00,.00
+3.00,70.00,1.00,1.00
+])
+AT_CLEANUP
+
+AT_SETUP([DESCRIPTIVES -- Z scores with SPLIT FILE])
+AT_DATA([descriptives.sps], [dnl
+DATA LIST LIST NOTABLE /group a b.
+BEGIN DATA.
+1 1 50
+1 2 60
+1 3 70
+2 100 6000
+2 200 7000
+2 400 9000
+2 500 10000
+END DATA.
+
+SPLIT FILE BY group.
+DESCRIPTIVES /VAR=a b /SAVE.
+LIST.
+])
+AT_CHECK([pspp -O format=csv descriptives.sps], [0], [dnl
+Table: Mapping of variables to corresponding Z-scores.
+Source,Target
+a,Za
+b,Zb
+
+Variable,Value,Label
+group,1.00,
+
+Table: Valid cases = 3; cases with missing value(s) = 0.
+Variable,N,Mean,Std Dev,Minimum,Maximum
+a,3,2.00,1.00,1.00,3.00
+b,3,60.00,10.00,50.00,70.00
+
+Variable,Value,Label
+group,2.00,
+
+Table: Valid cases = 4; cases with missing value(s) = 0.
+Variable,N,Mean,Std Dev,Minimum,Maximum
+a,4,300.00,182.57,100.00,500.00
+b,4,8000.00,1825.74,6000.00,10000.00
+
+Variable,Value,Label
+group,1.00,
+
+Table: Data List
+group,a,b,Za,Zb
+1.00,1.00,50.00,-1.00,-1.00
+1.00,2.00,60.00,.00,.00
+1.00,3.00,70.00,1.00,1.00
+
+Variable,Value,Label
+group,2.00,
+
+Table: Data List
+group,a,b,Za,Zb
+2.00,100.00,6000.00,-1.10,-1.10
+2.00,200.00,7000.00,-.55,-.55
+2.00,400.00,9000.00,.55,.55
+2.00,500.00,10000.00,1.10,1.10
+])
+AT_CLEANUP
index 38e2e7c4c1520e164855fcd22f8ba9be94a34729..f5eb2a404cc803182e338251244afc2eabf67624 100644 (file)
@@ -274,6 +274,28 @@ x,Group1,10.000,10.000,.435,.500,.678
 ])
 AT_CLEANUP
 
+
+
+dnl Test for a bug which caused binomial to crash.
+AT_SETUP([NPAR TESTS BINOMIAL - crash])
+AT_DATA([nparX.sps], [dnl
+data list list /range *.
+begin data.
+0
+1
+end data.
+
+* This is invalid syntax
+NPAR TEST
+       /BINOMIAL(0.5) = Range().
+
+])
+AT_CHECK([pspp -O format=csv nparX.sps], [1], [ignore])
+
+AT_CLEANUP
+
+
+
 AT_SETUP([NPAR TESTS CHISQUARE])
 AT_DATA([npar.sps], [dnl
 DATA LIST NOTABLE LIST /x * y * w *.
index 6cb366849b88da1e6c7664593ee3c2043cb0a93e..04d5accce741d4501b89273a79d65365dc7e7635 100644 (file)
@@ -481,19 +481,19 @@ DELETE VAR ran001 TO ran999.
 LIST.
 ])
 AT_CHECK([pspp -O format=csv rank.sps], [0], [dnl
-"rank.sps:3: warning: BEGIN DATA: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
+"rank.sps:3: warning: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
 
-"rank.sps:4: warning: BEGIN DATA: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
+"rank.sps:4: warning: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
 
-"rank.sps:5: warning: BEGIN DATA: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
+"rank.sps:5: warning: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
 
-"rank.sps:6: warning: BEGIN DATA: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
+"rank.sps:6: warning: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
 
-"rank.sps:7: warning: BEGIN DATA: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
+"rank.sps:7: warning: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
 
-"rank.sps:8: warning: BEGIN DATA: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
+"rank.sps:8: warning: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
 
-"rank.sps:9: warning: BEGIN DATA: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
+"rank.sps:9: warning: Missing value(s) for all variables from rx onward.  These will be filled with the system-missing value or blanks, as appropriate."
 
 Variables Created By RANK
 
index 302e05b1512c912d93e3081980f9b1dcfdc59727..049fc281922acecfb022fcedaf2eaeda53badc00 100644 (file)
@@ -151,6 +151,7 @@ frequencies pos neg pn
 ])
 
 
-AT_CHECK([pspp -O format=csv histogram.sps], [0], [ignore])
+dnl The --testing-mode flag is important!!
+AT_CHECK([pspp --testing-mode -O format=csv histogram.sps], [0], [ignore])
 
 AT_CLEANUP
index 1a22f7a0e85825b363dc046257e235b1d0ac556e..38a88eca14a779174d838d8218ad836f2690c36e 100644 (file)
@@ -34,6 +34,5 @@ include the syntax file that triggered it and a sample
 of any data file used for input.
 proximate cause:     Segmentation Violation
 ])
-AT_CHECK([sed -n '/\*\*\*/,$p
-/proximate/q' < stderr], [0], [expout])
+AT_CHECK([sed '/proximate/q' < stderr], [0], [expout])
 AT_CLEANUP