ui/gtk/text.c

branch
newapi
changeset 174
0358f1d9c506
parent 168
1b99acacc5bb
child 253
087cc9216f28
equal deleted inserted replaced
173:809581724cc7 174:0358f1d9c506
32 32
33 #include "text.h" 33 #include "text.h"
34 #include "container.h" 34 #include "container.h"
35 35
36 36
37 #include "../common/types.h"
38
37 static void selection_handler( 39 static void selection_handler(
38 GtkTextBuffer *buf, 40 GtkTextBuffer *buf,
39 GtkTextIter *location, 41 GtkTextIter *location,
40 GtkTextMark *mark, 42 GtkTextMark *mark,
41 UiTextArea *textview) 43 UiTextArea *textview)
302 if(!mgr->event) { 304 if(!mgr->event) {
303 return; 305 return;
304 } 306 }
305 307
306 if(mgr->cur) { 308 if(mgr->cur) {
307 UcxList *elm = mgr->cur->next; 309 UiTextBufOp *elm = mgr->cur->next;
308 if(elm) { 310 if(elm) {
309 mgr->cur->next = NULL; 311 mgr->cur->next = NULL;
312 mgr->end = mgr->cur;
310 while(elm) { 313 while(elm) {
311 elm->prev = NULL; 314 elm->prev = NULL;
312 UcxList *next = elm->next; 315 UiTextBufOp *next = elm->next;
313 ui_free_textbuf_op(elm->data); 316 ui_free_textbuf_op(elm);
314 free(elm);
315 elm = next; 317 elm = next;
316 } 318 }
317 } 319 }
318 320
319 UiTextBufOp *last_op = mgr->cur->data; 321 UiTextBufOp *last_op = mgr->cur;
320 if( 322 if(
321 last_op->type == UI_TEXTBUF_INSERT && 323 last_op->type == UI_TEXTBUF_INSERT &&
322 ui_check_insertstr(last_op->text, last_op->len, text, length) == 0) 324 ui_check_insertstr(last_op->text, last_op->len, text, length) == 0)
323 { 325 {
324 // append text to last op 326 // append text to last op
339 char *dpstr = malloc(length + 1); 341 char *dpstr = malloc(length + 1);
340 memcpy(dpstr, text, length); 342 memcpy(dpstr, text, length);
341 dpstr[length] = 0; 343 dpstr[length] = 0;
342 344
343 UiTextBufOp *op = malloc(sizeof(UiTextBufOp)); 345 UiTextBufOp *op = malloc(sizeof(UiTextBufOp));
346 op->prev = NULL;
347 op->next = NULL;
344 op->type = UI_TEXTBUF_INSERT; 348 op->type = UI_TEXTBUF_INSERT;
345 op->start = gtk_text_iter_get_offset(location); 349 op->start = gtk_text_iter_get_offset(location);
346 op->end = op->start+length; 350 op->end = op->start+length;
347 op->len = length; 351 op->len = length;
348 op->text = dpstr; 352 op->text = dpstr;
349 353
350 UcxList *elm = ucx_list_append(NULL, op); 354 cx_linked_list_add(
351 mgr->cur = elm; 355 (void**)&mgr->begin,
352 mgr->begin = ucx_list_concat(mgr->begin, elm); 356 (void**)&mgr->end,
357 offsetof(UiTextBufOp, prev),
358 offsetof(UiTextBufOp, next),
359 op);
360
361 mgr->cur = op;
353 } 362 }
354 363
355 void ui_textbuf_delete( 364 void ui_textbuf_delete(
356 GtkTextBuffer *textbuffer, 365 GtkTextBuffer *textbuffer,
357 GtkTextIter *start, 366 GtkTextIter *start,
367 if(!mgr->event) { 376 if(!mgr->event) {
368 return; 377 return;
369 } 378 }
370 379
371 if(mgr->cur) { 380 if(mgr->cur) {
372 UcxList *elm = mgr->cur->next; 381 UiTextBufOp *elm = mgr->cur->next;
373 if(elm) { 382 if(elm) {
374 mgr->cur->next = NULL; 383 mgr->cur->next = NULL;
384 mgr->end = mgr->cur;
375 while(elm) { 385 while(elm) {
376 elm->prev = NULL; 386 elm->prev = NULL;
377 UcxList *next = elm->next; 387 UiTextBufOp *next = elm->next;
378 ui_free_textbuf_op(elm->data); 388 ui_free_textbuf_op(elm);
379 free(elm);
380 elm = next; 389 elm = next;
381 } 390 }
382 } 391 }
383 } 392 }
384 393
385 char *text = gtk_text_buffer_get_text(value->obj, start, end, FALSE); 394 char *text = gtk_text_buffer_get_text(value->obj, start, end, FALSE);
386 395
387 UiTextBufOp *op = malloc(sizeof(UiTextBufOp)); 396 UiTextBufOp *op = malloc(sizeof(UiTextBufOp));
397 op->prev = NULL;
398 op->next = NULL;
388 op->type = UI_TEXTBUF_DELETE; 399 op->type = UI_TEXTBUF_DELETE;
389 op->start = gtk_text_iter_get_offset(start); 400 op->start = gtk_text_iter_get_offset(start);
390 op->end = gtk_text_iter_get_offset(end); 401 op->end = gtk_text_iter_get_offset(end);
391 op->len = op->end - op->start; 402 op->len = op->end - op->start;
392 403
393 char *dpstr = malloc(op->len + 1); 404 char *dpstr = malloc(op->len + 1);
394 memcpy(dpstr, text, op->len); 405 memcpy(dpstr, text, op->len);
395 dpstr[op->len] = 0; 406 dpstr[op->len] = 0;
396 op->text = dpstr; 407 op->text = dpstr;
397 408
398 UcxList *elm = ucx_list_append(NULL, op); 409 cx_linked_list_add(
399 mgr->cur = elm; 410 (void**)&mgr->begin,
400 mgr->begin = ucx_list_concat(mgr->begin, elm); 411 (void**)&mgr->end,
412 offsetof(UiTextBufOp, prev),
413 offsetof(UiTextBufOp, next),
414 op);
415
416 mgr->cur = op;
401 } 417 }
402 418
403 UiUndoMgr* ui_create_undomgr() { 419 UiUndoMgr* ui_create_undomgr() {
404 UiUndoMgr *mgr = malloc(sizeof(UiUndoMgr)); 420 UiUndoMgr *mgr = malloc(sizeof(UiUndoMgr));
405 mgr->begin = NULL; 421 mgr->begin = NULL;
422 mgr->end = NULL;
406 mgr->cur = NULL; 423 mgr->cur = NULL;
407 mgr->length = 0; 424 mgr->length = 0;
408 mgr->event = 1; 425 mgr->event = 1;
409 return mgr; 426 return mgr;
427 }
428
429 void ui_destroy_undomgr(UiUndoMgr *mgr) {
430 UiTextBufOp *op = mgr->begin;
431 while(op) {
432 UiTextBufOp *nextOp = op->next;
433 if(op->text) {
434 free(op->text);
435 }
436 free(op);
437 op = nextOp;
438 }
439 free(mgr);
410 } 440 }
411 441
412 void ui_free_textbuf_op(UiTextBufOp *op) { 442 void ui_free_textbuf_op(UiTextBufOp *op) {
413 if(op->text) { 443 if(op->text) {
414 free(op->text); 444 free(op->text);
438 468
439 void ui_text_undo(UiText *value) { 469 void ui_text_undo(UiText *value) {
440 UiUndoMgr *mgr = value->undomgr; 470 UiUndoMgr *mgr = value->undomgr;
441 471
442 if(mgr->cur) { 472 if(mgr->cur) {
443 UiTextBufOp *op = mgr->cur->data; 473 UiTextBufOp *op = mgr->cur;
444 mgr->event = 0; 474 mgr->event = 0;
445 switch(op->type) { 475 switch(op->type) {
446 case UI_TEXTBUF_INSERT: { 476 case UI_TEXTBUF_INSERT: {
447 GtkTextIter begin; 477 GtkTextIter begin;
448 GtkTextIter end; 478 GtkTextIter end;
466 } 496 }
467 497
468 void ui_text_redo(UiText *value) { 498 void ui_text_redo(UiText *value) {
469 UiUndoMgr *mgr = value->undomgr; 499 UiUndoMgr *mgr = value->undomgr;
470 500
471 UcxList *elm = NULL; 501 UiTextBufOp *elm = NULL;
472 if(mgr->cur) { 502 if(mgr->cur) {
473 if(mgr->cur->next) { 503 if(mgr->cur->next) {
474 elm = mgr->cur->next; 504 elm = mgr->cur->next;
475 } 505 }
476 } else if(mgr->begin) { 506 } else if(mgr->begin) {
477 elm = mgr->begin; 507 elm = mgr->begin;
478 } 508 }
479 509
480 if(elm) { 510 if(elm) {
481 UiTextBufOp *op = elm->data; 511 UiTextBufOp *op = elm;
482 mgr->event = 0; 512 mgr->event = 0;
483 switch(op->type) { 513 switch(op->type) {
484 case UI_TEXTBUF_INSERT: { 514 case UI_TEXTBUF_INSERT: {
485 GtkTextIter begin; 515 GtkTextIter begin;
486 GtkTextIter end; 516 GtkTextIter end;
578 return create_textfield_var(obj, width, frameless, password, var); 608 return create_textfield_var(obj, width, frameless, password, var);
579 } 609 }
580 610
581 void ui_textfield_destroy(GtkWidget *object, UiTextField *textfield) { 611 void ui_textfield_destroy(GtkWidget *object, UiTextField *textfield) {
582 if(textfield->var) { 612 if(textfield->var) {
613 UiText *text = textfield->var->value;
614 if(text->undomgr) {
615 ui_destroy_undomgr(text->undomgr);
616 }
583 ui_destroy_boundvar(textfield->ctx, textfield->var); 617 ui_destroy_boundvar(textfield->ctx, textfield->var);
584 } 618 }
585 free(textfield); 619 free(textfield);
586 } 620 }
587 621

mercurial