回精華區
作者itoc, 信區: itoc
標題[功能] xover.c 預覽
時間03/06/08
作者: itoc (太陽花兒~) 看板: plan
標題: [功能] 預覽
時間: Sun Dec 22 17:29:07 2002                          Updated: 2006/04/17

  [註] 做了本功能新增,就無需做 "看板說明" 這篇功能的新增

  首先新增看板說明的程式

: global.h

#define FN_VCH          ".VCH"          /* vote control header */
#define FN_NOTE         "note"          /* 進板畫面 */
+ #define FN_EXPLAIN      "explain"       /* 看板說明 */

: global.h

VAR char *fn_plans      INI(FN_PLANS);
VAR char *fn_note       INI(FN_NOTE);
+ VAR char *fn_explain    INI(FN_EXPLAIN);

: board.c:class_explain() 新增這函式在 class_help() 之前

static int
class_explain(xo)
  XO *xo;
{
  int mode, chn;
  char *img, *str;
  short *chp, *chx;
  char fpath[64], brdname[BNLEN + 1], *blist;
  BRD *brd;

  chp = (short *) xo->xyz + xo->pos;
  chn = *chp;

  if (chn >= 0)     /* 一般看板 */
  {
    brd = bshm->bcache + chn;
    blist = brd->BM;
    if (!(blist[0] > ' ' && is_bm(blist, cuser.userid)))
      return XO_NONE;
  }
  else              /* 分類群組 */
  {
    if (!HAS_PERM(PERM_ALLBOARD))
      return XO_NONE;
  }

  mode = vans("看板說明 (D)刪除 (E)修改 (Q)取消?[E] ");
  if (mode != 'q')
  {
    if (chn >= 0)
    {
      brd_fpath(fpath, brd->brdname, fn_explain);
    }
    else
    {
      img = class_img;
      chx = (short *) img + (CH_END - chn);
      str_ncpy(brdname, img + *chx, IDLEN + 1);
      if (str = strchr(brdname, '/'))         /* skip '/' */
        *str = '\0';
      sprintf(fpath, "run/%s.%s", fn_explain, brdname);
    }

    if (mode == 'd')
    {
      unlink(fpath);
    }
    else
    {
      if (vedit(fpath, 0))  /* Thor.981020: 注意被talk的問題 */
        vmsg(msg_cancel);
      return class_head(xo);
    }
  }
  return XO_FOOT;
}

: board.c:class_cb[]

+ 'l', class_explain,          // 按鍵自定 
  'h', class_help,

> ---------------------------------------------------------------- <

  接下來新增 xo_knee() 的部分

  把 XO 格式改成 head + neck + body + knee + foot
  其中 knee 是預覽
  使用者在看板列表/文章列表/使用者名單/好友名單/...等地方按 !
  切換預覽模式,可以預覽文章/Query/看板說明/...

: modes.h

#define XO_RSIZ         256             /* max record length */
- #define XO_TALL         (b_lines - 3)

: global.h

VAR int b_lines;                /* bottom line */
+ VAR int XO_TALL;                /* page size = b_lines - 3 */

: bbsd.c:term_init()

  else
  {
    b_lines = 23;
    b_cols = 79;
  }

  d_cols = b_cols - 79;

+ XO_TALL = b_lines - 3;
}

: visio.c:iac_count()

      /* fuse.030518: 線上調整畫面大小,重抓 b_lines */
      if ((*look) == TELOPT_NAWS)
      {
+       int knee;
+       knee = XO_TALL == b_lines - 7;
        b_lines = ntohs(* (short *) (look + 3)) - 1;
        b_cols = ntohs(* (short *) (look + 1)) - 1;
        if (b_lines >= T_LINES)
          b_lines = T_LINES - 1;
        else if (b_lines < 23)
          b_lines = 23;
        if (b_cols >= T_COLS)
          b_cols = T_COLS - 1;
        else if (b_cols < 79)
          b_cols = 79;
        d_cols = b_cols - 79;
+       XO_TALL = knee ? b_lines - 7 : b_lines - 3;
      }

: talk.c

- static pickup ulist_pool[MAXACTIVE];
+ pickup ulist_pool[MAXACTIVE];
static int pickup_ship = 0;     /* 0:故鄉 !=0:友誼敘述 */

: board.c

- static char *class_img;
+ char *class_img;
static XO board_xo;
BRD *xbrd;

: xover.c:xover()

    else if (cmd >= '1' && cmd <= '9')
    {
      cmd = xo_jump(cmd, zone);
    }
+   else if (cmd == '!')
+   {
+     XO_TALL = (XO_TALL == b_lines - 3) ? b_lines - 7 : b_lines - 3;
+     cmd = XO_LOAD;
+   }
    else

: xover.c:xover()

    if (xo->max > 0)            /* Thor:若是無東西就不show了 */
    {
      num = 3 + pos - xo->top;
      move(num, 0);
      outc('>');
+     xo_knee(xo, zone);
    }

: xover.c:preview_file()
: xover.c:preview_userid()
: xover.c:preview_tip()
: xover.c:xo_knee()

  這些函式加在 xover() 之前面

