[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Pspp-cvs] pspp/src data/ChangeLog data/dictionary.c data/...
From: |
Ben Pfaff |
Subject: |
[Pspp-cvs] pspp/src data/ChangeLog data/dictionary.c data/... |
Date: |
Mon, 13 Aug 2007 04:31:44 +0000 |
CVSROOT: /cvsroot/pspp
Module name: pspp
Changes by: Ben Pfaff <blp> 07/08/13 04:31:44
Modified files:
src/data : ChangeLog dictionary.c dictionary.h
src/ui/gui : ChangeLog automake.mk data-editor.c
data-editor.glade
Added files:
src/ui/gui : clipboard.c clipboard.h
Log message:
Patch #6117: Implement clipboard for data sheet.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/ChangeLog?cvsroot=pspp&r1=1.153&r2=1.154
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/dictionary.c?cvsroot=pspp&r1=1.43&r2=1.44
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/dictionary.h?cvsroot=pspp&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/ChangeLog?cvsroot=pspp&r1=1.78&r2=1.79
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/automake.mk?cvsroot=pspp&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/data-editor.c?cvsroot=pspp&r1=1.45&r2=1.46
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/data-editor.glade?cvsroot=pspp&r1=1.30&r2=1.31
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/clipboard.c?cvsroot=pspp&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/gui/clipboard.h?cvsroot=pspp&rev=1.1
Patches:
Index: data/ChangeLog
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/ChangeLog,v
retrieving revision 1.153
retrieving revision 1.154
diff -u -b -r1.153 -r1.154
--- data/ChangeLog 13 Aug 2007 04:23:28 -0000 1.153
+++ data/ChangeLog 13 Aug 2007 04:31:43 -0000 1.154
@@ -1,5 +1,9 @@
2007-08-12 Ben Pfaff <address@hidden>
+ * dictionary.c (dict_dump): New function.
+
+2007-08-12 Ben Pfaff <address@hidden>
+
Drop dict_compactor in favor of using the new struct case_map.
* dictionary.c (struct copy_map): Removed.
Index: data/dictionary.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/dictionary.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -b -r1.43 -r1.44
--- data/dictionary.c 13 Aug 2007 04:23:29 -0000 1.43
+++ data/dictionary.c 13 Aug 2007 04:31:43 -0000 1.44
@@ -63,6 +63,23 @@
void *cb_data ; /* Data passed to callbacks */
};
+/* Print a representation of dictionary D to stdout, for
+ debugging purposes. */
+void
+dict_dump (const struct dictionary *d)
+{
+ int i;
+ for (i = 0 ; i < d->var_cnt ; ++i )
+ {
+ const struct variable *v =
+ d->var[i];
+ printf ("Name: %s;\tdict_idx: %d; case_idx: %d\n",
+ var_get_name (v),
+ var_get_dict_index (v),
+ var_get_case_index (v));
+
+ }
+}
/* Associate CALLBACKS with DICT. Callbacks will be invoked whenever
the dictionary or any of the variables it contains are modified.
Index: data/dictionary.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/dictionary.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- data/dictionary.h 13 Aug 2007 04:23:29 -0000 1.20
+++ data/dictionary.h 13 Aug 2007 04:31:43 -0000 1.21
@@ -140,4 +140,6 @@
const char *name);
void dict_clear_vectors (struct dictionary *);
+void dict_dump (const struct dictionary *);
+
#endif /* dictionary.h */
Index: ui/gui/ChangeLog
===================================================================
RCS file: /cvsroot/pspp/pspp/src/ui/gui/ChangeLog,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -b -r1.78 -r1.79
--- ui/gui/ChangeLog 13 Aug 2007 03:44:46 -0000 1.78
+++ ui/gui/ChangeLog 13 Aug 2007 04:31:43 -0000 1.79
@@ -1,3 +1,21 @@
+2007-08-12 John Darrington <address@hidden>
+ Ben Pfaff <address@hidden>
+
+ Implement Edit|Cut operation for datasheet. Patch #6117.
+
+ * automake.mk: Add clipboard.c, clipboard.h.
+
+ * clipboard.c: New file.
+
+ * clipboard.h: New file.
+
+ * data-editor.c (new_data_editor): Connect Edit|Copy to
+ on_edit_copy function.
+ (data_var_select): Enable or disable Edit|Copy as appropriate.
+ (on_edit_copy): New function.
+
+ * data-editor.glade: Connect menu items to new operations.
+
2007-08-12 Ben Pfaff <address@hidden>
* psppire-dict.c (psppire_dict_dump): Don't use
Index: ui/gui/automake.mk
===================================================================
RCS file: /cvsroot/pspp/pspp/src/ui/gui/automake.mk,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- ui/gui/automake.mk 29 Jul 2007 07:56:53 -0000 1.33
+++ ui/gui/automake.mk 13 Aug 2007 04:31:43 -0000 1.34
@@ -71,6 +71,8 @@
src_ui_gui_psppire_SOURCES = \
src/ui/gui/about.c \
src/ui/gui/about.h \
+ src/ui/gui/clipboard.c \
+ src/ui/gui/clipboard.h \
src/ui/gui/compute-dialog.c \
src/ui/gui/compute-dialog.h \
src/ui/gui/comments-dialog.c \
Index: ui/gui/data-editor.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/ui/gui/data-editor.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -b -r1.45 -r1.46
--- ui/gui/data-editor.c 29 Jul 2007 07:56:53 -0000 1.45
+++ ui/gui/data-editor.c 13 Aug 2007 04:31:44 -0000 1.46
@@ -39,6 +39,7 @@
#include "comments-dialog.h"
#include "variable-info-dialog.h"
#include "dict-display.h"
+#include "clipboard.h"
#define _(msgid) gettext (msgid)
#define N_(msgid) msgid
@@ -52,6 +53,7 @@
#include "psppire-data-store.h"
#include "psppire-var-store.h"
+static void on_edit_copy (GtkMenuItem *, gpointer);
static void create_data_sheet_variable_popup_menu (struct data_editor *);
static void create_data_sheet_cases_popup_menu (struct data_editor *);
@@ -275,12 +277,18 @@
connect_help (de->xml);
+
+ g_signal_connect (get_widget_assert (de->xml, "edit_copy"),
+ "activate",
+ G_CALLBACK (on_edit_copy), de);
+
+
register_data_editor_actions (de);
de->toggle_value_labels =
gtk_toggle_action_new ("toggle-value-labels",
_("Labels"),
- _("Show (hide) value labels"),
+ _("Show/hide value labels"),
"pspp-value-labels");
g_signal_connect (de->toggle_value_labels, "activate",
@@ -771,21 +779,24 @@
GtkWidget *view_data = get_widget_assert (de->xml, "view_data");
GtkWidget *view_variables = get_widget_assert (de->xml, "view_variables");
+ GtkWidget *edit_copy = get_widget_assert (de->xml, "edit_copy");
switch (page_num)
{
case PAGE_VAR_SHEET:
gtk_widget_hide (view_variables);
gtk_widget_show (view_data);
+ gtk_widget_set_sensitive (edit_copy, FALSE);
gtk_action_set_sensitive (de->insert_variable, TRUE);
gtk_action_set_sensitive (de->insert_case, FALSE);
gtk_action_set_sensitive (de->invoke_goto_dialog, FALSE);
break;
case PAGE_DATA_SHEET:
gtk_widget_show (view_variables);
- gtk_widget_hide (view_data);
+ gtk_widget_show (view_data);
gtk_action_set_sensitive (de->invoke_goto_dialog, TRUE);
gtk_action_set_sensitive (de->insert_case, TRUE);
+ gtk_widget_set_sensitive (edit_copy, TRUE);
break;
default:
g_assert_not_reached ();
@@ -1713,3 +1724,18 @@
event->button, event->time);
}
}
+
+
+
+static void
+on_edit_copy (GtkMenuItem *m, gpointer data)
+{
+ struct data_editor *de = data;
+
+ GtkSheet *data_sheet = GTK_SHEET (get_widget_assert (de->xml,
+ "data_sheet"));
+
+ data_sheet_set_clip (data_sheet);
+}
+
+
Index: ui/gui/data-editor.glade
===================================================================
RCS file: /cvsroot/pspp/pspp/src/ui/gui/data-editor.glade,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- ui/gui/data-editor.glade 29 Jul 2007 07:56:53 -0000 1.30
+++ ui/gui/data-editor.glade 13 Aug 2007 04:31:44 -0000 1.31
@@ -134,7 +134,7 @@
<child>
<widget class="GtkMenu" id="edit_menu">
<child>
- <widget class="GtkImageMenuItem" id="cut1">
+ <widget class="GtkImageMenuItem" id="edit_cut">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="label">gtk-cut</property>
@@ -143,7 +143,7 @@
</widget>
</child>
<child>
- <widget class="GtkImageMenuItem" id="copy1">
+ <widget class="GtkImageMenuItem" id="edit_copy">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="label">gtk-copy</property>
@@ -152,7 +152,7 @@
</widget>
</child>
<child>
- <widget class="GtkImageMenuItem" id="paste1">
+ <widget class="GtkImageMenuItem" id="edit_paste">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="label">gtk-paste</property>
@@ -161,7 +161,7 @@
</widget>
</child>
<child>
- <widget class="GtkMenuItem" id="paste_variables1">
+ <widget class="GtkMenuItem" id="edit_paste-variables">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="label" translatable="yes">Paste
_Variables</property>
Index: ui/gui/clipboard.c
===================================================================
RCS file: ui/gui/clipboard.c
diff -N ui/gui/clipboard.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/gui/clipboard.c 13 Aug 2007 04:31:43 -0000 1.1
@@ -0,0 +1,306 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2007 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 <gtksheet/gtksheet.h>
+#include "clipboard.h"
+#include <data/case.h>
+#include "psppire-data-store.h"
+#include <data/casereader.h>
+#include <data/case-map.h>
+#include <libpspp/alloc.h>
+#include <data/casewriter.h>
+#include <data/format.h>
+#include <data/data-out.h>
+#include <stdlib.h>
+
+
+/* A casereader and dictionary holding the data currently in the clip */
+static struct casereader *clip_datasheet = NULL;
+struct dictionary *clip_dict = NULL;
+
+
+
+
+static void data_sheet_update_clipboard (GtkSheet *);
+
+/* Set the clip according to the currently
+ selected range in the data sheet */
+void
+data_sheet_set_clip (GtkSheet *sheet)
+{
+ int i;
+ struct casewriter *writer ;
+ GtkSheetRange range;
+ PsppireDataStore *ds;
+ struct case_map *map = NULL;
+ casenumber max_rows;
+ size_t max_columns;
+
+ ds = PSPPIRE_DATA_STORE (gtk_sheet_get_model (sheet));
+
+ gtk_sheet_get_selected_range (sheet, &range);
+
+ /* If nothing selected, then use active cell */
+ if ( range.row0 < 0 || range.col0 < 0 )
+ {
+ gint row, col;
+ gtk_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;
+
+ if (psppire_case_file_get_case (ds->case_file, i, &old))
+ {
+ struct ccase new;
+
+ case_map_execute (map, &old, &new);
+ case_destroy (&old);
+ casewriter_write (writer, &new);
+ }
+ 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);
+
+ string = g_string_sized_new (10 * val_cnt * case_cnt);
+
+ for (r = 0 ; r < case_cnt ; ++r )
+ {
+ int c;
+ struct ccase cc;
+ if ( ! casereader_peek (clip_datasheet, r, &cc))
+ {
+ g_warning ("Clipboard seems to have inexplicably shrunk");
+ break;
+ }
+
+ for (c = 0 ; c < val_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_destroy (&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);
+
+ /* 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;
+ if ( ! casereader_peek (clip_datasheet, r, &cc))
+ {
+ g_warning ("Clipboard seems to have inexplicably shrunk");
+ break;
+ }
+ g_string_append (string, "<tr>\n");
+
+ for (c = 0 ; c < val_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_destroy (&cc);
+ }
+ g_string_append (string, "</table>\n");
+
+ return string;
+}
+
+
+
+static void
+clipboard_get_cb (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info,
+ gpointer data)
+{
+ GString *string = NULL;
+
+ switch (info)
+ {
+ case SELECT_FMT_TEXT:
+ string = clip_to_text ();
+ break;
+ case SELECT_FMT_HTML:
+ string = clip_to_html ();
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ gtk_selection_data_set (selection_data, selection_data->target,
+ 8,
+ (const guchar *) string->str, string->len);
+
+ g_string_free (string, TRUE);
+}
+
+static void
+clipboard_clear_cb (GtkClipboard *clipboard,
+ gpointer data)
+{
+ dict_destroy (clip_dict);
+ clip_dict = NULL;
+
+ casereader_destroy (clip_datasheet);
+ clip_datasheet = NULL;
+}
+
+
+
+static void
+data_sheet_update_clipboard (GtkSheet *sheet)
+{
+ static const GtkTargetEntry targets[] = {
+ { "UTF8_STRING", 0, SELECT_FMT_TEXT },
+ { "STRING", 0, SELECT_FMT_TEXT },
+ { "TEXT", 0, SELECT_FMT_TEXT },
+ { "COMPOUND_TEXT", 0, SELECT_FMT_TEXT },
+ { "text/plain;charset=utf-8", 0, SELECT_FMT_TEXT },
+ { "text/plain", 0, SELECT_FMT_TEXT },
+ { "text/html", 0, SELECT_FMT_HTML }
+ };
+
+ GtkClipboard *clipboard =
+ gtk_widget_get_clipboard (GTK_WIDGET (sheet),
+ GDK_SELECTION_CLIPBOARD);
+
+ if (!gtk_clipboard_set_with_owner (clipboard, targets,
+ G_N_ELEMENTS (targets),
+ clipboard_get_cb, clipboard_clear_cb,
+ G_OBJECT (sheet)))
+ clipboard_clear_cb (clipboard, sheet);
+}
+
Index: ui/gui/clipboard.h
===================================================================
RCS file: ui/gui/clipboard.h
diff -N ui/gui/clipboard.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/gui/clipboard.h 13 Aug 2007 04:31:43 -0000 1.1
@@ -0,0 +1,28 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2007 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 <gtksheet/gtksheet.h>
+
+#ifndef CLIPBOARD_H
+#define CLIPBOARD_H
+
+
+void data_sheet_set_clip (GtkSheet *data_sheet);
+
+
+#endif /* CLIPBOARD_H */
+