Patch #6117: Implement clipboard for data sheet.
authorBen Pfaff <blp@gnu.org>
Mon, 13 Aug 2007 04:31:43 +0000 (04:31 +0000)
committerBen Pfaff <blp@gnu.org>
Mon, 13 Aug 2007 04:31:43 +0000 (04:31 +0000)
src/data/ChangeLog
src/data/dictionary.c
src/data/dictionary.h
src/ui/gui/ChangeLog
src/ui/gui/automake.mk
src/ui/gui/clipboard.c [new file with mode: 0644]
src/ui/gui/clipboard.h [new file with mode: 0644]
src/ui/gui/data-editor.c
src/ui/gui/data-editor.glade

index e32441d17836f212b3c7984250e12da558c3d08a..a74b7dd4739d5ccd11ef18933791ce99d57ad911 100644 (file)
@@ -1,3 +1,7 @@
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c (dict_dump): New function.
+
 2007-08-12  Ben Pfaff  <blp@gnu.org>
 
        Drop dict_compactor in favor of using the new struct case_map.
index 9589a72f0106f1bbfa7dcbbd87ce6e3330252218..f3c76c6e6d25bdf1c67b2796c2934295ee5be881 100644 (file)
@@ -63,6 +63,23 @@ struct dictionary
     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 9990410afaf52e6e6b6757166da1df91135d3901..581a49d827614a56277dd65cf7564addc9a0f49b 100644 (file)
@@ -140,4 +140,6 @@ const struct vector *dict_lookup_vector (const struct dictionary *,
                                          const char *name);
 void dict_clear_vectors (struct dictionary *);
 
+void dict_dump (const struct dictionary *);
+
 #endif /* dictionary.h */
index b5d9c6a83d04247f347775ba6be6f5c2cba0fedb..80c3ae975cb644b10746d0a6665dd5c251236bcd 100644 (file)
@@ -1,3 +1,21 @@
+2007-08-12  John Darrington <john@darrington.wattle.id.au>
+           Ben Pfaff  <blp@gnu.org>
+
+       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  <blp@gnu.org>
 
        * psppire-dict.c (psppire_dict_dump): Don't use
 
 2007-08-13  John Darrington <john@darrington.wattle.id.au>
 
-        * psppire-case-file.c (psppire_case_file_append_case):  
+        * psppire-case-file.c (psppire_case_file_append_case):
        Deleted unused function.
 
 2007-08-07  John Darrington <john@darrington.wattle.id.au>
 
-       * helper.c (execute_syntax): Set the active file data to NULL at the 
+       * helper.c (execute_syntax): Set the active file data to NULL at the
        end of the procedure.  Thanks to Ben for suggesting this.
 
-       * psppire-case-file.c: Added assertions to the remaining functions 
+       * psppire-case-file.c: Added assertions to the remaining functions
        on inaccessible objects.
 
-       * psppire-data-store.c psppire-data-store.h: Disconnect or block 
-       signals on dictionary and case_file, when make_reader has been called. 
-       Reconnect or unblock them when a new datasheet has been set for the 
+       * psppire-data-store.c psppire-data-store.h: Disconnect or block
+       signals on dictionary and case_file, when make_reader has been called.
+       Reconnect or unblock them when a new datasheet has been set for the
        data_store.
-       
+
 2007-08-06  John Darrington <john@darrington.wattle.id.au>
 
        * syntax-editor.glade: Changed some properties to be less annoying.
 
 2007-07-26  John Darrington <john@darrington.wattle.id.au>
 
-       * helper.c helper.h (execute_syntax): removed implicit EXECUTE at end 
+       * helper.c helper.h (execute_syntax): removed implicit EXECUTE at end
        of commands.
 
-       * data-editor.c data-editor.glade: Added "Run Pending Transformations" 
+       * data-editor.c data-editor.glade: Added "Run Pending Transformations"
        menuitem.
 
 2007-07-25  John Darrington <john@darrington.wattle.id.au>
 
