From 1d2e905763d2c403e54850d61044065b238e16bc Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 26 Apr 2016 22:34:25 +0200 Subject: Copy slide --- src/frame.c | 15 ++++++++- src/frame.h | 3 +- src/sc_editor.c | 26 +++++++++++++++ src/sc_interp.c | 7 ++++- src/sc_parse.c | 98 +++++++++++++++++++++++++++++++++++++++++---------------- src/sc_parse.h | 1 + 6 files changed, 120 insertions(+), 30 deletions(-) diff --git a/src/frame.c b/src/frame.c index 3713277..6323872 100644 --- a/src/frame.c +++ b/src/frame.c @@ -66,6 +66,7 @@ struct _paragraph /* For anything other than PARA_TYPE_TEXT */ SCBlock *scblock; + SCBlock *macro_real_scblock; /* For PARA_TYPE_IMAGE */ char *filename; @@ -422,7 +423,8 @@ static Paragraph *insert_paragraph(struct frame *fr, int pos) } -void add_callback_para(struct frame *fr, SCBlock *bl, double w, double h, +void add_callback_para(struct frame *fr, SCBlock *bl, SCBlock *mr, + double w, double h, SCCallbackDrawFunc draw_func, SCCallbackClickFunc click_func, void *bvp, void *vp) @@ -437,6 +439,7 @@ void add_callback_para(struct frame *fr, SCBlock *bl, double w, double h, pnew->type = PARA_TYPE_CALLBACK; pnew->scblock = bl; + pnew->macro_real_scblock = mr; pnew->cb_w = w; pnew->cb_h = h; pnew->draw_func = draw_func; @@ -946,3 +949,13 @@ SCBlock *split_paragraph(struct frame *fr, int pn, size_t pos, PangoContext *pc) return NULL; } } + + +SCBlock *block_at_cursor(struct frame *fr, int pn, size_t pos) +{ + Paragraph *para = fr->paras[pn]; + + if ( para->type != PARA_TYPE_CALLBACK ) return NULL; + + return para->macro_real_scblock; +} diff --git a/src/frame.h b/src/frame.h index 2941411..0ed7f88 100644 --- a/src/frame.h +++ b/src/frame.h @@ -115,7 +115,7 @@ extern void add_run(Paragraph *para, SCBlock *scblock, size_t offs_bytes, size_t len_bytes, PangoFontDescription *fdesc, double col[4]); -extern void add_callback_para(struct frame *fr, SCBlock *scblock, +extern void add_callback_para(struct frame *fr, SCBlock *scblock, SCBlock *mr, double w, double h, SCCallbackDrawFunc draw_func, SCCallbackClickFunc click_func, void *bvp, @@ -154,5 +154,6 @@ extern void delete_text_in_paragraph(Paragraph *para, extern SCBlock *split_paragraph(struct frame *fr, int pn, size_t pos, PangoContext *pc); +extern SCBlock *block_at_cursor(struct frame *fr, int para, size_t pos); #endif /* FRAME_H */ diff --git a/src/sc_editor.c b/src/sc_editor.c index 7a89036..4dfec35 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -1114,6 +1114,25 @@ static gboolean button_release_sig(GtkWidget *da, GdkEventButton *event, } +static void copy_selection(SCEditor *e) +{ + GtkClipboard *cb; + char *storycode; + SCBlock *bl; + + bl = block_at_cursor(e->cursor_frame, e->cursor_para, + e->cursor_pos+e->cursor_trail); + if ( bl == NULL ) return; + + storycode = serialise_sc_block(bl); + printf("Got '%s'\n", storycode); + + cb = gtk_clipboard_get(GDK_NONE); + gtk_clipboard_set_text(cb, storycode, -1); + free(storycode); +} + + static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, SCEditor *e) { @@ -1186,6 +1205,13 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, full_rerender(e); break; + case GDK_KEY_C : + case GDK_KEY_c : + if ( event->state == GDK_CONTROL_MASK ) { + copy_selection(e); + } + break; + } if ( claim ) return TRUE; diff --git a/src/sc_interp.c b/src/sc_interp.c index 993cb9e..9c4045b 100644 --- a/src/sc_interp.c +++ b/src/sc_interp.c @@ -212,11 +212,15 @@ static void do_callback(SCInterpreter *scin, SCBlock *bl, const char *name) double w, h; int r; void *bvp; + SCBlock *mr; + + mr = sc_interp_get_macro_real_block(scin); + if ( mr == NULL ) mr = bl; if ( strcmp(cbl->names[i], name) != 0 ) continue; r = cbl->box_funcs[i](scin, bl, &w, &h, &bvp, cbl->vps[i]); if ( !r ) return; - add_callback_para(sc_interp_get_frame(scin), bl, w, h, + add_callback_para(sc_interp_get_frame(scin), bl, mr, w, h, cbl->draw_funcs[i], cbl->click_funcs[i], bvp, cbl->vps[i]); @@ -562,6 +566,7 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, return NULL; } st->macro_contents = NULL; + st->macro_real_block = NULL; st->fr = NULL; scin->lang = lang; diff --git a/src/sc_parse.c b/src/sc_parse.c index 8265a13..689a31e 100644 --- a/src/sc_parse.c +++ b/src/sc_parse.c @@ -241,44 +241,88 @@ void sc_block_free(SCBlock *bl) } -void save_sc_block(FILE *fh, const SCBlock *bl) +char *serialise_sc_block(const SCBlock *bl) { - while ( bl != NULL ) { + char *a; + SCBlock *ch; + size_t len = 3; - if ( bl->name == NULL ) { - fprintf(fh, "%s", bl->contents); - } else { + if ( bl == NULL ) return strdup(""); - fprintf(fh, "\\%s", bl->name); - if ( bl->options != NULL ) { - fprintf(fh, "[%s]", bl->options); - } - if ( (bl->contents != NULL) || (bl->child != NULL) ) { - fprintf(fh, "{"); - } - if ( bl->contents != NULL ) { - fprintf(fh, "%s", bl->contents); - } + if ( bl->name != NULL ) len += 1+strlen(bl->name); + if ( bl->options != NULL ) len += 2+strlen(bl->options); + if ( bl->contents != NULL ) len += 2+strlen(bl->contents); + a = malloc(len); + if ( a == NULL ) return NULL; + a[0] = '\0'; - /* Special case to prevent "\somethingSome text" */ - if ( (bl->name != NULL) && (bl->options == NULL) - && (bl->contents == NULL) && (bl->next != NULL) - && (bl->next->name == NULL) && (bl->child == NULL) ) - { - fprintf(fh, "{}"); - } + if ( bl->name == NULL ) { + strcat(a, bl->contents); + } else { + strcat(a, "\\"); + strcat(a, bl->name); + if ( bl->options != NULL ) { + strcat(a, "["); + strcat(a, bl->options); + strcat(a, "]"); + } + if ( (bl->contents != NULL) || (bl->child != NULL) ) { + strcat(a, "{"); + } + if ( bl->contents != NULL ) { + strcat(a, bl->contents); } - if ( bl->child != NULL ) { - save_sc_block(fh, bl->child); + /* Special case to prevent "\somethingSome text" */ + if ( (bl->name != NULL) && (bl->options == NULL) + && (bl->contents == NULL) && (bl->next != NULL) + && (bl->next->name == NULL) && (bl->child == NULL) ) + { + strcat(a, "{}"); } - if ( (bl->name != NULL) && - ((bl->contents != NULL) || (bl->child != NULL)) ) { - fprintf(fh, "}"); + } + + /* Add ALL child blocks of this one */ + ch = bl->child; + while ( ch != NULL ) { + + char *c = serialise_sc_block(ch); + if ( c == NULL ) { + free(a); + return NULL; } + len += strlen(c); + a = realloc(a, len); + if ( a == NULL ) return NULL; + strcat(a, c); + free(c); + + ch = ch->next; + + } + + if ( (bl->name != NULL) && + ((bl->contents != NULL) || (bl->child != NULL)) ) { + strcat(a, "}"); + } + + return a; +} + + +void save_sc_block(FILE *fh, const SCBlock *bl) +{ + while ( bl != NULL ) { + char *a = serialise_sc_block(bl); + if ( a == NULL ) { + fprintf(stderr, "Failed to serialise block\n"); + return; + } + fprintf(fh, a); + free(a); bl = bl->next; } } diff --git a/src/sc_parse.h b/src/sc_parse.h index dad797b..1260cc0 100644 --- a/src/sc_parse.h +++ b/src/sc_parse.h @@ -71,6 +71,7 @@ extern SCBlock *sc_block_split(SCBlock *bl, size_t pos); extern void show_sc_blocks(const SCBlock *bl); extern void show_sc_block(const SCBlock *bl, const char *prefix); +extern char *serialise_sc_block(const SCBlock *bl); extern void save_sc_block(FILE *fh, const SCBlock *bl); #endif /* SC_PARSE_H */ -- cgit v1.2.3