aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2014-06-22 16:17:49 +0200
committerThomas White <taw@bitwiz.org.uk>2014-06-22 16:17:49 +0200
commit0574767480272acc854a31d046cc92b5a5683d8a (patch)
treea63d89bd5e25d16ea453d2fd3b9a96559ece5882
parentc8c48c4a22953c2da38e9947e56fbce0fde78cec (diff)
Insert text
-rw-r--r--src/mainwindow.c162
-rw-r--r--src/sc_parse.c15
-rw-r--r--src/sc_parse.h3
3 files changed, 85 insertions, 95 deletions
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 26c544f..7badcd5 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -1075,51 +1075,86 @@ void update_titlebar(struct presentation *p)
}
-static void insert_text(struct frame *fr, char *t, struct presentation *p)
+static void move_cursor(struct presentation *p, signed int x, signed int y)
{
-#warning Re-implement insert_text() and do_backspace() please
-#if 0
- char *tmp;
- size_t tlen, olen;
- int i;
+ if ( x > 0 ) {
- tlen = strlen(t);
- olen = strlen(fr->sc);
+ int advance = 0;
+ signed int cp, cb, cl;
+ struct wrap_line *line = &p->cursor_frame->lines[p->cursor_line];
+ struct wrap_box *box = &line->boxes[p->cursor_box];
- if ( tlen + olen + 1 > fr->sc_len ) {
+ cp = p->cursor_pos;
+ cb = p->cursor_box;
+ cl = p->cursor_line;
+
+ if ( box->type == WRAP_BOX_PANGO ) {
+
+ if ( cp+1 > box->len_chars ) {
+ advance = 1;
+ } else {
+ cp++;
+ }
- char *try;
- size_t new_len = fr->sc_len + tlen + 64;
+ } else {
+ cp++;
+ if ( cp > 1 ) advance = 1;
+ }
- try = realloc(fr->sc, new_len);
- if ( try == NULL ) return; /* Failed to insert */
- fr->sc = try;
- fr->sc_len = new_len;
+ if ( advance ) {
- }
+ do {
- tmp = malloc(fr->sc_len);
- if ( tmp == NULL ) return;
+ cb++;
+ cp = 0;
- for ( i=0; i<fr->pos; i++ ) {
- tmp[i] = fr->sc[i];
- }
- for ( i=0; i<tlen; i++ ) {
- tmp[i+fr->pos] = t[i];
- }
- for ( i=0; i<olen-fr->pos; i++ ) {
- tmp[i+fr->pos+tlen] = fr->sc[i+fr->pos];
+ if ( cb >= line->n_boxes ) {
+ cl++;
+ if ( cl >= p->cursor_frame->n_lines ) {
+ /* Give up - could not move */
+ return;
+ }
+ p->cursor_line = cl;
+ line = &p->cursor_frame->lines[cl];
+ cb = 0;
+ cp = 0;
+ }
+
+ } while ( (line->boxes[cb].type == WRAP_BOX_SENTINEL)
+ || (line->boxes[cb].type == WRAP_BOX_NOTHING)
+ || !line->boxes[cb].editable );
+
+ p->cursor_box = cb;
+
+ }
+ p->cursor_pos = cp;
+
+ } else {
+ move_cursor_back(p);
}
- tmp[olen+tlen] = '\0';
- memcpy(fr->sc, tmp, fr->sc_len);
- free(tmp);
+}
+
+
+static void insert_text(struct frame *fr, char *t, struct presentation *p)
+{
+ int sln, sbx, sps;
+ struct wrap_box *sbox;
+
+ if ( fr == NULL ) return;
+
+ /* If this is, say, the top level frame, do nothing */
+ if ( fr->boxes == NULL ) return;
+
+ sln = p->cursor_line;
+ sbx = p->cursor_box;
+ sps = p->cursor_pos;
+ sbox = &p->cursor_frame->lines[sln].boxes[sbx];
+
+ sc_insert_text(sbox->scblock, sps+sbox->offs_char, t);
+ move_cursor(p, +1, 0);
rerender_slide(p);
- fr->pos += tlen;
- p->cursor_pos = fr->pos;
redraw_editor(p);
- fr->empty = 0;
-#endif
}
@@ -1158,7 +1193,6 @@ static void do_backspace(struct frame *fr, struct presentation *p)
scbl = sc_block_next(scbl);
} while ( (scbl != fbox->scblock) && (scbl != NULL) );
-
rerender_slide(p);
redraw_editor(p);
}
@@ -1610,66 +1644,6 @@ static gboolean button_release_sig(GtkWidget *da, GdkEventButton *event,
}
-static void move_cursor(struct presentation *p, signed int x, signed int y)
-{
- if ( x > 0 ) {
-
- int advance = 0;
- signed int cp, cb, cl;
- struct wrap_line *line = &p->cursor_frame->lines[p->cursor_line];
- struct wrap_box *box = &line->boxes[p->cursor_box];
-
- cp = p->cursor_pos;
- cb = p->cursor_box;
- cl = p->cursor_line;
-
- if ( box->type == WRAP_BOX_PANGO ) {
-
- if ( cp+1 > box->len_chars ) {
- advance = 1;
- } else {
- cp++;
- }
-
- } else {
- cp++;
- if ( cp > 1 ) advance = 1;
- }
-
- if ( advance ) {
-
- do {
-
- cb++;
- cp = 0;
-
- if ( cb >= line->n_boxes ) {
- cl++;
- if ( cl >= p->cursor_frame->n_lines ) {
- /* Give up - could not move */
- return;
- }
- p->cursor_line = cl;
- line = &p->cursor_frame->lines[cl];
- cb = 0;
- cp = 0;
- }
-
- } while ( (line->boxes[cb].type == WRAP_BOX_SENTINEL)
- || (line->boxes[cb].type == WRAP_BOX_NOTHING)
- || !line->boxes[cb].editable );
-
- p->cursor_box = cb;
-
- }
- p->cursor_pos = cp;
-
- } else {
- move_cursor_back(p);
- }
-}
-
-
static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event,
struct presentation *p)
{
diff --git a/src/sc_parse.c b/src/sc_parse.c
index 1d5c549..51f55de 100644
--- a/src/sc_parse.c
+++ b/src/sc_parse.c
@@ -379,6 +379,21 @@ SCBlock *sc_parse(const char *sc)
}
+void sc_insert_text(SCBlock *b1, int o1, const char *t)
+{
+ size_t len = strlen(b1->contents)+1+strlen(t);
+ char *cnew = realloc(b1->contents, len);
+ char *tmp = malloc(len);
+ char *p1 = g_utf8_offset_to_pointer(cnew, o1);
+ if ( (cnew == NULL) || (tmp == NULL) ) return;
+ strcpy(tmp, p1);
+ strcpy(p1, t);
+ strcpy(p1+strlen(t), tmp);
+ free(tmp);
+ b1->contents = cnew;
+}
+
+
static void delete_from_block(SCBlock *b, int o1, int o2)
{
if ( o1 == o2 ) return; /* nothing to delete */
diff --git a/src/sc_parse.h b/src/sc_parse.h
index 020c345..b774c26 100644
--- a/src/sc_parse.h
+++ b/src/sc_parse.h
@@ -42,7 +42,8 @@ extern const char *sc_block_contents(const SCBlock *bl);
extern struct frame *sc_block_frame(const SCBlock *bl);
extern void sc_block_set_frame(SCBlock *bl, struct frame *fr);
-extern void sc_delete_text(SCBlock *b1, int p1, SCBlock *b2, int p2);
+extern void sc_insert_text(SCBlock *b1, int o1, const char *t);
+extern void sc_delete_text(SCBlock *b1, int o1, SCBlock *b2, int o2);
extern void show_sc_blocks(const SCBlock *bl);
extern void show_sc_block(const SCBlock *bl, const char *prefix);