-       * customentry.c: Redraw button in insensitive state, if the widget's 
-        "editable" style is FALSE.  Don't emit the "clicked" signal if 
+       * customentry.c: Redraw button in insensitive state, if the widget's
+        "editable" style is FALSE.  Don't emit the "clicked" signal if
         "editable" is FALSE.
-       
-       * var-sheet.c: If variables are long-string variables, then set the 
+
+       * var-sheet.c: If variables are long-string variables, then set the
        "editable" properties of the entry widgets for the values and missing
        cells to FALSE,
 
 2007-07-18  John Darrington <john@darrington.wattle.id.au>
 
-       * psppire-case-file.c psppire-case-file.h psppire-data-store.c 
+       * psppire-case-file.c psppire-case-file.h psppire-data-store.c
        psppire-dict.c psppire-dict.h psppire-var-store.c : Added the
        ability to resize string variables.  Fixed associated problems
-       inserting/deleting variables.   
-       
+       inserting/deleting variables.
+
        * helper.c helper.h (marshaller_VOID__INT_INT_INT): New marshaller
        function.
-       
+
 2007-07-16  John Darrington <john@darrington.wattle.id.au>
 
-       * data-editor.c: File Open dialog remembers directory.  Thanks to 
+       * data-editor.c: File Open dialog remembers directory.  Thanks to
        Ben Pfaff for this suggestion.
-       
+
 2007-07-15  John Darrington <john@darrington.wattle.id.au>
 
-       * compute-dialog.c: Only generate NUMERIC/STRING command if the 
+       * compute-dialog.c: Only generate NUMERIC/STRING command if the
        type-and-label dialog was used.
 
 2007-07-12  John Darrington <john@darrington.wattle.id.au>
 
-       * psppire-data-store.c: Added call to g_sheet_model_range_changed to 
+       * psppire-data-store.c: Added call to g_sheet_model_range_changed to
        ensure that datasheet displays the current store.
 
        * psppire-data-store.h: Formatting tidy up.
 
 2007-07-08  John Darrington <john@darrington.wattle.id.au>
 
-       * data-editor.c data-editor.glade data-editor.h: Implemented 
+       * data-editor.c data-editor.glade data-editor.h: Implemented
        the "Insert Case" button/dialog.
 
 2007-07-08  John Darrington <john@darrington.wattle.id.au>
 
        * goto-case-dialog.c goto-case-dialog.h (new files)
-       * automake.mk data-editor.c data-editor.glade data-editor.h 
-       psppire-case-file.c psppire-case-file.h psppire-data-store.c 
+       * automake.mk data-editor.c data-editor.glade data-editor.h
+       psppire-case-file.c psppire-case-file.h psppire-data-store.c
        psppire-data-store.h psppire.glade :  Implemented the goto-case dialog
-       
+
 
 2007-07-07  John Darrington <john@darrington.wattle.id.au>
-       
-       * psppire-data-store.c psppire-data-store.h: Made cases number from 
-       1 instead of 0. 
+
+       * psppire-data-store.c psppire-data-store.h: Made cases number from
+       1 instead of 0.
 
        * psppire-data-store.c: Added a tooltip like feature to display
-       the label of variables. 
-       
+       the label of variables.
+
 2007-07-03  John Darrington <john@darrington.wattle.id.au>
-       
-       * data-editor.c data-sheet.c: Turned off autoscrolling, and 
+
+       * data-editor.c data-sheet.c: Turned off autoscrolling, and
        manually move to cell on column click instead.
 
 2007-06-29  John Darrington <john@darrington.wattle.id.au>
 
-       * data-editor.c data-editor.glade psppire-data-store.c 
-       psppire-data-store.h: Enabled cell reference entry and datum 
+       * data-editor.c data-editor.glade psppire-data-store.c
+       psppire-data-store.h: Enabled cell reference entry and datum
        entry widgets.
 
 2007-06-29  John Darrington <john@darrington.wattle.id.au>
 
