pspp-cvs
[Top][All Lists]
Advanced

[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 */
+




reply via email to

[Prev in Thread] Current Thread [Next in Thread]