summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-10-08 03:52:42 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-10-08 03:52:42 +0800
commit3e1e3fbe83fdd03ba43b6a26d1644a560b9c51de (patch)
treef0e507c26b79719171c7fdbb330949595773d561
parent90dc414a63b2762345763381cf1363a966fabc97 (diff)
downloadpttbbs-3e1e3fbe83fdd03ba43b6a26d1644a560b9c51de.tar
pttbbs-3e1e3fbe83fdd03ba43b6a26d1644a560b9c51de.tar.gz
pttbbs-3e1e3fbe83fdd03ba43b6a26d1644a560b9c51de.tar.bz2
pttbbs-3e1e3fbe83fdd03ba43b6a26d1644a560b9c51de.tar.lz
pttbbs-3e1e3fbe83fdd03ba43b6a26d1644a560b9c51de.tar.xz
pttbbs-3e1e3fbe83fdd03ba43b6a26d1644a560b9c51de.tar.zst
pttbbs-3e1e3fbe83fdd03ba43b6a26d1644a560b9c51de.zip
* pmore: use key_handler callback to prevent dirty hotkey list
* pmore: new pluggable help system git-svn-id: http://opensvn.csie.org/pttbbs/trunk@4912 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--pttbbs/include/proto.h7
-rw-r--r--pttbbs/mbbsd/more.c200
-rw-r--r--pttbbs/mbbsd/pmore.c403
3 files changed, 391 insertions, 219 deletions
diff --git a/pttbbs/include/proto.h b/pttbbs/include/proto.h
index 45466453..bc1970bc 100644
--- a/pttbbs/include/proto.h
+++ b/pttbbs/include/proto.h
@@ -369,10 +369,13 @@ int m_sob(void);
void m_sob_brd(char *bname,char *fromdir);
#endif
-/* old more */
+/* pager */
int more(const char *fpath, int promptend);
/* piaip's new pager, pmore.c */
-int pmore(const char *fpath, int promptend);
+int pmore (const char *fpath, int promptend);
+int pmore2(const char *fpath, int promptend, void *ctx,
+ int (*key_handler) (int key, void *ctx),
+ int (*help_handler)(int y, void *ctx));
/* piaip's new telnet, telnet.c */
extern void telnet_init(int do_init_cmd);
extern ssize_t tty_read(unsigned char *buf, size_t max);
diff --git a/pttbbs/mbbsd/more.c b/pttbbs/mbbsd/more.c
index 878099f9..ffd368cc 100644
--- a/pttbbs/mbbsd/more.c
+++ b/pttbbs/mbbsd/more.c
@@ -20,43 +20,186 @@
* documentation and/or other materials provided with the distribution.
*/
+static int
+check_sysop_edit_perm(const char *fpath)
+{
+ if (!HasUserPerm(PERM_SYSOP) ||
+ strcmp(fpath, "etc/ve.hlp") == 0)
+ return 0;
+
+#ifdef BN_SECURITY
+ if (strcmp(currboard, BN_SECURITY) == 0)
+ return 0;
+#endif // BN_SECURITY
+
+ return 1;
+}
+
#ifdef USE_PMORE
+static int
+common_pmore_key_handler(int ch, void *ctx)
+{
+ switch(ch)
+ {
+ // Special service keys
+ case 'z':
+ if (!HasUserPerm(PERM_BASIC))
+ break;
+ return RET_DOCHESSREPLAY;
+
+#if defined(USE_BBSLUA) && !defined(DISABLE_BBSLUA_IN_PAGER)
+ case 'L':
+ case 'l':
+ if (!HasUserPerm(PERM_BASIC))
+ break;
+ return RET_DOBBSLUA;
+#endif
+
+ // Query information and file touch
+ case 'Q':
+ return RET_DOQUERYINFO;
+
+ case Ctrl('T'):
+ if (!HasUserPerm(PERM_BASIC))
+ break;
+ return RET_COPY2TMP;
+
+ case 'E':
+ if (!check_sysop_edit_perm("")) // for early check, skip file name (must check again later)
+ break;
+ return RET_DOSYSOPEDIT;
+
+ // Making Response
+ case '%':
+ case 'X':
+ return RET_DORECOMMEND;
+
+ case 'r': case 'R':
+ return RET_DOREPLY;
+
+ case 'Y': case 'y':
+ return RET_DOREPLYALL;
+
+ // Special Navigation
+ case 's':
+ if (!HasUserPerm(PERM_BASIC) ||
+ currstat != READING)
+ break;
+ return RET_SELECTBRD;
+
+ /* ------- SOB THREADED NAVIGATION EXITING KEYS ------- */
+ // I'm not sure if these keys are all invented by SOB,
+ // but let's honor their names.
+ // Kaede, Raw, Izero, woju - you are all TWBBS heroes
+ // -- by piaip, 2008.
+ case 'A':
+ return AUTHOR_PREV;
+ case 'a':
+ return AUTHOR_NEXT;
+ case 'F': case 'f':
+ return READ_NEXT;
+ case 'B': case 'b':
+ return READ_PREV;
+
+ /* from Kaede, thread reading */
+ case ']':
+ case '+':
+ return RELATE_NEXT;
+ case '[':
+ case '-':
+ return RELATE_PREV;
+ case '=':
+ return RELATE_FIRST;
+ }
+
+ return DONOTHING;
+}
+
+static const char
+*hlp_nav [] =
+{ "【瀏覽指令】",
+ "下篇文章 ", "f",
+ "前篇文章 ", "b",
+ "同主題下篇", "] +",
+ "同主題前篇", "[ -",
+ "同主題循序", "t",
+ "同主題首篇", "=",
+ "同作者前篇", "A",
+ "同作者下篇", "a",
+ NULL,
+},
+*hlp_reply [] =
+{ "【回應指令】",
+ "推薦文章", "% X",
+ "回信回文", "r",
+ "全部回覆", "y",
+ NULL,
+},
+*hlp_spc [] =
+{ "【特殊指令】",
+ "查詢資訊 ", "Q",
+ "存入暫存檔", "^T",
+ "切換看板 ", "s",
+ "棋局打譜 ", "z",
+#if defined(USE_BBSLUA) && !defined(DISABLE_BBSLUA_IN_PAGER)
+ "執行BBSLua", "L l",
+#endif
+ NULL,
+};
+
+// TODO make this help renderer into vtuikit or other location someday
+static int
+common_pmore_help_handler(int y, void *ctx)
+{
+ // simply show ptt special function keys
+ int i;
+ const char ** p[3] = { hlp_nav, hlp_reply, hlp_spc };
+ const int cols[3] = { 29, 29, 19 }, // columns
+ desc[3] = { 11, 11, 13 }; // desc width
+ prints( "\n" ANSI_COLOR(1;31) "%-*s%-*s%-*s" ANSI_RESET "\n",
+ cols[0], *p[0]++, cols[1], *p[1]++, cols[2], *p[2]++);
+ // render help page
+ while (*p[0] || *p[1] || *p[2])
+ {
+ y++; outc(' ');
+ for ( i = 0; i < 3; i++ )
+ {
+ if (!*p[i]) {
+ prints("%*s", cols[i], "");
+ continue;
+ }
+ prints("%-*s", desc[i], *p[i]++);
+ prints(ANSI_COLOR(1;36) "%-*s" ANSI_RESET , cols[i]-desc[i], *p[i]++);
+ }
+ outs("\n");
+ }
+ PRESSANYKEY();
+ return 0;
+}
+
/* use new pager: piaip's more. */
-int more(const char *fpath, int promptend)
+int
+more(const char *fpath, int promptend)
{
- int r = pmore(fpath, promptend);
+ int r = pmore2(fpath, promptend,
+ (void*) fpath,
+ common_pmore_key_handler,
+ common_pmore_help_handler);
+ // post processing
switch(r)
{
case RET_DOSYSOPEDIT:
r = FULLUPDATE;
-
- if (!HasUserPerm(PERM_SYSOP) ||
- strcmp(fpath, "etc/ve.hlp") == 0)
- break;
-
-#ifdef BN_SECURITY
- if (strcmp(currboard, BN_SECURITY) == 0)
+ if (!check_sysop_edit_perm(fpath))
break;
-#endif // BN_SECURITY
-
log_filef("log/security", LOG_CREAT,
"%u %s %d %s admin edit file=%s\n",
(int)now, Cdate(&now), getpid(), cuser.userid, fpath);
-
veditfile(fpath);
break;
- case RET_SELECTBRD:
- r = FULLUPDATE;
- if (HasUserPerm(PERM_BASIC))
- {
- if (currstat == READING)
- return Select();
- }
- break;
-
case RET_COPY2TMP:
r = FULLUPDATE;
if (HasUserPerm(PERM_BASIC))
@@ -71,23 +214,24 @@ int more(const char *fpath, int promptend)
}
break;
+ case RET_SELECTBRD:
+ r = FULLUPDATE;
+ if (currstat == READING)
+ Select();
+ break;
+
case RET_DOCHESSREPLAY:
r = FULLUPDATE;
if (HasUserPerm(PERM_BASIC))
- {
ChessReplayGame(fpath);
- }
break;
#if defined(USE_BBSLUA) && !defined(DISABLE_BBSLUA_IN_PAGER)
case RET_DOBBSLUA:
r = FULLUPDATE;
- if (HasUserPerm(PERM_BASIC))
- {
+ // check permission again
+ if (HasUserPerm(PERM_BASIC))
bbslua(fpath);
- } else {
- vmsg("抱歉,此帳號無權限執行 BBS-Lua 程式。");
- }
break;
#endif
}
diff --git a/pttbbs/mbbsd/pmore.c b/pttbbs/mbbsd/pmore.c
index 3290266d..4abd393b 100644
--- a/pttbbs/mbbsd/pmore.c
+++ b/pttbbs/mbbsd/pmore.c
@@ -98,7 +98,6 @@
#define PMORE_USE_ASCII_MOVIE // support ascii movie
#define PMORE_USE_INTERNAL_HELP // display pmore internal help
#define PMORE_USE_REPLYKEY_HINTS // prompt user the keys to reply/commenting
-#define PMORE_USE_SOB_THREAD_NAV // use SOB-like thread navigation
#define PMORE_HAVE_SYNCNOW // system needs calling sync API
#define PMORE_HAVE_NUMINBUF // input system have num_in_buf API
#define PMORE_IGNORE_UNKNOWN_NAVKEYS // does not return for all unknown keys
@@ -122,16 +121,35 @@
// ----------------------------------------------------------- <LOCALIZATION>
// Messages for localization are listed here.
+
+#define PMORE_MSG_PROGVER "pmore 2007+"
+
#define PMORE_MSG_PREF_TITLE \
- " piaip's more: pmore 2007 設定選項 "
+ " piaip's more: " PMORE_MSG_PROGVER " 設定選項 "
#define PMORE_MSG_PREF_TITLE_QRAW \
- " piaip's more: pmore 2007 快速設定選項 - 色彩(ANSI碼)顯示模式 "
+ " piaip's more: " PMORE_MSG_PROGVER " 快速設定 - 色彩(ANSI碼)顯示模式 "
+#define PMORE_MSG_HELP_TITLE \
+ " piaip's more: " PMORE_MSG_PROGVER " 瀏覽程式使用說明"
+#define PMORE_MSG_HELP_PAUSE \
+ "請按任意鍵離開此說明畫面"
#define PMORE_MSG_WARN_FAKEUSERINFO \
- " ▲此頁內容會依閱\讀者不同,原文未必有您的資料 "
+ " ▲此頁內容會依閱\讀者不同,原文未必有您的資料 "
#define PMORE_MSG_WARN_MOVECMD \
- " ▲此頁內容含移位碼,可能會顯示偽造的系統訊息 "
+ " ▲此頁內容含移位碼,可能會顯示偽造的系統訊息 "
#define PMORE_MSG_SEARCH_KEYWORD \
- "[搜尋]關鍵字:"
+ "[搜尋]關鍵字:"
+#define PMORE_MSG_SEARCH_LETTERCASE \
+ "區分大小寫(Y/N/Q)? "
+#define PMORE_MSG_GOTO_PAGE \
+ "跳至此頁(若要改指定行數請在結尾加.): "
+#define PMORE_MSG_GOTO_LINE \
+ "跳至此行: "
+#define PMORE_MSG_QPREF_SUBJECT \
+ "色彩顯示方式:"
+#define PMORE_MSG_QPREF_OPTIONS \
+ "1.預設格式化內容\t2.原始ANSI控制碼\t3.純文字"
+#define PMORE_MSG_QPREF_PROMPT \
+ "請調整設定 (1-3 可直接選定,\\可切換) 或其它任意鍵結束。"
#define PMORE_MSG_MOVIE_DETECTED \
" ★ 這份文件是可播放的文字動畫,要開始播放嗎? [Y/n]"
@@ -145,6 +163,8 @@
" >>> 動畫播放中... 可按 q, Ctrl-C 或其它任意鍵停止";
#define PMORE_MSG_MOVIE_INTERACTION_PLAYING \
" >>> 互動式動畫播放中... 可按 q 或 Ctrl-C 停止";
+#define PMORE_MSG_MOVIE_INTERACTION_WAITSEL \
+ " >> 請輸入選項: (互動式動畫播放中,可按 q 或 Ctrl-C 中斷)"
#define PMORE_MSG_MOVIE_INTERACTION_STOPPED \
"已強制中斷互動式系統"
@@ -208,6 +228,9 @@
// free(fimage);
// +#endif // M3_USE_PMORE
// if (!cmd) /* ...
+// (3) if you want to override to override any special keys
+// or help pages, you may change to pmore2 and write
+// your own key_handler and help_handler.
#ifdef M3_USE_PMORE
// input/output API
#define getdata(y,x,msg,buf,size,mode) vget(y,x,msg,buf,size,mode)
@@ -223,7 +246,6 @@
#define READ_PREV 'k'
// environments and features
#undef PMORE_USE_INTERNAL_HELP
- #undef PMORE_USE_SOB_THREAD_NAV
#undef PMORE_USE_REPLYKEY_HINTS
#undef PMORE_HAVE_SYNCNOW
#undef PMORE_HAVE_NUMINBUF
@@ -555,11 +577,16 @@ enum MFSEARCH_DIRECTION {
fh.lines = -1; }
// Artwork
-#define OPTATTR_NORMAL ANSI_COLOR(0;34;47)
-#define OPTATTR_NORMAL_KEY ANSI_COLOR(0;31;47)
-#define OPTATTR_SELECTED ANSI_COLOR(0;1;37;46)
-#define OPTATTR_SELECTED_KEY ANSI_COLOR(0;31;46)
-#define OPTATTR_BAR ANSI_COLOR(0;1;30;47)
+#define OPTATTR_NORMAL ANSI_COLOR(0;34;47)
+#define OPTATTR_NORMAL_KEY ANSI_COLOR(0;31;47)
+#define OPTATTR_SELECTED ANSI_COLOR(0;1;37;46)
+#define OPTATTR_SELECTED_KEY ANSI_COLOR(0;31;46)
+#define OPTATTR_BAR ANSI_COLOR(0;1;30;47)
+#define PREFATTR_NORMAL ANSI_COLOR(0)
+#define PREFATTR_NORMAL_KEY ANSI_COLOR(0;1;31)
+#define PREFATTR_SELECTED ANSI_COLOR(0;1;36)
+#define PREFATTR_SELECTED_KEY ANSI_COLOR(0;1;31)
+#define PREFATTR_BAR ANSI_COLOR(0;1;30)
// --------------------------- </Aux. Structures>
@@ -681,6 +708,8 @@ MFFPROTO int mf_movieMaskedInput(int c);
// some magic value that your vkey() will never return
#define MOVIE_KEY_ANY (0x4d464b41)
+// some environments already converted 0x7F to 0x08,
+// but we'd still do it again here for compatibility.
#ifndef MOVIE_KEY_BS2
#define MOVIE_KEY_BS2 (0x7f)
#endif
@@ -727,8 +756,10 @@ mf_attach(const char *fn)
return 0;
}
+#ifdef MADV_SEQUENTIAL
// BSD mmap advise. comment if your OS does not support this.
madvise(mf.start, mf.len, MADV_SEQUENTIAL);
+#endif
mf.end = mf.start + mf.len;
mf.disps = mf.dispe = mf.start;
@@ -1912,44 +1943,13 @@ mf_display()
}
/* --------------------- MAIN PROCEDURE ------------------------- */
+
+/*
+ * sub-system prototype
+ */
MFPROTO void pmore_Preference();
MFPROTO void pmore_QuickRawModePref();
-// MFPROTO void pmore_Help();
-
-#ifdef PMORE_USE_INTERNAL_HELP
-static const char * const pmore_help[] = {
- "\0piaip's more: pmore 2007 瀏覽程式使用說明",
- "\01游標移動",
- "(k/↑) (j/↓/Enter) 上捲/下捲一行",
- "(^B/PgUp/BackSpace) 上捲一頁",
- "(^F/PgDn/Space/→) 下捲一頁",
- "(,/</S-TAB)(./>/TAB) 左/右捲動",
- "(0/g/Home) ($/G/End) 檔案開頭/結尾",
- "數字鍵 1-9 (;/:) 跳至輸入的頁數或行數",
- "\01進階瀏覽",
- "(/) (s) 搜尋關鍵字/切換至其它看板",
- "(n/N) 重複正/反向搜尋",
- "(f/b) 跳至下/上篇",
- "(a/A) 跳至同一作者下/上篇",
- "(t/[-/]+) 主題式瀏覽: 循序/前/後篇",
- "\01其他",
-
- // the line below is already aligned, because of the backslash.
- "(o)/(\\) 選項設定/色彩顯示模式",
-
-#if defined (PMORE_USE_ASCII_MOVIE) || defined(RET_DOCHESSREPLAY)
- "(p)/(z) 播放動畫/棋局打譜",
-#endif // defined(PMORE_USE_ASCII_MOVIE) || defined(RET_DOCHESSREPLAY)
-#ifdef RET_COPY2TMP
- "(Ctrl-T) 存入暫存檔",
-#endif
- "(q/←) (h/H/?/F1) 結束/本說明畫面",
-#ifdef DEBUG
- "(d) 切換除錯(debug)模式",
-#endif
- NULL
-};
-#endif // PMORE_USE_INTERNAL_HELP
+MFPROTO void pmore_Help(void *ctx, int (*help_handler)(int y, void *ctx));
/*
* pmore utility macros
@@ -1987,8 +1987,12 @@ PMORE_UINAV_FORWARDLINE()
/*
* piaip's more, a replacement for old more
*/
-int
-pmore(const char *fpath, int promptend)
+int
+pmore2(
+ const char *fpath, int promptend, void *ctx,
+ int (*key_handler) (int key, void *ctx),
+ int (*help_handler)(int y, void *ctx)
+ )
{
int flExit = 0, retval = 0;
int ch = 0;
@@ -2366,67 +2370,35 @@ pmore(const char *fpath, int promptend)
/* vkey() will do refresh(); */
ch = vkey();
+
+ // first, try custom key_handler
+ if (key_handler)
+ {
+ int r = key_handler(ch, ctx);
+ switch(r)
+ {
+ case -1:
+ // common return value of 'file not exist',
+ // meaning 'bypassing this key' here.
+ continue;
+
+ case 0:
+ // common return value of 'do nothing',
+ // meaning 'continue processing this key' here.
+ break;
+
+ default:
+ // for all other cases, looks like handler wants us to quit.
+ retval = r;
+ flExit = 1;
+ continue;
+ }
+ }
+
+ // built-in navigation keys
switch (ch) {
- /* -------------- NEW EXITING KEYS ------------------ */
-#ifdef RET_DOREPLY
- case 'r': case 'R':
- flExit = 1, retval = RET_DOREPLY;
- break;
- case 'Y': case 'y':
- flExit = 1, retval = RET_DOREPLYALL;
- break;
-#endif
-#ifdef RET_DORECOMMEND
- // recommend
- case '%':
- case 'X':
- flExit = 1, retval = RET_DORECOMMEND;
- break;
-#endif
-#ifdef RET_DOQUERYINFO
- case 'Q': // info query interface
- flExit = 1, retval = RET_DOQUERYINFO;
- break;
-#endif
-#ifdef RET_DOSYSOPEDIT
- case 'E':
- flExit = 1, retval = RET_DOSYSOPEDIT;
- break;
-#endif
-#ifdef RET_DOCHESSREPLAY
- case 'z':
- flExit = 1, retval = RET_DOCHESSREPLAY;
- break;
-#endif
-#ifdef RET_COPY2TMP
- case Ctrl('T'):
- flExit = 1, retval = RET_COPY2TMP;
- break;
-#endif
-#ifdef RET_SELECTBRD
- case 's':
- flExit = 1, retval = RET_SELECTBRD;
- break;
-#endif
- /* ------- SOB THREADED NAVIGATION EXITING KEYS ------- */
-
-#ifdef PMORE_USE_SOB_THREAD_NAV
- // I'm not sure if these keys are all invented by SOB,
- // but let's honor their names.
- // Kaede, Raw, Izero, woju - you are all TWBBS heroes
- // -- by piaip, 2008.
- case 'A':
- flExit = 1, retval = AUTHOR_PREV;
- break;
- case 'a':
- flExit = 1, retval = AUTHOR_NEXT;
- break;
- case 'F': case 'f':
- flExit = 1, retval = READ_NEXT;
- break;
- case 'B': case 'b':
- flExit = 1, retval = READ_PREV;
- break;
+
+ /* ------------------ EXITING KEYS --------------------- */
case KEY_LEFT:
flExit = 1, retval = FULLUPDATE;
break;
@@ -2434,20 +2406,6 @@ pmore(const char *fpath, int promptend)
flExit = 1, retval = FULLUPDATE;
break;
- /* from Kaede, thread reading */
- case ']':
- case '+':
- flExit = 1, retval = RELATE_NEXT;
- break;
- case '[':
- case '-':
- flExit = 1, retval = RELATE_PREV;
- break;
- case '=':
- flExit = 1, retval = RELATE_FIRST;
- break;
-#endif // PMORE_USE_SOB_THREAD_NAV
-
/* ------------------ NAVIGATION KEYS ------------------ */
/* Simple Navigation */
case 'k':
@@ -2485,7 +2443,6 @@ pmore(const char *fpath, int promptend)
case 'G':
case KEY_END:
mf_goBottom();
-
#ifdef PMORE_ACCURATE_WRAPEND
/* allright. in design of pmore,
* it's possible that when user navigates to file end,
@@ -2493,13 +2450,12 @@ pmore(const char *fpath, int promptend)
*/
mf_display();
invalidate = 0;
+ if(mf_viewedAll())
+ break;
- if(!mf_viewedAll())
- {
- /* one more try. */
- mf_goBottom();
- invalidate = 1;
- }
+ /* one more try. */
+ mf_goBottom();
+ invalidate = 1;
#endif
break;
@@ -2586,7 +2542,9 @@ pmore(const char *fpath, int promptend)
else
PMORE_UINAV_FORWARDPAGE();
break;
- /* ------------------ SEARCH KEYS ------------------ */
+
+ /* ------------------ SEARCH AND GOTO --------------- */
+ /* Search */
case '/':
{
char sbuf[81] = "";
@@ -2601,7 +2559,8 @@ pmore(const char *fpath, int promptend)
40, DOECHO);
if (sbuf[0]) {
- if (getdata(b_lines - 1, 0, "區分大小寫(Y/N/Q)? [N] ",
+ if (getdata(b_lines - 1, 0,
+ PMORE_MSG_SEARCH_LETTERCASE "[N] ",
ans, sizeof(ans), LCECHO) && *ans == 'y')
sr.cmpfunc = strncmp;
else if (*ans == 'q')
@@ -2621,7 +2580,8 @@ pmore(const char *fpath, int promptend)
case 'N':
mf_search(MFSEARCH_BACKWARD);
break;
- /* ------------------ SPECIAL KEYS ------------------ */
+
+ /* Goto */
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
case ';': case ':':
@@ -2635,8 +2595,7 @@ pmore(const char *fpath, int promptend)
pmore_clrtoeol(b_lines-1, 0);
getdata_buf(b_lines-1, 0,
(pageMode ?
- "跳至此頁(若要改指定行數請在結尾加.): " :
- "跳至此行: "),
+ PMORE_MSG_GOTO_PAGE : PMORE_MSG_GOTO_LINE),
buf, 8, DOECHO);
if(buf[0]) {
i = atoi(buf);
@@ -2649,50 +2608,36 @@ pmore(const char *fpath, int promptend)
}
break;
-#ifdef PMORE_USE_INTERNAL_HELP
- case 'h': case 'H':
- case '?':
-#ifdef KEY_F1
- case KEY_F1:
-#endif
- // help
- show_help(pmore_help);
+ /* --------------- PREFERENCE AND HELP -------------- */
+ /* preference */
+ case 'o':
+ pmore_Preference();
MFDISP_DIRTY();
break;
-#endif // PMORE_USE_INTERNAL_HELP
-
-#ifdef PMORE_NOTIFY_NEWPREF
- //let's be backward compatible! (pmore 2005 keys)
- case 'l':
- case 'w':
- case 'W':
- case '|':
- vmsg("這個按鍵已整合進新的設定 (o) 了");
- break;
-
-#endif // PMORE_NOTIFY_NEWPREF
-
case '\\': // everyone loves backslash, let's keep it.
pmore_QuickRawModePref();
MFDISP_DIRTY();
break;
- case 'o':
- pmore_Preference();
+ /* internal help */
+#ifdef PMORE_USE_INTERNAL_HELP
+ case 'h': case 'H': case '?':
+#ifdef KEY_F1
+ case KEY_F1:
+#endif
+ pmore_Help(ctx, help_handler);
MFDISP_DIRTY();
break;
+#endif // PMORE_USE_INTERNAL_HELP
-#if defined(USE_BBSLUA) && defined(RET_DOBBSLUA)
- case 'P':
- vmsg("非常抱歉,BBS-Lua 的熱鍵已改為 L ,請改按 L");
- break;
-
- case 'L':
- case 'l':
- flExit = 1, retval = RET_DOBBSLUA;
+ /* debug system */
+#ifdef DEBUG
+ case 'd':
+ debug = !debug;
+ MFDISP_DIRTY();
break;
#endif
-
+ /* ------------------ MOVIE SYSTEM ------------------ */
#ifdef PMORE_USE_ASCII_MOVIE
case 'p':
/* play ascii movie again
@@ -2749,13 +2694,6 @@ pmore(const char *fpath, int promptend)
break;
#endif
-#ifdef DEBUG
- case 'd':
- debug = !debug;
- MFDISP_DIRTY();
- break;
-#endif
-
#ifndef PMORE_IGNORE_UNKNOWN_NAVKEYS
default:
return ch;
@@ -2771,6 +2709,13 @@ pmore(const char *fpath, int promptend)
return retval;
}
+// backward compatible
+int
+pmore(const char *fpath, int promptend)
+{
+ return pmore2(fpath, promptend, NULL, NULL, NULL);
+}
+
// ---------------------------------------------------- Preference and Help
MFPROTO void
@@ -2784,7 +2729,7 @@ pmore_prefEntry(
int i = 23;
// print key/text
- outs(" " ANSI_COLOR(1;31)); //OPTATTR_NORMAL_KEY);
+ outs(" " PREFATTR_NORMAL_KEY);
if (szKey < 0) szKey = strlen(key);
if (szKey > 0) pmore_outns(key, szKey);
outs(ANSI_RESET " ");
@@ -2807,14 +2752,14 @@ pmore_prefEntry(
}
if (i > 0)
- outs(ANSI_COLOR(1;30) " |" ANSI_RESET); //OPTATTR_BAR " | " ANSI_RESET);
+ outs(PREFATTR_BAR " |" ANSI_RESET);
// test if option has hotkey
if (*options && *options != '\t' &&
*(options+1) && *(options+1) == '.')
{
// found hotkey
- outs(ANSI_COLOR(1;31)); //OPTATTR_NORMAL_KEY);
+ outs(PREFATTR_NORMAL_KEY);
outc(*options);
outs(ANSI_RESET);
options +=2;
@@ -2822,7 +2767,7 @@ pmore_prefEntry(
if (i == isel)
{
- outs(ANSI_COLOR(1;36) "*");// OPTATTR_SELECTED);
+ outs(PREFATTR_SELECTED);
}
else
outc(' ');
@@ -2843,7 +2788,7 @@ pmore_PromptBar(const char *caption, int shadow)
{
int i = 0;
- if (shadow)
+ if (shadow & 0x01)
{
outs(ANSI_COLOR(0;1;30));
for(i = 0; i+2 < t_columns ; i+=2)
@@ -2858,6 +2803,14 @@ pmore_PromptBar(const char *caption, int shadow)
for(i -= strlen(caption); i > 0; i--)
outs(" ");
outs(ANSI_RESET "\n");
+
+ if (shadow & 0x02)
+ {
+ outs(ANSI_COLOR(0;1;30));
+ for(i = 0; i+2 < t_columns ; i+=2)
+ outs("▔");
+ outs(ANSI_RESET "\n");
+ }
}
MFPROTO void
@@ -2877,10 +2830,9 @@ pmore_QuickRawModePref()
// list options
pmore_prefEntry(bpref.rawmode,
- "\\", 1, "色彩顯示方式:", -1,
- "1.預設格式化內容\t2.原始ANSI控制碼\t3.純文字");
+ "\\", 1, PMORE_MSG_QPREF_SUBJECT, -1, PMORE_MSG_QPREF_OPTIONS);
- switch(vmsg("請調整設定 (1-3 可直接選定,\\可切換) 或其它任意鍵結束。"))
+ switch(vmsg( PMORE_MSG_QPREF_PROMPT ))
{
case '\\':
bpref.rawmode = (bpref.rawmode+1) % MFDISP_RAW_MODES;
@@ -2937,6 +2889,7 @@ pmore_Preference()
pmore_PromptBar(PMORE_MSG_PREF_TITLE, 1);
outs("\n");
+ // TODO move these strings to localization section...
// list options
pmore_prefEntry(bpref.rawmode,
"\\", 1, "色彩顯示方式:", -1,
@@ -2988,15 +2941,87 @@ pmore_Preference()
}
}
-/*
+#ifdef PMORE_USE_INTERNAL_HELP
+static const char
+*hlp_basic[] = {
+ "【基本移動】",
+ "下翻一頁", "^F → PgUp Space",
+ "上翻一頁", "^B ^H PgDn BS",
+ "下捲一行", " j ↓",
+ "上捲一行", " k ↑",
+ "檔案結尾", " $ G End",
+ "檔案開頭", " 0 g Home",
+ "離開 ", " q ←",
+ NULL,
+},
+*hlp_adv[] = {
+ "【進階移動】",
+ "搜尋關鍵字", "/",
+ "往後搜尋 ", "n",
+ "往前搜尋 ", "N",
+ "指定頁數 ", "; 0-9數字鍵",
+ "指定行數 ", ":",
+ "向右捲動 ", ". > TAB",
+ "向左捲動 ", ", < Shift-TAB",
+ NULL,
+},
+*hlp_sys[] = {
+ "【其它】",
+#ifdef PMORE_USE_ASCII_MOVIE
+ "播放動畫 ", "p",
+#endif
+ "選項設定 ", "o",
+ "色彩顯示模式", "\\",
+ "說明 ", "h ? F1",
+#ifdef DEBUG
+ "DBG 除錯模式", "d",
+#endif
+ NULL,
+};
+
MFPROTO void
-pmore_Help()
+pmore_Help(void *ctx, int (*help_handler)(int y, void *ctx))
{
+ const char ** p[3] = { hlp_basic, hlp_adv, hlp_sys};
+ const int cols[3] = { 29, 29, 19 }, // columns
+ desc[3] = { 10, 11, 13 }; // desc width
+ int y = 0, i;
+
clear();
- vs_hdr("pmore 使用說明");
- vmsg("");
+ pmore_PromptBar(PMORE_MSG_HELP_TITLE, 2);
+ prints(PREFATTR_NORMAL_KEY "%-*s%-*s%-*s" ANSI_RESET "\n",
+ cols[0], *p[0]++,
+ cols[1], *p[1]++,
+ cols[2], *p[2]++);
+ y = 4;
+ // render help page
+ while (*p[0] || *p[1] || *p[2])
+ {
+ y++; outc(' ');
+ for ( i = 0; i < 3; i++ )
+ {
+ if (!*p[i]) {
+ prints("%*s", cols[i], "");
+ continue;
+ }
+ prints("%-*s", desc[i], *p[i]++);
+ prints(PREFATTR_SELECTED "%-*s" ANSI_RESET,
+ cols[i]-desc[i], *p[i]++);
+ }
+ outs("\n");
+ }
+
+ // show additional help information
+ if (help_handler)
+ help_handler(y, ctx);
+ else
+#ifdef PRESSANYKEY
+ PRESSANYKEY();
+#else
+ vmsg(PMORE_MSG_HELP_PAUSE);
+#endif
}
-*/
+#endif // PMORE_USE_INTERNAL_HELP
// ---------------------------------------------------- Extra modules
@@ -3123,7 +3148,7 @@ mf_moviePromptPlaying(int type)
if (type)
{
outs(ANSI_RESET ANSI_COLOR(1;34;47));
- s = " >> 請輸入選項: (互動式動畫播放中,可按 q 或 Ctrl-C 中斷)";
+ s = PMORE_MSG_MOVIE_INTERACTION_WAITSEL;
}
else if (mfmovie.interactive)
{