X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=src%2Fui%2Fgui%2Fpsppire-data-editor.c;h=02ef97a9077b1907958a867c611e419751c942b9;hb=5166b8309e1fec33d5122de360ba212ad3107a2c;hp=1070f5c2871caef36db153d9b48aca7667497ad3;hpb=d6ede2e8f16079edae2e308583f8af4f7e9daddd;p=pspp
diff --git a/src/ui/gui/psppire-data-editor.c b/src/ui/gui/psppire-data-editor.c
index 1070f5c287..02ef97a907 100644
--- a/src/ui/gui/psppire-data-editor.c
+++ b/src/ui/gui/psppire-data-editor.c
@@ -1,5 +1,5 @@
/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2008, 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
@@ -15,17 +15,16 @@
along with this program. If not, see . */
#include
-#include
#include
#include
#include "psppire-data-editor.h"
#include "psppire-var-sheet.h"
+#include "psppire.h"
-#include
#include "psppire-data-store.h"
-#include
#include
-#include "helper.h"
+#include
+#include "executor.h"
#include
#include
@@ -196,6 +195,7 @@ traverse_cell_callback (PsppireSheet *sheet,
enum
{
PROP_0,
+ PROP_DATA_WINDOW,
PROP_DATA_STORE,
PROP_VAR_STORE,
PROP_VS_ROW_MENU,
@@ -221,9 +221,16 @@ new_data_callback (PsppireDataStore *ds, gpointer data)
for (i = 0; i < 2; ++i)
{
- psppire_axis_impl_clear (de->vaxis[i]);
- psppire_axis_impl_append_n (de->vaxis[i], n_cases, DEFAULT_ROW_HEIGHT);
+ psppire_axis_clear (de->vaxis[i]);
+ psppire_axis_append_n (de->vaxis[i], n_cases, DEFAULT_ROW_HEIGHT);
}
+
+ /* All of the data (potentially) changed, so unselect any selected cell(s) in
+ the data sheets. If we don't do this, then the sheet remembers the value
+ that was in the selected cell and stores it back, wiping out whatever
+ value there is in the new data. Bug #30502. */
+ if (de->data_sheet[0] != NULL)
+ psppire_sheet_unselect_range (PSPPIRE_SHEET (de->data_sheet[0]));
}
static void
@@ -233,7 +240,7 @@ case_inserted_callback (PsppireDataStore *ds, gint before, gpointer data)
PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
for (i = 0; i < 2; ++i)
- psppire_axis_impl_insert (de->vaxis[i], before, DEFAULT_ROW_HEIGHT);
+ psppire_axis_insert (de->vaxis[i], before, DEFAULT_ROW_HEIGHT);
}
@@ -244,7 +251,7 @@ cases_deleted_callback (PsppireDataStore *ds, gint first, gint n_cases, gpointer
PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
for (i = 0; i < 2; ++i)
- psppire_axis_impl_delete (de->vaxis[0], first, n_cases);
+ psppire_axis_delete (de->vaxis[0], first, n_cases);
}
@@ -289,22 +296,22 @@ new_variables_callback (PsppireDict *dict, gpointer data)
PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
gint m_width = width_of_m (GTK_WIDGET (de));
- PsppireAxisImpl *vaxis;
+ PsppireAxis *vaxis;
g_object_get (de->var_sheet, "vertical-axis", &vaxis, NULL);
- psppire_axis_impl_clear (vaxis);
- psppire_axis_impl_append_n (vaxis, 1 + psppire_dict_get_var_cnt (dict), DEFAULT_ROW_HEIGHT);
+ psppire_axis_clear (vaxis);
+ psppire_axis_append_n (vaxis, 1 + psppire_dict_get_var_cnt (dict), DEFAULT_ROW_HEIGHT);
g_signal_connect_swapped (de->haxis, "resize-unit",
G_CALLBACK (rewidth_variable), de);
- psppire_axis_impl_clear (de->haxis);
+ psppire_axis_clear (de->haxis);
for (v = 0 ; v < psppire_dict_get_var_cnt (dict); ++v)
{
const struct variable *var = psppire_dict_get_variable (dict, v);
- psppire_axis_impl_append (de->haxis, m_width * var_get_display_width (var));
+ psppire_axis_append (de->haxis, m_width * var_get_display_width (var));
}
}
@@ -315,31 +322,32 @@ insert_variable_callback (PsppireDict *dict, gint x, gpointer data)
gint m_width = width_of_m (GTK_WIDGET (de));
- PsppireAxisImpl *var_vaxis;
+ PsppireAxis *var_vaxis;
const struct variable *var = psppire_dict_get_variable (dict, x);
g_object_get (de->var_sheet, "vertical-axis", &var_vaxis, NULL);
- psppire_axis_impl_insert (var_vaxis, x, DEFAULT_ROW_HEIGHT);
+ psppire_axis_insert (var_vaxis, x, DEFAULT_ROW_HEIGHT);
- psppire_axis_impl_insert (de->haxis, x, m_width * var_get_display_width (var));
+ psppire_axis_insert (de->haxis, x, m_width * var_get_display_width (var));
}
static void
-delete_variable_callback (PsppireDict *dict, gint posn,
- gint x UNUSED, gint y UNUSED, gpointer data)
+delete_variable_callback (PsppireDict *dict,
+ const struct variable *var UNUSED,
+ gint dict_idx, gint case_idx UNUSED, gpointer data)
{
PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
- PsppireAxisImpl *var_vaxis;
+ PsppireAxis *var_vaxis;
g_object_get (de->var_sheet, "vertical-axis", &var_vaxis, NULL);
- psppire_axis_impl_delete (var_vaxis, posn, 1);
+ psppire_axis_delete (var_vaxis, dict_idx, 1);
- psppire_axis_impl_delete (de->haxis, posn, 1);
+ psppire_axis_delete (de->haxis, dict_idx, 1);
}
@@ -357,7 +365,7 @@ rewidth_variable_callback (PsppireDict *dict, gint posn, gpointer data)
if ( var_width < 1 )
var_width = 1;
- psppire_axis_impl_resize (de->haxis, posn, m_width * var_width);
+ psppire_axis_resize (de->haxis, posn, m_width * var_width);
}
@@ -375,6 +383,11 @@ psppire_data_editor_set_property (GObject *object,
case PROP_SPLIT_WINDOW:
psppire_data_editor_split_window (de, g_value_get_boolean (value));
break;
+ case PROP_DATA_WINDOW:
+ /* We hold no reference to this object, since it is used only by do_sort,
+ and that cannot be called unless the window is realized. */
+ de->data_window = g_value_get_pointer (value);
+ break;
case PROP_DATA_STORE:
if ( de->data_store) g_object_unref (de->data_store);
de->data_store = g_value_get_pointer (value);
@@ -502,6 +515,9 @@ psppire_data_editor_get_property (GObject *object,
case PROP_SPLIT_WINDOW:
g_value_set_boolean (value, de->split);
break;
+ case PROP_DATA_WINDOW:
+ g_value_set_pointer (value, de->data_window);
+ break;
case PROP_DATA_STORE:
g_value_set_pointer (value, de->data_store);
break;
@@ -535,6 +551,7 @@ psppire_data_editor_get_property (GObject *object,
static void
psppire_data_editor_class_init (PsppireDataEditorClass *klass)
{
+ GParamSpec *data_window_spec ;
GParamSpec *data_store_spec ;
GParamSpec *var_store_spec ;
GParamSpec *column_menu_spec;
@@ -557,6 +574,16 @@ psppire_data_editor_class_init (PsppireDataEditorClass *klass)
+ data_window_spec =
+ g_param_spec_pointer ("data-window",
+ "Data Window",
+ "A pointer to the data window associated with this editor",
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_READABLE );
+
+ g_object_class_install_property (object_class,
+ PROP_DATA_WINDOW,
+ data_window_spec);
+
data_store_spec =
g_param_spec_pointer ("data-store",
"Data Store",
@@ -744,15 +771,10 @@ update_data_ref_entry (const PsppireSheet *sheet,
gchar *text = g_strdup_printf ("%d: %s", row + FIRST_CASE_NUMBER,
var_get_name (var));
- gchar *s = recode_string (UTF8,
- psppire_dict_encoding (data_store->dict),
- text, -1);
-
- g_free (text);
- gtk_entry_set_text (GTK_ENTRY (de->cell_ref_entry), s);
+ gtk_entry_set_text (GTK_ENTRY (de->cell_ref_entry), text);
- g_free (s);
+ g_free (text);
}
else
goto blank_entry;
@@ -825,8 +847,8 @@ on_map (GtkWidget *w)
static void
init_sheet (PsppireDataEditor *de, int i,
GtkAdjustment *hadj, GtkAdjustment *vadj,
- PsppireAxisImpl *vaxis,
- PsppireAxisImpl *haxis
+ PsppireAxis *vaxis,
+ PsppireAxis *haxis
)
{
de->sheet_bin[i] = gtk_scrolled_window_new (hadj, vadj);
@@ -862,12 +884,12 @@ init_data_sheet (PsppireDataEditor *de)
GtkAdjustment *vadj1, *hadj1;
GtkWidget *sheet ;
- de->vaxis[0] = psppire_axis_impl_new ();
- de->vaxis[1] = psppire_axis_impl_new ();
+ de->vaxis[0] = psppire_axis_new ();
+ de->vaxis[1] = psppire_axis_new ();
/* There's only one horizontal axis, since the
column widths are parameters of the variables */
- de->haxis = psppire_axis_impl_new ();
+ de->haxis = psppire_axis_new ();
de->split = TRUE;
de->paned = gtk_xpaned_new ();
@@ -1014,13 +1036,15 @@ psppire_data_editor_init (PsppireDataEditor *de)
GtkWidget*
-psppire_data_editor_new (PsppireVarStore *var_store,
+psppire_data_editor_new (PsppireDataWindow *data_window,
+ PsppireVarStore *var_store,
PsppireDataStore *data_store)
{
return g_object_new (PSPPIRE_DATA_EDITOR_TYPE,
- "var-store", var_store,
- "data-store", data_store,
- NULL);
+ "data-window", data_window,
+ "var-store", var_store,
+ "data-store", data_store,
+ NULL);
}
@@ -1208,9 +1232,13 @@ popup_variable_row_menu (PsppireSheet *sheet, gint row,
PsppireVarStore *var_store =
PSPPIRE_VAR_STORE (psppire_sheet_get_model (sheet));
+
+ PsppireDict *dict;
+ const struct variable *v ;
- const struct variable *v =
- psppire_dict_get_variable (var_store->dict, row);
+ g_object_get (var_store, "dictionary", &dict, NULL);
+
+ v = psppire_dict_get_variable (dict, row);
if ( v && event->button == 3)
{
@@ -1248,23 +1276,15 @@ popup_cases_menu (PsppireSheet *sheet, gint row,
/* Sorting */
static void
-do_sort (PsppireDataStore *ds, int var, gboolean descend)
+do_sort (PsppireDataEditor *de, int var, gboolean descend)
{
- GString *string = g_string_new ("SORT CASES BY ");
-
- const struct variable *v =
- psppire_dict_get_variable (ds->dict, var);
-
- g_string_append_printf (string, "%s", var_get_name (v));
-
- if ( descend )
- g_string_append (string, " (D)");
+ const struct variable *v
+ = psppire_dict_get_variable (de->data_store->dict, var);
+ gchar *syntax;
- g_string_append (string, ".");
-
- execute_syntax (create_syntax_string_source (string->str));
-
- g_string_free (string, TRUE);
+ syntax = g_strdup_printf ("SORT CASES BY %s%s.",
+ var_get_name (v), descend ? " (D)" : "");
+ g_free (execute_syntax_string (de->data_window, syntax));
}
@@ -1276,7 +1296,7 @@ psppire_data_editor_sort_ascending (PsppireDataEditor *de)
PsppireSheetRange range;
psppire_sheet_get_selected_range (PSPPIRE_SHEET(de->data_sheet[0]), &range);
- do_sort (de->data_store, range.col0, FALSE);
+ do_sort (de, range.col0, FALSE);
}
@@ -1288,7 +1308,7 @@ psppire_data_editor_sort_descending (PsppireDataEditor *de)
PsppireSheetRange range;
psppire_sheet_get_selected_range (PSPPIRE_SHEET(de->data_sheet[0]), &range);
- do_sort (de->data_store, range.col0, TRUE);
+ do_sort (de, range.col0, TRUE);
}
@@ -1304,13 +1324,15 @@ psppire_data_editor_insert_variable (PsppireDataEditor *de)
switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (de)))
{
case PSPPIRE_DATA_EDITOR_DATA_VIEW:
- if ( de->data_sheet[0]->state == PSPPIRE_SHEET_COLUMN_SELECTED )
+ if ( PSPPIRE_SHEET (de->data_sheet[0])->select_status
+ == PSPPIRE_SHEET_COLUMN_SELECTED )
posn = PSPPIRE_SHEET (de->data_sheet[0])->range.col0;
else
posn = PSPPIRE_SHEET (de->data_sheet[0])->active_cell.col;
break;
case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
- if ( de->var_sheet->state == PSPPIRE_SHEET_ROW_SELECTED )
+ if ( PSPPIRE_SHEET (de->var_sheet)->select_status
+ == PSPPIRE_SHEET_ROW_SELECTED )
posn = PSPPIRE_SHEET (de->var_sheet)->range.row0;
else
posn = PSPPIRE_SHEET (de->var_sheet)->active_cell.row;
@@ -1329,10 +1351,14 @@ psppire_data_editor_insert_case (PsppireDataEditor *de)
{
glong posn = -1;
- if ( de->data_sheet[0]->state == PSPPIRE_SHEET_ROW_SELECTED )
- posn = PSPPIRE_SHEET (de->data_sheet[0])->range.row0;
+ if ( PSPPIRE_SHEET (de->data_sheet[0])->select_status == PSPPIRE_SHEET_ROW_SELECTED )
+ {
+ posn = PSPPIRE_SHEET (de->data_sheet[0])->range.row0;
+ }
else
- posn = PSPPIRE_SHEET (de->data_sheet[0])->active_cell.row;
+ {
+ posn = PSPPIRE_SHEET (de->data_sheet[0])->active_cell.row;
+ }
if ( posn == -1 ) posn = 0;
@@ -1356,6 +1382,7 @@ psppire_data_editor_delete_cases (PsppireDataEditor *de)
void
psppire_data_editor_delete_variables (PsppireDataEditor *de)
{
+ PsppireDict *dict = NULL;
gint first, n;
switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (de)))
@@ -1373,7 +1400,9 @@ psppire_data_editor_delete_variables (PsppireDataEditor *de)
break;
}
- psppire_dict_delete_variables (de->var_store->dict, first, n);
+ g_object_get (de->var_store, "dictionary", &dict, NULL);
+
+ psppire_dict_delete_variables (dict, first, n);
psppire_sheet_unselect_range (PSPPIRE_SHEET (de->data_sheet[0]));
psppire_sheet_unselect_range (PSPPIRE_SHEET (de->var_sheet));
@@ -1407,7 +1436,6 @@ void
psppire_data_editor_set_font (PsppireDataEditor *de, PangoFontDescription *font_desc)
{
set_font (GTK_WIDGET (de), font_desc);
- gtk_container_foreach (GTK_CONTAINER (de), set_font, font_desc);
}
@@ -1560,43 +1588,45 @@ data_sheet_set_clip (PsppireSheet *sheet)
struct case_map *map = NULL;
casenumber max_rows;
size_t max_columns;
+ gint row0, rowi;
+ gint col0, coli;
ds = PSPPIRE_DATA_STORE (psppire_sheet_get_model (sheet));
psppire_sheet_get_selected_range (sheet, &range);
+ col0 = MIN (range.col0, range.coli);
+ coli = MAX (range.col0, range.coli);
+ row0 = MIN (range.row0, range.rowi);
+ rowi = MAX (range.row0, range.rowi);
+
/* If nothing selected, then use active cell */
- if ( range.row0 < 0 || range.col0 < 0 )
+ if ( row0 < 0 || col0 < 0 )
{
gint row, col;
psppire_sheet_get_active_cell (sheet, &row, &col);
- range.row0 = range.rowi = row;
- range.col0 = range.coli = col;
+ row0 = rowi = row;
+ col0 = coli = col;
}
/* The sheet range can include cells that do not include data.
Exclude them from the range. */
max_rows = psppire_data_store_get_case_count (ds);
- if (range.rowi >= max_rows)
+ if (rowi >= max_rows)
{
if (max_rows == 0)
return;
- range.rowi = max_rows - 1;
+ rowi = max_rows - 1;
}
max_columns = dict_get_var_cnt (ds->dict->dict);
- if (range.coli >= max_columns)
+ if (coli >= max_columns)
{
if (max_columns == 0)
return;
- range.coli = max_columns - 1;
+ coli = max_columns - 1;
}
- g_return_if_fail (range.rowi >= range.row0);
- g_return_if_fail (range.row0 >= 0);
- g_return_if_fail (range.coli >= range.col0);
- g_return_if_fail (range.col0 >= 0);
-
/* Destroy any existing clip */
if ( clip_datasheet )
{
@@ -1611,17 +1641,14 @@ data_sheet_set_clip (PsppireSheet *sheet)
}
/* Construct clip dictionary. */
- clip_dict = dict_create ();
- for (i = range.col0; i <= range.coli; i++)
- {
- const struct variable *old = dict_get_var (ds->dict->dict, i);
- dict_clone_var_assert (clip_dict, old, var_get_name (old));
- }
+ clip_dict = dict_create (dict_get_encoding (ds->dict->dict));
+ for (i = col0; i <= coli; i++)
+ dict_clone_var_assert (clip_dict, dict_get_var (ds->dict->dict, i));
/* Construct clip data. */
map = case_map_by_name (ds->dict->dict, clip_dict);
- writer = autopaging_writer_create (dict_get_next_value_idx (clip_dict));
- for (i = range.row0; i <= range.rowi ; ++i )
+ writer = autopaging_writer_create (dict_get_proto (clip_dict));
+ for (i = row0; i <= rowi ; ++i )
{
struct ccase *old = psppire_data_store_get_case (ds, i);
if (old != NULL)
@@ -1648,17 +1675,14 @@ static void
data_out_g_string (GString *string, const struct variable *v,
const struct ccase *cc)
{
- char *buf ;
-
const struct fmt_spec *fs = var_get_print_format (v);
const union value *val = case_data (cc, v);
- buf = xzalloc (fs->w);
- data_out (val, fs, buf);
+ char *s = data_out (val, var_get_encoding (v), fs);
- g_string_append_len (string, buf, fs->w);
+ g_string_append (string, s);
- g_free (buf);
+ g_free (s);
}
static GString *
@@ -1667,7 +1691,7 @@ clip_to_text (void)
casenumber r;
GString *string;
- const size_t val_cnt = casereader_get_value_cnt (clip_datasheet);
+ const size_t val_cnt = caseproto_get_n_widths (casereader_get_proto (clip_datasheet));
const casenumber case_cnt = casereader_get_case_cnt (clip_datasheet);
const size_t var_cnt = dict_get_var_cnt (clip_dict);
@@ -1709,13 +1733,15 @@ clip_to_html (void)
casenumber r;
GString *string;
- const size_t val_cnt = casereader_get_value_cnt (clip_datasheet);
+ const size_t val_cnt = caseproto_get_n_widths (casereader_get_proto (clip_datasheet));
const casenumber case_cnt = casereader_get_case_cnt (clip_datasheet);
const size_t var_cnt = dict_get_var_cnt (clip_dict);
-
/* Guestimate the size needed */
- string = g_string_sized_new (20 * val_cnt * case_cnt);
+ string = g_string_sized_new (80 + 20 * val_cnt * case_cnt);
+
+ g_string_append (string,
+ "\n");
g_string_append (string, "\n");
for (r = 0 ; r < case_cnt ; ++r )