aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/colloquium.c4
-rw-r--r--src/narrative_window.c68
-rw-r--r--src/presentation.c83
-rw-r--r--src/presentation.h3
-rw-r--r--src/sc_interp.c26
-rw-r--r--src/sc_interp.h1
-rw-r--r--src/sc_parse.c13
-rw-r--r--src/sc_parse.h3
8 files changed, 161 insertions, 40 deletions
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)
" <attribute name='label'>Edit stylesheet...</attribute>"
" <attribute name='action'>win.stylesheet</attribute>"
" </item>"
+ " <item>"
+ " <attribute name='label'>Change stylesheet...</attribute>"
+ " <attribute name='action'>win.loadstylesheet</attribute>"
+ " </item>"
" </section>"
" </submenu>"
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 <taw@bitwiz.org.uk>
+ * Copyright © 2013-2017 Thomas White <taw@bitwiz.org.uk>
*
* 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 <taw@bitwiz.org.uk>
+ * Copyright © 2013-2017 Thomas White <taw@bitwiz.org.uk>
*
* 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,