diff options
-rw-r--r-- | src/frame.c | 72 | ||||
-rw-r--r-- | src/frame.h | 4 | ||||
-rw-r--r-- | src/sc_editor.c | 10 |
3 files changed, 78 insertions, 8 deletions
diff --git a/src/frame.c b/src/frame.c index 3c9dd34..136ff0f 100644 --- a/src/frame.c +++ b/src/frame.c @@ -945,14 +945,20 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po double wrapw) { int i; + size_t del = 0; sort_positions(&p1, &p2); + printf("para %i offs %ld\n", p1.para, p1.pos); + printf("para %i offs %li\n", p2.para, p2.pos); + for ( i=p1.para; i<=p2.para; i++ ) { size_t start; ssize_t finis; + printf("para %i\n", i); + Paragraph *para = fr->paras[i]; if ( i == p1.para ) { @@ -968,31 +974,44 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po } if ( (start == 0) && (finis == -1) ) { + printf("deleting para %i\n", i); delete_paragraph(fr, i); p2.para--; i--; } else { - delete_text_in_paragraph(para, start, finis); + printf("deleting from %ld to %ld\n", start, finis); + del += delete_text_in_paragraph(para, start, finis); wrap_paragraph(para, NULL, wrapw, 0, 0); } } + + /* Update offsets for all subsequent paragraphs, but only if they're + * from the same SCBlock */ + printf("fixing offsets from para %i by %i\n", p1.para, del); + fix_scblock_offsets(fr, p1, del); } /* offs2 negative means "to end" */ -void delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2) +size_t delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2) { int nrun1, nrun2, nrun; int i; size_t scblock_offs1, scblock_offs2; + size_t sum_del = 0; /* Find which run we are in */ nrun1 = which_run(para, offs1); - nrun2 = which_run(para, offs2); + if ( offs2 < 0 ) { + /* Delete to end */ + nrun2 = para->n_runs-1; + } else { + nrun2 = which_run(para, offs2); + } if ( (nrun1 == para->n_runs) || (nrun2 == para->n_runs) ) { fprintf(stderr, "Couldn't find run to delete from.\n"); - return; + return 0; } for ( nrun=nrun1; nrun<=nrun2; nrun++ ) { @@ -1008,7 +1027,11 @@ void delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2) } ds = offs1 - run->para_offs_bytes; - de = offs2 - run->para_offs_bytes; + if ( offs2 < 0 ) { + de = run->len_bytes; + } else { + de = offs2 - run->para_offs_bytes; + } if ( ds < 0 ) ds = 0; if ( de > run->len_bytes ) { de = run->len_bytes; @@ -1020,6 +1043,8 @@ void delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2) /* Delete from the corresponding SC block */ scblock_offs1 = ds + run->scblock_offs_bytes; scblock_offs2 = de + run->scblock_offs_bytes; + sum_del += scblock_offs2 - scblock_offs1; + printf("del %i %i\n", scblock_offs1, scblock_offs2); scblock_delete_text(run->scblock, scblock_offs1, scblock_offs2); /* Fix up the offsets of the subsequent text runs */ @@ -1034,6 +1059,43 @@ void delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2) offs2 -= del_len; } + + return sum_del; +} + + +void fix_scblock_offsets(struct frame *fr, struct edit_pos pos, size_t del) +{ + int i; + int nrun; + size_t offs; + SCBlock *scblock; + + offs = pos_trail_to_offset(fr->paras[pos.para], pos.pos, pos.trail); + nrun = which_run(fr->paras[pos.para], offs); + + if ( nrun == fr->paras[pos.para]->n_runs ) { + fprintf(stderr, "Couldn't find new start\n"); + return; + } + + /* We will update the offsets of any runs which match this block */ + scblock = fr->paras[pos.para]->runs[nrun].scblock; + + for ( i=pos.para+1; i<fr->n_paras; i++ ) { + + int j; + Paragraph *para; + + para = fr->paras[i]; + + if ( para->type != PARA_TYPE_TEXT ) continue; + + for ( j=0; j<para->n_runs; j++ ) { + if ( para->runs[j].scblock != scblock) return; + para->runs[j].scblock_offs_bytes -= del; + } + } } diff --git a/src/frame.h b/src/frame.h index 0386a51..8e2ffe3 100644 --- a/src/frame.h +++ b/src/frame.h @@ -181,7 +181,9 @@ 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 void delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2); +extern size_t delete_text_in_paragraph(Paragraph *para, size_t offs0, ssize_t offs2); + +extern void fix_scblock_offsets(struct frame *fr, struct edit_pos pos, size_t del); extern SCBlock *split_paragraph(struct frame *fr, int pn, size_t pos, PangoContext *pc); diff --git a/src/sc_editor.c b/src/sc_editor.c index aabb84a..db0f11d 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -720,7 +720,6 @@ static void do_backspace(struct frame *fr, SCEditor *e) if ( e->sel_active ) { /* Delete the selected block */ - printf("delete block\n"); delete_text_from_frame(e->cursor_frame, e->sel_start, e->sel_end, wrapw); /* Cursor goes at start of deletion */ @@ -753,15 +752,22 @@ static void do_backspace(struct frame *fr, SCEditor *e) } else { + size_t del; size_t offs_new, offs_old; + struct edit_pos pos; offs_new = pos_trail_to_offset(para, e->cursor_pos, e->cursor_trail); offs_old = pos_trail_to_offset(para, old_pos, old_trail); - delete_text_in_paragraph(para, offs_new, offs_old); + del = delete_text_in_paragraph(para, offs_new, offs_old); + pos.para = new_para; + pos.pos = new_pos; + pos.trail = new_trail; + fix_scblock_offsets(fr, pos, 1); wrap_paragraph(para, NULL, wrapw, 0, 0); + } } |