aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.me.uk>2018-10-28 00:03:51 +0200
committerThomas White <taw@bitwiz.me.uk>2018-10-28 00:03:51 +0200
commit8e05062ad3b94068825a1f80eb362aa3d3e9098f (patch)
tree77944d65437fa57755a7bc8bc16fd3e2c5b43f17 /src
parent791ee4e65f3ec7ef470302e4381baefb431fb56d (diff)
parent21418cfb52b87a32cfdc9bb14be83b85a8e70281 (diff)
Merge branch 'json-stylesheets'
Diffstat (limited to 'src')
-rw-r--r--src/colloquium.c6
-rw-r--r--src/colloquium.h1
-rw-r--r--src/debugger.c23
-rw-r--r--src/frame.c212
-rw-r--r--src/frame.h27
-rw-r--r--src/narrative_window.c102
-rw-r--r--src/presentation.c136
-rw-r--r--src/presentation.h5
-rw-r--r--src/print.c12
-rw-r--r--src/render.c28
-rw-r--r--src/render.h4
-rw-r--r--src/sc_editor.c28
-rw-r--r--src/sc_editor.h11
-rw-r--r--src/sc_interp.c727
-rw-r--r--src/sc_interp.h29
-rw-r--r--src/sc_parse.c92
-rw-r--r--src/sc_parse.h7
-rw-r--r--src/slide_window.c2
-rw-r--r--src/slide_window.h1
-rw-r--r--src/stylesheet.c234
-rw-r--r--src/stylesheet.h48
-rw-r--r--src/stylesheet_editor.c594
-rw-r--r--src/stylesheet_editor.h29
-rw-r--r--src/utils.c92
-rw-r--r--src/utils.h3
25 files changed, 915 insertions, 1538 deletions
diff --git a/src/colloquium.c b/src/colloquium.c
index 66e3dcb..a8da4d9 100644
--- a/src/colloquium.c
+++ b/src/colloquium.c
@@ -320,12 +320,6 @@ int colloquium_get_hidepointer(Colloquium *app)
}
-GtkBuilder *colloquium_get_uibuilder(Colloquium *app)
-{
- return app->builder;
-}
-
-
static void colloquium_startup(GApplication *papp)
{
Colloquium *app = COLLOQUIUM(papp);
diff --git a/src/colloquium.h b/src/colloquium.h
index 4c8133f..89f600f 100644
--- a/src/colloquium.h
+++ b/src/colloquium.h
@@ -38,7 +38,6 @@ typedef struct _colloquium Colloquium;
extern const char *colloquium_get_imagestore(Colloquium *app);
extern int colloquium_get_hidepointer(Colloquium *app);
-extern GtkBuilder *colloquium_get_uibuilder(Colloquium *app);
extern void open_about_dialog(GtkWidget *parent);
diff --git a/src/debugger.c b/src/debugger.c
index edb79e1..12ef9d8 100644
--- a/src/debugger.c
+++ b/src/debugger.c
@@ -109,25 +109,17 @@ static void debug_text_para(Paragraph *para, cairo_t *cr, double *ypos,
for ( i=0; i<nrun; i++ ) {
SCBlock *scblock;
- SCBlock *rscblock;
- if ( para_debug_run_info(para, i, &scblock, &rscblock) ) {
+ if ( para_debug_run_info(para, i, &scblock) ) {
/* Failed to get debug info for paragraph */
plot_text(cr, ypos, fontdesc, _("Error"));
} else {
-
- if ( scblock != rscblock ) {
- snprintf(tmp, 255, " Run %i: SCBlock %p / %p", i,
- scblock, rscblock);
- } else {
- snprintf(tmp, 255, " Run %i: SCBlock %p", i,
- scblock);
- }
+ snprintf(tmp, 255, " Run %i: SCBlock %p", i, scblock);
plot_text(cr, ypos, fontdesc, tmp);
-
}
}
- snprintf(tmp, 255, "Newline at end: %p", get_newline_at_end(para));
+ snprintf(tmp, 255, "Newline at end: %p",
+ para_debug_get_newline_at_end(para));
plot_text(cr, ypos, fontdesc, tmp);
}
@@ -161,17 +153,12 @@ static gboolean dbg_draw_sig(GtkWidget *da, cairo_t *cr, struct debugwindow *dbg
enum para_type t = para_type(dbgw->fr->paras[i]);
SCBlock *scblock = para_scblock(dbgw->fr->paras[i]);
- SCBlock *rscblock = para_rscblock(dbgw->fr->paras[i]);
plot_hr(cr, &ypos, width);
snprintf(tmp, 255, "Paragraph %i: type %s", i, str_type(t));
plot_text(cr, &ypos, fontdesc, tmp);
- if ( scblock == rscblock ) {
- snprintf(tmp, 255, "SCBlock %p", scblock);
- } else {
- snprintf(tmp, 255, "SCBlock %p / %p", scblock, rscblock);
- }
+ snprintf(tmp, 255, "SCBlock %p", scblock);
plot_text(cr, &ypos, fontdesc, tmp);
if ( t == PARA_TYPE_TEXT ) {
diff --git a/src/frame.c b/src/frame.c
index d4a5637..2926d4e 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -39,7 +39,6 @@
struct text_run
{
SCBlock *scblock; /* If macro, this is \macro */
- SCBlock *rscblock; /* The block with the actual text */
PangoFontDescription *fontdesc;
double col[4];
};
@@ -61,7 +60,6 @@ struct _paragraph
/* For anything other than PARA_TYPE_TEXT
* (for text paragraphs, these things are in the runs) */
SCBlock *scblock;
- SCBlock *rscblock;
/* For PARA_TYPE_IMAGE */
char *filename;
@@ -186,7 +184,7 @@ struct frame *add_subframe(struct frame *fr)
}
-void show_hierarchy(struct frame *fr, const char *t)
+void show_frame_hierarchy(struct frame *fr, const char *t)
{
int i;
char tn[1024];
@@ -197,65 +195,12 @@ void show_hierarchy(struct frame *fr, const char *t)
printf(_("%s%p (%.2f x %.2f)\n"), t, fr, fr->w, fr->h);
for ( i=0; i<fr->num_children; i++ ) {
- show_hierarchy(fr->children[i], tn);
+ show_frame_hierarchy(fr->children[i], tn);
}
}
-static struct frame *find_parent(struct frame *fr, struct frame *search)
-{
- int i;
-
- for ( i=0; i<fr->num_children; i++ ) {
- if ( fr->children[i] == search ) {
- return fr;
- }
- }
-
- for ( i=0; i<fr->num_children; i++ ) {
- struct frame *tt;
- tt = find_parent(fr->children[i], search);
- if ( tt != NULL ) return tt;
- }
-
- return NULL;
-}
-
-
-void delete_subframe(struct frame *top, struct frame *fr)
-{
- struct frame *parent;
- int i, idx, found;
-
- parent = find_parent(top, fr);
- if ( parent == NULL ) {
- fprintf(stderr, _("Couldn't find parent when deleting frame.\n"));
- return;
- }
-
- found = 0;
- for ( i=0; i<parent->num_children; i++ ) {
- if ( parent->children[i] == fr ) {
- idx = i;
- found = 1;
- break;
- }
- }
-
- if ( !found ) {
- fprintf(stderr, _("Couldn't find child when deleting frame.\n"));
- return;
- }
-
- for ( i=idx; i<parent->num_children-1; i++ ) {
- parent->children[i] = parent->children[i+1];
- }
-
- parent->num_children--;
-}
-
-
struct frame *find_frame_with_scblocks(struct frame *fr, SCBlock *scblocks)
{
int i;
@@ -279,17 +224,17 @@ static size_t run_text_len(const struct text_run *run)
return 0;
}
- if ( run->rscblock == NULL ) {
- fprintf(stderr, _("NULL rscblock in run_text_len\n"));
+ if ( run->scblock == NULL ) {
+ fprintf(stderr, _("NULL scblock in run_text_len\n"));
return 0;
}
- if ( sc_block_contents(run->rscblock) == NULL ) {
- fprintf(stderr, _("NULL rscblock contents in run_text_len\n"));
+ if ( sc_block_contents(run->scblock) == NULL ) {
+ fprintf(stderr, _("NULL scblock contents in run_text_len\n"));
return 0;
}
- return strlen(sc_block_contents(run->rscblock));
+ return strlen(sc_block_contents(run->scblock));
}
@@ -340,7 +285,7 @@ void wrap_paragraph(Paragraph *para, PangoContext *pc, double w,
size_t run_len;
guint16 r, g, b;
- run_text = sc_block_contents(para->runs[i].rscblock);
+ run_text = sc_block_contents(para->runs[i].scblock);
run_len = strlen(run_text);
attr = pango_attr_font_desc_new(para->runs[i].fontdesc);
@@ -384,19 +329,25 @@ void wrap_paragraph(Paragraph *para, PangoContext *pc, double w,
para->height = pango_units_to_double(rect.height);
}
-SCBlock *get_newline_at_end(Paragraph *para)
+static SCBlock *get_newline_at_end(Paragraph *para)
{
return para->newline_at_end;
}
+SCBlock *para_debug_get_newline_at_end(Paragraph *para)
+{
+ return get_newline_at_end(para);
+}
+
+
void set_newline_at_end(Paragraph *para, SCBlock *bl)
{
para->newline_at_end = bl;
}
-void add_run(Paragraph *para, SCBlock *scblock, SCBlock *rscblock,
+void add_run(Paragraph *para, SCBlock *scblock,
PangoFontDescription *fdesc, double col[4])
{
struct text_run *runs_new;
@@ -410,7 +361,6 @@ void add_run(Paragraph *para, SCBlock *scblock, SCBlock *rscblock,
para->runs = runs_new;
para->runs[para->n_runs].scblock = scblock;
- para->runs[para->n_runs].rscblock = rscblock;
para->runs[para->n_runs].fontdesc = pango_font_description_copy(fdesc);
para->runs[para->n_runs].col[0] = col[0];
para->runs[para->n_runs].col[1] = col[1];
@@ -421,7 +371,7 @@ void add_run(Paragraph *para, SCBlock *scblock, SCBlock *rscblock,
}
-Paragraph *create_paragraph(struct frame *fr, SCBlock *bl, SCBlock *rbl)
+Paragraph *create_paragraph(struct frame *fr, SCBlock *bl)
{
Paragraph **paras_new;
Paragraph *pnew;
@@ -439,7 +389,6 @@ Paragraph *create_paragraph(struct frame *fr, SCBlock *bl, SCBlock *rbl)
* However, this can easily be changed */
pnew->type = PARA_TYPE_TEXT;
pnew->scblock = bl;
- pnew->rscblock = rbl;
pnew->n_runs = 0;
pnew->runs = NULL;
pnew->layout = NULL;
@@ -481,8 +430,7 @@ Paragraph *insert_paragraph(struct frame *fr, int pos)
}
-Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, SCBlock *rbl,
- double w, double h,
+Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, double w, double h,
SCCallbackDrawFunc draw_func,
SCCallbackClickFunc click_func, void *bvp,
void *vp)
@@ -492,7 +440,7 @@ Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, SCBlock *rbl,
if ( (fr->n_paras > 0) && (fr->paras[fr->n_paras-1]->empty) ) {
pnew = fr->paras[fr->n_paras-1];
} else {
- pnew = create_paragraph(fr, bl, rbl);
+ pnew = create_paragraph(fr, bl);
if ( pnew == NULL ) {
fprintf(stderr, _("Failed to add callback paragraph\n"));
return NULL;
@@ -501,7 +449,6 @@ Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, SCBlock *rbl,
pnew->type = PARA_TYPE_CALLBACK;
pnew->scblock = bl;
- pnew->rscblock = rbl;
pnew->cb_w = w;
pnew->cb_h = h;
pnew->draw_func = draw_func;
@@ -515,7 +462,7 @@ Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, SCBlock *rbl,
}
-void add_image_para(struct frame *fr, SCBlock *scblock, SCBlock *rscblock,
+void add_image_para(struct frame *fr, SCBlock *scblock,
const char *filename,
ImageStore *is, double w, double h, int editable)
{
@@ -530,7 +477,7 @@ void add_image_para(struct frame *fr, SCBlock *scblock, SCBlock *rscblock,
if ( (fr->n_paras > 0) && (fr->paras[fr->n_paras-1]->empty) ) {
pnew = fr->paras[fr->n_paras-1];
} else {
- pnew = create_paragraph(fr, scblock, rscblock);
+ pnew = create_paragraph(fr, scblock);
if ( pnew == NULL ) {
fprintf(stderr, _("Failed to add image paragraph\n"));
return;
@@ -545,7 +492,6 @@ void add_image_para(struct frame *fr, SCBlock *scblock, SCBlock *rscblock,
pnew->type = PARA_TYPE_IMAGE;
pnew->scblock = scblock;
- pnew->rscblock = rscblock;
pnew->filename = strdup(filename);
pnew->image_w = w;
pnew->image_h = h;
@@ -662,7 +608,7 @@ void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is)
}
-size_t end_offset_of_para(struct frame *fr, int pn)
+static size_t end_offset_of_para(struct frame *fr, int pn)
{
int i;
size_t total = 0;
@@ -726,11 +672,6 @@ void ensure_run(struct frame *fr, struct edit_pos cpos)
if ( para->type != PARA_TYPE_TEXT ) return;
- if ( para->scblock != para->rscblock ) {
- fprintf(stderr, _("Need to add run, but paragraph not editable\n"));
- return;
- }
-
if ( para->scblock != NULL ) {
bl = sc_block_prepend(para->scblock, fr->scblocks);
@@ -745,13 +686,12 @@ void ensure_run(struct frame *fr, struct edit_pos cpos)
/* If the paragraph's SCBlock is NULL, it means this paragraph
* is right at the end of the document. The last thing in the
* document is something like \newpara. */
- bl = sc_block_append_end(fr->scblocks, NULL, NULL, strdup(""));
+ bl = sc_block_append_inside(fr->scblocks, NULL, NULL, strdup(""));
}
para->scblock = bl;
- para->rscblock = bl;
- add_run(para, bl, bl, fr->fontdesc, fr->col);
+ add_run(para, bl, fr->fontdesc, fr->col);
wrap_paragraph(para, NULL, fr->w - fr->pad_l - fr->pad_r, 0, 0);
}
@@ -907,11 +847,6 @@ void cursor_moveh(struct frame *fr, struct edit_pos *cp, signed int dir)
}
-void cursor_movev(struct frame *fr, struct edit_pos *cp, signed int dir)
-{
-}
-
-
void check_callback_click(struct frame *fr, int para)
{
Paragraph *p = fr->paras[para];
@@ -987,7 +922,7 @@ size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail)
return 0;
}
- if ( sc_block_contents(run->rscblock) == NULL ) {
+ if ( sc_block_contents(run->scblock) == NULL ) {
fprintf(stderr, _("pos_trail_to_offset: No contents "
"(%p name=%s, options=%s)\n"),
run->scblock, sc_block_name(run->scblock),
@@ -996,7 +931,7 @@ size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail)
}
/* Get the text for the run */
- run_text = sc_block_contents(run->rscblock);
+ run_text = sc_block_contents(run->scblock);
/* Turn the paragraph offset into a run offset */
para_offset_of_run = get_paragraph_offset(para, nrun);
@@ -1035,11 +970,6 @@ int position_editable(struct frame *fr, struct edit_pos cp)
para = fr->paras[cp.para];
- if ( para->scblock != para->rscblock ) {
- fprintf(stderr, _("Paragraph is not editable.\n"));
- return 0;
- }
-
if ( para->type != PARA_TYPE_TEXT ) {
fprintf(stderr, _("Paragraph is not text.\n"));
return 0;
@@ -1052,7 +982,7 @@ int position_editable(struct frame *fr, struct edit_pos cp)
return 0;
}
- return (para->runs[run].scblock == para->runs[run].rscblock);
+ return 1;
}
@@ -1074,33 +1004,11 @@ void insert_text_in_paragraph(Paragraph *para, size_t offs, const char *t)
size_t run_offs;
run = &para->runs[nrun];
run_offs = offs - get_paragraph_offset(para, nrun);
- sc_insert_text(run->rscblock, run_offs, t);
+ sc_insert_text(run->scblock, run_offs, t);
}
}
-static SCBlock *pos_to_rscblock(struct frame *fr, struct edit_pos p)
-{
- int run;
- size_t paraoffs;
- Paragraph *para;
-
- para = fr->paras[p.para];
-
- if ( para->type != PARA_TYPE_TEXT ) {
- return NULL;
- }
-
- paraoffs = pos_trail_to_offset(para, p.pos, p.trail);
-
- run = which_run(para, paraoffs);
- assert(run < para->n_runs);
-
- return para->runs[run].rscblock;
-}
-
-
-
static SCBlock *pos_to_scblock(struct frame *fr, struct edit_pos p,
enum para_type *type)
{
@@ -1192,17 +1100,9 @@ static Paragraph *scan_runs_for_scblock(struct frame *fr, int pn1, int pn2,
*run = 0;
return fr->paras[i];
}
- if ( fr->paras[i]->rscblock == bl ) {
- *run = 0;
- return fr->paras[i];
- }
/* Check all runs */
for ( j=0; j<fr->paras[i]->n_runs; j++ ) {
- if ( fr->paras[i]->runs[j].rscblock == bl ) {
- *run = j;
- return fr->paras[i];
- }
if ( fr->paras[i]->runs[j].scblock == bl ) {
*run = j;
return fr->paras[i];
@@ -1440,7 +1340,6 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po
{
int i;
SCBlock *p1scblock, *p2scblock;
- SCBlock *p1rscblock, *p2rscblock;
enum para_type type1, type2;
size_t p2offs;
SCBlock *scblock;
@@ -1467,8 +1366,6 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po
/* Find SC positions for start and end */
p1scblock = pos_to_scblock(fr, p1, &type1);
p2scblock = pos_to_scblock(fr, p2, &type2);
- p1rscblock = pos_to_rscblock(fr, p1);
- p2rscblock = pos_to_rscblock(fr, p2);
p2offs = pos_to_offset(fr, p2);
wrap_end = p2.para;
@@ -1512,9 +1409,9 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po
printf(" offs %li\n", (long int)p1offs);
if ( p1offs != 0 ) {
printf("Partial delete\n");
- printf("contents '%s'\n", sc_block_contents(p1rscblock));
+ printf("contents '%s'\n", sc_block_contents(p1scblock));
printf("from offs %li\n", (long int)p1offs);
- scblock_delete_text(p1rscblock, p1offs, -1);
+ scblock_delete_text(p1scblock, p1offs, -1);
} else {
printf("Deleting the whole text SCBlock\n");
sc_block_delete(&fr->scblocks, p1scblock);
@@ -1564,8 +1461,8 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po
if ( type2 == PARA_TYPE_TEXT ) {
size_t len;
printf(" offs %li\n", (long int)p2offs);
- if ( sc_block_contents(p2rscblock) != NULL ) {
- len = strlen(sc_block_contents(p2rscblock));
+ if ( sc_block_contents(p2scblock) != NULL ) {
+ len = strlen(sc_block_contents(p2scblock));
} else {
len = 0;
}
@@ -1580,9 +1477,9 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po
NULL);
} else if ( p2offs > 0 ) {
printf("Partial delete\n");
- printf("contents '%s'\n", sc_block_contents(p2rscblock));
+ printf("contents '%s'\n", sc_block_contents(p2scblock));
printf("up to offs %li\n", (long int)p2offs);
- scblock_delete_text(p2rscblock, 0, p2offs);
+ scblock_delete_text(p2scblock, 0, p2offs);
} /* else do nothing */
} else {
printf("Deleting the whole non-text SCBlock\n");
@@ -1610,10 +1507,10 @@ void show_para(Paragraph *p)
printf(_("%i runs:\n"), p->n_runs);
for ( i=0; i<p->n_runs; i++ ) {
- printf(_(" Run %2i: SCBlock %p/%p %s '%s'\n"),
- i, p->runs[i].scblock, p->runs[i].rscblock,
+ printf(_(" Run %2i: SCBlock %p %s '%s'\n"),
+ i, p->runs[i].scblock,
pango_font_description_to_string(p->runs[i].fontdesc),
- sc_block_contents(p->runs[i].rscblock));
+ sc_block_contents(p->runs[i].scblock));
}
} else if ( p->type == PARA_TYPE_IMAGE ) {
@@ -1695,9 +1592,8 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos,
end = sc_block_append(np, NULL, NULL, strdup(""), NULL);
pnew->n_runs = 0;
- add_run(pnew, end, end, fr->fontdesc, fr->col);
+ add_run(pnew, end, fr->fontdesc, fr->col);
pnew->scblock = end;
- pnew->rscblock = end;
wrap_paragraph(pnew, pc, fr->w - fr->pad_l - fr->pad_r, 0, 0);
@@ -1710,12 +1606,11 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos,
/* Split the run (and SCBlock) into two */
double col[4] = {0,0,0,0};
struct text_run *rn;
- int macro = 0;
printf("Splitting run %i. Before:\n", run);
show_para(para);
- add_run(para, NULL, NULL, NULL, col);
+ add_run(para, NULL, NULL, col);
/* -2 here because add_run increased para->n_runs by 1 */
memmove(&para->runs[run+2], &para->runs[run+1],
(para->n_runs - run - 2)*sizeof(struct text_run));
@@ -1723,19 +1618,7 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos,
rr = &para->runs[run]; /* Because add_run realloced the runs */
rn = &para->runs[run+1];
- if ( rr->rscblock != rr->scblock) {
- macro = 1;
- }
-
- rn->rscblock = sc_block_split(rr->rscblock, run_offs);
-
- if ( !macro ) {
- /* Literal text block */
- rn->scblock = rn->rscblock;
- } else {
- /* Macro block */
- rn->scblock = rr->scblock;
- }
+ rn->scblock = sc_block_split(rr->scblock, run_offs);
rn->fontdesc = pango_font_description_copy(rr->fontdesc);
rn->col[0] = rr->col[0];
@@ -1752,11 +1635,10 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos,
for ( i=run+1; i<para->n_runs; i++ ) {
double col[4] = {0,0,0,0};
printf("Moving run %i to pos %i\n", i, pnew->n_runs);
- add_run(pnew, NULL, NULL, NULL, col);
+ add_run(pnew, NULL, NULL, col);
pnew->runs[pnew->n_runs-1] = para->runs[i];
}
pnew->scblock = pnew->runs[0].scblock;
- pnew->rscblock = pnew->runs[0].rscblock;
/* Truncate the first paragraph at the appropriate position */
para->n_runs = run+1;
@@ -1768,7 +1650,7 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos,
show_para(pnew);
/* Add a \newpara after the end of the first paragraph's SC */
- nnp = sc_block_append(rr->rscblock, strdup("newpara"), NULL, NULL, NULL);
+ nnp = sc_block_append(rr->scblock, strdup("newpara"), NULL, NULL, NULL);
set_newline_at_end(pnew, get_newline_at_end(para));
set_newline_at_end(para, nnp);
@@ -1853,12 +1735,6 @@ SCBlock *para_scblock(Paragraph *para)
}
-SCBlock *para_rscblock(Paragraph *para)
-{
- return para->rscblock;
-}
-
-
enum para_type para_type(Paragraph *para)
{
return para->type;
@@ -1872,13 +1748,11 @@ int para_debug_num_runs(Paragraph *para)
}
-int para_debug_run_info(Paragraph *para, int i, SCBlock **scblock,
- SCBlock **rscblock)
+int para_debug_run_info(Paragraph *para, int i, SCBlock **scblock)
{
if ( para->type != PARA_TYPE_TEXT ) return 1;
if ( i >= para->n_runs ) return 1;
*scblock = para->runs[i].scblock;
- *rscblock = para->runs[i].rscblock;
return 0;
}
diff --git a/src/frame.h b/src/frame.h
index b50cfaf..f52c6e6 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -42,8 +42,7 @@ typedef enum
{
GRAD_NONE,
GRAD_HORIZ,
- GRAD_VERT,
- GRAD_NOBG
+ GRAD_VERT
} GradientType;
enum para_type
@@ -115,8 +114,6 @@ struct frame
extern struct frame *frame_new(void);
extern void frame_free(struct frame *fr);
extern struct frame *add_subframe(struct frame *fr);
-extern void show_hierarchy(struct frame *fr, const char *t);
-extern void delete_subframe(struct frame *top, struct frame *fr);
extern struct frame *find_frame_with_scblocks(struct frame *top,
SCBlock *scblocks);
@@ -130,32 +127,27 @@ extern void set_para_alignment(Paragraph *para, PangoAlignment align);
extern double paragraph_height(Paragraph *para);
extern void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is);
-extern SCBlock *get_newline_at_end(Paragraph *para);
extern void set_newline_at_end(Paragraph *para, SCBlock *bl);
-extern void check_run(struct frame *fr, int pn);
extern void show_edit_pos(struct edit_pos a);
-extern void add_run(Paragraph *para, SCBlock *scblock, SCBlock *rscblock,
+extern void add_run(Paragraph *para, SCBlock *scblock,
PangoFontDescription *fdesc, double col[4]);
extern Paragraph *insert_paragraph(struct frame *fr, int pos);
extern Paragraph *add_callback_para(struct frame *fr, SCBlock *scblock,
- SCBlock *rscblock,
double w, double h,
SCCallbackDrawFunc draw_func,
SCCallbackClickFunc click_func, void *bvp,
void *vp);
extern void add_image_para(struct frame *fr, SCBlock *scblock,
- SCBlock *rscblock, const char *filename,
+ const char *filename,
ImageStore *is, double w, double h, int editable);
extern void wrap_paragraph(Paragraph *para, PangoContext *pc, double w,
size_t sel_start, size_t sel_end);
-extern size_t end_offset_of_para(struct frame *fr, int pn);
-
extern int find_cursor(struct frame *fr, double x, double y,
struct edit_pos *pos);
@@ -175,8 +167,6 @@ extern int get_cursor_pos(struct frame *fr, int cursor_para, int cursor_pos,
extern void cursor_moveh(struct frame *fr, struct edit_pos *cp, signed int dir);
-extern void cursor_movev(struct frame *fr, struct edit_pos *cp, signed int dir);
-
extern void check_callback_click(struct frame *fr, int para);
extern size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail);
@@ -187,25 +177,24 @@ extern void insert_text_in_paragraph(Paragraph *para, size_t offs,
extern void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_pos p2,
double wrap_w);
-extern size_t delete_text_in_paragraph(struct frame *fr, int npara, size_t offs0, ssize_t offs2);
-
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);
+extern void show_frame_hierarchy(struct frame *fr, const char *t);
+
extern int get_sc_pos(struct frame *fr, int pn, size_t pos,
SCBlock **bl, size_t *ppos);
extern void *get_para_bvp(Paragraph *para);
-extern Paragraph *create_paragraph(struct frame *fr, SCBlock *bl, SCBlock *rbl);
+extern Paragraph *create_paragraph(struct frame *fr, SCBlock *bl);
extern enum para_type para_type(Paragraph *para);
extern SCBlock *para_scblock(Paragraph *para);
-extern SCBlock *para_rscblock(Paragraph *para);
+extern SCBlock *para_debug_get_newline_at_end(Paragraph *para);
extern int para_debug_num_runs(Paragraph *para);
-extern int para_debug_run_info(Paragraph *para, int i, SCBlock **scblock,
- SCBlock **rscblock);
+extern int para_debug_run_info(Paragraph *para, int i, SCBlock **scblock);
#endif /* FRAME_H */
diff --git a/src/narrative_window.c b/src/narrative_window.c
index e549fc1..b287f61 100644
--- a/src/narrative_window.c
+++ b/src/narrative_window.c
@@ -185,105 +185,31 @@ static void delete_slide_sig(GSimpleAction *action, GVariant *parameter,
}
-static struct template_id *get_templates(SCBlock *ss, int *n)
-{
- struct template_id *list;
- SCInterpreter *scin;
-
- scin = sc_interp_new(NULL, NULL, NULL, NULL);
- sc_interp_run_stylesheet(scin, ss); /* ss == NULL is OK */
- list = sc_interp_get_templates(scin, n);
- sc_interp_destroy(scin);
- return list;
-}
-
-
-static void update_template_menus(NarrativeWindow *nw)
-{
- struct template_id *templates;
- int i, n_templates;
-
- templates = get_templates(nw->p->stylesheet, &n_templates);
-
- for ( i=0; i<n_templates; i++ ) {
- free(templates[i].name);
- free(templates[i].friendlyname);
- sc_block_free(templates[i].scblock);
- }
-
- free(templates);
-}
-
-
-static SCBlock *get_slide_template(SCBlock *ss)
-{
- struct template_id *templates;
- int i, n_templates;
- SCBlock *ret = NULL;
-
- templates = get_templates(ss, &n_templates);
-
- for ( i=0; i<n_templates; i++ ) {
- if ( strcmp(templates[i].name, "slide") == 0 ) {
- ret = templates[i].scblock;
- } else {
- sc_block_free(templates[i].scblock);
- }
- free(templates[i].name);
- free(templates[i].friendlyname);
- }
- free(templates);
-
- /* No template? */
- if ( ret == NULL ) {
- ret = sc_parse("\\slide{}");
- }
-
- return ret; /* NB this is a copy of the one owned by the interpreter */
-}
-
-
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);
+ GFile *file;
+ Stylesheet *new_ss;
- stext = load_everything(filename);
- if ( stext != NULL ) {
+ file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(d));
- SCBlock *bl;
- SCBlock *ss;
- bl = sc_parse(stext);
- free(stext);
- ss = find_stylesheet(bl);
+ new_ss = stylesheet_load(file);
+ if ( new_ss != NULL ) {
- if ( ss != NULL ) {
+ stylesheet_free(nw->p->stylesheet);
+ nw->p->stylesheet = new_ss;
+ sc_editor_set_stylesheet(nw->sceditor, new_ss);
- /* Substitute the style sheet in
- * presentation Storycode */
- replace_stylesheet(nw->p, ss);
+ /* Full rerender */
+ sc_editor_set_scblock(nw->sceditor, nw->dummy_top);
- sc_editor_set_stylesheet(nw->sceditor, ss);
-
- /* Full rerender, first block may have
- * changed */
- sc_editor_set_scblock(nw->sceditor,
- nw->dummy_top);
-
- } else {
- fprintf(stderr, _("Not a style sheet\n"));
- }
} else {
fprintf(stderr, _("Failed to load\n"));
}
- g_free(filename);
+ g_object_unref(file);
}
@@ -351,9 +277,8 @@ static void add_slide_sig(GSimpleAction *action, GVariant *parameter,
/* Split the current paragraph */
nsblock = split_paragraph_at_cursor(nw->sceditor);
- /* Get the template */
- templ = get_slide_template(nw->p->stylesheet); /* our copy */
- show_sc_blocks(templ);
+ /* FIXME: Template from JSON */
+ templ = sc_parse("\\slide{}");
/* Link the new SCBlock in */
if ( nsblock != NULL ) {
@@ -886,7 +811,6 @@ NarrativeWindow *narrative_window_new(struct presentation *p, GApplication *papp
"win.last");
update_toolbar(nw);
- update_template_menus(nw);
scroll = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
diff --git a/src/presentation.c b/src/presentation.c
index b8b4589..eab0f5a 100644
--- a/src/presentation.c
+++ b/src/presentation.c
@@ -67,6 +67,59 @@ char *get_titlebar_string(struct presentation *p)
}
+static void find_and_load_stylesheet(struct presentation *p, GFile *file)
+{
+ GFile *ssfile;
+ GFile *parent;
+ gchar *ssuri;
+
+ if ( file != NULL ) {
+
+ /* First choice: /same/directory/<presentation>.ss */
+ ssuri = g_file_get_uri(file);
+ if ( ssuri != NULL ) {
+ size_t l = strlen(ssuri);
+ if ( ssuri[l-3] == '.' && ssuri[l-2] == 's' && ssuri[l-1] =='c' ) {
+ ssuri[l-1] = 's';
+ ssfile = g_file_new_for_uri(ssuri);
+ p->stylesheet = stylesheet_load(ssfile);
+ g_object_unref(ssfile);
+ g_free(ssuri);
+ }
+ }
+
+ /* Second choice: /same/directory/stylesheet.ss */
+ if ( p->stylesheet == NULL ) {
+ parent = g_file_get_parent(file);
+ if ( parent != NULL ) {
+ ssfile = g_file_get_child(parent, "stylesheet.ss");
+ if ( ssfile != NULL ) {
+ p->stylesheet = stylesheet_load(ssfile);
+ g_object_unref(ssfile);
+ }
+ }
+ }
+
+ }
+
+ /* Third choice: <cwd>/stylesheet.ss */
+ if ( p->stylesheet == NULL ) {
+ ssfile = g_file_new_for_path("./stylesheet.ss");
+ p->stylesheet = stylesheet_load(ssfile);
+ g_object_unref(ssfile);
+ }
+
+ /* Fourth choice: internal default stylesheet */
+ if ( p->stylesheet == NULL ) {
+ ssfile = g_file_new_for_uri("resource:///uk/me/bitwiz/Colloquium/default.ss");
+ p->stylesheet = stylesheet_load(ssfile);
+ g_object_unref(ssfile);
+ }
+
+ /* Last resort is NULL stylesheet and SCInterpreter's defaults */
+}
+
+
struct presentation *new_presentation(const char *imagestore)
{
struct presentation *new;
@@ -89,6 +142,8 @@ struct presentation *new_presentation(const char *imagestore)
new->lang = pango_language_get_default();
+ find_and_load_stylesheet(new, NULL);
+
return new;
}
@@ -226,75 +281,17 @@ SCBlock *prev_slide(struct presentation *p, SCBlock *sl)
}
-int replace_stylesheet(struct presentation *p, SCBlock *ss)
-{
- /* Create style sheet from union of old and new,
- * preferring items from the new one */
-
- /* If there was no stylesheet before, add a dummy one */
- if ( p->stylesheet == NULL ) {
- p->stylesheet = sc_block_append_end(p->scblocks,
- "stylesheet", NULL, NULL);
- }
-
- /* 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"));
- }
-}
-
-
static void set_slide_size_from_stylesheet(struct presentation *p)
{
- SCInterpreter *scin;
- double w, h;
- int r;
-
- if ( p->stylesheet == NULL ) return;
-
- scin = sc_interp_new(NULL, NULL, NULL, NULL);
- sc_interp_run_stylesheet(scin, p->stylesheet); /* ss == NULL is OK */
- r = sc_interp_get_slide_size(scin, &w, &h);
- sc_interp_destroy(scin);
-
- if ( r == 0 ) {
- p->slide_width = w;
- p->slide_height = h;
+ char *result;
+
+ result = stylesheet_lookup(p->stylesheet, "$.slide", "size");
+ if ( result != NULL ) {
+ float v[2];
+ if ( parse_double(result, v) == 0 ) {
+ p->slide_width = v[0];
+ p->slide_height = v[1];
+ }
}
}
@@ -324,7 +321,10 @@ int load_presentation(struct presentation *p, GFile *file)
return r; /* Error */
}
- install_stylesheet(p);
+ p->stylesheet = NULL;
+
+ find_and_load_stylesheet(p, file);
+
set_slide_size_from_stylesheet(p);
assert(p->uri == NULL);
diff --git a/src/presentation.h b/src/presentation.h
index ed8a188..ea3780e 100644
--- a/src/presentation.h
+++ b/src/presentation.h
@@ -34,6 +34,7 @@ struct presentation;
#include "slideshow.h"
#include "narrative_window.h"
#include "slide_window.h"
+#include "stylesheet.h"
struct menu_pl;
@@ -56,15 +57,13 @@ struct presentation
double slide_width;
double slide_height;
- SCBlock *stylesheet;
SCBlock *scblocks;
+ Stylesheet *stylesheet;
};
extern struct presentation *new_presentation(const char *imagestore);
-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/print.c b/src/print.c
index c50a3c5..43c967e 100644
--- a/src/print.c
+++ b/src/print.c
@@ -54,9 +54,6 @@ struct print_stuff
struct frame *top;
int start_paras[256];
int slide_number;
-
- ImageStore *is;
- const char *storename;
};
@@ -194,13 +191,11 @@ static void begin_narrative_print(GtkPrintOperation *op, GtkPrintContext *ctx,
sc_callback_list_add_callback(cbl, "slide", print_create_thumbnail,
print_render_thumbnail, NULL, ps);
- ps->is = imagestore_new(ps->storename);
-
pc = gtk_print_context_create_pango_context(ctx);
dummy_top = sc_block_new_parent(ps->p->scblocks, "presentation");
ps->top = interp_and_shape(dummy_top, ps->p->stylesheet, cbl,
- ps->is, 0, pc,
+ ps->p->is, 0, pc,
gtk_print_context_get_width(ctx),
gtk_print_context_get_height(ctx),
ps->p->lang);
@@ -242,7 +237,10 @@ static void print_narrative(GtkPrintOperation *op, GtkPrintContext *ctx,
h += paragraph_height(ps->top->paras[i]);
if ( h > page_height ) return;
- render_paragraph(cr, ps->top->paras[i], ps->is);
+ cairo_save(cr);
+ render_paragraph(cr, ps->top->paras[i], ps->p->is);
+ cairo_restore(cr);
+
cairo_translate(cr, 0.0, paragraph_height(ps->top->paras[i]));
}
diff --git a/src/render.c b/src/render.c
index 580a4cd..f9f4cca 100644
--- a/src/render.c
+++ b/src/render.c
@@ -48,8 +48,6 @@ static void do_background(cairo_t *cr, struct frame *fr)
{
cairo_pattern_t *patt = NULL;
- if ( fr->grad == GRAD_NOBG ) return; /* Should not end up here */
-
cairo_new_path(cr);
cairo_rectangle(cr, 0.0, 0.0, fr->w, fr->h);
@@ -86,9 +84,6 @@ static void do_background(cairo_t *cr, struct frame *fr)
cairo_set_source(cr, patt);
break;
- case GRAD_NOBG:
- break;
-
}
cairo_fill(cr);
@@ -176,14 +171,14 @@ int recursive_wrap(struct frame *fr, PangoContext *pc)
}
-struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet,
+struct frame *interp_and_shape(SCBlock *scblocks, Stylesheet *stylesheet,
SCCallbackList *cbl, ImageStore *is,
int slide_number,
PangoContext *pc, double w, double h,
PangoLanguage *lang)
{
SCInterpreter *scin;
- char snum[64];
+// char snum[64];
struct frame *top;
top = frame_new();
@@ -203,12 +198,13 @@ struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet,
sc_interp_set_callbacks(scin, cbl);
- snprintf(snum, 63, "%i", slide_number);
- add_macro(scin, "slidenumber", snum);
-
- if ( stylesheet != NULL ) {
- sc_interp_run_stylesheet(scin, stylesheet);
- }
+ /* FIXME: Set up slide number and style sheet */
+// snprintf(snum, 63, "%i", slide_number);
+// add_macro(scin, "slidenumber", snum);
+//
+// if ( stylesheet != NULL ) {
+// sc_interp_run_stylesheet(scin, stylesheet);
+// }
top->fontdesc = pango_font_description_copy(sc_interp_get_fontdesc(scin));
top->col[0] = sc_interp_get_fgcol(scin)[0];
@@ -216,7 +212,7 @@ struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet,
top->col[2] = sc_interp_get_fgcol(scin)[2];
top->col[3] = sc_interp_get_fgcol(scin)[3];
- sc_interp_add_block(scin, scblocks);
+ sc_interp_add_block(scin, scblocks, stylesheet);
sc_interp_destroy(scin);
@@ -226,7 +222,7 @@ struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet,
static struct frame *render_sc_with_context(SCBlock *scblocks,
cairo_t *cr, double log_w, double log_h,
- SCBlock *stylesheet, SCCallbackList *cbl,
+ Stylesheet *stylesheet, SCCallbackList *cbl,
ImageStore *is,
int slide_number, PangoLanguage *lang,
PangoContext *pc)
@@ -250,7 +246,7 @@ static struct frame *render_sc_with_context(SCBlock *scblocks,
cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h,
double log_w, double log_h,
- SCBlock *stylesheet, SCCallbackList *cbl,
+ Stylesheet *stylesheet, SCCallbackList *cbl,
ImageStore *is,
int slide_number, struct frame **ptop,
PangoLanguage *lang)
diff --git a/src/render.h b/src/render.h
index aadb033..0cfae26 100644
--- a/src/render.h
+++ b/src/render.h
@@ -35,7 +35,7 @@
/* Convienience function to run the entire pipeline */
extern cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h,
double log_w, double log_h,
- SCBlock *stylesheet, SCCallbackList *cbl,
+ Stylesheet *stylesheet, SCCallbackList *cbl,
ImageStore *is,
int slide_number, struct frame **ptop,
PangoLanguage *lang);
@@ -44,7 +44,7 @@ extern cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h,
* Needs to be followed by: wrap_contents() (recursively)
* recursive_draw()
*/
-extern struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet,
+extern struct frame *interp_and_shape(SCBlock *scblocks, Stylesheet *stylesheet,
SCCallbackList *cbl,
ImageStore *is,
int slide_number, PangoContext *pc,
diff --git a/src/sc_editor.c b/src/sc_editor.c
index 999f919..e95beb4 100644
--- a/src/sc_editor.c
+++ b/src/sc_editor.c
@@ -384,7 +384,7 @@ void sc_editor_ensure_cursor(SCEditor *e)
}
-void sc_editor_remove_cursor(SCEditor *e)
+static void sc_editor_remove_cursor(SCEditor *e)
{
e->cursor_frame = NULL;
e->cpos.para = 0;
@@ -999,7 +999,7 @@ static void insert_text(char *t, SCEditor *e)
fprintf(stderr, _("Failed to insert paragraph\n"));
return;
}
- add_run(pnew, ad, ad, e->cursor_frame->fontdesc,
+ add_run(pnew, ad, e->cursor_frame->fontdesc,
e->cursor_frame->col);
wrap_frame(e->cursor_frame, e->pc);
@@ -1222,7 +1222,7 @@ static void check_paragraph(struct frame *fr, PangoContext *pc,
}
scblocks = sc_block_append(scblocks, NULL, NULL, strdup(""), NULL);
- add_run(para, scblocks, scblocks, fr->fontdesc, fr->col);
+ add_run(para, scblocks, fr->fontdesc, fr->col);
wrap_paragraph(para, pc, fr->w - fr->pad_l - fr->pad_r, 0, 0);
}
@@ -1979,30 +1979,12 @@ void sc_editor_set_scblock(SCEditor *e, SCBlock *scblocks)
}
-SCBlock *sc_editor_get_scblock(SCEditor *e)
-{
- return e->scblocks;
-}
-
-
static void update_size_request(SCEditor *e)
{
gtk_widget_set_size_request(GTK_WIDGET(e), 0, e->h + 2.0*e->min_border);
}
-void sc_editor_set_size(SCEditor *e, int w, int h)
-{
- e->w = w;
- e->h = h;
- update_size_request(e);
- if ( gtk_widget_get_mapped(GTK_WIDGET(e)) ) {
- full_rerender(e);
- sc_editor_redraw(e);
- }
-}
-
-
void sc_editor_set_logical_size(SCEditor *e, double w, double h)
{
e->log_w = w;
@@ -2033,7 +2015,7 @@ void sc_editor_set_top_frame_editable(SCEditor *e, int top_frame_editable)
}
-void sc_editor_set_stylesheet(SCEditor *e, SCBlock *stylesheet)
+void sc_editor_set_stylesheet(SCEditor *e, Stylesheet *stylesheet)
{
e->stylesheet = stylesheet;
}
@@ -2125,7 +2107,7 @@ void sc_editor_set_imagestore(SCEditor *e, ImageStore *is)
}
-SCEditor *sc_editor_new(SCBlock *scblocks, SCBlock *stylesheet,
+SCEditor *sc_editor_new(SCBlock *scblocks, Stylesheet *stylesheet,
PangoLanguage *lang, const char *storename)
{
SCEditor *sceditor;
diff --git a/src/sc_editor.h b/src/sc_editor.h
index adbbaf2..d3c111b 100644
--- a/src/sc_editor.h
+++ b/src/sc_editor.h
@@ -32,6 +32,7 @@
#include "frame.h"
#include "sc_interp.h"
+#include "stylesheet.h"
struct presentation;
@@ -94,7 +95,7 @@ struct _sceditor
double log_w; /* Size of surface in "SC units" */
double log_h;
SCBlock *scblocks;
- SCBlock *stylesheet;
+ Stylesheet *stylesheet;
ImageStore *is;
SCCallbackList *cbl;
struct frame *top;
@@ -168,12 +169,9 @@ typedef struct _sceditor SCEditor;
typedef struct _sceditorclass SCEditorClass;
extern void sc_editor_set_scblock(SCEditor *e, SCBlock *scblocks);
-extern void sc_editor_set_stylesheet(SCEditor *e, SCBlock *stylesheet);
-extern SCBlock *sc_editor_get_scblock(SCEditor *e);
-extern GtkWidget *sc_editor_get_widget(SCEditor *e);
-extern SCEditor *sc_editor_new(SCBlock *scblocks, SCBlock *stylesheet,
+extern void sc_editor_set_stylesheet(SCEditor *e, Stylesheet *stylesheet);
+extern SCEditor *sc_editor_new(SCBlock *scblocks, Stylesheet *stylesheet,
PangoLanguage *lang, const char *storename);
-extern void sc_editor_set_size(SCEditor *e, int w, int h);
extern void sc_editor_set_logical_size(SCEditor *e, double w, double h);
extern void sc_editor_set_flow(SCEditor *e, int flow);
extern void sc_editor_set_scale(SCEditor *e, int scale);
@@ -188,7 +186,6 @@ extern void sc_editor_paste(SCEditor *e);
extern void sc_editor_add_storycode(SCEditor *e, const char *sc);
extern void sc_editor_copy_selected_frame(SCEditor *e);
extern void sc_editor_delete_selected_frame(SCEditor *e);
-extern void sc_editor_remove_cursor(SCEditor *e);
extern void sc_editor_ensure_cursor(SCEditor *e);
extern SCBlock *split_paragraph_at_cursor(SCEditor *e);
diff --git a/src/sc_interp.c b/src/sc_interp.c
index dea8446..7bbfeeb 100644
--- a/src/sc_interp.c
+++ b/src/sc_interp.c
@@ -38,21 +38,6 @@
#include "utils.h"
-struct macro
-{
- char *name;
- SCBlock *bl;
- struct macro *prev; /* Previous declaration, or NULL */
-};
-
-
-struct template
-{
- char *name;
- SCBlock *bl;
-};
-
-
struct sc_state
{
PangoFontDescription *fontdesc;
@@ -71,25 +56,8 @@ struct sc_state
double slide_height;
struct frame *fr; /* The current frame */
-
- int n_macros;
- int max_macros;
- struct macro *macros; /* Contents need to be copied on push */
-
- int n_styles;
- int max_styles;
- struct macro *styles; /* Contents need to be copied on push */
-
- int n_templates;
- int max_templates;
- struct template *templates;
-
- SCBlock *macro_contents; /* If running a macro, the child block of the caller */
- SCBlock *macro_real_block; /* If running a macro, the block which called the macro */
- int macro_editable; /* If running a macro, whether this bit can be edited or not */
};
-
struct _scinterp
{
PangoContext *pc;
@@ -118,6 +86,17 @@ struct _sccallbacklist
};
+static int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss)
+{
+ while ( bl != NULL ) {
+ if ( sc_interp_add_block(scin, bl, ss) ) return 1;
+ bl = sc_block_next(bl);
+ }
+
+ return 0;
+}
+
+
SCCallbackList *sc_callback_list_new()
{
SCCallbackList *cbl;
@@ -242,12 +221,6 @@ static int check_callback(SCInterpreter *scin, SCBlock *bl)
double w, h;
int r;
void *bvp;
- SCBlock *rbl;
-
- rbl = bl;
- if ( sc_interp_get_macro_real_block(scin) != NULL ) {
- bl = sc_interp_get_macro_real_block(scin);
- }
if ( strcmp(cbl->names[i], name) != 0 ) continue;
r = cbl->box_funcs[i](scin, bl, &w, &h, &bvp, cbl->vps[i]);
@@ -255,7 +228,7 @@ static int check_callback(SCInterpreter *scin, SCBlock *bl)
struct sc_state *st = &scin->state[scin->j];
Paragraph *pnew;
pnew = add_callback_para(sc_interp_get_frame(scin),
- bl, rbl, w, h,
+ bl, w, h,
cbl->draw_funcs[i],
cbl->click_funcs[i],
bvp, cbl->vps[i]);
@@ -293,41 +266,6 @@ double *sc_interp_get_fgcol(SCInterpreter *scin)
}
-double *sc_interp_get_bgcol(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->bgcol;
-}
-
-
-double *sc_interp_get_bgcol2(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->bgcol2;
-}
-
-
-GradientType sc_interp_get_bggrad(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->bggrad;
-}
-
-
-int sc_interp_get_ascent(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->ascent;
-}
-
-
-int sc_interp_get_height(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->height;
-}
-
-
static void set_frame_default_style(struct frame *fr, SCInterpreter *scin)
{
if ( fr == NULL ) return;
@@ -526,38 +464,22 @@ static void set_bggrad(SCInterpreter *scin, const char *options,
{
struct sc_state *st = &scin->state[scin->j];
GdkRGBA col1, col2;
- char *n2;
- char *optcopy = strdup(options);
- if ( options == NULL ) {
- fprintf(stderr, _("Invalid bg gradient spec '%s'\n"), options);
- return;
- }
-
- n2 = strchr(optcopy, ',');
- if ( n2 == NULL ) {
- fprintf(stderr, _("Invalid bg gradient spec '%s'\n"), options);
- return;
- }
+ if ( parse_colour_duo(options, &col1, &col2) == 0 ) {
- n2[0] = '\0';
+ st->bgcol[0] = col1.red;
+ st->bgcol[1] = col1.green;
+ st->bgcol[2] = col1.blue;
+ st->bgcol[3] = col1.alpha;
- gdk_rgba_parse(&col1, optcopy);
- gdk_rgba_parse(&col2, &n2[1]);
+ st->bgcol2[0] = col2.red;
+ st->bgcol2[1] = col2.green;
+ st->bgcol2[2] = col2.blue;
+ st->bgcol2[3] = col2.alpha;
- st->bgcol[0] = col1.red;
- st->bgcol[1] = col1.green;
- st->bgcol[2] = col1.blue;
- st->bgcol[3] = col1.alpha;
+ st->bggrad = grad;
- st->bgcol2[0] = col2.red;
- st->bgcol2[1] = col2.green;
- st->bgcol2[2] = col2.blue;
- st->bgcol2[3] = col2.alpha;
-
- st->bggrad = grad;
-
- free(optcopy);
+ }
}
@@ -611,13 +533,6 @@ struct frame *sc_interp_get_frame(SCInterpreter *scin)
}
-SCBlock *sc_interp_get_macro_real_block(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->macro_real_block;
-}
-
-
static void set_frame(SCInterpreter *scin, struct frame *fr)
{
struct sc_state *st = &scin->state[scin->j];
@@ -649,33 +564,6 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang,
scin->cbl = NULL;
st = &scin->state[0];
- st->n_macros = 0;
- st->max_macros = 16;
- st->macros = malloc(16*sizeof(struct macro));
- if ( st->macros == NULL ) {
- free(scin->state);
- free(scin);
- return NULL;
- }
- st->n_styles = 0;
- st->max_styles = 16;
- st->styles = malloc(16*sizeof(struct macro));
- if ( st->styles == NULL ) {
- free(scin->state);
- free(scin);
- return NULL;
- }
- st->n_templates = 0;
- st->max_templates = 16;
- st->templates = malloc(16*sizeof(struct template));
- if ( st->templates == NULL ) {
- free(scin->state);
- free(scin);
- return NULL;
- }
- st->macro_contents = NULL;
- st->macro_real_block = NULL;
- st->macro_editable = 0;
st->fr = NULL;
st->paraspace[0] = 0.0;
st->paraspace[1] = 0.0;
@@ -696,7 +584,7 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang,
st->bgcol2[1] = 1.0;
st->bgcol2[2] = 1.0;
st->bgcol2[3] = 1.0;
- st->bggrad = GRAD_NOBG;
+ st->bggrad = GRAD_NONE;
scin->lang = lang;
/* The "ultimate" default font */
@@ -713,8 +601,6 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang,
void sc_interp_destroy(SCInterpreter *scin)
{
- /* FIXME: Free all templates and macros */
-
/* Empty the stack */
while ( scin->j > 0 ) {
sc_interp_restore(scin);
@@ -729,34 +615,6 @@ void sc_interp_destroy(SCInterpreter *scin)
}
-static int parse_double(const char *a, float v[2])
-{
- int nn;
-
- nn = sscanf(a, "%fx%f", &v[0], &v[1]);
- if ( nn != 2 ) {
- fprintf(stderr, _("Invalid size '%s'\n"), a);
- return 1;
- }
-
- return 0;
-}
-
-
-static int parse_tuple(const char *a, float v[4])
-{
- int nn;
-
- nn = sscanf(a, "%f,%f,%f,%f", &v[0], &v[1], &v[2], &v[3]);
- if ( nn != 4 ) {
- fprintf(stderr, _("Invalid tuple '%s'\n"), a);
- return 1;
- }
-
- return 0;
-}
-
-
static void set_padding(struct frame *fr, const char *opts)
{
float p[4];
@@ -788,19 +646,6 @@ static void set_paraspace(SCInterpreter *scin, const char *opts)
}
-static void set_slide_size(SCInterpreter *scin, const char *opts)
-{
- float p[2];
- struct sc_state *st = &scin->state[scin->j];
-
- if ( parse_double(opts, p) ) return;
-
- st->slide_width = p[0];
- st->slide_height = p[1];
- st->have_size = 1;
-}
-
-
void update_geom(struct frame *fr)
{
char geom[256];
@@ -1015,24 +860,17 @@ static void maybe_recurse_before(SCInterpreter *scin, SCBlock *child)
}
-static void maybe_recurse_after(SCInterpreter *scin, SCBlock *child)
+static void maybe_recurse_after(SCInterpreter *scin, SCBlock *child,
+ Stylesheet *ss)
{
if ( child == NULL ) return;
- sc_interp_add_blocks(scin, child);
+ sc_interp_add_blocks(scin, child, ss);
sc_interp_restore(scin);
}
-static int in_macro(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- if ( st->macro_contents == NULL ) return 0;
- return 1;
-}
-
-
-static void add_newpara(struct frame *fr, SCBlock *bl, SCBlock *mrb)
+static void add_newpara(struct frame *fr, SCBlock *bl)
{
Paragraph *last_para;
@@ -1043,7 +881,7 @@ static void add_newpara(struct frame *fr, SCBlock *bl, SCBlock *mrb)
/* The block after the \newpara will always be the first one of the
* next paragraph, by definition, even if it's \f or another \newpara */
- create_paragraph(fr, sc_block_next(mrb), sc_block_next(bl));
+ create_paragraph(fr, sc_block_next(bl));
}
@@ -1055,7 +893,6 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl,
PangoFontDescription *fontdesc;
double *col;
struct sc_state *st = &scin->state[scin->j];
- SCBlock *rbl;
Paragraph *para;
/* Empty block? */
@@ -1064,47 +901,113 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl,
fontdesc = sc_interp_get_fontdesc(scin);
col = sc_interp_get_fgcol(scin);
- rbl = bl;
- if ( st->macro_real_block != NULL ) {
- bl = st->macro_real_block;
- }
-
para = last_para(fr);
if ( (para == NULL) || (para_type(para) != PARA_TYPE_TEXT) ) {
/* Last paragraph is not text.
* or: no paragraphs yet.
* Either way: Create the first one */
- para = create_paragraph(fr, bl, rbl);
+ para = create_paragraph(fr, bl);
}
set_para_alignment(para, st->alignment);
- add_run(para, bl, rbl, fontdesc, col);
+ add_run(para, bl, fontdesc, col);
set_para_spacing(para, st->paraspace);
return 0;
}
-void sc_interp_run_style(SCInterpreter *scin, const char *sname)
+static void apply_style(SCInterpreter *scin, Stylesheet *ss, const char *path)
{
- int i;
- struct sc_state *st = &scin->state[scin->j];
+ char *result;
- for ( i=0; i<st->n_styles; i++ ) {
- if ( strcmp(sname, st->styles[i].name) == 0 ) {
- sc_interp_add_blocks(scin, st->styles[i].bl);
- return;
+ if ( ss == NULL ) return;
+
+ /* Font */
+ result = stylesheet_lookup(ss, path, "font");
+ if ( result != NULL ) set_font(scin, result);
+
+ /* Foreground colour */
+ result = stylesheet_lookup(ss, path, "fgcol");
+ if ( result != NULL ) set_colour(scin, result);
+
+ /* Background (vertical gradient) */
+ result = stylesheet_lookup(ss, path, "bggradv");
+ if ( result != NULL ) set_bggrad(scin, result, GRAD_VERT);
+
+ /* Background (horizontal gradient) */
+ result = stylesheet_lookup(ss, path, "bggradh");
+ if ( result != NULL ) set_bggrad(scin, result, GRAD_HORIZ);
+
+ /* Background (solid colour) */
+ result = stylesheet_lookup(ss, path, "bgcol");
+ if ( result != NULL ) set_bgcol(scin, result);
+
+ /* Padding */
+ result = stylesheet_lookup(ss, path, "pad");
+ if ( result != NULL ) set_padding(sc_interp_get_frame(scin), result);
+
+ /* Paragraph spacing */
+ result = stylesheet_lookup(ss, path, "paraspace");
+ if ( result != NULL ) set_paraspace(scin, result);
+
+ /* Alignment */
+ result = stylesheet_lookup(ss, path, "alignment");
+ if ( result != NULL ) {
+ if ( strcmp(result, "center") == 0 ) {
+ set_alignment(scin, PANGO_ALIGN_CENTER);
}
+ if ( strcmp(result, "left") == 0 ) {
+ set_alignment(scin, PANGO_ALIGN_LEFT);
+ }
+ if ( strcmp(result, "right") == 0 ) {
+ set_alignment(scin, PANGO_ALIGN_RIGHT);
+ }
+ }
+
+ update_bg(scin);
+}
+
+
+static void output_frame(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss,
+ const char *stylename)
+{
+ struct frame *fr;
+ SCBlock *child = sc_block_child(bl);
+ const char *options = sc_block_options(bl);
+ char *result;
+
+ fr = add_subframe(sc_interp_get_frame(scin));
+ fr->scblocks = bl;
+ fr->resizable = 1;
+ if ( fr == NULL ) {
+ fprintf(stderr, _("Failed to add frame.\n"));
+ return;
+ }
+
+ /* Lowest priority: current state of interpreter */
+ set_frame_default_style(fr, scin);
+
+ /* Next priority: geometry from stylesheet */
+ result = stylesheet_lookup(ss, stylename, "geometry");
+ if ( result != NULL ) {
+ parse_frame_options(fr, sc_interp_get_frame(scin), result);
}
+
+ /* Highest priority: parameters to \f (or \slidetitle etc) */
+ parse_frame_options(fr, sc_interp_get_frame(scin), options);
+
+ maybe_recurse_before(scin, child);
+ set_frame(scin, fr);
+ apply_style(scin, ss, stylename);
+ maybe_recurse_after(scin, child, ss);
}
-static int check_outputs(SCBlock *bl, SCInterpreter *scin)
+static int check_outputs(SCBlock *bl, SCInterpreter *scin, Stylesheet *ss)
{
const char *name = sc_block_name(bl);
const char *options = sc_block_options(bl);
- SCBlock *child = sc_block_child(bl);
- struct sc_state *st = &scin->state[scin->j];
if ( name == NULL ) {
add_text(sc_interp_get_frame(scin),
@@ -1116,11 +1019,7 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin)
if ( parse_image_options(options, sc_interp_get_frame(scin),
&w, &h, &filename) == 0 )
{
- SCBlock *rbl = bl;
- if ( st->macro_real_block != NULL ) {
- bl = st->macro_real_block;
- }
- add_image_para(sc_interp_get_frame(scin), bl, rbl,
+ add_image_para(sc_interp_get_frame(scin), bl,
filename, scin->is, w, h, 1);
free(filename);
} else {
@@ -1129,38 +1028,20 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin)
}
} else if ( strcmp(name, "f")==0 ) {
+ output_frame(scin, bl, ss, "$.slide.frame");
- struct frame *fr;
+ } else if ( strcmp(name, "slidetitle")==0 ) {
+ output_frame(scin, bl, ss, "$.slide.slidetitle");
- fr = add_subframe(sc_interp_get_frame(scin));
- fr->scblocks = bl;
- if ( in_macro(scin) ) {
- fr->resizable = 0;
- } else {
- fr->resizable = 1;
- }
- if ( fr == NULL ) {
- fprintf(stderr, _("Failed to add frame.\n"));
- return 1;
- }
-
- set_frame_default_style(fr, scin);
+ } else if ( strcmp(name, "prestitle")==0 ) {
+ output_frame(scin, bl, ss, "$.slide.prestitle");
- parse_frame_options(fr, sc_interp_get_frame(scin), options);
-
- maybe_recurse_before(scin, child);
- set_frame(scin, fr);
- sc_interp_run_style(scin, "frame");
- maybe_recurse_after(scin, child);
+ } else if ( strcmp(name, "author")==0 ) {
+ output_frame(scin, bl, ss, "$.slide.author");
} else if ( strcmp(name, "newpara")==0 ) {
-
struct frame *fr = sc_interp_get_frame(scin);
- SCBlock *rbl = bl;
- if ( st->macro_real_block != NULL ) {
- bl = st->macro_real_block;
- }
- add_newpara(fr, bl, rbl);
+ add_newpara(fr, bl);
} else {
return 0;
@@ -1170,68 +1051,7 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin)
}
-static int check_macro(const char *name, SCInterpreter *scin)
-{
- int i;
- struct sc_state *st = &scin->state[scin->j];
-
- if ( name == NULL ) return 0;
-
- for ( i=0; i<st->n_macros; i++ ) {
- if ( strcmp(st->macros[i].name, name) == 0 ) {
- return 1;
- }
- }
-
- return 0;
-}
-
-
-static void exec_macro(SCBlock *bl, SCInterpreter *scin, SCBlock *child)
-{
- struct sc_state *st = &scin->state[scin->j];
- int i;
- const char *name;
-
- name = sc_block_name(bl);
- for ( i=0; i<st->n_macros; i++ ) {
- if ( strcmp(st->macros[i].name, name) == 0 ) {
- sc_interp_save(scin);
- scin->state[scin->j].macro_real_block = bl;
- scin->state[scin->j].macro_contents = child;
- sc_interp_add_blocks(scin, scin->state[scin->j].macros[i].bl);
- sc_interp_restore(scin);
- break; /* Stop iterating, because "st" is now invalid */
- }
- }
-}
-
-
-static void run_macro_contents(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- SCBlock *contents = st->macro_contents;
-
- sc_interp_save(scin);
- scin->state[scin->j].macro_real_block = NULL;
- sc_interp_add_blocks(scin, contents);
- sc_interp_restore(scin);
-}
-
-
-static void run_editable(SCInterpreter *scin, SCBlock *contents)
-{
- //struct sc_state *st = &scin->state[scin->j];
-
- sc_interp_save(scin);
- //scin->state[scin->j].macro_real_block = NULL;
- scin->state[scin->j].macro_editable = 1;
- sc_interp_add_blocks(scin, contents);
- sc_interp_restore(scin);
-}
-
-
-int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl)
+int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss)
{
const char *name = sc_block_name(bl);
const char *options = sc_block_options(bl);
@@ -1241,16 +1061,11 @@ int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl)
//show_sc_blocks(bl);
//printf("<------------\n");
- if ( check_macro(name, scin) ) {
- sc_interp_save(scin);
- exec_macro(bl, scin, child);
- sc_interp_restore(scin);
-
- } else if ( check_callback(scin, bl) ) {
+ if ( check_callback(scin, bl) ) {
/* Handled in check_callback, don't do anything else */
} else if ((sc_interp_get_frame(scin) != NULL)
- && check_outputs(bl, scin) ) {
+ && check_outputs(bl, scin, ss) ) {
/* Block handled as output thing */
} else if ( name == NULL ) {
@@ -1258,95 +1073,86 @@ int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl)
} else if ( strcmp(name, "presentation") == 0 ) {
maybe_recurse_before(scin, child);
- sc_interp_run_style(scin, "narrative");
- maybe_recurse_after(scin, child);
-
- } else if ( strcmp(name, "stylesheet") == 0 ) {
- /* Ignore (see sc_interp_run_stylesheet) */
+ apply_style(scin, ss, "$.narrative");
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "slide") == 0 ) {
maybe_recurse_before(scin, child);
- sc_interp_run_style(scin, "slide");
- maybe_recurse_after(scin, child);
+ apply_style(scin, ss, "$.slide");
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "font") == 0 ) {
maybe_recurse_before(scin, child);
set_font(scin, options);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "fontsize") == 0 ) {
maybe_recurse_before(scin, child);
set_fontsize(scin, options);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "bold") == 0 ) {
maybe_recurse_before(scin, child);
set_bold(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "oblique") == 0 ) {
maybe_recurse_before(scin, child);
set_oblique(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "italic") == 0 ) {
maybe_recurse_before(scin, child);
set_italic(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "lalign") == 0 ) {
maybe_recurse_before(scin, child);
set_alignment(scin, PANGO_ALIGN_LEFT);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "ralign") == 0 ) {
maybe_recurse_before(scin, child);
set_alignment(scin, PANGO_ALIGN_RIGHT);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "center") == 0 ) {
maybe_recurse_before(scin, child);
set_alignment(scin, PANGO_ALIGN_CENTER);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "fgcol") == 0 ) {
maybe_recurse_before(scin, child);
set_colour(scin, options);
- maybe_recurse_after(scin, child);
-
- } else if ( strcmp(name, "contents") == 0 ) {
- run_macro_contents(scin);
-
- } else if ( strcmp(name, "editable") == 0 ) {
- run_editable(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "pad") == 0 ) {
maybe_recurse_before(scin, child);
set_padding(sc_interp_get_frame(scin), options);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "bgcol") == 0 ) {
maybe_recurse_before(scin, child);
set_bgcol(scin, options);
update_bg(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "bggradh") == 0 ) {
maybe_recurse_before(scin, child);
set_bggrad(scin, options, GRAD_HORIZ);
update_bg(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "bggradv") == 0 ) {
maybe_recurse_before(scin, child);
set_bggrad(scin, options, GRAD_VERT);
update_bg(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "paraspace") == 0 ) {
maybe_recurse_before(scin, child);
set_paraspace(scin, options);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else {
@@ -1358,252 +1164,3 @@ int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl)
return 0;
}
-
-int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl)
-{
- while ( bl != NULL ) {
- if ( sc_interp_add_block(scin, bl) ) return 1;
- bl = sc_block_next(bl);
- }
-
- return 0;
-}
-
-
-static int try_add_style(SCInterpreter *scin, const char *options, SCBlock *bl)
-{
- struct sc_state *st = &scin->state[scin->j];
- char *nn;
- char *comma;
- int i;
-
- nn = strdup(options);
- comma = strchr(nn, ',');
- if ( comma != NULL ) {
- comma[0] = '\0';
- }
-
- for ( i=0; i<st->n_styles; i++ ) {
- if ( strcmp(st->styles[i].name, nn) == 0 ) {
- st->styles[i].name = nn;
- st->styles[i].bl = bl;
- st->styles[i].prev = NULL; /* FIXME: Stacking */
- return 0;
- }
- }
-
- if ( st->max_styles == st->n_styles ) {
-
- struct macro *styles_new;
-
- styles_new = realloc(st->styles, sizeof(struct macro)
- * (st->max_styles+16));
- if ( styles_new == NULL ) {
- fprintf(stderr, _("Failed to add style.\n"));
- return 1;
- }
-
- st->styles = styles_new;
- st->max_styles += 16;
-
- }
-
- i = st->n_styles++;
-
- st->styles[i].name = nn;
- st->styles[i].bl = bl;
- st->styles[i].prev = NULL; /* FIXME: Stacking */
-
- return 0;
-}
-
-
-static int try_add_macro(SCInterpreter *scin, const char *options, SCBlock *bl)
-{
- struct sc_state *st = &scin->state[scin->j];
- char *nn;
- char *comma;
- int i;
-
- nn = strdup(options);
- comma = strchr(nn, ',');
- if ( comma != NULL ) {
- comma[0] = '\0';
- }
-
- for ( i=0; i<st->n_macros; i++ ) {
- if ( strcmp(st->macros[i].name, nn) == 0 ) {
- st->macros[i].name = nn;
- st->macros[i].bl = bl;
- st->macros[i].prev = NULL; /* FIXME: Stacking */
- return 0;
- }
- }
-
- if ( st->max_macros == st->n_macros ) {
-
- struct macro *macros_new;
-
- macros_new = realloc(st->macros, sizeof(struct macro)
- * (st->max_macros+16));
- if ( macros_new == NULL ) {
- fprintf(stderr, _("Failed to add macro.\n"));
- return 1;
- }
-
- st->macros = macros_new;
- st->max_macros += 16;
-
- }
-
- i = st->n_macros++;
-
- st->macros[i].name = nn;
- st->macros[i].bl = bl;
- st->macros[i].prev = NULL; /* FIXME: Stacking */
-
- return 0;
-}
-
-
-static int try_add_template(SCInterpreter *scin, const char *options, SCBlock *bl)
-{
- struct sc_state *st = &scin->state[scin->j];
- char *nn;
- char *comma;
- int i;
-
- nn = strdup(options);
- comma = strchr(nn, ',');
- if ( comma != NULL ) {
- comma[0] = '\0';
- }
-
- for ( i=0; i<st->n_templates; i++ ) {
- if ( strcmp(st->templates[i].name, nn) == 0 ) {
- fprintf(stderr, _("Duplicate template '%s'\n"), nn);
- return 0;
- }
- }
-
- if ( st->max_templates == st->n_templates ) {
-
- struct template *templates_new;
-
- templates_new = realloc(st->templates, sizeof(struct template)
- * (st->max_templates+16));
- if ( templates_new == NULL ) {
- fprintf(stderr, _("Failed to add templates\n"));
- return 1;
- }
-
- st->templates = templates_new;
- st->max_templates += 16;
-
- }
-
- i = st->n_templates++;
-
- st->templates[i].name = nn;
- st->templates[i].bl = bl;
-
- return 0;
-}
-
-void add_macro(SCInterpreter *scin, const char *mname, const char *contents)
-{
- SCBlock *bl = sc_parse(contents);
- try_add_macro(scin, mname, bl);
-}
-
-
-void sc_interp_run_stylesheet(SCInterpreter *scin, SCBlock *bl)
-{
- if ( bl == NULL ) return;
-
- if ( strcmp(sc_block_name(bl), "stylesheet") != 0 ) {
- fprintf(stderr, _("Style sheet isn't a style sheet.\n"));
- return;
- }
-
- bl = sc_block_child(bl);
-
- while ( bl != NULL ) {
-
- const char *name = sc_block_name(bl);
- const char *options = sc_block_options(bl);
-
- if ( name == NULL ) {
-
- /* Do nothing */
-
- } else if ( strcmp(name, "def") == 0 ) {
- try_add_macro(scin, options, sc_block_child(bl));
-
- } else if ( strcmp(name, "ss") == 0 ) { /* Backward compatibility */
- try_add_macro(scin, options, sc_block_child(bl));
-
- } else if ( strcmp(name, "style") == 0 ) {
- try_add_style(scin, options, sc_block_child(bl));
-
- } else if ( strcmp(name, "template") == 0 ) {
- try_add_template(scin, options, sc_block_child(bl));
-
- } else if ( strcmp(name, "font") == 0 ) {
- set_font(scin, options);
-
- } else if ( strcmp(name, "fgcol") == 0 ) {
- set_colour(scin, options);
-
- } else if ( strcmp(name, "bgcol") == 0 ) {
- set_bgcol(scin, options);
- update_bg(scin);
-
- } else if ( strcmp(name, "bggradh") == 0 ) {
- set_bggrad(scin, options, GRAD_HORIZ);
- update_bg(scin);
-
- } else if ( strcmp(name, "bggradv") == 0 ) {
- set_bggrad(scin, options, GRAD_VERT);
- update_bg(scin);
-
- } else if ( strcmp(name, "paraspace") == 0 ) {
- set_paraspace(scin, options);
-
- } else if ( strcmp(name, "slidesize") == 0 ) {
- set_slide_size(scin, options);
-
- }
-
- bl = sc_block_next(bl);
-
- }
-}
-
-
-int sc_interp_get_slide_size(SCInterpreter *scin, double *w, double *h)
-{
- if ( !scin->state->have_size ) return 1;
- *w = scin->state->slide_width;
- *h = scin->state->slide_height;
- return 0;
-}
-
-
-struct template_id *sc_interp_get_templates(SCInterpreter *scin, int *np)
-{
- struct template_id *list;
- int i;
-
- list = malloc(sizeof(struct template_id)*scin->state->n_templates);
- if ( list == NULL ) return NULL;
-
- for ( i=0; i<scin->state->n_templates; i++ ) {
- list[i].name = strdup(scin->state->templates[i].name);
- list[i].friendlyname = strdup(scin->state->templates[i].name);
- list[i].scblock = sc_block_copy(scin->state->templates[i].bl);
- }
-
- *np = scin->state->n_templates;
- return list;
-}
diff --git a/src/sc_interp.h b/src/sc_interp.h
index 7b00aaa..418d6a6 100644
--- a/src/sc_interp.h
+++ b/src/sc_interp.h
@@ -41,6 +41,7 @@ typedef int (*SCCallbackClickFunc)(double x, double y, void *, void *);
#include "frame.h"
#include "imagestore.h"
+#include "stylesheet.h"
extern SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang,
ImageStore *is, struct frame *top);
@@ -49,13 +50,7 @@ extern void sc_interp_destroy(SCInterpreter *scin);
extern void sc_interp_save(SCInterpreter *scin);
extern void sc_interp_restore(SCInterpreter *scin);
-extern int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl);
-extern int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl);
-
-extern void sc_interp_run_stylesheet(SCInterpreter *scin, SCBlock *bl);
-extern void sc_interp_run_style(SCInterpreter *scin, const char *sname);
-extern void add_macro(SCInterpreter *scin, const char *mname,
- const char *contents);
+extern int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss);
/* Callback lists */
@@ -73,28 +68,8 @@ extern struct frame *sc_interp_get_frame(SCInterpreter *scin);
extern PangoFont *sc_interp_get_font(SCInterpreter *scin);
extern PangoFontDescription *sc_interp_get_fontdesc(SCInterpreter *scin);
extern double *sc_interp_get_fgcol(SCInterpreter *scin);
-extern double *sc_interp_get_bgcol(SCInterpreter *scin);
-extern double *sc_interp_get_bgcol2(SCInterpreter *scin);
-extern GradientType sc_interp_get_bggrad(SCInterpreter *scin);
-
-extern int sc_interp_get_slide_size(SCInterpreter *scin, double *w, double *h);
-extern SCBlock *sc_interp_get_macro_real_block(SCInterpreter *scin);
-
-extern int sc_interp_get_ascent(SCInterpreter *scin);
-extern int sc_interp_get_height(SCInterpreter *scin);
extern void update_geom(struct frame *fr);
-struct template_id
-{
- char *name;
- char *friendlyname;
- SCBlock *scblock;
-};
-
-extern struct template_id *sc_interp_get_templates(SCInterpreter *scin,
- int *np);
-
-
#endif /* SC_INTERP_H */
diff --git a/src/sc_parse.c b/src/sc_parse.c
index b66dc1f..e8904a0 100644
--- a/src/sc_parse.c
+++ b/src/sc_parse.c
@@ -264,26 +264,8 @@ static SCBlock *sc_find_parent(SCBlock *top, SCBlock *find)
}
-void sc_block_substitute(SCBlock **top, SCBlock *old, SCBlock *new)
-{
- if ( old == NULL ) {
- fprintf(stderr, _("Substituting nothing!\n"));
- return;
- }
-
- if ( old == *top ) {
- /* It is the first block */
- new->next = old->next;
- *top = new;
- } else {
- sc_block_unlink(top, old);
- sc_block_append_p(*top, new);
- }
-}
-
-
/* Unlink "deleteme", which is somewhere under "top" */
-int sc_block_unlink(SCBlock **top, SCBlock *deleteme)
+static int sc_block_unlink(SCBlock **top, SCBlock *deleteme)
{
SCBlock *parent = sc_find_parent(*top, deleteme);
if ( parent == NULL ) {
@@ -413,36 +395,6 @@ char *serialise_sc_block(const SCBlock *bl)
}
-/* Serialise an entire chain of blocks */
-char *serialise_sc_block_chain(const SCBlock *bl)
-{
- char *a = strdup("");
- size_t len = 1;
-
- if ( a == NULL ) return NULL;
-
- while ( bl != NULL ) {
-
- char *c = serialise_sc_block(bl);
- if ( c == NULL ) {
- free(a);
- return NULL;
- }
-
- len += strlen(c);
- a = realloc(a, len);
- if ( a == NULL ) return NULL;
- strcat(a, c);
- free(c);
-
- bl = bl->next;
-
- }
-
- return a;
-}
-
-
int save_sc_block(GOutputStream *fh, const SCBlock *bl)
{
while ( bl != NULL ) {
@@ -770,17 +722,6 @@ void sc_block_set_contents(SCBlock *bl, char *con)
}
-SCBlock *find_last_child(SCBlock *bl)
-{
- if ( bl == NULL ) return NULL;
- if ( bl->child == NULL ) return NULL;
-
- bl = bl->child;
- while ( bl->next != NULL ) bl = bl->next;
- return bl;
-}
-
-
void sc_insert_text(SCBlock *b1, size_t o1, const char *t)
{
if ( b1->contents == NULL ) {
@@ -850,37 +791,6 @@ size_t scblock_delete_text(SCBlock *b, ssize_t o1, ssize_t o2)
}
-/* Create a deep copy of "bl", including all its children */
-SCBlock *sc_block_copy(const SCBlock *bl)
-{
- SCBlock *copy;
- SCBlock *first_copy;
-
- first_copy = sc_block_new();
-
- copy = first_copy;
- do {
-
- if ( bl->name != NULL ) copy->name = strdup(bl->name);
- if ( bl->options != NULL ) copy->options = strdup(bl->options);
- if ( bl->contents != NULL ) copy->contents = strdup(bl->contents);
- if ( bl->child != NULL ) copy->child = sc_block_copy(bl->child);
-
- bl = bl->next;
-
- if ( bl != NULL ) {
- SCBlock *nn;
- nn = sc_block_new();
- copy->next = nn;
- copy = nn;
- }
-
- } while ( bl != NULL );
-
- return first_copy;
-}
-
-
static char *s_strdup(const char *a)
{
if ( a == NULL ) return NULL;
diff --git a/src/sc_parse.h b/src/sc_parse.h
index 9277ee6..17ce2dd 100644
--- a/src/sc_parse.h
+++ b/src/sc_parse.h
@@ -37,14 +37,11 @@ extern SCBlock *sc_parse(const char *sc);
extern SCBlock *sc_block_new(void);
extern void sc_block_free(SCBlock *bl);
-extern SCBlock *sc_block_copy(const SCBlock *bl);
-
extern SCBlock *sc_block_next(const SCBlock *bl);
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,
@@ -68,9 +65,6 @@ extern SCBlock *sc_block_insert_after(SCBlock *afterme,
char *name, char *opt, char *contents);
extern int sc_block_delete(SCBlock **top, SCBlock *deleteme);
-extern int sc_block_unlink(SCBlock **top, SCBlock *deleteme);
-
-extern SCBlock *find_last_child(SCBlock *bl);
extern void sc_block_set_name(SCBlock *bl, char *nam);
@@ -84,7 +78,6 @@ 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 char *serialise_sc_block_chain(const SCBlock *bl);
extern int save_sc_block(GOutputStream *fh, const SCBlock *bl);
extern size_t scblock_delete_text(SCBlock *b, ssize_t o1, ssize_t o2);
diff --git a/src/slide_window.c b/src/slide_window.c
index b010d1b..e23a3d7 100644
--- a/src/slide_window.c
+++ b/src/slide_window.c
@@ -109,7 +109,7 @@ static void delete_frame_sig(GSimpleAction *action, GVariant *parameter,
/* Change the editor's slide to "np" */
-void change_edit_slide(SlideWindow *sw, SCBlock *np)
+static void change_edit_slide(SlideWindow *sw, SCBlock *np)
{
sc_editor_set_slidenum(sw->sceditor, slide_number(sw->p, np));
diff --git a/src/slide_window.h b/src/slide_window.h
index 77de920..b1d39a8 100644
--- a/src/slide_window.h
+++ b/src/slide_window.h
@@ -31,6 +31,5 @@ typedef struct _slidewindow SlideWindow;
extern SlideWindow *slide_window_open(struct presentation *p, SCBlock *scblocks,
GApplication *app);
-extern void change_edit_slide(SlideWindow *sw, SCBlock *np);
#endif /* SLIDEWINDOW_H */
diff --git a/src/stylesheet.c b/src/stylesheet.c
new file mode 100644
index 0000000..96172a4
--- /dev/null
+++ b/src/stylesheet.c
@@ -0,0 +1,234 @@
+/*
+ * stylesheet.c
+ *
+ * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
+ *
+ * This file is part of Colloquium.
+ *
+ * Colloquium is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <json-glib/json-glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <gio/gio.h>
+#include <gdk/gdk.h>
+
+#include "stylesheet.h"
+#include "utils.h"
+
+
+struct _stylesheet {
+ JsonNode *root;
+};
+
+
+static int find_comma(const char *a)
+{
+ int i = 0;
+ int in_brackets = 0;
+ size_t len = strlen(a);
+
+ do {
+ if ( (a[i] == ',') && !in_brackets ) return i;
+ if ( a[i] == '(' ) in_brackets++;
+ if ( a[i] == ')' ) in_brackets--;
+ i++;
+ } while ( i < len );
+ return 0;
+}
+
+
+int parse_colour_duo(const char *a, GdkRGBA *col1, GdkRGBA *col2)
+{
+ char *acopy;
+ int cpos;
+
+ acopy = strdup(a);
+ if ( acopy == NULL ) return 1;
+
+ cpos = find_comma(acopy);
+ if ( cpos == 0 ) {
+ fprintf(stderr, _("Invalid bg gradient spec '%s'\n"), a);
+ return 1;
+ }
+
+ acopy[cpos] = '\0';
+
+ if ( gdk_rgba_parse(col1, acopy) != TRUE ) {
+ fprintf(stderr, _("Failed to parse colour: %s\n"), acopy);
+ }
+ if ( gdk_rgba_parse(col2, &acopy[cpos+1]) != TRUE ) {
+ fprintf(stderr, _("Failed to parse colour: %s\n"), &acopy[cpos+1]);
+ }
+
+ free(acopy);
+ return 0;
+}
+
+
+Stylesheet *stylesheet_load(GFile *file)
+{
+ JsonParser *parser;
+ gboolean r;
+ GError *err = NULL;
+ Stylesheet *ss;
+ char *everything;
+ gsize len;
+
+ printf("Trying stylesheet '%s'\n", g_file_get_uri(file));
+
+ ss = calloc(1, sizeof(Stylesheet));
+ if ( ss == NULL ) return NULL;
+
+ parser = json_parser_new();
+
+ if ( !g_file_load_contents(file, NULL, &everything, &len, NULL, NULL) ) {
+ fprintf(stderr, _("Failed to load stylesheet '%s'\n"),
+ g_file_get_uri(file));
+ return NULL;
+ }
+
+ r = json_parser_load_from_data(parser, everything, len, &err);
+ if ( r == FALSE ) {
+ fprintf(stderr, "Failed to load style sheet: '%s'\n", err->message);
+ return NULL;
+ }
+
+ ss->root = json_parser_steal_root(parser);
+ g_object_unref(parser);
+
+ return ss;
+}
+
+
+static JsonObject *find_stylesheet_object(Stylesheet *ss, const char *path,
+ JsonNode **freeme)
+{
+ JsonNode *node;
+ JsonObject *obj;
+ JsonArray *array;
+ GError *err = NULL;
+
+ node = json_path_query(path, ss->root, &err);
+ array = json_node_get_array(node);
+
+ if ( json_array_get_length(array) != 1 ) {
+ json_node_unref(node);
+ fprintf(stderr, "More than one result in SS lookup (%s)!\n", path);
+ return NULL;
+ }
+
+ obj = json_array_get_object_element(array, 0);
+ if ( obj == NULL ) {
+ printf("%s not a JSON object\n", path);
+ json_node_unref(node);
+ return NULL;
+ }
+
+ *freeme = node;
+ return obj;
+}
+
+
+char *stylesheet_lookup(Stylesheet *ss, const char *path, const char *key)
+{
+ JsonObject *obj;
+ char *ret = NULL;
+ JsonNode *node = NULL;
+
+ if ( ss == NULL ) {
+ fprintf(stderr, _("No stylesheet!\n"));
+ return NULL;
+ }
+
+ obj = find_stylesheet_object(ss, path, &node);
+
+ if ( json_object_has_member(obj, key) ) {
+
+ const gchar *v;
+ v = json_object_get_string_member(obj, key);
+ if ( v != NULL ) {
+ ret = strdup(v);
+ } else {
+ fprintf(stderr, "Error retrieving %s.%s\n", path, key);
+ }
+
+ } /* else not found, too bad */
+
+ if ( node != NULL ) json_node_unref(node);
+ return ret;
+}
+
+
+int stylesheet_set(Stylesheet *ss, const char *path, const char *key,
+ const char *new_val)
+{
+ JsonObject *obj;
+ JsonNode *node = NULL;
+ int r = 1;
+
+ if ( ss == NULL ) {
+ fprintf(stderr, _("No stylesheet!\n"));
+ return 1;
+ }
+
+ obj = find_stylesheet_object(ss, path, &node);
+ if ( obj != NULL ) {
+ json_object_set_string_member(obj, key, new_val);
+ r = 0;
+ } /* else most likely the object (e.g. "$.slide", "$.slide.frame",
+ * "$.narrative" etc doesn't exist */
+
+ if ( node != NULL ) json_node_unref(node);
+ return r;
+}
+
+
+int stylesheet_delete(Stylesheet *ss, const char *path, const char *key)
+{
+ JsonObject *obj;
+ JsonNode *node = NULL;
+ int r = 1;
+
+ if ( ss == NULL ) {
+ fprintf(stderr, _("No stylesheet!\n"));
+ return 1;
+ }
+
+ obj = find_stylesheet_object(ss, path, &node);
+ if ( obj != NULL ) {
+ json_object_remove_member(obj, key);
+ r = 0;
+ } /* else most likely the object (e.g. "$.slide", "$.slide.frame",
+ * "$.narrative" etc doesn't exist */
+
+ if ( node != NULL ) json_node_unref(node);
+ return r;
+}
+
+
+void stylesheet_free(Stylesheet *ss)
+{
+ g_object_unref(ss->root);
+ free(ss);
+}
+
diff --git a/src/stylesheet.h b/src/stylesheet.h
new file mode 100644
index 0000000..c24c62c
--- /dev/null
+++ b/src/stylesheet.h
@@ -0,0 +1,48 @@
+/*
+ * stylesheet.h
+ *
+ * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
+ *
+ * This file is part of Colloquium.
+ *
+ * Colloquium is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef STYLESHEET_H
+#define STYLESHEET_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+#include <gdk/gdk.h>
+
+typedef struct _stylesheet Stylesheet;
+
+extern Stylesheet *stylesheet_load(GFile *file);
+
+extern int parse_colour_duo(const char *a, GdkRGBA *col1, GdkRGBA *col2);
+
+extern char *stylesheet_lookup(Stylesheet *ss, const char *path, const char *key);
+
+extern int stylesheet_set(Stylesheet *ss, const char *path, const char *key,
+ const char *new_val);
+
+extern int stylesheet_delete(Stylesheet *ss, const char *path, const char *key);
+
+extern void stylesheet_free(Stylesheet *ss);
+
+#endif /* STYLESHEET_H */
diff --git a/src/stylesheet_editor.c b/src/stylesheet_editor.c
index 66e8afa..8100472 100644
--- a/src/stylesheet_editor.c
+++ b/src/stylesheet_editor.c
@@ -33,12 +33,13 @@
#include "stylesheet_editor.h"
#include "presentation.h"
#include "sc_interp.h"
+#include "stylesheet.h"
+#include "utils.h"
G_DEFINE_TYPE_WITH_CODE(StylesheetEditor, stylesheet_editor,
GTK_TYPE_DIALOG, NULL)
-static void set_values_from_presentation(StylesheetEditor *se);
struct _sspriv
{
@@ -46,175 +47,247 @@ struct _sspriv
};
-static SCBlock *find_block(SCBlock *bl, const char *find)
+static void set_font_from_ss(Stylesheet *ss, const char *path, GtkWidget *w)
{
- while ( bl != NULL ) {
-
- const char *name = sc_block_name(bl);
- if ( (name != NULL) && (strcmp(name, find)==0) ) {
- return bl;
- }
-
- bl = sc_block_next(bl);
-
+ char *result = stylesheet_lookup(ss, path, "font");
+ if ( result != NULL ) {
+ gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), result);
}
-
- return NULL;
}
-static void find_replace(SCBlock *parent, const char *find, const char *seti)
+static void set_col_from_ss(Stylesheet *ss, const char *path, GtkWidget *w)
{
- SCBlock *bl = find_block(sc_block_child(parent), find);
-
- if ( bl != NULL ) {
+ char *result = stylesheet_lookup(ss, path, "fgcol");
+ if ( result != NULL ) {
+ GdkRGBA rgba;
+ if ( gdk_rgba_parse(&rgba, result) == TRUE ) {
+ gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(w), &rgba);
+ }
+ }
+}
- printf("replacing '%s' with '%s'\n", sc_block_options(bl), seti);
- sc_block_set_options(bl, strdup(seti));
+static void set_vals_from_ss(Stylesheet *ss, const char *path, const char *key,
+ GtkWidget *wl, GtkWidget *wr,
+ GtkWidget *wt, GtkWidget *wb)
+{
+ char *result = stylesheet_lookup(ss, path, key);
+ if ( result != NULL ) {
+ float v[4];
+ if ( parse_tuple(result, v) == 0 ) {
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(wl), v[0]);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(wr), v[1]);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(wt), v[2]);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(wb), v[3]);
+ } else {
+ fprintf(stderr, _("Failed to parse quad: %s\n"), result);
+ }
} else {
-
- /* Block not found -> create it */
- sc_block_append_inside(parent, strdup(find), strdup(seti), NULL);
-
+ printf("Not found %s\n", path);
}
}
-static SCBlock *find_or_create_style(struct presentation *p, const char *style_name)
+static void set_size_from_ss(Stylesheet *ss, const char *path,
+ GtkWidget *ww, GtkWidget *wh)
{
- SCBlock *bl;
- const char *name;
-
- /* If no stylesheet yet, create one now */
- if ( p->stylesheet == NULL ) {
- p->stylesheet = sc_parse("\\stylesheet");
- if ( p->stylesheet == NULL ) {
- fprintf(stderr, "WARNING: Couldn't create stylesheet\n");
- return NULL;
+ char *result = stylesheet_lookup(ss, path, "size");
+ if ( result != NULL ) {
+ float v[2];
+ if ( parse_double(result, v) == 0 ) {
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(ww), v[0]);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(wh), v[1]);
+ } else {
+ fprintf(stderr, _("Failed to parse double: %s\n"), result);
}
- sc_block_append_p(p->stylesheet, p->scblocks);
- p->scblocks = p->stylesheet;
+ } else {
+ printf("Not found %s\n", path);
}
- bl = p->stylesheet;
+}
- name = sc_block_name(bl);
- if ( (name != NULL) && (strcmp(name, "stylesheet")==0) ) {
- bl = sc_block_child(bl);
+static void set_bg_from_ss(Stylesheet *ss, const char *path, GtkWidget *wcol,
+ GtkWidget *wcol2, GtkWidget *wgrad)
+{
+ char *result;
+ int found = 0;
+
+ result = stylesheet_lookup(ss, path, "bgcol");
+ if ( result != NULL ) {
+ GdkRGBA rgba;
+ found = 1;
+ if ( gdk_rgba_parse(&rgba, result) == TRUE ) {
+ gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba);
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "flat");
+ gtk_widget_set_sensitive(wcol, TRUE);
+ gtk_widget_set_sensitive(wcol2, FALSE);
+ } else {
+ fprintf(stderr, _("Failed to parse colour: %s\n"), result);
+ }
}
- while ( bl != NULL ) {
-
- const char *name = sc_block_name(bl);
- const char *options = sc_block_options(bl);
- if ( (name != NULL) && (strcmp(name, "style")==0)
- && (strcmp(options, style_name)==0) )
- {
- return bl;
+ result = stylesheet_lookup(ss, path, "bggradv");
+ if ( result != NULL ) {
+ GdkRGBA rgba1, rgba2;
+ found = 1;
+ if ( parse_colour_duo(result, &rgba1, &rgba2) == 0 ) {
+ gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba1);
+ gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol2), &rgba2);
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "vert");
+ gtk_widget_set_sensitive(wcol, TRUE);
+ gtk_widget_set_sensitive(wcol2, TRUE);
}
+ }
- bl = sc_block_next(bl);
+ result = stylesheet_lookup(ss, path, "bggradh");
+ if ( result != NULL ) {
+ GdkRGBA rgba1, rgba2;
+ found = 1;
+ if ( parse_colour_duo(result, &rgba1, &rgba2) == 0 ) {
+ gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba1);
+ gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol2), &rgba2);
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "horiz");
+ gtk_widget_set_sensitive(wcol, TRUE);
+ gtk_widget_set_sensitive(wcol2, TRUE);
+ }
+ }
+ if ( !found ) {
+ GdkRGBA rgba;
+ rgba.red = 1.0;
+ rgba.green = 1.0;
+ rgba.blue = 1.0;
+ rgba.alpha = 0.0;
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "flat");
+ gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba);
+ gtk_widget_set_sensitive(wcol, TRUE);
+ gtk_widget_set_sensitive(wcol2, FALSE);
}
+}
- /* Not found -> add style */
- return sc_block_append_inside(p->stylesheet, strdup("style"),
- strdup(style_name), NULL);
+
+static void set_values_from_presentation(StylesheetEditor *se)
+{
+ Stylesheet *ss = se->priv->p->stylesheet;
+
+ /* Narrative */
+ set_font_from_ss(ss, "$.narrative", se->narrative_style_font);
+ set_col_from_ss(ss, "$.narrative", se->narrative_style_fgcol);
+ set_bg_from_ss(ss, "$.narrative", se->narrative_style_bgcol,
+ se->narrative_style_bgcol2,
+ se->narrative_style_bggrad);
+ set_vals_from_ss(ss, "$.narrative", "pad", se->narrative_style_padding_l,
+ se->narrative_style_padding_r,
+ se->narrative_style_padding_t,
+ se->narrative_style_padding_b);
+ set_vals_from_ss(ss, "$.narrative", "paraspace", se->narrative_style_paraspace_l,
+ se->narrative_style_paraspace_r,
+ se->narrative_style_paraspace_t,
+ se->narrative_style_paraspace_b);
+
+ /* Slides */
+ set_size_from_ss(ss, "$.slide", se->slide_size_w, se->slide_size_h);
+ set_bg_from_ss(ss, "$.slide", se->slide_style_bgcol,
+ se->slide_style_bgcol2,
+ se->slide_style_bggrad);
+
+
+ /* Frames */
+ set_font_from_ss(ss, "$.slide.frame", se->frame_style_font);
+ set_col_from_ss(ss, "$.slide.frame", se->frame_style_fgcol);
+ set_bg_from_ss(ss, "$.slide.frame", se->frame_style_bgcol,
+ se->frame_style_bgcol2,
+ se->frame_style_bggrad);
+ set_vals_from_ss(ss, "$.slide.frame", "pad", se->frame_style_padding_l,
+ se->frame_style_padding_r,
+ se->frame_style_padding_t,
+ se->frame_style_padding_b);
+ set_vals_from_ss(ss, "$.slide.frame", "paraspace", se->frame_style_paraspace_l,
+ se->frame_style_paraspace_r,
+ se->frame_style_paraspace_t,
+ se->frame_style_paraspace_b);
}
-static void set_ss(struct presentation *p, const char *style_name,
- const char *find, const char *seti)
+static GradientType id_to_gradtype(const gchar *id)
{
- SCBlock *bl = find_or_create_style(p, style_name);
- if ( bl == NULL ) {
- fprintf(stderr, "WARNING: Couldn't find style\n");
- return;
- }
- find_replace(bl, find, seti);
+ assert(id != NULL);
+ if ( strcmp(id, "flat") == 0 ) return GRAD_NONE;
+ if ( strcmp(id, "horiz") == 0 ) return GRAD_HORIZ;
+ if ( strcmp(id, "vert") == 0 ) return GRAD_VERT;
+ return GRAD_NONE;
}
-static void set_ss_bg_block(SCBlock *bl, GradientType bggrad,
- GdkRGBA col1, GdkRGBA col2)
+static void update_bg(struct presentation *p, const char *style_name,
+ GtkWidget *bggradw, GtkWidget *col1w, GtkWidget*col2w)
{
- char tmp[64];
+ GradientType g;
+ const gchar *id;
+ GdkRGBA rgba;
+ gchar *col1;
+ gchar *col2;
+ gchar *gradient;
- switch ( bggrad ) {
+ id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(bggradw));
+ g = id_to_gradtype(id);
- case GRAD_NONE :
- sc_block_set_name(bl, strdup("bgcol"));
- snprintf(tmp, 63, "#%.2x%.2x%.2x",
- (int)(col1.red*255), (int)(col1.green*255), (int)(col1.blue*255));
- sc_block_set_options(bl, strdup(tmp));
- break;
+ gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(col1w), &rgba);
+ if ( rgba.alpha < 0.000001 ) rgba.alpha = 0.0;
+ col1 = gdk_rgba_to_string(&rgba);
- case GRAD_VERT :
- sc_block_set_name(bl, strdup("bggradv"));
- snprintf(tmp, 63, "#%.2x%.2x%.2x,#%.2x%.2x%.2x",
- (int)(col1.red*255), (int)(col1.green*255), (int)(col1.blue*255),
- (int)(col2.red*255), (int)(col2.green*255), (int)(col2.blue*255));
- sc_block_set_options(bl, strdup(tmp));
+ gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(col2w), &rgba);
+ col2 = gdk_rgba_to_string(&rgba);
+
+ gradient = g_strconcat(col1, ",", col2, NULL);
+
+ switch ( g ) {
+
+ case GRAD_NONE :
+ stylesheet_set(p->stylesheet, style_name, "bgcol",
+ col1);
+ stylesheet_delete(p->stylesheet, style_name, "bggradv");
+ stylesheet_delete(p->stylesheet, style_name, "bggradh");
break;
case GRAD_HORIZ :
- sc_block_set_name(bl, strdup("bggradh"));
- snprintf(tmp, 63, "#%.2x%.2x%.2x,#%.2x%.2x%.2x",
- (int)(col1.red*255), (int)(col1.green*255), (int)(col1.blue*255),
- (int)(col2.red*255), (int)(col2.green*255), (int)(col2.blue*255));
- sc_block_set_options(bl, strdup(tmp));
+ stylesheet_set(p->stylesheet, style_name, "bggradh",
+ gradient);
+ stylesheet_delete(p->stylesheet, style_name, "bggradv");
+ stylesheet_delete(p->stylesheet, style_name, "bgcol");
break;
- case GRAD_NOBG :
- printf("no bg\n");
- sc_block_set_name(bl, NULL);
- sc_block_set_options(bl, NULL);
- sc_block_set_contents(bl, NULL);
+ case GRAD_VERT :
+ stylesheet_set(p->stylesheet, style_name, "bggradv",
+ gradient);
+ stylesheet_delete(p->stylesheet, style_name, "bggradh");
+ stylesheet_delete(p->stylesheet, style_name, "bgcol");
break;
}
-}
-
-
-static int try_set_block(SCBlock **parent, const char *name,
- GradientType bggrad, GdkRGBA col1, GdkRGBA col2)
-{
- SCBlock *ibl;
-
- ibl = find_block(sc_block_child(*parent), name);
- if ( ibl != NULL ) {
- if ( bggrad != GRAD_NOBG ) {
- set_ss_bg_block(ibl, bggrad, col1, col2);
- return 1;
- } else {
- sc_block_delete(parent, ibl);
- return 1;
- }
- }
- return 0;
+ g_free(gradient);
+ g_free(col1);
+ g_free(col2);
}
-static void update_bg(struct presentation *p, const char *style_name,
- GradientType bggrad, GdkRGBA col1, GdkRGBA col2)
+static void update_spacing(struct presentation *p, const char *style_name,
+ const char *key, GtkWidget *wl, GtkWidget *wr,
+ GtkWidget *wt, GtkWidget *wb)
{
- int done;
- SCBlock *bl;
+ int v[4];
+ char tmp[256];
- bl = find_or_create_style(p, style_name);
- if ( bl == NULL ) {
- fprintf(stderr, "WARNING: Couldn't find style\n");
- return;
- }
+ v[0] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wl));
+ v[1] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wr));
+ v[2] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wt));
+ v[3] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wb));
- /* FIXME: What if there are two of these? */
- done = try_set_block(&bl, "bgcol", bggrad, col1, col2);
- if ( !done ) done = try_set_block(&bl, "bggradv", bggrad, col1, col2);
- if ( !done ) done = try_set_block(&bl, "bggradh", bggrad, col1, col2);
- if ( !done && bggrad != GRAD_NOBG ) {
- SCBlock *ibl = sc_block_append_inside(bl, NULL, NULL, NULL);
- set_ss_bg_block(ibl, bggrad, col1, col2);
+ if ( snprintf(tmp, 256, "%i,%i,%i,%i", v[0], v[1], v[2], v[3]) >= 256 ) {
+ fprintf(stderr, _("Spacing too long\n"));
+ } else {
+ stylesheet_set(p->stylesheet, style_name, key, tmp);
}
}
@@ -225,23 +298,13 @@ static void revert_sig(GtkButton *button, StylesheetEditor *widget)
}
-static GradientType id_to_gradtype(const gchar *id)
-{
- assert(id != NULL);
- if ( strcmp(id, "flat") == 0 ) return GRAD_NONE;
- if ( strcmp(id, "horiz") == 0 ) return GRAD_HORIZ;
- if ( strcmp(id, "vert") == 0 ) return GRAD_VERT;
- if ( strcmp(id, "none") == 0 ) return GRAD_NOBG;
- return GRAD_NONE;
-}
-
-
static void set_font(GtkFontButton *widget, StylesheetEditor *se,
const char *style_name)
{
const gchar *font;
font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget));
- set_ss(se->priv->p, style_name, "font", font);
+
+ stylesheet_set(se->priv->p->stylesheet, style_name, "font", font);
set_values_from_presentation(se);
g_signal_emit_by_name(se, "changed");
}
@@ -254,7 +317,7 @@ static void set_col(GtkColorButton *widget, StylesheetEditor *se,
gchar *col;
gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), &rgba);
col = gdk_rgba_to_string(&rgba);
- set_ss(se->priv->p, style_name, col_name, col);
+ stylesheet_set(se->priv->p->stylesheet, style_name, "fgcol", col);
g_free(col);
set_values_from_presentation(se);
g_signal_emit_by_name(se, "changed");
@@ -263,135 +326,125 @@ static void set_col(GtkColorButton *widget, StylesheetEditor *se,
static void narrative_font_sig(GtkFontButton *widget, StylesheetEditor *se)
{
- set_font(widget, se, "narrative");
+ set_font(widget, se, "$.narrative");
}
static void narrative_fgcol_sig(GtkColorButton *widget, StylesheetEditor *se)
{
- set_col(widget, se, "narrative", "fgcol");
+ set_col(widget, se, "$.narrative", "fgcol");
}
-static void narrative_bgcol_sig(GtkColorButton *widget, StylesheetEditor *se)
+static void narrative_bg_sig(GtkColorButton *widget, StylesheetEditor *se)
{
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget),
- &se->narrative_bgcol);
- update_bg(se->priv->p, "narrative", se->narrative_bggrad,
- se->narrative_bgcol, se->narrative_bgcol2);
-
+ update_bg(se->priv->p, "$.narrative",
+ se->narrative_style_bggrad,
+ se->narrative_style_bgcol,
+ se->narrative_style_bgcol2);
set_values_from_presentation(se);
g_signal_emit_by_name(se, "changed");
}
-static void narrative_bgcol2_sig(GtkColorButton *widget, StylesheetEditor *se)
+static void slide_size_sig(GtkSpinButton *widget, StylesheetEditor *se)
{
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget),
- &se->narrative_bgcol2);
- update_bg(se->priv->p, "narrative", se->narrative_bggrad,
- se->narrative_bgcol, se->narrative_bgcol2);
-
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
+ int w, h;
+ char tmp[256];
+ w = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(se->slide_size_w));
+ h = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(se->slide_size_h));
-static void narrative_bggrad_sig(GtkComboBox *widget, StylesheetEditor *se)
-{
- const gchar *id;
- id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget));
- se->narrative_bggrad = id_to_gradtype(id);
- update_bg(se->priv->p, "narrative", se->narrative_bggrad,
- se->narrative_bgcol, se->narrative_bgcol2);
+ if ( snprintf(tmp, 256, "%ix%i", w, h) >= 256 ) {
+ fprintf(stderr, _("Slide size too long\n"));
+ } else {
+ stylesheet_set(se->priv->p->stylesheet, "$.slide", "size", tmp);
+ se->priv->p->slide_width = w;
+ se->priv->p->slide_height = h;
+ }
set_values_from_presentation(se);
g_signal_emit_by_name(se, "changed");
}
-static void slide_bgcol_sig(GtkColorButton *widget, StylesheetEditor *se)
+static void slide_bg_sig(GtkColorButton *widget, StylesheetEditor *se)
{
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget),
- &se->slide_bgcol);
- update_bg(se->priv->p, "slide", se->slide_bggrad,
- se->slide_bgcol, se->slide_bgcol2);
-
+ update_bg(se->priv->p, "$.slide",
+ se->slide_style_bggrad,
+ se->slide_style_bgcol,
+ se->slide_style_bgcol2);
set_values_from_presentation(se);
g_signal_emit_by_name(se, "changed");
}
-static void slide_bgcol2_sig(GtkColorButton *widget, StylesheetEditor *se)
+static void frame_font_sig(GtkFontButton *widget, StylesheetEditor *se)
{
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget),
- &se->slide_bgcol2);
- update_bg(se->priv->p, "slide", se->slide_bggrad,
- se->slide_bgcol, se->slide_bgcol2);
-
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
+ set_font(widget, se, "$.slide.frame");
}
-static void slide_bggrad_sig(GtkComboBox *widget, StylesheetEditor *se)
+static void frame_fgcol_sig(GtkColorButton *widget, StylesheetEditor *se)
{
- const gchar *id;
-
- id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget));
- se->slide_bggrad = id_to_gradtype(id);
- update_bg(se->priv->p, "slide", se->slide_bggrad,
- se->slide_bgcol, se->slide_bgcol2);
-
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
+ set_col(widget, se, "$.slide.frame", "fgcol");
}
-static void frame_font_sig(GtkFontButton *widget, StylesheetEditor *se)
+static void frame_bg_sig(GtkColorButton *widget, StylesheetEditor *se)
{
- set_font(widget, se, "frame");
+ update_bg(se->priv->p, "$.slide.frame",
+ se->frame_style_bggrad,
+ se->frame_style_bgcol,
+ se->frame_style_bgcol2);
+ set_values_from_presentation(se);
+ g_signal_emit_by_name(se, "changed");
}
-static void frame_fgcol_sig(GtkColorButton *widget, StylesheetEditor *se)
+static void frame_padding_sig(GtkSpinButton *widget, StylesheetEditor *se)
{
- set_col(widget, se, "frame", "fgcol");
+ update_spacing(se->priv->p, "$.slide.frame", "pad",
+ se->frame_style_padding_l,
+ se->frame_style_padding_r,
+ se->frame_style_padding_t,
+ se->frame_style_padding_b);
+ set_values_from_presentation(se);
+ g_signal_emit_by_name(se, "changed");
}
-static void frame_bgcol_sig(GtkColorButton *widget, StylesheetEditor *se)
+static void frame_paraspace_sig(GtkSpinButton *widget, StylesheetEditor *se)
{
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget),
- &se->frame_bgcol);
- update_bg(se->priv->p, "frame", se->frame_bggrad,
- se->frame_bgcol, se->frame_bgcol2);
-
+ update_spacing(se->priv->p, "$.slide.frame", "paraspace",
+ se->frame_style_paraspace_l,
+ se->frame_style_paraspace_r,
+ se->frame_style_paraspace_t,
+ se->frame_style_paraspace_b);
set_values_from_presentation(se);
g_signal_emit_by_name(se, "changed");
}
-static void frame_bgcol2_sig(GtkColorButton *widget, StylesheetEditor *se)
+static void narrative_padding_sig(GtkSpinButton *widget, StylesheetEditor *se)
{
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget),
- &se->frame_bgcol);
- update_bg(se->priv->p, "frame", se->frame_bggrad,
- se->frame_bgcol, se->frame_bgcol2);
-
+ update_spacing(se->priv->p, "$.narrative", "pad",
+ se->narrative_style_padding_l,
+ se->narrative_style_padding_r,
+ se->narrative_style_padding_t,
+ se->narrative_style_padding_b);
set_values_from_presentation(se);
g_signal_emit_by_name(se, "changed");
}
-static void frame_bggrad_sig(GtkComboBox *widget, StylesheetEditor *se)
+static void narrative_paraspace_sig(GtkSpinButton *widget, StylesheetEditor *se)
{
- const gchar *id;
- id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget));
- se->frame_bggrad = id_to_gradtype(id);
- update_bg(se->priv->p, "frame", se->frame_bggrad,
- se->frame_bgcol, se->frame_bgcol2);
-
+ update_spacing(se->priv->p, "$.narrative", "paraspace",
+ se->narrative_style_paraspace_l,
+ se->narrative_style_paraspace_r,
+ se->narrative_style_paraspace_t,
+ se->narrative_style_paraspace_b);
set_values_from_presentation(se);
g_signal_emit_by_name(se, "changed");
}
@@ -423,21 +476,39 @@ void stylesheet_editor_class_init(StylesheetEditorClass *klass)
/* Narrative style */
SE_BIND_CHILD(narrative_style_font, narrative_font_sig);
SE_BIND_CHILD(narrative_style_fgcol, narrative_fgcol_sig);
- SE_BIND_CHILD(narrative_style_bgcol, narrative_bgcol_sig);
- SE_BIND_CHILD(narrative_style_bgcol2, narrative_bgcol2_sig);
- SE_BIND_CHILD(narrative_style_bggrad, narrative_bggrad_sig);
+ SE_BIND_CHILD(narrative_style_bgcol, narrative_bg_sig);
+ SE_BIND_CHILD(narrative_style_bgcol2, narrative_bg_sig);
+ SE_BIND_CHILD(narrative_style_bggrad, narrative_bg_sig);
+ SE_BIND_CHILD(narrative_style_paraspace_l, narrative_paraspace_sig);
+ SE_BIND_CHILD(narrative_style_paraspace_r, narrative_paraspace_sig);
+ SE_BIND_CHILD(narrative_style_paraspace_t, narrative_paraspace_sig);
+ SE_BIND_CHILD(narrative_style_paraspace_b, narrative_paraspace_sig);
+ SE_BIND_CHILD(narrative_style_padding_l, narrative_padding_sig);
+ SE_BIND_CHILD(narrative_style_padding_r, narrative_padding_sig);
+ SE_BIND_CHILD(narrative_style_padding_t, narrative_padding_sig);
+ SE_BIND_CHILD(narrative_style_padding_b, narrative_padding_sig);
/* Slide style */
- SE_BIND_CHILD(slide_style_bgcol, slide_bgcol_sig);
- SE_BIND_CHILD(slide_style_bgcol2, slide_bgcol2_sig);
- SE_BIND_CHILD(slide_style_bggrad, slide_bggrad_sig);
+ SE_BIND_CHILD(slide_size_w, slide_size_sig);
+ SE_BIND_CHILD(slide_size_h, slide_size_sig);
+ SE_BIND_CHILD(slide_style_bgcol, slide_bg_sig);
+ SE_BIND_CHILD(slide_style_bgcol2, slide_bg_sig);
+ SE_BIND_CHILD(slide_style_bggrad, slide_bg_sig);
/* Slide->frame style */
SE_BIND_CHILD(frame_style_font, frame_font_sig);
SE_BIND_CHILD(frame_style_fgcol, frame_fgcol_sig);
- SE_BIND_CHILD(frame_style_bgcol, frame_bgcol_sig);
- SE_BIND_CHILD(frame_style_bgcol2, frame_bgcol2_sig);
- SE_BIND_CHILD(frame_style_bggrad, frame_bggrad_sig);
+ SE_BIND_CHILD(frame_style_bgcol, frame_bg_sig);
+ SE_BIND_CHILD(frame_style_bgcol2, frame_bg_sig);
+ SE_BIND_CHILD(frame_style_bggrad, frame_bg_sig);
+ SE_BIND_CHILD(frame_style_paraspace_l, frame_paraspace_sig);
+ SE_BIND_CHILD(frame_style_paraspace_r, frame_paraspace_sig);
+ SE_BIND_CHILD(frame_style_paraspace_t, frame_paraspace_sig);
+ SE_BIND_CHILD(frame_style_paraspace_b, frame_paraspace_sig);
+ SE_BIND_CHILD(frame_style_padding_l, frame_padding_sig);
+ SE_BIND_CHILD(frame_style_padding_r, frame_padding_sig);
+ SE_BIND_CHILD(frame_style_padding_t, frame_padding_sig);
+ SE_BIND_CHILD(frame_style_padding_b, frame_padding_sig);
gtk_widget_class_bind_template_callback(widget_class, revert_sig);
@@ -446,103 +517,6 @@ void stylesheet_editor_class_init(StylesheetEditorClass *klass)
}
-static void set_from_interp_col(double *col, GtkWidget *w)
-{
- GdkRGBA rgba;
-
- rgba.red = col[0];
- rgba.green = col[1];
- rgba.blue = col[2];
- rgba.alpha = col[3];
- gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(w), &rgba);
-}
-
-
-static void set_from_interp_bggrad(SCInterpreter *scin, GtkWidget *w)
-{
- GradientType grad;
- const gchar *id;
-
- grad = sc_interp_get_bggrad(scin);
-
- switch ( grad ) {
- case GRAD_NONE : id = "flat"; break;
- case GRAD_HORIZ : id = "horiz"; break;
- case GRAD_VERT : id = "vert"; break;
- case GRAD_NOBG : id = "none"; break;
- default : id = NULL; break;
- }
-
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(w), id);
-}
-
-
-static void set_from_interp_font(SCInterpreter *scin, GtkWidget *w)
-{
- char *fontname;
- PangoFontDescription *fontdesc;
-
- fontdesc = sc_interp_get_fontdesc(scin);
- fontname = pango_font_description_to_string(fontdesc);
- gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), fontname);
- g_free(fontname);
-}
-
-
-static void set_values_from_presentation(StylesheetEditor *se)
-{
- SCInterpreter *scin;
- PangoContext *pc;
-
- pc = gdk_pango_context_get();
-
- scin = sc_interp_new(pc, NULL, NULL, NULL);
- sc_interp_run_stylesheet(scin, se->priv->p->stylesheet); /* NULL stylesheet is OK */
-
- /* Narrative style */
- sc_interp_save(scin);
- sc_interp_run_style(scin, "narrative");
- set_from_interp_font(scin, se->narrative_style_font);
- set_from_interp_col(sc_interp_get_fgcol(scin), se->narrative_style_fgcol);
- set_from_interp_col(sc_interp_get_bgcol(scin), se->narrative_style_bgcol);
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->narrative_style_bgcol),
- &se->narrative_bgcol);
- set_from_interp_col(sc_interp_get_bgcol2(scin), se->narrative_style_bgcol2);
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->narrative_style_bgcol2),
- &se->narrative_bgcol2);
- set_from_interp_bggrad(scin, se->narrative_style_bggrad);
- sc_interp_restore(scin);
-
- /* Slide style */
- sc_interp_save(scin);
- sc_interp_run_style(scin, "slide");
- set_from_interp_col(sc_interp_get_bgcol(scin), se->slide_style_bgcol);
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->slide_style_bgcol),
- &se->slide_bgcol);
- set_from_interp_col(sc_interp_get_bgcol2(scin), se->slide_style_bgcol2);
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->slide_style_bgcol2),
- &se->slide_bgcol2);
- set_from_interp_bggrad(scin, se->slide_style_bggrad);
- sc_interp_restore(scin);
-
- /* Slide->Frame style */
- sc_interp_save(scin);
- sc_interp_run_style(scin, "frame");
- set_from_interp_font(scin, se->frame_style_font);
- set_from_interp_col(sc_interp_get_fgcol(scin), se->frame_style_fgcol);
- set_from_interp_col(sc_interp_get_bgcol(scin), se->frame_style_bgcol);
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->frame_style_bgcol),
- &se->frame_bgcol);
- set_from_interp_col(sc_interp_get_bgcol2(scin), se->frame_style_bgcol2);
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->frame_style_bgcol2),
- &se->frame_bgcol2);
- set_from_interp_bggrad(scin, se->frame_style_bggrad);
- sc_interp_restore(scin);
-
- sc_interp_destroy(scin);
-}
-
-
StylesheetEditor *stylesheet_editor_new(struct presentation *p)
{
StylesheetEditor *se;
diff --git a/src/stylesheet_editor.h b/src/stylesheet_editor.h
index 480bd8a..22856da 100644
--- a/src/stylesheet_editor.h
+++ b/src/stylesheet_editor.h
@@ -63,6 +63,16 @@ struct _stylesheeteditor
GtkWidget *narrative_style_bgcol;
GtkWidget *narrative_style_bgcol2;
GtkWidget *narrative_style_bggrad;
+ GtkWidget *narrative_style_paraspace_l;
+ GtkWidget *narrative_style_paraspace_r;
+ GtkWidget *narrative_style_paraspace_t;
+ GtkWidget *narrative_style_paraspace_b;
+ GtkWidget *narrative_style_padding_l;
+ GtkWidget *narrative_style_padding_r;
+ GtkWidget *narrative_style_padding_t;
+ GtkWidget *narrative_style_padding_b;
+ GtkWidget *slide_size_w;
+ GtkWidget *slide_size_h;
GtkWidget *slide_style_bgcol;
GtkWidget *slide_style_bgcol2;
GtkWidget *slide_style_bggrad;
@@ -71,20 +81,17 @@ struct _stylesheeteditor
GtkWidget *frame_style_bgcol;
GtkWidget *frame_style_bgcol2;
GtkWidget *frame_style_bggrad;
+ GtkWidget *frame_style_paraspace_l;
+ GtkWidget *frame_style_paraspace_r;
+ GtkWidget *frame_style_paraspace_t;
+ GtkWidget *frame_style_paraspace_b;
+ GtkWidget *frame_style_padding_l;
+ GtkWidget *frame_style_padding_r;
+ GtkWidget *frame_style_padding_t;
+ GtkWidget *frame_style_padding_b;
StylesheetEditorPrivate *priv;
-
- GdkRGBA narrative_bgcol;
- GdkRGBA narrative_bgcol2;
- GradientType narrative_bggrad;
- GdkRGBA slide_bgcol;
- GdkRGBA slide_bgcol2;
- GradientType slide_bggrad;
- GdkRGBA frame_bgcol;
- GdkRGBA frame_bgcol2;
- GradientType frame_bggrad;
};
-
struct _stylesheeteditorclass
{
GtkDialogClass parent_class;
diff --git a/src/utils.c b/src/utils.c
index 9033466..277b3f1 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -54,90 +54,30 @@ int safe_strcmp(const char *a, const char *b)
}
-static char *fgets_long(FILE *fh, size_t *lp)
+int parse_double(const char *a, float v[2])
{
- char *line;
- size_t la;
- size_t l = 0;
-
- la = 1024;
- line = malloc(la);
- if ( line == NULL ) return NULL;
-
- do {
-
- int r;
-
- r = fgetc(fh);
- if ( r == EOF ) {
- if ( l == 0 ) {
- free(line);
- *lp = 0;
- return NULL;
- } else {
- line[l++] = '\0';
- *lp = l;
- return line;
- }
- }
-
- line[l++] = r;
-
- if ( r == '\n' ) {
- line[l++] = '\0';
- *lp = l;
- return line;
- }
-
- if ( l == la ) {
+ int nn;
- char *ln;
-
- la += 1024;
- ln = realloc(line, la);
- if ( ln == NULL ) {
- free(line);
- *lp = 0;
- return NULL;
- }
-
- line = ln;
-
- }
+ nn = sscanf(a, "%fx%f", &v[0], &v[1]);
+ if ( nn != 2 ) {
+ fprintf(stderr, _("Invalid size '%s'\n"), a);
+ return 1;
+ }
- } while ( 1 );
+ return 0;
}
-char *load_everything(const char *filename)
+int parse_tuple(const char *a, float v[4])
{
- FILE *fh;
- size_t el = 1;
- char *everything = strdup("");
-
- fh = fopen(filename, "r");
- if ( fh == NULL ) return NULL;
-
- while ( !feof(fh) ) {
-
- size_t len = 0;
- char *line = fgets_long(fh, &len);
-
- if ( line != NULL ) {
-
- everything = realloc(everything, el+len);
- if ( everything == NULL ) {
- fprintf(stderr, _("Failed to allocate memory\n"));
- return NULL;
- }
- el += len;
-
- strcat(everything, line);
- }
+ int nn;
+ nn = sscanf(a, "%f,%f,%f,%f", &v[0], &v[1], &v[2], &v[3]);
+ if ( nn != 4 ) {
+ fprintf(stderr, _("Invalid tuple '%s'\n"), a);
+ return 1;
}
- fclose(fh);
-
- return everything;
+ return 0;
}
+
diff --git a/src/utils.h b/src/utils.h
index bfc04c2..fc843c3 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -30,7 +30,8 @@
extern void chomp(char *s);
extern int safe_strcmp(const char *a, const char *b);
-extern char *load_everything(const char *filename);
+extern int parse_double(const char *a, float v[2]);
+extern int parse_tuple(const char *a, float v[4]);
#include <libintl.h>
#define _(x) gettext(x)