Disallow insertion and deletion unless scblock==rscblock
authorThomas White <taw@physics.org>
Sun, 18 Mar 2018 15:15:53 +0000 (16:15 +0100)
committerThomas White <taw@physics.org>
Sun, 18 Mar 2018 20:35:44 +0000 (21:35 +0100)
src/frame.c
src/frame.h
src/sc_editor.c
src/sc_interp.c

index 27e2210..a125ce6 100644 (file)
@@ -961,6 +961,40 @@ size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail)
 }
 
 
+int position_editable(struct frame *fr, struct edit_pos cp)
+{
+       Paragraph *para;
+       int run;
+       size_t paraoffs;
+
+       if ( fr == NULL ) {
+               fprintf(stderr, "Frame is NULL.\n");
+               return 0;
+       }
+
+       if ( cp.para >= fr->n_paras ) {
+               fprintf(stderr, "Paragraph number is too high!\n");
+               return 0;
+       }
+
+       para = fr->paras[cp.para];
+
+       if ( para->scblock != para->rscblock ) {
+               fprintf(stderr, "Paragraph is not editable.\n");
+               return 0;
+       }
+
+       paraoffs = pos_trail_to_offset(para, cp.pos, cp.trail);
+       run = which_run(para, paraoffs);
+       if ( run == para->n_runs ) {
+               fprintf(stderr, "Couldn't find run!\n");
+               return 0;
+       }
+
+       return (para->runs[run].scblock == para->runs[run].rscblock);
+}
+
+
 void insert_text_in_paragraph(Paragraph *para, size_t offs, const char *t)
 {
        int nrun;
@@ -1391,6 +1425,11 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po
 
        sort_positions(&p1, &p2);
 
+       if ( !position_editable(fr, p1) || !position_editable(fr, p2) ) {
+               fprintf(stderr, "Block delete outside editable region\n");
+               return;
+       }
+
        /* Find SC positions for start and end */
        p1scblock = pos_to_scblock(fr, p1, &type1);
        p2scblock = pos_to_scblock(fr, p2, &type2);
index 2548d6d..8eae26a 100644 (file)
@@ -164,6 +164,8 @@ extern int positions_equal(struct edit_pos a, struct edit_pos b);
 extern int get_para_highlight(struct frame *fr, int cursor_para,
                               double *cx, double *cy, double *cw, double *ch);
 
+extern int position_editable(struct frame *fr, struct edit_pos cp);
+
 extern int get_cursor_pos(struct frame *fr, int cursor_para, int cursor_pos,
                           double *cx, double *cy, double *ch);
 
index 065c76b..36ea899 100644 (file)
@@ -748,9 +748,16 @@ static void do_backspace(struct frame *fr, SCEditor *e)
                        show_edit_pos(p1);
                        show_edit_pos(p2);
 
-                       delete_text_from_frame(e->cursor_frame, p1, p2, wrapw);
+                       if ( position_editable(e->cursor_frame, p1)
+                         && position_editable(e->cursor_frame, p2) )
+                       {
 
-                       e->cpos = p2;
+                               delete_text_from_frame(e->cursor_frame, p1, p2, wrapw);
+                               e->cpos = p2;
+
+                       } else {
+                               fprintf(stderr, "Deleting not editable.\n");
+                       }
 
                } else {
 
@@ -770,13 +777,8 @@ static void insert_text(char *t, SCEditor *e)
 {
        Paragraph *para;
 
-       if ( e->cursor_frame == NULL ) {
-               fprintf(stderr, "Inserting text into no frame.\n");
-               return;
-       }
-
-       if ( e->cpos.para >= e->cursor_frame->n_paras ) {
-               fprintf(stderr, "Cursor paragraph number is too high!\n");
+       if ( !position_editable(e->cursor_frame, e->cpos) ) {
+               fprintf(stderr, "Position not editable\n");
                return;
        }
 
index 6914b13..55d5f34 100644 (file)
@@ -243,7 +243,7 @@ static int check_callback(SCInterpreter *scin, SCBlock *bl)
                if ( strcmp(cbl->names[i], name) != 0 ) continue;
                r = cbl->box_funcs[i](scin, bl, &w, &h, &bvp, cbl->vps[i]);
                if ( r )  {
-                       add_callback_para(sc_interp_get_frame(scin), bl, w, h,
+                       add_callback_para(sc_interp_get_frame(scin), bl, rbl, w, h,
                                          cbl->draw_funcs[i], cbl->click_funcs[i],
                                          bvp, cbl->vps[i]);
                }