-       * data-editor.c data-sheet.c: Moved update_cell_ref_entry from 
+       * data-editor.c data-sheet.c: Moved update_cell_ref_entry from
        data-sheet.c to data-editor.c and made it work again.
 
 2007-06-06  Ben Pfaff  <blp@gnu.org>
 
        Adapt case sources, sinks, and clients of procedure code to the
        new infrastructure.
-       
+
        * automake.mk: Removed files.
 
        * flexifile-factory.c: Removed, dead code.
 
        * psppire-var-store.c (psppire_var_store_item_editable): Use
        var_is_alpha.
-       
+
 2007-05-07 John Darrington <john@darrington.wattle.id.au>
 
        * psppire-dialog.c psppire-dialog.h: Added "orientation" property,
         to allow dialogs to be either vertical or horizontal.
 
-       * comments-dialog.c comments-dialog.h: New files, invoking 
+       * comments-dialog.c comments-dialog.h: New files, invoking
        ADD DOCUMENT cmd.
 
 2007-04-30 John Darrington <john@darrington.wattle.id.au>
 
        * var-display.c var-display.h variable-info-dialog.c
-       variable-info-dialog.h : New files. 
+       variable-info-dialog.h : New files.
 
-       * data-editor.c : 
+       * data-editor.c :
 
        * psppire-buttonbox.c psppire-buttonbox.h : Added the "buttons"
        property, and optional  GOTO and CONTINUE buttons.
 2007-04-25 John Darrington <john@darrington.wattle.id.au>
 
        * icons/scalable/splash.c icons/splash.png : More eye candy.
-       
+
        * main.c psppire.h : new files.
 
-       * psppire.c : Seperated the command line parsing and other 
+       * psppire.c : Seperated the command line parsing and other
        environment startup from the core psppire code.
 
 2007-04-25 John Darrington <john@darrington.wattle.id.au>
        * icons/scalable icons/16x16: new directories.
        * psppire.c : Add new icons to factory.
 
-       * dict-display.c: Refactor code get model from modelfilter. 
+       * dict-display.c: Refactor code get model from modelfilter.
        Added cellrenderer to display icon indicating variables' types.
         Displayed the label of variables, if there is one.
 
        builds.
 
 2007-04-13   John Darrington <john@darrington.wattle.id.au>
-       
+
        * var-type-dialog.c: Added a FMT_DATETIME20 template.
-       
+
 2007-04-04   John Darrington <john@darrington.wattle.id.au>
 
        * compute-dialog.c compute-dialog.h: New files
 
-       * data-editor.c data-editor.h data-editor.glade : Added Transform 
+       * data-editor.c data-editor.h data-editor.glade : Added Transform
        menu, and support for Compute dialog
 
-       * glade-register.c psppire-buttonbox.c psppire-buttonbox.h 
-         psppire-vbottonbox.c psppire-vbuttonbox.h psppire-hbuttonbox.c 
-         psppire-vbuttonbox.h : Made buttonbox an abstract base class 
+       * glade-register.c psppire-buttonbox.c psppire-buttonbox.h
+         psppire-vbottonbox.c psppire-vbuttonbox.h psppire-hbuttonbox.c
+         psppire-vbuttonbox.h : Made buttonbox an abstract base class
          and separated it into vbuttonbox and hbuttonbox.
 
-       * psppire-selector.c : Allowed GtkTextView to be the destination 
+       * psppire-selector.c : Allowed GtkTextView to be the destination
        widget.
 
-       * psppire-keypad.c: Added an "erase" signal.  Fixed other 
+       * psppire-keypad.c: Added an "erase" signal.  Fixed other
         minor problems.
 
 2007-04-03  Ben Pfaff  <blp@gnu.org>
        assert that may or may not trap some Windows-related bugs.
 
 2007-04-03   John Darrington <john@darrington.wattle.id.au>
-       
+
        * data-editor.c data-editor.glade helper.h syntax-editor.c
        syntax-editor.h : Implemented the File->Recently_Used_ menus.
 
 
 2007-03-31   John Darrington <john@darrington.wattle.id.au>
