From 7ed50d6a12512276156477061ba54ba4836f2831 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 13 Aug 2007 04:31:43 +0000 Subject: [PATCH] Patch #6117: Implement clipboard for data sheet. --- src/data/ChangeLog | 4 + src/data/dictionary.c | 17 ++ src/data/dictionary.h | 2 + src/ui/gui/ChangeLog | 258 +++++++++++++++-------------- src/ui/gui/automake.mk | 2 + src/ui/gui/clipboard.c | 306 +++++++++++++++++++++++++++++++++++ src/ui/gui/clipboard.h | 28 ++++ src/ui/gui/data-editor.c | 30 +++- src/ui/gui/data-editor.glade | 8 +- 9 files changed, 529 insertions(+), 126 deletions(-) create mode 100644 src/ui/gui/clipboard.c create mode 100644 src/ui/gui/clipboard.h diff --git a/src/data/ChangeLog b/src/data/ChangeLog index e32441d1..a74b7dd4 100644 --- a/src/data/ChangeLog +++ b/src/data/ChangeLog @@ -1,3 +1,7 @@ +2007-08-12 Ben Pfaff + + * dictionary.c (dict_dump): New function. + 2007-08-12 Ben Pfaff Drop dict_compactor in favor of using the new struct case_map. diff --git a/src/data/dictionary.c b/src/data/dictionary.c index 9589a72f..f3c76c6e 100644 --- a/src/data/dictionary.c +++ b/src/data/dictionary.c @@ -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. diff --git a/src/data/dictionary.h b/src/data/dictionary.h index 9990410a..581a49d8 100644 --- a/src/data/dictionary.h +++ b/src/data/dictionary.h @@ -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 */ diff --git a/src/ui/gui/ChangeLog b/src/ui/gui/ChangeLog index b5d9c6a8..80c3ae97 100644 --- a/src/ui/gui/ChangeLog +++ b/src/ui/gui/ChangeLog @@ -1,3 +1,21 @@ +2007-08-12 John Darrington + Ben Pfaff + + 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 * psppire-dict.c (psppire_dict_dump): Don't use @@ -6,22 +24,22 @@ 2007-08-13 John Darrington - * 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 - * 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 * syntax-editor.glade: Changed some properties to be less annoying. @@ -33,45 +51,45 @@ 2007-07-26 John Darrington - * 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 - * 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 - * 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 - * 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 - * 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 - * 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. @@ -82,46 +100,46 @@ 2007-07-08 John Darrington - * 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 * 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 - - * 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 - - * 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 - * 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 - * 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 Adapt case sources, sinks, and clients of procedure code to the new infrastructure. - + * automake.mk: Removed files. * flexifile-factory.c: Removed, dead code. @@ -137,21 +155,21 @@ * psppire-var-store.c (psppire_var_store_item_editable): Use var_is_alpha. - + 2007-05-07 John Darrington * 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 * 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. @@ -163,10 +181,10 @@ 2007-04-25 John Darrington * 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 @@ -174,7 +192,7 @@ * 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. @@ -190,25 +208,25 @@ builds. 2007-04-13 John Darrington - + * var-type-dialog.c: Added a FMT_DATETIME20 template. - + 2007-04-04 John Darrington * 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 @@ -218,33 +236,33 @@ assert that may or may not trap some Windows-related bugs. 2007-04-03 John Darrington - + * 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 - + * 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 - + * 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. @@ -255,20 +273,20 @@ conflict with POSIX function of same name. Tue Mar 13 17:20:05 CET 2007 John Darrington - * 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 - * 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 - * 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 @@ -290,10 +308,10 @@ Fri Jan 26 15:51:34 WST 2007 John Darrington * 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 * 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 * 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 @@ -327,33 +345,33 @@ Wed Jan 10 07:20:39 WST 2007 John Darrington * 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 - * 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 - * 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 @@ -373,16 +391,16 @@ Mon Dec 25 08:49:57 WST 2006 John Darrington Sun Dec 17 08:26:10 WST 2006 John Darrington - * 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 * psppire-data-store.c (geometry_get_justification): Don't assume @@ -399,16 +417,16 @@ Sat Dec 16 12:24:35 WST 2006 John Darrington * 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 @@ -435,50 +453,50 @@ Mon Jul 17 18:21:29 WST 2006 John Darrington Sat Jul 15 11:27:15 WST 2006 John Darrington - * 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 - + * psppire.c: Fixed --help and --version options. - + Sat Jun 24 16:56:22 WST 2006 John Darrington * 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 * 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 - * 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 - * 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 Sat May 27 16:25:38 WST 2006 John Darrington - * 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 @@ -512,24 +530,24 @@ Sat May 20 21:08:18 WST 2006 John Darrington * psppire.c: Allowed user to specify *.sav file on command line. Mon May 15 20:01:25 WST 2006 John Darrington - + * 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 - * 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 - * 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 * var-sheet.c: Changed maximum string length to use macro from data/values.h - + Sun May 7 10:07:28 WST 2006 John Darrington * psppire-data-store.c: Fixed buglet initialising string members. @@ -557,7 +575,7 @@ Tue Apr 25 11:08:04 2006 Ben Pfaff 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 @@ -583,7 +601,7 @@ Sun Apr 23 22:07:49 2006 Ben Pfaff 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 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 * Rename error-dialog.[ch] -> message-dialog.[ch] * Moved code from the psppire module. - + Sat Jan 28 16:22:23 WST 2006 John Darrington * Separated the data out of the GtkSheet. diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk index dff1a96c..df6f6d1e 100644 --- a/src/ui/gui/automake.mk +++ b/src/ui/gui/automake.mk @@ -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 index 00000000..b115a04a --- /dev/null +++ b/src/ui/gui/clipboard.c @@ -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 . */ + +#include + +#include +#include "clipboard.h" +#include +#include "psppire-data-store.h" +#include +#include +#include +#include +#include +#include +#include + + +/* 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, "\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, "\n"); + + for (c = 0 ; c < val_cnt ; ++c) + { + const struct variable *v = dict_get_var (clip_dict, c); + g_string_append (string, "\n"); + } + + g_string_append (string, "\n"); + + case_destroy (&cc); + } + g_string_append (string, "
"); + data_out_g_string (string, v, &cc); + g_string_append (string, "
\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 index 00000000..1cdffe8f --- /dev/null +++ b/src/ui/gui/clipboard.h @@ -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 . */ + +#include +#include + +#ifndef CLIPBOARD_H +#define CLIPBOARD_H + + +void data_sheet_set_clip (GtkSheet *data_sheet); + + +#endif /* CLIPBOARD_H */ + diff --git a/src/ui/gui/data-editor.c b/src/ui/gui/data-editor.c index 8fd9517d..50c181ee 100644 --- a/src/ui/gui/data-editor.c +++ b/src/ui/gui/data-editor.c @@ -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); +} + + diff --git a/src/ui/gui/data-editor.glade b/src/ui/gui/data-editor.glade index 24ee5807..4a626ebe 100644 --- a/src/ui/gui/data-editor.glade +++ b/src/ui/gui/data-editor.glade @@ -134,7 +134,7 @@ - + True False gtk-cut @@ -143,7 +143,7 @@ - + True False gtk-copy @@ -152,7 +152,7 @@ - + True False gtk-paste @@ -161,7 +161,7 @@ - + True False Paste _Variables -- 2.30.2