static void
preview_file(fpath, skipline)
  char *fpath;
  int skipline;
{
  int i;
  char buf[ANSILINELEN], *str;
  FILE *fp;

  if (!(fp = fopen(fpath, "r")))
    return;

  for (i = 0; i < skipline; i++)        /* 略過前幾行 */
    fgets(buf, ANSILINELEN, fp);

  for (i = 0; i < 3;)                   /* 預覽三行 */
  {
    if (fgets(buf, SCR_WIDTH + 1, fp))
    {
      if (*buf == '>' || *buf == '\n')
        continue;
      if (i == 2)
      {
        if (str = strchr(fpath, '\n'))
          *str = '\0';  /* 把 '\n' 換成 '\0',避免把 foot 吃了 */
      }
      outx(buf);
      i++;
    }
    else
      break;
  }

  outs(str_ransi);      /* 還原 ansi-code 避免文章裡面沒有還原 */
  fclose(fp);
}


static void
preview_userid(userid)
  char *userid;
{
  ACCT acct;

  acct_load(&acct, userid);
  prints("%s(%s) 上站 %d 次,文章 %d 篇,%s通過身分認證\n",
    userid, acct.username, acct.numlogins, acct.numposts,
    acct.userlevel & PERM_VALID ? "已經" : "尚未");
  prints("上次(%s)來自(%s)", Btime(&acct.lastlogin), acct.lasthost);
}


static void
preview_tip()
{
  int i, j, msg_num;
  char msg[128];
  FILE *fp;

  if (!(fp = fopen(FN_ETC_TIP, "r")))
    return;

  fgets(msg, 128, fp);
  msg_num = atoi(msg);         /* 第一行記錄總篇數 */
  i = time(0) % msg_num + 1;
  j = 0;

  while (j < i)                        /* 取第 i 個 tip */
  {
    fgets(msg, 128, fp);
    if (msg[0] == '#')
      j++;
  }

  fgets(msg, 128, fp);
  outs(msg);
  fgets(msg, 128, fp);
  outs(msg);
  fclose(fp);
}


static void
xo_knee(xo, zone)
  XO *xo;
  int zone;
{
  int cur;
  char fpath[64];

  if (XO_TALL == b_lines - 3)
    return;

  for (cur = b_lines - 4; cur < b_lines; cur++)
  {
    move(cur, 0);
    clrtoeol();
  }
  move(b_lines - 4, 0);
  prints("%s\n", msg_seperator);

  cur = xo->pos - xo->top;

  switch (zone)
  {
  /* ------------ */
  /* 預覽看板說明 */
  /* ------------ */
  case XZ_CLASS:
    {
      short *chp;
      int chn;
      chp = (short *) xo->xyz + xo->pos;
      chn = *chp;
      if (chn >= 0)     /* 一般看板 */
      {
        extern BCACHE *bshm;
        brd_fpath(fpath, (bshm->bcache + chn)->brdname, fn_explain);
      }
      else              /* 分類群組 */
      {
        extern char *class_img;
        char *img, *str;
        short *chx;
        char brdname[IDLEN + 1];
        img = class_img;
        chx = (short *) img + (CH_END - chn);
        str_ncpy(brdname, img + *chx, IDLEN + 1);
        if (str = strchr(brdname, '/'))     /* skip '/' */
          *str = '\0';
        sprintf(fpath, "run/%s.%s", fn_explain, brdname);
      }
      preview_file(fpath, 0);
    }
    break;

  /* ------------ */
  /* 預覽 Query   */
  /* ------------ */
  case XZ_ULIST:
    {
      typedef UTMP *pickup;
      extern pickup ulist_pool[];
      preview_userid(ulist_pool[xo->pos]->userid);
    }
    break;

  case XZ_PAL:
    preview_userid(((PAL *) xo_pool + cur)->userid);
    break;

#ifdef HAVE_ALOHA
  case XZ_ALOHA:
    preview_userid(((ALOHA *) xo_pool + cur)->userid);
    break;
#endif

  case XZ_BMW:
    preview_userid(((BMW *) xo_pool + cur)->userid);
    break;

  /* ------------ */
  /* 預覽文章信件 */
  /* ------------ */
  case XZ_XPOST:
  case XZ_MBOX:
  case XZ_POST:
    {
      HDR *hdr;
      hdr = (HDR *) xo_pool + cur;
      if (hdr->xmode & POST_RESTRICT)
        break;
      hdr_fpath(fpath, xo->dir, hdr);
      preview_file(fpath, 4);
    }
    break;

  /* ------------ */
  /* 預覽文章     */
  /* ------------ */
#ifdef HAVE_SONG
  case XZ_SONG:
#endif
  case XZ_GEM:
    {
      HDR *hdr;
      hdr = (HDR *) xo_pool + cur;
      if (hdr->xmode & (GEM_FOLDER | GEM_RESTRICT))
        break;
      hdr_fpath(fpath, xo->dir, hdr);
      preview_file(fpath, 4);
    }
    break;

  /* ------------ */
  /* 預覽 Tip     */
  /* ------------ */
  case XZ_VOTE:
#ifdef MY_FAVORITE
  case XZ_MF:
#endif
#ifdef HAVE_COSIGN
  case XZ_COSIGN:
#endif
#ifdef HAVE_XYNEWS
  case XZ_NEWS:
#endif
    preview_tip();
    break;
  }
}

--
□ 本文章由 itocitoc.Dorm-GD2.NCTU.edu.tw 發表
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