Ignore:
File:
1 edited

Legend:

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

    rec50d65e r87822ce  
    11/*
    2  * Copyright (c) 2024 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/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>
    68 #include <vfs/vfs.h>
    6951
    7052#include "sheet.h"
     
    8163 *
    8264 * A rectangular area of the screen used to edit a document. Different
    83  * panes can be possibly used to edit the same document. This is a custom
    84  * UI control.
     65 * panes can be possibly used to edit the same document.
    8566 */
    8667typedef 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 
    10568        /* Pane dimensions */
    10669        int rows, columns;
     
    12790        int ideal_column;
    12891
    129         bool search_reverse;
    13092        char *previous_search;
    13193        bool previous_search_reverse;
    13294} pane_t;
    133 
    134 /** Text editor */
    135 typedef struct {
    136         /** User interface */
    137         ui_t *ui;
    138         /** Editor window */
    139         ui_window_t *window;
    140         /** UI resource */
    141         ui_resource_t *ui_res;
    142         /** Menu bar */
    143         ui_menu_bar_t *menubar;
    144         /** Status bar */
    145         ui_label_t *status;
    146 } edit_t;
    14795
    14896/** Document
     
    155103} doc_t;
    156104
    157 static edit_t edit;
     105static console_ctrl_t *con;
    158106static doc_t doc;
     107static bool done;
    159108static pane_t pane;
     109static bool cursor_visible;
     110
     111static sysarg_t scr_rows;
     112static sysarg_t scr_columns;
    160113
    161114#define ROW_BUF_SIZE 4096
     
    166119#define INFNAME_MAX_LEN 128
    167120
     121static void cursor_show(void);
     122static void cursor_hide(void);
    168123static void cursor_setvis(bool visible);
    169124
     
    184139static char *range_get_str(spt_t const *spos, spt_t const *epos);
    185140
    186 static errno_t pane_init(ui_window_t *, pane_t *);
    187 static void pane_fini(pane_t *);
    188 static ui_control_t *pane_ctl(pane_t *);
    189 static errno_t pane_update(pane_t *);
    190 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);
    191144static void pane_row_display(void);
    192 static errno_t pane_row_range_display(pane_t *, int r0, int r1);
    193 static void pane_status_display(pane_t *);
    194 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);
    195148
    196149static void insert_char(char32_t c);
     
    211164static void selection_delete(void);
    212165static void selection_copy(void);
    213 static void edit_cut(void);
    214 static void edit_paste(void);
    215166static void insert_clipboard_data(void);
    216167
     
    234185
    235186static void status_display(char const *str);
    236 static errno_t edit_ui_create(edit_t *);
    237 static void edit_ui_destroy(edit_t *);
    238 
    239 static void edit_wnd_close(ui_window_t *, void *);
    240 static void edit_wnd_focus(ui_window_t *, void *, unsigned);
    241 static void edit_wnd_kbd_event(ui_window_t *, void *, kbd_event_t *);
    242 static void edit_wnd_unfocus(ui_window_t *, void *, unsigned);
    243 
    244 static 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 
    251 static void edit_menubar_activate(ui_menu_bar_t *, void *);
    252 static void edit_menubar_deactivate(ui_menu_bar_t *, void *);
    253 
    254 static ui_menu_bar_cb_t edit_menubar_cb = {
    255         .activate = edit_menubar_activate,
    256         .deactivate = edit_menubar_deactivate
    257 };
    258 
    259 static void edit_file_save(ui_menu_entry_t *, void *);
    260 static void edit_file_save_as(ui_menu_entry_t *, void *);
    261 static void edit_file_exit(ui_menu_entry_t *, void *);
    262 static void edit_edit_cut(ui_menu_entry_t *, void *);
    263 static void edit_edit_copy(ui_menu_entry_t *, void *);
    264 static void edit_edit_paste(ui_menu_entry_t *, void *);
    265 static void edit_edit_delete(ui_menu_entry_t *, void *);
    266 static void edit_edit_select_all(ui_menu_entry_t *, void *);
    267 static void edit_search_find(ui_menu_entry_t *, void *);
    268 static void edit_search_reverse_find(ui_menu_entry_t *, void *);
    269 static void edit_search_find_next(ui_menu_entry_t *, void *);
    270 static void edit_search_go_to_line(ui_menu_entry_t *, void *);
    271 
    272 static void pane_ctl_destroy(void *);
    273 static errno_t pane_ctl_paint(void *);
    274 static ui_evclaim_t pane_ctl_pos_event(void *, pos_event_t *);
    275 
    276 /** Pabe control ops */
    277 ui_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 
    283 static void save_as_dialog_bok(ui_file_dialog_t *, void *, const char *);
    284 static void save_as_dialog_bcancel(ui_file_dialog_t *, void *);
    285 static void save_as_dialog_close(ui_file_dialog_t *, void *);
    286 
    287 static 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 
    293 static void go_to_line_dialog_bok(ui_prompt_dialog_t *, void *, const char *);
    294 static void go_to_line_dialog_bcancel(ui_prompt_dialog_t *, void *);
    295 static void go_to_line_dialog_close(ui_prompt_dialog_t *, void *);
    296 
    297 static 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 
    303 static void search_dialog_bok(ui_prompt_dialog_t *, void *, const char *);
    304 static void search_dialog_bcancel(ui_prompt_dialog_t *, void *);
    305 static void search_dialog_close(ui_prompt_dialog_t *, void *);
    306 
    307 static ui_prompt_dialog_cb_t search_dialog_cb = {
    308         .bok = search_dialog_bok,
    309         .bcancel = search_dialog_bcancel,
    310         .close =  search_dialog_close
    311 };
    312187
    313188int main(int argc, char *argv[])
    314189{
     190        cons_event_t ev;
    315191        bool new_file;
    316192        errno_t rc;
    317193
     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;
    318201        pane.sh_row = 1;
    319202        pane.sh_column = 1;
     
    351234        /* Move to beginning of file. */
    352235        pt_get_sof(&sof);
    353 
    354         /* Create UI */
    355         rc = edit_ui_create(&edit);
    356         if (rc != EOK)
    357                 return 1;
    358 
    359236        caret_move(sof, true, true);
    360237
    361238        /* Initial 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);
     239        cursor_visible = true;
     240
     241        cursor_hide();
     242        console_clear(con);
     243        pane_text_display();
     244        pane_status_display();
    369245        if (new_file && doc.file_name != NULL)
    370246                status_display("File not found. Starting empty file.");
    371         pane_caret_display(&pane);
    372         cursor_setvis(true);
    373 
    374         ui_run(edit.ui);
    375 
    376         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
    377288        return 0;
    378 }
    379 
    380 /** Create text editor UI.
    381  *
    382  * @param edit Editor
    383  * @return EOK on success or an error code
    384  */
    385 static 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;
    623 error:
    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  */
    635 static void edit_ui_destroy(edit_t *edit)
    636 {
    637         ui_window_destroy(edit->window);
    638         ui_destroy(edit->ui);
    639289}
    640290
     
    659309}
    660310
     311static void cursor_show(void)
     312{
     313        cursor_setvis(true);
     314}
     315
     316static void cursor_hide(void)
     317{
     318        cursor_setvis(false);
     319}
     320
    661321static void cursor_setvis(bool visible)
    662322{
    663         gfx_context_t *gc = ui_window_get_gc(edit.window);
    664 
    665         (void) gfx_cursor_set_visible(gc, visible);
     323        if (cursor_visible != visible) {
     324                console_cursor_visibility(con, visible);
     325                cursor_visible = visible;
     326        }
    666327}
    667328
     
    739400        switch (ev->key) {
    740401        case KC_Q:
    741                 ui_quit(edit.ui);
     402                done = true;
    742403                break;
    743404        case KC_S:
     
    754415                break;
    755416        case KC_V:
    756                 edit_paste();
     417                selection_delete();
     418                insert_clipboard_data();
     419                pane.rflags |= REDRAW_TEXT;
     420                caret_update();
    757421                break;
    758422        case KC_X:
    759                 edit_cut();
     423                selection_copy();
     424                selection_delete();
     425                pane.rflags |= REDRAW_TEXT;
     426                caret_update();
    760427                break;
    761428        case KC_A:
     
    823490
    824491        if (ev->type == POS_PRESS && ev->vpos < (unsigned)pane.rows) {
    825                 bc.row = pane.sh_row + ev->vpos - pane.rect.p0.y;
    826                 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;
    827494                sheet_get_cell_pt(doc.sh, &bc, dir_before, &pt);
    828495
     
    830497
    831498                caret_move(pt, select, true);
    832                 pane_update(&pane);
    833499        }
    834500}
     
    940606}
    941607
    942 /** Open Save As dialog. */
     608/** Change document name and save. */
    943609static void file_save_as(void)
    944610{
    945611        const char *old_fname = (doc.file_name != NULL) ? doc.file_name : "";
    946         ui_file_dialog_params_t fdparams;
    947         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;
    948639        errno_t rc;
    949640
    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");
    957                 return;
    958         }
    959 
    960         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;
    961694}
    962695
     
    993726
    994727                bcnt -= off;
    995                 memmove(buf, buf + off, bcnt);
     728                memcpy(buf, buf + off, bcnt);
    996729
    997730                insert_char(c);
     
    1075808}
    1076809
    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  */
    1085 static 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;
    1119 error:
    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  */
    1139 static 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  */
    1154 static 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  */
    1164 static 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  */
    1193 static errno_t pane_text_display(pane_t *pane)
    1194 {
    1195         gfx_rect_t rect;
    1196         gfx_context_t *gc;
    1197         errno_t rc;
     810static void pane_text_display(void)
     811{
    1198812        int sh_rows, rows;
    1199813
    1200814        sheet_get_num_rows(doc.sh, &sh_rows);
    1201         rows = min(sh_rows - pane->sh_row + 1, pane->rows);
     815        rows = min(sh_rows - pane.sh_row + 1, pane.rows);
    1202816
    1203817        /* Draw rows from the sheet. */
    1204818
    1205         rc = pane_row_range_display(pane, 0, rows);
    1206         if (rc != EOK)
    1207                 return rc;
     819        console_set_pos(con, 0, 0);
     820        pane_row_range_display(0, rows);
    1208821
    1209822        /* Clear the remaining rows if file is short. */
    1210823
    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;
    1228 error:
    1229         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;
    1230835}
    1231836
     
    1241846
    1242847        ridx = coord.row - pane.sh_row;
    1243         (void) pane_row_range_display(&pane, ridx, ridx + 1);
     848        pane_row_range_display(ridx, ridx + 1);
    1244849        pane.rflags |= (REDRAW_STATUS | REDRAW_CARET);
    1245850}
    1246851
    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  */
    1253 static errno_t pane_row_range_display(pane_t *pane, int r0, int r1)
    1254 {
    1255         int i, fill;
     852static void pane_row_range_display(int r0, int r1)
     853{
     854        int i, j, fill;
    1256855        spt_t rb, re, dep, pt;
    1257856        coord_t rbc, rec;
    1258857        char row_buf[ROW_BUF_SIZE];
    1259         char cbuf[STR_BOUNDS(1) + 1];
    1260858        char32_t c;
    1261859        size_t pos, size;
    1262         size_t cpos;
    1263860        int s_column;
    1264861        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;
    1278862
    1279863        /* Determine selection start and end. */
    1280864
    1281         tag_get_pt(&pane->sel_start, &pt);
     865        tag_get_pt(&pane.sel_start, &pt);
    1282866        spt_get_coord(&pt, &csel_start);
    1283867
    1284         tag_get_pt(&pane->caret_pos, &pt);
     868        tag_get_pt(&pane.caret_pos, &pt);
    1285869        spt_get_coord(&pt, &csel_end);
    1286870
     
    1293877        /* Draw rows from the sheet. */
    1294878
     879        console_set_pos(con, 0, 0);
    1295880        for (i = r0; i < r1; ++i) {
    1296                 tpos.x = pane->rect.p0.x;
    1297                 tpos.y = pane->rect.p0.y + i;
    1298 
    1299881                /* Starting point for row display */
    1300                 rbc.row = pane->sh_row + i;
    1301                 rbc.column = pane->sh_column;
     882                rbc.row = pane.sh_row + i;
     883                rbc.column = pane.sh_column;
    1302884                sheet_get_cell_pt(doc.sh, &rbc, dir_before, &rb);
    1303885
    1304886                /* Ending point for row display */
    1305                 rec.row = pane->sh_row + i;
    1306                 rec.column = pane->sh_column + pane->columns;
     887                rec.row = pane.sh_row + i;
     888                rec.column = pane.sh_column + pane.columns;
    1307889                sheet_get_cell_pt(doc.sh, &rec, dir_before, &re);
    1308890
     
    1314896                if (coord_cmp(&csel_start, &rbc) <= 0 &&
    1315897                    coord_cmp(&rbc, &csel_end) < 0) {
    1316                         fmt.color = pane->sel_color;
     898                        console_flush(con);
     899                        console_set_style(con, STYLE_SELECTED);
     900                        console_flush(con);
    1317901                }
    1318902
     903                console_set_pos(con, 0, i);
    1319904                size = str_size(row_buf);
    1320905                pos = 0;
    1321                 s_column = pane->sh_column;
     906                s_column = pane.sh_column;
    1322907                while (pos < size) {
    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;
     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                        }
    1328919
    1329920                        c = str_decode(row_buf, &pos, size);
    1330921                        if (c != '\t') {
    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 
     922                                printf("%lc", (wint_t) c);
    1340923                                s_column += 1;
    1341                                 tpos.x++;
    1342924                        } else {
    1343925                                fill = 1 + ALIGN_UP(s_column, TAB_WIDTH) -
    1344926                                    s_column;
    1345927
    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 
     928                                for (j = 0; j < fill; ++j)
     929                                        putchar(' ');
    1359930                                s_column += fill;
    1360                                 tpos.x += fill;
    1361931                        }
    1362932                }
    1363933
    1364                 if ((csel_end.row == rbc.row) && (csel_end.column == s_column))
    1365                         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                }
    1366939
    1367940                /* Fill until the end of display area. */
    1368941
    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  */
    1390 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)
    1391958{
    1392959        spt_t caret_pt;
     
    1397964        char *text;
    1398965        size_t n;
     966        int pos;
    1399967        size_t nextra;
    1400968        size_t fnw;
    1401969
    1402         tag_get_pt(&pane->caret_pos, &caret_pt);
     970        tag_get_pt(&pane.caret_pos, &caret_pt);
    1403971        spt_get_coord(&caret_pt, &coord);
    1404972
     
    1419987                return;
    1420988
     989        console_set_pos(con, 0, scr_rows - 1);
     990        console_set_style(con, STYLE_INVERTED);
     991
    1421992        /*
    1422993         * Make sure the status fits on the screen. This loop should
     
    1424995         */
    1425996        while (true) {
    1426                 int rc = asprintf(&text, "%d, %d (%d): File '%s'. Ctrl-Q Quit  "
    1427                     "F10 Menu", coord.row, coord.column, last_row, fname);
     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);
    1428999                if (rc < 0) {
    14291000                        n = 0;
     
    14331004                /* If it already fits, we're done */
    14341005                n = str_width(text);
    1435                 if ((int)n <= pane->columns - 2)
     1006                if (n <= scr_columns - 2)
    14361007                        break;
    14371008
    14381009                /* Compute number of excess characters */
    1439                 nextra = n - (pane->columns - 2);
     1010                nextra = n - (scr_columns - 2);
    14401011                /** With of the file name part */
    14411012                fnw = str_width(fname);
     
    14451016                 * just give up and print a blank status.
    14461017                 */
    1447                 if (nextra > fnw - 2) {
    1448                         text[0] = '\0';
     1018                if (nextra > fnw - 2)
    14491019                        goto finish;
    1450                 }
    14511020
    14521021                /* Compute position where we overwrite with '..\0' */
     
    14651034        }
    14661035
    1467 finish:
    1468         (void) ui_label_set_text(edit.status, text);
    1469         (void) ui_label_paint(edit.status);
     1036        printf("%s", text);
    14701037        free(text);
    14711038        free(fname);
    1472 }
    1473 
    1474 /** Set cursor to reflect position of the caret.
    1475  *
    1476  * @param pane Pane
    1477  */
    1478 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)
    14791051{
    14801052        spt_t caret_pt;
    14811053        coord_t coord;
    1482         gfx_coord2_t pos;
    1483         gfx_context_t *gc;
    1484 
    1485         tag_get_pt(&pane->caret_pos, &caret_pt);
     1054
     1055        tag_get_pt(&pane.caret_pos, &caret_pt);
    14861056
    14871057        spt_get_coord(&caret_pt, &coord);
    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  */
    1500 static 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  */
    1511 static 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 
    1527 error:
    1528         return rc;
    1529 }
    1530 
    1531 /** Handle pane control position event.
    1532  *
    1533  * @param arg Argument (pane_t *)
    1534  * @param event Position event
    1535  */
    1536 static 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;
     1058        console_set_pos(con, coord.column - pane.sh_column,
     1059            coord.row - pane.sh_row);
    15491060}
    15501061
     
    17591270static void caret_go_to_line_ask(void)
    17601271{
    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");
     1272        char *sline;
     1273
     1274        sline = prompt("Go to line", "");
     1275        if (sline == NULL) {
     1276                status_display("Go to line cancelled.");
    17721277                return;
    17731278        }
    17741279
    1775         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);
    17761290}
    17771291
     
    18301344static void search_prompt(bool reverse)
    18311345{
    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 
     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 = "";
    18411353        if (pane.previous_search)
    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");
     1354                default_value = pane.previous_search;
     1355
     1356        pattern = prompt(prompt_text, default_value);
     1357        if (pattern == NULL) {
     1358                status_display("Search cancelled.");
    18471359                return;
    18481360        }
    18491361
    1850         ui_prompt_dialog_set_cb(dialog, &search_dialog_cb, &edit);
    1851         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);
    18521368}
    18531369
     
    19971513        }
    19981514        free(str);
    1999 }
    2000 
    2001 static 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 
    2009 static void edit_cut(void)
    2010 {
    2011         selection_copy();
    2012         selection_delete();
    2013         pane.rflags |= (REDRAW_TEXT | REDRAW_CARET);
    2014         pane_update(&pane);
    20151515}
    20161516
     
    22191719static void status_display(char const *str)
    22201720{
    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  */
    2230 static 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  */
    2243 static 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  */
    2258 static 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  */
    2279 static 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  */
    2292 static 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  */
    2305 static 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  */
    2319 static 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  */
    2336 static 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  */
    2349 static 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  */
    2361 static 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  */
    2373 static 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  */
    2384 static 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  */
    2396 static void edit_edit_delete(ui_menu_entry_t *mentry, void *arg)
    2397 {
    2398         (void) arg;
    2399 
    2400         if (selection_active())
    2401                 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);
    24021728
    24031729        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  */
    2413 static 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  */
    2428 static 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  */
    2439 static 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  */
    2450 static 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  */
    2463 static 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  */
    2475 static 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  */
    2506 static 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  */
    2519 static 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  */
    2533 static 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  */
    2557 static 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  */
    2570 static 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  */
    2584 static 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  */
    2616 static 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  */
    2629 static 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);
    26351730}
    26361731
Note: See TracChangeset for help on using the changeset viewer.