aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/loadsave.c107
-rw-r--r--src/loadsave.h5
-rw-r--r--src/presentation.c4
-rw-r--r--src/stylesheet.c44
4 files changed, 140 insertions, 20 deletions
diff --git a/src/loadsave.c b/src/loadsave.c
index 2d9e55f..b85f4d0 100644
--- a/src/loadsave.c
+++ b/src/loadsave.c
@@ -99,7 +99,7 @@ static struct ds_node *add_child(struct ds_node *node, const char *key)
}
-static void UNUSED show_tree(struct ds_node *root, const char *path)
+void show_tree(struct ds_node *root, const char *path)
{
char newpath[1024];
int i;
@@ -121,7 +121,7 @@ static void UNUSED show_tree(struct ds_node *root, const char *path)
}
-struct ds_node *find_node(struct ds_node *root, const char *path)
+struct ds_node *find_node(struct ds_node *root, const char *path, int cr)
{
size_t start, len;
char element[1024];
@@ -163,9 +163,13 @@ struct ds_node *find_node(struct ds_node *root, const char *path)
if ( !found ) {
- cur = add_child(cur, element);
- if ( cur == NULL ) {
- return NULL; /* Error */
+ if ( cr ) {
+ cur = add_child(cur, element);
+ if ( cur == NULL ) {
+ return NULL; /* Error */
+ }
+ } else {
+ return NULL;
}
}
@@ -267,7 +271,7 @@ static int deserialize_file(FILE *fh, struct ds_node *root)
}
value[pos] = '\0';
- node = find_node(cur_node, key);
+ node = find_node(cur_node, key, 1);
node->value = strdup(value);
} else {
@@ -279,7 +283,7 @@ static int deserialize_file(FILE *fh, struct ds_node *root)
if ( !isspace(line[i]) ) path[pos++] = line[i];
}
path[pos] = '\0';
- cur_node = find_node(root, path);
+ cur_node = find_node(root, path, 1);
}
@@ -311,7 +315,7 @@ int get_field_f(struct ds_node *root, const char *key, double *val)
double v;
char *check;
- node = find_node(root, key);
+ node = find_node(root, key, 0);
if ( node == NULL ) {
fprintf(stderr, "Couldn't find field '%s'\n", key);
return 1;
@@ -335,7 +339,7 @@ int get_field_i(struct ds_node *root, const char *key, int *val)
int v;
char *check;
- node = find_node(root, key);
+ node = find_node(root, key, 0);
if ( node == NULL ) {
fprintf(stderr, "Couldn't find field '%s'\n", key);
return 1;
@@ -360,9 +364,10 @@ int get_field_s(struct ds_node *root, const char *key, char **val)
size_t i, len, s1, s2;
int hq;
- node = find_node(root, key);
+ node = find_node(root, key, 0);
if ( node == NULL ) {
fprintf(stderr, "Couldn't find field '%s'\n", key);
+ *val = NULL;
return 1;
}
@@ -483,6 +488,78 @@ static struct slide *tree_to_slide(struct presentation *p, struct ds_node *root)
}
+static void try_last(struct slide *s, struct slide *ls, enum object_role r)
+{
+ if ( s->roles[r] == NULL ) {
+ s->roles[r] = ls->roles[r];
+ }
+}
+
+
+static void try_update(struct object *o)
+{
+ if ( o == NULL ) return;
+ o->update_object(o);
+}
+
+
+/* Go through all the slides and make sure the roles are tidied up */
+static void fix_up_roles(struct presentation *p)
+{
+ int i;
+ struct slide *last_slide = NULL;
+
+ for ( i=0; i<p->num_slides; i++ ) {
+
+ int j;
+ struct slide *s;
+
+ s = p->slides[i];
+
+ for ( j=0; j<NUM_S_ROLES; j++ ) {
+ s->roles[j] = NULL;
+ }
+
+ for ( j=0; j<s->num_objects; j++ ) {
+
+ struct object *o;
+ enum object_role r;
+
+ o = s->objects[j];
+ r = o->style->role;
+
+ if ( r == S_ROLE_NONE ) continue;
+
+ if ( s->roles[r] != NULL ) {
+ fprintf(stderr, "Warning, two objects in slide"
+ " with role %i.\n", r);
+ continue;
+ }
+
+ s->roles[r] = o;
+
+ }
+
+ if ( last_slide != NULL ) {
+
+ /* Set off-slide references for this slide */
+ try_last(s, last_slide, S_ROLE_PTITLE_REF);
+ try_last(s, last_slide, S_ROLE_PAUTHOR_REF);
+ try_last(s, last_slide, S_ROLE_PDATE_REF);
+
+ }
+
+ try_update(s->roles[S_ROLE_PTITLE]);
+ try_update(s->roles[S_ROLE_PAUTHOR]);
+ try_update(s->roles[S_ROLE_PDATE]);
+ try_update(s->roles[S_ROLE_SLIDENUMBER]);
+
+ last_slide = s;
+
+ }
+}
+
+
static int tree_to_slides(struct ds_node *root, struct presentation *p)
{
int i;
@@ -499,6 +576,8 @@ static int tree_to_slides(struct ds_node *root, struct presentation *p)
}
+ fix_up_roles(p);
+
return 0;
}
@@ -512,7 +591,7 @@ int tree_to_presentation(struct ds_node *root, struct presentation *p)
p->cur_edit_slide = NULL;
p->cur_proj_slide = NULL;
- node = find_node(root, "slide-properties/width");
+ node = find_node(root, "slide-properties/width", 0);
if ( node == NULL ) return 1;
p->slide_width = strtod(node->value, &check);
if ( check == node->value ) {
@@ -520,7 +599,7 @@ int tree_to_presentation(struct ds_node *root, struct presentation *p)
return 1;
}
- node = find_node(root, "slide-properties/height");
+ node = find_node(root, "slide-properties/height", 0);
if ( node == NULL ) return 1;
p->slide_height = strtod(node->value, &check);
if ( check == node->value ) {
@@ -528,7 +607,7 @@ int tree_to_presentation(struct ds_node *root, struct presentation *p)
return 1;
}
- node = find_node(root, "stylesheet");
+ node = find_node(root, "stylesheet", 0);
if ( node != NULL ) {
free_stylesheet(p->ss);
p->ss = tree_to_stylesheet(node);
@@ -543,7 +622,7 @@ int tree_to_presentation(struct ds_node *root, struct presentation *p)
p->num_slides = 0;
}
- node = find_node(root, "slides");
+ node = find_node(root, "slides", 0);
if ( node != NULL ) {
tree_to_slides(node, p);
if ( p->num_slides == 0 ) {
diff --git a/src/loadsave.h b/src/loadsave.h
index b5cd727..09226d3 100644
--- a/src/loadsave.h
+++ b/src/loadsave.h
@@ -51,6 +51,8 @@ struct serializer
int blank_written;
};
+extern void show_tree(struct ds_node *root, const char *path);
+
extern void serialize_start(struct serializer *s, const char *id);
extern void serialize_s(struct serializer *s, const char *key, const char *val);
extern void serialize_f(struct serializer *s, const char *key, double val);
@@ -61,7 +63,8 @@ extern int get_field_f(struct ds_node *root, const char *key, double *val);
extern int get_field_i(struct ds_node *root, const char *key, int *val);
extern int get_field_s(struct ds_node *root, const char *key, char **val);
-extern struct ds_node *find_node(struct ds_node *root, const char *path);
+extern struct ds_node *find_node(struct ds_node *root, const char *path,
+ int cr);
extern int load_presentation(struct presentation *p, const char *filename);
extern int save_presentation(struct presentation *p, const char *filename);
diff --git a/src/presentation.c b/src/presentation.c
index cf0d971..4aedc71 100644
--- a/src/presentation.c
+++ b/src/presentation.c
@@ -305,9 +305,7 @@ int slide_number(struct presentation *p, struct slide *s)
if ( p->slides[i] == s ) return i;
}
- fprintf(stderr, "Sorry, this point is never reached.\n");
- fprintf(stderr, "Please report a bug.\n");
- return 0;
+ return p->num_slides;
}
diff --git a/src/stylesheet.c b/src/stylesheet.c
index 2e97d66..5706cc2 100644
--- a/src/stylesheet.c
+++ b/src/stylesheet.c
@@ -632,6 +632,36 @@ enum vert_pos str_to_valign(char *valign)
}
+static const char *str_role(enum object_role r)
+{
+ switch ( r ) {
+ case S_ROLE_NONE : return "none";
+ case S_ROLE_SLIDENUMBER : return "slidenumber";
+ case S_ROLE_PTITLE : return "ptitle";
+ case S_ROLE_PTITLE_REF : return "ptitle-ref";
+ case S_ROLE_PAUTHOR : return "pauthor";
+ case S_ROLE_PAUTHOR_REF : return "pauthor-ref";
+ case S_ROLE_PDATE : return "pdate";
+ case S_ROLE_PDATE_REF : return "pdate-ref";
+ default : return "???";
+ }
+}
+
+
+enum object_role str_to_role(const char *s)
+{
+ if ( strcmp(s, "slidenumber") == 0 ) return S_ROLE_SLIDENUMBER;
+ if ( strcmp(s, "ptitle") == 0 ) return S_ROLE_PTITLE;
+ if ( strcmp(s, "ptitle-ref") == 0 ) return S_ROLE_PTITLE_REF;
+ if ( strcmp(s, "pauthor") == 0 ) return S_ROLE_PAUTHOR;
+ if ( strcmp(s, "pauthor-ref") == 0 ) return S_ROLE_PAUTHOR_REF;
+ if ( strcmp(s, "padte") == 0 ) return S_ROLE_PDATE;
+ if ( strcmp(s, "pdate-ref") == 0 ) return S_ROLE_PDATE_REF;
+
+ return S_ROLE_NONE;
+}
+
+
static const char *str_bgtype(enum bgblocktype t)
{
switch ( t ) {
@@ -662,6 +692,15 @@ static enum bgblocktype str_to_bgtype(char *t)
static int read_style(struct style *sty, struct ds_node *root)
{
char *align;
+ char *role;
+
+ get_field_s(root, "role", &role);
+ if ( role != NULL ) {
+ sty->role = str_to_role(role);
+ free(role);
+ } else {
+ sty->role = S_ROLE_NONE;
+ }
get_field_f(root, "margin_left", &sty->margin_left);
get_field_f(root, "margin_right", &sty->margin_right);
@@ -733,7 +772,7 @@ StyleSheet *tree_to_stylesheet(struct ds_node *root)
ss = new_stylesheet();
if ( ss == NULL ) return NULL;
- node = find_node(root, "styles");
+ node = find_node(root, "styles", 0);
if ( node == NULL ) {
fprintf(stderr, "Couldn't find styles\n");
free_stylesheet(ss);
@@ -766,7 +805,7 @@ StyleSheet *tree_to_stylesheet(struct ds_node *root)
}
- node = find_node(root, "bgblocks");
+ node = find_node(root, "bgblocks", 0);
if ( node == NULL ) {
fprintf(stderr, "Couldn't find bgblocks\n");
free_stylesheet(ss);
@@ -950,6 +989,7 @@ void write_stylesheet(StyleSheet *ss, struct serializer *ser)
serialize_start(ser, id);
serialize_s(ser, "name", s->name);
+ serialize_s(ser, "role", str_role(s->role));
serialize_f(ser, "margin_left", s->margin_left);
serialize_f(ser, "margin_right", s->margin_right);
serialize_f(ser, "margin_top", s->margin_top);