Changes in uspace/app/edit/edit.c [87822ce:ec50d65e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/edit/edit.c
r87822ce rec50d65e 1 1 /* 2 * Copyright (c) 20 09Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * Copyright (c) 2012 Martin Sucha 4 4 * All rights reserved. … … 36 36 */ 37 37 38 #include <align.h> 39 #include <clipboard.h> 40 #include <errno.h> 41 #include <gfx/color.h> 42 #include <gfx/cursor.h> 43 #include <gfx/font.h> 44 #include <gfx/render.h> 45 #include <gfx/text.h> 46 #include <io/kbd_event.h> 47 #include <io/keycode.h> 48 #include <io/pos_event.h> 49 #include <io/style.h> 50 #include <macros.h> 38 51 #include <stdio.h> 39 52 #include <stdlib.h> 40 53 #include <stddef.h> 41 54 #include <stdbool.h> 55 #include <types/common.h> 56 #include <ui/control.h> 57 #include <ui/filedialog.h> 58 #include <ui/fixed.h> 59 #include <ui/label.h> 60 #include <ui/menu.h> 61 #include <ui/menubar.h> 62 #include <ui/menudd.h> 63 #include <ui/menuentry.h> 64 #include <ui/promptdialog.h> 65 #include <ui/resource.h> 66 #include <ui/ui.h> 67 #include <ui/window.h> 42 68 #include <vfs/vfs.h> 43 #include <io/console.h>44 #include <io/style.h>45 #include <io/keycode.h>46 #include <errno.h>47 #include <align.h>48 #include <macros.h>49 #include <clipboard.h>50 #include <types/common.h>51 69 52 70 #include "sheet.h" … … 63 81 * 64 82 * A rectangular area of the screen used to edit a document. Different 65 * panes can be possibly used to edit the same document. 83 * panes can be possibly used to edit the same document. This is a custom 84 * UI control. 66 85 */ 67 86 typedef struct { 87 /** Base control object */ 88 struct ui_control *control; 89 90 /** Containing window */ 91 ui_window_t *window; 92 93 /** UI resource */ 94 struct ui_resource *res; 95 96 /** Pane rectangle */ 97 gfx_rect_t rect; 98 99 /** Pane color */ 100 gfx_color_t *color; 101 102 /** Selection color */ 103 gfx_color_t *sel_color; 104 68 105 /* Pane dimensions */ 69 106 int rows, columns; … … 90 127 int ideal_column; 91 128 129 bool search_reverse; 92 130 char *previous_search; 93 131 bool previous_search_reverse; 94 132 } pane_t; 133 134 /** Text editor */ 135 typedef struct { 136 /** User interface */ 137 ui_t *ui; 138 /** Editor window */ 139 ui_window_t *window; 140 /** UI resource */ 141 ui_resource_t *ui_res; 142 /** Menu bar */ 143 ui_menu_bar_t *menubar; 144 /** Status bar */ 145 ui_label_t *status; 146 } edit_t; 95 147 96 148 /** Document … … 103 155 } doc_t; 104 156 105 static console_ctrl_t *con;157 static edit_t edit; 106 158 static doc_t doc; 107 static bool done;108 159 static pane_t pane; 109 static bool cursor_visible;110 111 static sysarg_t scr_rows;112 static sysarg_t scr_columns;113 160 114 161 #define ROW_BUF_SIZE 4096 … … 119 166 #define INFNAME_MAX_LEN 128 120 167 121 static void cursor_show(void);122 static void cursor_hide(void);123 168 static void cursor_setvis(bool visible); 124 169 … … 139 184 static char *range_get_str(spt_t const *spos, spt_t const *epos); 140 185 141 static char *prompt(char const *prompt, char const *init_value); 142 143 static void pane_text_display(void); 186 static errno_t pane_init(ui_window_t *, pane_t *); 187 static void pane_fini(pane_t *); 188 static ui_control_t *pane_ctl(pane_t *); 189 static errno_t pane_update(pane_t *); 190 static errno_t pane_text_display(pane_t *); 144 191 static void pane_row_display(void); 145 static void pane_row_range_display(int r0, int r1);146 static void pane_status_display( void);147 static void pane_caret_display( void);192 static errno_t pane_row_range_display(pane_t *, int r0, int r1); 193 static void pane_status_display(pane_t *); 194 static void pane_caret_display(pane_t *); 148 195 149 196 static void insert_char(char32_t c); … … 164 211 static void selection_delete(void); 165 212 static void selection_copy(void); 213 static void edit_cut(void); 214 static void edit_paste(void); 166 215 static void insert_clipboard_data(void); 167 216 … … 185 234 186 235 static void status_display(char const *str); 236 static errno_t edit_ui_create(edit_t *); 237 static void edit_ui_destroy(edit_t *); 238 239 static void edit_wnd_close(ui_window_t *, void *); 240 static void edit_wnd_focus(ui_window_t *, void *, unsigned); 241 static void edit_wnd_kbd_event(ui_window_t *, void *, kbd_event_t *); 242 static void edit_wnd_unfocus(ui_window_t *, void *, unsigned); 243 244 static ui_window_cb_t edit_window_cb = { 245 .close = edit_wnd_close, 246 .focus = edit_wnd_focus, 247 .kbd = edit_wnd_kbd_event, 248 .unfocus = edit_wnd_unfocus 249 }; 250 251 static void edit_menubar_activate(ui_menu_bar_t *, void *); 252 static void edit_menubar_deactivate(ui_menu_bar_t *, void *); 253 254 static ui_menu_bar_cb_t edit_menubar_cb = { 255 .activate = edit_menubar_activate, 256 .deactivate = edit_menubar_deactivate 257 }; 258 259 static void edit_file_save(ui_menu_entry_t *, void *); 260 static void edit_file_save_as(ui_menu_entry_t *, void *); 261 static void edit_file_exit(ui_menu_entry_t *, void *); 262 static void edit_edit_cut(ui_menu_entry_t *, void *); 263 static void edit_edit_copy(ui_menu_entry_t *, void *); 264 static void edit_edit_paste(ui_menu_entry_t *, void *); 265 static void edit_edit_delete(ui_menu_entry_t *, void *); 266 static void edit_edit_select_all(ui_menu_entry_t *, void *); 267 static void edit_search_find(ui_menu_entry_t *, void *); 268 static void edit_search_reverse_find(ui_menu_entry_t *, void *); 269 static void edit_search_find_next(ui_menu_entry_t *, void *); 270 static void edit_search_go_to_line(ui_menu_entry_t *, void *); 271 272 static void pane_ctl_destroy(void *); 273 static errno_t pane_ctl_paint(void *); 274 static ui_evclaim_t pane_ctl_pos_event(void *, pos_event_t *); 275 276 /** Pabe control ops */ 277 ui_control_ops_t pane_ctl_ops = { 278 .destroy = pane_ctl_destroy, 279 .paint = pane_ctl_paint, 280 .pos_event = pane_ctl_pos_event 281 }; 282 283 static void save_as_dialog_bok(ui_file_dialog_t *, void *, const char *); 284 static void save_as_dialog_bcancel(ui_file_dialog_t *, void *); 285 static void save_as_dialog_close(ui_file_dialog_t *, void *); 286 287 static ui_file_dialog_cb_t save_as_dialog_cb = { 288 .bok = save_as_dialog_bok, 289 .bcancel = save_as_dialog_bcancel, 290 .close = save_as_dialog_close 291 }; 292 293 static void go_to_line_dialog_bok(ui_prompt_dialog_t *, void *, const char *); 294 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *, void *); 295 static void go_to_line_dialog_close(ui_prompt_dialog_t *, void *); 296 297 static ui_prompt_dialog_cb_t go_to_line_dialog_cb = { 298 .bok = go_to_line_dialog_bok, 299 .bcancel = go_to_line_dialog_bcancel, 300 .close = go_to_line_dialog_close 301 }; 302 303 static void search_dialog_bok(ui_prompt_dialog_t *, void *, const char *); 304 static void search_dialog_bcancel(ui_prompt_dialog_t *, void *); 305 static void search_dialog_close(ui_prompt_dialog_t *, void *); 306 307 static ui_prompt_dialog_cb_t search_dialog_cb = { 308 .bok = search_dialog_bok, 309 .bcancel = search_dialog_bcancel, 310 .close = search_dialog_close 311 }; 187 312 188 313 int main(int argc, char *argv[]) 189 314 { 190 cons_event_t ev;191 315 bool new_file; 192 316 errno_t rc; 193 317 194 con = console_init(stdin, stdout);195 console_clear(con);196 197 console_get_size(con, &scr_columns, &scr_rows);198 199 pane.rows = scr_rows - 1;200 pane.columns = scr_columns;201 318 pane.sh_row = 1; 202 319 pane.sh_column = 1; … … 234 351 /* Move to beginning of file. */ 235 352 pt_get_sof(&sof); 353 354 /* Create UI */ 355 rc = edit_ui_create(&edit); 356 if (rc != EOK) 357 return 1; 358 236 359 caret_move(sof, true, true); 237 360 238 361 /* Initial display */ 239 cursor_visible = true; 240 241 cursor_hide(); 242 console_clear(con); 243 pane_text_display(); 244 pane_status_display(); 362 rc = ui_window_paint(edit.window); 363 if (rc != EOK) { 364 printf("Error painting window.\n"); 365 return rc; 366 } 367 368 pane_status_display(&pane); 245 369 if (new_file && doc.file_name != NULL) 246 370 status_display("File not found. Starting empty file."); 247 pane_caret_display(); 248 cursor_show(); 249 250 done = false; 251 252 while (!done) { 253 rc = console_get_event(con, &ev); 254 if (rc != EOK) 255 break; 256 257 pane.rflags = 0; 258 259 switch (ev.type) { 260 case CEV_KEY: 261 pane.keymod = ev.ev.key.mods; 262 if (ev.ev.key.type == KEY_PRESS) 263 key_handle_press(&ev.ev.key); 264 break; 265 case CEV_POS: 266 pos_handle(&ev.ev.pos); 267 break; 268 } 269 270 /* Redraw as necessary. */ 271 272 cursor_hide(); 273 274 if (pane.rflags & REDRAW_TEXT) 275 pane_text_display(); 276 if (pane.rflags & REDRAW_ROW) 277 pane_row_display(); 278 if (pane.rflags & REDRAW_STATUS) 279 pane_status_display(); 280 if (pane.rflags & REDRAW_CARET) 281 pane_caret_display(); 282 283 cursor_show(); 284 } 285 286 console_clear(con); 287 371 pane_caret_display(&pane); 372 cursor_setvis(true); 373 374 ui_run(edit.ui); 375 376 edit_ui_destroy(&edit); 288 377 return 0; 378 } 379 380 /** Create text editor UI. 381 * 382 * @param edit Editor 383 * @return EOK on success or an error code 384 */ 385 static errno_t edit_ui_create(edit_t *edit) 386 { 387 errno_t rc; 388 ui_wnd_params_t params; 389 ui_fixed_t *fixed = NULL; 390 ui_menu_t *mfile = NULL; 391 ui_menu_t *medit = NULL; 392 ui_menu_entry_t *msave = NULL; 393 ui_menu_entry_t *msaveas = NULL; 394 ui_menu_entry_t *mfsep = NULL; 395 ui_menu_entry_t *mexit = NULL; 396 ui_menu_entry_t *mcut = NULL; 397 ui_menu_entry_t *mcopy = NULL; 398 ui_menu_entry_t *mpaste = NULL; 399 ui_menu_entry_t *mdelete = NULL; 400 ui_menu_entry_t *mesep = NULL; 401 ui_menu_entry_t *mselall = NULL; 402 ui_menu_t *msearch = NULL; 403 ui_menu_entry_t *mfind = NULL; 404 ui_menu_entry_t *mfindr = NULL; 405 ui_menu_entry_t *mfindn = NULL; 406 ui_menu_entry_t *mssep = NULL; 407 ui_menu_entry_t *mgoto = NULL; 408 gfx_rect_t arect; 409 gfx_rect_t rect; 410 411 rc = ui_create(UI_CONSOLE_DEFAULT, &edit->ui); 412 if (rc != EOK) { 413 printf("Error creating UI on display %s.\n", 414 UI_CONSOLE_DEFAULT); 415 goto error; 416 } 417 418 ui_wnd_params_init(¶ms); 419 params.caption = "Text Editor"; 420 params.style &= ~ui_wds_decorated; 421 params.placement = ui_wnd_place_full_screen; 422 423 rc = ui_window_create(edit->ui, ¶ms, &edit->window); 424 if (rc != EOK) { 425 printf("Error creating window.\n"); 426 goto error; 427 } 428 429 ui_window_set_cb(edit->window, &edit_window_cb, (void *) edit); 430 431 edit->ui_res = ui_window_get_res(edit->window); 432 433 rc = ui_fixed_create(&fixed); 434 if (rc != EOK) { 435 printf("Error creating fixed layout.\n"); 436 return rc; 437 } 438 439 rc = ui_menu_bar_create(edit->ui, edit->window, &edit->menubar); 440 if (rc != EOK) { 441 printf("Error creating menu bar.\n"); 442 return rc; 443 } 444 445 ui_menu_bar_set_cb(edit->menubar, &edit_menubar_cb, (void *) edit); 446 447 rc = ui_menu_dd_create(edit->menubar, "~F~ile", NULL, &mfile); 448 if (rc != EOK) { 449 printf("Error creating menu.\n"); 450 return rc; 451 } 452 453 rc = ui_menu_entry_create(mfile, "~S~ave", "Ctrl-S", &msave); 454 if (rc != EOK) { 455 printf("Error creating menu.\n"); 456 return rc; 457 } 458 459 ui_menu_entry_set_cb(msave, edit_file_save, (void *) edit); 460 461 rc = ui_menu_entry_create(mfile, "Save ~A~s", "Ctrl-E", &msaveas); 462 if (rc != EOK) { 463 printf("Error creating menu.\n"); 464 return rc; 465 } 466 467 ui_menu_entry_set_cb(msaveas, edit_file_save_as, (void *) edit); 468 469 rc = ui_menu_entry_sep_create(mfile, &mfsep); 470 if (rc != EOK) { 471 printf("Error creating menu.\n"); 472 return rc; 473 } 474 475 rc = ui_menu_entry_create(mfile, "E~x~it", "Ctrl-Q", &mexit); 476 if (rc != EOK) { 477 printf("Error creating menu.\n"); 478 return rc; 479 } 480 481 ui_menu_entry_set_cb(mexit, edit_file_exit, (void *) edit); 482 483 rc = ui_menu_dd_create(edit->menubar, "~E~dit", NULL, &medit); 484 if (rc != EOK) { 485 printf("Error creating menu.\n"); 486 return rc; 487 } 488 489 rc = ui_menu_entry_create(medit, "Cu~t~", "Ctrl-X", &mcut); 490 if (rc != EOK) { 491 printf("Error creating menu.\n"); 492 return rc; 493 } 494 495 ui_menu_entry_set_cb(mcut, edit_edit_cut, (void *) edit); 496 497 rc = ui_menu_entry_create(medit, "~C~opy", "Ctrl-C", &mcopy); 498 if (rc != EOK) { 499 printf("Error creating menu.\n"); 500 return rc; 501 } 502 503 ui_menu_entry_set_cb(mcopy, edit_edit_copy, (void *) edit); 504 505 rc = ui_menu_entry_create(medit, "~P~aste", "Ctrl-V", &mpaste); 506 if (rc != EOK) { 507 printf("Error creating menu.\n"); 508 return rc; 509 } 510 511 ui_menu_entry_set_cb(mpaste, edit_edit_paste, (void *) edit); 512 513 rc = ui_menu_entry_create(medit, "~D~elete", "Del", &mdelete); 514 if (rc != EOK) { 515 printf("Error creating menu.\n"); 516 return rc; 517 } 518 519 ui_menu_entry_set_cb(mdelete, edit_edit_delete, (void *) edit); 520 521 rc = ui_menu_entry_sep_create(medit, &mesep); 522 if (rc != EOK) { 523 printf("Error creating menu.\n"); 524 return rc; 525 } 526 527 rc = ui_menu_entry_create(medit, "Select ~A~ll", "Ctrl-A", &mselall); 528 if (rc != EOK) { 529 printf("Error creating menu.\n"); 530 return rc; 531 } 532 533 ui_menu_entry_set_cb(mselall, edit_edit_select_all, (void *) edit); 534 535 rc = ui_menu_dd_create(edit->menubar, "~S~earch", NULL, &msearch); 536 if (rc != EOK) { 537 printf("Error creating menu.\n"); 538 return rc; 539 } 540 541 rc = ui_menu_entry_create(msearch, "~F~ind", "Ctrl-F", &mfind); 542 if (rc != EOK) { 543 printf("Error creating menu.\n"); 544 return rc; 545 } 546 547 ui_menu_entry_set_cb(mfind, edit_search_find, (void *) edit); 548 549 rc = ui_menu_entry_create(msearch, "~R~everse Find", "Ctrl-Shift-F", &mfindr); 550 if (rc != EOK) { 551 printf("Error creating menu.\n"); 552 return rc; 553 } 554 555 ui_menu_entry_set_cb(mfindr, edit_search_reverse_find, (void *) edit); 556 557 rc = ui_menu_entry_create(msearch, "Find ~N~ext", "Ctrl-N", &mfindn); 558 if (rc != EOK) { 559 printf("Error creating menu.\n"); 560 return rc; 561 } 562 563 ui_menu_entry_set_cb(mfindn, edit_search_find_next, (void *) edit); 564 565 rc = ui_menu_entry_sep_create(msearch, &mssep); 566 if (rc != EOK) { 567 printf("Error creating menu.\n"); 568 return rc; 569 } 570 571 rc = ui_menu_entry_create(msearch, "Go To ~L~ine", "Ctrl-L", &mgoto); 572 if (rc != EOK) { 573 printf("Error creating menu.\n"); 574 return rc; 575 } 576 577 ui_menu_entry_set_cb(mgoto, edit_search_go_to_line, (void *) edit); 578 579 ui_window_get_app_rect(edit->window, &arect); 580 581 rect.p0 = arect.p0; 582 rect.p1.x = arect.p1.x; 583 rect.p1.y = arect.p0.y + 1; 584 ui_menu_bar_set_rect(edit->menubar, &rect); 585 586 rc = ui_fixed_add(fixed, ui_menu_bar_ctl(edit->menubar)); 587 if (rc != EOK) { 588 printf("Error adding control to layout.\n"); 589 return rc; 590 } 591 592 rc = pane_init(edit->window, &pane); 593 if (rc != EOK) { 594 printf("Error initializing pane.\n"); 595 return rc; 596 } 597 598 rc = ui_fixed_add(fixed, pane_ctl(&pane)); 599 if (rc != EOK) { 600 printf("Error adding control to layout.\n"); 601 return rc; 602 } 603 604 rc = ui_label_create(edit->ui_res, "", &edit->status); 605 if (rc != EOK) { 606 printf("Error creating menu bar.\n"); 607 return rc; 608 } 609 610 rect.p0.x = arect.p0.x; 611 rect.p0.y = arect.p1.y - 1; 612 rect.p1 = arect.p1; 613 ui_label_set_rect(edit->status, &rect); 614 615 rc = ui_fixed_add(fixed, ui_label_ctl(edit->status)); 616 if (rc != EOK) { 617 printf("Error adding control to layout.\n"); 618 return rc; 619 } 620 621 ui_window_add(edit->window, ui_fixed_ctl(fixed)); 622 return EOK; 623 error: 624 if (edit->window != NULL) 625 ui_window_destroy(edit->window); 626 if (edit->ui != NULL) 627 ui_destroy(edit->ui); 628 return rc; 629 } 630 631 /** Destroy text editor UI. 632 * 633 * @param edit Editor 634 */ 635 static void edit_ui_destroy(edit_t *edit) 636 { 637 ui_window_destroy(edit->window); 638 ui_destroy(edit->ui); 289 639 } 290 640 … … 309 659 } 310 660 311 static void cursor_show(void)312 {313 cursor_setvis(true);314 }315 316 static void cursor_hide(void)317 {318 cursor_setvis(false);319 }320 321 661 static void cursor_setvis(bool visible) 322 662 { 323 if (cursor_visible != visible) { 324 console_cursor_visibility(con, visible); 325 cursor_visible = visible; 326 } 663 gfx_context_t *gc = ui_window_get_gc(edit.window); 664 665 (void) gfx_cursor_set_visible(gc, visible); 327 666 } 328 667 … … 400 739 switch (ev->key) { 401 740 case KC_Q: 402 done = true;741 ui_quit(edit.ui); 403 742 break; 404 743 case KC_S: … … 415 754 break; 416 755 case KC_V: 417 selection_delete(); 418 insert_clipboard_data(); 419 pane.rflags |= REDRAW_TEXT; 420 caret_update(); 756 edit_paste(); 421 757 break; 422 758 case KC_X: 423 selection_copy(); 424 selection_delete(); 425 pane.rflags |= REDRAW_TEXT; 426 caret_update(); 759 edit_cut(); 427 760 break; 428 761 case KC_A: … … 490 823 491 824 if (ev->type == POS_PRESS && ev->vpos < (unsigned)pane.rows) { 492 bc.row = pane.sh_row + ev->vpos ;493 bc.column = pane.sh_column + ev->hpos ;825 bc.row = pane.sh_row + ev->vpos - pane.rect.p0.y; 826 bc.column = pane.sh_column + ev->hpos - pane.rect.p0.x; 494 827 sheet_get_cell_pt(doc.sh, &bc, dir_before, &pt); 495 828 … … 497 830 498 831 caret_move(pt, select, true); 832 pane_update(&pane); 499 833 } 500 834 } … … 606 940 } 607 941 608 /** Change document name and save. */942 /** Open Save As dialog. */ 609 943 static void file_save_as(void) 610 944 { 611 945 const char *old_fname = (doc.file_name != NULL) ? doc.file_name : ""; 612 char *fname; 613 614 fname = prompt("Save As", old_fname); 615 if (fname == NULL) { 616 status_display("Save cancelled."); 946 ui_file_dialog_params_t fdparams; 947 ui_file_dialog_t *dialog; 948 errno_t rc; 949 950 ui_file_dialog_params_init(&fdparams); 951 fdparams.caption = "Save As"; 952 fdparams.ifname = old_fname; 953 954 rc = ui_file_dialog_create(edit.ui, &fdparams, &dialog); 955 if (rc != EOK) { 956 printf("Error creating message dialog.\n"); 617 957 return; 618 958 } 619 959 620 errno_t rc = file_save(fname); 621 if (rc != EOK) 622 return; 623 624 if (doc.file_name != NULL) 625 free(doc.file_name); 626 doc.file_name = fname; 627 } 628 629 /** Ask for a string. */ 630 static char *prompt(char const *prompt, char const *init_value) 631 { 632 cons_event_t ev; 633 kbd_event_t *kev; 634 char *str; 635 char32_t buffer[INFNAME_MAX_LEN + 1]; 636 int max_len; 637 int nc; 638 bool done; 639 errno_t rc; 640 641 asprintf(&str, "%s: %s", prompt, init_value); 642 status_display(str); 643 console_set_pos(con, 1 + str_length(str), scr_rows - 1); 644 free(str); 645 646 console_set_style(con, STYLE_INVERTED); 647 648 max_len = min(INFNAME_MAX_LEN, scr_columns - 4 - str_length(prompt)); 649 str_to_wstr(buffer, max_len + 1, init_value); 650 nc = wstr_length(buffer); 651 done = false; 652 653 while (!done) { 654 rc = console_get_event(con, &ev); 655 if (rc != EOK) 656 return NULL; 657 658 if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS) { 659 kev = &ev.ev.key; 660 661 /* Handle key press. */ 662 if ((kev->mods & (KM_CTRL | KM_ALT)) == 0) { 663 switch (kev->key) { 664 case KC_ESCAPE: 665 return NULL; 666 case KC_BACKSPACE: 667 if (nc > 0) { 668 putchar('\b'); 669 console_flush(con); 670 --nc; 671 } 672 break; 673 case KC_ENTER: 674 done = true; 675 break; 676 default: 677 if (kev->c >= 32 && nc < max_len) { 678 putuchar(kev->c); 679 console_flush(con); 680 buffer[nc++] = kev->c; 681 } 682 break; 683 } 684 } 685 } 686 } 687 688 buffer[nc] = '\0'; 689 str = wstr_to_astr(buffer); 690 691 console_set_style(con, STYLE_NORMAL); 692 693 return str; 960 ui_file_dialog_set_cb(dialog, &save_as_dialog_cb, &edit); 694 961 } 695 962 … … 726 993 727 994 bcnt -= off; 728 mem cpy(buf, buf + off, bcnt);995 memmove(buf, buf + off, bcnt); 729 996 730 997 insert_char(c); … … 808 1075 } 809 1076 810 static void pane_text_display(void) 811 { 1077 /** Initialize pane. 1078 * 1079 * TODO: Replace with pane_create() that allocates the pane. 1080 * 1081 * @param window Editor window 1082 * @param pane Pane 1083 * @return EOK on success or an error code 1084 */ 1085 static errno_t pane_init(ui_window_t *window, pane_t *pane) 1086 { 1087 errno_t rc; 1088 gfx_rect_t arect; 1089 1090 pane->control = NULL; 1091 pane->color = NULL; 1092 pane->sel_color = NULL; 1093 1094 rc = ui_control_new(&pane_ctl_ops, (void *) pane, &pane->control); 1095 if (rc != EOK) 1096 goto error; 1097 1098 rc = gfx_color_new_ega(0x07, &pane->color); 1099 if (rc != EOK) 1100 goto error; 1101 1102 rc = gfx_color_new_ega(0x1e, &pane->sel_color); 1103 if (rc != EOK) 1104 goto error; 1105 1106 pane->res = ui_window_get_res(window); 1107 pane->window = window; 1108 1109 ui_window_get_app_rect(window, &arect); 1110 pane->rect.p0.x = arect.p0.x; 1111 pane->rect.p0.y = arect.p0.y + 1; 1112 pane->rect.p1.x = arect.p1.x; 1113 pane->rect.p1.y = arect.p1.y - 1; 1114 1115 pane->columns = pane->rect.p1.x - pane->rect.p0.x; 1116 pane->rows = pane->rect.p1.y - pane->rect.p0.y; 1117 1118 return EOK; 1119 error: 1120 if (pane->control != NULL) { 1121 ui_control_delete(pane->control); 1122 pane->control = NULL; 1123 } 1124 1125 if (pane->color != NULL) { 1126 gfx_color_delete(pane->color); 1127 pane->color = NULL; 1128 } 1129 1130 return rc; 1131 } 1132 1133 /** Finalize pane. 1134 * 1135 * TODO: Replace with pane_destroy() that deallocates the pane. 1136 * 1137 * @param pane Pane 1138 */ 1139 static void pane_fini(pane_t *pane) 1140 { 1141 gfx_color_delete(pane->color); 1142 pane->color = NULL; 1143 gfx_color_delete(pane->sel_color); 1144 pane->sel_color = NULL; 1145 ui_control_delete(pane->control); 1146 pane->control = NULL; 1147 } 1148 1149 /** Return base control object for a pane. 1150 * 1151 * @param pane Pane 1152 * @return Base UI cntrol 1153 */ 1154 static ui_control_t *pane_ctl(pane_t *pane) 1155 { 1156 return pane->control; 1157 } 1158 1159 /** Repaint parts of pane that need updating. 1160 * 1161 * @param pane Pane 1162 * @return EOK on succes or an error code 1163 */ 1164 static errno_t pane_update(pane_t *pane) 1165 { 1166 errno_t rc; 1167 1168 if (pane->rflags & REDRAW_TEXT) { 1169 rc = pane_text_display(pane); 1170 if (rc != EOK) 1171 return rc; 1172 } 1173 1174 if (pane->rflags & REDRAW_ROW) 1175 pane_row_display(); 1176 1177 if (pane->rflags & REDRAW_STATUS) 1178 pane_status_display(pane); 1179 1180 if (pane->rflags & REDRAW_CARET) 1181 pane_caret_display(pane); 1182 1183 pane->rflags &= ~(REDRAW_TEXT | REDRAW_ROW | REDRAW_STATUS | 1184 REDRAW_CARET); 1185 return EOK; 1186 } 1187 1188 /** Display pane text. 1189 * 1190 * @param pane Pane 1191 * @return EOK on success or an error code 1192 */ 1193 static errno_t pane_text_display(pane_t *pane) 1194 { 1195 gfx_rect_t rect; 1196 gfx_context_t *gc; 1197 errno_t rc; 812 1198 int sh_rows, rows; 813 1199 814 1200 sheet_get_num_rows(doc.sh, &sh_rows); 815 rows = min(sh_rows - pane .sh_row + 1, pane.rows);1201 rows = min(sh_rows - pane->sh_row + 1, pane->rows); 816 1202 817 1203 /* Draw rows from the sheet. */ 818 1204 819 console_set_pos(con, 0, 0); 820 pane_row_range_display(0, rows); 1205 rc = pane_row_range_display(pane, 0, rows); 1206 if (rc != EOK) 1207 return rc; 821 1208 822 1209 /* Clear the remaining rows if file is short. */ 823 1210 824 int i; 825 sysarg_t j; 826 for (i = rows; i < pane.rows; ++i) { 827 console_set_pos(con, 0, i); 828 for (j = 0; j < scr_columns; ++j) 829 putchar(' '); 830 console_flush(con); 831 } 832 833 pane.rflags |= (REDRAW_STATUS | REDRAW_CARET); 834 pane.rflags &= ~REDRAW_ROW; 1211 gc = ui_window_get_gc(pane->window); 1212 1213 rc = gfx_set_color(gc, pane->color); 1214 if (rc != EOK) 1215 goto error; 1216 1217 rect.p0.x = pane->rect.p0.x; 1218 rect.p0.y = pane->rect.p0.y + rows; 1219 rect.p1.x = pane->rect.p1.x; 1220 rect.p1.y = pane->rect.p1.y; 1221 1222 rc = gfx_fill_rect(gc, &rect); 1223 if (rc != EOK) 1224 goto error; 1225 1226 pane->rflags &= ~REDRAW_ROW; 1227 return EOK; 1228 error: 1229 return rc; 835 1230 } 836 1231 … … 846 1241 847 1242 ridx = coord.row - pane.sh_row; 848 pane_row_range_display(ridx, ridx + 1);1243 (void) pane_row_range_display(&pane, ridx, ridx + 1); 849 1244 pane.rflags |= (REDRAW_STATUS | REDRAW_CARET); 850 1245 } 851 1246 852 static void pane_row_range_display(int r0, int r1) 853 { 854 int i, j, fill; 1247 /** Display a range of rows of text. 1248 * 1249 * @param r0 Start row (inclusive) 1250 * @param r1 End row (exclusive) 1251 * @return EOk on success or an error code 1252 */ 1253 static errno_t pane_row_range_display(pane_t *pane, int r0, int r1) 1254 { 1255 int i, fill; 855 1256 spt_t rb, re, dep, pt; 856 1257 coord_t rbc, rec; 857 1258 char row_buf[ROW_BUF_SIZE]; 1259 char cbuf[STR_BOUNDS(1) + 1]; 858 1260 char32_t c; 859 1261 size_t pos, size; 1262 size_t cpos; 860 1263 int s_column; 861 1264 coord_t csel_start, csel_end, ctmp; 1265 gfx_font_t *font; 1266 gfx_context_t *gc; 1267 gfx_text_fmt_t fmt; 1268 gfx_coord2_t tpos; 1269 gfx_rect_t rect; 1270 errno_t rc; 1271 1272 font = ui_resource_get_font(edit.ui_res); 1273 gc = ui_window_get_gc(edit.window); 1274 1275 gfx_text_fmt_init(&fmt); 1276 fmt.font = font; 1277 fmt.color = pane->color; 862 1278 863 1279 /* Determine selection start and end. */ 864 1280 865 tag_get_pt(&pane .sel_start, &pt);1281 tag_get_pt(&pane->sel_start, &pt); 866 1282 spt_get_coord(&pt, &csel_start); 867 1283 868 tag_get_pt(&pane .caret_pos, &pt);1284 tag_get_pt(&pane->caret_pos, &pt); 869 1285 spt_get_coord(&pt, &csel_end); 870 1286 … … 877 1293 /* Draw rows from the sheet. */ 878 1294 879 console_set_pos(con, 0, 0);880 1295 for (i = r0; i < r1; ++i) { 1296 tpos.x = pane->rect.p0.x; 1297 tpos.y = pane->rect.p0.y + i; 1298 881 1299 /* Starting point for row display */ 882 rbc.row = pane .sh_row + i;883 rbc.column = pane .sh_column;1300 rbc.row = pane->sh_row + i; 1301 rbc.column = pane->sh_column; 884 1302 sheet_get_cell_pt(doc.sh, &rbc, dir_before, &rb); 885 1303 886 1304 /* Ending point for row display */ 887 rec.row = pane .sh_row + i;888 rec.column = pane .sh_column + pane.columns;1305 rec.row = pane->sh_row + i; 1306 rec.column = pane->sh_column + pane->columns; 889 1307 sheet_get_cell_pt(doc.sh, &rec, dir_before, &re); 890 1308 … … 896 1314 if (coord_cmp(&csel_start, &rbc) <= 0 && 897 1315 coord_cmp(&rbc, &csel_end) < 0) { 898 console_flush(con); 899 console_set_style(con, STYLE_SELECTED); 900 console_flush(con); 1316 fmt.color = pane->sel_color; 901 1317 } 902 1318 903 console_set_pos(con, 0, i);904 1319 size = str_size(row_buf); 905 1320 pos = 0; 906 s_column = pane .sh_column;1321 s_column = pane->sh_column; 907 1322 while (pos < size) { 908 if ((csel_start.row == rbc.row) && (csel_start.column == s_column)) { 909 console_flush(con); 910 console_set_style(con, STYLE_SELECTED); 911 console_flush(con); 912 } 913 914 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) { 915 console_flush(con); 916 console_set_style(con, STYLE_NORMAL); 917 console_flush(con); 918 } 1323 if ((csel_start.row == rbc.row) && (csel_start.column == s_column)) 1324 fmt.color = pane->sel_color; 1325 1326 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) 1327 fmt.color = pane->color; 919 1328 920 1329 c = str_decode(row_buf, &pos, size); 921 1330 if (c != '\t') { 922 printf("%lc", (wint_t) c); 1331 cpos = 0; 1332 rc = chr_encode(c, cbuf, &cpos, sizeof(cbuf)); 1333 if (rc != EOK) 1334 return rc; 1335 1336 rc = gfx_puttext(&tpos, &fmt, cbuf); 1337 if (rc != EOK) 1338 return rc; 1339 923 1340 s_column += 1; 1341 tpos.x++; 924 1342 } else { 925 1343 fill = 1 + ALIGN_UP(s_column, TAB_WIDTH) - 926 1344 s_column; 927 1345 928 for (j = 0; j < fill; ++j) 929 putchar(' '); 1346 rc = gfx_set_color(gc, fmt.color); 1347 if (rc != EOK) 1348 return rc; 1349 1350 rect.p0.x = tpos.x; 1351 rect.p0.y = tpos.y; 1352 rect.p1.x = tpos.x + fill; 1353 rect.p1.y = tpos.y + 1; 1354 1355 rc = gfx_fill_rect(gc, &rect); 1356 if (rc != EOK) 1357 return rc; 1358 930 1359 s_column += fill; 1360 tpos.x += fill; 931 1361 } 932 1362 } 933 1363 934 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) { 935 console_flush(con); 936 console_set_style(con, STYLE_NORMAL); 937 console_flush(con); 938 } 1364 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) 1365 fmt.color = pane->color; 939 1366 940 1367 /* Fill until the end of display area. */ 941 1368 942 if ((unsigned)s_column - 1 < scr_columns) 943 fill = scr_columns - (s_column - 1); 944 else 945 fill = 0; 946 947 for (j = 0; j < fill; ++j) 948 putchar(' '); 949 console_flush(con); 950 console_set_style(con, STYLE_NORMAL); 951 } 952 953 pane.rflags |= REDRAW_CARET; 954 } 955 956 /** Display pane status in the status line. */ 957 static void pane_status_display(void) 1369 rc = gfx_set_color(gc, fmt.color); 1370 if (rc != EOK) 1371 return rc; 1372 1373 rect.p0.x = tpos.x; 1374 rect.p0.y = tpos.y; 1375 rect.p1.x = pane->rect.p1.x; 1376 rect.p1.y = tpos.y + 1; 1377 1378 rc = gfx_fill_rect(gc, &rect); 1379 if (rc != EOK) 1380 return rc; 1381 } 1382 1383 return EOK; 1384 } 1385 1386 /** Display pane status in the status line. 1387 * 1388 * @param pane Pane 1389 */ 1390 static void pane_status_display(pane_t *pane) 958 1391 { 959 1392 spt_t caret_pt; … … 964 1397 char *text; 965 1398 size_t n; 966 int pos;967 1399 size_t nextra; 968 1400 size_t fnw; 969 1401 970 tag_get_pt(&pane .caret_pos, &caret_pt);1402 tag_get_pt(&pane->caret_pos, &caret_pt); 971 1403 spt_get_coord(&caret_pt, &coord); 972 1404 … … 987 1419 return; 988 1420 989 console_set_pos(con, 0, scr_rows - 1);990 console_set_style(con, STYLE_INVERTED);991 992 1421 /* 993 1422 * Make sure the status fits on the screen. This loop should … … 995 1424 */ 996 1425 while (true) { 997 int rc = asprintf(&text, " %d, %d (%d): File '%s'. Ctrl-Q Quit Ctrl-S Save"998 " Ctrl-E Save As", coord.row, coord.column, last_row, fname);1426 int rc = asprintf(&text, "%d, %d (%d): File '%s'. Ctrl-Q Quit " 1427 "F10 Menu", coord.row, coord.column, last_row, fname); 999 1428 if (rc < 0) { 1000 1429 n = 0; … … 1004 1433 /* If it already fits, we're done */ 1005 1434 n = str_width(text); 1006 if ( n <= scr_columns - 2)1435 if ((int)n <= pane->columns - 2) 1007 1436 break; 1008 1437 1009 1438 /* Compute number of excess characters */ 1010 nextra = n - ( scr_columns - 2);1439 nextra = n - (pane->columns - 2); 1011 1440 /** With of the file name part */ 1012 1441 fnw = str_width(fname); … … 1016 1445 * just give up and print a blank status. 1017 1446 */ 1018 if (nextra > fnw - 2) 1447 if (nextra > fnw - 2) { 1448 text[0] = '\0'; 1019 1449 goto finish; 1450 } 1020 1451 1021 1452 /* Compute position where we overwrite with '..\0' */ … … 1034 1465 } 1035 1466 1036 printf("%s", text); 1467 finish: 1468 (void) ui_label_set_text(edit.status, text); 1469 (void) ui_label_paint(edit.status); 1037 1470 free(text); 1038 1471 free(fname); 1039 finish: 1040 /* Fill the rest of the line */ 1041 pos = scr_columns - 1 - n; 1042 printf("%*s", pos, ""); 1043 console_flush(con); 1044 console_set_style(con, STYLE_NORMAL); 1045 1046 pane.rflags |= REDRAW_CARET; 1047 } 1048 1049 /** Set cursor to reflect position of the caret. */ 1050 static void pane_caret_display(void) 1472 } 1473 1474 /** Set cursor to reflect position of the caret. 1475 * 1476 * @param pane Pane 1477 */ 1478 static void pane_caret_display(pane_t *pane) 1051 1479 { 1052 1480 spt_t caret_pt; 1053 1481 coord_t coord; 1054 1055 tag_get_pt(&pane.caret_pos, &caret_pt); 1482 gfx_coord2_t pos; 1483 gfx_context_t *gc; 1484 1485 tag_get_pt(&pane->caret_pos, &caret_pt); 1056 1486 1057 1487 spt_get_coord(&caret_pt, &coord); 1058 console_set_pos(con, coord.column - pane.sh_column, 1059 coord.row - pane.sh_row); 1488 1489 gc = ui_window_get_gc(edit.window); 1490 pos.x = pane->rect.p0.x + coord.column - pane->sh_column; 1491 pos.y = pane->rect.p0.y + coord.row - pane->sh_row; 1492 1493 (void) gfx_cursor_set_pos(gc, &pos); 1494 } 1495 1496 /** Destroy pane control. 1497 * 1498 * @param arg Argument (pane_t *) 1499 */ 1500 static void pane_ctl_destroy(void *arg) 1501 { 1502 pane_t *pane = (pane_t *)arg; 1503 1504 pane_fini(pane); 1505 } 1506 1507 /** Paint pane control. 1508 * 1509 * @param arg Argument (pane_t *) 1510 */ 1511 static errno_t pane_ctl_paint(void *arg) 1512 { 1513 pane_t *pane = (pane_t *)arg; 1514 gfx_context_t *gc; 1515 errno_t rc; 1516 1517 gc = ui_window_get_gc(pane->window); 1518 1519 rc = pane_text_display(pane); 1520 if (rc != EOK) 1521 goto error; 1522 1523 rc = gfx_update(gc); 1524 if (rc != EOK) 1525 goto error; 1526 1527 error: 1528 return rc; 1529 } 1530 1531 /** Handle pane control position event. 1532 * 1533 * @param arg Argument (pane_t *) 1534 * @param event Position event 1535 */ 1536 static ui_evclaim_t pane_ctl_pos_event(void *arg, pos_event_t *event) 1537 { 1538 gfx_coord2_t pos; 1539 1540 pos.x = event->hpos; 1541 pos.y = event->vpos; 1542 1543 if (!gfx_pix_inside_rect(&pos, &pane.rect)) 1544 return ui_unclaimed; 1545 1546 pos_handle(event); 1547 (void) gfx_update(ui_window_get_gc(edit.window)); 1548 return ui_claimed; 1060 1549 } 1061 1550 … … 1270 1759 static void caret_go_to_line_ask(void) 1271 1760 { 1272 char *sline; 1273 1274 sline = prompt("Go to line", ""); 1275 if (sline == NULL) { 1276 status_display("Go to line cancelled."); 1761 ui_prompt_dialog_params_t pdparams; 1762 ui_prompt_dialog_t *dialog; 1763 errno_t rc; 1764 1765 ui_prompt_dialog_params_init(&pdparams); 1766 pdparams.caption = "Go To Line"; 1767 pdparams.prompt = "Line Number"; 1768 1769 rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog); 1770 if (rc != EOK) { 1771 printf("Error creating prompt dialog.\n"); 1277 1772 return; 1278 1773 } 1279 1774 1280 char *endptr; 1281 int line = strtol(sline, &endptr, 10); 1282 if (*endptr != '\0') { 1283 free(sline); 1284 status_display("Invalid number entered."); 1285 return; 1286 } 1287 free(sline); 1288 1289 caret_move_absolute(line, pane.ideal_column, dir_before, false); 1775 ui_prompt_dialog_set_cb(dialog, &go_to_line_dialog_cb, &edit); 1290 1776 } 1291 1777 … … 1344 1830 static void search_prompt(bool reverse) 1345 1831 { 1346 char *pattern; 1347 1348 const char *prompt_text = "Find next"; 1349 if (reverse) 1350 prompt_text = "Find previous"; 1351 1352 const char *default_value = ""; 1832 ui_prompt_dialog_params_t pdparams; 1833 ui_prompt_dialog_t *dialog; 1834 errno_t rc; 1835 1836 ui_prompt_dialog_params_init(&pdparams); 1837 pdparams.caption = reverse ? "Reverse Search" : "Search"; 1838 pdparams.prompt = "Search text"; 1839 pdparams.itext = ""; 1840 1353 1841 if (pane.previous_search) 1354 default_value= pane.previous_search;1355 1356 pattern = prompt(prompt_text, default_value);1357 if ( pattern == NULL) {1358 status_display("Search cancelled.");1842 pdparams.itext = pane.previous_search; 1843 1844 rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog); 1845 if (rc != EOK) { 1846 printf("Error creating prompt dialog.\n"); 1359 1847 return; 1360 1848 } 1361 1849 1362 if (pane.previous_search) 1363 free(pane.previous_search); 1364 pane.previous_search = pattern; 1365 pane.previous_search_reverse = reverse; 1366 1367 search(pattern, reverse); 1850 ui_prompt_dialog_set_cb(dialog, &search_dialog_cb, &edit); 1851 pane.search_reverse = reverse; 1368 1852 } 1369 1853 … … 1513 1997 } 1514 1998 free(str); 1999 } 2000 2001 static void edit_paste(void) 2002 { 2003 selection_delete(); 2004 insert_clipboard_data(); 2005 pane.rflags |= (REDRAW_TEXT | REDRAW_CARET); 2006 pane_update(&pane); 2007 } 2008 2009 static void edit_cut(void) 2010 { 2011 selection_copy(); 2012 selection_delete(); 2013 pane.rflags |= (REDRAW_TEXT | REDRAW_CARET); 2014 pane_update(&pane); 1515 2015 } 1516 2016 … … 1719 2219 static void status_display(char const *str) 1720 2220 { 1721 console_set_pos(con, 0, scr_rows - 1); 1722 console_set_style(con, STYLE_INVERTED); 1723 1724 int pos = -(scr_columns - 3); 1725 printf(" %*s ", pos, str); 1726 console_flush(con); 1727 console_set_style(con, STYLE_NORMAL); 2221 (void) ui_label_set_text(edit.status, str); 2222 (void) ui_label_paint(edit.status); 2223 } 2224 2225 /** Window close request 2226 * 2227 * @param window Window 2228 * @param arg Argument (edit_t *) 2229 */ 2230 static void edit_wnd_close(ui_window_t *window, void *arg) 2231 { 2232 edit_t *edit = (edit_t *) arg; 2233 2234 ui_quit(edit->ui); 2235 } 2236 2237 /** Window focus event 2238 * 2239 * @param window Window 2240 * @param arg Argument (edit_t *) 2241 * @param focus Focus number 2242 */ 2243 static void edit_wnd_focus(ui_window_t *window, void *arg, unsigned focus) 2244 { 2245 edit_t *edit = (edit_t *)arg; 2246 2247 (void)edit; 2248 pane_caret_display(&pane); 2249 cursor_setvis(true); 2250 } 2251 2252 /** Window keyboard event 2253 * 2254 * @param window Window 2255 * @param arg Argument (edit_t *) 2256 * @param event Keyboard event 2257 */ 2258 static void edit_wnd_kbd_event(ui_window_t *window, void *arg, 2259 kbd_event_t *event) 2260 { 2261 pane.keymod = event->mods; 2262 2263 if (ui_window_def_kbd(window, event) == ui_claimed) 2264 return; 2265 2266 if (event->type == KEY_PRESS) { 2267 key_handle_press(event); 2268 (void) pane_update(&pane); 2269 (void) gfx_update(ui_window_get_gc(window)); 2270 } 2271 } 2272 2273 /** Window unfocus event 2274 * 2275 * @param window Window 2276 * @param arg Argument (edit_t *) 2277 * @param focus Focus number 2278 */ 2279 static void edit_wnd_unfocus(ui_window_t *window, void *arg, unsigned focus) 2280 { 2281 edit_t *edit = (edit_t *) arg; 2282 2283 (void)edit; 2284 cursor_setvis(false); 2285 } 2286 2287 /** Menu bar activate event 2288 * 2289 * @param mbar Menu bar 2290 * @param arg Argument (edit_t *) 2291 */ 2292 static void edit_menubar_activate(ui_menu_bar_t *mbar, void *arg) 2293 { 2294 edit_t *edit = (edit_t *)arg; 2295 2296 (void)edit; 2297 cursor_setvis(false); 2298 } 2299 2300 /** Menu bar deactivate event 2301 * 2302 * @param mbar Menu bar 2303 * @param arg Argument (edit_t *) 2304 */ 2305 static void edit_menubar_deactivate(ui_menu_bar_t *mbar, void *arg) 2306 { 2307 edit_t *edit = (edit_t *)arg; 2308 2309 (void)edit; 2310 pane_caret_display(&pane); 2311 cursor_setvis(true); 2312 } 2313 2314 /** File / Save menu entry selected. 2315 * 2316 * @param mentry Menu entry 2317 * @param arg Argument (edit_t *) 2318 */ 2319 static void edit_file_save(ui_menu_entry_t *mentry, void *arg) 2320 { 2321 edit_t *edit = (edit_t *) arg; 2322 2323 (void)edit; 2324 2325 if (doc.file_name != NULL) 2326 file_save(doc.file_name); 2327 else 2328 file_save_as(); 2329 } 2330 2331 /** File / Save As menu entry selected. 2332 * 2333 * @param mentry Menu entry 2334 * @param arg Argument (edit_t *) 2335 */ 2336 static void edit_file_save_as(ui_menu_entry_t *mentry, void *arg) 2337 { 2338 edit_t *edit = (edit_t *) arg; 2339 2340 (void)edit; 2341 file_save_as(); 2342 } 2343 2344 /** File / Exit menu entry selected. 2345 * 2346 * @param mentry Menu entry 2347 * @param arg Argument (edit_t *) 2348 */ 2349 static void edit_file_exit(ui_menu_entry_t *mentry, void *arg) 2350 { 2351 edit_t *edit = (edit_t *) arg; 2352 2353 ui_quit(edit->ui); 2354 } 2355 2356 /** Edit / Cut menu entry selected. 2357 * 2358 * @param mentry Menu entry 2359 * @param arg Argument (edit_t *) 2360 */ 2361 static void edit_edit_cut(ui_menu_entry_t *mentry, void *arg) 2362 { 2363 (void) arg; 2364 edit_cut(); 2365 (void) gfx_update(ui_window_get_gc(edit.window)); 2366 } 2367 2368 /** Edit / Copy menu entry selected. 2369 * 2370 * @param mentry Menu entry 2371 * @param arg Argument (edit_t *) 2372 */ 2373 static void edit_edit_copy(ui_menu_entry_t *mentry, void *arg) 2374 { 2375 (void) arg; 2376 selection_copy(); 2377 } 2378 2379 /** Edit / Paste menu entry selected. 2380 * 2381 * @param mentry Menu entry 2382 * @param arg Argument (edit_t *) 2383 */ 2384 static void edit_edit_paste(ui_menu_entry_t *mentry, void *arg) 2385 { 2386 (void) arg; 2387 edit_paste(); 2388 (void) gfx_update(ui_window_get_gc(edit.window)); 2389 } 2390 2391 /** Edit / Delete menu entry selected. 2392 * 2393 * @param mentry Menu entry 2394 * @param arg Argument (edit_t *) 2395 */ 2396 static void edit_edit_delete(ui_menu_entry_t *mentry, void *arg) 2397 { 2398 (void) arg; 2399 2400 if (selection_active()) 2401 selection_delete(); 1728 2402 1729 2403 pane.rflags |= REDRAW_CARET; 2404 (void) pane_update(&pane); 2405 (void) gfx_update(ui_window_get_gc(edit.window)); 2406 } 2407 2408 /** Edit / Select All menu entry selected. 2409 * 2410 * @param mentry Menu entry 2411 * @param arg Argument (edit_t *) 2412 */ 2413 static void edit_edit_select_all(ui_menu_entry_t *mentry, void *arg) 2414 { 2415 (void) arg; 2416 2417 selection_sel_all(); 2418 pane.rflags |= (REDRAW_CARET | REDRAW_TEXT | REDRAW_STATUS); 2419 pane_update(&pane); 2420 (void) gfx_update(ui_window_get_gc(edit.window)); 2421 } 2422 2423 /** Search / Find menu entry selected. 2424 * 2425 * @param mentry Menu entry 2426 * @param arg Argument (edit_t *) 2427 */ 2428 static void edit_search_find(ui_menu_entry_t *mentry, void *arg) 2429 { 2430 (void) arg; 2431 search_prompt(false); 2432 } 2433 2434 /** Search / Reverse Find menu entry selected. 2435 * 2436 * @param mentry Menu entry 2437 * @param arg Argument (edit_t *) 2438 */ 2439 static void edit_search_reverse_find(ui_menu_entry_t *mentry, void *arg) 2440 { 2441 (void) arg; 2442 search_prompt(true); 2443 } 2444 2445 /** Search / Find Next menu entry selected. 2446 * 2447 * @param mentry Menu entry 2448 * @param arg Argument (edit_t *) 2449 */ 2450 static void edit_search_find_next(ui_menu_entry_t *mentry, void *arg) 2451 { 2452 (void) arg; 2453 search_repeat(); 2454 (void) pane_update(&pane); 2455 (void) gfx_update(ui_window_get_gc(edit.window)); 2456 } 2457 2458 /** Search / Go To Line menu entry selected. 2459 * 2460 * @param mentry Menu entry 2461 * @param arg Argument (edit_t *) 2462 */ 2463 static void edit_search_go_to_line(ui_menu_entry_t *mentry, void *arg) 2464 { 2465 (void) arg; 2466 caret_go_to_line_ask(); 2467 } 2468 2469 /** Save As dialog OK button press. 2470 * 2471 * @param dialog Save As dialog 2472 * @param arg Argument (ui_demo_t *) 2473 * @param fname File name 2474 */ 2475 static void save_as_dialog_bok(ui_file_dialog_t *dialog, void *arg, 2476 const char *fname) 2477 { 2478 edit_t *edit = (edit_t *)arg; 2479 char *cname; 2480 errno_t rc; 2481 2482 (void)edit; 2483 ui_file_dialog_destroy(dialog); 2484 2485 cname = str_dup(fname); 2486 if (cname == NULL) { 2487 printf("Out of memory.\n"); 2488 return; 2489 } 2490 2491 rc = file_save(fname); 2492 if (rc != EOK) 2493 return; 2494 2495 if (doc.file_name != NULL) 2496 free(doc.file_name); 2497 doc.file_name = cname; 2498 2499 } 2500 2501 /** Save As dialog cancel button press. 2502 * 2503 * @param dialog File dialog 2504 * @param arg Argument (ui_demo_t *) 2505 */ 2506 static void save_as_dialog_bcancel(ui_file_dialog_t *dialog, void *arg) 2507 { 2508 edit_t *edit = (edit_t *)arg; 2509 2510 (void)edit; 2511 ui_file_dialog_destroy(dialog); 2512 } 2513 2514 /** Save As dialog close request. 2515 * 2516 * @param dialog File dialog 2517 * @param arg Argument (ui_demo_t *) 2518 */ 2519 static void save_as_dialog_close(ui_file_dialog_t *dialog, void *arg) 2520 { 2521 edit_t *edit = (edit_t *)arg; 2522 2523 (void)edit; 2524 ui_file_dialog_destroy(dialog); 2525 } 2526 2527 /** Go To Line dialog OK button press. 2528 * 2529 * @param dialog Go To Line dialog 2530 * @param arg Argument (ui_demo_t *) 2531 * @param text Submitted text 2532 */ 2533 static void go_to_line_dialog_bok(ui_prompt_dialog_t *dialog, void *arg, 2534 const char *text) 2535 { 2536 edit_t *edit = (edit_t *) arg; 2537 char *endptr; 2538 int line; 2539 2540 ui_prompt_dialog_destroy(dialog); 2541 line = strtol(text, &endptr, 10); 2542 if (*endptr != '\0') { 2543 status_display("Invalid number entered."); 2544 return; 2545 } 2546 2547 caret_move_absolute(line, pane.ideal_column, dir_before, false); 2548 (void)edit; 2549 (void) pane_update(&pane); 2550 } 2551 2552 /** Go To Line dialog cancel button press. 2553 * 2554 * @param dialog File dialog 2555 * @param arg Argument (ui_demo_t *) 2556 */ 2557 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg) 2558 { 2559 edit_t *edit = (edit_t *) arg; 2560 2561 (void)edit; 2562 ui_prompt_dialog_destroy(dialog); 2563 } 2564 2565 /** Go To Line dialog close request. 2566 * 2567 * @param dialog File dialog 2568 * @param arg Argument (ui_demo_t *) 2569 */ 2570 static void go_to_line_dialog_close(ui_prompt_dialog_t *dialog, void *arg) 2571 { 2572 edit_t *edit = (edit_t *) arg; 2573 2574 (void)edit; 2575 ui_prompt_dialog_destroy(dialog); 2576 } 2577 2578 /** Search dialog OK button press. 2579 * 2580 * @param dialog Search dialog 2581 * @param arg Argument (ui_demo_t *) 2582 * @param text Submitted text 2583 */ 2584 static void search_dialog_bok(ui_prompt_dialog_t *dialog, void *arg, 2585 const char *text) 2586 { 2587 edit_t *edit = (edit_t *) arg; 2588 char *pattern; 2589 bool reverse; 2590 2591 (void)edit; 2592 ui_prompt_dialog_destroy(dialog); 2593 2594 /* Abort if search phrase is empty */ 2595 if (text[0] == '\0') 2596 return; 2597 2598 pattern = str_dup(text); 2599 reverse = pane.search_reverse; 2600 2601 if (pane.previous_search) 2602 free(pane.previous_search); 2603 pane.previous_search = pattern; 2604 pane.previous_search_reverse = reverse; 2605 2606 search(pattern, reverse); 2607 2608 (void) pane_update(&pane); 2609 } 2610 2611 /** Search dialog cancel button press. 2612 * 2613 * @param dialog File dialog 2614 * @param arg Argument (ui_demo_t *) 2615 */ 2616 static void search_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg) 2617 { 2618 edit_t *edit = (edit_t *) arg; 2619 2620 (void)edit; 2621 ui_prompt_dialog_destroy(dialog); 2622 } 2623 2624 /** Search dialog close request. 2625 * 2626 * @param dialog File dialog 2627 * @param arg Argument (ui_demo_t *) 2628 */ 2629 static void search_dialog_close(ui_prompt_dialog_t *dialog, void *arg) 2630 { 2631 edit_t *edit = (edit_t *) arg; 2632 2633 (void)edit; 2634 ui_prompt_dialog_destroy(dialog); 1730 2635 } 1731 2636
Note:
See TracChangeset
for help on using the changeset viewer.