Changes in uspace/app/edit/edit.c [87822ce:3c22438a] in mainline
- File:
-
- 1 edited
-
uspace/app/edit/edit.c (modified) (33 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/edit/edit.c
r87822ce r3c22438a 1 1 /* 2 * Copyright (c) 20 09Jiri Svoboda2 * Copyright (c) 2026 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 … … 132 177 static void pos_handle(pos_event_t *ev); 133 178 179 static errno_t file_new(void); 180 static void file_open(void); 181 static errno_t file_open_file(const char *fname); 134 182 static errno_t file_save(char const *fname); 135 183 static void file_save_as(void); 136 static errno_t file_insert(c har *fname);184 static errno_t file_insert(const char *fname); 137 185 static errno_t file_save_range(char const *fname, spt_t const *spos, 138 186 spt_t const *epos); 139 187 static char *range_get_str(spt_t const *spos, spt_t const *epos); 140 188 141 static char *prompt(char const *prompt, char const *init_value); 142 143 static void pane_text_display(void); 189 static errno_t pane_init(ui_window_t *, pane_t *); 190 static void pane_fini(pane_t *); 191 static ui_control_t *pane_ctl(pane_t *); 192 static errno_t pane_update(pane_t *); 193 static errno_t pane_text_display(pane_t *); 144 194 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);195 static errno_t pane_row_range_display(pane_t *, int r0, int r1); 196 static void pane_status_display(pane_t *); 197 static void pane_caret_display(pane_t *); 148 198 149 199 static void insert_char(char32_t c); … … 164 214 static void selection_delete(void); 165 215 static void selection_copy(void); 216 static void edit_cut(void); 217 static void edit_paste(void); 166 218 static void insert_clipboard_data(void); 167 219 … … 185 237 186 238 static void status_display(char const *str); 239 static errno_t edit_ui_create(edit_t *); 240 static void edit_ui_destroy(edit_t *); 241 242 static void edit_wnd_resize(ui_window_t *, void *); 243 static void edit_wnd_close(ui_window_t *, void *); 244 static void edit_wnd_focus(ui_window_t *, void *, unsigned); 245 static void edit_wnd_kbd_event(ui_window_t *, void *, kbd_event_t *); 246 static void edit_wnd_unfocus(ui_window_t *, void *, unsigned); 247 248 static ui_window_cb_t edit_window_cb = { 249 .resize = edit_wnd_resize, 250 .close = edit_wnd_close, 251 .focus = edit_wnd_focus, 252 .kbd = edit_wnd_kbd_event, 253 .unfocus = edit_wnd_unfocus 254 }; 255 256 static void edit_menubar_activate(ui_menu_bar_t *, void *); 257 static void edit_menubar_deactivate(ui_menu_bar_t *, void *); 258 259 static ui_menu_bar_cb_t edit_menubar_cb = { 260 .activate = edit_menubar_activate, 261 .deactivate = edit_menubar_deactivate 262 }; 263 264 static void edit_file_new(ui_menu_entry_t *, void *); 265 static void edit_file_open(ui_menu_entry_t *, void *); 266 static void edit_file_save(ui_menu_entry_t *, void *); 267 static void edit_file_save_as(ui_menu_entry_t *, void *); 268 static void edit_file_exit(ui_menu_entry_t *, void *); 269 static void edit_edit_cut(ui_menu_entry_t *, void *); 270 static void edit_edit_copy(ui_menu_entry_t *, void *); 271 static void edit_edit_paste(ui_menu_entry_t *, void *); 272 static void edit_edit_delete(ui_menu_entry_t *, void *); 273 static void edit_edit_select_all(ui_menu_entry_t *, void *); 274 static void edit_search_find(ui_menu_entry_t *, void *); 275 static void edit_search_reverse_find(ui_menu_entry_t *, void *); 276 static void edit_search_find_next(ui_menu_entry_t *, void *); 277 static void edit_search_go_to_line(ui_menu_entry_t *, void *); 278 279 static void pane_ctl_destroy(void *); 280 static errno_t pane_ctl_paint(void *); 281 static ui_evclaim_t pane_ctl_pos_event(void *, pos_event_t *); 282 283 /** Pabe control ops */ 284 ui_control_ops_t pane_ctl_ops = { 285 .destroy = pane_ctl_destroy, 286 .paint = pane_ctl_paint, 287 .pos_event = pane_ctl_pos_event 288 }; 289 290 static void open_dialog_bok(ui_file_dialog_t *, void *, const char *); 291 static void open_dialog_bcancel(ui_file_dialog_t *, void *); 292 static void open_dialog_close(ui_file_dialog_t *, void *); 293 294 static ui_file_dialog_cb_t open_dialog_cb = { 295 .bok = open_dialog_bok, 296 .bcancel = open_dialog_bcancel, 297 .close = open_dialog_close 298 }; 299 300 static void save_as_dialog_bok(ui_file_dialog_t *, void *, const char *); 301 static void save_as_dialog_bcancel(ui_file_dialog_t *, void *); 302 static void save_as_dialog_close(ui_file_dialog_t *, void *); 303 304 static ui_file_dialog_cb_t save_as_dialog_cb = { 305 .bok = save_as_dialog_bok, 306 .bcancel = save_as_dialog_bcancel, 307 .close = save_as_dialog_close 308 }; 309 310 static void go_to_line_dialog_bok(ui_prompt_dialog_t *, void *, const char *); 311 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *, void *); 312 static void go_to_line_dialog_close(ui_prompt_dialog_t *, void *); 313 314 static ui_prompt_dialog_cb_t go_to_line_dialog_cb = { 315 .bok = go_to_line_dialog_bok, 316 .bcancel = go_to_line_dialog_bcancel, 317 .close = go_to_line_dialog_close 318 }; 319 320 static void search_dialog_bok(ui_prompt_dialog_t *, void *, const char *); 321 static void search_dialog_bcancel(ui_prompt_dialog_t *, void *); 322 static void search_dialog_close(ui_prompt_dialog_t *, void *); 323 324 static ui_prompt_dialog_cb_t search_dialog_cb = { 325 .bok = search_dialog_bok, 326 .bcancel = search_dialog_bcancel, 327 .close = search_dialog_close 328 }; 187 329 188 330 int main(int argc, char *argv[]) 189 331 { 190 cons_event_t ev;191 bool new_file;192 332 errno_t rc; 193 333 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 334 pane.sh_row = 1; 202 335 pane.sh_column = 1; 203 336 204 /* Start with an empty sheet. */ 205 rc = sheet_create(&doc.sh); 206 if (rc != EOK) { 207 printf("Out of memory.\n"); 208 return -1; 209 } 210 211 /* Place caret at the beginning of file. */ 212 spt_t sof; 213 pt_get_sof(&sof); 214 sheet_place_tag(doc.sh, &sof, &pane.caret_pos); 215 pane.ideal_column = 1; 337 /* Create UI */ 338 rc = edit_ui_create(&edit); 339 if (rc != EOK) 340 return 1; 216 341 217 342 if (argc == 2) { 218 343 doc.file_name = str_dup(argv[1]); 344 rc = file_open_file(argv[1]); 345 if (rc != EOK) { 346 status_display("File not found. Starting empty file."); 347 rc = file_new(); 348 } 219 349 } else if (argc > 1) { 220 350 printf("Invalid arguments.\n"); 221 351 return -2; 222 352 } else { 223 doc.file_name = NULL; 224 } 225 226 new_file = false; 227 228 if (doc.file_name == NULL || file_insert(doc.file_name) != EOK) 229 new_file = true; 230 231 /* Place selection start tag. */ 232 sheet_place_tag(doc.sh, &sof, &pane.sel_start); 233 234 /* Move to beginning of file. */ 235 pt_get_sof(&sof); 236 caret_move(sof, true, true); 353 rc = file_new(); 354 } 237 355 238 356 /* Initial display */ 239 cursor_visible = true; 240 241 cursor_hide(); 242 console_clear(con); 243 pane_text_display(); 244 pane_status_display(); 245 if (new_file && doc.file_name != NULL) 246 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 357 rc = ui_window_paint(edit.window); 358 if (rc != EOK) { 359 printf("Error painting window.\n"); 360 return rc; 361 } 362 363 ui_run(edit.ui); 364 365 edit_ui_destroy(&edit); 288 366 return 0; 367 } 368 369 /** Set menu bar rectangle. 370 * 371 * Set the menu bar rectangle based on editor window dimensions. 372 * Used when window is created or resized. 373 * 374 * @param edit Editor 375 */ 376 static void edit_menubar_set_rect(edit_t *edit) 377 { 378 gfx_rect_t arect; 379 gfx_rect_t rect; 380 381 ui_window_get_app_rect(edit->window, &arect); 382 383 rect.p0 = arect.p0; 384 rect.p1.x = arect.p1.x; 385 rect.p1.y = arect.p0.y + 1; 386 ui_menu_bar_set_rect(edit->menubar, &rect); 387 } 388 389 /** Set status bar rectangle. 390 * 391 * Set the status bar rectangle based on editor window dimensions. 392 * Used when window is created or resized. 393 * 394 * @param edit Editor 395 */ 396 static void edit_status_set_rect(edit_t *edit) 397 { 398 gfx_rect_t arect; 399 gfx_rect_t rect; 400 401 ui_window_get_app_rect(edit->window, &arect); 402 rect.p0.x = arect.p0.x; 403 rect.p0.y = arect.p1.y - 1; 404 rect.p1 = arect.p1; 405 ui_label_set_rect(edit->status, &rect); 406 } 407 408 /** Create text editor UI. 409 * 410 * @param edit Editor 411 * @return EOK on success or an error code 412 */ 413 static errno_t edit_ui_create(edit_t *edit) 414 { 415 errno_t rc; 416 ui_wnd_params_t params; 417 ui_fixed_t *fixed = NULL; 418 ui_menu_t *mfile = NULL; 419 ui_menu_t *medit = NULL; 420 ui_menu_entry_t *mnew = NULL; 421 ui_menu_entry_t *mopen = NULL; 422 ui_menu_entry_t *msave = NULL; 423 ui_menu_entry_t *msaveas = NULL; 424 ui_menu_entry_t *mfsep = NULL; 425 ui_menu_entry_t *mexit = NULL; 426 ui_menu_entry_t *mcut = NULL; 427 ui_menu_entry_t *mcopy = NULL; 428 ui_menu_entry_t *mpaste = NULL; 429 ui_menu_entry_t *mdelete = NULL; 430 ui_menu_entry_t *mesep = NULL; 431 ui_menu_entry_t *mselall = NULL; 432 ui_menu_t *msearch = NULL; 433 ui_menu_entry_t *mfind = NULL; 434 ui_menu_entry_t *mfindr = NULL; 435 ui_menu_entry_t *mfindn = NULL; 436 ui_menu_entry_t *mssep = NULL; 437 ui_menu_entry_t *mgoto = NULL; 438 439 rc = ui_create(UI_CONSOLE_DEFAULT, &edit->ui); 440 if (rc != EOK) { 441 printf("Error creating UI on display %s.\n", 442 UI_CONSOLE_DEFAULT); 443 goto error; 444 } 445 446 ui_wnd_params_init(¶ms); 447 params.caption = "Text Editor"; 448 params.style &= ~ui_wds_decorated; 449 params.placement = ui_wnd_place_full_screen; 450 451 rc = ui_window_create(edit->ui, ¶ms, &edit->window); 452 if (rc != EOK) { 453 printf("Error creating window.\n"); 454 goto error; 455 } 456 457 ui_window_set_cb(edit->window, &edit_window_cb, (void *) edit); 458 459 edit->ui_res = ui_window_get_res(edit->window); 460 461 rc = ui_fixed_create(&fixed); 462 if (rc != EOK) { 463 printf("Error creating fixed layout.\n"); 464 return rc; 465 } 466 467 rc = ui_menu_bar_create(edit->ui, edit->window, &edit->menubar); 468 if (rc != EOK) { 469 printf("Error creating menu bar.\n"); 470 return rc; 471 } 472 473 ui_menu_bar_set_cb(edit->menubar, &edit_menubar_cb, (void *) edit); 474 475 rc = ui_menu_dd_create(edit->menubar, "~F~ile", NULL, &mfile); 476 if (rc != EOK) { 477 printf("Error creating menu.\n"); 478 return rc; 479 } 480 481 rc = ui_menu_entry_create(mfile, "~N~ew", "Ctrl-N", &mnew); 482 if (rc != EOK) { 483 printf("Error creating menu.\n"); 484 return rc; 485 } 486 487 ui_menu_entry_set_cb(mnew, edit_file_new, (void *) edit); 488 489 rc = ui_menu_entry_create(mfile, "~O~pen", "Ctrl-O", &mopen); 490 if (rc != EOK) { 491 printf("Error creating menu.\n"); 492 return rc; 493 } 494 495 ui_menu_entry_set_cb(mopen, edit_file_open, (void *) edit); 496 497 rc = ui_menu_entry_create(mfile, "~S~ave", "Ctrl-S", &msave); 498 if (rc != EOK) { 499 printf("Error creating menu.\n"); 500 return rc; 501 } 502 503 ui_menu_entry_set_cb(msave, edit_file_save, (void *) edit); 504 505 rc = ui_menu_entry_create(mfile, "Save ~A~s", "Ctrl-E", &msaveas); 506 if (rc != EOK) { 507 printf("Error creating menu.\n"); 508 return rc; 509 } 510 511 ui_menu_entry_set_cb(msaveas, edit_file_save_as, (void *) edit); 512 513 rc = ui_menu_entry_sep_create(mfile, &mfsep); 514 if (rc != EOK) { 515 printf("Error creating menu.\n"); 516 return rc; 517 } 518 519 rc = ui_menu_entry_create(mfile, "E~x~it", "Ctrl-Q", &mexit); 520 if (rc != EOK) { 521 printf("Error creating menu.\n"); 522 return rc; 523 } 524 525 ui_menu_entry_set_cb(mexit, edit_file_exit, (void *) edit); 526 527 rc = ui_menu_dd_create(edit->menubar, "~E~dit", NULL, &medit); 528 if (rc != EOK) { 529 printf("Error creating menu.\n"); 530 return rc; 531 } 532 533 rc = ui_menu_entry_create(medit, "Cu~t~", "Ctrl-X", &mcut); 534 if (rc != EOK) { 535 printf("Error creating menu.\n"); 536 return rc; 537 } 538 539 ui_menu_entry_set_cb(mcut, edit_edit_cut, (void *) edit); 540 541 rc = ui_menu_entry_create(medit, "~C~opy", "Ctrl-C", &mcopy); 542 if (rc != EOK) { 543 printf("Error creating menu.\n"); 544 return rc; 545 } 546 547 ui_menu_entry_set_cb(mcopy, edit_edit_copy, (void *) edit); 548 549 rc = ui_menu_entry_create(medit, "~P~aste", "Ctrl-V", &mpaste); 550 if (rc != EOK) { 551 printf("Error creating menu.\n"); 552 return rc; 553 } 554 555 ui_menu_entry_set_cb(mpaste, edit_edit_paste, (void *) edit); 556 557 rc = ui_menu_entry_create(medit, "~D~elete", "Del", &mdelete); 558 if (rc != EOK) { 559 printf("Error creating menu.\n"); 560 return rc; 561 } 562 563 ui_menu_entry_set_cb(mdelete, edit_edit_delete, (void *) edit); 564 565 rc = ui_menu_entry_sep_create(medit, &mesep); 566 if (rc != EOK) { 567 printf("Error creating menu.\n"); 568 return rc; 569 } 570 571 rc = ui_menu_entry_create(medit, "Select ~A~ll", "Ctrl-A", &mselall); 572 if (rc != EOK) { 573 printf("Error creating menu.\n"); 574 return rc; 575 } 576 577 ui_menu_entry_set_cb(mselall, edit_edit_select_all, (void *) edit); 578 579 rc = ui_menu_dd_create(edit->menubar, "~S~earch", NULL, &msearch); 580 if (rc != EOK) { 581 printf("Error creating menu.\n"); 582 return rc; 583 } 584 585 rc = ui_menu_entry_create(msearch, "~F~ind", "Ctrl-F", &mfind); 586 if (rc != EOK) { 587 printf("Error creating menu.\n"); 588 return rc; 589 } 590 591 ui_menu_entry_set_cb(mfind, edit_search_find, (void *) edit); 592 593 rc = ui_menu_entry_create(msearch, "~R~everse Find", "Ctrl-Shift-F", &mfindr); 594 if (rc != EOK) { 595 printf("Error creating menu.\n"); 596 return rc; 597 } 598 599 ui_menu_entry_set_cb(mfindr, edit_search_reverse_find, (void *) edit); 600 601 rc = ui_menu_entry_create(msearch, "Find ~N~ext", "Ctrl-R", &mfindn); 602 if (rc != EOK) { 603 printf("Error creating menu.\n"); 604 return rc; 605 } 606 607 ui_menu_entry_set_cb(mfindn, edit_search_find_next, (void *) edit); 608 609 rc = ui_menu_entry_sep_create(msearch, &mssep); 610 if (rc != EOK) { 611 printf("Error creating menu.\n"); 612 return rc; 613 } 614 615 rc = ui_menu_entry_create(msearch, "Go To ~L~ine", "Ctrl-L", &mgoto); 616 if (rc != EOK) { 617 printf("Error creating menu.\n"); 618 return rc; 619 } 620 621 ui_menu_entry_set_cb(mgoto, edit_search_go_to_line, (void *) edit); 622 623 edit_menubar_set_rect(edit); 624 625 rc = ui_fixed_add(fixed, ui_menu_bar_ctl(edit->menubar)); 626 if (rc != EOK) { 627 printf("Error adding control to layout.\n"); 628 return rc; 629 } 630 631 rc = pane_init(edit->window, &pane); 632 if (rc != EOK) { 633 printf("Error initializing pane.\n"); 634 return rc; 635 } 636 637 rc = ui_fixed_add(fixed, pane_ctl(&pane)); 638 if (rc != EOK) { 639 printf("Error adding control to layout.\n"); 640 return rc; 641 } 642 643 rc = ui_label_create(edit->ui_res, "", &edit->status); 644 if (rc != EOK) { 645 printf("Error creating menu bar.\n"); 646 return rc; 647 } 648 649 edit_status_set_rect(edit); 650 651 rc = ui_fixed_add(fixed, ui_label_ctl(edit->status)); 652 if (rc != EOK) { 653 printf("Error adding control to layout.\n"); 654 return rc; 655 } 656 657 ui_window_add(edit->window, ui_fixed_ctl(fixed)); 658 return EOK; 659 error: 660 if (edit->window != NULL) 661 ui_window_destroy(edit->window); 662 if (edit->ui != NULL) 663 ui_destroy(edit->ui); 664 return rc; 665 } 666 667 /** Destroy text editor UI. 668 * 669 * @param edit Editor 670 */ 671 static void edit_ui_destroy(edit_t *edit) 672 { 673 ui_window_destroy(edit->window); 674 ui_destroy(edit->ui); 289 675 } 290 676 … … 309 695 } 310 696 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 697 static void cursor_setvis(bool visible) 322 698 { 323 if (cursor_visible != visible) { 324 console_cursor_visibility(con, visible); 325 cursor_visible = visible; 326 } 699 gfx_context_t *gc = ui_window_get_gc(edit.window); 700 701 (void) gfx_cursor_set_visible(gc, visible); 327 702 } 328 703 … … 400 775 switch (ev->key) { 401 776 case KC_Q: 402 done = true; 777 ui_quit(edit.ui); 778 break; 779 case KC_N: 780 file_new(); 781 break; 782 case KC_O: 783 file_open(); 403 784 break; 404 785 case KC_S: … … 415 796 break; 416 797 case KC_V: 417 selection_delete(); 418 insert_clipboard_data(); 419 pane.rflags |= REDRAW_TEXT; 420 caret_update(); 798 edit_paste(); 421 799 break; 422 800 case KC_X: 423 selection_copy(); 424 selection_delete(); 425 pane.rflags |= REDRAW_TEXT; 426 caret_update(); 801 edit_cut(); 427 802 break; 428 803 case KC_A: … … 441 816 search_prompt(false); 442 817 break; 443 case KC_ N:818 case KC_R: 444 819 search_repeat(); 445 820 break; … … 490 865 491 866 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 ;867 bc.row = pane.sh_row + ev->vpos - pane.rect.p0.y; 868 bc.column = pane.sh_column + ev->hpos - pane.rect.p0.x; 494 869 sheet_get_cell_pt(doc.sh, &bc, dir_before, &pt); 495 870 … … 497 872 498 873 caret_move(pt, select, true); 874 pane_update(&pane); 499 875 } 500 876 } … … 579 955 } 580 956 957 /** Create new document. */ 958 static errno_t file_new(void) 959 { 960 errno_t rc; 961 sheet_t *sh; 962 963 /* Create empty sheet. */ 964 rc = sheet_create(&sh); 965 if (rc != EOK) { 966 printf("Out of memory.\n"); 967 return ENOMEM; 968 } 969 970 if (doc.sh != NULL) 971 sheet_destroy(doc.sh); 972 973 doc.sh = sh; 974 975 /* Place caret at the beginning of file. */ 976 spt_t sof; 977 pt_get_sof(&sof); 978 sheet_place_tag(doc.sh, &sof, &pane.caret_pos); 979 pane.ideal_column = 1; 980 981 doc.file_name = NULL; 982 983 /* Place selection start tag. */ 984 sheet_place_tag(doc.sh, &sof, &pane.sel_start); 985 986 /* Move to beginning of file. */ 987 pt_get_sof(&sof); 988 989 caret_move(sof, true, true); 990 991 pane_status_display(&pane); 992 pane_caret_display(&pane); 993 pane_text_display(&pane); 994 cursor_setvis(true); 995 996 return EOK; 997 } 998 999 /** Open Open File dialog. */ 1000 static void file_open(void) 1001 { 1002 const char *old_fname = (doc.file_name != NULL) ? doc.file_name : ""; 1003 ui_file_dialog_params_t fdparams; 1004 ui_file_dialog_t *dialog; 1005 errno_t rc; 1006 1007 ui_file_dialog_params_init(&fdparams); 1008 fdparams.caption = "Open File"; 1009 fdparams.ifname = old_fname; 1010 1011 rc = ui_file_dialog_create(edit.ui, &fdparams, &dialog); 1012 if (rc != EOK) { 1013 printf("Error creating message dialog.\n"); 1014 return; 1015 } 1016 1017 ui_file_dialog_set_cb(dialog, &open_dialog_cb, &edit); 1018 } 1019 1020 /** Open exising document. */ 1021 static errno_t file_open_file(const char *fname) 1022 { 1023 errno_t rc; 1024 sheet_t *sh; 1025 char *fn; 1026 1027 /* Create empty sheet. */ 1028 rc = sheet_create(&sh); 1029 if (rc != EOK) { 1030 printf("Out of memory.\n"); 1031 return ENOMEM; 1032 } 1033 1034 fn = str_dup(fname); 1035 if (fn == NULL) { 1036 sheet_destroy(sh); 1037 return ENOMEM; 1038 } 1039 1040 if (doc.sh != NULL) 1041 sheet_destroy(doc.sh); 1042 1043 doc.sh = sh; 1044 1045 /* Place caret at the beginning of file. */ 1046 spt_t sof; 1047 pt_get_sof(&sof); 1048 sheet_place_tag(doc.sh, &sof, &pane.caret_pos); 1049 pane.ideal_column = 1; 1050 1051 rc = file_insert(fname); 1052 if (rc != EOK) 1053 return rc; 1054 1055 doc.file_name = fn; 1056 1057 /* Place selection start tag. */ 1058 sheet_place_tag(doc.sh, &sof, &pane.sel_start); 1059 1060 /* Move to beginning of file. */ 1061 pt_get_sof(&sof); 1062 1063 caret_move(sof, true, true); 1064 1065 pane_status_display(&pane); 1066 pane_caret_display(&pane); 1067 pane_text_display(&pane); 1068 cursor_setvis(true); 1069 1070 return EOK; 1071 } 1072 581 1073 /** Save the document. */ 582 1074 static errno_t file_save(char const *fname) … … 606 1098 } 607 1099 608 /** Change document name and save. */1100 /** Open Save As dialog. */ 609 1101 static void file_save_as(void) 610 1102 { 611 1103 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."); 1104 ui_file_dialog_params_t fdparams; 1105 ui_file_dialog_t *dialog; 1106 errno_t rc; 1107 1108 ui_file_dialog_params_init(&fdparams); 1109 fdparams.caption = "Save As"; 1110 fdparams.ifname = old_fname; 1111 1112 rc = ui_file_dialog_create(edit.ui, &fdparams, &dialog); 1113 if (rc != EOK) { 1114 printf("Error creating message dialog.\n"); 617 1115 return; 618 1116 } 619 1117 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; 1118 ui_file_dialog_set_cb(dialog, &save_as_dialog_cb, &edit); 694 1119 } 695 1120 … … 699 1124 * of the caret. 700 1125 */ 701 static errno_t file_insert(c har *fname)1126 static errno_t file_insert(const char *fname) 702 1127 { 703 1128 FILE *f; … … 726 1151 727 1152 bcnt -= off; 728 mem cpy(buf, buf + off, bcnt);1153 memmove(buf, buf + off, bcnt); 729 1154 730 1155 insert_char(c); … … 808 1233 } 809 1234 810 static void pane_text_display(void) 811 { 1235 static void pane_set_rect(pane_t *pane) 1236 { 1237 gfx_rect_t arect; 1238 1239 ui_window_get_app_rect(pane->window, &arect); 1240 pane->rect.p0.x = arect.p0.x; 1241 pane->rect.p0.y = arect.p0.y + 1; 1242 pane->rect.p1.x = arect.p1.x; 1243 pane->rect.p1.y = arect.p1.y - 1; 1244 1245 pane->columns = pane->rect.p1.x - pane->rect.p0.x; 1246 pane->rows = pane->rect.p1.y - pane->rect.p0.y; 1247 } 1248 1249 /** Initialize pane. 1250 * 1251 * TODO: Replace with pane_create() that allocates the pane. 1252 * 1253 * @param window Editor window 1254 * @param pane Pane 1255 * @return EOK on success or an error code 1256 */ 1257 static errno_t pane_init(ui_window_t *window, pane_t *pane) 1258 { 1259 errno_t rc; 1260 1261 pane->control = NULL; 1262 pane->color = NULL; 1263 pane->sel_color = NULL; 1264 1265 rc = ui_control_new(&pane_ctl_ops, (void *) pane, &pane->control); 1266 if (rc != EOK) 1267 goto error; 1268 1269 rc = gfx_color_new_ega(0x07, &pane->color); 1270 if (rc != EOK) 1271 goto error; 1272 1273 rc = gfx_color_new_ega(0x1e, &pane->sel_color); 1274 if (rc != EOK) 1275 goto error; 1276 1277 pane->res = ui_window_get_res(window); 1278 pane->window = window; 1279 1280 pane_set_rect(pane); 1281 return EOK; 1282 error: 1283 if (pane->control != NULL) { 1284 ui_control_delete(pane->control); 1285 pane->control = NULL; 1286 } 1287 1288 if (pane->color != NULL) { 1289 gfx_color_delete(pane->color); 1290 pane->color = NULL; 1291 } 1292 1293 return rc; 1294 } 1295 1296 static void pane_resize(pane_t *pane) 1297 { 1298 pane_set_rect(pane); 1299 1300 /* Scroll in case cursor is now outside of the editor pane. */ 1301 caret_move_relative(0, 0, dir_before, true); 1302 1303 pane_caret_display(pane); 1304 } 1305 1306 /** Finalize pane. 1307 * 1308 * TODO: Replace with pane_destroy() that deallocates the pane. 1309 * 1310 * @param pane Pane 1311 */ 1312 static void pane_fini(pane_t *pane) 1313 { 1314 gfx_color_delete(pane->color); 1315 pane->color = NULL; 1316 gfx_color_delete(pane->sel_color); 1317 pane->sel_color = NULL; 1318 ui_control_delete(pane->control); 1319 pane->control = NULL; 1320 } 1321 1322 /** Return base control object for a pane. 1323 * 1324 * @param pane Pane 1325 * @return Base UI cntrol 1326 */ 1327 static ui_control_t *pane_ctl(pane_t *pane) 1328 { 1329 return pane->control; 1330 } 1331 1332 /** Repaint parts of pane that need updating. 1333 * 1334 * @param pane Pane 1335 * @return EOK on succes or an error code 1336 */ 1337 static errno_t pane_update(pane_t *pane) 1338 { 1339 errno_t rc; 1340 1341 if (pane->rflags & REDRAW_TEXT) { 1342 rc = pane_text_display(pane); 1343 if (rc != EOK) 1344 return rc; 1345 } 1346 1347 if (pane->rflags & REDRAW_ROW) 1348 pane_row_display(); 1349 1350 if (pane->rflags & REDRAW_STATUS) 1351 pane_status_display(pane); 1352 1353 if (pane->rflags & REDRAW_CARET) 1354 pane_caret_display(pane); 1355 1356 pane->rflags &= ~(REDRAW_TEXT | REDRAW_ROW | REDRAW_STATUS | 1357 REDRAW_CARET); 1358 return EOK; 1359 } 1360 1361 /** Display pane text. 1362 * 1363 * @param pane Pane 1364 * @return EOK on success or an error code 1365 */ 1366 static errno_t pane_text_display(pane_t *pane) 1367 { 1368 gfx_rect_t rect; 1369 gfx_context_t *gc; 1370 errno_t rc; 812 1371 int sh_rows, rows; 813 1372 814 1373 sheet_get_num_rows(doc.sh, &sh_rows); 815 rows = min(sh_rows - pane .sh_row + 1, pane.rows);1374 rows = min(sh_rows - pane->sh_row + 1, pane->rows); 816 1375 817 1376 /* Draw rows from the sheet. */ 818 1377 819 console_set_pos(con, 0, 0); 820 pane_row_range_display(0, rows); 1378 rc = pane_row_range_display(pane, 0, rows); 1379 if (rc != EOK) 1380 return rc; 821 1381 822 1382 /* Clear the remaining rows if file is short. */ 823 1383 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; 1384 gc = ui_window_get_gc(pane->window); 1385 1386 rc = gfx_set_color(gc, pane->color); 1387 if (rc != EOK) 1388 goto error; 1389 1390 rect.p0.x = pane->rect.p0.x; 1391 rect.p0.y = pane->rect.p0.y + rows; 1392 rect.p1.x = pane->rect.p1.x; 1393 rect.p1.y = pane->rect.p1.y; 1394 1395 rc = gfx_fill_rect(gc, &rect); 1396 if (rc != EOK) 1397 goto error; 1398 1399 pane->rflags &= ~REDRAW_ROW; 1400 return EOK; 1401 error: 1402 return rc; 835 1403 } 836 1404 … … 846 1414 847 1415 ridx = coord.row - pane.sh_row; 848 pane_row_range_display(ridx, ridx + 1);1416 (void) pane_row_range_display(&pane, ridx, ridx + 1); 849 1417 pane.rflags |= (REDRAW_STATUS | REDRAW_CARET); 850 1418 } 851 1419 852 static void pane_row_range_display(int r0, int r1) 853 { 854 int i, j, fill; 1420 /** Display a range of rows of text. 1421 * 1422 * @param r0 Start row (inclusive) 1423 * @param r1 End row (exclusive) 1424 * @return EOk on success or an error code 1425 */ 1426 static errno_t pane_row_range_display(pane_t *pane, int r0, int r1) 1427 { 1428 int i, fill; 855 1429 spt_t rb, re, dep, pt; 856 1430 coord_t rbc, rec; 857 1431 char row_buf[ROW_BUF_SIZE]; 1432 char cbuf[STR_BOUNDS(1) + 1]; 858 1433 char32_t c; 859 1434 size_t pos, size; 1435 size_t cpos; 860 1436 int s_column; 861 1437 coord_t csel_start, csel_end, ctmp; 1438 gfx_font_t *font; 1439 gfx_context_t *gc; 1440 gfx_text_fmt_t fmt; 1441 gfx_coord2_t tpos; 1442 gfx_rect_t rect; 1443 errno_t rc; 1444 1445 font = ui_resource_get_font(edit.ui_res); 1446 gc = ui_window_get_gc(edit.window); 1447 1448 gfx_text_fmt_init(&fmt); 1449 fmt.font = font; 1450 fmt.color = pane->color; 862 1451 863 1452 /* Determine selection start and end. */ 864 1453 865 tag_get_pt(&pane .sel_start, &pt);1454 tag_get_pt(&pane->sel_start, &pt); 866 1455 spt_get_coord(&pt, &csel_start); 867 1456 868 tag_get_pt(&pane .caret_pos, &pt);1457 tag_get_pt(&pane->caret_pos, &pt); 869 1458 spt_get_coord(&pt, &csel_end); 870 1459 … … 877 1466 /* Draw rows from the sheet. */ 878 1467 879 console_set_pos(con, 0, 0);880 1468 for (i = r0; i < r1; ++i) { 1469 tpos.x = pane->rect.p0.x; 1470 tpos.y = pane->rect.p0.y + i; 1471 881 1472 /* Starting point for row display */ 882 rbc.row = pane .sh_row + i;883 rbc.column = pane .sh_column;1473 rbc.row = pane->sh_row + i; 1474 rbc.column = pane->sh_column; 884 1475 sheet_get_cell_pt(doc.sh, &rbc, dir_before, &rb); 885 1476 886 1477 /* Ending point for row display */ 887 rec.row = pane .sh_row + i;888 rec.column = pane .sh_column + pane.columns;1478 rec.row = pane->sh_row + i; 1479 rec.column = pane->sh_column + pane->columns; 889 1480 sheet_get_cell_pt(doc.sh, &rec, dir_before, &re); 890 1481 … … 896 1487 if (coord_cmp(&csel_start, &rbc) <= 0 && 897 1488 coord_cmp(&rbc, &csel_end) < 0) { 898 console_flush(con); 899 console_set_style(con, STYLE_SELECTED); 900 console_flush(con); 1489 fmt.color = pane->sel_color; 901 1490 } 902 1491 903 console_set_pos(con, 0, i);904 1492 size = str_size(row_buf); 905 1493 pos = 0; 906 s_column = pane .sh_column;1494 s_column = pane->sh_column; 907 1495 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 } 1496 if ((csel_start.row == rbc.row) && (csel_start.column == s_column)) 1497 fmt.color = pane->sel_color; 1498 1499 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) 1500 fmt.color = pane->color; 919 1501 920 1502 c = str_decode(row_buf, &pos, size); 921 1503 if (c != '\t') { 922 printf("%lc", (wint_t) c); 1504 cpos = 0; 1505 rc = chr_encode(c, cbuf, &cpos, sizeof(cbuf)); 1506 if (rc != EOK) 1507 return rc; 1508 1509 rc = gfx_puttext(&tpos, &fmt, cbuf); 1510 if (rc != EOK) 1511 return rc; 1512 923 1513 s_column += 1; 1514 tpos.x++; 924 1515 } else { 925 1516 fill = 1 + ALIGN_UP(s_column, TAB_WIDTH) - 926 1517 s_column; 927 1518 928 for (j = 0; j < fill; ++j) 929 putchar(' '); 1519 rc = gfx_set_color(gc, fmt.color); 1520 if (rc != EOK) 1521 return rc; 1522 1523 rect.p0.x = tpos.x; 1524 rect.p0.y = tpos.y; 1525 rect.p1.x = tpos.x + fill; 1526 rect.p1.y = tpos.y + 1; 1527 1528 rc = gfx_fill_rect(gc, &rect); 1529 if (rc != EOK) 1530 return rc; 1531 930 1532 s_column += fill; 1533 tpos.x += fill; 931 1534 } 932 1535 } 933 1536 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 } 1537 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) 1538 fmt.color = pane->color; 939 1539 940 1540 /* Fill until the end of display area. */ 941 1541 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) 1542 rc = gfx_set_color(gc, fmt.color); 1543 if (rc != EOK) 1544 return rc; 1545 1546 rect.p0.x = tpos.x; 1547 rect.p0.y = tpos.y; 1548 rect.p1.x = pane->rect.p1.x; 1549 rect.p1.y = tpos.y + 1; 1550 1551 rc = gfx_fill_rect(gc, &rect); 1552 if (rc != EOK) 1553 return rc; 1554 } 1555 1556 return EOK; 1557 } 1558 1559 /** Display pane status in the status line. 1560 * 1561 * @param pane Pane 1562 */ 1563 static void pane_status_display(pane_t *pane) 958 1564 { 959 1565 spt_t caret_pt; … … 964 1570 char *text; 965 1571 size_t n; 966 int pos;967 1572 size_t nextra; 968 1573 size_t fnw; 969 1574 970 tag_get_pt(&pane .caret_pos, &caret_pt);1575 tag_get_pt(&pane->caret_pos, &caret_pt); 971 1576 spt_get_coord(&caret_pt, &coord); 972 1577 … … 987 1592 return; 988 1593 989 console_set_pos(con, 0, scr_rows - 1);990 console_set_style(con, STYLE_INVERTED);991 992 1594 /* 993 1595 * Make sure the status fits on the screen. This loop should … … 995 1597 */ 996 1598 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);1599 int rc = asprintf(&text, "%d, %d (%d): File '%s'. Ctrl-Q Quit " 1600 "F10 Menu", coord.row, coord.column, last_row, fname); 999 1601 if (rc < 0) { 1000 1602 n = 0; … … 1004 1606 /* If it already fits, we're done */ 1005 1607 n = str_width(text); 1006 if ( n <= scr_columns - 2)1608 if ((int)n <= pane->columns - 2) 1007 1609 break; 1008 1610 1009 1611 /* Compute number of excess characters */ 1010 nextra = n - ( scr_columns - 2);1612 nextra = n - (pane->columns - 2); 1011 1613 /** With of the file name part */ 1012 1614 fnw = str_width(fname); … … 1016 1618 * just give up and print a blank status. 1017 1619 */ 1018 if (nextra > fnw - 2) 1620 if (nextra > fnw - 2) { 1621 text[0] = '\0'; 1019 1622 goto finish; 1623 } 1020 1624 1021 1625 /* Compute position where we overwrite with '..\0' */ … … 1034 1638 } 1035 1639 1036 printf("%s", text); 1640 finish: 1641 (void) ui_label_set_text(edit.status, text); 1642 (void) ui_label_paint(edit.status); 1037 1643 free(text); 1038 1644 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) 1645 } 1646 1647 /** Set cursor to reflect position of the caret. 1648 * 1649 * @param pane Pane 1650 */ 1651 static void pane_caret_display(pane_t *pane) 1051 1652 { 1052 1653 spt_t caret_pt; 1053 1654 coord_t coord; 1054 1055 tag_get_pt(&pane.caret_pos, &caret_pt); 1655 gfx_coord2_t pos; 1656 gfx_context_t *gc; 1657 1658 tag_get_pt(&pane->caret_pos, &caret_pt); 1056 1659 1057 1660 spt_get_coord(&caret_pt, &coord); 1058 console_set_pos(con, coord.column - pane.sh_column, 1059 coord.row - pane.sh_row); 1661 1662 gc = ui_window_get_gc(edit.window); 1663 pos.x = pane->rect.p0.x + coord.column - pane->sh_column; 1664 pos.y = pane->rect.p0.y + coord.row - pane->sh_row; 1665 1666 (void) gfx_cursor_set_pos(gc, &pos); 1667 } 1668 1669 /** Destroy pane control. 1670 * 1671 * @param arg Argument (pane_t *) 1672 */ 1673 static void pane_ctl_destroy(void *arg) 1674 { 1675 pane_t *pane = (pane_t *)arg; 1676 1677 pane_fini(pane); 1678 } 1679 1680 /** Paint pane control. 1681 * 1682 * @param arg Argument (pane_t *) 1683 */ 1684 static errno_t pane_ctl_paint(void *arg) 1685 { 1686 pane_t *pane = (pane_t *)arg; 1687 gfx_context_t *gc; 1688 errno_t rc; 1689 1690 gc = ui_window_get_gc(pane->window); 1691 1692 rc = pane_text_display(pane); 1693 if (rc != EOK) 1694 goto error; 1695 1696 rc = gfx_update(gc); 1697 if (rc != EOK) 1698 goto error; 1699 1700 error: 1701 return rc; 1702 } 1703 1704 /** Handle pane control position event. 1705 * 1706 * @param arg Argument (pane_t *) 1707 * @param event Position event 1708 */ 1709 static ui_evclaim_t pane_ctl_pos_event(void *arg, pos_event_t *event) 1710 { 1711 gfx_coord2_t pos; 1712 1713 pos.x = event->hpos; 1714 pos.y = event->vpos; 1715 1716 if (!gfx_pix_inside_rect(&pos, &pane.rect)) 1717 return ui_unclaimed; 1718 1719 pos_handle(event); 1720 (void) gfx_update(ui_window_get_gc(edit.window)); 1721 return ui_claimed; 1060 1722 } 1061 1723 … … 1270 1932 static void caret_go_to_line_ask(void) 1271 1933 { 1272 char *sline; 1273 1274 sline = prompt("Go to line", ""); 1275 if (sline == NULL) { 1276 status_display("Go to line cancelled."); 1934 ui_prompt_dialog_params_t pdparams; 1935 ui_prompt_dialog_t *dialog; 1936 errno_t rc; 1937 1938 ui_prompt_dialog_params_init(&pdparams); 1939 pdparams.caption = "Go To Line"; 1940 pdparams.prompt = "Line Number"; 1941 1942 rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog); 1943 if (rc != EOK) { 1944 printf("Error creating prompt dialog.\n"); 1277 1945 return; 1278 1946 } 1279 1947 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); 1948 ui_prompt_dialog_set_cb(dialog, &go_to_line_dialog_cb, &edit); 1290 1949 } 1291 1950 … … 1344 2003 static void search_prompt(bool reverse) 1345 2004 { 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 = ""; 2005 ui_prompt_dialog_params_t pdparams; 2006 ui_prompt_dialog_t *dialog; 2007 errno_t rc; 2008 2009 ui_prompt_dialog_params_init(&pdparams); 2010 pdparams.caption = reverse ? "Reverse Search" : "Search"; 2011 pdparams.prompt = "Search text"; 2012 pdparams.itext = ""; 2013 1353 2014 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.");2015 pdparams.itext = pane.previous_search; 2016 2017 rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog); 2018 if (rc != EOK) { 2019 printf("Error creating prompt dialog.\n"); 1359 2020 return; 1360 2021 } 1361 2022 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); 2023 ui_prompt_dialog_set_cb(dialog, &search_dialog_cb, &edit); 2024 pane.search_reverse = reverse; 1368 2025 } 1369 2026 … … 1513 2170 } 1514 2171 free(str); 2172 } 2173 2174 static void edit_paste(void) 2175 { 2176 selection_delete(); 2177 insert_clipboard_data(); 2178 pane.rflags |= (REDRAW_TEXT | REDRAW_CARET); 2179 pane_update(&pane); 2180 } 2181 2182 static void edit_cut(void) 2183 { 2184 selection_copy(); 2185 selection_delete(); 2186 pane.rflags |= (REDRAW_TEXT | REDRAW_CARET); 2187 pane_update(&pane); 1515 2188 } 1516 2189 … … 1719 2392 static void status_display(char const *str) 1720 2393 { 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); 2394 (void) ui_label_set_text(edit.status, str); 2395 (void) ui_label_paint(edit.status); 2396 } 2397 2398 /** Window was resized. 2399 * 2400 * @param window Window 2401 * @param arg Argument (edit_t *) 2402 */ 2403 static void edit_wnd_resize(ui_window_t *window, void *arg) 2404 { 2405 edit_t *edit = (edit_t *) arg; 2406 2407 edit_menubar_set_rect(edit); 2408 edit_status_set_rect(edit); 2409 pane_resize(&pane); 2410 } 2411 2412 /** Window close request 2413 * 2414 * @param window Window 2415 * @param arg Argument (edit_t *) 2416 */ 2417 static void edit_wnd_close(ui_window_t *window, void *arg) 2418 { 2419 edit_t *edit = (edit_t *) arg; 2420 2421 ui_quit(edit->ui); 2422 } 2423 2424 /** Window focus event 2425 * 2426 * @param window Window 2427 * @param arg Argument (edit_t *) 2428 * @param focus Focus number 2429 */ 2430 static void edit_wnd_focus(ui_window_t *window, void *arg, unsigned focus) 2431 { 2432 edit_t *edit = (edit_t *)arg; 2433 2434 (void)edit; 2435 pane_caret_display(&pane); 2436 cursor_setvis(true); 2437 } 2438 2439 /** Window keyboard event 2440 * 2441 * @param window Window 2442 * @param arg Argument (edit_t *) 2443 * @param event Keyboard event 2444 */ 2445 static void edit_wnd_kbd_event(ui_window_t *window, void *arg, 2446 kbd_event_t *event) 2447 { 2448 pane.keymod = event->mods; 2449 2450 if (ui_window_def_kbd(window, event) == ui_claimed) 2451 return; 2452 2453 if (event->type == KEY_PRESS) { 2454 key_handle_press(event); 2455 (void) pane_update(&pane); 2456 (void) gfx_update(ui_window_get_gc(window)); 2457 } 2458 } 2459 2460 /** Window unfocus event 2461 * 2462 * @param window Window 2463 * @param arg Argument (edit_t *) 2464 * @param focus Focus number 2465 */ 2466 static void edit_wnd_unfocus(ui_window_t *window, void *arg, unsigned focus) 2467 { 2468 edit_t *edit = (edit_t *) arg; 2469 2470 (void)edit; 2471 cursor_setvis(false); 2472 } 2473 2474 /** Menu bar activate event 2475 * 2476 * @param mbar Menu bar 2477 * @param arg Argument (edit_t *) 2478 */ 2479 static void edit_menubar_activate(ui_menu_bar_t *mbar, void *arg) 2480 { 2481 edit_t *edit = (edit_t *)arg; 2482 2483 (void)edit; 2484 cursor_setvis(false); 2485 } 2486 2487 /** Menu bar deactivate event 2488 * 2489 * @param mbar Menu bar 2490 * @param arg Argument (edit_t *) 2491 */ 2492 static void edit_menubar_deactivate(ui_menu_bar_t *mbar, void *arg) 2493 { 2494 edit_t *edit = (edit_t *)arg; 2495 2496 (void)edit; 2497 pane_caret_display(&pane); 2498 cursor_setvis(true); 2499 } 2500 2501 /** File / New menu entry selected. 2502 * 2503 * @param mentry Menu entry 2504 * @param arg Argument (edit_t *) 2505 */ 2506 static void edit_file_new(ui_menu_entry_t *mentry, void *arg) 2507 { 2508 edit_t *edit = (edit_t *) arg; 2509 2510 (void)edit; 2511 file_new(); 2512 (void) gfx_update(ui_window_get_gc(edit->window)); 2513 } 2514 2515 /** File / Open menu entry selected. 2516 * 2517 * @param mentry Menu entry 2518 * @param arg Argument (edit_t *) 2519 */ 2520 static void edit_file_open(ui_menu_entry_t *mentry, void *arg) 2521 { 2522 edit_t *edit = (edit_t *) arg; 2523 2524 (void)edit; 2525 file_open(); 2526 } 2527 2528 /** File / Save menu entry selected. 2529 * 2530 * @param mentry Menu entry 2531 * @param arg Argument (edit_t *) 2532 */ 2533 static void edit_file_save(ui_menu_entry_t *mentry, void *arg) 2534 { 2535 edit_t *edit = (edit_t *) arg; 2536 2537 (void)edit; 2538 2539 if (doc.file_name != NULL) 2540 file_save(doc.file_name); 2541 else 2542 file_save_as(); 2543 } 2544 2545 /** File / Save As menu entry selected. 2546 * 2547 * @param mentry Menu entry 2548 * @param arg Argument (edit_t *) 2549 */ 2550 static void edit_file_save_as(ui_menu_entry_t *mentry, void *arg) 2551 { 2552 edit_t *edit = (edit_t *) arg; 2553 2554 (void)edit; 2555 file_save_as(); 2556 } 2557 2558 /** File / Exit menu entry selected. 2559 * 2560 * @param mentry Menu entry 2561 * @param arg Argument (edit_t *) 2562 */ 2563 static void edit_file_exit(ui_menu_entry_t *mentry, void *arg) 2564 { 2565 edit_t *edit = (edit_t *) arg; 2566 2567 ui_quit(edit->ui); 2568 } 2569 2570 /** Edit / Cut menu entry selected. 2571 * 2572 * @param mentry Menu entry 2573 * @param arg Argument (edit_t *) 2574 */ 2575 static void edit_edit_cut(ui_menu_entry_t *mentry, void *arg) 2576 { 2577 (void) arg; 2578 edit_cut(); 2579 (void) gfx_update(ui_window_get_gc(edit.window)); 2580 } 2581 2582 /** Edit / Copy menu entry selected. 2583 * 2584 * @param mentry Menu entry 2585 * @param arg Argument (edit_t *) 2586 */ 2587 static void edit_edit_copy(ui_menu_entry_t *mentry, void *arg) 2588 { 2589 (void) arg; 2590 selection_copy(); 2591 } 2592 2593 /** Edit / Paste menu entry selected. 2594 * 2595 * @param mentry Menu entry 2596 * @param arg Argument (edit_t *) 2597 */ 2598 static void edit_edit_paste(ui_menu_entry_t *mentry, void *arg) 2599 { 2600 (void) arg; 2601 edit_paste(); 2602 (void) gfx_update(ui_window_get_gc(edit.window)); 2603 } 2604 2605 /** Edit / Delete menu entry selected. 2606 * 2607 * @param mentry Menu entry 2608 * @param arg Argument (edit_t *) 2609 */ 2610 static void edit_edit_delete(ui_menu_entry_t *mentry, void *arg) 2611 { 2612 (void) arg; 2613 2614 if (selection_active()) 2615 selection_delete(); 1728 2616 1729 2617 pane.rflags |= REDRAW_CARET; 2618 (void) pane_update(&pane); 2619 (void) gfx_update(ui_window_get_gc(edit.window)); 2620 } 2621 2622 /** Edit / Select All menu entry selected. 2623 * 2624 * @param mentry Menu entry 2625 * @param arg Argument (edit_t *) 2626 */ 2627 static void edit_edit_select_all(ui_menu_entry_t *mentry, void *arg) 2628 { 2629 (void) arg; 2630 2631 selection_sel_all(); 2632 pane.rflags |= (REDRAW_CARET | REDRAW_TEXT | REDRAW_STATUS); 2633 pane_update(&pane); 2634 (void) gfx_update(ui_window_get_gc(edit.window)); 2635 } 2636 2637 /** Search / Find menu entry selected. 2638 * 2639 * @param mentry Menu entry 2640 * @param arg Argument (edit_t *) 2641 */ 2642 static void edit_search_find(ui_menu_entry_t *mentry, void *arg) 2643 { 2644 (void) arg; 2645 search_prompt(false); 2646 } 2647 2648 /** Search / Reverse Find menu entry selected. 2649 * 2650 * @param mentry Menu entry 2651 * @param arg Argument (edit_t *) 2652 */ 2653 static void edit_search_reverse_find(ui_menu_entry_t *mentry, void *arg) 2654 { 2655 (void) arg; 2656 search_prompt(true); 2657 } 2658 2659 /** Search / Find Next menu entry selected. 2660 * 2661 * @param mentry Menu entry 2662 * @param arg Argument (edit_t *) 2663 */ 2664 static void edit_search_find_next(ui_menu_entry_t *mentry, void *arg) 2665 { 2666 (void) arg; 2667 search_repeat(); 2668 (void) pane_update(&pane); 2669 (void) gfx_update(ui_window_get_gc(edit.window)); 2670 } 2671 2672 /** Search / Go To Line menu entry selected. 2673 * 2674 * @param mentry Menu entry 2675 * @param arg Argument (edit_t *) 2676 */ 2677 static void edit_search_go_to_line(ui_menu_entry_t *mentry, void *arg) 2678 { 2679 (void) arg; 2680 caret_go_to_line_ask(); 2681 } 2682 2683 /** Open File dialog OK button press. 2684 * 2685 * @param dialog Open File dialog 2686 * @param arg Argument (ui_demo_t *) 2687 * @param fname File name 2688 */ 2689 static void open_dialog_bok(ui_file_dialog_t *dialog, void *arg, 2690 const char *fname) 2691 { 2692 edit_t *edit = (edit_t *)arg; 2693 char *cname; 2694 errno_t rc; 2695 2696 (void)edit; 2697 ui_file_dialog_destroy(dialog); 2698 2699 cname = str_dup(fname); 2700 if (cname == NULL) { 2701 printf("Out of memory.\n"); 2702 return; 2703 } 2704 2705 rc = file_open_file(fname); 2706 if (rc != EOK) 2707 return; 2708 2709 if (doc.file_name != NULL) 2710 free(doc.file_name); 2711 doc.file_name = cname; 2712 2713 (void) gfx_update(ui_window_get_gc(edit->window)); 2714 } 2715 2716 /** Open File dialog cancel button press. 2717 * 2718 * @param dialog File dialog 2719 * @param arg Argument (ui_demo_t *) 2720 */ 2721 static void open_dialog_bcancel(ui_file_dialog_t *dialog, void *arg) 2722 { 2723 edit_t *edit = (edit_t *)arg; 2724 2725 (void)edit; 2726 ui_file_dialog_destroy(dialog); 2727 } 2728 2729 /** Open File dialog close request. 2730 * 2731 * @param dialog File dialog 2732 * @param arg Argument (ui_demo_t *) 2733 */ 2734 static void open_dialog_close(ui_file_dialog_t *dialog, void *arg) 2735 { 2736 edit_t *edit = (edit_t *)arg; 2737 2738 (void)edit; 2739 ui_file_dialog_destroy(dialog); 2740 } 2741 2742 /** Save As dialog OK button press. 2743 * 2744 * @param dialog Save As dialog 2745 * @param arg Argument (ui_demo_t *) 2746 * @param fname File name 2747 */ 2748 static void save_as_dialog_bok(ui_file_dialog_t *dialog, void *arg, 2749 const char *fname) 2750 { 2751 edit_t *edit = (edit_t *)arg; 2752 char *cname; 2753 errno_t rc; 2754 2755 (void)edit; 2756 ui_file_dialog_destroy(dialog); 2757 2758 cname = str_dup(fname); 2759 if (cname == NULL) { 2760 printf("Out of memory.\n"); 2761 return; 2762 } 2763 2764 rc = file_save(fname); 2765 if (rc != EOK) 2766 return; 2767 2768 if (doc.file_name != NULL) 2769 free(doc.file_name); 2770 doc.file_name = cname; 2771 2772 } 2773 2774 /** Save As dialog cancel button press. 2775 * 2776 * @param dialog File dialog 2777 * @param arg Argument (ui_demo_t *) 2778 */ 2779 static void save_as_dialog_bcancel(ui_file_dialog_t *dialog, void *arg) 2780 { 2781 edit_t *edit = (edit_t *)arg; 2782 2783 (void)edit; 2784 ui_file_dialog_destroy(dialog); 2785 } 2786 2787 /** Save As dialog close request. 2788 * 2789 * @param dialog File dialog 2790 * @param arg Argument (ui_demo_t *) 2791 */ 2792 static void save_as_dialog_close(ui_file_dialog_t *dialog, void *arg) 2793 { 2794 edit_t *edit = (edit_t *)arg; 2795 2796 (void)edit; 2797 ui_file_dialog_destroy(dialog); 2798 } 2799 2800 /** Go To Line dialog OK button press. 2801 * 2802 * @param dialog Go To Line dialog 2803 * @param arg Argument (ui_demo_t *) 2804 * @param text Submitted text 2805 */ 2806 static void go_to_line_dialog_bok(ui_prompt_dialog_t *dialog, void *arg, 2807 const char *text) 2808 { 2809 edit_t *edit = (edit_t *) arg; 2810 char *endptr; 2811 int line; 2812 2813 ui_prompt_dialog_destroy(dialog); 2814 line = strtol(text, &endptr, 10); 2815 if (*endptr != '\0') { 2816 status_display("Invalid number entered."); 2817 return; 2818 } 2819 2820 caret_move_absolute(line, pane.ideal_column, dir_before, false); 2821 (void)edit; 2822 (void) pane_update(&pane); 2823 } 2824 2825 /** Go To Line dialog cancel button press. 2826 * 2827 * @param dialog File dialog 2828 * @param arg Argument (ui_demo_t *) 2829 */ 2830 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg) 2831 { 2832 edit_t *edit = (edit_t *) arg; 2833 2834 (void)edit; 2835 ui_prompt_dialog_destroy(dialog); 2836 } 2837 2838 /** Go To Line dialog close request. 2839 * 2840 * @param dialog File dialog 2841 * @param arg Argument (ui_demo_t *) 2842 */ 2843 static void go_to_line_dialog_close(ui_prompt_dialog_t *dialog, void *arg) 2844 { 2845 edit_t *edit = (edit_t *) arg; 2846 2847 (void)edit; 2848 ui_prompt_dialog_destroy(dialog); 2849 } 2850 2851 /** Search dialog OK button press. 2852 * 2853 * @param dialog Search dialog 2854 * @param arg Argument (ui_demo_t *) 2855 * @param text Submitted text 2856 */ 2857 static void search_dialog_bok(ui_prompt_dialog_t *dialog, void *arg, 2858 const char *text) 2859 { 2860 edit_t *edit = (edit_t *) arg; 2861 char *pattern; 2862 bool reverse; 2863 2864 (void)edit; 2865 ui_prompt_dialog_destroy(dialog); 2866 2867 /* Abort if search phrase is empty */ 2868 if (text[0] == '\0') 2869 return; 2870 2871 pattern = str_dup(text); 2872 reverse = pane.search_reverse; 2873 2874 if (pane.previous_search) 2875 free(pane.previous_search); 2876 pane.previous_search = pattern; 2877 pane.previous_search_reverse = reverse; 2878 2879 search(pattern, reverse); 2880 2881 (void) pane_update(&pane); 2882 } 2883 2884 /** Search dialog cancel button press. 2885 * 2886 * @param dialog File dialog 2887 * @param arg Argument (ui_demo_t *) 2888 */ 2889 static void search_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg) 2890 { 2891 edit_t *edit = (edit_t *) arg; 2892 2893 (void)edit; 2894 ui_prompt_dialog_destroy(dialog); 2895 } 2896 2897 /** Search dialog close request. 2898 * 2899 * @param dialog File dialog 2900 * @param arg Argument (ui_demo_t *) 2901 */ 2902 static void search_dialog_close(ui_prompt_dialog_t *dialog, void *arg) 2903 { 2904 edit_t *edit = (edit_t *) arg; 2905 2906 (void)edit; 2907 ui_prompt_dialog_destroy(dialog); 1730 2908 } 1731 2909
Note:
See TracChangeset
for help on using the changeset viewer.