-        
+
        * data-editor.c data-editor.glade data-editor.h dialog-common.c
        psppire-buttonbox.c psppire-dialog.c psppire-dialog.h
        psppire-selector.c psppire-selector.h psppire.c psppire.glade
        sort-cases-dialog.c sort-cases-dialog.h split-file-dialog.c
        transpose-dialog.c weight-cases-dialog.c : Fixed the Refresh
-       button on all the dialogs. 
-       
+       button on all the dialogs.
+
 2007-03-31   John Darrington <john@darrington.wattle.id.au>
-       
+
        * data-editor.c: Added hooks for the split-file-dialog
 
        * psppire.glade: Added the split file dialog box.
-       
+
        * split-file-dialog.c split-file-dialog.h: New files.
-       
-       * dialog-common.c dialog-common.h: New files containing functions 
-       which seem to be used a lot in dialog box implementations. 
+
+       * dialog-common.c dialog-common.h: New files containing functions
+       which seem to be used a lot in dialog box implementations.
 
        * psppire-keypad.c psppire-keypad.h: New files.  Implements keypad
-       thingumy widget.  
+       thingumy widget.
 
        * psppire-selector.c: Made the orientation of the arrow a property
        of the widget, so that it can be selected from glade.
        conflict with POSIX function of same name.
 
 Tue Mar 13 17:20:05 CET 2007 John Darrington <john@darrington.wattle.id.au>
-       * psppire.c:  Changed gtk_init to gtk_parse_args, followed by a delayed         call to gdk_init, so that psppire --version will succeed, even if it 
+       * psppire.c:  Changed gtk_init to gtk_parse_args, followed by a delayed         call to gdk_init, so that psppire --version will succeed, even if it
        cannot connect to a display .
-       
+
 Wed Mar  7 19:05:12 CET 2007 John Darrington <john@darrington.wattle.id.au>
 
-       * var-sheet.c: Replaced call to nl_langinfo with locale_charset 
+       * var-sheet.c: Replaced call to nl_langinfo with locale_charset
        from gnulib.
 
 Thu Feb 22 12:27:41 CET 2007 John Darrington <john@darrington.wattle.id.au>
 
-       * data-editor.c : called new gen_quoted_string function to properly 
+       * data-editor.c : called new gen_quoted_string function to properly
           quote filenames in generated syntax.
 
-       * window-manager.c : Converted name from filename encoding to UTF8 
+       * window-manager.c : Converted name from filename encoding to UTF8
           before displaying in title bar.
 
 Tue Jan 30 20:13:46 WST 2007 John Darrington <john@darrington.wattle.id.au>
@@ -290,10 +308,10 @@ Fri Jan 26 15:51:34 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
        * transpose-dialog.c transpose-dialog.h : New files.
 
-       * psppire-dict.c psppire-dict.h : Added missing GtkTreeModel 
+       * psppire-dict.c psppire-dict.h : Added missing GtkTreeModel
        interface functions.
 
-       * weight-cases-dialog.c weight-cases-dialog.h : Re-implemented, 
+       * weight-cases-dialog.c weight-cases-dialog.h : Re-implemented,
        using new PsppireSelector widget.
 
        * dict-display.c dict-display.h : New files.
@@ -304,21 +322,21 @@ Tue Jan 23 21:10:01 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
        * helper.c helper.h: New function execute_syntax.
 
-       * syntax-editor.c syntax-editor.glade: Disabled data open/save menu 
+       * syntax-editor.c syntax-editor.glade: Disabled data open/save menu
        items.
 
-       * data-editor.c data-editor.glade data-editor.h: Enabled data 
+       * data-editor.c data-editor.glade data-editor.h: Enabled data
        open/save/save_as  menu-items.
-       
-       * window-manager.h window-manager.c (default_window_name) : New 
+
+       * window-manager.h window-manager.c (default_window_name) : New
        function.
 
 Sat Jan 13 07:47:26 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
        * psppire-case-file.c psppire-data-store.c psppire-dialog.c
-       psppire-dict.c psppire-var-select.c : Replaced identifier 'signal' 
+       psppire-dict.c psppire-var-select.c : Replaced identifier 'signal'
        with 'signals' to avoid conflict with sysv based systems which use
