Changes in uspace/app/edit/edit.c [87822ce:994f87b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/edit/edit.c
r87822ce r994f87b 1 1 /* 2 * Copyright (c) 20 09Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * Copyright (c) 2012 Martin Sucha 4 4 * All rights reserved. … … 36 36 */ 37 37 38 #include <align.h> 39 #include <clipboard.h> 40 #include <errno.h> 41 #include <gfx/color.h> 42 #include <gfx/cursor.h> 43 #include <gfx/font.h> 44 #include <gfx/render.h> 45 #include <gfx/text.h> 46 #include <io/kbd_event.h> 47 #include <io/keycode.h> 48 #include <io/pos_event.h> 49 #include <io/style.h> 50 #include <macros.h> 38 51 #include <stdio.h> 39 52 #include <stdlib.h> 40 53 #include <stddef.h> 41 54 #include <stdbool.h> 55 #include <types/common.h> 56 #include <ui/control.h> 57 #include <ui/filedialog.h> 58 #include <ui/fixed.h> 59 #include <ui/label.h> 60 #include <ui/menu.h> 61 #include <ui/menubar.h> 62 #include <ui/menudd.h> 63 #include <ui/menuentry.h> 64 #include <ui/promptdialog.h> 65 #include <ui/resource.h> 66 #include <ui/ui.h> 67 #include <ui/window.h> 42 68 #include <vfs/vfs.h> 43 #include <io/console.h>44 #include <io/style.h>45 #include <io/keycode.h>46 #include <errno.h>47 #include <align.h>48 #include <macros.h>49 #include <clipboard.h>50 #include <types/common.h>51 69 52 70 #include "sheet.h" … … 63 81 * 64 82 * A rectangular area of the screen used to edit a document. Different 65 * panes can be possibly used to edit the same document. 83 * panes can be possibly used to edit the same document. This is a custom 84 * UI control. 66 85 */ 67 86 typedef struct { 87 /** Base control object */ 88 struct ui_control *control; 89 90 /** Containing window */ 91 ui_window_t *window; 92 93 /** UI resource */ 94 struct ui_resource *res; 95 96 /** Pane rectangle */ 97 gfx_rect_t rect; 98 99 /** Pane color */ 100 gfx_color_t *color; 101 102 /** Selection color */ 103 gfx_color_t *sel_color; 104 68 105 /* Pane dimensions */ 69 106 int rows, columns; … … 90 127 int ideal_column; 91 128 129 bool search_reverse; 92 130 char *previous_search; 93 131 bool previous_search_reverse; 94 132 } pane_t; 133 134 /** Text editor */ 135 typedef struct { 136 /** User interface */ 137 ui_t *ui; 138 /** Editor window */ 139 ui_window_t *window; 140 /** UI resource */ 141 ui_resource_t *ui_res; 142 /** Menu bar */ 143 ui_menu_bar_t *menubar; 144 /** Status bar */ 145 ui_label_t *status; 146 } edit_t; 95 147 96 148 /** Document … … 103 155 } doc_t; 104 156 105 static console_ctrl_t *con;157 static edit_t edit; 106 158 static doc_t doc; 107 static bool done;108 159 static pane_t pane; 109 static bool cursor_visible;110 111 static sysarg_t scr_rows;112 static sysarg_t scr_columns;113 160 114 161 #define ROW_BUF_SIZE 4096 … … 119 166 #define INFNAME_MAX_LEN 128 120 167 121 static void cursor_show(void);122 static void cursor_hide(void);123 168 static void cursor_setvis(bool visible); 124 169 … … 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_close(ui_window_t *, void *); 243 static void edit_wnd_focus(ui_window_t *, void *, unsigned); 244 static void edit_wnd_kbd_event(ui_window_t *, void *, kbd_event_t *); 245 static void edit_wnd_unfocus(ui_window_t *, void *, unsigned); 246 247 static ui_window_cb_t edit_window_cb = { 248 .close = edit_wnd_close, 249 .focus = edit_wnd_focus, 250 .kbd = edit_wnd_kbd_event, 251 .unfocus = edit_wnd_unfocus 252 }; 253 254 static void edit_menubar_activate(ui_menu_bar_t *, void *); 255 static void edit_menubar_deactivate(ui_menu_bar_t *, void *); 256 257 static ui_menu_bar_cb_t edit_menubar_cb = { 258 .activate = edit_menubar_activate, 259 .deactivate = edit_menubar_deactivate 260 }; 261 262 static void edit_file_new(ui_menu_entry_t *, void *); 263 static void edit_file_open(ui_menu_entry_t *, void *); 264 static void edit_file_save(ui_menu_entry_t *, void *); 265 static void edit_file_save_as(ui_menu_entry_t *, void *); 266 static void edit_file_exit(ui_menu_entry_t *, void *); 267 static void edit_edit_cut(ui_menu_entry_t *, void *); 268 static void edit_edit_copy(ui_menu_entry_t *, void *); 269 static void edit_edit_paste(ui_menu_entry_t *, void *); 270 static void edit_edit_delete(ui_menu_entry_t *, void *); 271 static void edit_edit_select_all(ui_menu_entry_t *, void *); 272 static void edit_search_find(ui_menu_entry_t *, void *); 273 static void edit_search_reverse_find(ui_menu_entry_t *, void *); 274 static void edit_search_find_next(ui_menu_entry_t *, void *); 275 static void edit_search_go_to_line(ui_menu_entry_t *, void *); 276 277 static void pane_ctl_destroy(void *); 278 static errno_t pane_ctl_paint(void *); 279 static ui_evclaim_t pane_ctl_pos_event(void *, pos_event_t *); 280 281 /** Pabe control ops */ 282 ui_control_ops_t pane_ctl_ops = { 283 .destroy = pane_ctl_destroy, 284 .paint = pane_ctl_paint, 285 .pos_event = pane_ctl_pos_event 286 }; 287 288 static void open_dialog_bok(ui_file_dialog_t *, void *, const char *); 289 static void open_dialog_bcancel(ui_file_dialog_t *, void *); 290 static void open_dialog_close(ui_file_dialog_t *, void *); 291 292 static ui_file_dialog_cb_t open_dialog_cb = { 293 .bok = open_dialog_bok, 294 .bcancel = open_dialog_bcancel, 295 .close = open_dialog_close 296 }; 297 298 static void save_as_dialog_bok(ui_file_dialog_t *, void *, const char *); 299 static void save_as_dialog_bcancel(ui_file_dialog_t *, void *); 300 static void save_as_dialog_close(ui_file_dialog_t *, void *); 301 302 static ui_file_dialog_cb_t save_as_dialog_cb = { 303 .bok = save_as_dialog_bok, 304 .bcancel = save_as_dialog_bcancel, 305 .close = save_as_dialog_close 306 }; 307 308 static void go_to_line_dialog_bok(ui_prompt_dialog_t *, void *, const char *); 309 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *, void *); 310 static void go_to_line_dialog_close(ui_prompt_dialog_t *, void *); 311 312 static ui_prompt_dialog_cb_t go_to_line_dialog_cb = { 313 .bok = go_to_line_dialog_bok, 314 .bcancel = go_to_line_dialog_bcancel, 315 .close = go_to_line_dialog_close 316 }; 317 318 static void search_dialog_bok(ui_prompt_dialog_t *, void *, const char *); 319 static void search_dialog_bcancel(ui_prompt_dialog_t *, void *); 320 static void search_dialog_close(ui_prompt_dialog_t *, void *); 321 322 static ui_prompt_dialog_cb_t search_dialog_cb = { 323 .bok = search_dialog_bok, 324 .bcancel = search_dialog_bcancel, 325 .close = search_dialog_close 326 }; 187 327 188 328 int main(int argc, char *argv[]) 189 329 { 190 cons_event_t ev;191 bool new_file;192 330 errno_t rc; 193 331 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 332 pane.sh_row = 1; 202 333 pane.sh_column = 1; 203 334 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; 335 /* Create UI */ 336 rc = edit_ui_create(&edit); 337 if (rc != EOK) 338 return 1; 216 339 217 340 if (argc == 2) { 218 341 doc.file_name = str_dup(argv[1]); 342 rc = file_open_file(argv[1]); 343 if (rc != EOK) { 344 status_display("File not found. Starting empty file."); 345 rc = file_new(); 346 } 219 347 } else if (argc > 1) { 220 348 printf("Invalid arguments.\n"); 221 349 return -2; 222 350 } 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); 351 rc = file_new(); 352 } 237 353 238 354 /* 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 355 rc = ui_window_paint(edit.window); 356 if (rc != EOK) { 357 printf("Error painting window.\n"); 358 return rc; 359 } 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 *mnew = NULL; 380 ui_menu_entry_t *mopen = NULL; 381 ui_menu_entry_t *msave = NULL; 382 ui_menu_entry_t *msaveas = NULL; 383 ui_menu_entry_t *mfsep = NULL; 384 ui_menu_entry_t *mexit = NULL; 385 ui_menu_entry_t *mcut = NULL; 386 ui_menu_entry_t *mcopy = NULL; 387 ui_menu_entry_t *mpaste = NULL; 388 ui_menu_entry_t *mdelete = NULL; 389 ui_menu_entry_t *mesep = NULL; 390 ui_menu_entry_t *mselall = NULL; 391 ui_menu_t *msearch = NULL; 392 ui_menu_entry_t *mfind = NULL; 393 ui_menu_entry_t *mfindr = NULL; 394 ui_menu_entry_t *mfindn = NULL; 395 ui_menu_entry_t *mssep = NULL; 396 ui_menu_entry_t *mgoto = NULL; 397 gfx_rect_t arect; 398 gfx_rect_t rect; 399 400 rc = ui_create(UI_CONSOLE_DEFAULT, &edit->ui); 401 if (rc != EOK) { 402 printf("Error creating UI on display %s.\n", 403 UI_CONSOLE_DEFAULT); 404 goto error; 405 } 406 407 ui_wnd_params_init(¶ms); 408 params.caption = "Text Editor"; 409 params.style &= ~ui_wds_decorated; 410 params.placement = ui_wnd_place_full_screen; 411 412 rc = ui_window_create(edit->ui, ¶ms, &edit->window); 413 if (rc != EOK) { 414 printf("Error creating window.\n"); 415 goto error; 416 } 417 418 ui_window_set_cb(edit->window, &edit_window_cb, (void *) edit); 419 420 edit->ui_res = ui_window_get_res(edit->window); 421 422 rc = ui_fixed_create(&fixed); 423 if (rc != EOK) { 424 printf("Error creating fixed layout.\n"); 425 return rc; 426 } 427 428 rc = ui_menu_bar_create(edit->ui, edit->window, &edit->menubar); 429 if (rc != EOK) { 430 printf("Error creating menu bar.\n"); 431 return rc; 432 } 433 434 ui_menu_bar_set_cb(edit->menubar, &edit_menubar_cb, (void *) edit); 435 436 rc = ui_menu_dd_create(edit->menubar, "~F~ile", NULL, &mfile); 437 if (rc != EOK) { 438 printf("Error creating menu.\n"); 439 return rc; 440 } 441 442 rc = ui_menu_entry_create(mfile, "~N~ew", "Ctrl-N", &mnew); 443 if (rc != EOK) { 444 printf("Error creating menu.\n"); 445 return rc; 446 } 447 448 ui_menu_entry_set_cb(mnew, edit_file_new, (void *) edit); 449 450 rc = ui_menu_entry_create(mfile, "~O~pen", "Ctrl-O", &mopen); 451 if (rc != EOK) { 452 printf("Error creating menu.\n"); 453 return rc; 454 } 455 456 ui_menu_entry_set_cb(mopen, edit_file_open, (void *) edit); 457 458 rc = ui_menu_entry_create(mfile, "~S~ave", "Ctrl-S", &msave); 459 if (rc != EOK) { 460 printf("Error creating menu.\n"); 461 return rc; 462 } 463 464 ui_menu_entry_set_cb(msave, edit_file_save, (void *) edit); 465 466 rc = ui_menu_entry_create(mfile, "Save ~A~s", "Ctrl-E", &msaveas); 467 if (rc != EOK) { 468 printf("Error creating menu.\n"); 469 return rc; 470 } 471 472 ui_menu_entry_set_cb(msaveas, edit_file_save_as, (void *) edit); 473 474 rc = ui_menu_entry_sep_create(mfile, &mfsep); 475 if (rc != EOK) { 476 printf("Error creating menu.\n"); 477 return rc; 478 } 479 480 rc = ui_menu_entry_create(mfile, "E~x~it", "Ctrl-Q", &mexit); 481 if (rc != EOK) { 482 printf("Error creating menu.\n"); 483 return rc; 484 } 485 486 ui_menu_entry_set_cb(mexit, edit_file_exit, (void *) edit); 487 488 rc = ui_menu_dd_create(edit->menubar, "~E~dit", NULL, &medit); 489 if (rc != EOK) { 490 printf("Error creating menu.\n"); 491 return rc; 492 } 493 494 rc = ui_menu_entry_create(medit, "Cu~t~", "Ctrl-X", &mcut); 495 if (rc != EOK) { 496 printf("Error creating menu.\n"); 497 return rc; 498 } 499 500 ui_menu_entry_set_cb(mcut, edit_edit_cut, (void *) edit); 501 502 rc = ui_menu_entry_create(medit, "~C~opy", "Ctrl-C", &mcopy); 503 if (rc != EOK) { 504 printf("Error creating menu.\n"); 505 return rc; 506 } 507 508 ui_menu_entry_set_cb(mcopy, edit_edit_copy, (void *) edit); 509 510 rc = ui_menu_entry_create(medit, "~P~aste", "Ctrl-V", &mpaste); 511 if (rc != EOK) { 512 printf("Error creating menu.\n"); 513 return rc; 514 } 515 516 ui_menu_entry_set_cb(mpaste, edit_edit_paste, (void *) edit); 517 518 rc = ui_menu_entry_create(medit, "~D~elete", "Del", &mdelete); 519 if (rc != EOK) { 520 printf("Error creating menu.\n"); 521 return rc; 522 } 523 524 ui_menu_entry_set_cb(mdelete, edit_edit_delete, (void *) edit); 525 526 rc = ui_menu_entry_sep_create(medit, &mesep); 527 if (rc != EOK) { 528 printf("Error creating menu.\n"); 529 return rc; 530 } 531 532 rc = ui_menu_entry_create(medit, "Select ~A~ll", "Ctrl-A", &mselall); 533 if (rc != EOK) { 534 printf("Error creating menu.\n"); 535 return rc; 536 } 537 538 ui_menu_entry_set_cb(mselall, edit_edit_select_all, (void *) edit); 539 540 rc = ui_menu_dd_create(edit->menubar, "~S~earch", NULL, &msearch); 541 if (rc != EOK) { 542 printf("Error creating menu.\n"); 543 return rc; 544 } 545 546 rc = ui_menu_entry_create(msearch, "~F~ind", "Ctrl-F", &mfind); 547 if (rc != EOK) { 548 printf("Error creating menu.\n"); 549 return rc; 550 } 551 552 ui_menu_entry_set_cb(mfind, edit_search_find, (void *) edit); 553 554 rc = ui_menu_entry_create(msearch, "~R~everse Find", "Ctrl-Shift-F", &mfindr); 555 if (rc != EOK) { 556 printf("Error creating menu.\n"); 557 return rc; 558 } 559 560 ui_menu_entry_set_cb(mfindr, edit_search_reverse_find, (void *) edit); 561 562 rc = ui_menu_entry_create(msearch, "Find ~N~ext", "Ctrl-R", &mfindn); 563 if (rc != EOK) { 564 printf("Error creating menu.\n"); 565 return rc; 566 } 567 568 ui_menu_entry_set_cb(mfindn, edit_search_find_next, (void *) edit); 569 570 rc = ui_menu_entry_sep_create(msearch, &mssep); 571 if (rc != EOK) { 572 printf("Error creating menu.\n"); 573 return rc; 574 } 575 576 rc = ui_menu_entry_create(msearch, "Go To ~L~ine", "Ctrl-L", &mgoto); 577 if (rc != EOK) { 578 printf("Error creating menu.\n"); 579 return rc; 580 } 581 582 ui_menu_entry_set_cb(mgoto, edit_search_go_to_line, (void *) edit); 583 584 ui_window_get_app_rect(edit->window, &arect); 585 586 rect.p0 = arect.p0; 587 rect.p1.x = arect.p1.x; 588 rect.p1.y = arect.p0.y + 1; 589 ui_menu_bar_set_rect(edit->menubar, &rect); 590 591 rc = ui_fixed_add(fixed, ui_menu_bar_ctl(edit->menubar)); 592 if (rc != EOK) { 593 printf("Error adding control to layout.\n"); 594 return rc; 595 } 596 597 rc = pane_init(edit->window, &pane); 598 if (rc != EOK) { 599 printf("Error initializing pane.\n"); 600 return rc; 601 } 602 603 rc = ui_fixed_add(fixed, pane_ctl(&pane)); 604 if (rc != EOK) { 605 printf("Error adding control to layout.\n"); 606 return rc; 607 } 608 609 rc = ui_label_create(edit->ui_res, "", &edit->status); 610 if (rc != EOK) { 611 printf("Error creating menu bar.\n"); 612 return rc; 613 } 614 615 rect.p0.x = arect.p0.x; 616 rect.p0.y = arect.p1.y - 1; 617 rect.p1 = arect.p1; 618 ui_label_set_rect(edit->status, &rect); 619 620 rc = ui_fixed_add(fixed, ui_label_ctl(edit->status)); 621 if (rc != EOK) { 622 printf("Error adding control to layout.\n"); 623 return rc; 624 } 625 626 ui_window_add(edit->window, ui_fixed_ctl(fixed)); 627 return EOK; 628 error: 629 if (edit->window != NULL) 630 ui_window_destroy(edit->window); 631 if (edit->ui != NULL) 632 ui_destroy(edit->ui); 633 return rc; 634 } 635 636 /** Destroy text editor UI. 637 * 638 * @param edit Editor 639 */ 640 static void edit_ui_destroy(edit_t *edit) 641 { 642 ui_window_destroy(edit->window); 643 ui_destroy(edit->ui); 289 644 } 290 645 … … 309 664 } 310 665 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 666 static void cursor_setvis(bool visible) 322 667 { 323 if (cursor_visible != visible) { 324 console_cursor_visibility(con, visible); 325 cursor_visible = visible; 326 } 668 gfx_context_t *gc = ui_window_get_gc(edit.window); 669 670 (void) gfx_cursor_set_visible(gc, visible); 327 671 } 328 672 … … 400 744 switch (ev->key) { 401 745 case KC_Q: 402 done = true; 746 ui_quit(edit.ui); 747 break; 748 case KC_N: 749 file_new(); 750 break; 751 case KC_O: 752 file_open(); 403 753 break; 404 754 case KC_S: … … 415 765 break; 416 766 case KC_V: 417 selection_delete(); 418 insert_clipboard_data(); 419 pane.rflags |= REDRAW_TEXT; 420 caret_update(); 767 edit_paste(); 421 768 break; 422 769 case KC_X: 423 selection_copy(); 424 selection_delete(); 425 pane.rflags |= REDRAW_TEXT; 426 caret_update(); 770 edit_cut(); 427 771 break; 428 772 case KC_A: … … 441 785 search_prompt(false); 442 786 break; 443 case KC_ N:787 case KC_R: 444 788 search_repeat(); 445 789 break; … … 490 834 491 835 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 ;836 bc.row = pane.sh_row + ev->vpos - pane.rect.p0.y; 837 bc.column = pane.sh_column + ev->hpos - pane.rect.p0.x; 494 838 sheet_get_cell_pt(doc.sh, &bc, dir_before, &pt); 495 839 … … 497 841 498 842 caret_move(pt, select, true); 843 pane_update(&pane); 499 844 } 500 845 } … … 579 924 } 580 925 926 /** Create new document. */ 927 static errno_t file_new(void) 928 { 929 errno_t rc; 930 sheet_t *sh; 931 932 /* Create empty sheet. */ 933 rc = sheet_create(&sh); 934 if (rc != EOK) { 935 printf("Out of memory.\n"); 936 return ENOMEM; 937 } 938 939 if (doc.sh != NULL) 940 sheet_destroy(doc.sh); 941 942 doc.sh = sh; 943 944 /* Place caret at the beginning of file. */ 945 spt_t sof; 946 pt_get_sof(&sof); 947 sheet_place_tag(doc.sh, &sof, &pane.caret_pos); 948 pane.ideal_column = 1; 949 950 doc.file_name = NULL; 951 952 /* Place selection start tag. */ 953 sheet_place_tag(doc.sh, &sof, &pane.sel_start); 954 955 /* Move to beginning of file. */ 956 pt_get_sof(&sof); 957 958 caret_move(sof, true, true); 959 960 pane_status_display(&pane); 961 pane_caret_display(&pane); 962 pane_text_display(&pane); 963 cursor_setvis(true); 964 965 return EOK; 966 } 967 968 /** Open Open File dialog. */ 969 static void file_open(void) 970 { 971 const char *old_fname = (doc.file_name != NULL) ? doc.file_name : ""; 972 ui_file_dialog_params_t fdparams; 973 ui_file_dialog_t *dialog; 974 errno_t rc; 975 976 ui_file_dialog_params_init(&fdparams); 977 fdparams.caption = "Open File"; 978 fdparams.ifname = old_fname; 979 980 rc = ui_file_dialog_create(edit.ui, &fdparams, &dialog); 981 if (rc != EOK) { 982 printf("Error creating message dialog.\n"); 983 return; 984 } 985 986 ui_file_dialog_set_cb(dialog, &open_dialog_cb, &edit); 987 } 988 989 /** Open exising document. */ 990 static errno_t file_open_file(const char *fname) 991 { 992 errno_t rc; 993 sheet_t *sh; 994 char *fn; 995 996 /* Create empty sheet. */ 997 rc = sheet_create(&sh); 998 if (rc != EOK) { 999 printf("Out of memory.\n"); 1000 return ENOMEM; 1001 } 1002 1003 fn = str_dup(fname); 1004 if (fn == NULL) { 1005 sheet_destroy(sh); 1006 return ENOMEM; 1007 } 1008 1009 if (doc.sh != NULL) 1010 sheet_destroy(doc.sh); 1011 1012 doc.sh = sh; 1013 1014 /* Place caret at the beginning of file. */ 1015 spt_t sof; 1016 pt_get_sof(&sof); 1017 sheet_place_tag(doc.sh, &sof, &pane.caret_pos); 1018 pane.ideal_column = 1; 1019 1020 rc = file_insert(fname); 1021 if (rc != EOK) 1022 return rc; 1023 1024 doc.file_name = fn; 1025 1026 /* Place selection start tag. */ 1027 sheet_place_tag(doc.sh, &sof, &pane.sel_start); 1028 1029 /* Move to beginning of file. */ 1030 pt_get_sof(&sof); 1031 1032 caret_move(sof, true, true); 1033 1034 pane_status_display(&pane); 1035 pane_caret_display(&pane); 1036 pane_text_display(&pane); 1037 cursor_setvis(true); 1038 1039 return EOK; 1040 } 1041 581 1042 /** Save the document. */ 582 1043 static errno_t file_save(char const *fname) … … 606 1067 } 607 1068 608 /** Change document name and save. */1069 /** Open Save As dialog. */ 609 1070 static void file_save_as(void) 610 1071 { 611 1072 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."); 1073 ui_file_dialog_params_t fdparams; 1074 ui_file_dialog_t *dialog; 1075 errno_t rc; 1076 1077 ui_file_dialog_params_init(&fdparams); 1078 fdparams.caption = "Save As"; 1079 fdparams.ifname = old_fname; 1080 1081 rc = ui_file_dialog_create(edit.ui, &fdparams, &dialog); 1082 if (rc != EOK) { 1083 printf("Error creating message dialog.\n"); 617 1084 return; 618 1085 } 619 1086 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; 1087 ui_file_dialog_set_cb(dialog, &save_as_dialog_cb, &edit); 694 1088 } 695 1089 … … 699 1093 * of the caret. 700 1094 */ 701 static errno_t file_insert(c har *fname)1095 static errno_t file_insert(const char *fname) 702 1096 { 703 1097 FILE *f; … … 726 1120 727 1121 bcnt -= off; 728 mem cpy(buf, buf + off, bcnt);1122 memmove(buf, buf + off, bcnt); 729 1123 730 1124 insert_char(c); … … 808 1202 } 809 1203 810 static void pane_text_display(void) 811 { 1204 /** Initialize pane. 1205 * 1206 * TODO: Replace with pane_create() that allocates the pane. 1207 * 1208 * @param window Editor window 1209 * @param pane Pane 1210 * @return EOK on success or an error code 1211 */ 1212 static errno_t pane_init(ui_window_t *window, pane_t *pane) 1213 { 1214 errno_t rc; 1215 gfx_rect_t arect; 1216 1217 pane->control = NULL; 1218 pane->color = NULL; 1219 pane->sel_color = NULL; 1220 1221 rc = ui_control_new(&pane_ctl_ops, (void *) pane, &pane->control); 1222 if (rc != EOK) 1223 goto error; 1224 1225 rc = gfx_color_new_ega(0x07, &pane->color); 1226 if (rc != EOK) 1227 goto error; 1228 1229 rc = gfx_color_new_ega(0x1e, &pane->sel_color); 1230 if (rc != EOK) 1231 goto error; 1232 1233 pane->res = ui_window_get_res(window); 1234 pane->window = window; 1235 1236 ui_window_get_app_rect(window, &arect); 1237 pane->rect.p0.x = arect.p0.x; 1238 pane->rect.p0.y = arect.p0.y + 1; 1239 pane->rect.p1.x = arect.p1.x; 1240 pane->rect.p1.y = arect.p1.y - 1; 1241 1242 pane->columns = pane->rect.p1.x - pane->rect.p0.x; 1243 pane->rows = pane->rect.p1.y - pane->rect.p0.y; 1244 1245 return EOK; 1246 error: 1247 if (pane->control != NULL) { 1248 ui_control_delete(pane->control); 1249 pane->control = NULL; 1250 } 1251 1252 if (pane->color != NULL) { 1253 gfx_color_delete(pane->color); 1254 pane->color = NULL; 1255 } 1256 1257 return rc; 1258 } 1259 1260 /** Finalize pane. 1261 * 1262 * TODO: Replace with pane_destroy() that deallocates the pane. 1263 * 1264 * @param pane Pane 1265 */ 1266 static void pane_fini(pane_t *pane) 1267 { 1268 gfx_color_delete(pane->color); 1269 pane->color = NULL; 1270 gfx_color_delete(pane->sel_color); 1271 pane->sel_color = NULL; 1272 ui_control_delete(pane->control); 1273 pane->control = NULL; 1274 } 1275 1276 /** Return base control object for a pane. 1277 * 1278 * @param pane Pane 1279 * @return Base UI cntrol 1280 */ 1281 static ui_control_t *pane_ctl(pane_t *pane) 1282 { 1283 return pane->control; 1284 } 1285 1286 /** Repaint parts of pane that need updating. 1287 * 1288 * @param pane Pane 1289 * @return EOK on succes or an error code 1290 */ 1291 static errno_t pane_update(pane_t *pane) 1292 { 1293 errno_t rc; 1294 1295 if (pane->rflags & REDRAW_TEXT) { 1296 rc = pane_text_display(pane); 1297 if (rc != EOK) 1298 return rc; 1299 } 1300 1301 if (pane->rflags & REDRAW_ROW) 1302 pane_row_display(); 1303 1304 if (pane->rflags & REDRAW_STATUS) 1305 pane_status_display(pane); 1306 1307 if (pane->rflags & REDRAW_CARET) 1308 pane_caret_display(pane); 1309 1310 pane->rflags &= ~(REDRAW_TEXT | REDRAW_ROW | REDRAW_STATUS | 1311 REDRAW_CARET); 1312 return EOK; 1313 } 1314 1315 /** Display pane text. 1316 * 1317 * @param pane Pane 1318 * @return EOK on success or an error code 1319 */ 1320 static errno_t pane_text_display(pane_t *pane) 1321 { 1322 gfx_rect_t rect; 1323 gfx_context_t *gc; 1324 errno_t rc; 812 1325 int sh_rows, rows; 813 1326 814 1327 sheet_get_num_rows(doc.sh, &sh_rows); 815 rows = min(sh_rows - pane .sh_row + 1, pane.rows);1328 rows = min(sh_rows - pane->sh_row + 1, pane->rows); 816 1329 817 1330 /* Draw rows from the sheet. */ 818 1331 819 console_set_pos(con, 0, 0); 820 pane_row_range_display(0, rows); 1332 rc = pane_row_range_display(pane, 0, rows); 1333 if (rc != EOK) 1334 return rc; 821 1335 822 1336 /* Clear the remaining rows if file is short. */ 823 1337 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; 1338 gc = ui_window_get_gc(pane->window); 1339 1340 rc = gfx_set_color(gc, pane->color); 1341 if (rc != EOK) 1342 goto error; 1343 1344 rect.p0.x = pane->rect.p0.x; 1345 rect.p0.y = pane->rect.p0.y + rows; 1346 rect.p1.x = pane->rect.p1.x; 1347 rect.p1.y = pane->rect.p1.y; 1348 1349 rc = gfx_fill_rect(gc, &rect); 1350 if (rc != EOK) 1351 goto error; 1352 1353 pane->rflags &= ~REDRAW_ROW; 1354 return EOK; 1355 error: 1356 return rc; 835 1357 } 836 1358 … … 846 1368 847 1369 ridx = coord.row - pane.sh_row; 848 pane_row_range_display(ridx, ridx + 1);1370 (void) pane_row_range_display(&pane, ridx, ridx + 1); 849 1371 pane.rflags |= (REDRAW_STATUS | REDRAW_CARET); 850 1372 } 851 1373 852 static void pane_row_range_display(int r0, int r1) 853 { 854 int i, j, fill; 1374 /** Display a range of rows of text. 1375 * 1376 * @param r0 Start row (inclusive) 1377 * @param r1 End row (exclusive) 1378 * @return EOk on success or an error code 1379 */ 1380 static errno_t pane_row_range_display(pane_t *pane, int r0, int r1) 1381 { 1382 int i, fill; 855 1383 spt_t rb, re, dep, pt; 856 1384 coord_t rbc, rec; 857 1385 char row_buf[ROW_BUF_SIZE]; 1386 char cbuf[STR_BOUNDS(1) + 1]; 858 1387 char32_t c; 859 1388 size_t pos, size; 1389 size_t cpos; 860 1390 int s_column; 861 1391 coord_t csel_start, csel_end, ctmp; 1392 gfx_font_t *font; 1393 gfx_context_t *gc; 1394 gfx_text_fmt_t fmt; 1395 gfx_coord2_t tpos; 1396 gfx_rect_t rect; 1397 errno_t rc; 1398 1399 font = ui_resource_get_font(edit.ui_res); 1400 gc = ui_window_get_gc(edit.window); 1401 1402 gfx_text_fmt_init(&fmt); 1403 fmt.font = font; 1404 fmt.color = pane->color; 862 1405 863 1406 /* Determine selection start and end. */ 864 1407 865 tag_get_pt(&pane .sel_start, &pt);1408 tag_get_pt(&pane->sel_start, &pt); 866 1409 spt_get_coord(&pt, &csel_start); 867 1410 868 tag_get_pt(&pane .caret_pos, &pt);1411 tag_get_pt(&pane->caret_pos, &pt); 869 1412 spt_get_coord(&pt, &csel_end); 870 1413 … … 877 1420 /* Draw rows from the sheet. */ 878 1421 879 console_set_pos(con, 0, 0);880 1422 for (i = r0; i < r1; ++i) { 1423 tpos.x = pane->rect.p0.x; 1424 tpos.y = pane->rect.p0.y + i; 1425 881 1426 /* Starting point for row display */ 882 rbc.row = pane .sh_row + i;883 rbc.column = pane .sh_column;1427 rbc.row = pane->sh_row + i; 1428 rbc.column = pane->sh_column; 884 1429 sheet_get_cell_pt(doc.sh, &rbc, dir_before, &rb); 885 1430 886 1431 /* Ending point for row display */ 887 rec.row = pane .sh_row + i;888 rec.column = pane .sh_column + pane.columns;1432 rec.row = pane->sh_row + i; 1433 rec.column = pane->sh_column + pane->columns; 889 1434 sheet_get_cell_pt(doc.sh, &rec, dir_before, &re); 890 1435 … … 896 1441 if (coord_cmp(&csel_start, &rbc) <= 0 && 897 1442 coord_cmp(&rbc, &csel_end) < 0) { 898 console_flush(con); 899 console_set_style(con, STYLE_SELECTED); 900 console_flush(con); 1443 fmt.color = pane->sel_color; 901 1444 } 902 1445 903 console_set_pos(con, 0, i);904 1446 size = str_size(row_buf); 905 1447 pos = 0; 906 s_column = pane .sh_column;1448 s_column = pane->sh_column; 907 1449 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 } 1450 if ((csel_start.row == rbc.row) && (csel_start.column == s_column)) 1451 fmt.color = pane->sel_color; 1452 1453 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) 1454 fmt.color = pane->color; 919 1455 920 1456 c = str_decode(row_buf, &pos, size); 921 1457 if (c != '\t') { 922 printf("%lc", (wint_t) c); 1458 cpos = 0; 1459 rc = chr_encode(c, cbuf, &cpos, sizeof(cbuf)); 1460 if (rc != EOK) 1461 return rc; 1462 1463 rc = gfx_puttext(&tpos, &fmt, cbuf); 1464 if (rc != EOK) 1465 return rc; 1466 923 1467 s_column += 1; 1468 tpos.x++; 924 1469 } else { 925 1470 fill = 1 + ALIGN_UP(s_column, TAB_WIDTH) - 926 1471 s_column; 927 1472 928 for (j = 0; j < fill; ++j) 929 putchar(' '); 1473 rc = gfx_set_color(gc, fmt.color); 1474 if (rc != EOK) 1475 return rc; 1476 1477 rect.p0.x = tpos.x; 1478 rect.p0.y = tpos.y; 1479 rect.p1.x = tpos.x + fill; 1480 rect.p1.y = tpos.y + 1; 1481 1482 rc = gfx_fill_rect(gc, &rect); 1483 if (rc != EOK) 1484 return rc; 1485 930 1486 s_column += fill; 1487 tpos.x += fill; 931 1488 } 932 1489 } 933 1490 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 } 1491 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) 1492 fmt.color = pane->color; 939 1493 940 1494 /* Fill until the end of display area. */ 941 1495 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) 1496 rc = gfx_set_color(gc, fmt.color); 1497 if (rc != EOK) 1498 return rc; 1499 1500 rect.p0.x = tpos.x; 1501 rect.p0.y = tpos.y; 1502 rect.p1.x = pane->rect.p1.x; 1503 rect.p1.y = tpos.y + 1; 1504 1505 rc = gfx_fill_rect(gc, &rect); 1506 if (rc != EOK) 1507 return rc; 1508 } 1509 1510 return EOK; 1511 } 1512 1513 /** Display pane status in the status line. 1514 * 1515 * @param pane Pane 1516 */ 1517 static void pane_status_display(pane_t *pane) 958 1518 { 959 1519 spt_t caret_pt; … … 964 1524 char *text; 965 1525 size_t n; 966 int pos;967 1526 size_t nextra; 968 1527 size_t fnw; 969 1528 970 tag_get_pt(&pane .caret_pos, &caret_pt);1529 tag_get_pt(&pane->caret_pos, &caret_pt); 971 1530 spt_get_coord(&caret_pt, &coord); 972 1531 … … 987 1546 return; 988 1547 989 console_set_pos(con, 0, scr_rows - 1);990 console_set_style(con, STYLE_INVERTED);991 992 1548 /* 993 1549 * Make sure the status fits on the screen. This loop should … … 995 1551 */ 996 1552 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);1553 int rc = asprintf(&text, "%d, %d (%d): File '%s'. Ctrl-Q Quit " 1554 "F10 Menu", coord.row, coord.column, last_row, fname); 999 1555 if (rc < 0) { 1000 1556 n = 0; … … 1004 1560 /* If it already fits, we're done */ 1005 1561 n = str_width(text); 1006 if ( n <= scr_columns - 2)1562 if ((int)n <= pane->columns - 2) 1007 1563 break; 1008 1564 1009 1565 /* Compute number of excess characters */ 1010 nextra = n - ( scr_columns - 2);1566 nextra = n - (pane->columns - 2); 1011 1567 /** With of the file name part */ 1012 1568 fnw = str_width(fname); … … 1016 1572 * just give up and print a blank status. 1017 1573 */ 1018 if (nextra > fnw - 2) 1574 if (nextra > fnw - 2) { 1575 text[0] = '\0'; 1019 1576 goto finish; 1577 } 1020 1578 1021 1579 /* Compute position where we overwrite with '..\0' */ … … 1034 1592 } 1035 1593 1036 printf("%s", text); 1594 finish: 1595 (void) ui_label_set_text(edit.status, text); 1596 (void) ui_label_paint(edit.status); 1037 1597 free(text); 1038 1598 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) 1599 } 1600 1601 /** Set cursor to reflect position of the caret. 1602 * 1603 * @param pane Pane 1604 */ 1605 static void pane_caret_display(pane_t *pane) 1051 1606 { 1052 1607 spt_t caret_pt; 1053 1608 coord_t coord; 1054 1055 tag_get_pt(&pane.caret_pos, &caret_pt); 1609 gfx_coord2_t pos; 1610 gfx_context_t *gc; 1611 1612 tag_get_pt(&pane->caret_pos, &caret_pt); 1056 1613 1057 1614 spt_get_coord(&caret_pt, &coord); 1058 console_set_pos(con, coord.column - pane.sh_column, 1059 coord.row - pane.sh_row); 1615 1616 gc = ui_window_get_gc(edit.window); 1617 pos.x = pane->rect.p0.x + coord.column - pane->sh_column; 1618 pos.y = pane->rect.p0.y + coord.row - pane->sh_row; 1619 1620 (void) gfx_cursor_set_pos(gc, &pos); 1621 } 1622 1623 /** Destroy pane control. 1624 * 1625 * @param arg Argument (pane_t *) 1626 */ 1627 static void pane_ctl_destroy(void *arg) 1628 { 1629 pane_t *pane = (pane_t *)arg; 1630 1631 pane_fini(pane); 1632 } 1633 1634 /** Paint pane control. 1635 * 1636 * @param arg Argument (pane_t *) 1637 */ 1638 static errno_t pane_ctl_paint(void *arg) 1639 { 1640 pane_t *pane = (pane_t *)arg; 1641 gfx_context_t *gc; 1642 errno_t rc; 1643 1644 gc = ui_window_get_gc(pane->window); 1645 1646 rc = pane_text_display(pane); 1647 if (rc != EOK) 1648 goto error; 1649 1650 rc = gfx_update(gc); 1651 if (rc != EOK) 1652 goto error; 1653 1654 error: 1655 return rc; 1656 } 1657 1658 /** Handle pane control position event. 1659 * 1660 * @param arg Argument (pane_t *) 1661 * @param event Position event 1662 */ 1663 static ui_evclaim_t pane_ctl_pos_event(void *arg, pos_event_t *event) 1664 { 1665 gfx_coord2_t pos; 1666 1667 pos.x = event->hpos; 1668 pos.y = event->vpos; 1669 1670 if (!gfx_pix_inside_rect(&pos, &pane.rect)) 1671 return ui_unclaimed; 1672 1673 pos_handle(event); 1674 (void) gfx_update(ui_window_get_gc(edit.window)); 1675 return ui_claimed; 1060 1676 } 1061 1677 … … 1270 1886 static void caret_go_to_line_ask(void) 1271 1887 { 1272 char *sline; 1273 1274 sline = prompt("Go to line", ""); 1275 if (sline == NULL) { 1276 status_display("Go to line cancelled."); 1888 ui_prompt_dialog_params_t pdparams; 1889 ui_prompt_dialog_t *dialog; 1890 errno_t rc; 1891 1892 ui_prompt_dialog_params_init(&pdparams); 1893 pdparams.caption = "Go To Line"; 1894 pdparams.prompt = "Line Number"; 1895 1896 rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog); 1897 if (rc != EOK) { 1898 printf("Error creating prompt dialog.\n"); 1277 1899 return; 1278 1900 } 1279 1901 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); 1902 ui_prompt_dialog_set_cb(dialog, &go_to_line_dialog_cb, &edit); 1290 1903 } 1291 1904 … … 1344 1957 static void search_prompt(bool reverse) 1345 1958 { 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 = ""; 1959 ui_prompt_dialog_params_t pdparams; 1960 ui_prompt_dialog_t *dialog; 1961 errno_t rc; 1962 1963 ui_prompt_dialog_params_init(&pdparams); 1964 pdparams.caption = reverse ? "Reverse Search" : "Search"; 1965 pdparams.prompt = "Search text"; 1966 pdparams.itext = ""; 1967 1353 1968 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.");1969 pdparams.itext = pane.previous_search; 1970 1971 rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog); 1972 if (rc != EOK) { 1973 printf("Error creating prompt dialog.\n"); 1359 1974 return; 1360 1975 } 1361 1976 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); 1977 ui_prompt_dialog_set_cb(dialog, &search_dialog_cb, &edit); 1978 pane.search_reverse = reverse; 1368 1979 } 1369 1980 … … 1513 2124 } 1514 2125 free(str); 2126 } 2127 2128 static void edit_paste(void) 2129 { 2130 selection_delete(); 2131 insert_clipboard_data(); 2132 pane.rflags |= (REDRAW_TEXT | REDRAW_CARET); 2133 pane_update(&pane); 2134 } 2135 2136 static void edit_cut(void) 2137 { 2138 selection_copy(); 2139 selection_delete(); 2140 pane.rflags |= (REDRAW_TEXT | REDRAW_CARET); 2141 pane_update(&pane); 1515 2142 } 1516 2143 … … 1719 2346 static void status_display(char const *str) 1720 2347 { 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); 2348 (void) ui_label_set_text(edit.status, str); 2349 (void) ui_label_paint(edit.status); 2350 } 2351 2352 /** Window close request 2353 * 2354 * @param window Window 2355 * @param arg Argument (edit_t *) 2356 */ 2357 static void edit_wnd_close(ui_window_t *window, void *arg) 2358 { 2359 edit_t *edit = (edit_t *) arg; 2360 2361 ui_quit(edit->ui); 2362 } 2363 2364 /** Window focus event 2365 * 2366 * @param window Window 2367 * @param arg Argument (edit_t *) 2368 * @param focus Focus number 2369 */ 2370 static void edit_wnd_focus(ui_window_t *window, void *arg, unsigned focus) 2371 { 2372 edit_t *edit = (edit_t *)arg; 2373 2374 (void)edit; 2375 pane_caret_display(&pane); 2376 cursor_setvis(true); 2377 } 2378 2379 /** Window keyboard event 2380 * 2381 * @param window Window 2382 * @param arg Argument (edit_t *) 2383 * @param event Keyboard event 2384 */ 2385 static void edit_wnd_kbd_event(ui_window_t *window, void *arg, 2386 kbd_event_t *event) 2387 { 2388 pane.keymod = event->mods; 2389 2390 if (ui_window_def_kbd(window, event) == ui_claimed) 2391 return; 2392 2393 if (event->type == KEY_PRESS) { 2394 key_handle_press(event); 2395 (void) pane_update(&pane); 2396 (void) gfx_update(ui_window_get_gc(window)); 2397 } 2398 } 2399 2400 /** Window unfocus event 2401 * 2402 * @param window Window 2403 * @param arg Argument (edit_t *) 2404 * @param focus Focus number 2405 */ 2406 static void edit_wnd_unfocus(ui_window_t *window, void *arg, unsigned focus) 2407 { 2408 edit_t *edit = (edit_t *) arg; 2409 2410 (void)edit; 2411 cursor_setvis(false); 2412 } 2413 2414 /** Menu bar activate event 2415 * 2416 * @param mbar Menu bar 2417 * @param arg Argument (edit_t *) 2418 */ 2419 static void edit_menubar_activate(ui_menu_bar_t *mbar, void *arg) 2420 { 2421 edit_t *edit = (edit_t *)arg; 2422 2423 (void)edit; 2424 cursor_setvis(false); 2425 } 2426 2427 /** Menu bar deactivate event 2428 * 2429 * @param mbar Menu bar 2430 * @param arg Argument (edit_t *) 2431 */ 2432 static void edit_menubar_deactivate(ui_menu_bar_t *mbar, void *arg) 2433 { 2434 edit_t *edit = (edit_t *)arg; 2435 2436 (void)edit; 2437 pane_caret_display(&pane); 2438 cursor_setvis(true); 2439 } 2440 2441 /** File / New menu entry selected. 2442 * 2443 * @param mentry Menu entry 2444 * @param arg Argument (edit_t *) 2445 */ 2446 static void edit_file_new(ui_menu_entry_t *mentry, void *arg) 2447 { 2448 edit_t *edit = (edit_t *) arg; 2449 2450 (void)edit; 2451 file_new(); 2452 (void) gfx_update(ui_window_get_gc(edit->window)); 2453 } 2454 2455 /** File / Open menu entry selected. 2456 * 2457 * @param mentry Menu entry 2458 * @param arg Argument (edit_t *) 2459 */ 2460 static void edit_file_open(ui_menu_entry_t *mentry, void *arg) 2461 { 2462 edit_t *edit = (edit_t *) arg; 2463 2464 (void)edit; 2465 file_open(); 2466 } 2467 2468 /** File / Save menu entry selected. 2469 * 2470 * @param mentry Menu entry 2471 * @param arg Argument (edit_t *) 2472 */ 2473 static void edit_file_save(ui_menu_entry_t *mentry, void *arg) 2474 { 2475 edit_t *edit = (edit_t *) arg; 2476 2477 (void)edit; 2478 2479 if (doc.file_name != NULL) 2480 file_save(doc.file_name); 2481 else 2482 file_save_as(); 2483 } 2484 2485 /** File / Save As menu entry selected. 2486 * 2487 * @param mentry Menu entry 2488 * @param arg Argument (edit_t *) 2489 */ 2490 static void edit_file_save_as(ui_menu_entry_t *mentry, void *arg) 2491 { 2492 edit_t *edit = (edit_t *) arg; 2493 2494 (void)edit; 2495 file_save_as(); 2496 } 2497 2498 /** File / Exit menu entry selected. 2499 * 2500 * @param mentry Menu entry 2501 * @param arg Argument (edit_t *) 2502 */ 2503 static void edit_file_exit(ui_menu_entry_t *mentry, void *arg) 2504 { 2505 edit_t *edit = (edit_t *) arg; 2506 2507 ui_quit(edit->ui); 2508 } 2509 2510 /** Edit / Cut menu entry selected. 2511 * 2512 * @param mentry Menu entry 2513 * @param arg Argument (edit_t *) 2514 */ 2515 static void edit_edit_cut(ui_menu_entry_t *mentry, void *arg) 2516 { 2517 (void) arg; 2518 edit_cut(); 2519 (void) gfx_update(ui_window_get_gc(edit.window)); 2520 } 2521 2522 /** Edit / Copy menu entry selected. 2523 * 2524 * @param mentry Menu entry 2525 * @param arg Argument (edit_t *) 2526 */ 2527 static void edit_edit_copy(ui_menu_entry_t *mentry, void *arg) 2528 { 2529 (void) arg; 2530 selection_copy(); 2531 } 2532 2533 /** Edit / Paste menu entry selected. 2534 * 2535 * @param mentry Menu entry 2536 * @param arg Argument (edit_t *) 2537 */ 2538 static void edit_edit_paste(ui_menu_entry_t *mentry, void *arg) 2539 { 2540 (void) arg; 2541 edit_paste(); 2542 (void) gfx_update(ui_window_get_gc(edit.window)); 2543 } 2544 2545 /** Edit / Delete menu entry selected. 2546 * 2547 * @param mentry Menu entry 2548 * @param arg Argument (edit_t *) 2549 */ 2550 static void edit_edit_delete(ui_menu_entry_t *mentry, void *arg) 2551 { 2552 (void) arg; 2553 2554 if (selection_active()) 2555 selection_delete(); 1728 2556 1729 2557 pane.rflags |= REDRAW_CARET; 2558 (void) pane_update(&pane); 2559 (void) gfx_update(ui_window_get_gc(edit.window)); 2560 } 2561 2562 /** Edit / Select All menu entry selected. 2563 * 2564 * @param mentry Menu entry 2565 * @param arg Argument (edit_t *) 2566 */ 2567 static void edit_edit_select_all(ui_menu_entry_t *mentry, void *arg) 2568 { 2569 (void) arg; 2570 2571 selection_sel_all(); 2572 pane.rflags |= (REDRAW_CARET | REDRAW_TEXT | REDRAW_STATUS); 2573 pane_update(&pane); 2574 (void) gfx_update(ui_window_get_gc(edit.window)); 2575 } 2576 2577 /** Search / Find menu entry selected. 2578 * 2579 * @param mentry Menu entry 2580 * @param arg Argument (edit_t *) 2581 */ 2582 static void edit_search_find(ui_menu_entry_t *mentry, void *arg) 2583 { 2584 (void) arg; 2585 search_prompt(false); 2586 } 2587 2588 /** Search / Reverse Find menu entry selected. 2589 * 2590 * @param mentry Menu entry 2591 * @param arg Argument (edit_t *) 2592 */ 2593 static void edit_search_reverse_find(ui_menu_entry_t *mentry, void *arg) 2594 { 2595 (void) arg; 2596 search_prompt(true); 2597 } 2598 2599 /** Search / Find Next menu entry selected. 2600 * 2601 * @param mentry Menu entry 2602 * @param arg Argument (edit_t *) 2603 */ 2604 static void edit_search_find_next(ui_menu_entry_t *mentry, void *arg) 2605 { 2606 (void) arg; 2607 search_repeat(); 2608 (void) pane_update(&pane); 2609 (void) gfx_update(ui_window_get_gc(edit.window)); 2610 } 2611 2612 /** Search / Go To Line menu entry selected. 2613 * 2614 * @param mentry Menu entry 2615 * @param arg Argument (edit_t *) 2616 */ 2617 static void edit_search_go_to_line(ui_menu_entry_t *mentry, void *arg) 2618 { 2619 (void) arg; 2620 caret_go_to_line_ask(); 2621 } 2622 2623 /** Open File dialog OK button press. 2624 * 2625 * @param dialog Open File dialog 2626 * @param arg Argument (ui_demo_t *) 2627 * @param fname File name 2628 */ 2629 static void open_dialog_bok(ui_file_dialog_t *dialog, void *arg, 2630 const char *fname) 2631 { 2632 edit_t *edit = (edit_t *)arg; 2633 char *cname; 2634 errno_t rc; 2635 2636 (void)edit; 2637 ui_file_dialog_destroy(dialog); 2638 2639 cname = str_dup(fname); 2640 if (cname == NULL) { 2641 printf("Out of memory.\n"); 2642 return; 2643 } 2644 2645 rc = file_open_file(fname); 2646 if (rc != EOK) 2647 return; 2648 2649 if (doc.file_name != NULL) 2650 free(doc.file_name); 2651 doc.file_name = cname; 2652 2653 (void) gfx_update(ui_window_get_gc(edit->window)); 2654 } 2655 2656 /** Open File dialog cancel button press. 2657 * 2658 * @param dialog File dialog 2659 * @param arg Argument (ui_demo_t *) 2660 */ 2661 static void open_dialog_bcancel(ui_file_dialog_t *dialog, void *arg) 2662 { 2663 edit_t *edit = (edit_t *)arg; 2664 2665 (void)edit; 2666 ui_file_dialog_destroy(dialog); 2667 } 2668 2669 /** Open File dialog close request. 2670 * 2671 * @param dialog File dialog 2672 * @param arg Argument (ui_demo_t *) 2673 */ 2674 static void open_dialog_close(ui_file_dialog_t *dialog, void *arg) 2675 { 2676 edit_t *edit = (edit_t *)arg; 2677 2678 (void)edit; 2679 ui_file_dialog_destroy(dialog); 2680 } 2681 2682 /** Save As dialog OK button press. 2683 * 2684 * @param dialog Save As dialog 2685 * @param arg Argument (ui_demo_t *) 2686 * @param fname File name 2687 */ 2688 static void save_as_dialog_bok(ui_file_dialog_t *dialog, void *arg, 2689 const char *fname) 2690 { 2691 edit_t *edit = (edit_t *)arg; 2692 char *cname; 2693 errno_t rc; 2694 2695 (void)edit; 2696 ui_file_dialog_destroy(dialog); 2697 2698 cname = str_dup(fname); 2699 if (cname == NULL) { 2700 printf("Out of memory.\n"); 2701 return; 2702 } 2703 2704 rc = file_save(fname); 2705 if (rc != EOK) 2706 return; 2707 2708 if (doc.file_name != NULL) 2709 free(doc.file_name); 2710 doc.file_name = cname; 2711 2712 } 2713 2714 /** Save As dialog cancel button press. 2715 * 2716 * @param dialog File dialog 2717 * @param arg Argument (ui_demo_t *) 2718 */ 2719 static void save_as_dialog_bcancel(ui_file_dialog_t *dialog, void *arg) 2720 { 2721 edit_t *edit = (edit_t *)arg; 2722 2723 (void)edit; 2724 ui_file_dialog_destroy(dialog); 2725 } 2726 2727 /** Save As dialog close request. 2728 * 2729 * @param dialog File dialog 2730 * @param arg Argument (ui_demo_t *) 2731 */ 2732 static void save_as_dialog_close(ui_file_dialog_t *dialog, void *arg) 2733 { 2734 edit_t *edit = (edit_t *)arg; 2735 2736 (void)edit; 2737 ui_file_dialog_destroy(dialog); 2738 } 2739 2740 /** Go To Line dialog OK button press. 2741 * 2742 * @param dialog Go To Line dialog 2743 * @param arg Argument (ui_demo_t *) 2744 * @param text Submitted text 2745 */ 2746 static void go_to_line_dialog_bok(ui_prompt_dialog_t *dialog, void *arg, 2747 const char *text) 2748 { 2749 edit_t *edit = (edit_t *) arg; 2750 char *endptr; 2751 int line; 2752 2753 ui_prompt_dialog_destroy(dialog); 2754 line = strtol(text, &endptr, 10); 2755 if (*endptr != '\0') { 2756 status_display("Invalid number entered."); 2757 return; 2758 } 2759 2760 caret_move_absolute(line, pane.ideal_column, dir_before, false); 2761 (void)edit; 2762 (void) pane_update(&pane); 2763 } 2764 2765 /** Go To Line dialog cancel button press. 2766 * 2767 * @param dialog File dialog 2768 * @param arg Argument (ui_demo_t *) 2769 */ 2770 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg) 2771 { 2772 edit_t *edit = (edit_t *) arg; 2773 2774 (void)edit; 2775 ui_prompt_dialog_destroy(dialog); 2776 } 2777 2778 /** Go To Line dialog close request. 2779 * 2780 * @param dialog File dialog 2781 * @param arg Argument (ui_demo_t *) 2782 */ 2783 static void go_to_line_dialog_close(ui_prompt_dialog_t *dialog, void *arg) 2784 { 2785 edit_t *edit = (edit_t *) arg; 2786 2787 (void)edit; 2788 ui_prompt_dialog_destroy(dialog); 2789 } 2790 2791 /** Search dialog OK button press. 2792 * 2793 * @param dialog Search dialog 2794 * @param arg Argument (ui_demo_t *) 2795 * @param text Submitted text 2796 */ 2797 static void search_dialog_bok(ui_prompt_dialog_t *dialog, void *arg, 2798 const char *text) 2799 { 2800 edit_t *edit = (edit_t *) arg; 2801 char *pattern; 2802 bool reverse; 2803 2804 (void)edit; 2805 ui_prompt_dialog_destroy(dialog); 2806 2807 /* Abort if search phrase is empty */ 2808 if (text[0] == '\0') 2809 return; 2810 2811 pattern = str_dup(text); 2812 reverse = pane.search_reverse; 2813 2814 if (pane.previous_search) 2815 free(pane.previous_search); 2816 pane.previous_search = pattern; 2817 pane.previous_search_reverse = reverse; 2818 2819 search(pattern, reverse); 2820 2821 (void) pane_update(&pane); 2822 } 2823 2824 /** Search dialog cancel button press. 2825 * 2826 * @param dialog File dialog 2827 * @param arg Argument (ui_demo_t *) 2828 */ 2829 static void search_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg) 2830 { 2831 edit_t *edit = (edit_t *) arg; 2832 2833 (void)edit; 2834 ui_prompt_dialog_destroy(dialog); 2835 } 2836 2837 /** Search dialog close request. 2838 * 2839 * @param dialog File dialog 2840 * @param arg Argument (ui_demo_t *) 2841 */ 2842 static void search_dialog_close(ui_prompt_dialog_t *dialog, void *arg) 2843 { 2844 edit_t *edit = (edit_t *) arg; 2845 2846 (void)edit; 2847 ui_prompt_dialog_destroy(dialog); 1730 2848 } 1731 2849
Note:
See TracChangeset
for help on using the changeset viewer.