/* (I think this was originally by Pinkfish) Mods by Hamlet, Aug 1997. * Fixed screen-size issues. * fixed odd bug with finish_func * removed annoying end-of-doc [more] thing. * Added quite a few commands. * Wrote /doc/more.help */ /* Notes: Should probably change searches to regexp Terrible hack in string_display_file() needs fixed... format now and send raw to player at the end, instead of double-formatting. Add a 'raw' variable that keeps system from converting colors. Convert more_file.c to inherit this to do the brunt of the work, probably. */ static int fsize, topl, used; static string last_search, *the_bit, more_bit, stat_line; static object finish_ob; static mixed finish_func; #define ROWS ((int)this_object()->query_rows() - 1) #define COLS (int)this_object()->query_cols() void call_finish_func(string str); int string_display_file() { int botl, i, j, tmp; string out = ""; int cols = COLS; botl = topl + ROWS; i = topl; tmp = sizeof(explode(sprintf("%-=*s", cols, the_bit[topl]), "\n")) - 1; if(tmp >= 0) j = tmp; while((i+j)<botl && i<fsize) { out += the_bit[i] + "\n"; if((i+1) < fsize) { tmp = sizeof(explode(sprintf("%-=*s", cols, the_bit[i+1]), "\n")) - 1; /* ^^^^ Extra lines it's gonna wrap. Terrible hack. */ if(tmp > 0) j += tmp; } i++; } if(i == topl) { /* The first line is longer than a screen. */ out += the_bit[i] + "\n"; i++; } write(out); return (i - topl); } void more_string_status_line() { string *frog; string s; int i, percentage; if (!stat_line) stat_line = "$N From $T to $B of $S ($%%) - h for help. "; s = ""; frog = explode(stat_line, "$"); for (i=0;i<sizeof(frog);i++) { if (frog[i] == "") { s += "$"; i ++; } else switch (frog[i][0]) { case 'N' : s += more_bit+frog[i][1..]; break; case 'T' : s += (topl - used + 1)+frog[i][1..]; break; case 'B' : if (topl > fsize) s += fsize+frog[i][1..]; else s += topl+frog[i][1..]; break; case '%' : { percentage = ((topl)*100)/fsize; if(percentage > 100) percentage = 100; s += percentage+frog[i][1..]; break; } case 'S' : s += fsize+frog[i][1..]; break; } } tell_object(this_object(), s); return; } void string_next_page(string str) { int num, noargs, i, redraw; string s1, s4, s5; if (!str) str = ""; if (sscanf(str,"%d%s", num, str)!=2) noargs = 1; s1 = str[1..]; str = str[0..0]; /* case statements WEEEEEE */ switch(str) { case "" : case "f" : /* go on a number of pages... */ if(!noargs) topl += (ROWS * (num - 1)); redraw = 1; break; case "b" : if(noargs) num = 1; topl -= (ROWS * (num + 1)); redraw = 1; break; case " " : case "z" : if(noargs) num = 1; while(num--) { write(the_bit[topl] + "\n"); topl++; if(topl >= fsize) break; } break; case "." : topl -= used; redraw = 1; break; case "s" : topl += num; redraw = 1; break; case "q" : case "Q" : call_finish_func(str); return; case "g" : topl = num; if(topl >= fsize) topl = fsize - 2; redraw = 1; break; case "G" : redraw = 1; if (noargs) topl = fsize - ROWS; else topl = (fsize - num); break; case "/" : if (s1=="") s1 = last_search; if (!s1 || s1 == "") s1 = "bing!"; last_search = s1; for (i=topl;i<fsize;i++) if (sscanf(the_bit[i],"%s"+s1+"%s",s4,s5)==2) if (num--<=0) break; if (i==fsize) write("Sorry "+s1+" not found.\n"); else { topl = i-3; redraw = 1; } break; case "-" : if (s1=="") s1 = last_search; if (!s1 || s1 == "") s1 = "bing!"; last_search = s1; for (i=(topl-ROWS);i>=0;i--) if (sscanf(the_bit[i],"%s"+s1+"%s",s4,s5)==2) if (num--<=0) break; if (i<0) write("Sorry "+s1+" not found.\n"); else { topl = i-3; redraw = 1; } break; case "?" : case "h" : if(file_size("/doc/more.help") > 0) tell_object(this_object(), read_file("/doc/more.help")); else tell_object(this_object(), "The help document (/doc/more.help) " "is missing. Get someone to fix it.\n"); break; } if(topl < 0) topl = 0; else if(topl >= fsize) topl = fsize - ROWS; if (redraw) { used = string_display_file(); topl += used; } if (topl<fsize) { more_string_status_line(); input_to("string_next_page"); } else call_finish_func(0); } varargs int more_string(mixed str, string bity, string more_fmt) { if (bity) more_bit = bity; else more_bit = "--- MORE"; last_search = ""; if(more_fmt) stat_line = more_fmt; else stat_line = 0; if (!pointerp(str)) the_bit = explode(str,"\n"); fsize = sizeof(the_bit); if (fsize == 0) { notify_fail("Empty String.\n"); return 0; } topl = 0; used = string_display_file(); topl += used; if (topl < fsize) { more_string_status_line(); input_to("string_next_page"); } else call_finish_func(0); return 1; } int set_finish_func(mixed str, object ob) { finish_func = str; if (!functionp(str) && !ob) finish_ob = previous_object(); else finish_ob = ob; } void call_finish_func(string str) { mixed f_func; if (finish_func) { f_func = finish_func; finish_func = 0; if(functionp(f_func)) // This will have to wait. requires modifications of mailer. // evaluate(f_func, str); evaluate(f_func); else // call_other(finish_ob, f_func, str); call_other(finish_ob, f_func); } }