Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/edit/edit.c

    r87822ce rec50d65e  
    11/*
    2  * Copyright (c) 2009 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * Copyright (c) 2012 Martin Sucha
    44 * All rights reserved.
     
    3636 */
    3737
     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>
    3851#include <stdio.h>
    3952#include <stdlib.h>
    4053#include <stddef.h>
    4154#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>
    4268#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>
    5169
    5270#include "sheet.h"
     
    6381 *
    6482 * 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.
    6685 */
    6786typedef 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
    68105        /* Pane dimensions */
    69106        int rows, columns;
     
    90127        int ideal_column;
    91128
     129        bool search_reverse;
    92130        char *previous_search;
    93131        bool previous_search_reverse;
    94132} pane_t;
     133
     134/** Text editor */
     135typedef 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;
    95147
    96148/** Document
     
    103155} doc_t;
    104156
    105 static console_ctrl_t *con;
     157static edit_t edit;
    106158static doc_t doc;
    107 static bool done;
    108159static pane_t pane;
    109 static bool cursor_visible;
    110 
    111 static sysarg_t scr_rows;
    112 static sysarg_t scr_columns;
    113160
    114161#define ROW_BUF_SIZE 4096
     
    119166#define INFNAME_MAX_LEN 128
    120167
    121 static void cursor_show(void);
    122 static void cursor_hide(void);
    123168static void cursor_setvis(bool visible);
    124169
     
    139184static char *range_get_str(spt_t const *spos, spt_t const *epos);
    140185
    141 static char *prompt(char const *prompt, char const *init_value);
    142 
    143 static void pane_text_display(void);
     186static errno_t pane_init(ui_window_t *, pane_t *);
     187static void pane_fini(pane_t *);
     188static ui_control_t *pane_ctl(pane_t *);
     189static errno_t pane_update(pane_t *);
     190static errno_t pane_text_display(pane_t *);
    144191static 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);
     192static errno_t pane_row_range_display(pane_t *, int r0, int r1);
     193static void pane_status_display(pane_t *);
     194static void pane_caret_display(pane_t *);
    148195
    149196static void insert_char(char32_t c);
     
    164211static void selection_delete(void);
    165212static void selection_copy(void);
     213static void edit_cut(void);
     214static void edit_paste(void);
    166215static void insert_clipboard_data(void);
    167216
     
    185234
    186235static void status_display(char const *str);
     236static errno_t edit_ui_create(edit_t *);
     237static void edit_ui_destroy(edit_t *);
     238
     239static void edit_wnd_close(ui_window_t *, void *);
     240static void edit_wnd_focus(ui_window_t *, void *, unsigned);
     241static void edit_wnd_kbd_event(ui_window_t *, void *, kbd_event_t *);
     242static void edit_wnd_unfocus(ui_window_t *, void *, unsigned);
     243
     244static ui_window_cb_t edit_window_cb = {
     245        .close = edit_wnd_close,
     246        .focus = edit_wnd_focus,
     247        .kbd = edit_wnd_kbd_event,
     248        .unfocus = edit_wnd_unfocus
     249};
     250
     251static void edit_menubar_activate(ui_menu_bar_t *, void *);
     252static void edit_menubar_deactivate(ui_menu_bar_t *, void *);
     253
     254static ui_menu_bar_cb_t edit_menubar_cb = {
     255        .activate = edit_menubar_activate,
     256        .deactivate = edit_menubar_deactivate
     257};
     258
     259static void edit_file_save(ui_menu_entry_t *, void *);
     260static void edit_file_save_as(ui_menu_entry_t *, void *);
     261static void edit_file_exit(ui_menu_entry_t *, void *);
     262static void edit_edit_cut(ui_menu_entry_t *, void *);
     263static void edit_edit_copy(ui_menu_entry_t *, void *);
     264static void edit_edit_paste(ui_menu_entry_t *, void *);
     265static void edit_edit_delete(ui_menu_entry_t *, void *);
     266static void edit_edit_select_all(ui_menu_entry_t *, void *);
     267static void edit_search_find(ui_menu_entry_t *, void *);
     268static void edit_search_reverse_find(ui_menu_entry_t *, void *);
     269static void edit_search_find_next(ui_menu_entry_t *, void *);
     270static void edit_search_go_to_line(ui_menu_entry_t *, void *);
     271
     272static void pane_ctl_destroy(void *);
     273static errno_t pane_ctl_paint(void *);
     274static ui_evclaim_t pane_ctl_pos_event(void *, pos_event_t *);
     275
     276/** Pabe control ops */
     277ui_control_ops_t pane_ctl_ops = {
     278        .destroy = pane_ctl_destroy,
     279        .paint = pane_ctl_paint,
     280        .pos_event = pane_ctl_pos_event
     281};
     282
     283static void save_as_dialog_bok(ui_file_dialog_t *, void *, const char *);
     284static void save_as_dialog_bcancel(ui_file_dialog_t *, void *);
     285static void save_as_dialog_close(ui_file_dialog_t *, void *);
     286
     287static ui_file_dialog_cb_t save_as_dialog_cb = {
     288        .bok = save_as_dialog_bok,
     289        .bcancel = save_as_dialog_bcancel,
     290        .close = save_as_dialog_close
     291};
     292
     293static void go_to_line_dialog_bok(ui_prompt_dialog_t *, void *, const char *);
     294static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *, void *);
     295static void go_to_line_dialog_close(ui_prompt_dialog_t *, void *);
     296
     297static ui_prompt_dialog_cb_t go_to_line_dialog_cb = {
     298        .bok = go_to_line_dialog_bok,
     299        .bcancel = go_to_line_dialog_bcancel,
     300        .close =  go_to_line_dialog_close
     301};
     302
     303static void search_dialog_bok(ui_prompt_dialog_t *, void *, const char *);
     304static void search_dialog_bcancel(ui_prompt_dialog_t *, void *);
     305static void search_dialog_close(ui_prompt_dialog_t *, void *);
     306
     307static ui_prompt_dialog_cb_t search_dialog_cb = {
     308        .bok = search_dialog_bok,
     309        .bcancel = search_dialog_bcancel,
     310        .close =  search_dialog_close
     311};
    187312
    188313int main(int argc, char *argv[])
    189314{
    190         cons_event_t ev;
    191315        bool new_file;
    192316        errno_t rc;
    193317
    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;
    201318        pane.sh_row = 1;
    202319        pane.sh_column = 1;
     
    234351        /* Move to beginning of file. */
    235352        pt_get_sof(&sof);
     353
     354        /* Create UI */
     355        rc = edit_ui_create(&edit);
     356        if (rc != EOK)
     357                return 1;
     358
    236359        caret_move(sof, true, true);
    237360
    238361        /* Initial display */
    239         cursor_visible = true;
    240 
    241         cursor_hide();
    242         console_clear(con);
    243         pane_text_display();
    244         pane_status_display();
     362        rc = ui_window_paint(edit.window);
     363        if (rc != EOK) {
     364                printf("Error painting window.\n");
     365                return rc;
     366        }
     367
     368        pane_status_display(&pane);
    245369        if (new_file && doc.file_name != NULL)
    246370                status_display("File not found. Starting empty file.");
    247         pane_caret_display();
    248         cursor_show();
    249 
    250         done = false;
    251 
    252         while (!done) {
    253                 rc = console_get_event(con, &ev);
    254                 if (rc != EOK)
    255                         break;
    256 
    257                 pane.rflags = 0;
    258 
    259                 switch (ev.type) {
    260                 case CEV_KEY:
    261                         pane.keymod = ev.ev.key.mods;
    262                         if (ev.ev.key.type == KEY_PRESS)
    263                                 key_handle_press(&ev.ev.key);
    264                         break;
    265                 case CEV_POS:
    266                         pos_handle(&ev.ev.pos);
    267                         break;
    268                 }
    269 
    270                 /* Redraw as necessary. */
    271 
    272                 cursor_hide();
    273 
    274                 if (pane.rflags & REDRAW_TEXT)
    275                         pane_text_display();
    276                 if (pane.rflags & REDRAW_ROW)
    277                         pane_row_display();
    278                 if (pane.rflags & REDRAW_STATUS)
    279                         pane_status_display();
    280                 if (pane.rflags & REDRAW_CARET)
    281                         pane_caret_display();
    282 
    283                 cursor_show();
    284         }
    285 
    286         console_clear(con);
    287 
     371        pane_caret_display(&pane);
     372        cursor_setvis(true);
     373
     374        ui_run(edit.ui);
     375
     376        edit_ui_destroy(&edit);
    288377        return 0;
     378}
     379
     380/** Create text editor UI.
     381 *
     382 * @param edit Editor
     383 * @return EOK on success or an error code
     384 */
     385static errno_t edit_ui_create(edit_t *edit)
     386{
     387        errno_t rc;
     388        ui_wnd_params_t params;
     389        ui_fixed_t *fixed = NULL;
     390        ui_menu_t *mfile = NULL;
     391        ui_menu_t *medit = NULL;
     392        ui_menu_entry_t *msave = NULL;
     393        ui_menu_entry_t *msaveas = NULL;
     394        ui_menu_entry_t *mfsep = NULL;
     395        ui_menu_entry_t *mexit = NULL;
     396        ui_menu_entry_t *mcut = NULL;
     397        ui_menu_entry_t *mcopy = NULL;
     398        ui_menu_entry_t *mpaste = NULL;
     399        ui_menu_entry_t *mdelete = NULL;
     400        ui_menu_entry_t *mesep = NULL;
     401        ui_menu_entry_t *mselall = NULL;
     402        ui_menu_t *msearch = NULL;
     403        ui_menu_entry_t *mfind = NULL;
     404        ui_menu_entry_t *mfindr = NULL;
     405        ui_menu_entry_t *mfindn = NULL;
     406        ui_menu_entry_t *mssep = NULL;
     407        ui_menu_entry_t *mgoto = NULL;
     408        gfx_rect_t arect;
     409        gfx_rect_t rect;
     410
     411        rc = ui_create(UI_CONSOLE_DEFAULT, &edit->ui);
     412        if (rc != EOK) {
     413                printf("Error creating UI on display %s.\n",
     414                    UI_CONSOLE_DEFAULT);
     415                goto error;
     416        }
     417
     418        ui_wnd_params_init(&params);
     419        params.caption = "Text Editor";
     420        params.style &= ~ui_wds_decorated;
     421        params.placement = ui_wnd_place_full_screen;
     422
     423        rc = ui_window_create(edit->ui, &params, &edit->window);
     424        if (rc != EOK) {
     425                printf("Error creating window.\n");
     426                goto error;
     427        }
     428
     429        ui_window_set_cb(edit->window, &edit_window_cb, (void *) edit);
     430
     431        edit->ui_res = ui_window_get_res(edit->window);
     432
     433        rc = ui_fixed_create(&fixed);
     434        if (rc != EOK) {
     435                printf("Error creating fixed layout.\n");
     436                return rc;
     437        }
     438
     439        rc = ui_menu_bar_create(edit->ui, edit->window, &edit->menubar);
     440        if (rc != EOK) {
     441                printf("Error creating menu bar.\n");
     442                return rc;
     443        }
     444
     445        ui_menu_bar_set_cb(edit->menubar, &edit_menubar_cb, (void *) edit);
     446
     447        rc = ui_menu_dd_create(edit->menubar, "~F~ile", NULL, &mfile);
     448        if (rc != EOK) {
     449                printf("Error creating menu.\n");
     450                return rc;
     451        }
     452
     453        rc = ui_menu_entry_create(mfile, "~S~ave", "Ctrl-S", &msave);
     454        if (rc != EOK) {
     455                printf("Error creating menu.\n");
     456                return rc;
     457        }
     458
     459        ui_menu_entry_set_cb(msave, edit_file_save, (void *) edit);
     460
     461        rc = ui_menu_entry_create(mfile, "Save ~A~s", "Ctrl-E", &msaveas);
     462        if (rc != EOK) {
     463                printf("Error creating menu.\n");
     464                return rc;
     465        }
     466
     467        ui_menu_entry_set_cb(msaveas, edit_file_save_as, (void *) edit);
     468
     469        rc = ui_menu_entry_sep_create(mfile, &mfsep);
     470        if (rc != EOK) {
     471                printf("Error creating menu.\n");
     472                return rc;
     473        }
     474
     475        rc = ui_menu_entry_create(mfile, "E~x~it", "Ctrl-Q", &mexit);
     476        if (rc != EOK) {
     477                printf("Error creating menu.\n");
     478                return rc;
     479        }
     480
     481        ui_menu_entry_set_cb(mexit, edit_file_exit, (void *) edit);
     482
     483        rc = ui_menu_dd_create(edit->menubar, "~E~dit", NULL, &medit);
     484        if (rc != EOK) {
     485                printf("Error creating menu.\n");
     486                return rc;
     487        }
     488
     489        rc = ui_menu_entry_create(medit, "Cu~t~", "Ctrl-X", &mcut);
     490        if (rc != EOK) {
     491                printf("Error creating menu.\n");
     492                return rc;
     493        }
     494
     495        ui_menu_entry_set_cb(mcut, edit_edit_cut, (void *) edit);
     496
     497        rc = ui_menu_entry_create(medit, "~C~opy", "Ctrl-C", &mcopy);
     498        if (rc != EOK) {
     499                printf("Error creating menu.\n");
     500                return rc;
     501        }
     502
     503        ui_menu_entry_set_cb(mcopy, edit_edit_copy, (void *) edit);
     504
     505        rc = ui_menu_entry_create(medit, "~P~aste", "Ctrl-V", &mpaste);
     506        if (rc != EOK) {
     507                printf("Error creating menu.\n");
     508                return rc;
     509        }
     510
     511        ui_menu_entry_set_cb(mpaste, edit_edit_paste, (void *) edit);
     512
     513        rc = ui_menu_entry_create(medit, "~D~elete", "Del", &mdelete);
     514        if (rc != EOK) {
     515                printf("Error creating menu.\n");
     516                return rc;
     517        }
     518
     519        ui_menu_entry_set_cb(mdelete, edit_edit_delete, (void *) edit);
     520
     521        rc = ui_menu_entry_sep_create(medit, &mesep);
     522        if (rc != EOK) {
     523                printf("Error creating menu.\n");
     524                return rc;
     525        }
     526
     527        rc = ui_menu_entry_create(medit, "Select ~A~ll", "Ctrl-A", &mselall);
     528        if (rc != EOK) {
     529                printf("Error creating menu.\n");
     530                return rc;
     531        }
     532
     533        ui_menu_entry_set_cb(mselall, edit_edit_select_all, (void *) edit);
     534
     535        rc = ui_menu_dd_create(edit->menubar, "~S~earch", NULL, &msearch);
     536        if (rc != EOK) {
     537                printf("Error creating menu.\n");
     538                return rc;
     539        }
     540
     541        rc = ui_menu_entry_create(msearch, "~F~ind", "Ctrl-F", &mfind);
     542        if (rc != EOK) {
     543                printf("Error creating menu.\n");
     544                return rc;
     545        }
     546
     547        ui_menu_entry_set_cb(mfind, edit_search_find, (void *) edit);
     548
     549        rc = ui_menu_entry_create(msearch, "~R~everse Find", "Ctrl-Shift-F", &mfindr);
     550        if (rc != EOK) {
     551                printf("Error creating menu.\n");
     552                return rc;
     553        }
     554
     555        ui_menu_entry_set_cb(mfindr, edit_search_reverse_find, (void *) edit);
     556
     557        rc = ui_menu_entry_create(msearch, "Find ~N~ext", "Ctrl-N", &mfindn);
     558        if (rc != EOK) {
     559                printf("Error creating menu.\n");
     560                return rc;
     561        }
     562
     563        ui_menu_entry_set_cb(mfindn, edit_search_find_next, (void *) edit);
     564
     565        rc = ui_menu_entry_sep_create(msearch, &mssep);
     566        if (rc != EOK) {
     567                printf("Error creating menu.\n");
     568                return rc;
     569        }
     570
     571        rc = ui_menu_entry_create(msearch, "Go To ~L~ine", "Ctrl-L", &mgoto);
     572        if (rc != EOK) {
     573                printf("Error creating menu.\n");
     574                return rc;
     575        }
     576
     577        ui_menu_entry_set_cb(mgoto, edit_search_go_to_line, (void *) edit);
     578
     579        ui_window_get_app_rect(edit->window, &arect);
     580
     581        rect.p0 = arect.p0;
     582        rect.p1.x = arect.p1.x;
     583        rect.p1.y = arect.p0.y + 1;
     584        ui_menu_bar_set_rect(edit->menubar, &rect);
     585
     586        rc = ui_fixed_add(fixed, ui_menu_bar_ctl(edit->menubar));
     587        if (rc != EOK) {
     588                printf("Error adding control to layout.\n");
     589                return rc;
     590        }
     591
     592        rc = pane_init(edit->window, &pane);
     593        if (rc != EOK) {
     594                printf("Error initializing pane.\n");
     595                return rc;
     596        }
     597
     598        rc = ui_fixed_add(fixed, pane_ctl(&pane));
     599        if (rc != EOK) {
     600                printf("Error adding control to layout.\n");
     601                return rc;
     602        }
     603
     604        rc = ui_label_create(edit->ui_res, "", &edit->status);
     605        if (rc != EOK) {
     606                printf("Error creating menu bar.\n");
     607                return rc;
     608        }
     609
     610        rect.p0.x = arect.p0.x;
     611        rect.p0.y = arect.p1.y - 1;
     612        rect.p1 = arect.p1;
     613        ui_label_set_rect(edit->status, &rect);
     614
     615        rc = ui_fixed_add(fixed, ui_label_ctl(edit->status));
     616        if (rc != EOK) {
     617                printf("Error adding control to layout.\n");
     618                return rc;
     619        }
     620
     621        ui_window_add(edit->window, ui_fixed_ctl(fixed));
     622        return EOK;
     623error:
     624        if (edit->window != NULL)
     625                ui_window_destroy(edit->window);
     626        if (edit->ui != NULL)
     627                ui_destroy(edit->ui);
     628        return rc;
     629}
     630
     631/** Destroy text editor UI.
     632 *
     633 * @param edit Editor
     634 */
     635static void edit_ui_destroy(edit_t *edit)
     636{
     637        ui_window_destroy(edit->window);
     638        ui_destroy(edit->ui);
    289639}
    290640
     
    309659}
    310660
    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 
    321661static void cursor_setvis(bool visible)
    322662{
    323         if (cursor_visible != visible) {
    324                 console_cursor_visibility(con, visible);
    325                 cursor_visible = visible;
    326         }
     663        gfx_context_t *gc = ui_window_get_gc(edit.window);
     664
     665        (void) gfx_cursor_set_visible(gc, visible);
    327666}
    328667
     
    400739        switch (ev->key) {
    401740        case KC_Q:
    402                 done = true;
     741                ui_quit(edit.ui);
    403742                break;
    404743        case KC_S:
     
    415754                break;
    416755        case KC_V:
    417                 selection_delete();
    418                 insert_clipboard_data();
    419                 pane.rflags |= REDRAW_TEXT;
    420                 caret_update();
     756                edit_paste();
    421757                break;
    422758        case KC_X:
    423                 selection_copy();
    424                 selection_delete();
    425                 pane.rflags |= REDRAW_TEXT;
    426                 caret_update();
     759                edit_cut();
    427760                break;
    428761        case KC_A:
     
    490823
    491824        if (ev->type == POS_PRESS && ev->vpos < (unsigned)pane.rows) {
    492                 bc.row = pane.sh_row + ev->vpos;
    493                 bc.column = pane.sh_column + ev->hpos;
     825                bc.row = pane.sh_row + ev->vpos - pane.rect.p0.y;
     826                bc.column = pane.sh_column + ev->hpos - pane.rect.p0.x;
    494827                sheet_get_cell_pt(doc.sh, &bc, dir_before, &pt);
    495828
     
    497830
    498831                caret_move(pt, select, true);
     832                pane_update(&pane);
    499833        }
    500834}
     
    606940}
    607941
    608 /** Change document name and save. */
     942/** Open Save As dialog. */
    609943static void file_save_as(void)
    610944{
    611945        const char *old_fname = (doc.file_name != NULL) ? doc.file_name : "";
    612         char *fname;
    613 
    614         fname = prompt("Save As", old_fname);
    615         if (fname == NULL) {
    616                 status_display("Save cancelled.");
     946        ui_file_dialog_params_t fdparams;
     947        ui_file_dialog_t *dialog;
     948        errno_t rc;
     949
     950        ui_file_dialog_params_init(&fdparams);
     951        fdparams.caption = "Save As";
     952        fdparams.ifname = old_fname;
     953
     954        rc = ui_file_dialog_create(edit.ui, &fdparams, &dialog);
     955        if (rc != EOK) {
     956                printf("Error creating message dialog.\n");
    617957                return;
    618958        }
    619959
    620         errno_t rc = file_save(fname);
    621         if (rc != EOK)
    622                 return;
    623 
    624         if (doc.file_name != NULL)
    625                 free(doc.file_name);
    626         doc.file_name = fname;
    627 }
    628 
    629 /** Ask for a string. */
    630 static char *prompt(char const *prompt, char const *init_value)
    631 {
    632         cons_event_t ev;
    633         kbd_event_t *kev;
    634         char *str;
    635         char32_t buffer[INFNAME_MAX_LEN + 1];
    636         int max_len;
    637         int nc;
    638         bool done;
    639         errno_t rc;
    640 
    641         asprintf(&str, "%s: %s", prompt, init_value);
    642         status_display(str);
    643         console_set_pos(con, 1 + str_length(str), scr_rows - 1);
    644         free(str);
    645 
    646         console_set_style(con, STYLE_INVERTED);
    647 
    648         max_len = min(INFNAME_MAX_LEN, scr_columns - 4 - str_length(prompt));
    649         str_to_wstr(buffer, max_len + 1, init_value);
    650         nc = wstr_length(buffer);
    651         done = false;
    652 
    653         while (!done) {
    654                 rc = console_get_event(con, &ev);
    655                 if (rc != EOK)
    656                         return NULL;
    657 
    658                 if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS) {
    659                         kev = &ev.ev.key;
    660 
    661                         /* Handle key press. */
    662                         if ((kev->mods & (KM_CTRL | KM_ALT)) == 0) {
    663                                 switch (kev->key) {
    664                                 case KC_ESCAPE:
    665                                         return NULL;
    666                                 case KC_BACKSPACE:
    667                                         if (nc > 0) {
    668                                                 putchar('\b');
    669                                                 console_flush(con);
    670                                                 --nc;
    671                                         }
    672                                         break;
    673                                 case KC_ENTER:
    674                                         done = true;
    675                                         break;
    676                                 default:
    677                                         if (kev->c >= 32 && nc < max_len) {
    678                                                 putuchar(kev->c);
    679                                                 console_flush(con);
    680                                                 buffer[nc++] = kev->c;
    681                                         }
    682                                         break;
    683                                 }
    684                         }
    685                 }
    686         }
    687 
    688         buffer[nc] = '\0';
    689         str = wstr_to_astr(buffer);
    690 
    691         console_set_style(con, STYLE_NORMAL);
    692 
    693         return str;
     960        ui_file_dialog_set_cb(dialog, &save_as_dialog_cb, &edit);
    694961}
    695962
     
    726993
    727994                bcnt -= off;
    728                 memcpy(buf, buf + off, bcnt);
     995                memmove(buf, buf + off, bcnt);
    729996
    730997                insert_char(c);
     
    8081075}
    8091076
    810 static void pane_text_display(void)
    811 {
     1077/** Initialize pane.
     1078 *
     1079 * TODO: Replace with pane_create() that allocates the pane.
     1080 *
     1081 * @param window Editor window
     1082 * @param pane Pane
     1083 * @return EOK on success or an error code
     1084 */
     1085static errno_t pane_init(ui_window_t *window, pane_t *pane)
     1086{
     1087        errno_t rc;
     1088        gfx_rect_t arect;
     1089
     1090        pane->control = NULL;
     1091        pane->color = NULL;
     1092        pane->sel_color = NULL;
     1093
     1094        rc = ui_control_new(&pane_ctl_ops, (void *) pane, &pane->control);
     1095        if (rc != EOK)
     1096                goto error;
     1097
     1098        rc = gfx_color_new_ega(0x07, &pane->color);
     1099        if (rc != EOK)
     1100                goto error;
     1101
     1102        rc = gfx_color_new_ega(0x1e, &pane->sel_color);
     1103        if (rc != EOK)
     1104                goto error;
     1105
     1106        pane->res = ui_window_get_res(window);
     1107        pane->window = window;
     1108
     1109        ui_window_get_app_rect(window, &arect);
     1110        pane->rect.p0.x = arect.p0.x;
     1111        pane->rect.p0.y = arect.p0.y + 1;
     1112        pane->rect.p1.x = arect.p1.x;
     1113        pane->rect.p1.y = arect.p1.y - 1;
     1114
     1115        pane->columns = pane->rect.p1.x - pane->rect.p0.x;
     1116        pane->rows = pane->rect.p1.y - pane->rect.p0.y;
     1117
     1118        return EOK;
     1119error:
     1120        if (pane->control != NULL) {
     1121                ui_control_delete(pane->control);
     1122                pane->control = NULL;
     1123        }
     1124
     1125        if (pane->color != NULL) {
     1126                gfx_color_delete(pane->color);
     1127                pane->color = NULL;
     1128        }
     1129
     1130        return rc;
     1131}
     1132
     1133/** Finalize pane.
     1134 *
     1135 * TODO: Replace with pane_destroy() that deallocates the pane.
     1136 *
     1137 * @param pane Pane
     1138 */
     1139static void pane_fini(pane_t *pane)
     1140{
     1141        gfx_color_delete(pane->color);
     1142        pane->color = NULL;
     1143        gfx_color_delete(pane->sel_color);
     1144        pane->sel_color = NULL;
     1145        ui_control_delete(pane->control);
     1146        pane->control = NULL;
     1147}
     1148
     1149/** Return base control object for a pane.
     1150 *
     1151 * @param pane Pane
     1152 * @return Base UI cntrol
     1153 */
     1154static ui_control_t *pane_ctl(pane_t *pane)
     1155{
     1156        return pane->control;
     1157}
     1158
     1159/** Repaint parts of pane that need updating.
     1160 *
     1161 * @param pane Pane
     1162 * @return EOK on succes or an error code
     1163 */
     1164static errno_t pane_update(pane_t *pane)
     1165{
     1166        errno_t rc;
     1167
     1168        if (pane->rflags & REDRAW_TEXT) {
     1169                rc = pane_text_display(pane);
     1170                if (rc != EOK)
     1171                        return rc;
     1172        }
     1173
     1174        if (pane->rflags & REDRAW_ROW)
     1175                pane_row_display();
     1176
     1177        if (pane->rflags & REDRAW_STATUS)
     1178                pane_status_display(pane);
     1179
     1180        if (pane->rflags & REDRAW_CARET)
     1181                pane_caret_display(pane);
     1182
     1183        pane->rflags &= ~(REDRAW_TEXT | REDRAW_ROW | REDRAW_STATUS |
     1184            REDRAW_CARET);
     1185        return EOK;
     1186}
     1187
     1188/** Display pane text.
     1189 *
     1190 * @param pane Pane
     1191 * @return EOK on success or an error code
     1192 */
     1193static errno_t pane_text_display(pane_t *pane)
     1194{
     1195        gfx_rect_t rect;
     1196        gfx_context_t *gc;
     1197        errno_t rc;
    8121198        int sh_rows, rows;
    8131199
    8141200        sheet_get_num_rows(doc.sh, &sh_rows);
    815         rows = min(sh_rows - pane.sh_row + 1, pane.rows);
     1201        rows = min(sh_rows - pane->sh_row + 1, pane->rows);
    8161202
    8171203        /* Draw rows from the sheet. */
    8181204
    819         console_set_pos(con, 0, 0);
    820         pane_row_range_display(0, rows);
     1205        rc = pane_row_range_display(pane, 0, rows);
     1206        if (rc != EOK)
     1207                return rc;
    8211208
    8221209        /* Clear the remaining rows if file is short. */
    8231210
    824         int i;
    825         sysarg_t j;
    826         for (i = rows; i < pane.rows; ++i) {
    827                 console_set_pos(con, 0, i);
    828                 for (j = 0; j < scr_columns; ++j)
    829                         putchar(' ');
    830                 console_flush(con);
    831         }
    832 
    833         pane.rflags |= (REDRAW_STATUS | REDRAW_CARET);
    834         pane.rflags &= ~REDRAW_ROW;
     1211        gc = ui_window_get_gc(pane->window);
     1212
     1213        rc = gfx_set_color(gc, pane->color);
     1214        if (rc != EOK)
     1215                goto error;
     1216
     1217        rect.p0.x = pane->rect.p0.x;
     1218        rect.p0.y = pane->rect.p0.y + rows;
     1219        rect.p1.x = pane->rect.p1.x;
     1220        rect.p1.y = pane->rect.p1.y;
     1221
     1222        rc = gfx_fill_rect(gc, &rect);
     1223        if (rc != EOK)
     1224                goto error;
     1225
     1226        pane->rflags &= ~REDRAW_ROW;
     1227        return EOK;
     1228error:
     1229        return rc;
    8351230}
    8361231
     
    8461241
    8471242        ridx = coord.row - pane.sh_row;
    848         pane_row_range_display(ridx, ridx + 1);
     1243        (void) pane_row_range_display(&pane, ridx, ridx + 1);
    8491244        pane.rflags |= (REDRAW_STATUS | REDRAW_CARET);
    8501245}
    8511246
    852 static void pane_row_range_display(int r0, int r1)
    853 {
    854         int i, j, fill;
     1247/** Display a range of rows of text.
     1248 *
     1249 * @param r0 Start row (inclusive)
     1250 * @param r1 End row (exclusive)
     1251 * @return EOk on success or an error code
     1252 */
     1253static errno_t pane_row_range_display(pane_t *pane, int r0, int r1)
     1254{
     1255        int i, fill;
    8551256        spt_t rb, re, dep, pt;
    8561257        coord_t rbc, rec;
    8571258        char row_buf[ROW_BUF_SIZE];
     1259        char cbuf[STR_BOUNDS(1) + 1];
    8581260        char32_t c;
    8591261        size_t pos, size;
     1262        size_t cpos;
    8601263        int s_column;
    8611264        coord_t csel_start, csel_end, ctmp;
     1265        gfx_font_t *font;
     1266        gfx_context_t *gc;
     1267        gfx_text_fmt_t fmt;
     1268        gfx_coord2_t tpos;
     1269        gfx_rect_t rect;
     1270        errno_t rc;
     1271
     1272        font = ui_resource_get_font(edit.ui_res);
     1273        gc = ui_window_get_gc(edit.window);
     1274
     1275        gfx_text_fmt_init(&fmt);
     1276        fmt.font = font;
     1277        fmt.color = pane->color;
    8621278
    8631279        /* Determine selection start and end. */
    8641280
    865         tag_get_pt(&pane.sel_start, &pt);
     1281        tag_get_pt(&pane->sel_start, &pt);
    8661282        spt_get_coord(&pt, &csel_start);
    8671283
    868         tag_get_pt(&pane.caret_pos, &pt);
     1284        tag_get_pt(&pane->caret_pos, &pt);
    8691285        spt_get_coord(&pt, &csel_end);
    8701286
     
    8771293        /* Draw rows from the sheet. */
    8781294
    879         console_set_pos(con, 0, 0);
    8801295        for (i = r0; i < r1; ++i) {
     1296                tpos.x = pane->rect.p0.x;
     1297                tpos.y = pane->rect.p0.y + i;
     1298
    8811299                /* Starting point for row display */
    882                 rbc.row = pane.sh_row + i;
    883                 rbc.column = pane.sh_column;
     1300                rbc.row = pane->sh_row + i;
     1301                rbc.column = pane->sh_column;
    8841302                sheet_get_cell_pt(doc.sh, &rbc, dir_before, &rb);
    8851303
    8861304                /* Ending point for row display */
    887                 rec.row = pane.sh_row + i;
    888                 rec.column = pane.sh_column + pane.columns;
     1305                rec.row = pane->sh_row + i;
     1306                rec.column = pane->sh_column + pane->columns;
    8891307                sheet_get_cell_pt(doc.sh, &rec, dir_before, &re);
    8901308
     
    8961314                if (coord_cmp(&csel_start, &rbc) <= 0 &&
    8971315                    coord_cmp(&rbc, &csel_end) < 0) {
    898                         console_flush(con);
    899                         console_set_style(con, STYLE_SELECTED);
    900                         console_flush(con);
     1316                        fmt.color = pane->sel_color;
    9011317                }
    9021318
    903                 console_set_pos(con, 0, i);
    9041319                size = str_size(row_buf);
    9051320                pos = 0;
    906                 s_column = pane.sh_column;
     1321                s_column = pane->sh_column;
    9071322                while (pos < size) {
    908                         if ((csel_start.row == rbc.row) && (csel_start.column == s_column)) {
    909                                 console_flush(con);
    910                                 console_set_style(con, STYLE_SELECTED);
    911                                 console_flush(con);
    912                         }
    913 
    914                         if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) {
    915                                 console_flush(con);
    916                                 console_set_style(con, STYLE_NORMAL);
    917                                 console_flush(con);
    918                         }
     1323                        if ((csel_start.row == rbc.row) && (csel_start.column == s_column))
     1324                                fmt.color = pane->sel_color;
     1325
     1326                        if ((csel_end.row == rbc.row) && (csel_end.column == s_column))
     1327                                fmt.color = pane->color;
    9191328
    9201329                        c = str_decode(row_buf, &pos, size);
    9211330                        if (c != '\t') {
    922                                 printf("%lc", (wint_t) c);
     1331                                cpos = 0;
     1332                                rc = chr_encode(c, cbuf, &cpos, sizeof(cbuf));
     1333                                if (rc != EOK)
     1334                                        return rc;
     1335
     1336                                rc = gfx_puttext(&tpos, &fmt, cbuf);
     1337                                if (rc != EOK)
     1338                                        return rc;
     1339
    9231340                                s_column += 1;
     1341                                tpos.x++;
    9241342                        } else {
    9251343                                fill = 1 + ALIGN_UP(s_column, TAB_WIDTH) -
    9261344                                    s_column;
    9271345
    928                                 for (j = 0; j < fill; ++j)
    929                                         putchar(' ');
     1346                                rc = gfx_set_color(gc, fmt.color);
     1347                                if (rc != EOK)
     1348                                        return rc;
     1349
     1350                                rect.p0.x = tpos.x;
     1351                                rect.p0.y = tpos.y;
     1352                                rect.p1.x = tpos.x + fill;
     1353                                rect.p1.y = tpos.y + 1;
     1354
     1355                                rc = gfx_fill_rect(gc, &rect);
     1356                                if (rc != EOK)
     1357                                        return rc;
     1358
    9301359                                s_column += fill;
     1360                                tpos.x += fill;
    9311361                        }
    9321362                }
    9331363
    934                 if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) {
    935                         console_flush(con);
    936                         console_set_style(con, STYLE_NORMAL);
    937                         console_flush(con);
    938                 }
     1364                if ((csel_end.row == rbc.row) && (csel_end.column == s_column))
     1365                        fmt.color = pane->color;
    9391366
    9401367                /* Fill until the end of display area. */
    9411368
    942                 if ((unsigned)s_column - 1 < scr_columns)
    943                         fill = scr_columns - (s_column - 1);
    944                 else
    945                         fill = 0;
    946 
    947                 for (j = 0; j < fill; ++j)
    948                         putchar(' ');
    949                 console_flush(con);
    950                 console_set_style(con, STYLE_NORMAL);
    951         }
    952 
    953         pane.rflags |= REDRAW_CARET;
    954 }
    955 
    956 /** Display pane status in the status line. */
    957 static void pane_status_display(void)
     1369                rc = gfx_set_color(gc, fmt.color);
     1370                if (rc != EOK)
     1371                        return rc;
     1372
     1373                rect.p0.x = tpos.x;
     1374                rect.p0.y = tpos.y;
     1375                rect.p1.x = pane->rect.p1.x;
     1376                rect.p1.y = tpos.y + 1;
     1377
     1378                rc = gfx_fill_rect(gc, &rect);
     1379                if (rc != EOK)
     1380                        return rc;
     1381        }
     1382
     1383        return EOK;
     1384}
     1385
     1386/** Display pane status in the status line.
     1387 *
     1388 * @param pane Pane
     1389 */
     1390static void pane_status_display(pane_t *pane)
    9581391{
    9591392        spt_t caret_pt;
     
    9641397        char *text;
    9651398        size_t n;
    966         int pos;
    9671399        size_t nextra;
    9681400        size_t fnw;
    9691401
    970         tag_get_pt(&pane.caret_pos, &caret_pt);
     1402        tag_get_pt(&pane->caret_pos, &caret_pt);
    9711403        spt_get_coord(&caret_pt, &coord);
    9721404
     
    9871419                return;
    9881420
    989         console_set_pos(con, 0, scr_rows - 1);
    990         console_set_style(con, STYLE_INVERTED);
    991 
    9921421        /*
    9931422         * Make sure the status fits on the screen. This loop should
     
    9951424         */
    9961425        while (true) {
    997                 int rc = asprintf(&text, " %d, %d (%d): File '%s'. Ctrl-Q Quit  Ctrl-S Save  "
    998                     "Ctrl-E Save As", coord.row, coord.column, last_row, fname);
     1426                int rc = asprintf(&text, "%d, %d (%d): File '%s'. Ctrl-Q Quit  "
     1427                    "F10 Menu", coord.row, coord.column, last_row, fname);
    9991428                if (rc < 0) {
    10001429                        n = 0;
     
    10041433                /* If it already fits, we're done */
    10051434                n = str_width(text);
    1006                 if (n <= scr_columns - 2)
     1435                if ((int)n <= pane->columns - 2)
    10071436                        break;
    10081437
    10091438                /* Compute number of excess characters */
    1010                 nextra = n - (scr_columns - 2);
     1439                nextra = n - (pane->columns - 2);
    10111440                /** With of the file name part */
    10121441                fnw = str_width(fname);
     
    10161445                 * just give up and print a blank status.
    10171446                 */
    1018                 if (nextra > fnw - 2)
     1447                if (nextra > fnw - 2) {
     1448                        text[0] = '\0';
    10191449                        goto finish;
     1450                }
    10201451
    10211452                /* Compute position where we overwrite with '..\0' */
     
    10341465        }
    10351466
    1036         printf("%s", text);
     1467finish:
     1468        (void) ui_label_set_text(edit.status, text);
     1469        (void) ui_label_paint(edit.status);
    10371470        free(text);
    10381471        free(fname);
    1039 finish:
    1040         /* Fill the rest of the line */
    1041         pos = scr_columns - 1 - n;
    1042         printf("%*s", pos, "");
    1043         console_flush(con);
    1044         console_set_style(con, STYLE_NORMAL);
    1045 
    1046         pane.rflags |= REDRAW_CARET;
    1047 }
    1048 
    1049 /** Set cursor to reflect position of the caret. */
    1050 static void pane_caret_display(void)
     1472}
     1473
     1474/** Set cursor to reflect position of the caret.
     1475 *
     1476 * @param pane Pane
     1477 */
     1478static void pane_caret_display(pane_t *pane)
    10511479{
    10521480        spt_t caret_pt;
    10531481        coord_t coord;
    1054 
    1055         tag_get_pt(&pane.caret_pos, &caret_pt);
     1482        gfx_coord2_t pos;
     1483        gfx_context_t *gc;
     1484
     1485        tag_get_pt(&pane->caret_pos, &caret_pt);
    10561486
    10571487        spt_get_coord(&caret_pt, &coord);
    1058         console_set_pos(con, coord.column - pane.sh_column,
    1059             coord.row - pane.sh_row);
     1488
     1489        gc = ui_window_get_gc(edit.window);
     1490        pos.x = pane->rect.p0.x + coord.column - pane->sh_column;
     1491        pos.y = pane->rect.p0.y + coord.row - pane->sh_row;
     1492
     1493        (void) gfx_cursor_set_pos(gc, &pos);
     1494}
     1495
     1496/** Destroy pane control.
     1497 *
     1498 * @param arg Argument (pane_t *)
     1499 */
     1500static void pane_ctl_destroy(void *arg)
     1501{
     1502        pane_t *pane = (pane_t *)arg;
     1503
     1504        pane_fini(pane);
     1505}
     1506
     1507/** Paint pane control.
     1508 *
     1509 * @param arg Argument (pane_t *)
     1510 */
     1511static errno_t pane_ctl_paint(void *arg)
     1512{
     1513        pane_t *pane = (pane_t *)arg;
     1514        gfx_context_t *gc;
     1515        errno_t rc;
     1516
     1517        gc = ui_window_get_gc(pane->window);
     1518
     1519        rc = pane_text_display(pane);
     1520        if (rc != EOK)
     1521                goto error;
     1522
     1523        rc = gfx_update(gc);
     1524        if (rc != EOK)
     1525                goto error;
     1526
     1527error:
     1528        return rc;
     1529}
     1530
     1531/** Handle pane control position event.
     1532 *
     1533 * @param arg Argument (pane_t *)
     1534 * @param event Position event
     1535 */
     1536static ui_evclaim_t pane_ctl_pos_event(void *arg, pos_event_t *event)
     1537{
     1538        gfx_coord2_t pos;
     1539
     1540        pos.x = event->hpos;
     1541        pos.y = event->vpos;
     1542
     1543        if (!gfx_pix_inside_rect(&pos, &pane.rect))
     1544                return ui_unclaimed;
     1545
     1546        pos_handle(event);
     1547        (void) gfx_update(ui_window_get_gc(edit.window));
     1548        return ui_claimed;
    10601549}
    10611550
     
    12701759static void caret_go_to_line_ask(void)
    12711760{
    1272         char *sline;
    1273 
    1274         sline = prompt("Go to line", "");
    1275         if (sline == NULL) {
    1276                 status_display("Go to line cancelled.");
     1761        ui_prompt_dialog_params_t pdparams;
     1762        ui_prompt_dialog_t *dialog;
     1763        errno_t rc;
     1764
     1765        ui_prompt_dialog_params_init(&pdparams);
     1766        pdparams.caption = "Go To Line";
     1767        pdparams.prompt = "Line Number";
     1768
     1769        rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog);
     1770        if (rc != EOK) {
     1771                printf("Error creating prompt dialog.\n");
    12771772                return;
    12781773        }
    12791774
    1280         char *endptr;
    1281         int line = strtol(sline, &endptr, 10);
    1282         if (*endptr != '\0') {
    1283                 free(sline);
    1284                 status_display("Invalid number entered.");
    1285                 return;
    1286         }
    1287         free(sline);
    1288 
    1289         caret_move_absolute(line, pane.ideal_column, dir_before, false);
     1775        ui_prompt_dialog_set_cb(dialog, &go_to_line_dialog_cb, &edit);
    12901776}
    12911777
     
    13441830static void search_prompt(bool reverse)
    13451831{
    1346         char *pattern;
    1347 
    1348         const char *prompt_text = "Find next";
    1349         if (reverse)
    1350                 prompt_text = "Find previous";
    1351 
    1352         const char *default_value = "";
     1832        ui_prompt_dialog_params_t pdparams;
     1833        ui_prompt_dialog_t *dialog;
     1834        errno_t rc;
     1835
     1836        ui_prompt_dialog_params_init(&pdparams);
     1837        pdparams.caption = reverse ? "Reverse Search" : "Search";
     1838        pdparams.prompt = "Search text";
     1839        pdparams.itext = "";
     1840
    13531841        if (pane.previous_search)
    1354                 default_value = pane.previous_search;
    1355 
    1356         pattern = prompt(prompt_text, default_value);
    1357         if (pattern == NULL) {
    1358                 status_display("Search cancelled.");
     1842                pdparams.itext = pane.previous_search;
     1843
     1844        rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog);
     1845        if (rc != EOK) {
     1846                printf("Error creating prompt dialog.\n");
    13591847                return;
    13601848        }
    13611849
    1362         if (pane.previous_search)
    1363                 free(pane.previous_search);
    1364         pane.previous_search = pattern;
    1365         pane.previous_search_reverse = reverse;
    1366 
    1367         search(pattern, reverse);
     1850        ui_prompt_dialog_set_cb(dialog, &search_dialog_cb, &edit);
     1851        pane.search_reverse = reverse;
    13681852}
    13691853
     
    15131997        }
    15141998        free(str);
     1999}
     2000
     2001static void edit_paste(void)
     2002{
     2003        selection_delete();
     2004        insert_clipboard_data();
     2005        pane.rflags |= (REDRAW_TEXT | REDRAW_CARET);
     2006        pane_update(&pane);
     2007}
     2008
     2009static void edit_cut(void)
     2010{
     2011        selection_copy();
     2012        selection_delete();
     2013        pane.rflags |= (REDRAW_TEXT | REDRAW_CARET);
     2014        pane_update(&pane);
    15152015}
    15162016
     
    17192219static void status_display(char const *str)
    17202220{
    1721         console_set_pos(con, 0, scr_rows - 1);
    1722         console_set_style(con, STYLE_INVERTED);
    1723 
    1724         int pos = -(scr_columns - 3);
    1725         printf(" %*s ", pos, str);
    1726         console_flush(con);
    1727         console_set_style(con, STYLE_NORMAL);
     2221        (void) ui_label_set_text(edit.status, str);
     2222        (void) ui_label_paint(edit.status);
     2223}
     2224
     2225/** Window close request
     2226 *
     2227 * @param window Window
     2228 * @param arg Argument (edit_t *)
     2229 */
     2230static void edit_wnd_close(ui_window_t *window, void *arg)
     2231{
     2232        edit_t *edit = (edit_t *) arg;
     2233
     2234        ui_quit(edit->ui);
     2235}
     2236
     2237/** Window focus event
     2238 *
     2239 * @param window Window
     2240 * @param arg Argument (edit_t *)
     2241 * @param focus Focus number
     2242 */
     2243static void edit_wnd_focus(ui_window_t *window, void *arg, unsigned focus)
     2244{
     2245        edit_t *edit = (edit_t *)arg;
     2246
     2247        (void)edit;
     2248        pane_caret_display(&pane);
     2249        cursor_setvis(true);
     2250}
     2251
     2252/** Window keyboard event
     2253 *
     2254 * @param window Window
     2255 * @param arg Argument (edit_t *)
     2256 * @param event Keyboard event
     2257 */
     2258static void edit_wnd_kbd_event(ui_window_t *window, void *arg,
     2259    kbd_event_t *event)
     2260{
     2261        pane.keymod = event->mods;
     2262
     2263        if (ui_window_def_kbd(window, event) == ui_claimed)
     2264                return;
     2265
     2266        if (event->type == KEY_PRESS) {
     2267                key_handle_press(event);
     2268                (void) pane_update(&pane);
     2269                (void) gfx_update(ui_window_get_gc(window));
     2270        }
     2271}
     2272
     2273/** Window unfocus event
     2274 *
     2275 * @param window Window
     2276 * @param arg Argument (edit_t *)
     2277 * @param focus Focus number
     2278 */
     2279static void edit_wnd_unfocus(ui_window_t *window, void *arg, unsigned focus)
     2280{
     2281        edit_t *edit = (edit_t *) arg;
     2282
     2283        (void)edit;
     2284        cursor_setvis(false);
     2285}
     2286
     2287/** Menu bar activate event
     2288 *
     2289 * @param mbar Menu bar
     2290 * @param arg Argument (edit_t *)
     2291 */
     2292static void edit_menubar_activate(ui_menu_bar_t *mbar, void *arg)
     2293{
     2294        edit_t *edit = (edit_t *)arg;
     2295
     2296        (void)edit;
     2297        cursor_setvis(false);
     2298}
     2299
     2300/** Menu bar deactivate event
     2301 *
     2302 * @param mbar Menu bar
     2303 * @param arg Argument (edit_t *)
     2304 */
     2305static void edit_menubar_deactivate(ui_menu_bar_t *mbar, void *arg)
     2306{
     2307        edit_t *edit = (edit_t *)arg;
     2308
     2309        (void)edit;
     2310        pane_caret_display(&pane);
     2311        cursor_setvis(true);
     2312}
     2313
     2314/** File / Save menu entry selected.
     2315 *
     2316 * @param mentry Menu entry
     2317 * @param arg Argument (edit_t *)
     2318 */
     2319static void edit_file_save(ui_menu_entry_t *mentry, void *arg)
     2320{
     2321        edit_t *edit = (edit_t *) arg;
     2322
     2323        (void)edit;
     2324
     2325        if (doc.file_name != NULL)
     2326                file_save(doc.file_name);
     2327        else
     2328                file_save_as();
     2329}
     2330
     2331/** File / Save As menu entry selected.
     2332 *
     2333 * @param mentry Menu entry
     2334 * @param arg Argument (edit_t *)
     2335 */
     2336static void edit_file_save_as(ui_menu_entry_t *mentry, void *arg)
     2337{
     2338        edit_t *edit = (edit_t *) arg;
     2339
     2340        (void)edit;
     2341        file_save_as();
     2342}
     2343
     2344/** File / Exit menu entry selected.
     2345 *
     2346 * @param mentry Menu entry
     2347 * @param arg Argument (edit_t *)
     2348 */
     2349static void edit_file_exit(ui_menu_entry_t *mentry, void *arg)
     2350{
     2351        edit_t *edit = (edit_t *) arg;
     2352
     2353        ui_quit(edit->ui);
     2354}
     2355
     2356/** Edit / Cut menu entry selected.
     2357 *
     2358 * @param mentry Menu entry
     2359 * @param arg Argument (edit_t *)
     2360 */
     2361static void edit_edit_cut(ui_menu_entry_t *mentry, void *arg)
     2362{
     2363        (void) arg;
     2364        edit_cut();
     2365        (void) gfx_update(ui_window_get_gc(edit.window));
     2366}
     2367
     2368/** Edit / Copy menu entry selected.
     2369 *
     2370 * @param mentry Menu entry
     2371 * @param arg Argument (edit_t *)
     2372 */
     2373static void edit_edit_copy(ui_menu_entry_t *mentry, void *arg)
     2374{
     2375        (void) arg;
     2376        selection_copy();
     2377}
     2378
     2379/** Edit / Paste menu entry selected.
     2380 *
     2381 * @param mentry Menu entry
     2382 * @param arg Argument (edit_t *)
     2383 */
     2384static void edit_edit_paste(ui_menu_entry_t *mentry, void *arg)
     2385{
     2386        (void) arg;
     2387        edit_paste();
     2388        (void) gfx_update(ui_window_get_gc(edit.window));
     2389}
     2390
     2391/** Edit / Delete menu entry selected.
     2392 *
     2393 * @param mentry Menu entry
     2394 * @param arg Argument (edit_t *)
     2395 */
     2396static void edit_edit_delete(ui_menu_entry_t *mentry, void *arg)
     2397{
     2398        (void) arg;
     2399
     2400        if (selection_active())
     2401                selection_delete();
    17282402
    17292403        pane.rflags |= REDRAW_CARET;
     2404        (void) pane_update(&pane);
     2405        (void) gfx_update(ui_window_get_gc(edit.window));
     2406}
     2407
     2408/** Edit / Select All menu entry selected.
     2409 *
     2410 * @param mentry Menu entry
     2411 * @param arg Argument (edit_t *)
     2412 */
     2413static void edit_edit_select_all(ui_menu_entry_t *mentry, void *arg)
     2414{
     2415        (void) arg;
     2416
     2417        selection_sel_all();
     2418        pane.rflags |= (REDRAW_CARET | REDRAW_TEXT | REDRAW_STATUS);
     2419        pane_update(&pane);
     2420        (void) gfx_update(ui_window_get_gc(edit.window));
     2421}
     2422
     2423/** Search / Find menu entry selected.
     2424 *
     2425 * @param mentry Menu entry
     2426 * @param arg Argument (edit_t *)
     2427 */
     2428static void edit_search_find(ui_menu_entry_t *mentry, void *arg)
     2429{
     2430        (void) arg;
     2431        search_prompt(false);
     2432}
     2433
     2434/** Search / Reverse Find menu entry selected.
     2435 *
     2436 * @param mentry Menu entry
     2437 * @param arg Argument (edit_t *)
     2438 */
     2439static void edit_search_reverse_find(ui_menu_entry_t *mentry, void *arg)
     2440{
     2441        (void) arg;
     2442        search_prompt(true);
     2443}
     2444
     2445/** Search / Find Next menu entry selected.
     2446 *
     2447 * @param mentry Menu entry
     2448 * @param arg Argument (edit_t *)
     2449 */
     2450static void edit_search_find_next(ui_menu_entry_t *mentry, void *arg)
     2451{
     2452        (void) arg;
     2453        search_repeat();
     2454        (void) pane_update(&pane);
     2455        (void) gfx_update(ui_window_get_gc(edit.window));
     2456}
     2457
     2458/** Search / Go To Line menu entry selected.
     2459 *
     2460 * @param mentry Menu entry
     2461 * @param arg Argument (edit_t *)
     2462 */
     2463static void edit_search_go_to_line(ui_menu_entry_t *mentry, void *arg)
     2464{
     2465        (void) arg;
     2466        caret_go_to_line_ask();
     2467}
     2468
     2469/** Save As dialog OK button press.
     2470 *
     2471 * @param dialog Save As dialog
     2472 * @param arg Argument (ui_demo_t *)
     2473 * @param fname File name
     2474 */
     2475static void save_as_dialog_bok(ui_file_dialog_t *dialog, void *arg,
     2476    const char *fname)
     2477{
     2478        edit_t *edit = (edit_t *)arg;
     2479        char *cname;
     2480        errno_t rc;
     2481
     2482        (void)edit;
     2483        ui_file_dialog_destroy(dialog);
     2484
     2485        cname = str_dup(fname);
     2486        if (cname == NULL) {
     2487                printf("Out of memory.\n");
     2488                return;
     2489        }
     2490
     2491        rc = file_save(fname);
     2492        if (rc != EOK)
     2493                return;
     2494
     2495        if (doc.file_name != NULL)
     2496                free(doc.file_name);
     2497        doc.file_name = cname;
     2498
     2499}
     2500
     2501/** Save As dialog cancel button press.
     2502 *
     2503 * @param dialog File dialog
     2504 * @param arg Argument (ui_demo_t *)
     2505 */
     2506static void save_as_dialog_bcancel(ui_file_dialog_t *dialog, void *arg)
     2507{
     2508        edit_t *edit = (edit_t *)arg;
     2509
     2510        (void)edit;
     2511        ui_file_dialog_destroy(dialog);
     2512}
     2513
     2514/** Save As dialog close request.
     2515 *
     2516 * @param dialog File dialog
     2517 * @param arg Argument (ui_demo_t *)
     2518 */
     2519static void save_as_dialog_close(ui_file_dialog_t *dialog, void *arg)
     2520{
     2521        edit_t *edit = (edit_t *)arg;
     2522
     2523        (void)edit;
     2524        ui_file_dialog_destroy(dialog);
     2525}
     2526
     2527/** Go To Line dialog OK button press.
     2528 *
     2529 * @param dialog Go To Line dialog
     2530 * @param arg Argument (ui_demo_t *)
     2531 * @param text Submitted text
     2532 */
     2533static void go_to_line_dialog_bok(ui_prompt_dialog_t *dialog, void *arg,
     2534    const char *text)
     2535{
     2536        edit_t *edit = (edit_t *) arg;
     2537        char *endptr;
     2538        int line;
     2539
     2540        ui_prompt_dialog_destroy(dialog);
     2541        line = strtol(text, &endptr, 10);
     2542        if (*endptr != '\0') {
     2543                status_display("Invalid number entered.");
     2544                return;
     2545        }
     2546
     2547        caret_move_absolute(line, pane.ideal_column, dir_before, false);
     2548        (void)edit;
     2549        (void) pane_update(&pane);
     2550}
     2551
     2552/** Go To Line dialog cancel button press.
     2553 *
     2554 * @param dialog File dialog
     2555 * @param arg Argument (ui_demo_t *)
     2556 */
     2557static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg)
     2558{
     2559        edit_t *edit = (edit_t *) arg;
     2560
     2561        (void)edit;
     2562        ui_prompt_dialog_destroy(dialog);
     2563}
     2564
     2565/** Go To Line dialog close request.
     2566 *
     2567 * @param dialog File dialog
     2568 * @param arg Argument (ui_demo_t *)
     2569 */
     2570static void go_to_line_dialog_close(ui_prompt_dialog_t *dialog, void *arg)
     2571{
     2572        edit_t *edit = (edit_t *) arg;
     2573
     2574        (void)edit;
     2575        ui_prompt_dialog_destroy(dialog);
     2576}
     2577
     2578/** Search dialog OK button press.
     2579 *
     2580 * @param dialog Search dialog
     2581 * @param arg Argument (ui_demo_t *)
     2582 * @param text Submitted text
     2583 */
     2584static void search_dialog_bok(ui_prompt_dialog_t *dialog, void *arg,
     2585    const char *text)
     2586{
     2587        edit_t *edit = (edit_t *) arg;
     2588        char *pattern;
     2589        bool reverse;
     2590
     2591        (void)edit;
     2592        ui_prompt_dialog_destroy(dialog);
     2593
     2594        /* Abort if search phrase is empty */
     2595        if (text[0] == '\0')
     2596                return;
     2597
     2598        pattern = str_dup(text);
     2599        reverse = pane.search_reverse;
     2600
     2601        if (pane.previous_search)
     2602                free(pane.previous_search);
     2603        pane.previous_search = pattern;
     2604        pane.previous_search_reverse = reverse;
     2605
     2606        search(pattern, reverse);
     2607
     2608        (void) pane_update(&pane);
     2609}
     2610
     2611/** Search dialog cancel button press.
     2612 *
     2613 * @param dialog File dialog
     2614 * @param arg Argument (ui_demo_t *)
     2615 */
     2616static void search_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg)
     2617{
     2618        edit_t *edit = (edit_t *) arg;
     2619
     2620        (void)edit;
     2621        ui_prompt_dialog_destroy(dialog);
     2622}
     2623
     2624/** Search dialog close request.
     2625 *
     2626 * @param dialog File dialog
     2627 * @param arg Argument (ui_demo_t *)
     2628 */
     2629static void search_dialog_close(ui_prompt_dialog_t *dialog, void *arg)
     2630{
     2631        edit_t *edit = (edit_t *) arg;
     2632
     2633        (void)edit;
     2634        ui_prompt_dialog_destroy(dialog);
    17302635}
    17312636
Note: See TracChangeset for help on using the changeset viewer.