Ignore:
File:
1 edited

Legend:

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

    rcd82bb1 rb67c7d64  
    4545#include <align.h>
    4646#include <macros.h>
    47 #include <clipboard.h>
    4847#include <bool.h>
    4948
     
    7574        tag_t caret_pos;
    7675
    77         /** Start of selection */
    78         tag_t sel_start;
    79 
    8076        /**
    8177         * Ideal column where the caret should try to get. This is used
     
    111107static void key_handle_unmod(console_event_t const *ev);
    112108static void key_handle_ctrl(console_event_t const *ev);
    113 static void key_handle_shift(console_event_t const *ev);
    114 static void key_handle_movement(unsigned int key, bool shift);
    115 
    116109static int file_save(char const *fname);
    117110static void file_save_as(void);
     
    120113    spt_t const *epos);
    121114static char *filename_prompt(char const *prompt, char const *init_value);
    122 static char *range_get_str(spt_t const *spos, spt_t const *epos);
    123 
    124115static void pane_text_display(void);
    125116static void pane_row_display(void);
     
    127118static void pane_status_display(void);
    128119static void pane_caret_display(void);
    129 
    130120static void insert_char(wchar_t c);
    131121static void delete_char_before(void);
     
    133123static void caret_update(void);
    134124static void caret_move(int drow, int dcolumn, enum dir_spec align_dir);
    135 
    136 static bool selection_active(void);
    137 static void selection_sel_all(void);
    138 static void selection_get_points(spt_t *pa, spt_t *pb);
    139 static void selection_delete(void);
    140 static void selection_copy(void);
    141 static void insert_clipboard_data(void);
    142 
    143125static void pt_get_sof(spt_t *pt);
    144126static void pt_get_eof(spt_t *pt);
    145 static int tag_cmp(tag_t const *a, tag_t const *b);
    146 static int spt_cmp(spt_t const *a, spt_t const *b);
    147 static int coord_cmp(coord_t const *a, coord_t const *b);
    148 
    149127static void status_display(char const *str);
    150128
     
    194172        caret_move(-ED_INFTY, -ED_INFTY, dir_before);
    195173
    196         /* Place selection start tag. */
    197         tag_get_pt(&pane.caret_pos, &pt);
    198         sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
    199 
    200174        /* Initial display */
    201175        console_clear(con);
     
    216190                        /* Handle key press. */
    217191                        if (((ev.mods & KM_ALT) == 0) &&
    218                             ((ev.mods & KM_SHIFT) == 0) &&
    219192                             (ev.mods & KM_CTRL) != 0) {
    220193                                key_handle_ctrl(&ev);
    221                         } else if (((ev.mods & KM_ALT) == 0) &&
    222                             ((ev.mods & KM_CTRL) == 0) &&
    223                              (ev.mods & KM_SHIFT) != 0) {
    224                                 key_handle_shift(&ev);
    225                         } else if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
     194                        } else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) {
    226195                                key_handle_unmod(&ev);
    227196                        }
     
    238207                if (pane.rflags & REDRAW_CARET)
    239208                        pane_caret_display();
     209                       
    240210        }
    241211
     
    250220        switch (ev->key) {
    251221        case KC_ENTER:
    252                 selection_delete();
    253222                insert_char('\n');
    254223                caret_update();
    255224                break;
    256225        case KC_LEFT:
     226                caret_move(0, -1, dir_before);
     227                break;
    257228        case KC_RIGHT:
     229                caret_move(0, 0, dir_after);
     230                break;
    258231        case KC_UP:
     232                caret_move(-1, 0, dir_before);
     233                break;
    259234        case KC_DOWN:
     235                caret_move(+1, 0, dir_before);
     236                break;
    260237        case KC_HOME:
     238                caret_move(0, -ED_INFTY, dir_before);
     239                break;
    261240        case KC_END:
     241                caret_move(0, +ED_INFTY, dir_before);
     242                break;
    262243        case KC_PAGE_UP:
     244                caret_move(-pane.rows, 0, dir_before);
     245                break;
    263246        case KC_PAGE_DOWN:
    264                 key_handle_movement(ev->key, false);
     247                caret_move(+pane.rows, 0, dir_before);
    265248                break;
    266249        case KC_BACKSPACE:
    267                 if (selection_active())
    268                         selection_delete();
    269                 else
    270                         delete_char_before();
     250                delete_char_before();
    271251                caret_update();
    272252                break;
    273253        case KC_DELETE:
    274                 if (selection_active())
    275                         selection_delete();
    276                 else
    277                         delete_char_after();
     254                delete_char_after();
    278255                caret_update();
    279256                break;
    280257        default:
    281258                if (ev->c >= 32 || ev->c == '\t') {
    282                         selection_delete();
    283                         insert_char(ev->c);
    284                         caret_update();
    285                 }
    286                 break;
    287         }
    288 }
    289 
    290 /** Handle Shift-key combination. */
    291 static void key_handle_shift(console_event_t const *ev)
    292 {
    293         switch (ev->key) {
    294         case KC_LEFT:
    295         case KC_RIGHT:
    296         case KC_UP:
    297         case KC_DOWN:
    298         case KC_HOME:
    299         case KC_END:
    300         case KC_PAGE_UP:
    301         case KC_PAGE_DOWN:
    302                 key_handle_movement(ev->key, true);
    303                 break;
    304         default:
    305                 if (ev->c >= 32 || ev->c == '\t') {
    306                         selection_delete();
    307259                        insert_char(ev->c);
    308260                        caret_update();
     
    328280                file_save_as();
    329281                break;
    330         case KC_C:
    331                 selection_copy();
    332                 break;
    333         case KC_V:
    334                 selection_delete();
    335                 insert_clipboard_data();
    336                 pane.rflags |= REDRAW_TEXT;
    337                 caret_update();
    338                 break;
    339         case KC_X:
    340                 selection_copy();
    341                 selection_delete();
    342                 pane.rflags |= REDRAW_TEXT;
    343                 caret_update();
    344                 break;
    345         case KC_A:
    346                 selection_sel_all();
    347                 break;
    348282        default:
    349283                break;
    350         }
    351 }
    352 
    353 static void key_handle_movement(unsigned int key, bool select)
    354 {
    355         spt_t pt;
    356         spt_t caret_pt;
    357         coord_t c_old, c_new;
    358         bool had_sel;
    359 
    360         /* Check if we had selection before. */
    361         tag_get_pt(&pane.caret_pos, &caret_pt);
    362         tag_get_pt(&pane.sel_start, &pt);
    363         had_sel = !spt_equal(&caret_pt, &pt);
    364 
    365         switch (key) {
    366         case KC_LEFT:
    367                 caret_move(0, -1, dir_before);
    368                 break;
    369         case KC_RIGHT:
    370                 caret_move(0, 0, dir_after);
    371                 break;
    372         case KC_UP:
    373                 caret_move(-1, 0, dir_before);
    374                 break;
    375         case KC_DOWN:
    376                 caret_move(+1, 0, dir_before);
    377                 break;
    378         case KC_HOME:
    379                 caret_move(0, -ED_INFTY, dir_before);
    380                 break;
    381         case KC_END:
    382                 caret_move(0, +ED_INFTY, dir_before);
    383                 break;
    384         case KC_PAGE_UP:
    385                 caret_move(-pane.rows, 0, dir_before);
    386                 break;
    387         case KC_PAGE_DOWN:
    388                 caret_move(+pane.rows, 0, dir_before);
    389                 break;
    390         default:
    391                 break;
    392         }
    393 
    394         if (select == false) {
    395                 /* Move sel_start to the same point as caret. */
    396                 sheet_remove_tag(&doc.sh, &pane.sel_start);
    397                 tag_get_pt(&pane.caret_pos, &pt);
    398                 sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
    399         }
    400 
    401         if (select) {
    402                 tag_get_pt(&pane.caret_pos, &pt);
    403                 spt_get_coord(&caret_pt, &c_old);
    404                 spt_get_coord(&pt, &c_new);
    405 
    406                 if (c_old.row == c_new.row)
    407                         pane.rflags |= REDRAW_ROW;
    408                 else
    409                         pane.rflags |= REDRAW_TEXT;
    410 
    411         } else if (had_sel == true) {
    412                 /* Redraw because text was unselected. */
    413                 pane.rflags |= REDRAW_TEXT;
    414284        }
    415285}
     
    603473}
    604474
    605 /** Return contents of range as a new string. */
    606 static char *range_get_str(spt_t const *spos, spt_t const *epos)
    607 {
    608         char *buf;
    609         spt_t sp, bep;
    610         size_t bytes;
    611         size_t buf_size, bpos;
    612 
    613         buf_size = 1;
    614 
    615         buf = malloc(buf_size);
    616         if (buf == NULL)
    617                 return NULL;
    618 
    619         bpos = 0;
    620         sp = *spos;
    621 
    622         while (true) {
    623                 sheet_copy_out(&doc.sh, &sp, epos, &buf[bpos], buf_size - bpos,
    624                     &bep);
    625                 bytes = str_size(&buf[bpos]);
    626                 bpos += bytes;
    627                 sp = bep;
    628 
    629                 if (spt_equal(&bep, epos))
    630                         break;
    631 
    632                 buf_size *= 2;
    633                 buf = realloc(buf, buf_size);
    634                 if (buf == NULL)
    635                         return NULL;
    636         }
    637 
    638         return buf;
    639 }
    640 
    641475static void pane_text_display(void)
    642476{
     
    683517{
    684518        int i, j, fill;
    685         spt_t rb, re, dep, pt;
     519        spt_t rb, re, dep;
    686520        coord_t rbc, rec;
    687521        char row_buf[ROW_BUF_SIZE];
     
    689523        size_t pos, size;
    690524        unsigned s_column;
    691         coord_t csel_start, csel_end, ctmp;
    692 
    693         /* Determine selection start and end. */
    694 
    695         tag_get_pt(&pane.sel_start, &pt);
    696         spt_get_coord(&pt, &csel_start);
    697 
    698         tag_get_pt(&pane.caret_pos, &pt);
    699         spt_get_coord(&pt, &csel_end);
    700 
    701         if (coord_cmp(&csel_start, &csel_end) > 0) {
    702                 ctmp = csel_start;
    703                 csel_start = csel_end;
    704                 csel_end = ctmp;
    705         }
    706525
    707526        /* Draw rows from the sheet. */
     
    724543                /* Display text from the buffer. */
    725544
    726                 if (coord_cmp(&csel_start, &rbc) <= 0 &&
    727                     coord_cmp(&rbc, &csel_end) < 0) {
    728                         fflush(stdout);
    729                         console_set_color(con, COLOR_BLACK, COLOR_RED, 0);
    730                         fflush(stdout);
    731                 }
    732 
    733545                console_goto(con, 0, i);
    734546                size = str_size(row_buf);
    735547                pos = 0;
    736                 s_column = pane.sh_column;
     548                s_column = 1;
    737549                while (pos < size) {
    738                         if (csel_start.row == rbc.row && csel_start.column == s_column) {
    739                                 fflush(stdout);
    740                                 console_set_color(con, COLOR_BLACK, COLOR_RED, 0);
    741                                 fflush(stdout);
    742                         }
    743        
    744                         if (csel_end.row == rbc.row && csel_end.column == s_column) {
    745                                 fflush(stdout);
    746                                 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
    747                                 fflush(stdout);
    748                         }
    749        
    750550                        c = str_decode(row_buf, &pos, size);
    751551                        if (c != '\t') {
     
    762562                }
    763563
    764                 if (csel_end.row == rbc.row && csel_end.column == s_column) {
    765                         fflush(stdout);
    766                         console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
    767                         fflush(stdout);
    768                 }
    769 
    770564                /* Fill until the end of display area. */
    771565
     
    778572                        putchar(' ');
    779573                fflush(stdout);
    780                 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
    781574        }
    782575
     
    967760}
    968761
    969 /** Check for non-empty selection. */
    970 static bool selection_active(void)
    971 {
    972         return (tag_cmp(&pane.caret_pos, &pane.sel_start) != 0);
    973 }
    974 
    975 static void selection_get_points(spt_t *pa, spt_t *pb)
    976 {
    977         spt_t pt;
    978 
    979         tag_get_pt(&pane.sel_start, pa);
    980         tag_get_pt(&pane.caret_pos, pb);
    981 
    982         if (spt_cmp(pa, pb) > 0) {
    983                 pt = *pa;
    984                 *pa = *pb;
    985                 *pb = pt;
    986         }
    987 }
    988 
    989 /** Delete selected text. */
    990 static void selection_delete(void)
    991 {
    992         spt_t pa, pb;
    993         coord_t ca, cb;
    994         int rel;
    995 
    996         tag_get_pt(&pane.sel_start, &pa);
    997         tag_get_pt(&pane.caret_pos, &pb);
    998         spt_get_coord(&pa, &ca);
    999         spt_get_coord(&pb, &cb);
    1000         rel = coord_cmp(&ca, &cb);
    1001 
    1002         if (rel == 0)
    1003                 return;
    1004 
    1005         if (rel < 0)
    1006                 sheet_delete(&doc.sh, &pa, &pb);
    1007         else
    1008                 sheet_delete(&doc.sh, &pb, &pa);
    1009 
    1010         if (ca.row == cb.row)
    1011                 pane.rflags |= REDRAW_ROW;
    1012         else
    1013                 pane.rflags |= REDRAW_TEXT;
    1014 }
    1015 
    1016 static void selection_sel_all(void)
    1017 {
    1018         spt_t spt, ept;
    1019 
    1020         pt_get_sof(&spt);
    1021         pt_get_eof(&ept);
    1022         sheet_remove_tag(&doc.sh, &pane.sel_start);
    1023         sheet_place_tag(&doc.sh, &spt, &pane.sel_start);
    1024         sheet_remove_tag(&doc.sh, &pane.caret_pos);
    1025         sheet_place_tag(&doc.sh, &ept, &pane.caret_pos);
    1026 
    1027         pane.rflags |= REDRAW_TEXT;
    1028         caret_update();
    1029 }
    1030 
    1031 static void selection_copy(void)
    1032 {
    1033         spt_t pa, pb;
    1034         char *str;
    1035 
    1036         selection_get_points(&pa, &pb);
    1037         str = range_get_str(&pa, &pb);
    1038         if (str == NULL || clipboard_put_str(str) != EOK) {
    1039                 status_display("Copying to clipboard failed!");
    1040         }
    1041         free(str);
    1042 }
    1043 
    1044 static void insert_clipboard_data(void)
    1045 {
    1046         char *str;
    1047         size_t off;
    1048         wchar_t c;
    1049         int rc;
    1050 
    1051         rc = clipboard_get_str(&str);
    1052         if (rc != EOK || str == NULL)
    1053                 return;
    1054 
    1055         off = 0;
    1056 
    1057         while (true) {
    1058                 c = str_decode(str, &off, STR_NO_LIMIT);
    1059                 if (c == '\0')
    1060                         break;
    1061 
    1062                 insert_char(c);
    1063         }
    1064 
    1065         free(str);
    1066 }
    1067762
    1068763/** Get start-of-file s-point. */
     
    1086781
    1087782        sheet_get_cell_pt(&doc.sh, &coord, dir_after, pt);
    1088 }
    1089 
    1090 /** Compare tags. */
    1091 static int tag_cmp(tag_t const *a, tag_t const *b)
    1092 {
    1093         spt_t pa, pb;
    1094 
    1095         tag_get_pt(a, &pa);
    1096         tag_get_pt(b, &pb);
    1097 
    1098         return spt_cmp(&pa, &pb);
    1099 }
    1100 
    1101 /** Compare s-points. */
    1102 static int spt_cmp(spt_t const *a, spt_t const *b)
    1103 {
    1104         coord_t ca, cb;
    1105 
    1106         spt_get_coord(a, &ca);
    1107         spt_get_coord(b, &cb);
    1108 
    1109         return coord_cmp(&ca, &cb);
    1110 }
    1111 
    1112 /** Compare coordinats. */
    1113 static int coord_cmp(coord_t const *a, coord_t const *b)
    1114 {
    1115         if (a->row - b->row != 0)
    1116                 return a->row - b->row;
    1117 
    1118         return a->column - b->column;
    1119783}
    1120784
Note: See TracChangeset for help on using the changeset viewer.