-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);
-}
-
-
-\f
-
-
-static void
-emit_selected_signal (PsppireDataEditor *de)
-{
- gboolean data_selected = data_is_selected (de);
-
- g_signal_emit (de, data_editor_signals[DATA_SELECTION_CHANGED], 0, data_selected);
-}
-
-
-static void
-on_activate (PsppireDataEditor *de)
-{
- gint row, col;
- psppire_sheet_get_active_cell (PSPPIRE_SHEET (de->data_sheet[0]), &row, &col);
-
-
- if ( row < psppire_data_store_get_case_count (de->data_store)
- &&
- col < psppire_var_store_get_var_cnt (de->var_store))
- {
- emit_selected_signal (de);
- return ;
- }
-
- emit_selected_signal (de);
-}
-
-
-static void
-on_select_range (PsppireDataEditor *de)
-{
- PsppireSheetRange range;
-
- psppire_sheet_get_selected_range (PSPPIRE_SHEET (de->data_sheet[0]), &range);
-
- if ( range.rowi < psppire_data_store_get_case_count (de->data_store)
- &&
- range.coli < psppire_var_store_get_var_cnt (de->var_store))
- {
- emit_selected_signal (de);
- return;
- }
-
- emit_selected_signal (de);
-}
-
-
-static gboolean
-on_switch_page (PsppireDataEditor *de, GtkNotebookPage *p,
- gint pagenum, gpointer data)
-{
- switch (pagenum)
- {
- case PSPPIRE_DATA_EDITOR_DATA_VIEW:
- gtk_widget_grab_focus (de->data_vbox);
- on_select_range (de);
- break;
- case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
- gtk_widget_grab_focus (de->var_sheet);
- emit_selected_signal (de);
- break;
- default:
- break;
- };
-
- return TRUE;
-}
-
-
-
-static gboolean
-data_is_selected (PsppireDataEditor *de)
-{
- PsppireSheetRange range;
- gint row, col;
-
- if ( gtk_notebook_get_current_page (GTK_NOTEBOOK (de)) != PSPPIRE_DATA_EDITOR_DATA_VIEW)
- return FALSE;
-
- psppire_sheet_get_active_cell (PSPPIRE_SHEET (de->data_sheet[0]), &row, &col);
-
- if ( row >= psppire_data_store_get_case_count (de->data_store)
- ||
- col >= psppire_var_store_get_var_cnt (de->var_store))
- {
- return FALSE;
- }
-
- psppire_sheet_get_selected_range (PSPPIRE_SHEET (de->data_sheet[0]), &range);
-
- if ( range.rowi >= psppire_data_store_get_case_count (de->data_store)
- ||
- range.coli >= psppire_var_store_get_var_cnt (de->var_store))
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-static void
-on_select_row (PsppireSheet *sheet, gint row, PsppireDataEditor *de)
-{
- g_signal_emit (de, data_editor_signals[CASES_SELECTED], 0, row);
-}
-
-
-static void
-on_select_variable (PsppireSheet *sheet, gint var, PsppireDataEditor *de)
-{
- g_signal_emit (de, data_editor_signals[VARIABLES_SELECTED], 0, var);
-}
-
-
-\f
-
-/* Clipboard stuff */
-
-
-#include <data/casereader.h>
-#include <data/case-map.h>
-#include <data/casewriter.h>
-
-#include <data/data-out.h>
-#include "xalloc.h"
-
-/* A casereader and dictionary holding the data currently in the clip */
-static struct casereader *clip_datasheet = NULL;
-static struct dictionary *clip_dict = NULL;
-
-
-static void data_sheet_update_clipboard (PsppireSheet *);
-
-/* Set the clip according to the currently
- selected range in the data sheet */
-static void
-data_sheet_set_clip (PsppireSheet *sheet)
-{
- int i;
- struct casewriter *writer ;
- PsppireSheetRange range;
- PsppireDataStore *ds;
- struct case_map *map = NULL;
- casenumber max_rows;
- size_t max_columns;
-
- ds = PSPPIRE_DATA_STORE (psppire_sheet_get_model (sheet));
-
- psppire_sheet_get_selected_range (sheet, &range);
-
- /* If nothing selected, then use active cell */
- if ( range.row0 < 0 || range.col0 < 0 )
- {
- gint row, col;
- psppire_sheet_get_active_cell (sheet, &row, &col);
-
- range.row0 = range.rowi = row;
- range.col0 = range.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 (max_rows == 0)
- return;
- range.rowi = max_rows - 1;
- }
- max_columns = dict_get_var_cnt (ds->dict->dict);
- if (range.coli >= max_columns)
- {
- if (max_columns == 0)
- return;
- range.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 )
- {
- casereader_destroy (clip_datasheet);
- clip_datasheet = NULL;
- }
-
- if ( clip_dict )
- {
- dict_destroy (clip_dict);
- clip_dict = NULL;
- }
-
- /* 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));
- }
-
- /* 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 )
- {
- struct ccase *old = psppire_data_store_get_case (ds, i);
- if (old != NULL)
- casewriter_write (writer, case_map_execute (map, old));
- else
- casewriter_force_error (writer);
- }
- case_map_destroy (map);
-
- clip_datasheet = casewriter_make_reader (writer);
-
- data_sheet_update_clipboard (sheet);
-}
-
-enum {
- SELECT_FMT_NULL,
- SELECT_FMT_TEXT,
- SELECT_FMT_HTML
-};
-
-
-/* Perform data_out for case CC, variable V, appending to STRING */
-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);
-
- g_string_append_len (string, buf, fs->w);
-
- g_free (buf);
-}
-
-static GString *
-clip_to_text (void)
-{
- casenumber r;
- GString *string;
-
- const size_t val_cnt = casereader_get_value_cnt (clip_datasheet);
- const casenumber case_cnt = casereader_get_case_cnt (clip_datasheet);
- const size_t var_cnt = dict_get_var_cnt (clip_dict);
-
- string = g_string_sized_new (10 * val_cnt * case_cnt);
-
- for (r = 0 ; r < case_cnt ; ++r )
- {
- int c;
- struct ccase *cc;
-
- cc = casereader_peek (clip_datasheet, r);
- if (cc == NULL)
- {
- g_warning ("Clipboard seems to have inexplicably shrunk");
- break;
- }
-
- for (c = 0 ; c < var_cnt ; ++c)
- {
- const struct variable *v = dict_get_var (clip_dict, c);
- data_out_g_string (string, v, cc);
- if ( c < val_cnt - 1 )
- g_string_append (string, "\t");
- }
-
- if ( r < case_cnt)
- g_string_append (string, "\n");
-
- case_unref (cc);
- }
-
- return string;
-}
-
-
-static GString *
-clip_to_html (void)
-{
- casenumber r;
- GString *string;
-
- const size_t val_cnt = casereader_get_value_cnt (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);
-
- g_string_append (string, "<table>\n");
- for (r = 0 ; r < case_cnt ; ++r )
- {
- int c;
- struct ccase *cc = casereader_peek (clip_datasheet, r);
- if (cc == NULL)
- {
- g_warning ("Clipboard seems to have inexplicably shrunk");
- break;
- }
- g_string_append (string, "<tr>\n");
-
- for (c = 0 ; c < var_cnt ; ++c)
- {
- const struct variable *v = dict_get_var (clip_dict, c);
- g_string_append (string, "<td>");
- data_out_g_string (string, v, cc);
- g_string_append (string, "</td>\n");
- }
-
- g_string_append (string, "</tr>\n");
-
- case_unref (cc);
- }
- g_string_append (string, "</table>\n");
-
- return string;
-}
-
-
-
-static void
-clipboard_get_cb (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- guint info,
- gpointer data)