Ticket #2979: 1_bookmarks_2.2.patch

File 1_bookmarks_2.2.patch, 27.2 KB (added by aurel, 10 years ago)
  • lib/keybind.c

    old new static name_keymap_t command_names[] = { 
    287287    {"SpellCheckCurrentWord", CK_SpellCheckCurrentWord}, 
    288288    {"SpellCheckSelectLang", CK_SpellCheckSelectLang}, 
    289289#endif /* HAVE_ASPELL */ 
     290    {"BookmarkList", CK_BookmarkList}, 
    290291    {"BookmarkFlush", CK_BookmarkFlush}, 
    291292    {"BookmarkNext", CK_BookmarkNext}, 
    292293    {"BookmarkPrev", CK_BookmarkPrev}, 
  • lib/keybind.h

    old new enum 
    243243    CK_BlockShiftRight, 
    244244    CK_DeleteLine, 
    245245    /* bookmarks */ 
     246    CK_BookmarkList, 
    246247    CK_BookmarkFlush, 
    247248    CK_BookmarkNext, 
    248249    CK_BookmarkPrev, 
  • misc/mc.default.keymap

    old new ExternalCommand = alt-u 
    316316UserMenu = f11 
    317317Menu = f9 
    318318Bookmark = alt-k 
     319BookmarkList = alt-shift-k; alt-shift-j 
    319320BookmarkFlush = alt-o 
    320321BookmarkNext = alt-j 
    321322BookmarkPrev = alt-i 
  • misc/mc.emacs.keymap

    old new ExternalCommand = alt-u 
    315315UserMenu = f11 
    316316Menu = f9 
    317317# Bookmark = 
     318# BookmarkList = 
    318319# BookmarkFlush = 
    319320# BookmarkNext = 
    320321# BookmarkPrev = 
  • src/editor/bookmark.c

    old new  
    4444 
    4545#include "lib/global.h" 
    4646#include "lib/util.h"           /* MAX_SAVED_BOOKMARKS */ 
     47#include "lib/strutil.h" 
     48 
     49#include "lib/skin.h"           /* BOOK_MARK_COLOR ... */ 
     50#include "lib/tty/key.h"        /* KEY_M_CTRL */ 
     51#include "lib/tty/tty.h"        /* LINES, COLS */ 
     52 
     53#include "src/setup.h"          /* option_tab_spacing */ 
    4754 
    4855#include "editwidget.h" 
    4956 
     
    5360 
    5461/*** file scope type declarations ****************************************************************/ 
    5562 
     63typedef struct 
     64{ 
     65    edit_book_mark_t *mark; 
     66    char *text; 
     67    int detail_cols; 
     68    char *detail[4]; 
     69} list_entry_t; 
     70 
    5671/*** file scope variables ************************************************************************/ 
    5772 
    5873/*** file scope functions ************************************************************************/ 
    5974/* --------------------------------------------------------------------------------------------- */ 
     75static void list_add_entry (WEdit * edit, WListbox * list, edit_book_mark_t * book_mark, 
     76                            GString * buff, GString * detail); 
    6077 
    6178/** note, if there is more than one bookmark on a line, then they are 
    6279   appended after each other and the last one is always the one found 
    book_mark_find (WEdit * edit, long line) 
    135152    return NULL;                /* can't get here */ 
    136153} 
    137154 
     155#define UX 3 
     156#define UY 2 
     157 
     158#define DLG_H (LINES - 6) 
     159#define DLG_W (COLS > 86 ? 80 : COLS - 6) 
     160 
     161#define LABELS          3 
     162#define B_ADD_NEW       B_USER 
     163#define B_REMOVE        (B_USER + 1) 
     164#define B_FLUSH         (B_USER + 2) 
     165#define B_FILTER        (B_USER + 3) 
     166#define B_SORT          (B_USER + 4) 
     167#define B_REVERSE       (B_USER + 5) 
     168 
     169#define SORT_LINE 0 
     170#define SORT_FREQ 1 
     171#define SORT_ALPHA 2 
     172 
     173#define FILTER_NONE 0 
     174#define FILTER_BOOK 1 
     175#define FILTER_FOUND 2 
     176 
     177static WDialog *list_dlg; 
     178static WGroupbox *list_grp; 
     179static WListbox *list_box; 
     180static WLabel *list_detail; 
     181static WButton *list_sort; 
     182static WButton *list_filter; 
     183static struct 
     184{ 
     185    WEdit *edit; 
     186    GList *hidden; 
     187    int filter;                 /* find/bookmark/all */ 
     188    int sort;                   /* sort by line num/usage/alpha */ 
     189    gboolean reverse;           /* reverse sort */ 
     190} list_cfg = 
     191{ 
     192    /* *INDENT-OFF* */ 
     193    NULL, NULL, FILTER_NONE, SORT_LINE, FALSE 
     194    /* *INDENT-ON* */ 
     195}; 
     196 
     197static struct 
     198{ 
     199    int ret_cmd, flags, y, x, len; 
     200    const char *text; 
     201    widget_pos_flags_t pos_flags; 
     202} list_btn[] = 
     203{ 
     204    /* *INDENT-OFF* */ 
     205    { B_ENTER, DEFPUSH_BUTTON, 0, 0, 0, N_("&Go to"), 
     206            WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, 
     207    { B_ADD_NEW, NORMAL_BUTTON, 0, 12, 0, N_("&Add"), 
     208            WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, 
     209    { B_REMOVE, NORMAL_BUTTON, 0, 20, 0, N_("&Remove"), 
     210            WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, 
     211    { B_FLUSH, NORMAL_BUTTON, 0, 31, 0, N_("Fl&ush"), 
     212            WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, 
     213    { B_CANCEL, NORMAL_BUTTON, 0, -16, 0, N_("&Cancel"), 
     214            WPOS_KEEP_RIGHT | WPOS_KEEP_BOTTOM }, 
     215    { B_FILTER, NORMAL_BUTTON, 1, 0, 0, N_("&Filter"), 
     216            WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, 
     217    { B_SORT, NORMAL_BUTTON, 1, 11, 0, N_("&Sort"), 
     218            WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, 
     219    { B_REVERSE, NORMAL_BUTTON, 1, 20, 0, N_("Re&verse"), 
     220            WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, 
     221    /* *INDENT-ON* */ 
     222}; 
     223 
     224static const size_t list_btn_num = G_N_ELEMENTS (list_btn); 
     225 
     226/* --------------------------------------------------------------------------------------------- */ 
     227 
     228static void 
     229list_entry_free2 (list_entry_t * entry) 
     230{ 
     231    g_free (entry->text); 
     232    g_free (entry->detail[0]); 
     233    g_free (entry->detail[1]); 
     234    g_free (entry->detail[2]); 
     235    g_free (entry); 
     236} 
     237 
     238static gint 
     239list_sort_alpha (gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer user_data) 
     240{ 
     241    return strcmp (((list_entry_t *) ((WLEntry *) a)->data)->text, 
     242                   ((list_entry_t *) ((WLEntry *) b)->data)->text); 
     243} 
     244 
     245static gint 
     246list_sort_freq (gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer user_data) 
     247{ 
     248    int afreq = ((list_entry_t *) ((WLEntry *) a)->data)->mark->freq; 
     249    int bfreq = ((list_entry_t *) ((WLEntry *) b)->data)->mark->freq; 
     250    return afreq > bfreq ? 1 : (afreq < bfreq ? -1 : 0); 
     251} 
     252 
     253static gint 
     254list_sort_line (gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer user_data) 
     255{ 
     256    int aline = ((list_entry_t *) ((WLEntry *) a)->data)->mark->line; 
     257    int bline = ((list_entry_t *) ((WLEntry *) b)->data)->mark->line; 
     258    return aline > bline ? 1 : (aline < bline ? -1 : 0); 
     259} 
     260 
     261static void 
     262list_filter_none (void) 
     263{ 
     264    if (!list_box->list || !list_cfg.hidden) 
     265        return; 
     266 
     267    for (; list_cfg.hidden;) 
     268    { 
     269        GList *next = list_cfg.hidden->next; 
     270        list_cfg.hidden->next = list_cfg.hidden->prev = NULL; 
     271        g_queue_push_tail_link(list_box->list, list_cfg.hidden); 
     272        list_cfg.hidden = next; 
     273    } 
     274} 
     275 
     276static void 
     277list_filter_color (int color) 
     278{ 
     279    guint i, length; 
     280 
     281    list_filter_none (); 
     282 
     283    if (!list_box->list || color == -1) 
     284        return; 
     285 
     286    length = g_queue_get_length(list_box->list); 
     287    for (i = 0; i < length;) 
     288    { 
     289        GList *entry = g_queue_peek_nth_link (list_box->list, i); 
     290        if (!entry) 
     291            continue; 
     292 
     293        if (((list_entry_t *) ((WLEntry *) entry->data)->data)->mark->c != color) 
     294        { 
     295            GList *entry_to_hide = g_queue_pop_nth_link (list_box->list, i); 
     296            list_cfg.hidden = g_list_concat (list_cfg.hidden, entry_to_hide); 
     297            length--; 
     298        } 
     299        else 
     300            i++; 
     301    } 
     302 
     303    // listbox_refresh_list (list_box, list); 
     304} 
     305 
     306/* --------------------------------------------------------------------------------------------- */ 
     307 
     308static void 
     309update_detail (void) 
     310{ 
     311    list_entry_t *entry; 
     312    WListbox *list = list_box; 
     313 
     314    if (list_box->list && g_queue_get_length(list_box->list) != 0) 
     315    { 
     316        char *ctext = NULL; 
     317 
     318        listbox_get_current (list, &ctext, (void **) &entry); 
     319        if (list->widget.cols != entry->detail_cols) 
     320        { 
     321            GString *buff = g_string_new (""); 
     322            g_string_append (buff, str_trunc (entry->detail[0], list->widget.cols - 1)); 
     323            g_string_append (buff, "\n"); 
     324            g_string_append (buff, str_trunc (entry->detail[1], list->widget.cols - 1)); 
     325            g_string_append (buff, "\n"); 
     326            g_string_append (buff, str_trunc (entry->detail[2], list->widget.cols - 1)); 
     327            g_free (entry->detail[3]); 
     328            entry->detail[3] = g_strdup (buff->str); 
     329            entry->detail_cols = list->widget.cols; 
     330        } 
     331        label_set_text (list_detail, entry->detail[3]); 
     332    } 
     333} 
     334 
     335/* --------------------------------------------------------------------------------------------- */ 
     336 
     337static void 
     338update_list_title (void) 
     339{ 
     340    GString *buff = g_string_new (_("Bookmarks")); 
     341 
     342    if (list_cfg.sort != SORT_LINE || list_cfg.reverse) 
     343    { 
     344        g_string_append (buff, _(" - Sort: ")); 
     345        g_string_append (buff, 
     346                         list_cfg.sort == SORT_ALPHA ? _("ABC") : list_cfg.sort == 
     347                         SORT_LINE ? "" : _("FRQ")); 
     348        g_string_append (buff, list_cfg.reverse ? " v" : " ^"); 
     349    } 
     350    if (list_cfg.filter != FILTER_NONE) 
     351    { 
     352        g_string_append (buff, _(" - Filter: ")); 
     353        g_string_append (buff, list_cfg.filter == FILTER_FOUND ? _("FOUND") : _("USER")); 
     354    } 
     355    groupbox_set_title (list_grp, str_trunc (buff->str, list_box->widget.cols - 4)); 
     356    g_string_free (buff, TRUE); 
     357} 
     358 
     359/* --------------------------------------------------------------------------------------------- */ 
     360 
     361static int 
     362list_button_callback (WButton * button, int action) 
     363{ 
     364    list_entry_t *entry = NULL; 
     365    WEdit *edit = list_cfg.edit; 
     366 
     367    (void) button; 
     368 
     369    switch (action) 
     370    { 
     371    case B_REMOVE: 
     372        { 
     373            listbox_get_current (list_box, NULL, (void **) &entry); 
     374            if (entry != NULL) 
     375            { 
     376                book_mark_clear (edit, entry->mark->line, entry->mark->c); 
     377                list_entry_free2 (entry); 
     378                /* now remove list entry from screen */ 
     379                listbox_remove_current (list_box); 
     380            } 
     381        } 
     382        edit_update_screen (edit); 
     383        dlg_redraw (list_dlg); 
     384        break; 
     385 
     386    case B_FLUSH: 
     387        { 
     388            while (list_box->list && g_queue_get_length(list_box->list)) 
     389            { 
     390                GList *list = g_queue_pop_head_link(list_box->list); 
     391                entry = (list_entry_t *) ((WLEntry *) list->data)->data; 
     392                book_mark_clear (edit, entry->mark->line, entry->mark->c); 
     393                list_entry_free2 (entry); 
     394            } 
     395            listbox_set_list (list_box, NULL); 
     396        } 
     397        edit_update_screen (edit); 
     398        dlg_redraw (list_dlg); 
     399        break; 
     400 
     401    case B_ADD_NEW: 
     402        if (!book_mark_query_color (edit, edit->curs_row, BOOK_MARK_FOUND_COLOR) && 
     403            !book_mark_query_color (edit, edit->curs_row, BOOK_MARK_COLOR)) 
     404        { 
     405            edit_book_mark_t *book_mark; 
     406            long int line = edit->curs_row; 
     407            GString *buff = g_string_new (""); 
     408            GString *detail = g_string_new (""); 
     409 
     410            book_mark_insert (edit, edit->curs_row, BOOK_MARK_COLOR); 
     411            book_mark = book_mark_find (edit, edit->curs_row); 
     412            list_add_entry (list_cfg.edit, list_box, book_mark, buff, detail); 
     413            g_string_free (buff, 1); 
     414            g_string_free (detail, 1); 
     415            g_queue_sort (list_box->list, 
     416                          list_cfg.sort == 2 ? 
     417                              list_sort_alpha : 
     418                              (list_cfg.sort == 0 ? 
     419                                   list_sort_line : 
     420                                   list_sort_freq), 
     421                          NULL); 
     422            if (edit->curs_row < line) 
     423                edit_move_down (edit, line - edit->curs_row, FALSE); 
     424            else 
     425                edit_move_up (edit, edit->curs_row - line, FALSE); 
     426        } 
     427        edit_update_screen (edit); 
     428        dlg_redraw (list_dlg); 
     429        break; 
     430 
     431    case B_ENTER: 
     432        { 
     433            return 1; 
     434        } 
     435 
     436    case B_FILTER: 
     437        { 
     438            if (++list_cfg.filter > FILTER_FOUND) 
     439                list_cfg.filter = FILTER_NONE; 
     440            if (list_cfg.filter == FILTER_FOUND) 
     441                list_filter_color (BOOK_MARK_FOUND_COLOR); 
     442            else if (list_cfg.filter == FILTER_NONE) 
     443                list_filter_color (-1); 
     444            else 
     445                list_filter_color (BOOK_MARK_COLOR); 
     446            update_list_title (); 
     447        } 
     448        break; 
     449 
     450    case B_SORT: 
     451        if (++list_cfg.sort > SORT_ALPHA) 
     452            list_cfg.sort = SORT_LINE; 
     453        if (list_box->list) 
     454            g_queue_sort (list_box->list, 
     455                          list_cfg.sort == SORT_ALPHA ? 
     456                              list_sort_alpha : 
     457                              (list_cfg.sort == SORT_LINE ? 
     458                               list_sort_line : 
     459                               list_sort_freq), 
     460                          NULL); 
     461        // listbox_refresh_list (list_box, list_box->list); 
     462        update_list_title (); 
     463        break; 
     464 
     465    case B_REVERSE: 
     466        list_cfg.reverse = !list_cfg.reverse; 
     467        if (list_box->list) 
     468            g_queue_reverse (list_box->list); 
     469        // listbox_refresh_list (list_box, list_box->list); 
     470        update_list_title (); 
     471        break; 
     472 
     473    default: 
     474        return 1; 
     475    } 
     476 
     477    return 0; 
     478} 
     479 
     480/* --------------------------------------------------------------------------------------------- */ 
     481 
     482static inline cb_ret_t 
     483list_handle_key (WDialog * h, int key) 
     484{ 
     485    switch (key) 
     486    { 
     487    case KEY_M_CTRL | '\n': 
     488        goto l1; 
     489 
     490    case '\n': 
     491    case KEY_ENTER: 
     492    case KEY_RIGHT: 
     493        if (list_button_callback (NULL, B_ENTER) != 0) 
     494        { 
     495            h->ret_value = B_ENTER; 
     496            dlg_stop (h); 
     497        } 
     498        return MSG_HANDLED; 
     499 
     500    case KEY_IC: 
     501    case KEY_KP_ADD: 
     502    case '+': 
     503        list_button_callback (NULL, B_ADD_NEW); 
     504        return MSG_HANDLED; 
     505 
     506    case KEY_DC: 
     507    case KEY_BACKSPACE: 
     508    case KEY_KP_SUBTRACT: 
     509    case '-': 
     510        list_button_callback (NULL, B_REMOVE); 
     511        return MSG_HANDLED; 
     512 
     513      l1: 
     514    case ALT ('\n'): 
     515    case ALT ('\r'): 
     516        { 
     517            void *ldata = NULL; 
     518 
     519            listbox_get_current (list_box, NULL, &ldata); 
     520 
     521            if (ldata != NULL) 
     522            { 
     523            } 
     524        } 
     525        return MSG_HANDLED;     /* ignore key */ 
     526 
     527    default: 
     528        return MSG_NOT_HANDLED; 
     529    } 
     530} 
     531 
     532/* --------------------------------------------------------------------------------------------- */ 
     533 
     534static cb_ret_t 
     535list_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data) 
     536{ 
     537    WDialog *h = DIALOG (w); 
     538 
     539    switch (msg) 
     540    { 
     541    case MSG_UNHANDLED_KEY: 
     542        return list_handle_key (h, parm); 
     543 
     544    case MSG_POST_KEY: 
     545        dlg_select_widget (list_box); 
     546        /* always stay on hotlist */ 
     547        /* fall through */ 
     548 
     549    case MSG_INIT: 
     550        update_detail (); 
     551        update_list_title (); 
     552        return MSG_HANDLED; 
     553 
     554    case MSG_RESIZE: 
     555        /* simply call dlg_set_size() with new size */ 
     556        dlg_set_size (h, DLG_H, DLG_W); 
     557        update_detail (); 
     558        update_list_title (); 
     559        return MSG_HANDLED; 
     560 
     561    default: 
     562        return dlg_default_callback (w, sender, msg, parm, data); 
     563    } 
     564} 
     565 
     566/* --------------------------------------------------------------------------------------------- */ 
     567 
     568static lcback_ret_t 
     569list_listbox_callback (WListbox * list) 
     570{ 
     571    WDialog *dlg = WIDGET (list)->owner; 
     572 
     573    if (list->list && g_queue_get_length(list->list) != 0) 
     574    { 
     575        void *data = NULL; 
     576 
     577        listbox_get_current (list, NULL, &data); 
     578 
     579        if (data == NULL) 
     580        { 
     581            dlg->ret_value = B_ENTER; 
     582            dlg_stop (dlg); 
     583            return LISTBOX_DONE; 
     584        } 
     585    } 
     586 
     587    return LISTBOX_CONT; 
     588} 
     589 
     590/* --------------------------------------------------------------------------------------------- */ 
     591 
     592static void 
     593fill_line_listbox (WEdit * edit, int skip_sp, GString * buff) 
     594{ 
     595    off_t off; 
     596    int cw = 1, c = -1; 
     597 
     598    off = edit_buffer_get_current_bol (&edit->buffer); 
     599    while (c != '\r' && c != '\n' && c != 0) 
     600    { 
     601#ifdef HAVE_CHARSET 
     602        if (edit->utf8) 
     603        { 
     604            c = edit_buffer_get_utf (&edit->buffer, off, &cw); 
     605            if (cw < 1) 
     606                cw = 1; 
     607            if (skip_sp && c != ' ' && c != '\t') 
     608                skip_sp = 0; 
     609            if (c != '\r' && c != '\n' && c != 0 && !skip_sp) 
     610            { 
     611                /* convert TAB to spaces */ 
     612                if (c == '\t') 
     613                { 
     614                    for (c = option_tab_spacing; c > 1; c--) 
     615                        g_string_append_unichar (buff, ' '); 
     616                    c = ' '; 
     617                } 
     618                g_string_append_unichar (buff, c); 
     619            } 
     620        } 
     621        else 
     622#endif 
     623        { 
     624            c = edit_buffer_get_byte (&edit->buffer, off); 
     625            if (skip_sp && c != ' ' && c != '\t') 
     626                skip_sp = 0; 
     627            if (c != '\r' && c != '\n' && c != 0 && !skip_sp) 
     628            { 
     629                /* convert TAB to spaces */ 
     630                if (c == '\t') 
     631                { 
     632                    for (c = option_tab_spacing; c > 1; c--) 
     633                        g_string_append_c (buff, ' '); 
     634                    c = ' '; 
     635                } 
     636                g_string_append_c (buff, c); 
     637            } 
     638        } 
     639        off += cw; 
     640    } 
     641} 
     642 
     643/* --------------------------------------------------------------------------------------------- */ 
     644/* 
     645 * Copy&Paste (and rewrite) from filemanager/hotlsist.c 
     646 */ 
     647/** 
     648 * Expands all button names (once) and recalculates button positions. 
     649 * returns number of columns in the dialog box, which is 10 chars longer 
     650 * then buttonbar. 
     651 * 
     652 * If common width of the window (i.e. in xterm) is less than returned 
     653 * width - sorry :)  (anyway this did not handled in previous version too) 
     654 */ 
     655 
     656static void 
     657init_i18n_stuff (int cols) 
     658{ 
     659    size_t i; 
     660 
     661    static gboolean i18n_flag = FALSE; 
     662    int curr_x = 0; 
     663    int curr_minus_x = cols - 5; 
     664 
     665    if (!i18n_flag) 
     666    { 
     667        for (i = 0; i < list_btn_num; i++) 
     668        { 
     669#ifdef ENABLE_NLS 
     670            list_btn[i].text = _(list_btn[i].text); 
     671#endif /* ENABLE_NLS */ 
     672            list_btn[i].len = str_term_width1 (list_btn[i].text) + 3; 
     673            if (list_btn[i].flags == DEFPUSH_BUTTON) 
     674                list_btn[i].len += 2; 
     675            /* reset current X at line start */ 
     676            if (list_btn[i].x == 0) 
     677            { 
     678                curr_x = 0; 
     679                curr_minus_x = cols - 5; 
     680            } 
     681            if (list_btn[i].x >= 0) 
     682            { 
     683                list_btn[i].x = curr_x; 
     684                curr_x += list_btn[i].len + 1; 
     685            } 
     686            else if (list_btn[i].x < 0) 
     687            { 
     688                curr_minus_x -= list_btn[i].len + 1; 
     689                list_btn[i].x = curr_minus_x; 
     690            } 
     691        } 
     692 
     693        i18n_flag = TRUE; 
     694    } 
     695} 
     696 
     697/* --------------------------------------------------------------------------------------------- */ 
     698 
     699static void 
     700list_add_entry (WEdit * edit, WListbox * list, edit_book_mark_t * book_mark, GString * buff, 
     701                GString * detail) 
     702{ 
     703    list_entry_t *entry; 
     704 
     705    entry = g_malloc (sizeof (list_entry_t)); 
     706    g_string_truncate (buff, 0); 
     707    g_string_truncate (detail, 0); 
     708 
     709    fill_line_listbox (edit, 1, buff); 
     710    fill_line_listbox (edit, 0, detail); 
     711    entry->detail[1] = g_strdup (detail->str); 
     712    g_string_truncate (detail, 0); 
     713 
     714    if (book_mark->line != 0) 
     715    { 
     716        edit_move_up (edit, 1, FALSE); 
     717        fill_line_listbox (edit, 0, detail); 
     718    } 
     719    entry->detail[0] = g_strdup (detail->str); 
     720    g_string_truncate (detail, 0); 
     721 
     722    if (book_mark->line != edit->buffer.lines) 
     723    { 
     724        edit_move_down (edit, (book_mark->line == 0) ? 1 : 2, FALSE); 
     725        fill_line_listbox (edit, 0, detail); 
     726    } 
     727    entry->detail[2] = g_strdup (detail->str); 
     728    entry->detail[3] = g_strdup (""); 
     729    entry->detail_cols = -1; 
     730 
     731    entry->text = g_strndup (buff->str, 80); 
     732    entry->mark = book_mark; 
     733    g_string_printf (buff, "% 6ld [%c/%d] -> %s", book_mark->line + 1, 
     734                     book_mark->c == BOOK_MARK_FOUND_COLOR ? 'F' : 'U', book_mark->freq, 
     735                     str_trunc (buff->str, list->widget.cols - 1)); 
     736    listbox_add_item (list, LISTBOX_APPEND_AT_END, 0, buff->str, entry); 
     737} 
     738 
     739/* --------------------------------------------------------------------------------------------- */ 
     740 
     741static void 
     742fill_list_box (WEdit * edit, WListbox * list) 
     743{ 
     744    edit_book_mark_t *book_mark; 
     745    GString *detail; 
     746    GString *buff; 
     747    long int curs_line = edit->buffer.curs_line; 
     748 
     749    buff = g_string_new (""); 
     750    detail = g_string_new (""); 
     751    // edit_bol (edit, edit->curs1); // ??? Is it needed? 
     752 
     753    for (book_mark = book_mark_find (edit, 0); book_mark != NULL; book_mark = book_mark->next) 
     754    { 
     755        if (book_mark->line == -1) 
     756            continue; 
     757        if (edit->buffer.curs_line == book_mark->line) 
     758            ; 
     759        else if (edit->buffer.curs_line < book_mark->line) 
     760            edit_move_down (edit, book_mark->line - edit->buffer.curs_line, FALSE); 
     761        else 
     762            edit_move_up (edit, edit->buffer.curs_line - book_mark->line, FALSE); 
     763 
     764        list_add_entry (edit, list, book_mark, buff, detail); 
     765    } 
     766    if (edit->buffer.curs_line < curs_line) 
     767        edit_move_down (edit, curs_line - edit->buffer.curs_line, FALSE); 
     768    else 
     769        edit_move_up (edit, edit->buffer.curs_line - curs_line, FALSE); 
     770    g_string_free (buff, TRUE); 
     771    g_string_free (detail, TRUE); 
     772} 
     773 
     774/* --------------------------------------------------------------------------------------------- */ 
     775 
     776static void 
     777list_init (WEdit * edit) 
     778{ 
     779    size_t i; 
     780    const char *title, *help_node; 
     781    int lines, cols; 
     782    int y; 
     783    int dh = 0; 
     784    WGroupbox *dtl_box; 
     785    Widget *list_widget; 
     786 
     787    do_refresh (); 
     788 
     789    lines = DLG_H; 
     790    cols = DLG_W; 
     791    init_i18n_stuff (cols); 
     792 
     793    title = _("Bookmark list"); 
     794    help_node = "[Bookmarklist]"; 
     795 
     796    list_cfg.hidden = NULL; 
     797    list_cfg.edit = edit; 
     798    list_dlg = 
     799        dlg_create (TRUE, 0, 0, lines, cols, dialog_colors, list_callback, NULL, help_node, 
     800                    title, DLG_CENTER); 
     801    y = UY; 
     802    list_grp = groupbox_new (y, UX, lines - 12 + dh, cols - 2 * UX, _("Bookmarks")); 
     803    list_widget = WIDGET (list_grp); 
     804    add_widget_autopos (list_dlg, list_widget, WPOS_KEEP_ALL, NULL); 
     805 
     806    list_box = 
     807        listbox_new (y + 1, UX + 1, list_widget->lines - 2, list_widget->cols - 2, FALSE, 
     808                     list_listbox_callback); 
     809 
     810    fill_list_box (edit, list_box); 
     811 
     812    /* insert before groupbox to view scrollbar */ 
     813    add_widget_autopos (list_dlg, list_box, WPOS_KEEP_ALL, NULL); 
     814 
     815    y += list_widget->lines; 
     816 
     817    dtl_box = groupbox_new (y, UX, 5, list_widget->cols, _("Bookmark detail")); 
     818    add_widget_autopos (list_dlg, dtl_box, WPOS_KEEP_BOTTOM | WPOS_KEEP_HORZ, NULL); 
     819 
     820    list_detail = label_new (y + 1, UX + 2, ""); 
     821    widget_set_size ((Widget *) list_detail, y + 1, UX + 2, 80, 3); 
     822    add_widget_autopos (list_dlg, list_detail, WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT, NULL); 
     823    y += WIDGET (dtl_box)->lines; 
     824 
     825    add_widget_autopos (list_dlg, hline_new (y++, -1, -1), WPOS_KEEP_BOTTOM, NULL); 
     826 
     827    for (i = 0; i < list_btn_num; i++) 
     828    { 
     829        WButton *btn; 
     830        if (list_btn[i].x < 0) 
     831            list_btn[i].x = cols + list_btn[i].x; 
     832        btn = button_new (y + list_btn[i].y, UX + list_btn[i].x, 
     833                          list_btn[i].ret_cmd, list_btn[i].flags, 
     834                          list_btn[i].text, list_button_callback); 
     835        if (i == 5) 
     836            list_filter = btn; 
     837        if (i == 6) 
     838            list_sort = btn; 
     839        add_widget_autopos (list_dlg, btn, list_btn[i].pos_flags, NULL); 
     840    } 
     841 
     842    dlg_select_widget (list_box); 
     843} 
     844 
     845 
     846/* --------------------------------------------------------------------------------------------- */ 
     847 
     848static void 
     849list_entry_free (void *data) 
     850{ 
     851    list_entry_free2 (((WLEntry *) data)->data); 
     852} 
     853 
    138854/* --------------------------------------------------------------------------------------------- */ 
    139855/*** public functions ****************************************************************************/ 
    140856/* --------------------------------------------------------------------------------------------- */ 
    141857 
     858void 
     859book_mark_list_show (WEdit * edit) 
     860{ 
     861    int res; 
     862 
     863/*** Check list_box running...?? */ 
     864    list_init (edit); 
     865 
     866    res = dlg_run (list_dlg); 
     867    if (res == B_ENTER) 
     868    { 
     869        char *text; 
     870        list_entry_t *entry; 
     871 
     872        listbox_get_current (list_box, &text, (void **) &entry); 
     873        if (entry != NULL) 
     874        { 
     875            if (entry->mark->line >= edit->start_line + WIDGET (edit)->lines 
     876                || entry->mark->line < edit->start_line) 
     877                edit_move_display (edit, entry->mark->line - WIDGET (edit)->lines / 2); 
     878            edit_move_to_line (edit, entry->mark->line); 
     879            if (entry->mark->freq < 128 * 1024) 
     880                entry->mark->freq++; 
     881        } 
     882    } 
     883    g_queue_foreach (list_box->list, (GFunc) list_entry_free, NULL); 
     884    dlg_destroy (list_dlg); 
     885    list_cfg.edit = NULL; 
     886} 
     887 
    142888/**  
    143889 * Check if bookmark bookmark exists at this line of this color 
    144890 * 
    book_mark_insert (WEdit * edit, long lin 
    192938    q = g_new (edit_book_mark_t, 1); 
    193939    q->line = line; 
    194940    q->c = c; 
     941    q->freq = 0; 
    195942    q->next = p->next; 
    196943    /* insert into list */ 
    197944    q->prev = p; 
  • src/editor/edit-impl.h

    old new void book_mark_inc (WEdit * edit, long l 
    275275void book_mark_dec (WEdit * edit, long line); 
    276276void book_mark_serialize (WEdit * edit, int color); 
    277277void book_mark_restore (WEdit * edit, int color); 
     278void book_mark_list_show (WEdit * edit); 
    278279 
    279280gboolean edit_line_is_blank (WEdit * edit, long line); 
    280281gboolean is_break_char (char c); 
  • src/editor/edit.c

    old new edit_execute_cmd (WEdit * edit, unsigned 
    36823682                if (p->line >= edit->start_line + w->lines || p->line < edit->start_line) 
    36833683                    edit_move_display (edit, p->line - w->lines / 2); 
    36843684                edit_move_to_line (edit, p->line); 
     3685                if (p->freq < 128*1024) 
     3686                    p->freq++; 
     3687                if (p->freq < 128*1024) 
     3688                    p->freq++; 
    36853689            } 
    36863690        } 
    36873691        break; 
     3692    case CK_BookmarkList: 
     3693        book_mark_list_show (edit); 
     3694        break; 
    36883695 
    36893696    case CK_Top: 
    36903697    case CK_MarkToFileBegin: 
  • src/editor/editmenu.c

    old new create_search_replace_menu (void) 
    135135    entries = g_list_prepend (entries, menu_entry_create (_("&Toggle bookmark"), CK_Bookmark)); 
    136136    entries = g_list_prepend (entries, menu_entry_create (_("&Next bookmark"), CK_BookmarkNext)); 
    137137    entries = g_list_prepend (entries, menu_entry_create (_("&Prev bookmark"), CK_BookmarkPrev)); 
     138    entries = g_list_prepend (entries, menu_entry_create (_("&List bookmarks"), CK_BookmarkList)); 
    138139    entries = g_list_prepend (entries, menu_entry_create (_("&Flush bookmarks"), CK_BookmarkFlush)); 
    139140 
    140141    return g_list_reverse (entries); 
  • src/editor/editwidget.h

    old new struct edit_book_mark_t 
    3434{ 
    3535    long line;                  /* line number */ 
    3636    int c;                      /* color */ 
     37    int freq;                   /* usage freq */ 
    3738    edit_book_mark_t *next; 
    3839    edit_book_mark_t *prev; 
    3940}; 
  • src/keybind-defaults.c

    old new static const global_keymap_ini_t default 
    401401    {"MatchBracket", "alt-b"}, 
    402402    {"ParagraphFormat", "alt-p"}, 
    403403    {"Bookmark", "alt-k"}, 
     404    {"BookmarkList", "alt-shift-k; alt-shift-j"}, 
    404405    {"BookmarkFlush", "alt-o"}, 
    405406    {"BookmarkNext", "alt-j"}, 
    406407    {"BookmarkPrev", "alt-i"},