Ticket #2979: 1_bookmarks_2.patch

File 1_bookmarks_2.patch, 27.6 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) 
     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) 
     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) 
     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    size_t increment = 0; 
     265    GList *tail; 
     266 
     267    if (!list_cfg.hidden) 
     268        return; 
     269 
     270    for (tail = list_cfg.hidden; tail->next; tail = tail->next, increment++); 
     271 
     272    list_box->list->tail = g_list_concat (list_box->list->tail, list_cfg.hidden); 
     273    list_box->list->tail = tail; 
     274    list_box->list->length += increment; 
     275 
     276    list_cfg.hidden = NULL; 
     277} 
     278 
     279static void 
     280list_filter_color (int color) 
     281{ 
     282    GList *e; 
     283 
     284    list_filter_none (); 
     285    if (color != -1) 
     286    { 
     287        e = list_box->list->head; 
     288 
     289        while (e != NULL) 
     290        { 
     291            if (((list_entry_t *) ((WLEntry *) e->data)->data)->mark->c != color) 
     292            { 
     293                list_box->list->head = g_list_remove_link (list_box->list->head, e); 
     294                list_box->list->length--; 
     295                list_cfg.hidden = g_list_concat (list_cfg.hidden, e); 
     296                e = list_box->list->head; 
     297            } 
     298            else 
     299            { 
     300                e = g_list_next (e); 
     301            } 
     302        } 
     303    } 
     304    /*else 
     305    { 
     306        list_box->list->head; 
     307    }*/ 
     308    //listbox_set_list (list_box, list_box->list->head); 
     309} 
     310 
     311/* --------------------------------------------------------------------------------------------- */ 
     312 
     313static void 
     314update_detail (void) 
     315{ 
     316    list_entry_t *entry; 
     317    WListbox *list = list_box; 
     318 
     319    if (list->list->length != 0) 
     320    { 
     321        char *ctext = NULL; 
     322 
     323        listbox_get_current (list, &ctext, (void **) &entry); 
     324        if (list->widget.cols != entry->detail_cols) 
     325        { 
     326            GString *buff = g_string_new (""); 
     327            g_string_append (buff, str_trunc (entry->detail[0], list->widget.cols - 1)); 
     328            g_string_append (buff, "\n"); 
     329            g_string_append (buff, str_trunc (entry->detail[1], list->widget.cols - 1)); 
     330            g_string_append (buff, "\n"); 
     331            g_string_append (buff, str_trunc (entry->detail[2], list->widget.cols - 1)); 
     332            g_free (entry->detail[3]); 
     333            entry->detail[3] = g_strdup (buff->str); 
     334            entry->detail_cols = list->widget.cols; 
     335        } 
     336        label_set_text (list_detail, entry->detail[3]); 
     337    } 
     338} 
     339 
     340/* --------------------------------------------------------------------------------------------- */ 
     341 
     342static void 
     343update_list_title (void) 
     344{ 
     345    GString *buff = g_string_new (_("Bookmarks")); 
     346 
     347    if (list_cfg.sort != SORT_LINE || list_cfg.reverse) 
     348    { 
     349        g_string_append (buff, _(" - Sort: ")); 
     350        g_string_append (buff, 
     351                         list_cfg.sort == SORT_ALPHA ? _("ABC") : list_cfg.sort == 
     352                         SORT_LINE ? "" : _("FRQ")); 
     353        g_string_append (buff, list_cfg.reverse ? " v" : " ^"); 
     354    } 
     355    if (list_cfg.filter != FILTER_NONE) 
     356    { 
     357        g_string_append (buff, _(" - Filter: ")); 
     358        g_string_append (buff, list_cfg.filter == FILTER_FOUND ? _("FOUND") : _("USER")); 
     359    } 
     360    groupbox_set_title (list_grp, str_trunc (buff->str, list_box->widget.cols - 4)); 
     361    g_string_free (buff, TRUE); 
     362} 
     363 
     364/* --------------------------------------------------------------------------------------------- */ 
     365 
     366static int 
     367list_button_callback (WButton * button, int action) 
     368{ 
     369    list_entry_t *entry = NULL; 
     370    WEdit *edit = list_cfg.edit; 
     371 
     372    (void) button; 
     373 
     374    switch (action) 
     375    { 
     376    case B_REMOVE: 
     377        { 
     378            listbox_get_current (list_box, NULL, (void **) &entry); 
     379            if (entry != NULL) 
     380            { 
     381                book_mark_clear (edit, entry->mark->line, entry->mark->c); 
     382                list_entry_free2 (entry); 
     383                /* now remove list entry from screen */ 
     384                listbox_remove_current (list_box); 
     385            } 
     386        } 
     387        edit_update_screen (edit); 
     388        dlg_redraw (list_dlg); 
     389        break; 
     390 
     391    case B_FLUSH: 
     392        { 
     393            GList *list = list_box->list->head; 
     394            list_box->list->head = list_box->list->tail = NULL; 
     395            list_box->list->length = 0; 
     396 
     397            while (list != NULL) 
     398            { 
     399                entry = (list_entry_t *) ((WLEntry *) list->data)->data; 
     400                book_mark_clear (edit, entry->mark->line, entry->mark->c); 
     401                list_entry_free2 (entry); 
     402 
     403                list = g_list_next (list); 
     404            } 
     405            //listbox_set_list (list_box, NULL); 
     406        } 
     407        edit_update_screen (edit); 
     408        dlg_redraw (list_dlg); 
     409        break; 
     410 
     411    case B_ADD_NEW: 
     412        if (!book_mark_query_color (edit, edit->curs_row, BOOK_MARK_FOUND_COLOR) && 
     413            !book_mark_query_color (edit, edit->curs_row, BOOK_MARK_COLOR)) 
     414        { 
     415            edit_book_mark_t *book_mark; 
     416            GList *new_list; 
     417            long int line = edit->curs_row; 
     418            GString *buff = g_string_new (""); 
     419            GString *detail = g_string_new (""); 
     420 
     421            book_mark_insert (edit, edit->curs_row, BOOK_MARK_COLOR); 
     422            book_mark = book_mark_find (edit, edit->curs_row); 
     423            list_add_entry (list_cfg.edit, list_box, book_mark, buff, detail); 
     424            g_string_free (buff, 1); 
     425            g_string_free (detail, 1); 
     426            new_list = g_list_sort (list_box->list->head, list_cfg.sort == 2 ? 
     427                                    list_sort_alpha : (list_cfg.sort == 
     428                                                       0 ? list_sort_line : list_sort_freq)); 
     429            list_box->list->length++; 
     430            list_box->list->head = new_list; 
     431            while (list_box->list->tail->next) 
     432                list_box->list->tail = list_box->list->tail->next; 
     433 
     434            if (edit->curs_row < line) 
     435                edit_move_down (edit, line - edit->curs_row, FALSE); 
     436            else 
     437                edit_move_up (edit, edit->curs_row - line, FALSE); 
     438        } 
     439        edit_update_screen (edit); 
     440        dlg_redraw (list_dlg); 
     441        break; 
     442 
     443    case B_ENTER: 
     444        { 
     445            return 1; 
     446        } 
     447 
     448    case B_FILTER: 
     449        { 
     450            if (++list_cfg.filter > FILTER_FOUND) 
     451                list_cfg.filter = FILTER_NONE; 
     452            if (list_cfg.filter == FILTER_FOUND) 
     453                list_filter_color (BOOK_MARK_FOUND_COLOR); 
     454            else if (list_cfg.filter == FILTER_NONE) 
     455                list_filter_color (-1); 
     456            else 
     457                list_filter_color (BOOK_MARK_COLOR); 
     458            update_list_title (); 
     459        } 
     460        break; 
     461 
     462    case B_SORT: 
     463        if (++list_cfg.sort > SORT_ALPHA) 
     464            list_cfg.sort = SORT_LINE; 
     465        list_box->list->head = g_list_sort (list_box->list->head, 
     466                                            list_cfg.sort == SORT_ALPHA ? list_sort_alpha : 
     467                                                (list_cfg.sort == 
     468                                                SORT_LINE ? list_sort_line : list_sort_freq)); 
     469        while (list_box->list->tail->next) 
     470            list_box->list->tail = list_box->list->tail->next; 
     471        //listbox_set_list (list_box, list_box->list->head); 
     472        update_list_title (); 
     473        break; 
     474 
     475    case B_REVERSE: 
     476        { 
     477            GList *t; 
     478            list_cfg.reverse = !list_cfg.reverse; 
     479            t = list_box->list->head; 
     480            list_box->list->head = g_list_reverse (list_box->list->head); 
     481            list_box->list->tail = t; 
     482            //listbox_set_list (list_box, list_box->list->head); 
     483            update_list_title (); 
     484        } 
     485        break; 
     486 
     487    default: 
     488        return 1; 
     489    } 
     490 
     491    return 0; 
     492} 
     493 
     494/* --------------------------------------------------------------------------------------------- */ 
     495 
     496static inline cb_ret_t 
     497list_handle_key (WDialog * h, int key) 
     498{ 
     499    switch (key) 
     500    { 
     501    case KEY_M_CTRL | '\n': 
     502        goto l1; 
     503 
     504    case '\n': 
     505    case KEY_ENTER: 
     506    case KEY_RIGHT: 
     507        if (list_button_callback (NULL, B_ENTER) != 0) 
     508        { 
     509            h->ret_value = B_ENTER; 
     510            dlg_stop (h); 
     511        } 
     512        return MSG_HANDLED; 
     513 
     514    case KEY_IC: 
     515    case KEY_KP_ADD: 
     516    case '+': 
     517        list_button_callback (NULL, B_ADD_NEW); 
     518        return MSG_HANDLED; 
     519 
     520    case KEY_DC: 
     521    case KEY_BACKSPACE: 
     522    case KEY_KP_SUBTRACT: 
     523    case '-': 
     524        list_button_callback (NULL, B_REMOVE); 
     525        return MSG_HANDLED; 
     526 
     527      l1: 
     528    case ALT ('\n'): 
     529    case ALT ('\r'): 
     530        { 
     531            void *ldata = NULL; 
     532 
     533            listbox_get_current (list_box, NULL, &ldata); 
     534 
     535            if (ldata != NULL) 
     536            { 
     537            } 
     538        } 
     539        return MSG_HANDLED;     /* ignore key */ 
     540 
     541    default: 
     542        return MSG_NOT_HANDLED; 
     543    } 
     544} 
     545 
     546/* --------------------------------------------------------------------------------------------- */ 
     547 
     548static cb_ret_t 
     549list_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data) 
     550{ 
     551    WDialog *h = DIALOG (w); 
     552 
     553    switch (msg) 
     554    { 
     555    case MSG_UNHANDLED_KEY: 
     556        return list_handle_key (h, parm); 
     557 
     558    case MSG_POST_KEY: 
     559        dlg_select_widget (list_box); 
     560        /* always stay on hotlist */ 
     561        /* fall through */ 
     562 
     563    case MSG_INIT: 
     564        update_detail (); 
     565        update_list_title (); 
     566        return MSG_HANDLED; 
     567 
     568    case MSG_RESIZE: 
     569        /* simply call dlg_set_size() with new size */ 
     570        dlg_set_size (h, DLG_H, DLG_W); 
     571        update_detail (); 
     572        update_list_title (); 
     573        return MSG_HANDLED; 
     574 
     575    default: 
     576        return dlg_default_callback (w, sender, msg, parm, data); 
     577    } 
     578} 
     579 
     580/* --------------------------------------------------------------------------------------------- */ 
     581 
     582static lcback_ret_t 
     583list_listbox_callback (WListbox * list) 
     584{ 
     585    WDialog *dlg = WIDGET (list)->owner; 
     586 
     587    if (list->list->length != 0) 
     588    { 
     589        void *data = NULL; 
     590 
     591        listbox_get_current (list, NULL, &data); 
     592 
     593        if (data == NULL) 
     594        { 
     595            dlg->ret_value = B_ENTER; 
     596            dlg_stop (dlg); 
     597            return LISTBOX_DONE; 
     598        } 
     599    } 
     600 
     601    return LISTBOX_CONT; 
     602} 
     603 
     604/* --------------------------------------------------------------------------------------------- */ 
     605 
     606static void 
     607fill_line_listbox (WEdit * edit, int skip_sp, GString * buff) 
     608{ 
     609    off_t off; 
     610    int cw = 1, c = -1; 
     611 
     612    off = edit_buffer_get_current_bol (&edit->buffer); 
     613    while (c != '\r' && c != '\n' && c != 0) 
     614    { 
     615#ifdef HAVE_CHARSET 
     616        if (edit->utf8) 
     617        { 
     618            c = edit_buffer_get_utf (&edit->buffer, off, &cw); 
     619            if (cw < 1) 
     620                cw = 1; 
     621            if (skip_sp && c != ' ' && c != '\t') 
     622                skip_sp = 0; 
     623            if (c != '\r' && c != '\n' && c != 0 && !skip_sp) 
     624            { 
     625                /* convert TAB to spaces */ 
     626                if (c == '\t') 
     627                { 
     628                    for (c = option_tab_spacing; c > 1; c--) 
     629                        g_string_append_unichar (buff, ' '); 
     630                    c = ' '; 
     631                } 
     632                g_string_append_unichar (buff, c); 
     633            } 
     634        } 
     635        else 
     636#endif 
     637        { 
     638            c = edit_buffer_get_byte (&edit->buffer, off); 
     639            if (skip_sp && c != ' ' && c != '\t') 
     640                skip_sp = 0; 
     641            if (c != '\r' && c != '\n' && c != 0 && !skip_sp) 
     642            { 
     643                /* convert TAB to spaces */ 
     644                if (c == '\t') 
     645                { 
     646                    for (c = option_tab_spacing; c > 1; c--) 
     647                        g_string_append_c (buff, ' '); 
     648                    c = ' '; 
     649                } 
     650                g_string_append_c (buff, c); 
     651            } 
     652        } 
     653        off += cw; 
     654    } 
     655} 
     656 
     657/* --------------------------------------------------------------------------------------------- */ 
     658/* 
     659 * Copy&Paste (and rewrite) from filemanager/hotlsist.c 
     660 */ 
     661/** 
     662 * Expands all button names (once) and recalculates button positions. 
     663 * returns number of columns in the dialog box, which is 10 chars longer 
     664 * then buttonbar. 
     665 * 
     666 * If common width of the window (i.e. in xterm) is less than returned 
     667 * width - sorry :)  (anyway this did not handled in previous version too) 
     668 */ 
     669 
     670static void 
     671init_i18n_stuff (int cols) 
     672{ 
     673    size_t i; 
     674 
     675    static gboolean i18n_flag = FALSE; 
     676    int curr_x = 0; 
     677    int curr_minus_x = cols - 5; 
     678 
     679    if (!i18n_flag) 
     680    { 
     681        for (i = 0; i < list_btn_num; i++) 
     682        { 
     683#ifdef ENABLE_NLS 
     684            list_btn[i].text = _(list_btn[i].text); 
     685#endif /* ENABLE_NLS */ 
     686            list_btn[i].len = str_term_width1 (list_btn[i].text) + 3; 
     687            if (list_btn[i].flags == DEFPUSH_BUTTON) 
     688                list_btn[i].len += 2; 
     689            /* reset current X at line start */ 
     690            if (list_btn[i].x == 0) 
     691            { 
     692                curr_x = 0; 
     693                curr_minus_x = cols - 5; 
     694            } 
     695            if (list_btn[i].x >= 0) 
     696            { 
     697                list_btn[i].x = curr_x; 
     698                curr_x += list_btn[i].len + 1; 
     699            } 
     700            else if (list_btn[i].x < 0) 
     701            { 
     702                curr_minus_x -= list_btn[i].len + 1; 
     703                list_btn[i].x = curr_minus_x; 
     704            } 
     705        } 
     706 
     707        i18n_flag = TRUE; 
     708    } 
     709} 
     710 
     711/* --------------------------------------------------------------------------------------------- */ 
     712 
     713static void 
     714list_add_entry (WEdit * edit, WListbox * list, edit_book_mark_t * book_mark, GString * buff, 
     715                GString * detail) 
     716{ 
     717    list_entry_t *entry; 
     718 
     719    entry = g_malloc (sizeof (list_entry_t)); 
     720    g_string_truncate (buff, 0); 
     721    g_string_truncate (detail, 0); 
     722 
     723    fill_line_listbox (edit, 1, buff); 
     724    fill_line_listbox (edit, 0, detail); 
     725    entry->detail[1] = g_strdup (detail->str); 
     726    g_string_truncate (detail, 0); 
     727 
     728    if (book_mark->line != 0) 
     729    { 
     730        edit_move_up (edit, 1, FALSE); 
     731        fill_line_listbox (edit, 0, detail); 
     732    } 
     733    entry->detail[0] = g_strdup (detail->str); 
     734    g_string_truncate (detail, 0); 
     735 
     736    if (book_mark->line != edit->buffer.lines) 
     737    { 
     738        edit_move_down (edit, (book_mark->line == 0) ? 1 : 2, FALSE); 
     739        fill_line_listbox (edit, 0, detail); 
     740    } 
     741    entry->detail[2] = g_strdup (detail->str); 
     742    entry->detail[3] = g_strdup (""); 
     743    entry->detail_cols = -1; 
     744 
     745    entry->text = g_strndup (buff->str, 80); 
     746    entry->mark = book_mark; 
     747    g_string_printf (buff, "% 6ld [%c/%d] -> %s", book_mark->line + 1, 
     748                     book_mark->c == BOOK_MARK_FOUND_COLOR ? 'F' : 'U', book_mark->freq, 
     749                     str_trunc (buff->str, list->widget.cols - 1)); 
     750    listbox_add_item (list, LISTBOX_APPEND_AT_END, 0, buff->str, entry); 
     751} 
     752 
     753/* --------------------------------------------------------------------------------------------- */ 
     754 
     755static void 
     756fill_list_box (WEdit * edit, WListbox * list) 
     757{ 
     758    edit_book_mark_t *book_mark; 
     759    GString *detail; 
     760    GString *buff; 
     761    long int curs_line = edit->buffer.curs_line; 
     762 
     763    buff = g_string_new (""); 
     764    detail = g_string_new (""); 
     765    // edit_bol (edit, edit->curs1); ??? Is it needed? 
     766 
     767    for (book_mark = book_mark_find (edit, 0); book_mark != NULL; book_mark = book_mark->next) 
     768    { 
     769        if (book_mark->line == -1) 
     770            continue; 
     771        if (edit->buffer.curs_line == book_mark->line) 
     772            ; 
     773        else if (edit->buffer.curs_line < book_mark->line) 
     774            edit_move_down (edit, book_mark->line - edit->buffer.curs_line, FALSE); 
     775        else 
     776            edit_move_up (edit, edit->buffer.curs_line - book_mark->line, FALSE); 
     777 
     778        list_add_entry (edit, list, book_mark, buff, detail); 
     779    } 
     780    if (edit->buffer.curs_line < curs_line) 
     781        edit_move_down (edit, curs_line - edit->buffer.curs_line, FALSE); 
     782    else 
     783        edit_move_up (edit, edit->buffer.curs_line - curs_line, FALSE); 
     784    g_string_free (buff, TRUE); 
     785    g_string_free (detail, TRUE); 
     786} 
     787 
     788/* --------------------------------------------------------------------------------------------- */ 
     789 
     790static void 
     791list_init (WEdit * edit) 
     792{ 
     793    size_t i; 
     794    const char *title, *help_node; 
     795    int lines, cols; 
     796    int y; 
     797    int dh = 0; 
     798    WGroupbox *dtl_box; 
     799    Widget *list_widget; 
     800 
     801    do_refresh (); 
     802 
     803    lines = DLG_H; 
     804    cols = DLG_W; 
     805    init_i18n_stuff (cols); 
     806 
     807    title = _("Bookmark list"); 
     808    help_node = "[Bookmarklist]"; 
     809 
     810    list_cfg.hidden = NULL; 
     811    list_cfg.edit = edit; 
     812    list_dlg = 
     813        dlg_create (TRUE, 0, 0, lines, cols, dialog_colors, list_callback, NULL, help_node, 
     814                    title, DLG_CENTER); 
     815    y = UY; 
     816    list_grp = groupbox_new (y, UX, lines - 12 + dh, cols - 2 * UX, _("Bookmarks")); 
     817    list_widget = WIDGET (list_grp); 
     818    add_widget_autopos (list_dlg, list_widget, WPOS_KEEP_ALL, NULL); 
     819 
     820    list_box = 
     821        listbox_new (y + 1, UX + 1, list_widget->lines - 2, list_widget->cols - 2, FALSE, 
     822                     list_listbox_callback); 
     823 
     824    fill_list_box (edit, list_box); 
     825 
     826    /* insert before groupbox to view scrollbar */ 
     827    add_widget_autopos (list_dlg, list_box, WPOS_KEEP_ALL, NULL); 
     828 
     829    y += list_widget->lines; 
     830 
     831    dtl_box = groupbox_new (y, UX, 5, list_widget->cols, _("Bookmark detail")); 
     832    add_widget_autopos (list_dlg, dtl_box, WPOS_KEEP_BOTTOM | WPOS_KEEP_HORZ, NULL); 
     833 
     834    list_detail = label_new (y + 1, UX + 2, ""); 
     835    widget_set_size ((Widget *) list_detail, y + 1, UX + 2, 80, 3); 
     836    add_widget_autopos (list_dlg, list_detail, WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT, NULL); 
     837    y += WIDGET (dtl_box)->lines; 
     838 
     839    add_widget_autopos (list_dlg, hline_new (y++, -1, -1), WPOS_KEEP_BOTTOM, NULL); 
     840 
     841    for (i = 0; i < list_btn_num; i++) 
     842    { 
     843        WButton *btn; 
     844        if (list_btn[i].x < 0) 
     845            list_btn[i].x = cols + list_btn[i].x; 
     846        btn = button_new (y + list_btn[i].y, UX + list_btn[i].x, 
     847                          list_btn[i].ret_cmd, list_btn[i].flags, 
     848                          list_btn[i].text, list_button_callback); 
     849        if (i == 5) 
     850            list_filter = btn; 
     851        if (i == 6) 
     852            list_sort = btn; 
     853        add_widget_autopos (list_dlg, btn, list_btn[i].pos_flags, NULL); 
     854    } 
     855 
     856    dlg_select_widget (list_box); 
     857} 
     858 
     859 
     860/* --------------------------------------------------------------------------------------------- */ 
     861 
     862static void 
     863list_entry_free (void *data) 
     864{ 
     865    list_entry_free2 (((WLEntry *) data)->data); 
     866} 
     867 
    138868/* --------------------------------------------------------------------------------------------- */ 
    139869/*** public functions ****************************************************************************/ 
    140870/* --------------------------------------------------------------------------------------------- */ 
    141871 
     872void 
     873book_mark_list_show (WEdit * edit) 
     874{ 
     875    int res; 
     876 
     877/*** Check list_box running...?? */ 
     878    list_init (edit); 
     879 
     880    res = dlg_run (list_dlg); 
     881    if (res == B_ENTER) 
     882    { 
     883        char *text; 
     884        list_entry_t *entry; 
     885 
     886        listbox_get_current (list_box, &text, (void **) &entry); 
     887        if (entry != NULL) 
     888        { 
     889            if (entry->mark->line >= edit->start_line + WIDGET (edit)->lines 
     890                || entry->mark->line < edit->start_line) 
     891                edit_move_display (edit, entry->mark->line - WIDGET (edit)->lines / 2); 
     892            edit_move_to_line (edit, entry->mark->line); 
     893            if (entry->mark->freq < 128 * 1024) 
     894                entry->mark->freq++; 
     895        } 
     896    } 
     897    g_list_foreach (list_box->list->head, (GFunc) list_entry_free, NULL); 
     898    dlg_destroy (list_dlg); 
     899    list_cfg.edit = NULL; 
     900} 
     901 
    142902/**  
    143903 * Check if bookmark bookmark exists at this line of this color 
    144904 * 
    book_mark_insert (WEdit * edit, long lin 
    192952    q = g_new (edit_book_mark_t, 1); 
    193953    q->line = line; 
    194954    q->c = c; 
     955    q->freq = 0; 
    195956    q->next = p->next; 
    196957    /* insert into list */ 
    197958    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"},