From 1431aced5f9615be656519bb438c6bc96d2c2442 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 4 Feb 2017 22:36:03 +0100 Subject: Change stylesheet --- src/colloquium.c | 4 +++ src/narrative_window.c | 68 +++++++++++++++++++++++++++++++++++++++++ src/presentation.c | 83 ++++++++++++++++++++++++++++++++++++++++++-------- src/presentation.h | 3 ++ src/sc_interp.c | 26 ---------------- src/sc_interp.h | 1 - src/sc_parse.c | 13 ++++++++ src/sc_parse.h | 3 +- 8 files changed, 161 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/colloquium.c b/src/colloquium.c index 484adb5..657b7ef 100644 --- a/src/colloquium.c +++ b/src/colloquium.c @@ -263,6 +263,10 @@ static void colloquium_startup(GApplication *papp) " Edit stylesheet..." " win.stylesheet" " " + " " + " Change stylesheet..." + " win.loadstylesheet" + " " " " " " diff --git a/src/narrative_window.c b/src/narrative_window.c index 22517b4..a1a522e 100644 --- a/src/narrative_window.c +++ b/src/narrative_window.c @@ -223,6 +223,73 @@ static SCBlock *get_slide_template(SCBlock *ss) } +static gint load_ss_response_sig(GtkWidget *d, gint response, + NarrativeWindow *nw) +{ + if ( response == GTK_RESPONSE_ACCEPT ) { + + char *filename; + char *stext; + + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d)); + printf("Loading %s\n",filename); + + stext = load_everything(filename); + if ( stext != NULL ) { + SCBlock *bl; + SCBlock *ss; + bl = sc_parse(stext); + free(stext); + ss = find_stylesheet(bl); + if ( ss != NULL ) { + + /* Substitute the style sheet */ + replace_stylesheet(nw->p, ss); + + /* Full rerender, first block may have + * changed */ + sc_editor_set_scblock(nw->sceditor, + nw->p->scblocks); + + } else { + fprintf(stderr, "Not a style sheet\n"); + } + } else { + fprintf(stderr, "Failed to load\n"); + } + + g_free(filename); + + } + + gtk_widget_destroy(d); + + return 0; +} + + +static void load_ss_sig(GSimpleAction *action, GVariant *parameter, + gpointer vp) +{ + SCBlock *nsblock; + SCBlock *templ; + NarrativeWindow *nw = vp; + GtkWidget *d; + + d = gtk_file_chooser_dialog_new("Load stylesheet", + GTK_WINDOW(nw->window), + GTK_FILE_CHOOSER_ACTION_OPEN, + "_Cancel", GTK_RESPONSE_CANCEL, + "_Open", GTK_RESPONSE_ACCEPT, + NULL); + + g_signal_connect(G_OBJECT(d), "response", + G_CALLBACK(load_ss_response_sig), nw); + + gtk_widget_show_all(d); +} + + static void add_slide_sig(GSimpleAction *action, GVariant *parameter, gpointer vp) { @@ -564,6 +631,7 @@ GActionEntry nw_entries[] = { { "sorter", open_slidesorter_sig, NULL, NULL, NULL }, { "deleteslide", delete_slide_sig, NULL, NULL, NULL }, { "slide", add_slide_sig, NULL, NULL, NULL }, + { "loadstylesheet", load_ss_sig, NULL, NULL, NULL }, { "startslideshow", start_slideshow_sig, NULL, NULL, NULL }, { "clock", open_clock_sig, NULL, NULL, NULL }, { "testcard", testcard_sig, NULL, NULL, NULL }, diff --git a/src/presentation.c b/src/presentation.c index 5b4a3de..55219e2 100644 --- a/src/presentation.c +++ b/src/presentation.c @@ -1,7 +1,7 @@ /* * presentation.c * - * Copyright © 2013-2014 Thomas White + * Copyright © 2013-2017 Thomas White * * This file is part of Colloquium. * @@ -321,19 +321,14 @@ SCBlock *prev_slide(struct presentation *p, SCBlock *sl) } -int load_presentation(struct presentation *p, const char *filename) +char *load_everything(const char *filename) { FILE *fh; - int r = 0; - char *everything; size_t el = 1; - - everything = strdup(""); - - assert(p->completely_empty); + char *everything = strdup(""); fh = fopen(filename, "r"); - if ( fh == NULL ) return 1; + if ( fh == NULL ) return NULL; while ( !feof(fh) ) { @@ -344,8 +339,8 @@ int load_presentation(struct presentation *p, const char *filename) everything = realloc(everything, el+len); if ( everything == NULL ) { - r = 1; - break; + fprintf(stderr, "Failed to allocate memory\n"); + return NULL; } el += len; @@ -356,6 +351,70 @@ int load_presentation(struct presentation *p, const char *filename) fclose(fh); + return everything; +} + + +int replace_stylesheet(struct presentation *p, SCBlock *ss) +{ + /* Create style sheet from union of old and new, + * preferring items from the new one */ + + /* Cut the old stylesheet out of the presentation, + * and put in the new one */ + sc_block_substitute(&p->scblocks, p->stylesheet, ss); + p->stylesheet = ss; + + return 0; +} + + +SCBlock *find_stylesheet(SCBlock *bl) +{ + while ( bl != NULL ) { + + const char *name = sc_block_name(bl); + + if ( (name != NULL) && (strcmp(name, "stylesheet") == 0) ) { + return bl; + } + + bl = sc_block_next(bl); + + } + + return NULL; +} + + +static void install_stylesheet(struct presentation *p) +{ + if ( p->stylesheet != NULL ) { + fprintf(stderr, "Duplicate style sheet!\n"); + return; + } + + p->stylesheet = find_stylesheet(p->scblocks); + + if ( p->stylesheet == NULL ) { + fprintf(stderr, "No style sheet.\n"); + } +} + + +int load_presentation(struct presentation *p, const char *filename) +{ + int r = 0; + char *everything; + + assert(p->completely_empty); + + everything = load_everything(filename); + if ( everything == NULL ) { + fprintf(stderr, "Failed to load '%s'\n", filename); + return 1; + } + p->scblocks = sc_parse(everything); free(everything); @@ -370,7 +429,7 @@ int load_presentation(struct presentation *p, const char *filename) return r; /* Error */ } - find_stylesheet(p); + install_stylesheet(p); assert(p->filename == NULL); p->filename = strdup(filename); diff --git a/src/presentation.h b/src/presentation.h index dae4ffd..a639c59 100644 --- a/src/presentation.h +++ b/src/presentation.h @@ -69,6 +69,9 @@ struct presentation extern struct presentation *new_presentation(void); +extern char *load_everything(const char *filename); +extern SCBlock *find_stylesheet(SCBlock *bl); +extern int replace_stylesheet(struct presentation *p, SCBlock *ss); extern void free_presentation(struct presentation *p); extern char *get_titlebar_string(struct presentation *p); diff --git a/src/sc_interp.c b/src/sc_interp.c index 92bf10f..852f8ac 100644 --- a/src/sc_interp.c +++ b/src/sc_interp.c @@ -1317,32 +1317,6 @@ void sc_interp_run_stylesheet(SCInterpreter *scin, SCBlock *bl) } -void find_stylesheet(struct presentation *p) -{ - SCBlock *bl = p->scblocks; - - if ( p->stylesheet != NULL ) { - fprintf(stderr, "Duplicate style sheet!\n"); - return; - } - - while ( bl != NULL ) { - - const char *name = sc_block_name(bl); - - if ( (name != NULL) && (strcmp(name, "stylesheet") == 0) ) { - p->stylesheet = bl; - return; - } - - bl = sc_block_next(bl); - - } - - fprintf(stderr, "No style sheet.\n"); -} - - struct template_id *sc_interp_get_templates(SCInterpreter *scin, int *np) { struct template_id *list; diff --git a/src/sc_interp.h b/src/sc_interp.h index ad9048c..fe38a39 100644 --- a/src/sc_interp.h +++ b/src/sc_interp.h @@ -50,7 +50,6 @@ extern void sc_interp_restore(SCInterpreter *scin); extern int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl); -extern void find_stylesheet(struct presentation *p); extern void sc_interp_run_stylesheet(SCInterpreter *scin, SCBlock *bl); extern void add_macro(SCInterpreter *scin, const char *mname, const char *contents); diff --git a/src/sc_parse.c b/src/sc_parse.c index 56b72bf..1018d24 100644 --- a/src/sc_parse.c +++ b/src/sc_parse.c @@ -211,6 +211,19 @@ static SCBlock *sc_find_parent(SCBlock *top, SCBlock *find) } +void sc_block_substitute(SCBlock **top, SCBlock *old, SCBlock *new) +{ + if ( old == *top ) { + /* It is the first block */ + new->next = old->next; + *top = new; + } else { + sc_block_delete(*top, old); + sc_block_append_p(new, *top); + } +} + + /* Delete "deleteme", which is somewhere under "top" */ void sc_block_delete(SCBlock *top, SCBlock *deleteme) { diff --git a/src/sc_parse.h b/src/sc_parse.h index 66b3ff9..a07901f 100644 --- a/src/sc_parse.h +++ b/src/sc_parse.h @@ -1,7 +1,7 @@ /* * sc_parse.h * - * Copyright © 2013-2016 Thomas White + * Copyright © 2013-2017 Thomas White * * This file is part of Colloquium. * @@ -42,6 +42,7 @@ extern SCBlock *sc_block_child(const SCBlock *bl); extern const char *sc_block_name(const SCBlock *bl); extern const char *sc_block_options(const SCBlock *bl); extern const char *sc_block_contents(const SCBlock *bl); +extern void sc_block_substitute(SCBlock **top, SCBlock *old, SCBlock *new); extern SCBlock *sc_block_append(SCBlock *bl, char *name, char *opt, char *contents, -- cgit v1.2.3