[gnumeric] Clipboard: code cleanup
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Clipboard: code cleanup
- Date: Sat, 21 Apr 2018 16:48:54 +0000 (UTC)
commit 0408e1a679817f7cb9e3e1ceed30a6c1ae0c41c3
Author: Morten Welinder <terra gnome org>
Date: Sat Apr 21 12:47:36 2018 -0400
Clipboard: code cleanup
src/gui-clipboard.c | 622 +++++++++++++++++++++++++++-----------------------
src/gui-clipboard.h | 3 +
src/libgnumeric.c | 3 +
3 files changed, 342 insertions(+), 286 deletions(-)
---
diff --git a/src/gui-clipboard.c b/src/gui-clipboard.c
index 1a78197..66fb0f4 100644
--- a/src/gui-clipboard.c
+++ b/src/gui-clipboard.c
@@ -49,65 +49,113 @@
#define APP_CLIP_DISP_KEY "clipboard-displays"
-static gboolean
-debug_clipboard (void)
-{
- static gboolean d_clipboard;
- static gboolean inited = FALSE;
-
- if (!inited) {
- inited = TRUE;
- d_clipboard = gnm_debug_flag ("clipboard");
- }
-
- return d_clipboard;
-}
+// ----------------------------------------------------------------------------
+
+static gboolean debug_clipboard;
+static gboolean debug_clipboard_dump;
+static gboolean debug_clipboard_undump;
+
+// ----------------------------------------------------------------------------
+
+enum {
+ ATOM_GNUMERIC,
+ ATOM_GOFFICE_GRAPH,
+ // ----------
+ ATOM_UTF8_STRING,
+ ATOM_STRING,
+ ATOM_COMPOUND_TEXT,
+ ATOM_TEXT_HTML,
+ ATOM_TEXT_HTML_WINDOWS,
+ // ----------
+ ATOM_BIFF8,
+ ATOM_BIFF8_OO,
+ ATOM_BIFF8_CITRIX,
+ ATOM_BIFF5,
+ ATOM_BIFF,
+ // ----------
+ ATOM_OOO,
+ ATOM_OOO_WINDOWS,
+ ATOM_OOO11,
+ // ----------
+ ATOM_IMAGE_SVGXML,
+ ATOM_IMAGE_XWMF,
+ ATOM_IMAGE_XEMF,
+ ATOM_IMAGE_PNG,
+ ATOM_IMAGE_JPEG,
+ ATOM_IMAGE_BMP,
+ // ----------
+ ATOM_SAVE_TARGETS,
+};
+
+static const char *const atom_names[] = {
+ "application/x-gnumeric",
+ "application/x-goffice-graph",
+ // ----------
+ "UTF8_STRING",
+ "STRING",
+ "COMPOUND_TEXT",
+ "text/html",
+ "HTML Format",
+ // ----------
+ "Biff8",
+ "application/x-openoffice-biff-8;windows_formatname=\"Biff8\"",
+ "_CITRIX_Biff8",
+ "Biff5",
+ "Biff",
+ // ----------
+ "application/x-openoffice;windows_formatname=\"Star Embed Source (XML)\"",
+ "Star Embed Source (XML)",
+ "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"",
+ // ----------
+ "image/svg+xml",
+ "image/x-wmf",
+ "image/x-emf",
+ "image/png",
+ "image/jpeg",
+ "image/bmp",
+ // ----------
+ "SAVE_TARGETS",
+};
+
+static GdkAtom atoms[G_N_ELEMENTS(atom_names)];
+
+typedef enum {
+ INFO_UNKNOWN,
+ INFO_GNUMERIC,
+ INFO_EXCEL,
+ INFO_OOO,
+ INFO_GENERIC_TEXT,
+ INFO_HTML,
+ INFO_OBJECT,
+ INFO_IMAGE,
+ INFO_STRING
+} AtomInfoType;
+
+static GtkTargetList *generic_text_targets;
+static GtkTargetList *image_targets;
+
+// ----------------------------------------------------------------------------
typedef struct {
WBCGtk *wbcg;
- GnmPasteTarget *paste_target;
- GdkAtom image_atom;
- GdkAtom string_atom;
+ GnmPasteTarget *paste_target;
} GnmGtkClipboardCtxt;
-/* The name of our clipboard atom and the 'magic' info number */
-#define GNUMERIC_ATOM_NAME "application/x-gnumeric"
-#define GNUMERIC_ATOM_INFO 2001
-#define GOFFICE_GRAPH_ATOM_NAME "application/x-goffice-graph"
+static void
+gnm_gtk_clipboard_context_free (GnmGtkClipboardCtxt *ctxt)
+{
+ g_free (ctxt->paste_target);
+ g_free (ctxt);
+}
/*
* Emacs hack:
* (x-get-selection-internal 'CLIPBOARD 'TARGETS)
*/
-/* From MS Excel */
-#define BIFF8_ATOM_NAME "Biff8"
-#define BIFF8_ATOM_NAME_CITRIX "_CITRIX_Biff8"
-#define BIFF8_ATOM_NAME_OO "application/x-openoffice-biff-8;windows_formatname=\"Biff8\""
-#define BIFF5_ATOM_NAME "Biff5"
-#define BIFF4_ATOM_NAME "Biff4"
-#define BIFF3_ATOM_NAME "Biff3"
-#define BIFF_ATOM_NAME "Biff"
-
-#define HTML_ATOM_NAME_UNIX "text/html"
-#define HTML_ATOM_NAME_WINDOWS "HTML Format"
-#ifdef G_OS_WIN32
-#define HTML_ATOM_NAME HTML_ATOM_NAME_WINDOWS
-#else
-#define HTML_ATOM_NAME HTML_ATOM_NAME_UNIX
-#endif
-
-#define OOO_ATOM_NAME "application/x-openoffice;windows_formatname=\"Star Embed Source (XML)\""
-#define OOO11_ATOM_NAME "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source
(XML)\""
-#define OOO_ATOM_NAME_WINDOWS "Star Embed Source (XML)"
-
-#define UTF8_ATOM_NAME "UTF8_STRING"
-#define CTEXT_ATOM_NAME "COMPOUND_TEXT"
-#define STRING_ATOM_NAME "STRING"
-
- /* See if this is a "single line + line end", a "multiline" or a "tab separated"
- * string. If this is _not_ the case we won't invoke the STF, it is
- * unlikely that the user will actually need it in this case. */
+/* See if this is a "single line + line end", a "multiline" or a "tab separated"
+ * string. If this is _not_ the case we won't invoke the STF, it is
+ * unlikely that the user will actually need it in this case. */
static gboolean
text_is_single_cell (gchar const *data, int data_len)
{
@@ -199,7 +247,7 @@ text_to_cell_region (WBCGtk *wbcg,
}
static void
-text_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
+text_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
gpointer closure)
{
GnmGtkClipboardCtxt *ctxt = closure;
@@ -210,12 +258,11 @@ text_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
GdkAtom target = gtk_selection_data_get_target (sel);
int sel_len = gtk_selection_data_get_length (sel);
- if (debug_clipboard ()) {
+ if (debug_clipboard) {
int maxlen = 1024;
char *name = gdk_atom_name (gtk_selection_data_get_target (sel));
g_printerr ("Received %d bytes of text for target %s\n",
- sel_len,
- name);
+ sel_len, name);
g_free (name);
if (sel_len > 0) {
gsf_mem_dump (gtk_selection_data_get_data (sel), MIN (sel_len, maxlen));
@@ -227,15 +274,15 @@ text_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
/* Nothing on clipboard? */
if (sel_len < 0) {
;
- } else if (target == gdk_atom_intern (UTF8_ATOM_NAME, FALSE)) {
+ } else if (target == atoms[ATOM_UTF8_STRING]) {
content = text_to_cell_region (wbcg, (const char *)gtk_selection_data_get_data (sel),
sel_len, "UTF-8", TRUE);
- } else if (target == gdk_atom_intern (CTEXT_ATOM_NAME, FALSE)) {
+ } else if (target == atoms[ATOM_COMPOUND_TEXT]) {
/* COMPOUND_TEXT is icky. Just let GTK+ do the work. */
char *data_utf8 = (char *)gtk_selection_data_get_text (sel);
content = text_to_cell_region (wbcg, data_utf8, strlen (data_utf8), "UTF-8", TRUE);
g_free (data_utf8);
- } else if (target == gdk_atom_intern (STRING_ATOM_NAME, FALSE)) {
+ } else if (target == atoms[ATOM_STRING]) {
char const *locale_encoding;
g_get_charset (&locale_encoding);
@@ -253,8 +300,8 @@ text_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
/* Release the resources we used */
cellregion_unref (content);
}
- g_free (ctxt->paste_target);
- g_free (ctxt);
+
+ gnm_gtk_clipboard_context_free (ctxt);
}
static void
@@ -284,8 +331,8 @@ utf8_content_received (GtkClipboard *clipboard, const gchar *text,
/* Release the resources we used */
cellregion_unref (content);
}
- g_free (ctxt->paste_target);
- g_free (ctxt);
+
+ gnm_gtk_clipboard_context_free (ctxt);
}
/*
@@ -380,7 +427,7 @@ image_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
GnmPasteTarget *pt = ctxt->paste_target;
int sel_len = gtk_selection_data_get_length (sel);
- if (debug_clipboard ()) {
+ if (debug_clipboard) {
int maxlen = 1024;
char *name = gdk_atom_name (gtk_selection_data_get_target (sel));
g_printerr ("Received %d bytes of image for target %s\n",
@@ -397,15 +444,9 @@ image_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
if (sel_len > 0) {
scg_paste_image (wbcg_cur_scg (wbcg), &pt->range,
gtk_selection_data_get_data (sel), sel_len);
- g_free (ctxt->paste_target);
- g_free (ctxt);
- } else if (ctxt->string_atom != GDK_NONE) {
- gtk_clipboard_request_contents (clipboard, ctxt->string_atom,
- text_content_received, ctxt);
- } else {
- g_free (ctxt->paste_target);
- g_free (ctxt);
}
+
+ gnm_gtk_clipboard_context_free (ctxt);
}
static void
@@ -448,7 +489,7 @@ parse_ms_headers (const char *data, size_t length, size_t *start, size_t *end)
i = k;
- if (debug_clipboard ())
+ if (debug_clipboard)
g_printerr ("MS HTML Header [%s] => [%s]\n", key, value);
if (strcmp (key, "StartHTML") == 0) {
@@ -498,7 +539,7 @@ table_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
const guint8 *buffer = gtk_selection_data_get_data (sel);
int sel_len = gtk_selection_data_get_length (sel);
- if (debug_clipboard ()) {
+ if (debug_clipboard) {
int maxlen = 1024;
char *name = gdk_atom_name (gtk_selection_data_get_target (sel));
g_printerr ("Received %d bytes of table for target %s\n",
@@ -519,7 +560,7 @@ table_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
/* Nothing on clipboard? */
if (sel_len < 0) {
;
- } else if (target == gdk_atom_intern (GNUMERIC_ATOM_NAME, FALSE)) {
+ } else if (target == atoms[ATOM_GNUMERIC]) {
/* The data is the gnumeric specific XML interchange format */
GOIOContext *io_context =
go_io_context_new (GO_CMD_CONTEXT (wbcg));
@@ -528,17 +569,17 @@ table_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
pt->sheet,
(const char *)buffer, sel_len);
g_object_unref (io_context);
- } else if (target == gdk_atom_intern (OOO_ATOM_NAME, FALSE) ||
- target == gdk_atom_intern (OOO_ATOM_NAME_WINDOWS, FALSE) ||
- target == gdk_atom_intern (OOO11_ATOM_NAME, FALSE)) {
+ } else if (target == atoms[ATOM_OOO] ||
+ target == atoms[ATOM_OOO_WINDOWS] ||
+ target == atoms[ATOM_OOO11]) {
content = table_cellregion_read (wbc, "Gnumeric_OpenCalc:openoffice",
pt, buffer,
sel_len);
- } else if (target == gdk_atom_intern (HTML_ATOM_NAME_UNIX, FALSE) ||
- target == gdk_atom_intern (HTML_ATOM_NAME_WINDOWS, FALSE)) {
+ } else if (target == atoms[ATOM_TEXT_HTML] ||
+ target == atoms[ATOM_TEXT_HTML_WINDOWS]) {
size_t start = 0, end = sel_len;
- if (target == gdk_atom_intern (HTML_ATOM_NAME_WINDOWS, FALSE)) {
+ if (target == atoms[ATOM_TEXT_HTML_WINDOWS]) {
/* See bug 143084 */
parse_ms_headers (buffer, sel_len, &start, &end);
}
@@ -547,12 +588,11 @@ table_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
pt,
buffer + start,
end - start);
- } else if ((target == gdk_atom_intern ( BIFF8_ATOM_NAME, FALSE)) ||
- (target == gdk_atom_intern ( BIFF8_ATOM_NAME_CITRIX, FALSE)) ||
- (target == gdk_atom_intern ( BIFF5_ATOM_NAME, FALSE)) ||
- (target == gdk_atom_intern ( BIFF4_ATOM_NAME, FALSE)) ||
- (target == gdk_atom_intern ( BIFF3_ATOM_NAME, FALSE)) ||
- (target == gdk_atom_intern ( BIFF_ATOM_NAME, FALSE))) {
+ } else if (target == atoms[ATOM_BIFF8] ||
+ target == atoms[ATOM_BIFF8_CITRIX] ||
+ target == atoms[ATOM_BIFF8_OO] ||
+ target == atoms[ATOM_BIFF5] ||
+ target == atoms[ATOM_BIFF]) {
content = table_cellregion_read (wbc, "Gnumeric_Excel:excel",
pt, buffer,
sel_len);
@@ -568,18 +608,19 @@ table_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
/* Release the resources we used */
cellregion_unref (content);
- g_free (ctxt->paste_target);
- g_free (ctxt);
- } else if (ctxt->image_atom != GDK_NONE) {
- gtk_clipboard_request_contents (clipboard, ctxt->image_atom,
- image_content_received, ctxt);
- } else if (ctxt->string_atom != GDK_NONE) {
- gtk_clipboard_request_contents (clipboard, ctxt->string_atom,
- text_content_received, ctxt);
- } else {
- g_free (ctxt->paste_target);
- g_free (ctxt);
}
+
+ gnm_gtk_clipboard_context_free (ctxt);
+}
+
+static gboolean
+find_in_table (GdkAtom *targets, int n, GdkAtom a)
+{
+ int i;
+ for (i = 0; i < n; i++)
+ if (targets[i] == a)
+ return TRUE;
+ return FALSE;
}
/**
@@ -597,105 +638,78 @@ x_targets_received (GtkClipboard *clipboard, GdkAtom *targets,
gint n_targets, gpointer closure)
{
GnmGtkClipboardCtxt *ctxt = closure;
- GdkAtom table_atom = GDK_NONE;
- gint i, j;
-
- /* in order of preference */
- static char const *table_fmts [] = {
- GNUMERIC_ATOM_NAME,
-
- BIFF8_ATOM_NAME,
- BIFF8_ATOM_NAME_CITRIX,
- BIFF5_ATOM_NAME,
- BIFF4_ATOM_NAME,
- BIFF3_ATOM_NAME,
- BIFF_ATOM_NAME,
-
- OOO_ATOM_NAME,
- OOO11_ATOM_NAME,
- OOO_ATOM_NAME_WINDOWS,
-
- HTML_ATOM_NAME_UNIX,
- HTML_ATOM_NAME_WINDOWS,
- NULL
+ int i;
+ unsigned ui;
+
+ // In order of preference
+ static const int table_fmts[] = {
+ ATOM_GNUMERIC,
+ ATOM_BIFF8, ATOM_BIFF8_CITRIX,
+ ATOM_OOO, ATOM_OOO11, ATOM_OOO_WINDOWS,
+ ATOM_BIFF5, ATOM_BIFF,
+ ATOM_TEXT_HTML, ATOM_TEXT_HTML_WINDOWS,
};
- static char const *string_fmts [] = {
- UTF8_ATOM_NAME,
- STRING_ATOM_NAME,
- CTEXT_ATOM_NAME,
- NULL
+
+ // In order of preference
+ static const int string_fmts[] = {
+ ATOM_UTF8_STRING,
+ ATOM_STRING,
+ ATOM_COMPOUND_TEXT
};
- /* Nothing on clipboard? */
+ // Nothing on clipboard? Try text.
if (targets == NULL || n_targets == 0) {
gtk_clipboard_request_text (clipboard, utf8_content_received,
ctxt);
return;
}
- if (debug_clipboard ()) {
+ if (debug_clipboard) {
int j;
- for (j = 0; j < n_targets; j++)
+ for (j = 0; j < n_targets; j++) {
+ char *name = gdk_atom_name (targets[j]);
g_printerr ("Clipboard target %d is %s\n",
- j, gdk_atom_name (targets[j]));
+ j, name);
+ g_free (name);
+ }
}
- /* The data is a list of atoms */
- /* Find the best table format offered */
- for (i = 0 ; table_fmts[i] && table_atom == GDK_NONE ; i++) {
- /* Look for one we can use */
- GdkAtom atom = gdk_atom_intern (table_fmts[i], FALSE);
- /* is it on offer? */
- for (j = 0; j < n_targets && table_atom == GDK_NONE; j++) {
- if (targets [j] == atom)
- table_atom = atom;
+ // First look for anything that can be considered a spreadsheet
+ for (ui = 0; ui < G_N_ELEMENTS(table_fmts); ui++) {
+ GdkAtom atom = atoms[table_fmts[ui]];
+ if (find_in_table (targets, n_targets, atom)) {
+ gtk_clipboard_request_contents (clipboard, atom,
+ table_content_received,
+ ctxt);
+ return;
}
}
- if (table_atom == GDK_NONE) {
- GtkTargetList *tl = gtk_target_list_new (NULL, 0);
- gboolean found = FALSE;
-
- gtk_target_list_add_image_targets (tl, 0, FALSE);
-
- /* Find an image format */
- for (i = 0 ; i < n_targets && !found; i++) {
- if (gtk_target_list_find (tl, targets[i], NULL)) {
- ctxt->image_atom = targets[i];
- found = TRUE;
- }
+ // Try an image format
+ for (i = 0; i < n_targets; i++) {
+ GdkAtom atom = targets[i];
+ if (gtk_target_list_find (image_targets, atom, NULL)) {
+ gtk_clipboard_request_contents (clipboard, atom,
+ image_content_received,
+ ctxt);
+ return;
}
- gtk_target_list_unref (tl);
}
- /* Find a string format to fall back to */
- for (i = 0 ; string_fmts[i] && ctxt->string_atom == GDK_NONE ; i++) {
- /* Look for one we can use */
- GdkAtom atom = gdk_atom_intern (string_fmts[i], FALSE);
- /* is it on offer? */
- for (j = 0; j < n_targets && ctxt->string_atom == GDK_NONE;
- j++) {
- if (targets [j] == atom)
- ctxt->string_atom = atom;
+ // Try a string format
+ for (ui = 0; ui < G_N_ELEMENTS (string_fmts); ui++) {
+ GdkAtom atom = atoms[string_fmts[ui]];
+ if (find_in_table (targets, n_targets, atom)) {
+ gtk_clipboard_request_contents (clipboard, atom,
+ text_content_received,
+ ctxt);
+ return;
}
- if (ctxt->string_atom != GDK_NONE)
- break;
}
- if (table_atom != GDK_NONE)
- gtk_clipboard_request_contents (clipboard, table_atom,
- table_content_received, ctxt);
- else if (ctxt->image_atom != GDK_NONE)
- gtk_clipboard_request_contents (clipboard, ctxt->image_atom,
- image_content_received, ctxt);
- else if (ctxt->string_atom != GDK_NONE)
- gtk_clipboard_request_contents (clipboard, ctxt->string_atom,
- text_content_received, ctxt);
- else {
- g_free (ctxt->paste_target);
- g_free (ctxt);
- }
+ // Give up
+ gnm_gtk_clipboard_context_free (ctxt);
}
/* Cheezy implementation: paste into a temporary workbook, save that. */
@@ -889,7 +903,7 @@ object_write (GnmCellRegion *cr, gchar const *mime_type, int *size)
*/
static void
x_clipboard_get_cb (GtkClipboard *gclipboard, GtkSelectionData *selection_data,
- guint info, GObject *app)
+ guint info_, gpointer app)
{
gboolean to_gnumeric = FALSE, content_needs_free = FALSE;
GnmCellRegion *clipboard = gnm_app_clipboard_contents_get ();
@@ -897,18 +911,19 @@ x_clipboard_get_cb (GtkClipboard *gclipboard, GtkSelectionData *selection_data,
GnmRange const *a = gnm_app_clipboard_area_get ();
GOCmdContext *ctx = gnm_cmd_context_stderr_new ();
GdkAtom target = gtk_selection_data_get_target (selection_data);
+ AtomInfoType info = info_;
gchar *target_name = gdk_atom_name (target);
- if (debug_clipboard ())
- g_printerr ("clipboard target=%s\n", target_name);
+ if (debug_clipboard)
+ g_printerr ("clipboard requested, target=%s\n", target_name);
/*
* There are 4 cases. What variables are valid depends on case:
* source is
- * a cut: clipboard NULL, sheet, area non NULL.
- * a copy: clipboard, sheet, area all non NULL.
+ * a cut: clipboard NULL, sheet, area non-NULL.
+ * a copy: clipboard, sheet, area all non-NULL.
* a cut, source closed: clipboard, sheet, area all NULL.
- * a copy, source closed: clipboard non NULL, sheet, area non NULL.
+ * a copy, source closed: clipboard non-NULL, sheet, area non-NULL.
*
* If the source is a cut, we copy it for pasting. We
* postpone clearing it until after the selection has been
@@ -923,7 +938,7 @@ x_clipboard_get_cb (GtkClipboard *gclipboard, GtkSelectionData *selection_data,
goto out;
/* What format does the other application want? */
- if (target == gdk_atom_intern (GNUMERIC_ATOM_NAME, FALSE)) {
+ if (target == atoms[ATOM_GNUMERIC]) {
GsfOutputMemory *output = gnm_cellregion_to_xml (clipboard);
if (output) {
gsf_off_t size = gsf_output_size (GSF_OUTPUT (output));
@@ -932,7 +947,7 @@ x_clipboard_get_cb (GtkClipboard *gclipboard, GtkSelectionData *selection_data,
g_file_set_contents ("paste-from-gnumeric.dat",
data, size, NULL);
}
- if (debug_clipboard ())
+ if (debug_clipboard)
g_printerr ("clipboard .gnumeric of %d bytes\n",
(int)size);
gtk_selection_data_set
@@ -942,74 +957,72 @@ x_clipboard_get_cb (GtkClipboard *gclipboard, GtkSelectionData *selection_data,
g_object_unref (output);
to_gnumeric = TRUE;
}
- } else if (target == gdk_atom_intern (HTML_ATOM_NAME, FALSE)) {
+ } else if (info == INFO_HTML) {
const char *saver_id = "Gnumeric_html:xhtml_range";
int buffer_size;
guchar *buffer = table_cellregion_write (ctx, clipboard,
saver_id,
&buffer_size);
- if (debug_clipboard ())
+ if (debug_clipboard)
g_message ("clipboard html of %d bytes",
buffer_size);
gtk_selection_data_set (selection_data,
target, 8,
buffer, buffer_size);
g_free (buffer);
- } else if (target == gdk_atom_intern (BIFF8_ATOM_NAME, FALSE) ||
- target == gdk_atom_intern (BIFF8_ATOM_NAME_CITRIX, FALSE) ||
- target == gdk_atom_intern (BIFF8_ATOM_NAME_OO, FALSE)) {
+ } else if (info == INFO_EXCEL) {
const char *saver_id = "Gnumeric_Excel:excel_biff8";
int buffer_size;
guchar *buffer = table_cellregion_write (ctx, clipboard,
saver_id,
&buffer_size);
- if (debug_clipboard ())
+ if (debug_clipboard)
g_message ("clipboard biff8 of %d bytes",
buffer_size);
gtk_selection_data_set (selection_data,
target, 8,
buffer, buffer_size);
g_free (buffer);
- } else if (strcmp (target_name, "application/x-goffice-graph") == 0 ||
+ } else if (target == atoms[ATOM_GOFFICE_GRAPH] ||
g_slist_find_custom (go_components_get_mime_types (), target_name, (GCompareFunc) strcmp)
!= NULL) {
int buffer_size;
guchar *buffer = object_write (clipboard, target_name,
&buffer_size);
- if (debug_clipboard ())
+ if (debug_clipboard)
g_message ("clipboard graph of %d bytes",
buffer_size);
gtk_selection_data_set (selection_data,
target, 8,
buffer, buffer_size);
g_free (buffer);
- } else if (strncmp (target_name, "image/", 6) == 0) {
+ } else if (info == INFO_IMAGE) {
int buffer_size;
guchar *buffer = image_write (clipboard, target_name,
&buffer_size);
- if (debug_clipboard ())
+ if (debug_clipboard)
g_message ("clipboard image of %d bytes",
buffer_size);
gtk_selection_data_set (selection_data,
target, 8,
buffer, buffer_size);
g_free (buffer);
- } else if (strcmp (target_name, "SAVE_TARGETS") == 0) {
+ } else if (target == atoms[ATOM_SAVE_TARGETS]) {
/* We implicitly registered this when calling
* gtk_clipboard_set_can_store. We're supposed to
* ignore it. */
- } else if (clipboard->origin_sheet) {
+ } else if (info == INFO_STRING) {
Workbook *wb = clipboard->origin_sheet->workbook;
GString *res = cellregion_to_string (clipboard,
TRUE, workbook_date_conv (wb));
if (res != NULL) {
- if (debug_clipboard ())
+ if (debug_clipboard)
g_message ("clipboard text of %d bytes",
(int)res->len);
gtk_selection_data_set_text (selection_data,
res->str, res->len);
g_string_free (res, TRUE);
} else {
- if (debug_clipboard ())
+ if (debug_clipboard)
g_message ("clipboard empty text");
gtk_selection_data_set_text (selection_data, "", 0);
}
@@ -1057,16 +1070,13 @@ x_clipboard_get_cb (GtkClipboard *gclipboard, GtkSelectionData *selection_data,
*
* Callback for the "we lost the X selection" signal.
*/
-static gint
-x_clipboard_clear_cb (GtkClipboard *clipboard,
- GObject *obj)
+static void
+x_clipboard_clear_cb (GtkClipboard *clipboard, gpointer app_)
{
- if (debug_clipboard ())
+ if (debug_clipboard)
g_printerr ("Lost clipboard ownership.\n");
gnm_app_clipboard_clear (FALSE);
-
- return TRUE;
}
void
@@ -1085,8 +1095,6 @@ gnm_x_request_clipboard (WBCGtk *wbcg, GnmPasteTarget const *pt)
ctxt->wbcg = wbcg;
ctxt->paste_target = g_new (GnmPasteTarget, 1);
*ctxt->paste_target = *pt;
- ctxt->image_atom = GDK_NONE;
- ctxt->string_atom = GDK_NONE;
/* Query the formats, This will callback x_targets_received */
gtk_clipboard_request_targets (clipboard,
@@ -1096,48 +1104,67 @@ gnm_x_request_clipboard (WBCGtk *wbcg, GnmPasteTarget const *pt)
/* Restrict the set of formats offered to clipboard manager. */
/* We include bmp in the whitelist because that's the only image format
* we share with OOo over clipboard (!) */
+
+static gboolean
+is_clipman_target (const char *target)
+{
+ return (g_str_equal (target, atom_names[ATOM_GNUMERIC]) ||
+ g_str_equal (target, atom_names[ATOM_GOFFICE_GRAPH]) ||
+ g_str_equal (target, atom_names[ATOM_TEXT_HTML]) ||
+ g_str_equal (target, atom_names[ATOM_UTF8_STRING]) ||
+ g_str_equal (target, atom_names[ATOM_BIFF8_OO]) ||
+ g_str_equal (target, atom_names[ATOM_IMAGE_SVGXML]) ||
+ g_str_equal (target, atom_names[ATOM_IMAGE_XWMF]) ||
+ g_str_equal (target, atom_names[ATOM_IMAGE_XEMF]) ||
+ g_str_equal (target, atom_names[ATOM_IMAGE_PNG]) ||
+ g_str_equal (target, atom_names[ATOM_IMAGE_JPEG]) ||
+ g_str_equal (target, atom_names[ATOM_IMAGE_BMP]));
+}
+
static void
-set_clipman_targets (GdkDisplay *disp, GtkTargetEntry *targets, guint n_targets)
+set_clipman_targets (GdkDisplay *disp, GArray *targets)
{
- static GtkTargetEntry clipman_whitelist[] = {
- { (char *) GNUMERIC_ATOM_NAME, 0, GNUMERIC_ATOM_INFO },
- { (char *) BIFF8_ATOM_NAME_OO, 0, 0 },
- { (char *) HTML_ATOM_NAME, 0, 0 },
- { (char *)"UTF8_STRING", 0, 0 },
- { (char *)"application/x-goffice-graph", 0, 0 },
- { (char *)"image/svg+xml", 0, 0 },
- { (char *)"image/x-wmf", 0, 0 },
- { (char *)"image/x-emf", 0, 0 },
- { (char *)"image/png", 0, 0 },
- { (char *)"image/jpeg", 0, 0 },
- { (char *)"image/bmp", 0, 0 },
- };
- guint n_whitelist = G_N_ELEMENTS (clipman_whitelist);
- int n_allowed;
- GtkTargetList *tl = gtk_target_list_new (NULL, 0);
- GtkTargetEntry *t, *wt, *t_allowed;
-
- for (t = targets; t < targets + n_targets; t++) {
- for (wt = clipman_whitelist;
- wt < clipman_whitelist + n_whitelist; wt++) {
- if (strcmp(t->target, wt->target) == 0) {
- gtk_target_list_add
- (tl, gdk_atom_intern (t->target, FALSE),
- t->flags, t->info);
- break;
- }
- }
+ GArray *allowed = g_array_new (FALSE, FALSE, sizeof (GtkTargetEntry));
+ unsigned ui;
+
+ for (ui = 0; ui < targets->len; ui++) {
+ GtkTargetEntry *te = &g_array_index (targets, GtkTargetEntry, ui);
+ if (is_clipman_target (te->target))
+ g_array_append_val (allowed, *te);
}
- t_allowed = gtk_target_table_new_from_list (tl, &n_allowed);
- gtk_target_list_unref (tl);
+ gtk_clipboard_set_can_store
+ (gtk_clipboard_get_for_display
+ (disp, GDK_SELECTION_CLIPBOARD),
+ &g_array_index (allowed, GtkTargetEntry, 0),
+ allowed->len);
+
+ g_array_free (allowed, TRUE);
+}
+
+static void
+add_target (GArray *targets, const char *target, int flags, AtomInfoType info)
+{
+ GtkTargetEntry t;
+ t.target = (char *)target;
+ t.flags = flags;
+ t.info = info;
+ g_array_append_val (targets, t);
+}
+
- gtk_clipboard_set_can_store (
- gtk_clipboard_get_for_display (
- disp, GDK_SELECTION_CLIPBOARD),
- t_allowed, n_allowed);
- gtk_target_table_free (t_allowed, n_allowed);
- t_allowed = NULL;
+static void
+add_target_list (GArray *targets, GtkTargetList *src, AtomInfoType info)
+{
+ int n;
+ GtkTargetEntry *entries = gtk_target_table_new_from_list (src, &n);
+ unsigned ui = targets->len;
+ g_array_append_vals (targets, entries, n);
+ if (info != INFO_UNKNOWN) {
+ for (; ui < targets->len; ui++)
+ g_array_index (targets, GtkTargetEntry, ui).info = info;
+ }
+ gtk_target_table_free (entries, n);
}
gboolean
@@ -1145,77 +1172,69 @@ gnm_x_claim_clipboard (GdkDisplay *display)
{
GnmCellRegion *content = gnm_app_clipboard_contents_get ();
SheetObject *imageable = NULL, *exportable = NULL;
- GtkTargetEntry *targets = NULL;
- gboolean free_targets = FALSE;
- int n_targets;
+ GArray *targets = g_array_new (FALSE, FALSE, sizeof (GtkTargetEntry));
gboolean ret;
GObject *app = gnm_app_get_app ();
+ gboolean no_cells = (!content) || (content->cols <= 0 || content->rows <= 0);
- static GtkTargetEntry const table_targets[] = {
- { (char *)GNUMERIC_ATOM_NAME, 0, GNUMERIC_ATOM_INFO },
- { (char *)BIFF8_ATOM_NAME, 0, 0 },
- { (char *)BIFF8_ATOM_NAME_CITRIX, 0, 0 },
- { (char *)BIFF8_ATOM_NAME_OO, 0, 0 },
- { (char *)HTML_ATOM_NAME, 0, 0 },
- { (char *)"UTF8_STRING", 0, 0 },
- { (char *)"COMPOUND_TEXT", 0, 0 },
- { (char *)"STRING", 0, 0 },
- };
+ if (no_cells) {
+ GSList *ptr = content ? content->objects : NULL;
+
+ add_target (targets, atom_names[ATOM_GNUMERIC], 0, INFO_GNUMERIC);
- targets = (GtkTargetEntry *) table_targets;
- n_targets = G_N_ELEMENTS (table_targets);
- if (content &&
- (content->cols <= 0 || content->rows <= 0)) {
- GSList *ptr;
- for (ptr = content->objects; ptr != NULL;
- ptr = ptr->next) {
+ for (; ptr != NULL; ptr = ptr->next) {
SheetObject *candidate = GNM_SO (ptr->data);
if (exportable == NULL && GNM_IS_SO_EXPORTABLE (candidate))
exportable = candidate;
if (imageable == NULL && GNM_IS_SO_IMAGEABLE (candidate))
imageable = candidate;
}
- /* Currently, we can't render sheet objects as text or html */
- // Also cuts biff8
- n_targets = 1;
+ } else {
+ add_target (targets, atom_names[ATOM_GNUMERIC], 0, INFO_GNUMERIC);
+ add_target (targets, atom_names[ATOM_BIFF8], 0, INFO_EXCEL);
+ add_target (targets, atom_names[ATOM_BIFF8_CITRIX], 0, INFO_EXCEL);
+ add_target (targets, atom_names[ATOM_BIFF8_OO], 0, INFO_EXCEL);
+#ifdef G_OS_WIN32
+ add_target (targets, atom_names[ATOM_TEXT_HTML_WINDOWS], 0, INFO_HTML);
+#else
+ add_target (targets, atom_names[ATOM_TEXT_HTML], 0, INFO_HTML);
+#endif
+ add_target (targets, atom_names[ATOM_UTF8_STRING], 0, INFO_STRING);
+ add_target (targets, atom_names[ATOM_COMPOUND_TEXT], 0, INFO_STRING);
+ add_target (targets, atom_names[ATOM_STRING], 0, INFO_STRING);
}
+
if (exportable) {
GtkTargetList *tl =
sheet_object_exportable_get_target_list (exportable);
- /* _add_table prepends to target_list */
- gtk_target_list_add_table (tl, table_targets, 1);
- targets = gtk_target_table_new_from_list (tl, &n_targets);
+ add_target_list (targets, tl, INFO_OBJECT);
gtk_target_list_unref (tl);
- free_targets = TRUE;
}
+
if (imageable) {
GtkTargetList *tl =
sheet_object_get_target_list (imageable);
- /* _add_table prepends to target_list */
- gtk_target_list_add_table (tl, targets, (exportable)? n_targets: 1);
- if (free_targets)
- gtk_target_table_free (targets, n_targets);
- targets = gtk_target_table_new_from_list (tl, &n_targets);
+ add_target_list (targets, tl, INFO_IMAGE);
gtk_target_list_unref (tl);
- free_targets = TRUE;
}
+
/* Register a x_clipboard_clear_cb only for CLIPBOARD, not for
* PRIMARY */
ret = gtk_clipboard_set_with_owner (
gtk_clipboard_get_for_display (display, GDK_SELECTION_CLIPBOARD),
- targets, n_targets,
- (GtkClipboardGetFunc) x_clipboard_get_cb,
- (GtkClipboardClearFunc) x_clipboard_clear_cb,
+ &g_array_index(targets,GtkTargetEntry,0), targets->len,
+ x_clipboard_get_cb,
+ x_clipboard_clear_cb,
app);
if (ret) {
- if (debug_clipboard ()) {
- int i;
+ if (debug_clipboard) {
+ unsigned ui;
g_printerr ("Clipboard successfully claimed.\n");
g_printerr ("Clipboard targets offered: ");
- for (i = 0; i < n_targets; i++) {
+ for (ui = 0; ui < targets->len; ui++) {
g_printerr ("%s%s",
- (i ? ", " : ""),
- targets[i].target);
+ (ui ? ", " : ""),
+ g_array_index(targets,GtkTargetEntry,ui).target);
}
g_printerr ("\n");
}
@@ -1225,21 +1244,20 @@ gnm_x_claim_clipboard (GdkDisplay *display)
display),
(GDestroyNotify)g_slist_free);
-
- set_clipman_targets (display, targets, n_targets);
+ set_clipman_targets (display, targets);
(void)gtk_clipboard_set_with_owner (
gtk_clipboard_get_for_display (display,
GDK_SELECTION_PRIMARY),
- targets, n_targets,
- (GtkClipboardGetFunc) x_clipboard_get_cb,
+ &g_array_index(targets,GtkTargetEntry,0), targets->len,
+ x_clipboard_get_cb,
NULL,
app);
} else {
- if (debug_clipboard ())
+ if (debug_clipboard)
g_printerr ("Failed to claim clipboard.\n");
}
- if (free_targets)
- gtk_target_table_free (targets, n_targets);
+
+ g_array_free (targets, TRUE);
return ret;
}
@@ -1287,10 +1305,42 @@ gnm_x_store_clipboard_if_needed (Workbook *wb)
(GTK_WIDGET (wbcg_toplevel (wbcg))),
GDK_SELECTION_CLIPBOARD);
if (gtk_clipboard_get_owner (clip) == gnm_app_get_app ()) {
- if (debug_clipboard ())
+ if (debug_clipboard)
g_printerr ("Handing off clipboard\n");
gtk_clipboard_store (clip);
}
}
}
}
+
+/**
+ * gui_clipboard_init: (skip)
+ */
+void
+gui_clipboard_init (void)
+{
+ unsigned ui;
+
+ debug_clipboard = gnm_debug_flag ("clipboard");
+ debug_clipboard_dump = gnm_debug_flag ("clipboard-dump");
+ debug_clipboard_undump = gnm_debug_flag ("clipboard-undump");
+
+ for (ui = 0; ui < G_N_ELEMENTS (atoms); ui++)
+ atoms[ui] = gdk_atom_intern_static_string (atom_names[ui]);
+
+ generic_text_targets = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add_text_targets (generic_text_targets, INFO_STRING);
+
+ image_targets = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add_image_targets (image_targets, 0, FALSE);
+}
+
+/**
+ * gui_clipboard_shutdown: (skip)
+ */
+void
+gui_clipboard_shutdown (void)
+{
+ gtk_target_list_unref (generic_text_targets);
+ gtk_target_list_unref (image_targets);
+}
diff --git a/src/gui-clipboard.h b/src/gui-clipboard.h
index 6206328..307d769 100644
--- a/src/gui-clipboard.h
+++ b/src/gui-clipboard.h
@@ -12,6 +12,9 @@ void gnm_x_store_clipboard_if_needed (Workbook *wb);
gboolean gnm_x_claim_clipboard (GdkDisplay *display);
void gnm_x_disown_clipboard (void);
+void gui_clipboard_init (void);
+void gui_clipboard_shutdown (void);
+
G_END_DECLS
#endif /* _GNM_GUI_CLIPBOARD_H_ */
diff --git a/src/libgnumeric.c b/src/libgnumeric.c
index eac55e0..7b15abe 100644
--- a/src/libgnumeric.c
+++ b/src/libgnumeric.c
@@ -48,6 +48,7 @@
#include "sheet-private.h"
#include "xml-sax.h"
#include "clipboard.h"
+#include "gui-clipboard.h"
#include "value.h"
#include "expr.h"
#include "expr-deriv.h"
@@ -321,6 +322,7 @@ gnm_init (void)
_gnm_expr_init ();
gnm_sheet_cell_init ();
clipboard_init ();
+ gui_clipboard_init ();
dependent_types_init ();
gnm_rendered_value_init ();
functions_init ();
@@ -363,6 +365,7 @@ gnm_shutdown (void)
gnm_rendered_value_shutdown ();
dependent_types_shutdown ();
+ gui_clipboard_shutdown ();
clipboard_shutdown ();
gnm_sheet_cell_shutdown ();
_gnm_expr_deriv_shutdown ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]