/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2009 Free Software Foundation
+ Copyright (C) 2009, 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
#include <config.h>
#include "dialog-common.h"
-#include <language/syntax-string-source.h>
#include <ui/syntax-gen.h>
#include <libpspp/str.h>
{
gdouble mineigen;
gint n_factors;
- gint iterations;
+ gint n_iterations;
gboolean explicit_nfactors;
gboolean covariance;
gboolean paf;
};
+enum rotation_type {
+ ROT_NONE,
+ ROT_VARIMAX,
+ ROT_QUARTIMAX,
+ ROT_EQUIMAX
+};
+
+static const char *rot_method_syntax[] =
+ {
+ "NOROTATE",
+ "VARIMAX",
+ "QUARTIMAX",
+ "EQUAMAX"
+ };
+
+struct rotation_parameters
+{
+ gboolean rotated_solution;
+ gint iterations;
+
+ enum rotation_type method;
+};
+
+
static const struct extraction_parameters default_extraction_parameters = {1.0, 0, 25, FALSE, TRUE, FALSE, TRUE, FALSE};
+static const struct rotation_parameters default_rotation_parameters = {TRUE, 25, ROT_VARIMAX};
+
struct factor
{
GtkBuilder *xml;
/* The Extraction subdialog */
GtkWidget *extraction_dialog;
+ GtkWidget *rotation_dialog;
GtkWidget *n_factors;
GtkWidget *mineigen;
- GtkWidget *iterations;
+ GtkWidget *extract_iterations;
GtkWidget *nfactors_toggle;
GtkWidget *mineigen_toggle;
GtkWidget *extraction_combo;
+
+ /* Rotation Widgets */
+ GtkWidget *rotate_iterations;
+ GtkWidget *display_rotated_solution;
+ GtkWidget *rotation_none;
+ GtkWidget *rotation_varimax;
+ GtkWidget *rotation_quartimax;
+ GtkWidget *rotation_equimax;
+
+
struct extraction_parameters extraction;
+ struct rotation_parameters rotation;
};
+static void
+load_rotation_parameters (struct factor *fd, const struct rotation_parameters *p)
+{
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->display_rotated_solution),
+ p->rotated_solution);
+
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (fd->rotate_iterations),
+ p->iterations);
+
+ switch (p->method)
+ {
+ case ROT_NONE:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->rotation_none), TRUE);
+ break;
+ case ROT_VARIMAX:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->rotation_varimax), TRUE);
+ break;
+ case ROT_QUARTIMAX:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->rotation_quartimax), TRUE);
+ break;
+ case ROT_EQUIMAX:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->rotation_equimax), TRUE);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
static void
load_extraction_parameters (struct factor *fd, const struct extraction_parameters *p)
{
gtk_spin_button_set_value (GTK_SPIN_BUTTON (fd->mineigen), p->mineigen);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (fd->n_factors), p->n_factors);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (fd->iterations), p->iterations);
+
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (fd->extract_iterations), p->n_iterations);
+
if (p->explicit_nfactors)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fd->nfactors_toggle), TRUE);
}
static void
-set_extraction_parameters (struct extraction_parameters *p, const struct factor *fd)
+set_rotation_parameters (const struct factor *fd, struct rotation_parameters *p)
+{
+ p->iterations = gtk_spin_button_get_value (GTK_SPIN_BUTTON (fd->rotate_iterations));
+ p->rotated_solution = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->display_rotated_solution));
+
+
+ if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->rotation_none)))
+ p->method = ROT_NONE;
+
+ if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->rotation_varimax)))
+ p->method = ROT_VARIMAX;
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->rotation_quartimax)))
+ p->method = ROT_QUARTIMAX;
+
+ if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->rotation_equimax)))
+ p->method = ROT_EQUIMAX;
+}
+
+static void
+set_extraction_parameters (const struct factor *fd, struct extraction_parameters *p)
{
p->mineigen = gtk_spin_button_get_value (GTK_SPIN_BUTTON (fd->mineigen));
p->n_factors = gtk_spin_button_get_value (GTK_SPIN_BUTTON (fd->n_factors));
- p->iterations = gtk_spin_button_get_value (GTK_SPIN_BUTTON (fd->iterations));
+ p->n_iterations = gtk_spin_button_get_value (GTK_SPIN_BUTTON (fd->extract_iterations));
p->explicit_nfactors = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->nfactors_toggle));
p->covariance = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fd->covariance_toggle));
p->paf = (gtk_combo_box_get_active (GTK_COMBO_BOX (fd->extraction_combo)) == 1);
}
-static void run_extractions_subdialog (struct factor *fd)
+static void
+run_extractions_subdialog (struct factor *fd)
{
struct extraction_parameters *ex = &fd->extraction;
if ( response == PSPPIRE_RESPONSE_CONTINUE )
{
/* Set the parameters from their respective widgets */
- set_extraction_parameters (ex, fd);
+ set_extraction_parameters (fd, ex);
}
else
{
}
}
+static void
+run_rotations_subdialog (struct factor *fd)
+{
+ struct rotation_parameters *rot = &fd->rotation;
+
+ gint response = psppire_dialog_run (PSPPIRE_DIALOG (fd->rotation_dialog));
+
+ if ( response == PSPPIRE_RESPONSE_CONTINUE )
+ {
+ /* Set the parameters from their respective widgets */
+ set_rotation_parameters (fd, rot);
+ }
+ else
+ {
+ /* Cancelled. Reset the widgets to their old state */
+ load_rotation_parameters (fd, rot);
+ }
+}
+
static char * generate_syntax (const struct factor *rd);
gtk_list_store_clear (GTK_LIST_STORE (liststore));
load_extraction_parameters (fd, &default_extraction_parameters);
+ load_rotation_parameters (fd, &default_rotation_parameters);
}
/* Pops up the Factor dialog box */
void
-factor_dialog (GObject *o, gpointer data)
+factor_dialog (PsppireDataWindow *dw)
{
struct factor fd;
gint response;
GtkWidget *dialog ;
GtkWidget *source ;
GtkWidget *extraction_button ;
+ GtkWidget *rotation_button ;
fd.xml = builder_new ("factor.ui");
fd.extraction = default_extraction_parameters;
+ fd.rotation = default_rotation_parameters;
dialog = get_widget_assert (fd.xml, "factor-dialog");
source = get_widget_assert (fd.xml, "dict-view");
- extraction_button = get_widget_assert (fd.xml, "button-extraction");
+ extraction_button = get_widget_assert (fd.xml, "button-extractions");
+ rotation_button = get_widget_assert (fd.xml, "button-rotations");
fd.extraction_dialog = get_widget_assert (fd.xml, "extractions-dialog");
+ fd.rotation_dialog = get_widget_assert (fd.xml, "rotations-dialog");
- fd.de = PSPPIRE_DATA_WINDOW (data);
+ fd.de = dw;
g_signal_connect_swapped (dialog, "refresh", G_CALLBACK (refresh), &fd);
fd.nfactors_toggle = get_widget_assert (fd.xml, "nfactors-radiobutton");
fd.mineigen_toggle = get_widget_assert (fd.xml, "mineigen-radiobutton");
fd.n_factors = get_widget_assert (fd.xml, "spinbutton-nfactors");
- fd.iterations = get_widget_assert (fd.xml, "spinbutton-iterations");
+ fd.extract_iterations = get_widget_assert (fd.xml, "spinbutton-extract-iterations");
fd.covariance_toggle = get_widget_assert (fd.xml, "covariance-radiobutton");
fd.correlation_toggle = get_widget_assert (fd.xml, "correlations-radiobutton");
gtk_widget_show_all (eigenvalue_extraction);
}
+ {
+ fd.rotate_iterations = get_widget_assert (fd.xml, "spinbutton-rot-iterations");
+
+ fd.display_rotated_solution = get_widget_assert (fd.xml, "checkbutton-rotated-solution");
+
+ fd.rotation_none = get_widget_assert (fd.xml, "radiobutton-none");
+ fd.rotation_varimax = get_widget_assert (fd.xml, "radiobutton-varimax");
+ fd.rotation_quartimax = get_widget_assert (fd.xml, "radiobutton-quartimax");
+ fd.rotation_equimax = get_widget_assert (fd.xml, "radiobutton-equimax");
+ }
+
g_signal_connect_swapped (extraction_button, "clicked", G_CALLBACK (run_extractions_subdialog), &fd);
+ g_signal_connect_swapped (rotation_button, "clicked", G_CALLBACK (run_rotations_subdialog), &fd);
g_signal_connect_swapped (fd.extraction_dialog, "show", G_CALLBACK (on_show), &fd);
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fd.de));
gtk_window_set_transient_for (GTK_WINDOW (fd.extraction_dialog), GTK_WINDOW (fd.de));
+ gtk_window_set_transient_for (GTK_WINDOW (fd.rotation_dialog), GTK_WINDOW (fd.de));
g_object_get (vs, "dictionary", &fd.dict, NULL);
g_object_set (source, "model", fd.dict, NULL);
switch (response)
{
case GTK_RESPONSE_OK:
- {
- gchar *syntax = generate_syntax (&fd);
-
- struct getl_interface *sss = create_syntax_string_source (syntax);
- execute_syntax (sss);
-
- g_free (syntax);
- }
+ g_free (execute_syntax_string (generate_syntax (&fd)));
break;
case PSPPIRE_RESPONSE_PASTE:
- {
- gchar *syntax = generate_syntax (&fd);
- paste_syntax_in_new_window (syntax);
-
- g_free (syntax);
- }
+ g_free (paste_syntax_to_window (generate_syntax (&fd)));
break;
default:
break;
psppire_var_view_append_names (PSPPIRE_VAR_VIEW (rd->variables), 0, string);
+
+ g_string_append (string, "\n\t/CRITERIA = ");
+ if ( rd->extraction.explicit_nfactors )
+ g_string_append_printf (string, "FACTORS (%d)", rd->extraction.n_factors);
+ else
+ g_string_append_printf (string, "MINEIGEN (%g)", rd->extraction.mineigen);
+
+ /*
+ The CRITERIA = ITERATE subcommand is overloaded.
+ It applies to the next /ROTATION and/or EXTRACTION command whatever comes first.
+ */
+ g_string_append_printf (string, " ITERATE (%d)", rd->extraction.n_iterations);
+
+
g_string_append (string, "\n\t/EXTRACTION =");
if ( rd->extraction.paf)
g_string_append (string, "PAF");
g_string_append (string, "PC");
+
+
g_string_append (string, "\n\t/METHOD = ");
if ( rd->extraction.covariance )
g_string_append (string, "COVARIANCE");
g_string_append (string, "CORRELATION");
- g_string_append (string, "\n\t/CRITERIA = ");
- if ( rd->extraction.explicit_nfactors )
- g_string_append_printf (string, "FACTORS (%d)", rd->extraction.n_factors);
- else
- g_string_append_printf (string, "MINEIGEN (%g)", rd->extraction.mineigen);
-
if ( rd->extraction.scree )
{
g_string_append (string, "\n\t/PRINT = ");
g_string_append (string, "INITIAL ");
+
if ( rd->extraction.unrotated )
g_string_append (string, "EXTRACTION ");
+ if ( rd->rotation.rotated_solution )
+ g_string_append (string, "ROTATION");
+
+
+ /* The CRITERIA = ITERATE subcommand is overloaded.
+ It applies to the next /ROTATION and/or EXTRACTION command whatever comes first.
+ */
+ g_string_append_printf (string, "\n\t/CRITERIA = ITERATE (%d)", rd->rotation.iterations );
+
+ g_string_append (string, "\n\t/ROTATION = ");
+ g_string_append (string, rot_method_syntax[rd->rotation.method]);
+
g_string_append (string, ".\n");