Changes in uspace/app/edit/edit.c [e0cf963:87822ce] in mainline


Ignore:
File:
1 edited

Legend:

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

    re0cf963 r87822ce  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2009 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>
    5138#include <stdio.h>
    5239#include <stdlib.h>
    5340#include <stddef.h>
    5441#include <stdbool.h>
     42#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>
    5550#include <types/common.h>
    56 #include <ui/control.h>
    57 #include <ui/filedialog.h>
    58 #include <ui/fixed.h>
    59 #include <ui/label.h>
    60 #include <ui/menu.h>
    61 #include <ui/menubar.h>
    62 #include <ui/menuentry.h>
    63 #include <ui/promptdialog.h>
    64 #include <ui/resource.h>
    65 #include <ui/ui.h>
    66 #include <ui/window.h>
    67 #include <vfs/vfs.h>
    6851
    6952#include "sheet.h"
     
    8063 *
    8164 * A rectangular area of the screen used to edit a document. Different
    82  * panes can be possibly used to edit the same document. This is a custom
    83  * UI control.
     65 * panes can be possibly used to edit the same document.
    8466 */
    8567typedef struct {
    86         /** Base control object */
    87         struct ui_control *control;
    88 
    89         /** Containing window */
    90         ui_window_t *window;
    91 
    92         /** UI resource */
    93         struct ui_resource *res;
    94 
    95         /** Pane rectangle */
    96         gfx_rect_t rect;
    97 
    98         /** Pane color */
    99         gfx_color_t *color;
    100 
    101         /** Selection color */
    102         gfx_color_t *sel_color;
    103 
    10468        /* Pane dimensions */
    10569        int rows, columns;
     
    12690        int ideal_column;
    12791
    128         bool search_reverse;
    12992        char *previous_search;
    13093        bool previous_search_reverse;
    13194} pane_t;
    132 
    133 /** Text editor */
    134 typedef struct {
    135         /** User interface */
    136         ui_t *ui;
    137         /** Editor window */
    138         ui_window_t *window;
    139         /** UI resource */
    140         ui_resource_t *ui_res;
    141         /** Menu bar */
    142         ui_menu_bar_t *menubar;
    143         /** Status bar */
    144         ui_label_t *status;
    145 } edit_t;
    14695
    14796/** Document
     
    154103} doc_t;
    155104
    156 static edit_t edit;
     105static console_ctrl_t *con;
    157106static doc_t doc;
     107static bool done;
    158108static pane_t pane;
     109static bool cursor_visible;
     110
     111static sysarg_t scr_rows;
     112static sysarg_t scr_columns;
    159113
    160114#define ROW_BUF_SIZE 4096
     
    165119#define INFNAME_MAX_LEN 128
    166120
     121static void cursor_show(void);
     122static void cursor_hide(void);
    167123static void cursor_setvis(bool visible);
    168124
     
    183139static char *range_get_str(spt_t const *spos, spt_t const *epos);
    184140
    185 static errno_t pane_init(ui_window_t *, pane_t *);
    186 static void pane_fini(pane_t *);
    187 static ui_control_t *pane_ctl(pane_t *);
    188 static errno_t pane_update(pane_t *);
    189 static errno_t pane_text_display(pane_t *);
     141static char *prompt(char const *prompt, char const *init_value);
     142
     143static void pane_text_display(void);
    190144static void pane_row_display(void);
    191 static errno_t pane_row_range_display(pane_t *, int r0, int r1);
    192 static void pane_status_display(pane_t *);
    193 static void pane_caret_display(pane_t *);
     145static void pane_row_range_display(int r0, int r1);
     146static void pane_status_display(void);
     147static void pane_caret_display(void);
    194148
    195149static void insert_char(char32_t c);
     
    210164static void selection_delete(void);
    211165static void selection_copy(void);
    212 static void edit_cut(void);
    213 static void edit_paste(void);
    214166static void insert_clipboard_data(void);
    215167
     
    233185
    234186static void status_display(char const *str);
    235 static errno_t edit_ui_create(edit_t *);
    236 static void edit_ui_destroy(edit_t *);
    237 
    238 static void edit_wnd_close(ui_window_t *, void *);
    239 static void edit_wnd_kbd_event(ui_window_t *, void *, kbd_event_t *);
    240 
    241 static ui_window_cb_t edit_window_cb = {
    242         .close = edit_wnd_close,
    243         .kbd = edit_wnd_kbd_event
    244 };
    245 
    246 static void edit_file_save(ui_menu_entry_t *, void *);
    247 static void edit_file_save_as(ui_menu_entry_t *, void *);
    248 static void edit_file_exit(ui_menu_entry_t *, void *);
    249 static void edit_edit_cut(ui_menu_entry_t *, void *);
    250 static void edit_edit_copy(ui_menu_entry_t *, void *);
    251 static void edit_edit_paste(ui_menu_entry_t *, void *);
    252 static void edit_edit_delete(ui_menu_entry_t *, void *);
    253 static void edit_edit_select_all(ui_menu_entry_t *, void *);
    254 static void edit_search_find(ui_menu_entry_t *, void *);
    255 static void edit_search_reverse_find(ui_menu_entry_t *, void *);
    256 static void edit_search_find_next(ui_menu_entry_t *, void *);
    257 static void edit_search_go_to_line(ui_menu_entry_t *, void *);
    258 
    259 static void pane_ctl_destroy(void *);
    260 static errno_t pane_ctl_paint(void *);
    261 static ui_evclaim_t pane_ctl_pos_event(void *, pos_event_t *);
    262 
    263 /** Pabe control ops */
    264 ui_control_ops_t pane_ctl_ops = {
    265         .destroy = pane_ctl_destroy,
    266         .paint = pane_ctl_paint,
    267         .pos_event = pane_ctl_pos_event
    268 };
    269 
    270 static void save_as_dialog_bok(ui_file_dialog_t *, void *, const char *);
    271 static void save_as_dialog_bcancel(ui_file_dialog_t *, void *);
    272 static void save_as_dialog_close(ui_file_dialog_t *, void *);
    273 
    274 static ui_file_dialog_cb_t save_as_dialog_cb = {
    275         .bok = save_as_dialog_bok,
    276         .bcancel = save_as_dialog_bcancel,
    277         .close = save_as_dialog_close
    278 };
    279 
    280 static void go_to_line_dialog_bok(ui_prompt_dialog_t *, void *, const char *);
    281 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *, void *);
    282 static void go_to_line_dialog_close(ui_prompt_dialog_t *, void *);
    283 
    284 static ui_prompt_dialog_cb_t go_to_line_dialog_cb = {
    285         .bok = go_to_line_dialog_bok,
    286         .bcancel = go_to_line_dialog_bcancel,
    287         .close =  go_to_line_dialog_close
    288 };
    289 
    290 static void search_dialog_bok(ui_prompt_dialog_t *, void *, const char *);
    291 static void search_dialog_bcancel(ui_prompt_dialog_t *, void *);
    292 static void search_dialog_close(ui_prompt_dialog_t *, void *);
    293 
    294 static ui_prompt_dialog_cb_t search_dialog_cb = {
    295         .bok = search_dialog_bok,
    296         .bcancel = search_dialog_bcancel,
    297         .close =  search_dialog_close
    298 };
    299187
    300188int main(int argc, char *argv[])
    301189{
     190        cons_event_t ev;
    302191        bool new_file;
    303192        errno_t rc;
    304193
     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;
    305201        pane.sh_row = 1;
    306202        pane.sh_column = 1;
     
    338234        /* Move to beginning of file. */
    339235        pt_get_sof(&sof);
    340 
    341         /* Create UI */
    342         rc = edit_ui_create(&edit);
    343         if (rc != EOK)
    344                 return 1;
    345 
    346236        caret_move(sof, true, true);
    347237
    348238        /* Initial display */
    349         rc = ui_window_paint(edit.window);
    350         if (rc != EOK) {
    351                 printf("Error painting window.\n");
    352                 return rc;
    353         }
    354 
    355         pane_status_display(&pane);
     239        cursor_visible = true;
     240
     241        cursor_hide();
     242        console_clear(con);
     243        pane_text_display();
     244        pane_status_display();
    356245        if (new_file && doc.file_name != NULL)
    357246                status_display("File not found. Starting empty file.");
    358         pane_caret_display(&pane);
    359         cursor_setvis(true);
    360 
    361         ui_run(edit.ui);
    362 
    363         edit_ui_destroy(&edit);
     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
    364288        return 0;
    365 }
    366 
    367 /** Create text editor UI.
    368  *
    369  * @param edit Editor
    370  * @return EOK on success or an error code
    371  */
    372 static errno_t edit_ui_create(edit_t *edit)
    373 {
    374         errno_t rc;
    375         ui_wnd_params_t params;
    376         ui_fixed_t *fixed = NULL;
    377         ui_menu_t *mfile = NULL;
    378         ui_menu_t *medit = NULL;
    379         ui_menu_entry_t *msave = NULL;
    380         ui_menu_entry_t *msaveas = NULL;
    381         ui_menu_entry_t *mfsep = NULL;
    382         ui_menu_entry_t *mexit = NULL;
    383         ui_menu_entry_t *mcut = NULL;
    384         ui_menu_entry_t *mcopy = NULL;
    385         ui_menu_entry_t *mpaste = NULL;
    386         ui_menu_entry_t *mdelete = NULL;
    387         ui_menu_entry_t *mesep = NULL;
    388         ui_menu_entry_t *mselall = NULL;
    389         ui_menu_t *msearch = NULL;
    390         ui_menu_entry_t *mfind = NULL;
    391         ui_menu_entry_t *mfindr = NULL;
    392         ui_menu_entry_t *mfindn = NULL;
    393         ui_menu_entry_t *mssep = NULL;
    394         ui_menu_entry_t *mgoto = NULL;
    395         gfx_rect_t arect;
    396         gfx_rect_t rect;
    397 
    398         rc = ui_create(UI_CONSOLE_DEFAULT, &edit->ui);
    399         if (rc != EOK) {
    400                 printf("Error creating UI on display %s.\n",
    401                     UI_CONSOLE_DEFAULT);
    402                 goto error;
    403         }
    404 
    405         ui_wnd_params_init(&params);
    406         params.caption = "Text Editor";
    407         params.style &= ~ui_wds_decorated;
    408         params.placement = ui_wnd_place_full_screen;
    409 
    410         rc = ui_window_create(edit->ui, &params, &edit->window);
    411         if (rc != EOK) {
    412                 printf("Error creating window.\n");
    413                 goto error;
    414         }
    415 
    416         ui_window_set_cb(edit->window, &edit_window_cb, (void *) edit);
    417 
    418         edit->ui_res = ui_window_get_res(edit->window);
    419 
    420         rc = ui_fixed_create(&fixed);
    421         if (rc != EOK) {
    422                 printf("Error creating fixed layout.\n");
    423                 return rc;
    424         }
    425 
    426         rc = ui_menu_bar_create(edit->ui, edit->window, &edit->menubar);
    427         if (rc != EOK) {
    428                 printf("Error creating menu bar.\n");
    429                 return rc;
    430         }
    431 
    432         rc = ui_menu_create(edit->menubar, "File", &mfile);
    433         if (rc != EOK) {
    434                 printf("Error creating menu.\n");
    435                 return rc;
    436         }
    437 
    438         rc = ui_menu_entry_create(mfile, "Save", "Ctrl-S", &msave);
    439         if (rc != EOK) {
    440                 printf("Error creating menu.\n");
    441                 return rc;
    442         }
    443 
    444         ui_menu_entry_set_cb(msave, edit_file_save, (void *) edit);
    445 
    446         rc = ui_menu_entry_create(mfile, "Save As", "Ctrl-E", &msaveas);
    447         if (rc != EOK) {
    448                 printf("Error creating menu.\n");
    449                 return rc;
    450         }
    451 
    452         ui_menu_entry_set_cb(msaveas, edit_file_save_as, (void *) edit);
    453 
    454         rc = ui_menu_entry_sep_create(mfile, &mfsep);
    455         if (rc != EOK) {
    456                 printf("Error creating menu.\n");
    457                 return rc;
    458         }
    459 
    460         rc = ui_menu_entry_create(mfile, "Exit", "Ctrl-Q", &mexit);
    461         if (rc != EOK) {
    462                 printf("Error creating menu.\n");
    463                 return rc;
    464         }
    465 
    466         ui_menu_entry_set_cb(mexit, edit_file_exit, (void *) edit);
    467 
    468         rc = ui_menu_create(edit->menubar, "Edit", &medit);
    469         if (rc != EOK) {
    470                 printf("Error creating menu.\n");
    471                 return rc;
    472         }
    473 
    474         rc = ui_menu_entry_create(medit, "Cut", "Ctrl-X", &mcut);
    475         if (rc != EOK) {
    476                 printf("Error creating menu.\n");
    477                 return rc;
    478         }
    479 
    480         ui_menu_entry_set_cb(mcut, edit_edit_cut, (void *) edit);
    481 
    482         rc = ui_menu_entry_create(medit, "Copy", "Ctrl-C", &mcopy);
    483         if (rc != EOK) {
    484                 printf("Error creating menu.\n");
    485                 return rc;
    486         }
    487 
    488         ui_menu_entry_set_cb(mcopy, edit_edit_copy, (void *) edit);
    489 
    490         rc = ui_menu_entry_create(medit, "Paste", "Ctrl-V", &mpaste);
    491         if (rc != EOK) {
    492                 printf("Error creating menu.\n");
    493                 return rc;
    494         }
    495 
    496         ui_menu_entry_set_cb(mpaste, edit_edit_paste, (void *) edit);
    497 
    498         rc = ui_menu_entry_create(medit, "Delete", "Del", &mdelete);
    499         if (rc != EOK) {
    500                 printf("Error creating menu.\n");
    501                 return rc;
    502         }
    503 
    504         ui_menu_entry_set_cb(mdelete, edit_edit_delete, (void *) edit);
    505 
    506         rc = ui_menu_entry_sep_create(medit, &mesep);
    507         if (rc != EOK) {
    508                 printf("Error creating menu.\n");
    509                 return rc;
    510         }
    511 
    512         rc = ui_menu_entry_create(medit, "Select All", "Ctrl-A", &mselall);
    513         if (rc != EOK) {
    514                 printf("Error creating menu.\n");
    515                 return rc;
    516         }
    517 
    518         ui_menu_entry_set_cb(mselall, edit_edit_select_all, (void *) edit);
    519 
    520         rc = ui_menu_create(edit->menubar, "Search", &msearch);
    521         if (rc != EOK) {
    522                 printf("Error creating menu.\n");
    523                 return rc;
    524         }
    525 
    526         rc = ui_menu_entry_create(msearch, "Find", "Ctrl-F", &mfind);
    527         if (rc != EOK) {
    528                 printf("Error creating menu.\n");
    529                 return rc;
    530         }
    531 
    532         ui_menu_entry_set_cb(mfind, edit_search_find, (void *) edit);
    533 
    534         rc = ui_menu_entry_create(msearch, "Reverse Find", "Ctrl-Shift-F", &mfindr);
    535         if (rc != EOK) {
    536                 printf("Error creating menu.\n");
    537                 return rc;
    538         }
    539 
    540         ui_menu_entry_set_cb(mfindr, edit_search_reverse_find, (void *) edit);
    541 
    542         rc = ui_menu_entry_create(msearch, "Find Next", "Ctrl-N", &mfindn);
    543         if (rc != EOK) {
    544                 printf("Error creating menu.\n");
    545                 return rc;
    546         }
    547 
    548         ui_menu_entry_set_cb(mfindn, edit_search_find_next, (void *) edit);
    549 
    550         rc = ui_menu_entry_sep_create(msearch, &mssep);
    551         if (rc != EOK) {
    552                 printf("Error creating menu.\n");
    553                 return rc;
    554         }
    555 
    556         rc = ui_menu_entry_create(msearch, "Go To Line", "Ctrl-L", &mgoto);
    557         if (rc != EOK) {
    558                 printf("Error creating menu.\n");
    559                 return rc;
    560         }
    561 
    562         ui_menu_entry_set_cb(mgoto, edit_search_go_to_line, (void *) edit);
    563 
    564         ui_window_get_app_rect(edit->window, &arect);
    565 
    566         rect.p0 = arect.p0;
    567         rect.p1.x = arect.p1.x;
    568         rect.p1.y = arect.p0.y + 1;
    569         ui_menu_bar_set_rect(edit->menubar, &rect);
    570 
    571         rc = ui_fixed_add(fixed, ui_menu_bar_ctl(edit->menubar));
    572         if (rc != EOK) {
    573                 printf("Error adding control to layout.\n");
    574                 return rc;
    575         }
    576 
    577         rc = pane_init(edit->window, &pane);
    578         if (rc != EOK) {
    579                 printf("Error initializing pane.\n");
    580                 return rc;
    581         }
    582 
    583         rc = ui_fixed_add(fixed, pane_ctl(&pane));
    584         if (rc != EOK) {
    585                 printf("Error adding control to layout.\n");
    586                 return rc;
    587         }
    588 
    589         rc = ui_label_create(edit->ui_res, "", &edit->status);
    590         if (rc != EOK) {
    591                 printf("Error creating menu bar.\n");
    592                 return rc;
    593         }
    594 
    595         rect.p0.x = arect.p0.x;
    596         rect.p0.y = arect.p1.y - 1;
    597         rect.p1 = arect.p1;
    598         ui_label_set_rect(edit->status, &rect);
    599 
    600         rc = ui_fixed_add(fixed, ui_label_ctl(edit->status));
    601         if (rc != EOK) {
    602                 printf("Error adding control to layout.\n");
    603                 return rc;
    604         }
    605 
    606         ui_window_add(edit->window, ui_fixed_ctl(fixed));
    607         return EOK;
    608 error:
    609         if (edit->window != NULL)
    610                 ui_window_destroy(edit->window);
    611         if (edit->ui != NULL)
    612                 ui_destroy(edit->ui);
    613         return rc;
    614 }
    615 
    616 /** Destroy text editor UI.
    617  *
    618  * @param edit Editor
    619  */
    620 static void edit_ui_destroy(edit_t *edit)
    621 {
    622         ui_window_destroy(edit->window);
    623         ui_destroy(edit->ui);
    624289}
    625290
     
    644309}
    645310
     311static void cursor_show(void)
     312{
     313        cursor_setvis(true);
     314}
     315
     316static void cursor_hide(void)
     317{
     318        cursor_setvis(false);
     319}
     320
    646321static void cursor_setvis(bool visible)
    647322{
    648         gfx_context_t *gc = ui_window_get_gc(edit.window);
    649 
    650         (void) gfx_cursor_set_visible(gc, visible);
     323        if (cursor_visible != visible) {
     324                console_cursor_visibility(con, visible);
     325                cursor_visible = visible;
     326        }
    651327}
    652328
     
    724400        switch (ev->key) {
    725401        case KC_Q:
    726                 ui_quit(edit.ui);
     402                done = true;
    727403                break;
    728404        case KC_S:
     
    739415                break;
    740416        case KC_V:
    741                 edit_paste();
     417                selection_delete();
     418                insert_clipboard_data();
     419                pane.rflags |= REDRAW_TEXT;
     420                caret_update();
    742421                break;
    743422        case KC_X:
    744                 edit_cut();
     423                selection_copy();
     424                selection_delete();
     425                pane.rflags |= REDRAW_TEXT;
     426                caret_update();
    745427                break;
    746428        case KC_A:
     
    808490
    809491        if (ev->type == POS_PRESS && ev->vpos < (unsigned)pane.rows) {
    810                 bc.row = pane.sh_row + ev->vpos - pane.rect.p0.y;
    811                 bc.column = pane.sh_column + ev->hpos - pane.rect.p0.x;
     492                bc.row = pane.sh_row + ev->vpos;
     493                bc.column = pane.sh_column + ev->hpos;
    812494                sheet_get_cell_pt(doc.sh, &bc, dir_before, &pt);
    813495
     
    815497
    816498                caret_move(pt, select, true);
    817                 pane_update(&pane);
    818499        }
    819500}
     
    925606}
    926607
    927 /** Open Save As dialog. */
     608/** Change document name and save. */
    928609static void file_save_as(void)
    929610{
    930611        const char *old_fname = (doc.file_name != NULL) ? doc.file_name : "";
    931         ui_file_dialog_params_t fdparams;
    932         ui_file_dialog_t *dialog;
     612        char *fname;
     613
     614        fname = prompt("Save As", old_fname);
     615        if (fname == NULL) {
     616                status_display("Save cancelled.");
     617                return;
     618        }
     619
     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. */
     630static 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;
    933639        errno_t rc;
    934640
    935         ui_file_dialog_params_init(&fdparams);
    936         fdparams.caption = "Save As";
    937         fdparams.ifname = old_fname;
    938 
    939         rc = ui_file_dialog_create(edit.ui, &fdparams, &dialog);
    940         if (rc != EOK) {
    941                 printf("Error creating message dialog.\n");
    942                 return;
    943         }
    944 
    945         ui_file_dialog_set_cb(dialog, &save_as_dialog_cb, &edit);
     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;
    946694}
    947695
     
    1060808}
    1061809
    1062 /** Initialize pane.
    1063  *
    1064  * TODO: Replace with pane_create() that allocates the pane.
    1065  *
    1066  * @param window Editor window
    1067  * @param pane Pane
    1068  * @return EOK on success or an error code
    1069  */
    1070 static errno_t pane_init(ui_window_t *window, pane_t *pane)
    1071 {
    1072         errno_t rc;
    1073         gfx_rect_t arect;
    1074 
    1075         pane->control = NULL;
    1076         pane->color = NULL;
    1077         pane->sel_color = NULL;
    1078 
    1079         rc = ui_control_new(&pane_ctl_ops, (void *) pane, &pane->control);
    1080         if (rc != EOK)
    1081                 goto error;
    1082 
    1083         rc = gfx_color_new_ega(0x07, &pane->color);
    1084         if (rc != EOK)
    1085                 goto error;
    1086 
    1087         rc = gfx_color_new_ega(0x1e, &pane->sel_color);
    1088         if (rc != EOK)
    1089                 goto error;
    1090 
    1091         pane->res = ui_window_get_res(window);
    1092         pane->window = window;
    1093 
    1094         ui_window_get_app_rect(window, &arect);
    1095         pane->rect.p0.x = arect.p0.x;
    1096         pane->rect.p0.y = arect.p0.y + 1;
    1097         pane->rect.p1.x = arect.p1.x;
    1098         pane->rect.p1.y = arect.p1.y - 1;
    1099 
    1100         pane->columns = pane->rect.p1.x - pane->rect.p0.x;
    1101         pane->rows = pane->rect.p1.y - pane->rect.p0.y;
    1102 
    1103         return EOK;
    1104 error:
    1105         if (pane->control != NULL) {
    1106                 ui_control_delete(pane->control);
    1107                 pane->control = NULL;
    1108         }
    1109 
    1110         if (pane->color != NULL) {
    1111                 gfx_color_delete(pane->color);
    1112                 pane->color = NULL;
    1113         }
    1114 
    1115         return rc;
    1116 }
    1117 
    1118 /** Finalize pane.
    1119  *
    1120  * TODO: Replace with pane_destroy() that deallocates the pane.
    1121  *
    1122  * @param pane Pane
    1123  */
    1124 static void pane_fini(pane_t *pane)
    1125 {
    1126         gfx_color_delete(pane->color);
    1127         pane->color = NULL;
    1128         gfx_color_delete(pane->sel_color);
    1129         pane->sel_color = NULL;
    1130         ui_control_delete(pane->control);
    1131         pane->control = NULL;
    1132 }
    1133 
    1134 /** Return base control object for a pane.
    1135  *
    1136  * @param pane Pane
    1137  * @return Base UI cntrol
    1138  */
    1139 static ui_control_t *pane_ctl(pane_t *pane)
    1140 {
    1141         return pane->control;
    1142 }
    1143 
    1144 /** Repaint parts of pane that need updating.
    1145  *
    1146  * @param pane Pane
    1147  * @return EOK on succes or an error code
    1148  */
    1149 static errno_t pane_update(pane_t *pane)
    1150 {
    1151         errno_t rc;
    1152 
    1153         if (pane->rflags & REDRAW_TEXT) {
    1154                 rc = pane_text_display(pane);
    1155                 if (rc != EOK)
    1156                         return rc;
    1157         }
    1158 
    1159         if (pane->rflags & REDRAW_ROW)
    1160                 pane_row_display();
    1161 
    1162         if (pane->rflags & REDRAW_STATUS)
    1163                 pane_status_display(pane);
    1164 
    1165         if (pane->rflags & REDRAW_CARET)
    1166                 pane_caret_display(pane);
    1167 
    1168         pane->rflags &= ~(REDRAW_TEXT | REDRAW_ROW | REDRAW_STATUS |
    1169             REDRAW_CARET);
    1170         return EOK;
    1171 }
    1172 
    1173 /** Display pane text.
    1174  *
    1175  * @param pane Pane
    1176  * @return EOK on success or an error code
    1177  */
    1178 static errno_t pane_text_display(pane_t *pane)
    1179 {
    1180         gfx_rect_t rect;
    1181         gfx_context_t *gc;
    1182         errno_t rc;
     810static void pane_text_display(void)
     811{
    1183812        int sh_rows, rows;
    1184813
    1185814        sheet_get_num_rows(doc.sh, &sh_rows);
    1186         rows = min(sh_rows - pane->sh_row + 1, pane->rows);
     815        rows = min(sh_rows - pane.sh_row + 1, pane.rows);
    1187816
    1188817        /* Draw rows from the sheet. */
    1189818
    1190         rc = pane_row_range_display(pane, 0, rows);
    1191         if (rc != EOK)
    1192                 return rc;
     819        console_set_pos(con, 0, 0);
     820        pane_row_range_display(0, rows);
    1193821
    1194822        /* Clear the remaining rows if file is short. */
    1195823
    1196         gc = ui_window_get_gc(pane->window);
    1197 
    1198         rc = gfx_set_color(gc, pane->color);
    1199         if (rc != EOK)
    1200                 goto error;
    1201 
    1202         rect.p0.x = pane->rect.p0.x;
    1203         rect.p0.y = pane->rect.p0.y + rows;
    1204         rect.p1.x = pane->rect.p1.x;
    1205         rect.p1.y = pane->rect.p1.y;
    1206 
    1207         rc = gfx_fill_rect(gc, &rect);
    1208         if (rc != EOK)
    1209                 goto error;
    1210 
    1211         pane->rflags &= ~REDRAW_ROW;
    1212         return EOK;
    1213 error:
    1214         return rc;
     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;
    1215835}
    1216836
     
    1226846
    1227847        ridx = coord.row - pane.sh_row;
    1228         (void) pane_row_range_display(&pane, ridx, ridx + 1);
     848        pane_row_range_display(ridx, ridx + 1);
    1229849        pane.rflags |= (REDRAW_STATUS | REDRAW_CARET);
    1230850}
    1231851
    1232 /** Display a range of rows of text.
    1233  *
    1234  * @param r0 Start row (inclusive)
    1235  * @param r1 End row (exclusive)
    1236  * @return EOk on success or an error code
    1237  */
    1238 static errno_t pane_row_range_display(pane_t *pane, int r0, int r1)
    1239 {
    1240         int i, fill;
     852static void pane_row_range_display(int r0, int r1)
     853{
     854        int i, j, fill;
    1241855        spt_t rb, re, dep, pt;
    1242856        coord_t rbc, rec;
    1243857        char row_buf[ROW_BUF_SIZE];
    1244         char cbuf[STR_BOUNDS(1) + 1];
    1245858        char32_t c;
    1246859        size_t pos, size;
    1247         size_t cpos;
    1248860        int s_column;
    1249861        coord_t csel_start, csel_end, ctmp;
    1250         gfx_font_t *font;
    1251         gfx_context_t *gc;
    1252         gfx_text_fmt_t fmt;
    1253         gfx_coord2_t tpos;
    1254         gfx_rect_t rect;
    1255         errno_t rc;
    1256 
    1257         font = ui_resource_get_font(edit.ui_res);
    1258         gc = ui_window_get_gc(edit.window);
    1259 
    1260         gfx_text_fmt_init(&fmt);
    1261         fmt.color = pane->color;
    1262862
    1263863        /* Determine selection start and end. */
    1264864
    1265         tag_get_pt(&pane->sel_start, &pt);
     865        tag_get_pt(&pane.sel_start, &pt);
    1266866        spt_get_coord(&pt, &csel_start);
    1267867
    1268         tag_get_pt(&pane->caret_pos, &pt);
     868        tag_get_pt(&pane.caret_pos, &pt);
    1269869        spt_get_coord(&pt, &csel_end);
    1270870
     
    1277877        /* Draw rows from the sheet. */
    1278878
     879        console_set_pos(con, 0, 0);
    1279880        for (i = r0; i < r1; ++i) {
    1280                 tpos.x = pane->rect.p0.x;
    1281                 tpos.y = pane->rect.p0.y + i;
    1282 
    1283881                /* Starting point for row display */
    1284                 rbc.row = pane->sh_row + i;
    1285                 rbc.column = pane->sh_column;
     882                rbc.row = pane.sh_row + i;
     883                rbc.column = pane.sh_column;
    1286884                sheet_get_cell_pt(doc.sh, &rbc, dir_before, &rb);
    1287885
    1288886                /* Ending point for row display */
    1289                 rec.row = pane->sh_row + i;
    1290                 rec.column = pane->sh_column + pane->columns;
     887                rec.row = pane.sh_row + i;
     888                rec.column = pane.sh_column + pane.columns;
    1291889                sheet_get_cell_pt(doc.sh, &rec, dir_before, &re);
    1292890
     
    1298896                if (coord_cmp(&csel_start, &rbc) <= 0 &&
    1299897                    coord_cmp(&rbc, &csel_end) < 0) {
    1300                         fmt.color = pane->sel_color;
     898                        console_flush(con);
     899                        console_set_style(con, STYLE_SELECTED);
     900                        console_flush(con);
    1301901                }
    1302902
     903                console_set_pos(con, 0, i);
    1303904                size = str_size(row_buf);
    1304905                pos = 0;
    1305                 s_column = pane->sh_column;
     906                s_column = pane.sh_column;
    1306907                while (pos < size) {
    1307                         if ((csel_start.row == rbc.row) && (csel_start.column == s_column))
    1308                                 fmt.color = pane->sel_color;
    1309 
    1310                         if ((csel_end.row == rbc.row) && (csel_end.column == s_column))
    1311                                 fmt.color = pane->color;
     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                        }
    1312919
    1313920                        c = str_decode(row_buf, &pos, size);
    1314921                        if (c != '\t') {
    1315                                 cpos = 0;
    1316                                 rc = chr_encode(c, cbuf, &cpos, sizeof(cbuf));
    1317                                 if (rc != EOK)
    1318                                         return rc;
    1319 
    1320                                 rc = gfx_puttext(font, &tpos, &fmt, cbuf);
    1321                                 if (rc != EOK)
    1322                                         return rc;
    1323 
     922                                printf("%lc", (wint_t) c);
    1324923                                s_column += 1;
    1325                                 tpos.x++;
    1326924                        } else {
    1327925                                fill = 1 + ALIGN_UP(s_column, TAB_WIDTH) -
    1328926                                    s_column;
    1329927
    1330                                 rc = gfx_set_color(gc, fmt.color);
    1331                                 if (rc != EOK)
    1332                                         return rc;
    1333 
    1334                                 rect.p0.x = tpos.x;
    1335                                 rect.p0.y = tpos.y;
    1336                                 rect.p1.x = tpos.x + fill;
    1337                                 rect.p1.y = tpos.y + 1;
    1338 
    1339                                 rc = gfx_fill_rect(gc, &rect);
    1340                                 if (rc != EOK)
    1341                                         return rc;
    1342 
     928                                for (j = 0; j < fill; ++j)
     929                                        putchar(' ');
    1343930                                s_column += fill;
    1344                                 tpos.x += fill;
    1345931                        }
    1346932                }
    1347933
    1348                 if ((csel_end.row == rbc.row) && (csel_end.column == s_column))
    1349                         fmt.color = pane->color;
     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                }
    1350939
    1351940                /* Fill until the end of display area. */
    1352941
    1353                 rc = gfx_set_color(gc, fmt.color);
    1354                 if (rc != EOK)
    1355                         return rc;
    1356 
    1357                 rect.p0.x = tpos.x;
    1358                 rect.p0.y = tpos.y;
    1359                 rect.p1.x = pane->rect.p1.x;
    1360                 rect.p1.y = tpos.y + 1;
    1361 
    1362                 rc = gfx_fill_rect(gc, &rect);
    1363                 if (rc != EOK)
    1364                         return rc;
    1365         }
    1366 
    1367         return EOK;
    1368 }
    1369 
    1370 /** Display pane status in the status line.
    1371  *
    1372  * @param pane Pane
    1373  */
    1374 static void pane_status_display(pane_t *pane)
     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. */
     957static void pane_status_display(void)
    1375958{
    1376959        spt_t caret_pt;
     
    1381964        char *text;
    1382965        size_t n;
     966        int pos;
    1383967        size_t nextra;
    1384968        size_t fnw;
    1385969
    1386         tag_get_pt(&pane->caret_pos, &caret_pt);
     970        tag_get_pt(&pane.caret_pos, &caret_pt);
    1387971        spt_get_coord(&caret_pt, &coord);
    1388972
     
    1403987                return;
    1404988
     989        console_set_pos(con, 0, scr_rows - 1);
     990        console_set_style(con, STYLE_INVERTED);
     991
    1405992        /*
    1406993         * Make sure the status fits on the screen. This loop should
     
    1408995         */
    1409996        while (true) {
    1410                 int rc = asprintf(&text, "%d, %d (%d): File '%s'. Ctrl-Q Quit  Ctrl-S Save  "
     997                int rc = asprintf(&text, " %d, %d (%d): File '%s'. Ctrl-Q Quit  Ctrl-S Save  "
    1411998                    "Ctrl-E Save As", coord.row, coord.column, last_row, fname);
    1412999                if (rc < 0) {
     
    14171004                /* If it already fits, we're done */
    14181005                n = str_width(text);
    1419                 if ((int)n <= pane->columns - 2)
     1006                if (n <= scr_columns - 2)
    14201007                        break;
    14211008
    14221009                /* Compute number of excess characters */
    1423                 nextra = n - (pane->columns - 2);
     1010                nextra = n - (scr_columns - 2);
    14241011                /** With of the file name part */
    14251012                fnw = str_width(fname);
     
    14291016                 * just give up and print a blank status.
    14301017                 */
    1431                 if (nextra > fnw - 2) {
    1432                         text[0] = '\0';
     1018                if (nextra > fnw - 2)
    14331019                        goto finish;
    1434                 }
    14351020
    14361021                /* Compute position where we overwrite with '..\0' */
     
    14491034        }
    14501035
    1451 finish:
    1452         (void) ui_label_set_text(edit.status, text);
    1453         (void) ui_label_paint(edit.status);
     1036        printf("%s", text);
    14541037        free(text);
    14551038        free(fname);
    1456 }
    1457 
    1458 /** Set cursor to reflect position of the caret.
    1459  *
    1460  * @param pane Pane
    1461  */
    1462 static void pane_caret_display(pane_t *pane)
     1039finish:
     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. */
     1050static void pane_caret_display(void)
    14631051{
    14641052        spt_t caret_pt;
    14651053        coord_t coord;
    1466         gfx_coord2_t pos;
    1467         gfx_context_t *gc;
    1468 
    1469         tag_get_pt(&pane->caret_pos, &caret_pt);
     1054
     1055        tag_get_pt(&pane.caret_pos, &caret_pt);
    14701056
    14711057        spt_get_coord(&caret_pt, &coord);
    1472 
    1473         gc = ui_window_get_gc(edit.window);
    1474         pos.x = pane->rect.p0.x + coord.column - pane->sh_column;
    1475         pos.y = pane->rect.p0.y + coord.row - pane->sh_row;
    1476 
    1477         (void) gfx_cursor_set_pos(gc, &pos);
    1478 }
    1479 
    1480 /** Destroy pane control.
    1481  *
    1482  * @param arg Argument (pane_t *)
    1483  */
    1484 static void pane_ctl_destroy(void *arg)
    1485 {
    1486         pane_t *pane = (pane_t *)arg;
    1487 
    1488         pane_fini(pane);
    1489 }
    1490 
    1491 /** Paint pane control.
    1492  *
    1493  * @param arg Argument (pane_t *)
    1494  */
    1495 static errno_t pane_ctl_paint(void *arg)
    1496 {
    1497         pane_t *pane = (pane_t *)arg;
    1498         gfx_context_t *gc;
    1499         errno_t rc;
    1500 
    1501         gc = ui_window_get_gc(pane->window);
    1502 
    1503         rc = pane_text_display(pane);
    1504         if (rc != EOK)
    1505                 goto error;
    1506 
    1507         rc = gfx_update(gc);
    1508         if (rc != EOK)
    1509                 goto error;
    1510 
    1511 error:
    1512         return rc;
    1513 }
    1514 
    1515 /** Handle pane control position event.
    1516  *
    1517  * @param arg Argument (pane_t *)
    1518  * @param event Position event
    1519  */
    1520 static ui_evclaim_t pane_ctl_pos_event(void *arg, pos_event_t *event)
    1521 {
    1522         gfx_coord2_t pos;
    1523 
    1524         pos.x = event->hpos;
    1525         pos.y = event->vpos;
    1526 
    1527         if (!gfx_pix_inside_rect(&pos, &pane.rect))
    1528                 return ui_unclaimed;
    1529 
    1530         pos_handle(event);
    1531         (void) gfx_update(ui_window_get_gc(edit.window));
    1532         return ui_claimed;
     1058        console_set_pos(con, coord.column - pane.sh_column,
     1059            coord.row - pane.sh_row);
    15331060}
    15341061
     
    17431270static void caret_go_to_line_ask(void)
    17441271{
    1745         ui_prompt_dialog_params_t pdparams;
    1746         ui_prompt_dialog_t *dialog;
    1747         errno_t rc;
    1748 
    1749         ui_prompt_dialog_params_init(&pdparams);
    1750         pdparams.caption = "Go To Line";
    1751         pdparams.prompt = "Line Number";
    1752 
    1753         rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog);
    1754         if (rc != EOK) {
    1755                 printf("Error creating prompt dialog.\n");
     1272        char *sline;
     1273
     1274        sline = prompt("Go to line", "");
     1275        if (sline == NULL) {
     1276                status_display("Go to line cancelled.");
    17561277                return;
    17571278        }
    17581279
    1759         ui_prompt_dialog_set_cb(dialog, &go_to_line_dialog_cb, &edit);
     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);
    17601290}
    17611291
     
    18141344static void search_prompt(bool reverse)
    18151345{
    1816         ui_prompt_dialog_params_t pdparams;
    1817         ui_prompt_dialog_t *dialog;
    1818         errno_t rc;
    1819 
    1820         ui_prompt_dialog_params_init(&pdparams);
    1821         pdparams.caption = reverse ? "Reverse Search" : "Search";
    1822         pdparams.prompt = "Search text";
    1823         pdparams.itext = "";
    1824 
     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 = "";
    18251353        if (pane.previous_search)
    1826                 pdparams.itext = pane.previous_search;
    1827 
    1828         rc = ui_prompt_dialog_create(edit.ui, &pdparams, &dialog);
    1829         if (rc != EOK) {
    1830                 printf("Error creating prompt dialog.\n");
     1354                default_value = pane.previous_search;
     1355
     1356        pattern = prompt(prompt_text, default_value);
     1357        if (pattern == NULL) {
     1358                status_display("Search cancelled.");
    18311359                return;
    18321360        }
    18331361
    1834         ui_prompt_dialog_set_cb(dialog, &search_dialog_cb, &edit);
    1835         pane.search_reverse = reverse;
     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);
    18361368}
    18371369
     
    19811513        }
    19821514        free(str);
    1983 }
    1984 
    1985 static void edit_paste(void)
    1986 {
    1987         selection_delete();
    1988         insert_clipboard_data();
    1989         pane.rflags |= (REDRAW_TEXT | REDRAW_CARET);
    1990         pane_update(&pane);
    1991 }
    1992 
    1993 static void edit_cut(void)
    1994 {
    1995         selection_copy();
    1996         selection_delete();
    1997         pane.rflags |= (REDRAW_TEXT | REDRAW_CARET);
    1998         pane_update(&pane);
    19991515}
    20001516
     
    22031719static void status_display(char const *str)
    22041720{
    2205         (void) ui_label_set_text(edit.status, str);
    2206         (void) ui_label_paint(edit.status);
    2207 }
    2208 
    2209 /** Window close request
    2210  *
    2211  * @param window Window
    2212  * @param arg Argument (edit_t *)
    2213  */
    2214 static void edit_wnd_close(ui_window_t *window, void *arg)
    2215 {
    2216         edit_t *edit = (edit_t *) arg;
    2217 
    2218         ui_quit(edit->ui);
    2219 }
    2220 
    2221 /** Window keyboard event
    2222  *
    2223  * @param window Window
    2224  * @param arg Argument (edit_t *)
    2225  * @param event Keyboard event
    2226  */
    2227 static void edit_wnd_kbd_event(ui_window_t *window, void *arg,
    2228     kbd_event_t *event)
    2229 {
    2230         pane.keymod = event->mods;
    2231 
    2232         if (event->type == KEY_PRESS) {
    2233                 key_handle_press(event);
    2234                 (void) pane_update(&pane);
    2235                 (void) gfx_update(ui_window_get_gc(window));
    2236         }
    2237 }
    2238 
    2239 /** File / Save menu entry selected.
    2240  *
    2241  * @param mentry Menu entry
    2242  * @param arg Argument (edit_t *)
    2243  */
    2244 static void edit_file_save(ui_menu_entry_t *mentry, void *arg)
    2245 {
    2246         edit_t *edit = (edit_t *) arg;
    2247 
    2248         (void)edit;
    2249 
    2250         if (doc.file_name != NULL)
    2251                 file_save(doc.file_name);
    2252         else
    2253                 file_save_as();
    2254 }
    2255 
    2256 /** File / Save As menu entry selected.
    2257  *
    2258  * @param mentry Menu entry
    2259  * @param arg Argument (edit_t *)
    2260  */
    2261 static void edit_file_save_as(ui_menu_entry_t *mentry, void *arg)
    2262 {
    2263         edit_t *edit = (edit_t *) arg;
    2264 
    2265         (void)edit;
    2266         file_save_as();
    2267 }
    2268 
    2269 /** File / Exit menu entry selected.
    2270  *
    2271  * @param mentry Menu entry
    2272  * @param arg Argument (edit_t *)
    2273  */
    2274 static void edit_file_exit(ui_menu_entry_t *mentry, void *arg)
    2275 {
    2276         edit_t *edit = (edit_t *) arg;
    2277 
    2278         ui_quit(edit->ui);
    2279 }
    2280 
    2281 /** Edit / Cut menu entry selected.
    2282  *
    2283  * @param mentry Menu entry
    2284  * @param arg Argument (edit_t *)
    2285  */
    2286 static void edit_edit_cut(ui_menu_entry_t *mentry, void *arg)
    2287 {
    2288         (void) arg;
    2289         edit_cut();
    2290         (void) gfx_update(ui_window_get_gc(edit.window));
    2291 }
    2292 
    2293 /** Edit / Copy menu entry selected.
    2294  *
    2295  * @param mentry Menu entry
    2296  * @param arg Argument (edit_t *)
    2297  */
    2298 static void edit_edit_copy(ui_menu_entry_t *mentry, void *arg)
    2299 {
    2300         (void) arg;
    2301         selection_copy();
    2302 }
    2303 
    2304 /** Edit / Paste menu entry selected.
    2305  *
    2306  * @param mentry Menu entry
    2307  * @param arg Argument (edit_t *)
    2308  */
    2309 static void edit_edit_paste(ui_menu_entry_t *mentry, void *arg)
    2310 {
    2311         (void) arg;
    2312         edit_paste();
    2313         (void) gfx_update(ui_window_get_gc(edit.window));
    2314 }
    2315 
    2316 /** Edit / Delete menu entry selected.
    2317  *
    2318  * @param mentry Menu entry
    2319  * @param arg Argument (edit_t *)
    2320  */
    2321 static void edit_edit_delete(ui_menu_entry_t *mentry, void *arg)
    2322 {
    2323         (void) arg;
    2324 
    2325         if (selection_active())
    2326                 selection_delete();
     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);
    23271728
    23281729        pane.rflags |= REDRAW_CARET;
    2329         (void) pane_update(&pane);
    2330         (void) gfx_update(ui_window_get_gc(edit.window));
    2331 }
    2332 
    2333 /** Edit / Select All menu entry selected.
    2334  *
    2335  * @param mentry Menu entry
    2336  * @param arg Argument (edit_t *)
    2337  */
    2338 static void edit_edit_select_all(ui_menu_entry_t *mentry, void *arg)
    2339 {
    2340         (void) arg;
    2341 
    2342         selection_sel_all();
    2343         pane.rflags |= (REDRAW_CARET | REDRAW_TEXT | REDRAW_STATUS);
    2344         pane_update(&pane);
    2345         (void) gfx_update(ui_window_get_gc(edit.window));
    2346 }
    2347 
    2348 /** Search / Find menu entry selected.
    2349  *
    2350  * @param mentry Menu entry
    2351  * @param arg Argument (edit_t *)
    2352  */
    2353 static void edit_search_find(ui_menu_entry_t *mentry, void *arg)
    2354 {
    2355         (void) arg;
    2356         search_prompt(false);
    2357 }
    2358 
    2359 /** Search / Reverse Find menu entry selected.
    2360  *
    2361  * @param mentry Menu entry
    2362  * @param arg Argument (edit_t *)
    2363  */
    2364 static void edit_search_reverse_find(ui_menu_entry_t *mentry, void *arg)
    2365 {
    2366         (void) arg;
    2367         search_prompt(true);
    2368 }
    2369 
    2370 /** Search / Find Next menu entry selected.
    2371  *
    2372  * @param mentry Menu entry
    2373  * @param arg Argument (edit_t *)
    2374  */
    2375 static void edit_search_find_next(ui_menu_entry_t *mentry, void *arg)
    2376 {
    2377         (void) arg;
    2378         search_repeat();
    2379         (void) pane_update(&pane);
    2380         (void) gfx_update(ui_window_get_gc(edit.window));
    2381 }
    2382 
    2383 /** Search / Go To Line menu entry selected.
    2384  *
    2385  * @param mentry Menu entry
    2386  * @param arg Argument (edit_t *)
    2387  */
    2388 static void edit_search_go_to_line(ui_menu_entry_t *mentry, void *arg)
    2389 {
    2390         (void) arg;
    2391         caret_go_to_line_ask();
    2392 }
    2393 
    2394 /** Save As dialog OK button press.
    2395  *
    2396  * @param dialog Save As dialog
    2397  * @param arg Argument (ui_demo_t *)
    2398  * @param fname File name
    2399  */
    2400 static void save_as_dialog_bok(ui_file_dialog_t *dialog, void *arg,
    2401     const char *fname)
    2402 {
    2403         edit_t *edit = (edit_t *)arg;
    2404         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2405         char *cname;
    2406         errno_t rc;
    2407 
    2408         ui_file_dialog_destroy(dialog);
    2409         // TODO Smarter cursor management
    2410         pane.rflags |= REDRAW_CARET;
    2411         (void) pane_update(&pane);
    2412         gfx_cursor_set_visible(gc, true);
    2413 
    2414         cname = str_dup(fname);
    2415         if (cname == NULL) {
    2416                 printf("Out of memory.\n");
    2417                 return;
    2418         }
    2419 
    2420         rc = file_save(fname);
    2421         if (rc != EOK)
    2422                 return;
    2423 
    2424         if (doc.file_name != NULL)
    2425                 free(doc.file_name);
    2426         doc.file_name = cname;
    2427 
    2428 }
    2429 
    2430 /** Save As dialog cancel button press.
    2431  *
    2432  * @param dialog File dialog
    2433  * @param arg Argument (ui_demo_t *)
    2434  */
    2435 static void save_as_dialog_bcancel(ui_file_dialog_t *dialog, void *arg)
    2436 {
    2437         edit_t *edit = (edit_t *)arg;
    2438         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2439 
    2440         ui_file_dialog_destroy(dialog);
    2441         // TODO Smarter cursor management
    2442         pane.rflags |= REDRAW_CARET;
    2443         (void) pane_update(&pane);
    2444         gfx_cursor_set_visible(gc, true);
    2445 }
    2446 
    2447 /** Save As dialog close request.
    2448  *
    2449  * @param dialog File dialog
    2450  * @param arg Argument (ui_demo_t *)
    2451  */
    2452 static void save_as_dialog_close(ui_file_dialog_t *dialog, void *arg)
    2453 {
    2454         edit_t *edit = (edit_t *)arg;
    2455         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2456 
    2457         ui_file_dialog_destroy(dialog);
    2458         // TODO Smarter cursor management
    2459         pane.rflags |= REDRAW_CARET;
    2460         (void) pane_update(&pane);
    2461         gfx_cursor_set_visible(gc, true);
    2462 }
    2463 
    2464 /** Go To Line dialog OK button press.
    2465  *
    2466  * @param dialog Go To Line dialog
    2467  * @param arg Argument (ui_demo_t *)
    2468  * @param text Submitted text
    2469  */
    2470 static void go_to_line_dialog_bok(ui_prompt_dialog_t *dialog, void *arg,
    2471     const char *text)
    2472 {
    2473         edit_t *edit = (edit_t *) arg;
    2474         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2475         char *endptr;
    2476         int line;
    2477 
    2478         ui_prompt_dialog_destroy(dialog);
    2479         line = strtol(text, &endptr, 10);
    2480         if (*endptr != '\0') {
    2481                 status_display("Invalid number entered.");
    2482                 return;
    2483         }
    2484 
    2485         caret_move_absolute(line, pane.ideal_column, dir_before, false);
    2486         // TODO Smarter cursor management
    2487         (void) pane_update(&pane);
    2488         gfx_cursor_set_visible(gc, true);
    2489         (void) gfx_update(gc);
    2490 }
    2491 
    2492 /** Go To Line dialog cancel button press.
    2493  *
    2494  * @param dialog File dialog
    2495  * @param arg Argument (ui_demo_t *)
    2496  */
    2497 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg)
    2498 {
    2499         edit_t *edit = (edit_t *) arg;
    2500         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2501 
    2502         ui_prompt_dialog_destroy(dialog);
    2503         // TODO Smarter cursor management
    2504         pane.rflags |= REDRAW_CARET;
    2505         (void) pane_update(&pane);
    2506         gfx_cursor_set_visible(gc, true);
    2507 }
    2508 
    2509 /** Go To Line dialog close request.
    2510  *
    2511  * @param dialog File dialog
    2512  * @param arg Argument (ui_demo_t *)
    2513  */
    2514 static void go_to_line_dialog_close(ui_prompt_dialog_t *dialog, void *arg)
    2515 {
    2516         edit_t *edit = (edit_t *) arg;
    2517         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2518 
    2519         ui_prompt_dialog_destroy(dialog);
    2520         // TODO Smarter cursor management
    2521         pane.rflags |= REDRAW_CARET;
    2522         (void) pane_update(&pane);
    2523         gfx_cursor_set_visible(gc, true);
    2524 }
    2525 
    2526 /** Search dialog OK button press.
    2527  *
    2528  * @param dialog Search dialog
    2529  * @param arg Argument (ui_demo_t *)
    2530  * @param text Submitted text
    2531  */
    2532 static void search_dialog_bok(ui_prompt_dialog_t *dialog, void *arg,
    2533     const char *text)
    2534 {
    2535         edit_t *edit = (edit_t *) arg;
    2536         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2537         char *pattern;
    2538         bool reverse;
    2539 
    2540         ui_prompt_dialog_destroy(dialog);
    2541 
    2542         /* Abort if search phrase is empty */
    2543         if (text[0] == '\0')
    2544                 return;
    2545 
    2546         pattern = str_dup(text);
    2547         reverse = pane.search_reverse;
    2548 
    2549         if (pane.previous_search)
    2550                 free(pane.previous_search);
    2551         pane.previous_search = pattern;
    2552         pane.previous_search_reverse = reverse;
    2553 
    2554         search(pattern, reverse);
    2555 
    2556         // TODO Smarter cursor management
    2557         (void) pane_update(&pane);
    2558         gfx_cursor_set_visible(gc, true);
    2559         (void) gfx_update(gc);
    2560 }
    2561 
    2562 /** Search dialog cancel button press.
    2563  *
    2564  * @param dialog File dialog
    2565  * @param arg Argument (ui_demo_t *)
    2566  */
    2567 static void search_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg)
    2568 {
    2569         edit_t *edit = (edit_t *) arg;
    2570         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2571 
    2572         ui_prompt_dialog_destroy(dialog);
    2573         // TODO Smarter cursor management
    2574         pane.rflags |= REDRAW_CARET;
    2575         (void) pane_update(&pane);
    2576         gfx_cursor_set_visible(gc, true);
    2577 }
    2578 
    2579 /** Search dialog close request.
    2580  *
    2581  * @param dialog File dialog
    2582  * @param arg Argument (ui_demo_t *)
    2583  */
    2584 static void search_dialog_close(ui_prompt_dialog_t *dialog, void *arg)
    2585 {
    2586         edit_t *edit = (edit_t *) arg;
    2587         gfx_context_t *gc = ui_window_get_gc(edit->window);
    2588 
    2589         ui_prompt_dialog_destroy(dialog);
    2590         // TODO Smarter cursor management
    2591         pane.rflags |= REDRAW_CARET;
    2592         (void) pane_update(&pane);
    2593         gfx_cursor_set_visible(gc, true);
    25941730}
    25951731
Note: See TracChangeset for help on using the changeset viewer.