From 837b3b4b1cc97c8e2b6809256ec0bb20a1d98c0c Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 22 Dec 2020 18:04:10 +0100 Subject: Avoid deleting slide when pressing backspace in an empty text paragraph --- libstorycode/gtk/gtknarrativeview.c | 34 +++++++++++++++++++++++++--------- libstorycode/narrative.c | 20 +++++++++++++++----- libstorycode/narrative.h | 2 ++ 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/libstorycode/gtk/gtknarrativeview.c b/libstorycode/gtk/gtknarrativeview.c index 9311812..28a2a33 100644 --- a/libstorycode/gtk/gtknarrativeview.c +++ b/libstorycode/gtk/gtknarrativeview.c @@ -703,20 +703,36 @@ static void gtknv_do_backspace(GtkNarrativeView *e, signed int dir) p1 = e->sel_start; p2 = e->sel_end; + sort_positions(&p1, &p2); + o1 = narrative_pos_trail_to_offset(e->n, p1.para, p1.pos, p1.trail); + o2 = narrative_pos_trail_to_offset(e->n, p2.para, p2.pos, p2.trail); + narrative_delete_block(e->n, p1.para, o1, p2.para, o2); + e->cpos = p1; + } else { /* Delete one character, as represented visually */ - p2 = e->cpos; - p1 = p2; - gtknv_cursor_moveh(e->n, &p1, dir); - set_cursor_h_pos(e); + + if ( narrative_item_is_empty_text(e->n, e->cpos.para) ) { + narrative_delete_item(e->n, e->cpos.para); + if ( dir == -1 ) { + e->cpos.para--; + } /* else we are already on the right item */ + } else { + + p2 = e->cpos; + p1 = p2; + gtknv_cursor_moveh(e->n, &p1, dir); + set_cursor_h_pos(e); + sort_positions(&p1, &p2); + o1 = narrative_pos_trail_to_offset(e->n, p1.para, p1.pos, p1.trail); + o2 = narrative_pos_trail_to_offset(e->n, p2.para, p2.pos, p2.trail); + narrative_delete_block(e->n, p1.para, o1, p2.para, o2); + e->cpos = p1; + + } } - sort_positions(&p1, &p2); - o1 = narrative_pos_trail_to_offset(e->n, p1.para, p1.pos, p1.trail); - o2 = narrative_pos_trail_to_offset(e->n, p2.para, p2.pos, p2.trail); - narrative_delete_block(e->n, p1.para, o1, p2.para, o2); - e->cpos = p1; gtknv_unset_selection(e); /* The only paragraphs which still exist and might have been diff --git a/libstorycode/narrative.c b/libstorycode/narrative.c index ffd7dab..34c55aa 100644 --- a/libstorycode/narrative.c +++ b/libstorycode/narrative.c @@ -199,6 +199,16 @@ int narrative_item_is_text(Narrative *n, int item) } +int narrative_item_is_empty_text(Narrative *n, int item) +{ + struct narrative_item *i = &n->items[item]; + + return (narrative_item_is_text(n, item) + && (i->n_runs == 1) + && (strlen(i->runs[0].text)==0)); +} + + void narrative_add_stylesheet(Narrative *n, Stylesheet *ss) { assert(n->stylesheet == NULL); @@ -336,7 +346,7 @@ void narrative_insert_slide(Narrative *n, int pos, Slide *slide) } -static void delete_item(Narrative *n, int del) +void narrative_delete_item(Narrative *n, int del) { int i; narrative_item_destroy(&n->items[del]); @@ -408,7 +418,7 @@ void narrative_delete_block(Narrative *n, int i1, size_t o1, int i2, size_t o2) /* Starting item */ if ( !narrative_item_is_text(n, i1) ) { - delete_item(n, i1); + narrative_delete_item(n, i1); if ( i1 == i2 ) return; /* only one slide to delete */ middle = i1; /* ... which is now the item just after the slide */ i2--; @@ -429,14 +439,14 @@ void narrative_delete_block(Narrative *n, int i1, size_t o1, int i2, size_t o2) for ( i=middle; in_runs += item2->n_runs; - delete_item(n, i2); + narrative_delete_item(n, i2); update_timing(item1); } } diff --git a/libstorycode/narrative.h b/libstorycode/narrative.h index fba69d2..26a2d9c 100644 --- a/libstorycode/narrative.h +++ b/libstorycode/narrative.h @@ -52,6 +52,7 @@ extern void narrative_set_unsaved(Narrative *n); extern int narrative_get_unsaved(Narrative *n); extern int narrative_item_is_text(Narrative *n, int item); +extern int narrative_item_is_empty_text(Narrative *n, int item); extern void narrative_insert_text(Narrative *n, int pos, struct text_run *runs, int n_runs); extern void narrative_insert_bp(Narrative *n, int pos, struct text_run *runs, int n_runs); @@ -64,6 +65,7 @@ extern void narrative_insert_eop(Narrative *n, int pos); extern void narrative_delete_block(Narrative *n, int i1, size_t o1, int i2, size_t o2); extern void narrative_split_item(Narrative *n, int i1, size_t o1); +extern void narrative_delete_item(Narrative *n, int del); extern int narrative_get_num_items(Narrative *n); extern int narrative_get_num_items_to_eop(Narrative *n); extern int narrative_get_num_slides(Narrative *n); -- cgit v1.2.3