From 4311844d85cc4e4feca1dc9221ce7725626e7c82 Mon Sep 17 00:00:00 2001 From: victor Date: Sun, 5 Oct 2003 08:01:41 +0000 Subject: tmp git-svn-id: http://opensvn.csie.org/pttbbs/branches/victor.tmp@1216 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- pttbbs/docs/fav.txt | 36 +++++++ pttbbs/include/proto.h | 42 ++++++++ pttbbs/mbbsd/board.c | 264 +++++++++++++++++-------------------------------- 3 files changed, 170 insertions(+), 172 deletions(-) create mode 100644 pttbbs/docs/fav.txt diff --git a/pttbbs/docs/fav.txt b/pttbbs/docs/fav.txt new file mode 100644 index 00000000..c8edf8d9 --- /dev/null +++ b/pttbbs/docs/fav.txt @@ -0,0 +1,36 @@ +Favorite ver.4 + +Feature +======= +•重寫、整個架構改變 +•folding + +Structure +========= + fav4 的主要架構如下: + +•fav_t + 進入我的最愛時,看到的東西就是根據 fav_t 生出來的。 + 裡面紀錄者,這一個 level 中有多少個看板、目錄、分隔線。(favh) + +•fav_type_t + 這算是架在以下三個東西之上的介面,等於是將他們視為同一種東西,方便之後的存取。 + 用一個 void * 指標指向某塊記憶體,存取時可透過 type 變數來得知正確的型態。 + +•fav_board_t + 紀錄了 bid 及上次拜訪時間。 + +•fav_line_t + 紀錄了 lid + +•fav_folder_t + 紀錄了 fid 及可自訂的名稱。 + +•fav.c 中以 cast_(board|line|folder)_t() 來將一個 fav_type_t 轉為正確的型態。 + +Policy +====== +•為了避免過度的資料搬移,當將一個 item 從我的最愛中移除時,只將他的 FAVH_FAV + flag 移除。而沒有這個 flag 的 item 也不被視為我的最愛。 +•我的最愛中,沒設 FAVH_FAV 的資料,將在某些時候,如寫入檔案時,呼叫 + rebuild_fav 清除乾淨。 diff --git a/pttbbs/include/proto.h b/pttbbs/include/proto.h index 41fa2a7f..b202e20e 100644 --- a/pttbbs/include/proto.h +++ b/pttbbs/include/proto.h @@ -200,6 +200,48 @@ void editlock(char *fpath); void editunlock(char *fpath); int iseditlocking(char *fpath, char *action); +/* fav */ +fav_type_t *get_current_entry(void); +void fav_set_old_folder(fav_t *fp); +fav_t *get_current_fav(void); +int get_item_type(fav_type_t *ft); +char *get_folder_title(int fid); +void set_attr(fav_type_t *ft, int bit, int bool); +void fav_sort_by_name(void); +void fav_sort_by_class(void); +int fav_load(void); +int fav_save(void); +void fav_remove_current(void); +void fav_remove_board_from_whole(int bid); +char getbrdattr(short bid); +time_t getbrdtime(short bid); +void setbrdtime(short bid, time_t t); +int fav_getid(fav_type_t *ft); +int fav_add(fav_t *fp, fav_type_t *item); +void move_in_current_folder(int from, int to); +void fav_move(int from, int to); +fav_type_t *fav_add_line(int place); +fav_type_t *fav_add_folder(int place); +fav_type_t *fav_add_board(int bid, int place); +void fav_tag_current(int bool); +void fav_remove_all_tagged_item(void); +void fav_remove_all_tagged_item(void); +void fav_add_all_tagged_item(void); +void fav_remove_all_tag(void); +void fav_set_folder_title(fav_type_t *ft, char *title); +int fav_max_folder_level(void); +void fav_folder_in(void); +void fav_folder_out(void); +void fav_free(void); +int fav_v3_to_v4(void); +void fav_cursor_up(void); +void fav_cursor_down(void); +void fav_cursor_up_step(int step); +void fav_cursor_down_step(int step); +void fav_cursor_set(int where); +int is_set_attr(fav_type_t *ft, int bit); +void cleanup(void); + /* friend */ void friend_edit(int type); void friend_load(); diff --git a/pttbbs/mbbsd/board.c b/pttbbs/mbbsd/board.c index c29180d9..d7f4e0b7 100644 --- a/pttbbs/mbbsd/board.c +++ b/pttbbs/mbbsd/board.c @@ -272,154 +272,6 @@ fav_t *fav; static short brdnum; static char yank_flag = 1; -int cmpfav(const void *a, const void *b) -{ - if( *(short *)a > ((fav_board_t *)b)->bid ) - return 1; - else if( *(short *)a == ((fav_board_t *)b)->bid ) - return 0; - return -1; -} - -fav_board_t *getfav(short bid) -{ - int i; - for(i = 0; i < fav->nDatas; i++) - if(fav->b[i].bid == bid) - break; - return i == fav->nDatas ? NULL : &fav->b[i]; -} - -char getfavattr(short bid) -{ - fav_board_t *ptr = getfav(bid); - if( ptr == NULL ) - return 0; // default here - else - return ptr->attr; -} - -time_t getfavtime(short bid) -{ - fav_board_t *ptr = getfav(bid); - if( ptr == NULL ) - return login_start_time; // default here - else - return ptr->lastvisit; -} - -void basemovefav(int src, int des) -{ - int i; - fav_board_t tmp = fav->b[src]; - - if(src < des){ - for(i = src; i < des; i++) - fav->b[i] = fav->b[i + 1]; - } - else{ // des < src - for(i = src; i > des; i--) - fav->b[i] = fav->b[i - 1]; - } - fav->b[des] = tmp; - - brdnum = -1; -} - -void movefav(int old, int new) -{ - int i, src = -1, des = -1; - favchange = 1; - - for(i = 0; i < fav->nDatas; i++){ - if(nbrd[old].bid == fav->b[i].bid) - src = i; - if(nbrd[new].bid == fav->b[i].bid) - des = i; - } - - if(src == -1 || des == -1) - return; - basemovefav(src, des); -} - -void delfavline(int bid, int num) -{ - int i; - - movefav(num, --brdnum); - fav->nLines++; - fav->nDatas--; - - for(i = 0; i < fav->nDatas; i++) - if(fav->b[i].bid < bid) - fav->b[i].bid++; - for(i = 0; i < brdnum; i++) - if(nbrd[i].bid < bid) - nbrd[i].bid++; -} - -void setfav(short bid, char attr, char mode, time_t t) -{ - /* mode: 0: 設成 off, 1: 設成 on, 2: 反相 */ - fav_board_t *ptr = getfav(bid); - - favchange = 1; - - if( ptr != NULL ){ - if( mode == 2 ) - ptr->attr ^= attr; - else if( mode ) - ptr->attr |= attr; - else - ptr->attr &= ~attr; - if( t ) - ptr->lastvisit = t; - } - else{ - int where; - if( fav->nDatas == fav->nAllocs ){ -#ifdef DEBUG - vmsg("realloc fav"); -#endif - fav = realloc(fav, - sizeof(fav_t) + - sizeof(fav_board_t) * - (16 + fav->nAllocs)); - memset(&fav->b[fav->nDatas], 0, sizeof(fav_board_t) * 16); - fav->nAllocs += 16; - } - - where = fav->nDatas; - - if( attr & BRD_LINE ){ - fav->b[where].bid = --(fav->nLines); - fav->b[where].attr = mode ? (BRD_LINE | BRD_FAV) : 0; - } - else{ - fav->b[where].bid = bid ; - fav->b[where].attr = mode ? attr : 0; - } - - fav->b[where].lastvisit = t ? t : login_start_time; - fav->nDatas++; - } -} - -void imovefav(int old) -{ - char buf[5]; - int new; - - getdata(b_lines - 1, 0, "請輸入新次序:", buf, sizeof(buf), DOECHO); - new = atoi(buf) - 1; - if (new < 0 || brdnum <= new){ - vmsg("輸入範圍有誤!"); - return; - } - movefav(old, new); -} - #define BRD_OLD 0 #define BRD_NEW 1 #define BRD_END 2 @@ -473,19 +325,22 @@ void updatenewfav(int mode) } } -void favclean(fav_t *fav){ - int i; - boardheader_t *bptr; - - for(i = 0; i < fav->nDatas; i++){ - if(fav->b[i].attr & BRD_LINE) - continue; - bptr = &bcache[ fav->b[i].bid - 1 ]; - if(!(fav->b[i].attr & BRD_FAV) || !Ben_Perm(bptr)){ - basemovefav(i, fav->nDatas--); - continue; - } +void imovefav(int old) +{ + char buf[5]; + int new; + + getdata(b_lines - 1, 0, "請輸入新次序:", buf, sizeof(buf), DOECHO); + new = atoi(buf) - 1; + if (new < 0 || brdnum <= new){ + vmsg("輸入範圍有誤!"); + return; } + move_in_current_folder(old, new); +} + +inline int validboard(int bid){ + return bcache[bid].brdname[0]; } void freefav(fav_t *fav){ @@ -785,7 +640,7 @@ load_boards(char *key) if (class_bid <= 0) { if( yank_flag == 0 ){ // fav mode nbrd = (boardstat_t *)malloc(sizeof(boardstat_t) * fav->nDatas); - for( i = 0 ; i < fav->nDatas ; ++i ){ + for( i = 0 ; i < fav->nAllocs; ++i ){ if( fav->b[i].attr & BRD_FAV ){ if( fav->b[i].attr & BRD_LINE && !key[0]) addnewbrdstat(fav->b[i].bid - 1, BRD_FAV | BRD_LINE); @@ -963,15 +818,31 @@ show_brdlist(int head, int clsflag, int newflag) "\033[1;32m", "\033[1;33m"}; char *unread[2] = {"\33[37m \033[m", "\033[1;31mˇ\033[m"}; + if (yank_flag == 0 && nbrd[0].myattr == 0){ + move(3, 0); + prints(" --- 空目錄 ---"); + return; + } + while (++myrow < b_lines) { move(myrow, 0); clrtoeol(); if (head < brdnum) { ptr = &nbrd[head++]; - if(ptr->myattr & BRD_LINE){ + if (ptr->myattr & BRD_LINE){ prints("%5d %c ------------ ------------------------------------------", head, ptr->myattr & BRD_TAG ? 'D' : ' '); continue; } + else if (ptr->myattr & BRD_FOLDER){ + char *title = get_folder_title(ptr->bid); + prints("%5d %c %sMyFavFolder\033[m 目錄 □%-34s\033[m", + head, + ptr->myattr & BRD_TAG ? 'D' : ' ', + (cuser.uflag2 & FAVNOHILIGHT)? "" : "\033[1;36m", + title); + continue; + } + if (class_bid == 1) prints(" "); if (!newflag) { @@ -1080,6 +951,7 @@ choose_board(int newflag) do { if (brdnum <= 0) { load_boards(keyword); + fav_cursor_set(num); if (brdnum <= 0) { if (keyword[0] != 0) { mprints(b_lines - 1, 0, "沒有任何看板標題有此關鍵字 " @@ -1104,10 +976,16 @@ choose_board(int newflag) } head = -1; } - if (num < 0) + + /* reset the cursor when out of range */ + if (num < 0){ num = 0; - else if (num >= brdnum) + fav_cursor_set(num); + } + else if (num >= brdnum){ num = brdnum - 1; + fav_cursor_set(num); + } if (head < 0) { if (newflag) { @@ -1157,20 +1035,26 @@ choose_board(int newflag) case Ctrl('B'): if (num) { num -= p_lines; + fav_cursor_down_step(p_lines); break; } case KEY_END: case '$': num = brdnum - 1; + fav_cursor_set(num); break; case ' ': case KEY_PGDN: case 'N': case Ctrl('F'): - if (num == brdnum - 1) + if (num == brdnum - 1){ num = 0; - else + fav_cursor_set(num); + } + else{ num += p_lines; + fav_cursor_down_step(p_lines); + } break; case Ctrl('C'): cal(); @@ -1183,8 +1067,12 @@ choose_board(int newflag) case KEY_UP: case 'p': case 'k': - if (num-- <= 0) + if (num-- <= 0){ num = brdnum - 1; + fav_cursor_set(num); + } + else + fav_cursor_up(); break; case 't': ptr = &nbrd[num]; @@ -1194,11 +1082,13 @@ choose_board(int newflag) case KEY_DOWN: case 'n': case 'j': + fav_cursor_down(); if (++num < brdnum) break; case '0': case KEY_HOME: num = 0; + fav_cursor_set(num); break; case '1': case '2': @@ -1209,8 +1099,10 @@ choose_board(int newflag) case '7': case '8': case '9': - if ((tmp = search_num(ch, brdnum)) >= 0) + if ((tmp = search_num(ch, brdnum)) >= 0){ num = tmp; + fav_cursor_set(num); + } brdlist_foot(); break; case 'F': @@ -1342,6 +1234,16 @@ choose_board(int newflag) head = 9999; } break; + case 'T': + if (HAS_PERM(PERM_BASIC)) { + char title[64]; + fav_type_t *ft = get_current_entry(); + strlcpy(title, get_item_title(ft), sizeof(title)); + getdata_buf(b_lines - 1, 0, "請輸入檔名:", title, sizeof(title), DOECHO); + fav_set_folder_title(ft, title); + brdnum = -1; + } + break; case 'K': if (HAS_PERM(PERM_BASIC)) { char c, fname[80], genbuf[256]; @@ -1353,7 +1255,7 @@ choose_board(int newflag) break; switch(c){ case '1': - favclean(fav); + cleanup(); break; case '2': setuserfile(fname, FAV3); @@ -1361,7 +1263,7 @@ choose_board(int newflag) system(genbuf); break; case '3': - setuserfile(fname, FAV3); + setuserfile(fname, FAV4); sprintf(genbuf, "%s.bak", fname); if((fd = open(genbuf, O_RDONLY)) < 0){ vmsg("你沒有備份你的最愛喔"); @@ -1383,8 +1285,6 @@ choose_board(int newflag) vmsg("嘿嘿 這個功\能已經被我的最愛取代掉了喔!"); break; case 'Z': - if (!HAS_PERM(PERM_BASIC)) - break; cuser.uflag2 ^= FAVNEW_FLAG; if(cuser.uflag2 & FAVNEW_FLAG){ char fname[80]; @@ -1438,6 +1338,7 @@ choose_board(int newflag) break; } num = tmp; + fav_cursor_set(num); break; case 'E': if (HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU)) { @@ -1470,6 +1371,14 @@ choose_board(int newflag) brdnum = -1; } break; + case 'A': { + char buf[128]; + fav_type_t *ft = get_current_entry(); + fav_t *fp = get_current_fav(); + sprintf(buf, "d: %d b: %d f: %d bn: %d num: %d t: %d, id: %d", fp->nDatas, fp->nBoards, fp->nFolders, brdnum, num, ft->type, fav_getid(ft)); + vmsg(buf); + } + break; case KEY_RIGHT: case '\n': case '\r': @@ -1480,6 +1389,17 @@ choose_board(int newflag) ptr = &nbrd[num]; if(ptr->myattr & BRD_LINE) break; + else if (ptr->myattr & BRD_FOLDER){ + int t = num; + fav_folder_in(); + choose_board(0); + fav_folder_out(); + num = t; + fav_cursor_set(num); + brdnum = -1; + head = 9999; + break; + } if (!(B_BH(ptr)->brdattr & BRD_GROUPBOARD)) { /* 非sub class */ if (!(B_BH(ptr)->brdattr & BRD_HIDE) || -- cgit v1.2.3