-       this identifer for something else.  
+       this identifer for something else.
        Thanks to Daniel E WILLIAMS for reporting this problem.
 
 Wed Jan 10 07:20:39 WST 2007 John Darrington <john@darrington.wattle.id.au>
@@ -327,33 +345,33 @@ Wed Jan 10 07:20:39 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
        * psppire-data-store.c : assertions.
 
-       * psppire.c: Ignore replace source callbacks if the new source is 
+       * psppire.c: Ignore replace source callbacks if the new source is
          not of storiage_source_class
 
        * syntax-editor.c: Close/Abort source after parsing is complete.
 
 Sun Jan  7 08:38:29 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
-       * psppire-dict.c: Add FILTER_CHANGED and SPLIT_CHANGED signals 
+       * psppire-dict.c: Add FILTER_CHANGED and SPLIT_CHANGED signals
        corresponding to the callbacks in src/data/dictionary.c
 
-       * data-editor.c : Connect functions to the FILTER_CHANGED and 
+       * data-editor.c : Connect functions to the FILTER_CHANGED and
        SPLIT_CHANGED signals to update the status bar accordingly.
 
 Mon Jan  1 10:37:07 WST 2007 John Darrington <john@darrington.wattle.id.au>
 
-       * psppire-case-file.c psppire-case-file.h: Changed the backend 
+       * psppire-case-file.c psppire-case-file.h: Changed the backend
        semantics. An object is now created without any backend.  A new function        ( psppire_case_file_replace_flexifile ) sets the backend to use.
 
        * psppire-data-store.c : Updated callers accordingly.
 
-       * psppire-dict.c psppire-dict.h : New function 
+       * psppire-dict.c psppire-dict.h : New function
        (psppire_dict_replace_dictionary) .
 
-       * psppire.c : Updated to use new dataset replace_{source, dictionary} 
+       * psppire.c : Updated to use new dataset replace_{source, dictionary}
        callbacks.
 
-       * syntax-editor.c : parses in state CMD_STATE_DATA unless there are 
+       * syntax-editor.c : parses in state CMD_STATE_DATA unless there are
        no variables in the dictionary.
 
 Mon Dec 25 12:38:24 WST 2006 John Darrington <john@darrington.wattle.id.au>
@@ -373,16 +391,16 @@ Mon Dec 25 08:49:57 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
 Sun Dec 17 08:26:10 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
-       * syntax-editor-source.c syntax-editor-source.h syntax-editor.h: 
-       New files. 
+       * syntax-editor-source.c syntax-editor-source.h syntax-editor.h:
+       New files.
 
-       * message-dialog.c :  Now reports the filename and line number in 
+       * message-dialog.c :  Now reports the filename and line number in
        error messages.
-       
-       * psppire.c psppire.glade syntax-editor.c: Added the ability to run 
+
+       * psppire.c psppire.glade syntax-editor.c: Added the ability to run
        syntax from the syntax editor.
 
-       
+
 Sat Dec 16 14:13:07 2006  Ben Pfaff  <blp@gnu.org>
 
        * psppire-data-store.c (geometry_get_justification): Don't assume
@@ -399,16 +417,16 @@ Sat Dec 16 12:24:35 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
        * psppire-variable.c psppire-variable.h: Deleted.
 
-       * psppire-dict.c psppire-dict.h: Removed the caching of the variable 
-           data, which is now unecessary because src/data/vardict.h maintains 
+       * psppire-dict.c psppire-dict.h: Removed the caching of the variable
+           data, which is now unecessary because src/data/vardict.h maintains
            an association between variables and their dictionary.
-       
-       * data-sheet.c menu-actions.c missing-val-dialog.c 
-         missing-val-dialog.h psppire-data-store.c 
-         psppire-var-store.c psppire-var-store.h 
-         sort-cases-dialog.c val-labs-dialog.c val-labs-dialog.h 
-         var-sheet.c var-type-dialog.c var-type-dialog.h: Dealt with the 
-           consequences of deleting psppire-variable.[ch]. 
+
+       * data-sheet.c menu-actions.c missing-val-dialog.c
+         missing-val-dialog.h psppire-data-store.c
+         psppire-var-store.c psppire-var-store.h
+         sort-cases-dialog.c val-labs-dialog.c val-labs-dialog.h
+         var-sheet.c var-type-dialog.c var-type-dialog.h: Dealt with the
+           consequences of deleting psppire-variable.[ch].
 
 
 Sat Dec  9 20:03:04 2006  Ben Pfaff  <blp@gnu.org>
@@ -435,50 +453,50 @@ Mon Jul 17 18:21:29 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
 Sat Jul 15 11:27:15 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
-   * psppire.c psppire.glade automake.mk icons/* : Added toolbar icons where 
+   * psppire.c psppire.glade automake.mk icons/* : Added toolbar icons where
        there's no suitable gtk stock icon.
 
 Tue Jul  4 09:08:38 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
+
    * psppire.c: Fixed --help and --version options.
-       
+
 Sat Jun 24 16:56:22 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
    * menu-actions.c: Added goto case and sort cases dialogs.
 
    * psppire-case-file.c psppire-case-file.h: Added sort function.
 
-   * psppire-data-store.c psppire-variable.c psppire-variable.h: 
+   * psppire-data-store.c psppire-variable.c psppire-variable.h:
      Renamed  psppire_variable_get_index to psppire_variable_get_fv and
      dealt with the consequences.  Added a psppire_variable_get_index
      function which actually does what the name suggests.
 
    * psppire-dict.c psppire-dict.h: Implemented GtkTreeModel interface,
-     which allows a dictionary to be displayed in a GtkTreeView.       
+     which allows a dictionary to be displayed in a GtkTreeView.
 
-   * psppire.glade: Added dialog boxes for Goto Case and Sort Case.    
+   * psppire.glade: Added dialog boxes for Goto Case and Sort Case.
 
    * sort-cases-dialog.c sort-cases-dialog.h (new files).
 
 Mon Jun 19 18:10:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
    * psppire-case-file.c psppire-case-file.h (new files)
-   
+
    * automake.mk data-sheet.c data-sheet.h menu-actions.c
    psppire-data-store.c psppire-data-store.h psppire-dict.c
    psppire-dict.h psppire-var-store.c psppire.c
-   
+
      Replaced psppire-case-array.c  with psppire-case-file.c, so as to
      allow an arbitrary number of cases to be represented.
-   
+
 Sun Jun  4 15:50:28 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
-   * psppire-var-store.c, psppire.c, var-sheet.c :  Unlimited the number of 
+   * psppire-var-store.c, psppire.c, var-sheet.c :  Unlimited the number of
    variables that can be displayed. Minor i18n issues.
 
 Tue May 30 19:53:35 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
-   * menu-actions.c menu-actions.h psppire.c: Fixed up load/new 
+   * menu-actions.c menu-actions.h psppire.c: Fixed up load/new
    interactions with startup.
 
    * psppire-data-store.c: Fixed bad i18n call.
@@ -490,8 +508,8 @@ Tue May 30 19:53:35 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
 Sat May 27 16:25:38 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
-   * customentry.c data-sheet.c menu-actions.c message-dialog.c 
-     missing-val-dialog.c psppire-data-store.c psppire-var-store.c 
+   * customentry.c data-sheet.c menu-actions.c message-dialog.c
+     missing-val-dialog.c psppire-data-store.c psppire-var-store.c
      psppire.c psppire.glade var-sheet.c: Fixed internationalisation.
 
 Thu May 25 18:01:17 WST 2006 John Darrington <john@darrington.wattle.id.au>
@@ -512,24 +530,24 @@ Sat May 20 21:08:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
    * psppire.c: Allowed user to specify *.sav file on command line.
 
 Mon May 15 20:01:25 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
+
        * menu-actions.c psppire-case-array.c psppire-case-array.h
-         psppire-data-store.c  psppire-dict.c psppire-dict.h 
+         psppire-data-store.c  psppire-dict.c psppire-dict.h
          psppire-variable.c:
 
          Initialised new cases to SYSMIS/blank when inserting in data sheet.
 
 Sat May 13 08:00:50 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
-       * data-sheet.c, helper.c, helper.h, psppire-data-store.c, 
+       * data-sheet.c, helper.c, helper.h, psppire-data-store.c,
           psppire-var-store.c:
-         
-         Set free_strings flag so that the gtksheet frees the string data 
+
+         Set free_strings flag so that the gtksheet frees the string data
          when it's done with them.
 
 Thu May 11 22:25:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
-       * data-sheet.c helper.c helper.h psppire-data-store.c psppire-var-store.c 
+       * data-sheet.c helper.c helper.h psppire-data-store.c psppire-var-store.c
        psppire.c: Converted strings to utf8 before passing to gtksheet.
 
        * psppire-dict.c: Changed buffer to more reasonable length
@@ -537,7 +555,7 @@ Thu May 11 22:25:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
        * var-sheet.c: Changed maximum string length to use macro from
        data/values.h
 
-       
+
 Sun May  7 10:07:28 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
        * psppire-data-store.c: Fixed buglet initialising string members.
@@ -557,7 +575,7 @@ Tue Apr 25 11:08:04 2006  Ben Pfaff  <blp@gnu.org>
 
        Finish reforming error message support.  In this phase, move
        message.c into libpspp.
-       
+
        * automake.mk: (src_ui_gui_psppire_SOURCES) Remove src/message.c.
 
 Tue Apr 25 10:56:53 2006  Ben Pfaff  <blp@gnu.org>
@@ -583,7 +601,7 @@ Sun Apr 23 22:07:49 2006  Ben Pfaff  <blp@gnu.org>
        Continue reforming error message support.  In this phase, get rid
        of message "titles" and put the message text in `struct error'.
        Now `struct error' encapsulates a message more properly.
-       
+
        * message-dialog.c: (err_vmsg) Rename err_msg().  Updated
        interface.
 
@@ -603,7 +621,7 @@ Sun Apr 16 16:06:54 2006  Ben Pfaff  <blp@gnu.org>
        rid of VM() and the other msg() support for "verbosity", replacing
        it by a new function verbose_msg().
 
-       * message-dialog.c: (verbose_msg) New function.  
+       * message-dialog.c: (verbose_msg) New function.
        (err_cond_fail) Removed (dead code).
        (err_failure) Removed (dead code).
 
@@ -622,7 +640,7 @@ Mon Mar 13 16:42:44 WST 2006 John Darrington <john@darrington.wattle.id.au>
     * Rename error-dialog.[ch] -> message-dialog.[ch]
 
     * Moved code from the psppire module.
-       
+
 Sat Jan 28 16:22:23 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
     * Separated the data out of the GtkSheet.
index dff1a96cdea1e073348943c05603bbec79d990ec..df6f6d1efd45e63aba902d2ca6a22c17ebefe3e6 100644 (file)
@@ -71,6 +71,8 @@ dist_src_ui_gui_psppire_DATA = \
 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 \
diff --git a/src/ui/gui/clipboard.c b/src/ui/gui/clipboard.c
new file mode 100644 (file)
index 0000000..b115a04
--- /dev/null
@@ -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);
+}
+
diff --git a/src/ui/gui/clipboard.h b/src/ui/gui/clipboard.h
new file mode 100644 (file)
index 0000000..1cdffe8
--- /dev/null
@@ -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 */
+
index 8fd9517db535ca94c6efe062bb59752c8880ebd4..50c181ee6da726fb37fc14a0858e85a7340398f4 100644 (file)
@@ -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 @@ new_data_editor (void)
   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 @@ data_var_select (GtkNotebook *notebook,
 
   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 @@ popup_cases_menu (GtkSheet *sheet, gint row,
                      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 24ee580756625d6a14ea7e5d4d392c7e76204f05..4a626ebe1c3eba9090ff645af30142641b6119d6 100644 (file)
                 <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>
                       </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>
                       </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>
                       </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>