From be129f071c3d7b400c5b8a4ed145b6011123819f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 6 Jan 2020 23:26:00 +0100 Subject: Fixes for copy, add text paste and hooks for SC paste --- libstorycode/gtk/gtknarrativeview.c | 241 ++++++++++++++++------------------ libstorycode/narrative.c | 1 - libstorycode/narrative_render_cairo.c | 4 +- libstorycode/narrative_render_cairo.h | 2 + libstorycode/storycode.c | 3 +- 5 files changed, 117 insertions(+), 134 deletions(-) diff --git a/libstorycode/gtk/gtknarrativeview.c b/libstorycode/gtk/gtknarrativeview.c index 409b48b..480f5c6 100644 --- a/libstorycode/gtk/gtknarrativeview.c +++ b/libstorycode/gtk/gtknarrativeview.c @@ -32,6 +32,8 @@ #include #include #include +#include +#define _(x) gettext(x) #include #include @@ -297,129 +299,18 @@ static void gtk_narrative_view_init(GtkNarrativeView *e) } -static void paste_storycode_received(GtkClipboard *cb, GtkSelectionData *seldata, - gpointer vp) -{ -// GtkNarrativeView *e = vp; -// SCBlock *nf; -// const guchar *t; -// -// t = gtk_selection_data_get_data(seldata); -// -// printf("received storycode paste\n"); -// printf("'%s'\n", t); -// if ( t == NULL ) return; -// -// /* FIXME: It might not be a new frame */ -// nf = sc_parse((char *)t); -// show_sc_blocks(nf); -// sc_block_append_block(sc_block_child(e->scblocks), nf); -// full_rerender(e); -} - - -static void paste_text_received(GtkClipboard *cb, GtkSelectionData *seldata, - gpointer vp) -{ -// GtkNarrativeView *e = vp; -// SCBlock *bl; -// guchar *t; -// SCBlock *cur_bl; -// size_t cur_sc_pos; -// size_t offs; -// Paragraph *para; -// -// t = gtk_selection_data_get_text(seldata); -// -// printf("received text paste\n"); -// printf("'%s'\n", t); -// if ( t == NULL ) return; -// -// bl = sc_parse((char *)t); -// -// if ( e->cursor_frame == NULL ) { -// fprintf(stderr, _("No frame selected for paste\n")); -// return; -// } -// -// para = e->cursor_frame->paras[e->cpos.para]; -// offs = narrative_pos_trail_to_offset(para, e->cpos.pos, e->cpos.trail); -// -// get_sc_pos(e->cursor_frame, e->cpos.para, offs, &cur_bl, &cur_sc_pos); -// sc_insert_block(cur_bl, cur_sc_pos, bl); -// full_rerender(e); -} - - -static void paste_targets_received(GtkClipboard *cb, GdkAtom *targets, - gint n_targets, gpointer vp) -{ - GtkNarrativeView *e = vp; - int i; - int have_sc = 0; - int index_sc, index_text; - int have_text = 0; - - if ( targets == NULL ) { - fprintf(stderr, "No paste targets offered.\n"); - return; - } - - for ( i=0; isel_start; + end = e->sel_end; + narrative_sort_positions(&start, &end); clipboard_data = malloc(2*sizeof(char *)); if ( clipboard_data == NULL ) return; cb = gtk_clipboard_get_default(gtk_widget_get_display(GTK_WIDGET(e))); - start_offs = narrative_pos_trail_to_offset(e->n, e->sel_start.para, - e->sel_start.pos, e->sel_start.trail); - end_offs = narrative_pos_trail_to_offset(e->n, e->sel_end.para, - e->sel_end.pos, e->sel_end.trail); + start_offs = narrative_pos_trail_to_offset(e->n, start.para, + start.pos, start.trail); + end_offs = narrative_pos_trail_to_offset(e->n, end.para, + end.pos, end.trail); + /* Data is prepared for all the possible MIME types right now, not later + * when the data is requested. This avoids having to convert + * everything to a new, intermediate format, or saving a copy of the + * entire GtkNarrativeView's state (which might change before the data + * gets requested). + * Perhaps I missed something, and there is an easier way. + */ targets[0].target = "text/plain"; targets[0].flags = 0; targets[0].info = 0; - clipboard_data[0] = narrative_range_as_text(e->n, e->sel_start.para, start_offs, - e->sel_end.para, end_offs); + clipboard_data[0] = narrative_range_as_text(e->n, start.para, start_offs, + end.para, end_offs); targets[1].target = "text/x-storycode"; targets[1].flags = 0; targets[1].info = 1; - clipboard_data[1] = narrative_range_as_storycode(e->n, e->sel_start.para, start_offs, - e->sel_end.para, end_offs); + clipboard_data[1] = narrative_range_as_storycode(e->n, start.para, start_offs, + end.para, end_offs); - /* Data is prepared for all the possible MIME types right now, not later - * when the data is represented. This avoids having to convert - * everything to a new, intermediate format, or saving a copy of the - * entire GtkNarrativeView's state (which might change before the data - * gets requested. - * Perhaps I missed something and there is an easier way. - */ gtk_clipboard_set_with_data(cb, targets, 2, clipboard_get, clipboard_clear, clipboard_data); } @@ -1074,6 +969,92 @@ static gboolean gtknv_motion_sig(GtkWidget *da, GdkEventMotion *event, return FALSE; } +static void paste_storycode_received(GtkClipboard *cb, GtkSelectionData *seldata, + gpointer vp) +{ + GtkNarrativeView *e = vp; + const guchar *t; + + t = gtk_selection_data_get_data(seldata); + if ( t == NULL ) { + printf("NULL!\n"); + return; + } + + printf("got SC '%s'\n", t); + Narrative *nnew = storycode_parse_presentation(t); + narrative_debug(nnew); + + gtknv_emit_change_sig(e); + check_cursor_visible(e); + gtknv_redraw(e); +} + + +static void paste_text_received(GtkClipboard *cb, GtkSelectionData *seldata, + gpointer vp) +{ + GtkNarrativeView *e = vp; + guchar *t; + + t = gtk_selection_data_get_text(seldata); + if ( t == NULL ) return; + + gtknv_insert_text((char *)t, e); + g_free(t); + + gtknv_emit_change_sig(e); + check_cursor_visible(e); + gtknv_redraw(e); +} + + +static void paste_targets_received(GtkClipboard *cb, GdkAtom *targets, + gint n_targets, gpointer vp) +{ + GtkNarrativeView *e = vp; + int i; + int have_sc = 0; + int index_sc, index_text; + int have_text = 0; + + if ( targets == NULL ) { + fprintf(stderr, "No paste targets offered.\n"); + return; + } + + for ( i=0; ipara > b->para ) { size_t tpos; @@ -256,7 +256,7 @@ int narrative_wrap_range(Narrative *n, Stylesheet *stylesheet, PangoLanguage *la n->w = w; w -= n->space_l + n->space_r; - sort_positions(&sel_start, &sel_end); + narrative_sort_positions(&sel_start, &sel_end); if ( min < 0 ) min = 0; if ( max >= n->n_items ) max = n->n_items-1; diff --git a/libstorycode/narrative_render_cairo.h b/libstorycode/narrative_render_cairo.h index 4933078..0da0ce6 100644 --- a/libstorycode/narrative_render_cairo.h +++ b/libstorycode/narrative_render_cairo.h @@ -53,4 +53,6 @@ extern int narrative_render_item_cairo(Narrative*n, cairo_t *cr, int i); extern int narrative_render_cairo(Narrative *n, cairo_t *cr, Stylesheet *stylesheet, ImageStore *is, double min_y, double max_y); +extern void narrative_sort_positions(struct edit_pos *a, struct edit_pos *b); + #endif /* NARRATIVE_RENDER_CAIRO_H */ diff --git a/libstorycode/storycode.c b/libstorycode/storycode.c index 42c4820..983ae02 100644 --- a/libstorycode/storycode.c +++ b/libstorycode/storycode.c @@ -47,8 +47,9 @@ Narrative *storycode_parse_presentation(const char *sc) YY_BUFFER_STATE b; Narrative *n; + //BEGIN(0); b = sc_scan_string(sc); - //scdebug = 1; + scdebug = 1; n = narrative_new(); scparse(n); sc_delete_buffer(b); -- cgit v1.2.3