📄 bookmark.c
字号:
#include "links.h"/* The location of the box in the bookmark manager */#define BM_BOX_IND 5/* The list of bookmarks */struct list_head bookmarks = {&bookmarks, &bookmarks};/* The last used id of a bookmark */bookmark_id next_bookmark_id = 0;/* Clears the bookmark list */void free_bookmarks() { struct bookmark *bm; foreach(bm, bookmarks) { mem_free(bm->title); mem_free(bm->url); } free_list(bookmarks);}/* Does final cleanup and saving of bookmarks */void finalize_bookmarks() { write_bookmarks(); free_bookmarks();}/* Loads the bookmarks from file */void read_bookmarks() { unsigned char in_buffer[MAX_STR_LEN]; unsigned char *file_name; unsigned char *title, *url; /* Pointers to the start of each field (in buffer)*/ FILE *f; file_name = stracpy(links_home); if (!file_name) return; add_to_strn(&file_name, "bookmarks"); f = fopen(file_name, "r"); mem_free(file_name); if (f == NULL) return; title = in_buffer; while (fgets(in_buffer, MAX_STR_LEN, f)) { url = strchr(in_buffer, '|'); if (url == NULL) continue; *url = '\0'; url++; if (strchr(url, '\n')) *( strchr(url, '\n') ) = '\0'; add_bookmark(title, url); } fclose(f);}/* Saves the bookmarks to file */void write_bookmarks() { struct bookmark *bm; FILE *out; unsigned char *tmp_file_name, *file_name; tmp_file_name = stracpy(links_home); if (!tmp_file_name) return; add_to_strn(&tmp_file_name, "bookmarks.tmp"); out = fopen(tmp_file_name, "w"); if (!out) { mem_free(tmp_file_name); return; } foreachback(bm, bookmarks) { unsigned char *p = stracpy(bm->title); int i; for (i = strlen(p) - 1; i >= 0; i--) if (p[i] < ' '|| p[i] == '|') p[i] = ' '; fputs(p,out); fputc('|', out); fputs(bm->url,out); fputc('\n',out); mem_free(p); } if (ferror(out)) { fclose(out); goto err; } if (fclose(out) == EOF) { err: remove(tmp_file_name); mem_free(tmp_file_name); return; } file_name = stracpy(links_home); if (!file_name) { mem_free(tmp_file_name); return; } add_to_strn(&file_name, "bookmarks");#ifndef RENAME_OVER_EXISTING_FILES unlink(file_name); /* OS/2 needs this */#endif rename(tmp_file_name, file_name); mem_free(tmp_file_name); mem_free(file_name);}/* Gets a bookmark by id */struct bookmark *get_bookmark_by_id(bookmark_id id) { struct bookmark *bm; if (id == BAD_BOOKMARK_ID) return NULL; foreach(bm, bookmarks) { if (id == bm->id) return bm; } return NULL;}/* Adds a bookmark to the bookmark list. Don't play with new_bm after you're done. It would be impolite. */void add_bookmark(const unsigned char *title, const unsigned char *url) { struct bookmark *bm; int title_size; /* How much mem to allocate for the strings */ int url_size; title_size = strlen(title) + 1; url_size = strlen(url) + 1; bm = mem_alloc(sizeof(struct bookmark)); bm->title = mem_alloc(title_size); bm->url = mem_alloc(url_size); strcpy(bm->title, title); strcpy(bm->url, url); bm->id = next_bookmark_id++; /* Actually add it */ add_to_list(bookmarks, bm);}/* Updates an existing bookmark. * * If the requested bookmark does not exist, return 0. Otherwise, return 1. * * If any of the fields are NULL, the value is left unchanged. */int bookmark_update(bookmark_id id, const unsigned char *title, const unsigned char *url) { struct bookmark *bm = get_bookmark_by_id(id); if (bm == NULL) { /* Does not exist. */ return 0; } if (title) { mem_free(bm->title); bm->title = stracpy((unsigned char *)title); } if (url) { mem_free(bm->url); bm->url = stracpy((unsigned char *)url); } return 1;}/* Allocates and returns a bookmark */struct bookmark *create_bookmark(const unsigned char *title, const unsigned char *url) { struct bookmark *new_bm = NULL; size_t title_size; /* How much mem to allocate for the strings */ size_t url_size; title_size = strlen(title) + 1; url_size = strlen(url) + 1; if (title_size > MAXINT) overalloc(); if (url_size > MAXINT) overalloc(); new_bm = mem_alloc(sizeof(struct bookmark)); new_bm->title = mem_alloc(title_size); new_bm->url = mem_alloc(url_size); strncpy(new_bm->title, title, title_size); strncpy(new_bm->url, url, url_size); return new_bm;}/* Deletes a bookmark, given the id. Returns 0 on failure (no such bm), 1 on success */int delete_bookmark_by_id(bookmark_id id) { struct bookmark *bm; bm = get_bookmark_by_id(id); if (bm == NULL) return 0; del_from_list(bm); /* Now wipe the bookmark */ mem_free(bm->title); mem_free(bm->url); mem_free(bm); return 1;}/****************************************************************************** Bookmark manager stuff.*****************************************************************************/void bookmark_edit_dialog( struct terminal *, unsigned char *, const unsigned char *, const unsigned char *, struct session *, struct dialog_data *, void when_done(struct dialog *), void *);/* Gets the head of the bookmark list kept by the dialog (the one used for display purposes *//* I really should use this somewhere...static inline *list_head bookmark_dlg_list_get(struct dialog) { return dialog->items[BM_BOX_IND].data;}*//* Clears the bookmark list from the bookmark_dialog */static inline void bookmark_dlg_list_clear(struct list_head *bm_list) { free_list( *bm_list );}/* Updates the bookmark list for a dialog. Returns the number of bookmarks. FIXME: Must be changed for hierarchical bookmarks.*/int bookmark_dlg_list_update(struct list_head *bm_list) { struct bookmark *bm; /* Iterator over bm list */ struct box_item *item; /* New box item (one per displayed bookmark) */ unsigned char *text; int count = 0; bookmark_id id; /* Empty the list */ bookmark_dlg_list_clear(bm_list); /* Copy each bookmark into the display list */ foreach(bm, bookmarks) { /* Deleted in bookmark_dlg_clear_list() */ item = mem_alloc( sizeof(struct box_item) + strlen(bm->title) + 1); item->text = text = ((unsigned char *)item + sizeof(struct box_item)); item->data = (void *)(id = bm->id); /* Note that free_i is left at zero */ strcpy(text, bm->title); add_to_list( *bm_list, item); count++; } return count;}/* Creates the box display (holds everything EXCEPT the actual rendering data) */struct dlg_data_item_data_box *bookmark_dlg_box_build(struct dlg_data_item_data_box **box) { /* Deleted in abort */ *box = mem_alloc( sizeof(struct dlg_data_item_data_box) ); memset(*box, 0, sizeof(struct dlg_data_item_data_box)); init_list((*box)->items); (*box)->list_len = bookmark_dlg_list_update(&((*box)->items)); return *box;}/* Get the id of the currently selected bookmark */bookmark_id bookmark_dlg_box_id_get(struct dlg_data_item_data_box *box) { struct box_item *citem; int sel; sel = box->sel; if (sel == -1) return BAD_BOOKMARK_ID; /* Sel is an index into the list of bookmarks. Therefore, we spin thru until sel equals zero, and return the id at that point */ foreach(citem, box->items) { if (sel == 0) return (bookmark_id)(citem->data); sel--; } return BAD_BOOKMARK_ID;}/* Cleans up after the bookmark dialog */void bookmark_dialog_abort_handler(struct dialog_data *dlg) { struct dlg_data_item_data_box *box; box = (struct dlg_data_item_data_box *)(dlg->dlg->items[BM_BOX_IND].data); /* Zap the display list */ bookmark_dlg_list_clear(&(box->items)); /* Delete the box structure */ mem_free(box);}/* Handles events for a bookmark dialog */int bookmark_dialog_event_handler(struct dialog_data *dlg, struct event *ev) { struct dialog_item_data *di; switch (ev->ev) { case EV_KBD: di = &dlg->items[dlg->selected]; /* Catch change focus requests */ if (ev->x == KBD_RIGHT || (ev->x == KBD_TAB && !ev->y)) { /* MP: dirty crap!!! this should be done in bfu.c */ /* Move right */ display_dlg_item(dlg, &dlg->items[dlg->selected], 0); if (++dlg->selected >= BM_BOX_IND) dlg->selected = 0; display_dlg_item(dlg, &dlg->items[dlg->selected], 1); return EVENT_PROCESSED; } if (ev->x == KBD_LEFT || (ev->x == KBD_TAB && ev->y)) { /* Move left */ display_dlg_item(dlg, &dlg->items[dlg->selected], 0); if (--dlg->selected < 0) dlg->selected = BM_BOX_IND - 1; display_dlg_item(dlg, &dlg->items[dlg->selected], 1); return EVENT_PROCESSED; } /* Moving the box */ if (ev->x == KBD_DOWN) { box_sel_move(&dlg->items[BM_BOX_IND], 1); show_dlg_item_box(dlg, &dlg->items[BM_BOX_IND]); return EVENT_PROCESSED; } if (ev->x == KBD_UP) { box_sel_move(&dlg->items[BM_BOX_IND], -1); show_dlg_item_box(dlg, &dlg->items[BM_BOX_IND]); return EVENT_PROCESSED; } if (ev->x == KBD_PAGE_DOWN) { box_sel_move(&dlg->items[BM_BOX_IND], dlg->items[BM_BOX_IND].item->gid / 2); show_dlg_item_box(dlg, &dlg->items[BM_BOX_IND]); return EVENT_PROCESSED; } if (ev->x == KBD_PAGE_UP) { box_sel_move(&dlg->items[BM_BOX_IND], (-1) * dlg->items[BM_BOX_IND].item->gid / 2); show_dlg_item_box(dlg, &dlg->items[BM_BOX_IND]); return EVENT_PROCESSED; } /* Selecting a button */ break; case EV_INIT: case EV_RESIZE: case EV_REDRAW: case EV_MOUSE: case EV_ABORT: break; default: internal("Unknown event received: %d", ev->ev); } return EVENT_NOT_PROCESSED;}/* The titles to appear in the bookmark add dialog */unsigned char *bookmark_add_msg[] = { TEXT(T_BOOKMARK_TITLE), TEXT(T_URL),};/* The titles to appear in the bookmark manager */unsigned char *bookmark_dialog_msg[] = { TEXT(T_BOOKMARKS),};/* Loads the selected bookmark */void menu_goto_bookmark(struct terminal *term, void *url, struct session *ses) { goto_url(ses, (unsigned char*)url);}/* Gets the url of the requested bookmark. * * This returns a pointer to the url's data. Be gentle with it. * * Returns a NULL if the bookmark has no url, AND if the passed bookmark id is * invalid. */const unsigned char *bookmark_get_url(bookmark_id id) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -