Changeset 8a9a41e in mainline for uspace/app/edit/edit.c
- Timestamp:
- 2021-10-24T08:28:43Z (2 years ago)
- Children:
- f628215
- Parents:
- 2ce943a (diff), cd981f2a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - git-author:
- Erik Kučák <35500848+Riko196@…> (2021-10-24 08:28:43)
- git-committer:
- GitHub <noreply@…> (2021-10-24 08:28:43)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/edit/edit.c
r2ce943a r8a9a41e 1 1 /* 2 * Copyright (c) 20 09Jiri Svoboda2 * Copyright (c) 2021 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/menuentry.h> 63 #include <ui/promptdialog.h> 64 #include <ui/resource.h> 65 #include <ui/ui.h> 66 #include <ui/window.h> 42 67 #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 68 52 69 #include "sheet.h" … … 63 80 * 64 81 * A rectangular area of the screen used to edit a document. Different 65 * panes can be possibly used to edit the same document. 82 * panes can be possibly used to edit the same document. This is a custom 83 * UI control. 66 84 */ 67 85 typedef struct { 86 /** Base control object */ 87 struct ui_control *control; 88 89 /** Containing window */ 90 ui_window_t *window; 91 92 /** UI resource */ 93 struct ui_resource *res; 94 95 /** Pane rectangle */ 96 gfx_rect_t rect; 97 98 /** Pane color */ 99 gfx_color_t *color; 100 101 /** Selection color */ 102 gfx_color_t *sel_color; 103 68 104 /* Pane dimensions */ 69 105 int rows, columns; … … 90 126 int ideal_column; 91 127 128 bool search_reverse; 92 129 char *previous_search; 93 130 bool previous_search_reverse; 94 131 } pane_t; 132 133 /** Text editor */ 134 typedef struct { 135 /** User interface */ 136 ui_t *ui; 137 /** Editor window */ 138 ui_window_t *window; 139 /** UI resource */ 140 ui_resource_t *ui_res; 141 /** Menu bar */ 142 ui_menu_bar_t *menubar; 143 /** Status bar */ 144 ui_label_t *status; 145 } edit_t; 95 146 96 147 /** Document … … 103 154 } doc_t; 104 155 105 static console_ctrl_t *con;156 static edit_t edit; 106 157 static doc_t doc; 107 static bool done;108 158 static pane_t pane; 109 static bool cursor_visible;110 111 static sysarg_t scr_rows;112 static sysarg_t scr_columns;113 159 114 160 #define ROW_BUF_SIZE 4096 … … 119 165 #define INFNAME_MAX_LEN 128 120 166 121 static void cursor_show(void);122 static void cursor_hide(void);123 167 static void cursor_setvis(bool visible); 124 168 … … 139 183 static char *range_get_str(spt_t const *spos, spt_t const *epos); 140 184 141 static char *prompt(char const *prompt, char const *init_value); 142 143 static void pane_text_display(void); 185 static errno_t pane_init(ui_window_t *, pane_t *); 186 static void pane_fini(pane_t *); 187 static ui_control_t *pane_ctl(pane_t *); 188 static errno_t pane_update(pane_t *); 189 static errno_t pane_text_display(pane_t *); 144 190 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);191 static errno_t pane_row_range_display(pane_t *, int r0, int r1); 192 static void pane_status_display(pane_t *); 193 static void pane_caret_display(pane_t *); 148 194 149 195 static void insert_char(char32_t c); … … 164 210 static void selection_delete(void); 165 211 static void selection_copy(void); 212 static void edit_cut(void); 213 static void edit_paste(void); 166 214 static void insert_clipboard_data(void); 167 215 … … 185 233 186 234 static void status_display(char const *str); 235 static errno_t edit_ui_create(edit_t *); 236 static void edit_ui_destroy(edit_t *); 237 238 static void edit_wnd_close(ui_window_t *, void *); 239 static void edit_wnd_kbd_event(ui_window_t *, void *, kbd_event_t *); 240 241 static ui_window_cb_t edit_window_cb = { 242 .close = edit_wnd_close, 243 .kbd = edit_wnd_kbd_event 244 }; 245 246 static void edit_file_save(ui_menu_entry_t *, void *); 247 static void edit_file_save_as(ui_menu_entry_t *, void *); 248 static void edit_file_exit(ui_menu_entry_t *, void *); 249 static void edit_edit_cut(ui_menu_entry_t *, void *); 250 static void edit_edit_copy(ui_menu_entry_t *, void *); 251 static void edit_edit_paste(ui_menu_entry_t *, void *); 252 static void edit_edit_delete(ui_menu_entry_t *, void *); 253 static void edit_edit_select_all(ui_menu_entry_t *, void *); 254 static void edit_search_find(ui_menu_entry_t *, void *); 255 static void edit_search_reverse_find(ui_menu_entry_t *, void *); 256 static void edit_search_find_next(ui_menu_entry_t *, void *); 257 static void edit_search_go_to_line(ui_menu_entry_t *, void *); 258 259 static void pane_ctl_destroy(void *); 260 static errno_t pane_ctl_paint(void *); 261 static ui_evclaim_t pane_ctl_pos_event(void *, pos_event_t *); 262 263 /** Pabe control ops */ 264 ui_control_ops_t pane_ctl_ops = { 265 .destroy = pane_ctl_destroy, 266 .paint = pane_ctl_paint, 267 .pos_event = pane_ctl_pos_event 268 }; 269 270 static void save_as_dialog_bok(ui_file_dialog_t *, void *, const char *); 271 static void save_as_dialog_bcancel(ui_file_dialog_t *, void *); 272 static void save_as_dialog_close(ui_file_dialog_t *, void *); 273 274 static ui_file_dialog_cb_t save_as_dialog_cb = { 275 .bok = save_as_dialog_bok, 276 .bcancel = save_as_dialog_bcancel, 277 .close = save_as_dialog_close 278 }; 279 280 static void go_to_line_dialog_bok(ui_prompt_dialog_t *, void *, const char *); 281 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *, void *); 282 static void go_to_line_dialog_close(ui_prompt_dialog_t *, void *); 283 284 static ui_prompt_dialog_cb_t go_to_line_dialog_cb = { 285 .bok = go_to_line_dialog_bok, 286 .bcancel = go_to_line_dialog_bcancel, 287 .close = go_to_line_dialog_close 288 }; 289 290 static void search_dialog_bok(ui_prompt_dialog_t *, void *, const char *); 291 static void search_dialog_bcancel(ui_prompt_dialog_t *, void *); 292 static void search_dialog_close(ui_prompt_dialog_t *, void *); 293 294 static ui_prompt_dialog_cb_t search_dialog_cb = { 295 .bok = search_dialog_bok, 296 .bcancel = search_dialog_bcancel, 297 .close = search_dialog_close 298 }; 187 299 188 300 int main(int argc, char *argv[]) 189 301 { 190 cons_event_t ev;191 302 bool new_file; 192 303 errno_t rc; 193 304 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 305 pane.sh_row = 1; 202 306 pane.sh_column = 1; … … 234 338 /* Move to beginning of file. */ 235 339 pt_get_sof(&sof); 340 341 /* Create UI */ 342 rc = edit_ui_create(&edit); 343 if (rc != EOK) 344 return 1; 345 236 346 caret_move(sof, true, true); 237 347 238 348 /* Initial display */ 239 cursor_visible = true; 240 241 cursor_hide(); 242 console_clear(con); 243 pane_text_display(); 244 pane_status_display(); 349 rc = ui_window_paint(edit.window); 350 if (rc != EOK) { 351 printf("Error painting window.\n"); 352 return rc; 353 } 354 355 pane_status_display(&pane); 245 356 if (new_file && doc.file_name != NULL) 246 357 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 358 pane_caret_display(&pane); 359 cursor_setvis(true); 360 361 ui_run(edit.ui); 362 363 edit_ui_destroy(&edit); 288 364 return 0; 365 } 366 367 /** Create text editor UI. 368 * 369 * @param edit Editor 370 * @return EOK on success or an error code 371 */ 372 static errno_t edit_ui_create(edit_t *edit) 373 { 374 errno_t rc; 375 ui_wnd_params_t params; 376 ui_fixed_t *fixed = NULL; 377 ui_menu_t *mfile = NULL; 378 ui_menu_t *medit = NULL; 379 ui_menu_entry_t *msave = NULL; 380 ui_menu_entry_t *msaveas = NULL; 381 ui_menu_entry_t *mfsep = NULL; 382 ui_menu_entry_t *mexit = NULL; 383 ui_menu_entry_t *mcut = NULL; 384 ui_menu_entry_t *mcopy = NULL; 385 ui_menu_entry_t *mpaste = NULL; 386 ui_menu_entry_t *mdelete = NULL; 387 ui_menu_entry_t *mesep = NULL; 388 ui_menu_entry_t *mselall = NULL; 389 ui_menu_t *msearch = NULL; 390 ui_menu_entry_t *mfind = NULL; 391 ui_menu_entry_t *mfindr = NULL; 392 ui_menu_entry_t *mfindn = NULL; 393 ui_menu_entry_t *mssep = NULL; 394 ui_menu_entry_t *mgoto = NULL; 395 gfx_rect_t arect; 396 gfx_rect_t rect; 397 398 rc = ui_create(UI_CONSOLE_DEFAULT, &edit->ui); 399 if (rc != EOK) { 400 printf("Error creating UI on display %s.\n", 401 UI_CONSOLE_DEFAULT); 402 goto error; 403 } 404 405 ui_wnd_params_init(¶ms); 406 params.caption = "Text Editor"; 407 params.style &= ~ui_wds_decorated; 408 params.placement = ui_wnd_place_full_screen; 409 410 rc = ui_window_create(edit->ui, ¶ms, &edit->window); 411 if (rc != EOK) { 412 printf("Error creating window.\n"); 413 goto error; 414 } 415 416 ui_window_set_cb(edit->window, &edit_window_cb, (void *) edit); 417 418 edit->ui_res = ui_window_get_res(edit->window); 419 420 rc = ui_fixed_create(&fixed); 421 if (rc != EOK) { 422 printf("Error creating fixed layout.\n"); 423 return rc; 424 } 425 426 rc = ui_menu_bar_create(edit->ui, edit->window, &edit->menubar); 427 if (rc != EOK) { 428 printf("Error creating menu bar.\n"); 429 return rc; 430 } 431 432 rc = ui_menu_create(edit->menubar, "File", &mfile); 433 if (rc != EOK) { 434 printf("Error creating menu.\n"); 435 return rc; 436 } 437 438 rc = ui_menu_entry_create(mfile, "Save", "Ctrl-S", &msave); 439 if (rc != EOK) { 440 printf("Error creating menu.\n"); 441 return rc; 442 } 443 444 ui_menu_entry_set_cb(msave, edit_file_save, (void *) edit); 445 446 rc = ui_menu_entry_create(mfile, "Save As", "Ctrl-E", &msaveas); 447 if (rc != EOK) { 448 printf("Error creating menu.\n"); 449 return rc; 450 } 451 452 ui_menu_entry_set_cb(msaveas, edit_file_save_as, (void *) edit); 453 454 rc = ui_menu_entry_sep_create(mfile, &mfsep); 455 if (rc != EOK) { 456 printf("Error creating menu.\n"); 457 return rc; 458 } 459 460 rc = ui_menu_entry_create(mfile, "Exit", "Ctrl-Q", &mexit); 461 if (rc != EOK) { 462 printf("Error creating menu.\n"); 463 return rc; 464 } 465 466 ui_menu_entry_set_cb(mexit, edit_file_exit, (void *) edit); 467 468 rc = ui_menu_create(edit->menubar, "Edit", &medit); 469 if (rc != EOK) { 470 printf("Error creating menu.\n"); 471 return rc; 472 } 473 474 rc = ui_menu_entry_create(medit, "Cut", "Ctrl-X", &mcut); 475 if (rc != EOK) { 476 printf("Error creating menu.\n"); 477 return rc; 478 } 479 480 ui_menu_entry_set_cb(mcut, edit_edit_cut, (void *) edit); 481 482 rc = ui_menu_entry_create(medit, "Copy", "Ctrl-C", &mcopy); 483 if (rc != EOK) { 484 printf("Error creating menu.\n"); 485 return rc; 486 } 487 488 ui_menu_entry_set_cb(mcopy, edit_edit_copy, (void *) edit); 489 490 rc = ui_menu_entry_create(medit, "Paste", "Ctrl-V", &mpaste); 491 if (rc != EOK) { 492 printf("Error creating menu.\n"); 493 return rc; 494 } 495 496 ui_menu_entry_set_cb(mpaste, edit_edit_paste, (void *) edit); 497 498 rc = ui_menu_entry_create(medit, "Delete", "Del", &mdelete); 499 if (rc != EOK) { 500 printf("Error creating menu.\n"); 501 return rc; 502 } 503 504 ui_menu_entry_set_cb(mdelete, edit_edit_delete, (void *) edit); 505 506 rc = ui_menu_entry_sep_create(medit, &mesep); 507 if (rc != EOK) { 508 printf("Error creating menu.\n"); 509 return rc; 510 } 511 512 rc = ui_menu_entry_create(medit, "Select All", "Ctrl-A", &mselall); 513 if (rc != EOK) { 514 printf("Error creating menu.\n"); 515 return rc; 516 } 517 518 ui_menu_entry_set_cb(mselall, edit_edit_select_all, (void *) edit); 519 520 rc = ui_menu_create(edit->menubar, "Search", &msearch); 521 if (rc != EOK) { 522 printf("Error creating menu.\n"); 523 return rc; 524 } 525 526 rc = ui_menu_entry_create(msearch, "Find", "Ctrl-F", &mfind); 527 if (rc != EOK) { 528 printf("Error creating menu.\n"); 529 return rc; 530 } 531 532 ui_menu_entry_set_cb(mfind, edit_search_find, (void *) edit); 533 534 rc = ui_menu_entry_create(msearch, "Reverse Find", "Ctrl-Shift-F", &mfindr); 535 if (rc != EOK) { 536 printf("Error creating menu.\n"); 537 return rc; 538 } 539 540 ui_menu_entry_set_cb(mfindr, edit_search_reverse_find, (void *) edit); 541 542 rc = ui_menu_entry_create(msearch, "Find Next", "Ctrl-N", &mfindn); 543 if (rc != EOK) { 544 printf("Error creating menu.\n"); 545 return rc; 546 } 547 548 ui_menu_entry_set_cb(mfindn, edit_search_find_next, (void *) edit); 549 550 rc = ui_menu_entry_sep_create(msearch, &mssep); 551 if (rc != EOK) { 552 printf("Error creating menu.\n"); 553 return rc; 554 } 555 556 rc = ui_menu_entry_create(msearch, "Go To Line", "Ctrl-L", &mgoto); 557 if (rc != EOK) { 558 printf("Error creating menu.\n"); 559 return rc; 560 } 561 562 ui_menu_entry_set_cb(mgoto, edit_search_go_to_line, (void *) edit); 563 564 ui_window_get_app_rect(edit->window, &arect); 565 566 rect.p0 = arect.p0; 567 rect.p1.x = arect.p1.x; 568 rect.p1.y = arect.p0.y + 1; 569 ui_menu_bar_set_rect(edit->menubar, &rect); 570 571 rc = ui_fixed_add(fixed, ui_menu_bar_ctl(edit->menubar)); 572 if (rc != EOK) { 573 printf("Error adding control to layout.\n"); 574 return rc; 575 } 576 577 rc = pane_init(edit->window, &pane); 578 if (rc != EOK) { 579 printf("Error initializing pane.\n"); 580 return rc; 581 } 582 583 rc = ui_fixed_add(fixed, pane_ctl(&pane)); 584 if (rc != EOK) { 585 printf("Error adding control to layout.\n"); 586 return rc; 587 } 588 589 rc = ui_label_create(edit->ui_res, "", &edit->status); 590 if (rc != EOK) { 591 printf("Error creating menu bar.\n"); 592 return rc; 593 } 594 595 rect.p0.x = arect.p0.x; 596 rect.p0.y = arect.p1.y - 1; 597 rect.p1 = arect.p1; 598 ui_label_set_rect(edit->status, &rect); 599 600 rc = ui_fixed_add(fixed, ui_label_ctl(edit->status)); 601 if (rc != EOK) { 602 printf("Error adding control to layout.\n"); 603 return rc; 604 } 605 606 ui_window_add(edit->window, ui_fixed_ctl(fixed)); 607 return EOK; 608 error: 609 if (edit->window != NULL) 610 ui_window_destroy(edit->window); 611 if (edit->ui != NULL) 612 ui_destroy(edit->ui); 613 return rc; 614 } 615 616 /** Destroy text editor UI. 617 * 618 * @param edit Editor 619 */ 620 static void edit_ui_destroy(edit_t *edit) 621 { 622 ui_window_destroy(edit->window); 623 ui_destroy(edit->ui); 289 624 } 290 625 … … 309 644 } 310 645 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 646 static void cursor_setvis(bool visible) 322 647 { 323 if (cursor_visible != visible) { 324 console_cursor_visibility(con, visible); 325 cursor_visible = visible; 326 } 648 gfx_context_t *gc = ui_window_get_gc(edit.window); 649 650 (void) gfx_cursor_set_visible(gc, visible); 327 651 } 328 652 … … 400 724 switch (ev->key) { 401 725 case KC_Q: 402 done = true;726 ui_quit(edit.ui); 403 727 break; 404 728 case KC_S: … … 415 739 break; 416 740 case KC_V: 417 selection_delete(); 418 insert_clipboard_data(); 419 pane.rflags |= REDRAW_TEXT; 420 caret_update(); 741 edit_paste(); 421 742 break; 422 743 case KC_X: 423 selection_copy(); 424 selection_delete(); 425 pane.rflags |= REDRAW_TEXT; 426 caret_update(); 744 edit_cut(); 427 745 break; 428 746 case KC_A: … … 490 808 491 809 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 ;810 bc.row = pane.sh_row + ev->vpos - pane.rect.p0.y; 811 bc.column = pane.sh_column + ev->hpos - pane.rect.p0.x; 494 812 sheet_get_cell_pt(doc.sh, &bc, dir_before, &pt); 495 813 … … 497 815 498 816 caret_move(pt, select, true); 817 pane_update(&pane); 499 818 } 500 819 } … … 606 925 } 607 926 608 /** Change document name and save. */927 /** Open Save As dialog. */ 609 928 static void file_save_as(void) 610 929 { 611 930 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."); 931 ui_file_dialog_params_t fdparams; 932 ui_file_dialog_t *dialog; 933 errno_t rc; 934 935 ui_file_dialog_params_init(&fdparams); 936 fdparams.caption = "Save As"; 937 fdparams.ifname = old_fname; 938 939 rc = ui_file_dialog_create(edit.ui, &fdparams, &dialog); 940 if (rc != EOK) { 941 printf("Error creating message dialog.\n"); 617 942 return; 618 943 } 619 944 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; 945 ui_file_dialog_set_cb(dialog, &save_as_dialog_cb, &edit); 694 946 } 695 947 … … 808 1060 } 809 1061 810 static void pane_text_display(void) 811 { 1062 /** Initialize pane. 1063 * 1064 * TODO: Replace with pane_create() that allocates the pane. 1065 * 1066 * @param window Editor window 1067 * @param pane Pane 1068 * @return EOK on success or an error code 1069 */ 1070 static errno_t pane_init(ui_window_t *window, pane_t *pane) 1071 { 1072 errno_t rc; 1073 gfx_rect_t arect; 1074 1075 pane->control = NULL; 1076 pane->color = NULL; 1077 pane->sel_color = NULL; 1078 1079 rc = ui_control_new(&pane_ctl_ops, (void *) pane, &pane->control); 1080 if (rc != EOK) 1081 goto error; 1082 1083 rc = gfx_color_new_ega(0x07, &pane->color); 1084 if (rc != EOK) 1085 goto error; 1086 1087 rc = gfx_color_new_ega(0x1e, &pane->sel_color); 1088 if (rc != EOK) 1089 goto error; 1090 1091 pane->res = ui_window_get_res(window); 1092 pane->window = window; 1093 1094 ui_window_get_app_rect(window, &arect); 1095 pane->rect.p0.x = arect.p0.x; 1096 pane->rect.p0.y = arect.p0.y + 1; 1097 pane->rect.p1.x = arect.p1.x; 1098 pane->rect.p1.y = arect.p1.y - 1; 1099 1100 pane->columns = pane->rect.p1.x - pane->rect.p0.x; 1101 pane->rows = pane->rect.p1.y - pane->rect.p0.y; 1102 1103 return EOK; 1104 error: 1105 if (pane->control != NULL) { 1106 ui_control_delete(pane->control); 1107 pane->control = NULL; 1108 } 1109 1110 if (pane->color != NULL) { 1111 gfx_color_delete(pane->color); 1112 pane->color = NULL; 1113 } 1114 1115 return rc; 1116 } 1117 1118 /** Finalize pane. 1119 * 1120 * TODO: Replace with pane_destroy() that deallocates the pane. 1121 * 1122 * @param pane Pane 1123 */ 1124 static void pane_fini(pane_t *pane) 1125 { 1126 gfx_color_delete(pane->color); 1127 pane->color = NULL; 1128 gfx_color_delete(pane->sel_color); 1129 pane->sel_color = NULL; 1130 ui_control_delete(pane->control); 1131 pane->control = NULL; 1132 } 1133 1134 /** Return base control object for a pane. 1135 * 1136 * @param pane Pane 1137 * @return Base UI cntrol 1138 */ 1139 static ui_control_t *pane_ctl(pane_t *pane) 1140 { 1141 return pane->control; 1142 } 1143 1144 /** Repaint parts of pane that need updating. 1145 * 1146 * @param pane Pane 1147 * @return EOK on succes or an error code 1148 */ 1149 static errno_t pane_update(pane_t *pane) 1150 { 1151 errno_t rc; 1152 1153 if (pane->rflags & REDRAW_TEXT) { 1154 rc = pane_text_display(pane); 1155 if (rc != EOK) 1156 return rc; 1157 } 1158 1159 if (pane->rflags & REDRAW_ROW) 1160 pane_row_display(); 1161 1162 if (pane->rflags & REDRAW_STATUS) 1163 pane_status_display(pane); 1164 1165 if (pane->rflags & REDRAW_CARET) 1166 pane_caret_display(pane); 1167 1168 pane->rflags &= ~(REDRAW_TEXT | REDRAW_ROW | REDRAW_STATUS | 1169 REDRAW_CARET); 1170 return EOK; 1171 } 1172 1173 /** Display pane text. 1174 * 1175 * @param pane Pane 1176 * @return EOK on success or an error code 1177 */ 1178 static errno_t pane_text_display(pane_t *pane) 1179 { 1180 gfx_rect_t rect; 1181 gfx_context_t *gc; 1182 errno_t rc; 812 1183 int sh_rows, rows; 813 1184 814 1185 sheet_get_num_rows(doc.sh, &sh_rows); 815 rows = min(sh_rows - pane .sh_row + 1, pane.rows);1186 rows = min(sh_rows - pane->sh_row + 1, pane->rows); 816 1187 817 1188 /* Draw rows from the sheet. */ 818 1189 819 console_set_pos(con, 0, 0); 820 pane_row_range_display(0, rows); 1190 rc = pane_row_range_display(pane, 0, rows); 1191 if (rc != EOK) 1192 return rc; 821 1193 822 1194 /* Clear the remaining rows if file is short. */ 823 1195 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; 1196 gc = ui_window_get_gc(pane->window); 1197 1198 rc = gfx_set_color(gc, pane->color); 1199 if (rc != EOK) 1200 goto error; 1201 1202 rect.p0.x = pane->rect.p0.x; 1203 rect.p0.y = pane->rect.p0.y + rows; 1204 rect.p1.x = pane->rect.p1.x; 1205 rect.p1.y = pane->rect.p1.y; 1206 1207 rc = gfx_fill_rect(gc, &rect); 1208 if (rc != EOK) 1209 goto error; 1210 1211 pane->rflags &= ~REDRAW_ROW; 1212 return EOK; 1213 error: 1214 return rc; 835 1215 } 836 1216 … … 846 1226 847 1227 ridx = coord.row - pane.sh_row; 848 pane_row_range_display(ridx, ridx + 1);1228 (void) pane_row_range_display(&pane, ridx, ridx + 1); 849 1229 pane.rflags |= (REDRAW_STATUS | REDRAW_CARET); 850 1230 } 851 1231 852 static void pane_row_range_display(int r0, int r1) 853 { 854 int i, j, fill; 1232 /** Display a range of rows of text. 1233 * 1234 * @param r0 Start row (inclusive) 1235 * @param r1 End row (exclusive) 1236 * @return EOk on success or an error code 1237 */ 1238 static errno_t pane_row_range_display(pane_t *pane, int r0, int r1) 1239 { 1240 int i, fill; 855 1241 spt_t rb, re, dep, pt; 856 1242 coord_t rbc, rec; 857 1243 char row_buf[ROW_BUF_SIZE]; 1244 char cbuf[STR_BOUNDS(1) + 1]; 858 1245 char32_t c; 859 1246 size_t pos, size; 1247 size_t cpos; 860 1248 int s_column; 861 1249 coord_t csel_start, csel_end, ctmp; 1250 gfx_font_t *font; 1251 gfx_context_t *gc; 1252 gfx_text_fmt_t fmt; 1253 gfx_coord2_t tpos; 1254 gfx_rect_t rect; 1255 errno_t rc; 1256 1257 font = ui_resource_get_font(edit.ui_res); 1258 gc = ui_window_get_gc(edit.window); 1259 1260 gfx_text_fmt_init(&fmt); 1261 fmt.color = pane->color; 862 1262 863 1263 /* Determine selection start and end. */ 864 1264 865 tag_get_pt(&pane .sel_start, &pt);1265 tag_get_pt(&pane->sel_start, &pt); 866 1266 spt_get_coord(&pt, &csel_start); 867 1267 868 tag_get_pt(&pane .caret_pos, &pt);1268 tag_get_pt(&pane->caret_pos, &pt); 869 1269 spt_get_coord(&pt, &csel_end); 870 1270 … … 877 1277 /* Draw rows from the sheet. */ 878 1278 879 console_set_pos(con, 0, 0);880 1279 for (i = r0; i < r1; ++i) { 1280 tpos.x = pane->rect.p0.x; 1281 tpos.y = pane->rect.p0.y + i; 1282 881 1283 /* Starting point for row display */ 882 rbc.row = pane .sh_row + i;883 rbc.column = pane .sh_column;1284 rbc.row = pane->sh_row + i; 1285 rbc.column = pane->sh_column; 884 1286 sheet_get_cell_pt(doc.sh, &rbc, dir_before, &rb); 885 1287 886 1288 /* Ending point for row display */ 887 rec.row = pane .sh_row + i;888 rec.column = pane .sh_column + pane.columns;1289 rec.row = pane->sh_row + i; 1290 rec.column = pane->sh_column + pane->columns; 889 1291 sheet_get_cell_pt(doc.sh, &rec, dir_before, &re); 890 1292 … … 896 1298 if (coord_cmp(&csel_start, &rbc) <= 0 && 897 1299 coord_cmp(&rbc, &csel_end) < 0) { 898 console_flush(con); 899 console_set_style(con, STYLE_SELECTED); 900 console_flush(con); 1300 fmt.color = pane->sel_color; 901 1301 } 902 1302 903 console_set_pos(con, 0, i);904 1303 size = str_size(row_buf); 905 1304 pos = 0; 906 s_column = pane .sh_column;1305 s_column = pane->sh_column; 907 1306 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 } 1307 if ((csel_start.row == rbc.row) && (csel_start.column == s_column)) 1308 fmt.color = pane->sel_color; 1309 1310 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) 1311 fmt.color = pane->color; 919 1312 920 1313 c = str_decode(row_buf, &pos, size); 921 1314 if (c != '\t') { 922 printf("%lc", (wint_t) c); 1315 cpos = 0; 1316 rc = chr_encode(c, cbuf, &cpos, sizeof(cbuf)); 1317 if (rc != EOK) 1318 return rc; 1319 1320 rc = gfx_puttext(font, &tpos, &fmt, cbuf); 1321 if (rc != EOK) 1322 return rc; 1323 923 1324 s_column += 1; 1325 tpos.x++; 924 1326 } else { 925 1327 fill = 1 + ALIGN_UP(s_column, TAB_WIDTH) - 926 1328 s_column; 927 1329 928 for (j = 0; j < fill; ++j) 929 putchar(' '); 1330 rc = gfx_set_color(gc, fmt.color); 1331 if (rc != EOK) 1332 return rc; 1333 1334 rect.p0.x = tpos.x; 1335 rect.p0.y = tpos.y; 1336 rect.p1.x = tpos.x + fill; 1337 rect.p1.y = tpos.y + 1; 1338 1339 rc = gfx_fill_rect(gc, &rect); 1340 if (rc != EOK) 1341 return rc; 1342 930 1343 s_column += fill; 1344 tpos.x += fill; 931 1345 } 932 1346 } 933 1347 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 } 1348 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) 1349 fmt.color = pane->color; 939 1350 940 1351 /* Fill until the end of display area. */ 941 1352 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) 1353 rc = gfx_set_color(gc, fmt.color); 1354 if (rc != EOK) 1355 return rc; 1356 1357 rect.p0.x = tpos.x; 1358 rect.p0.y = tpos.y; 1359 rect.p1.x = pane->rect.p1.x; 1360 rect.p1.y = tpos.y + 1; 1361 1362 rc = gfx_fill_rect(gc, &rect); 1363 if (rc != EOK) 1364 return rc; 1365 } 1366 1367 return EOK; 1368 } 1369 1370 /** Display pane status in the status line. 1371 * 1372 * @param pane Pane 1373 */ 1374 static void pane_status_display(pane_t *pane) 958 1375 { 959 1376 spt_t caret_pt; … … 964 1381 char *text; 965 1382 size_t n; 966 int pos;967 1383 size_t nextra; 968 1384 size_t fnw; 969 1385 970 tag_get_pt(&pane .caret_pos, &caret_pt);1386 tag_get_pt(&pane->caret_pos, &caret_pt); 971 1387 spt_get_coord(&caret_pt, &coord); 972 1388 … … 987 1403 return; 988 1404 989 console_set_pos(con, 0, scr_rows - 1);990 console_set_style(con, STYLE_INVERTED);991 992 1405 /* 993 1406 * Make sure the status fits on the screen. This loop should … … 995 1408 */ 996 1409 while (true) { 997 int rc = asprintf(&text, " 1410 int rc = asprintf(&text, "%d, %d (%d): File '%s'. Ctrl-Q Quit Ctrl-S Save " 998 1411 "Ctrl-E Save As", coord.row, coord.column, last_row, fname); 999 1412 if (rc < 0) { … … 1004 1417 /* If it already fits, we're done */ 1005 1418 n = str_width(text); 1006 if ( n <= scr_columns - 2)1419 if ((int)n <= pane->columns - 2) 1007 1420 break; 1008 1421 1009 1422 /* Compute number of excess characters */ 1010 nextra = n - ( scr_columns - 2);1423 nextra = n - (pane->columns - 2); 1011 1424 /** With of the file name part */ 1012 1425 fnw = str_width(fname); … … 1016 1429 * just give up and print a blank status. 1017 1430 */ 1018 if (nextra > fnw - 2) 1431 if (nextra > fnw - 2) { 1432 text[0] = '\0'; 1019 1433 goto finish; 1434 } 1020 1435 1021 1436 /* Compute position where we overwrite with '..\0' */ … … 1034 1449 } 1035 1450 1036 printf("%s", text); 1451 finish: 1452 (void) ui_label_set_text(edit.status, text); 1453 (void) ui_label_paint(edit.status); 1037 1454 free(text); 1038 1455 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) 1456 } 1457 1458 /** Set cursor to reflect position of the caret. 1459 * 1460 * @param pane Pane 1461 */ 1462 static void pane_caret_display(pane_t *pane) 1051 1463 { 1052 1464 spt_t caret_pt; 1053 1465 coord_t coord; 1054 1055 tag_get_pt(&pane.caret_pos, &caret_pt); 1466 gfx_coord2_t pos; 1467 gfx_context_t *gc; 1468 1469 tag_get_pt(&pane->caret_pos, &caret_pt); 1056 1470 1057 1471 spt_get_coord(&caret_pt, &coord); 1058 console_set_pos(con, coord.column - pane.sh_column, 1059 coord.row - pane.sh_row); 1472 1473 gc = ui_window_get_gc(edit.window); 1474 pos.x = pane->rect.p0.x + coord.column - pane->sh_column; 1475 pos.y = pane->rect.p0.y + coord.row - pane->sh_row; 1476 1477 (void) gfx_cursor_set_pos(gc, &pos); 1478 } 1479 1480 /** Destroy pane control. 1481 * 1482 * @param arg Argument (pane_t *) 1483 */ 1484 static void pane_ctl_destroy(void *arg) 1485 { 1486 pane_t *pane = (pane_t *)arg; 1487 1488 pane_fini(pane); 1489 } 1490 1491 /** Paint pane control. 1492 * 1493 * @param arg Argument (pane_t *) 1494 */ 1495 static errno_t pane_ctl_paint(void *arg) 1496 { 1497 pane_t *pane = (pane_t *)arg; 1498 gfx_context_t *gc; 1499 errno_t rc; 1500 1501 gc = ui_window_get_gc(pane->window); 1502 1503 rc = pane_text_display(pane); 1504 if (rc != EOK) 1505 goto error; 1506 1507 rc = gfx_update(gc); 1508 if (rc != EOK) 1509 goto error; 1510 1511 error: 1512 return rc; 1513 } 1514 1515 /** Handle pane control position event. 1516 * 1517 * @param arg Argument (pane_t *) 1518 * @param event Position event 1519 */ 1520 static ui_evclaim_t pane_ctl_pos_event(void *arg, pos_event_t *event) 1521 { 1522 gfx_coord2_t pos; 1523 1524 pos.x = event->hpos; 1525 pos.y = event->vpos; 1526 1527 if (!gfx_pix_inside_rect(&pos, &pane.rect)) 1528 return ui_unclaimed; 1529 1530 pos_handle(event); 1531 (void) gfx_update(ui_window_get_gc(edit.window)); 1532 return ui_claimed; 1060 1533 } 1061 1534 … … 1270 1743 static void caret_go_to_line_ask(void) 1271 1744 { 1272 char *sline; 1273 1274 sline = prompt("Go to line", ""); 1275 if (sline == NULL) { 1276 status_display("Go to line cancelled."); 1745 ui_prompt_dialog_params_t pdparams; 1746 ui_prompt_dialog_t *dialog; 1747 errno_t rc; 1748 1749 ui_prompt_dialog_params_init(&pdparams); 1750 pdparams.caption = "Go To Line"; 1751 pdparams.prompt = "Line Number"; 1752 1753 rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog); 1754 if (rc != EOK) { 1755 printf("Error creating prompt dialog.\n"); 1277 1756 return; 1278 1757 } 1279 1758 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); 1759 ui_prompt_dialog_set_cb(dialog, &go_to_line_dialog_cb, &edit); 1290 1760 } 1291 1761 … … 1344 1814 static void search_prompt(bool reverse) 1345 1815 { 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 = ""; 1816 ui_prompt_dialog_params_t pdparams; 1817 ui_prompt_dialog_t *dialog; 1818 errno_t rc; 1819 1820 ui_prompt_dialog_params_init(&pdparams); 1821 pdparams.caption = reverse ? "Reverse Search" : "Search"; 1822 pdparams.prompt = "Search text"; 1823 pdparams.itext = ""; 1824 1353 1825 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.");1826 pdparams.itext = pane.previous_search; 1827 1828 rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog); 1829 if (rc != EOK) { 1830 printf("Error creating prompt dialog.\n"); 1359 1831 return; 1360 1832 } 1361 1833 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); 1834 ui_prompt_dialog_set_cb(dialog, &search_dialog_cb, &edit); 1835 pane.search_reverse = reverse; 1368 1836 } 1369 1837 … … 1513 1981 } 1514 1982 free(str); 1983 } 1984 1985 static void edit_paste(void) 1986 { 1987 selection_delete(); 1988 insert_clipboard_data(); 1989 pane.rflags |= (REDRAW_TEXT | REDRAW_CARET); 1990 pane_update(&pane); 1991 } 1992 1993 static void edit_cut(void) 1994 { 1995 selection_copy(); 1996 selection_delete(); 1997 pane.rflags |= (REDRAW_TEXT | REDRAW_CARET); 1998 pane_update(&pane); 1515 1999 } 1516 2000 … … 1719 2203 static void status_display(char const *str) 1720 2204 { 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); 2205 (void) ui_label_set_text(edit.status, str); 2206 (void) ui_label_paint(edit.status); 2207 } 2208 2209 /** Window close request 2210 * 2211 * @param window Window 2212 * @param arg Argument (edit_t *) 2213 */ 2214 static void edit_wnd_close(ui_window_t *window, void *arg) 2215 { 2216 edit_t *edit = (edit_t *) arg; 2217 2218 ui_quit(edit->ui); 2219 } 2220 2221 /** Window keyboard event 2222 * 2223 * @param window Window 2224 * @param arg Argument (edit_t *) 2225 * @param event Keyboard event 2226 */ 2227 static void edit_wnd_kbd_event(ui_window_t *window, void *arg, 2228 kbd_event_t *event) 2229 { 2230 pane.keymod = event->mods; 2231 2232 if (event->type == KEY_PRESS) { 2233 key_handle_press(event); 2234 (void) pane_update(&pane); 2235 (void) gfx_update(ui_window_get_gc(window)); 2236 } 2237 } 2238 2239 /** File / Save menu entry selected. 2240 * 2241 * @param mentry Menu entry 2242 * @param arg Argument (edit_t *) 2243 */ 2244 static void edit_file_save(ui_menu_entry_t *mentry, void *arg) 2245 { 2246 edit_t *edit = (edit_t *) arg; 2247 2248 (void)edit; 2249 2250 if (doc.file_name != NULL) 2251 file_save(doc.file_name); 2252 else 2253 file_save_as(); 2254 } 2255 2256 /** File / Save As menu entry selected. 2257 * 2258 * @param mentry Menu entry 2259 * @param arg Argument (edit_t *) 2260 */ 2261 static void edit_file_save_as(ui_menu_entry_t *mentry, void *arg) 2262 { 2263 edit_t *edit = (edit_t *) arg; 2264 2265 (void)edit; 2266 file_save_as(); 2267 } 2268 2269 /** File / Exit menu entry selected. 2270 * 2271 * @param mentry Menu entry 2272 * @param arg Argument (edit_t *) 2273 */ 2274 static void edit_file_exit(ui_menu_entry_t *mentry, void *arg) 2275 { 2276 edit_t *edit = (edit_t *) arg; 2277 2278 ui_quit(edit->ui); 2279 } 2280 2281 /** Edit / Cut menu entry selected. 2282 * 2283 * @param mentry Menu entry 2284 * @param arg Argument (edit_t *) 2285 */ 2286 static void edit_edit_cut(ui_menu_entry_t *mentry, void *arg) 2287 { 2288 (void) arg; 2289 edit_cut(); 2290 (void) gfx_update(ui_window_get_gc(edit.window)); 2291 } 2292 2293 /** Edit / Copy menu entry selected. 2294 * 2295 * @param mentry Menu entry 2296 * @param arg Argument (edit_t *) 2297 */ 2298 static void edit_edit_copy(ui_menu_entry_t *mentry, void *arg) 2299 { 2300 (void) arg; 2301 selection_copy(); 2302 } 2303 2304 /** Edit / Paste menu entry selected. 2305 * 2306 * @param mentry Menu entry 2307 * @param arg Argument (edit_t *) 2308 */ 2309 static void edit_edit_paste(ui_menu_entry_t *mentry, void *arg) 2310 { 2311 (void) arg; 2312 edit_paste(); 2313 (void) gfx_update(ui_window_get_gc(edit.window)); 2314 } 2315 2316 /** Edit / Delete menu entry selected. 2317 * 2318 * @param mentry Menu entry 2319 * @param arg Argument (edit_t *) 2320 */ 2321 static void edit_edit_delete(ui_menu_entry_t *mentry, void *arg) 2322 { 2323 (void) arg; 2324 2325 if (selection_active()) 2326 selection_delete(); 1728 2327 1729 2328 pane.rflags |= REDRAW_CARET; 2329 (void) pane_update(&pane); 2330 (void) gfx_update(ui_window_get_gc(edit.window)); 2331 } 2332 2333 /** Edit / Select All menu entry selected. 2334 * 2335 * @param mentry Menu entry 2336 * @param arg Argument (edit_t *) 2337 */ 2338 static void edit_edit_select_all(ui_menu_entry_t *mentry, void *arg) 2339 { 2340 (void) arg; 2341 2342 selection_sel_all(); 2343 pane.rflags |= (REDRAW_CARET | REDRAW_TEXT | REDRAW_STATUS); 2344 pane_update(&pane); 2345 (void) gfx_update(ui_window_get_gc(edit.window)); 2346 } 2347 2348 /** Search / Find menu entry selected. 2349 * 2350 * @param mentry Menu entry 2351 * @param arg Argument (edit_t *) 2352 */ 2353 static void edit_search_find(ui_menu_entry_t *mentry, void *arg) 2354 { 2355 (void) arg; 2356 search_prompt(false); 2357 } 2358 2359 /** Search / Reverse Find menu entry selected. 2360 * 2361 * @param mentry Menu entry 2362 * @param arg Argument (edit_t *) 2363 */ 2364 static void edit_search_reverse_find(ui_menu_entry_t *mentry, void *arg) 2365 { 2366 (void) arg; 2367 search_prompt(true); 2368 } 2369 2370 /** Search / Find Next menu entry selected. 2371 * 2372 * @param mentry Menu entry 2373 * @param arg Argument (edit_t *) 2374 */ 2375 static void edit_search_find_next(ui_menu_entry_t *mentry, void *arg) 2376 { 2377 (void) arg; 2378 search_repeat(); 2379 (void) pane_update(&pane); 2380 (void) gfx_update(ui_window_get_gc(edit.window)); 2381 } 2382 2383 /** Search / Go To Line menu entry selected. 2384 * 2385 * @param mentry Menu entry 2386 * @param arg Argument (edit_t *) 2387 */ 2388 static void edit_search_go_to_line(ui_menu_entry_t *mentry, void *arg) 2389 { 2390 (void) arg; 2391 caret_go_to_line_ask(); 2392 } 2393 2394 /** Save As dialog OK button press. 2395 * 2396 * @param dialog Save As dialog 2397 * @param arg Argument (ui_demo_t *) 2398 * @param fname File name 2399 */ 2400 static void save_as_dialog_bok(ui_file_dialog_t *dialog, void *arg, 2401 const char *fname) 2402 { 2403 edit_t *edit = (edit_t *)arg; 2404 gfx_context_t *gc = ui_window_get_gc(edit->window); 2405 char *cname; 2406 errno_t rc; 2407 2408 ui_file_dialog_destroy(dialog); 2409 // TODO Smarter cursor management 2410 pane.rflags |= REDRAW_CARET; 2411 (void) pane_update(&pane); 2412 gfx_cursor_set_visible(gc, true); 2413 2414 cname = str_dup(fname); 2415 if (cname == NULL) { 2416 printf("Out of memory.\n"); 2417 return; 2418 } 2419 2420 rc = file_save(fname); 2421 if (rc != EOK) 2422 return; 2423 2424 if (doc.file_name != NULL) 2425 free(doc.file_name); 2426 doc.file_name = cname; 2427 2428 } 2429 2430 /** Save As dialog cancel button press. 2431 * 2432 * @param dialog File dialog 2433 * @param arg Argument (ui_demo_t *) 2434 */ 2435 static void save_as_dialog_bcancel(ui_file_dialog_t *dialog, void *arg) 2436 { 2437 edit_t *edit = (edit_t *)arg; 2438 gfx_context_t *gc = ui_window_get_gc(edit->window); 2439 2440 ui_file_dialog_destroy(dialog); 2441 // TODO Smarter cursor management 2442 pane.rflags |= REDRAW_CARET; 2443 (void) pane_update(&pane); 2444 gfx_cursor_set_visible(gc, true); 2445 } 2446 2447 /** Save As dialog close request. 2448 * 2449 * @param dialog File dialog 2450 * @param arg Argument (ui_demo_t *) 2451 */ 2452 static void save_as_dialog_close(ui_file_dialog_t *dialog, void *arg) 2453 { 2454 edit_t *edit = (edit_t *)arg; 2455 gfx_context_t *gc = ui_window_get_gc(edit->window); 2456 2457 ui_file_dialog_destroy(dialog); 2458 // TODO Smarter cursor management 2459 pane.rflags |= REDRAW_CARET; 2460 (void) pane_update(&pane); 2461 gfx_cursor_set_visible(gc, true); 2462 } 2463 2464 /** Go To Line dialog OK button press. 2465 * 2466 * @param dialog Go To Line dialog 2467 * @param arg Argument (ui_demo_t *) 2468 * @param text Submitted text 2469 */ 2470 static void go_to_line_dialog_bok(ui_prompt_dialog_t *dialog, void *arg, 2471 const char *text) 2472 { 2473 edit_t *edit = (edit_t *) arg; 2474 gfx_context_t *gc = ui_window_get_gc(edit->window); 2475 char *endptr; 2476 int line; 2477 2478 ui_prompt_dialog_destroy(dialog); 2479 line = strtol(text, &endptr, 10); 2480 if (*endptr != '\0') { 2481 status_display("Invalid number entered."); 2482 return; 2483 } 2484 2485 caret_move_absolute(line, pane.ideal_column, dir_before, false); 2486 // TODO Smarter cursor management 2487 (void) pane_update(&pane); 2488 gfx_cursor_set_visible(gc, true); 2489 (void) gfx_update(gc); 2490 } 2491 2492 /** Go To Line dialog cancel button press. 2493 * 2494 * @param dialog File dialog 2495 * @param arg Argument (ui_demo_t *) 2496 */ 2497 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg) 2498 { 2499 edit_t *edit = (edit_t *) arg; 2500 gfx_context_t *gc = ui_window_get_gc(edit->window); 2501 2502 ui_prompt_dialog_destroy(dialog); 2503 // TODO Smarter cursor management 2504 pane.rflags |= REDRAW_CARET; 2505 (void) pane_update(&pane); 2506 gfx_cursor_set_visible(gc, true); 2507 } 2508 2509 /** Go To Line dialog close request. 2510 * 2511 * @param dialog File dialog 2512 * @param arg Argument (ui_demo_t *) 2513 */ 2514 static void go_to_line_dialog_close(ui_prompt_dialog_t *dialog, void *arg) 2515 { 2516 edit_t *edit = (edit_t *) arg; 2517 gfx_context_t *gc = ui_window_get_gc(edit->window); 2518 2519 ui_prompt_dialog_destroy(dialog); 2520 // TODO Smarter cursor management 2521 pane.rflags |= REDRAW_CARET; 2522 (void) pane_update(&pane); 2523 gfx_cursor_set_visible(gc, true); 2524 } 2525 2526 /** Search dialog OK button press. 2527 * 2528 * @param dialog Search dialog 2529 * @param arg Argument (ui_demo_t *) 2530 * @param text Submitted text 2531 */ 2532 static void search_dialog_bok(ui_prompt_dialog_t *dialog, void *arg, 2533 const char *text) 2534 { 2535 edit_t *edit = (edit_t *) arg; 2536 gfx_context_t *gc = ui_window_get_gc(edit->window); 2537 char *pattern; 2538 bool reverse; 2539 2540 ui_prompt_dialog_destroy(dialog); 2541 2542 /* Abort if search phrase is empty */ 2543 if (text[0] == '\0') 2544 return; 2545 2546 pattern = str_dup(text); 2547 reverse = pane.search_reverse; 2548 2549 if (pane.previous_search) 2550 free(pane.previous_search); 2551 pane.previous_search = pattern; 2552 pane.previous_search_reverse = reverse; 2553 2554 search(pattern, reverse); 2555 2556 // TODO Smarter cursor management 2557 (void) pane_update(&pane); 2558 gfx_cursor_set_visible(gc, true); 2559 (void) gfx_update(gc); 2560 } 2561 2562 /** Search dialog cancel button press. 2563 * 2564 * @param dialog File dialog 2565 * @param arg Argument (ui_demo_t *) 2566 */ 2567 static void search_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg) 2568 { 2569 edit_t *edit = (edit_t *) arg; 2570 gfx_context_t *gc = ui_window_get_gc(edit->window); 2571 2572 ui_prompt_dialog_destroy(dialog); 2573 // TODO Smarter cursor management 2574 pane.rflags |= REDRAW_CARET; 2575 (void) pane_update(&pane); 2576 gfx_cursor_set_visible(gc, true); 2577 } 2578 2579 /** Search dialog close request. 2580 * 2581 * @param dialog File dialog 2582 * @param arg Argument (ui_demo_t *) 2583 */ 2584 static void search_dialog_close(ui_prompt_dialog_t *dialog, void *arg) 2585 { 2586 edit_t *edit = (edit_t *) arg; 2587 gfx_context_t *gc = ui_window_get_gc(edit->window); 2588 2589 ui_prompt_dialog_destroy(dialog); 2590 // TODO Smarter cursor management 2591 pane.rflags |= REDRAW_CARET; 2592 (void) pane_update(&pane); 2593 gfx_cursor_set_visible(gc, true); 1730 2594 } 1731 2595
Note:
See TracChangeset
for help on using the changeset viewer.