1 /*
2 * Copyright (c) 1993-1997 by Alexander V. Lukyanov (lav@yars.free.net)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <config.h>
20 #include <ctype.h>
21 #include "edit.h"
22 #include "keymap.h"
23 #include <string.h>
24 #include <stdlib.h>
25
26 #if 0
27 void Help(char ***h,char *title)
28 {
29 static struct menu
30 c[]={
31 {" &Cancel ",MIDDLE,FDOWN-2},
32 {NULL}},
33 pnc[]={
34 {" &Previous ",MIDDLE-12,FDOWN-2},
35 {" &Next ",MIDDLE,FDOWN-2},
36 {" &Cancel ",MIDDLE+12,FDOWN-2},
37 {NULL}},
38 npc[]={
39 {" &Next ",MIDDLE-12,FDOWN-2},
40 {" &Previous ",MIDDLE,FDOWN-2},
41 {" &Cancel ",MIDDLE+12,FDOWN-2},
42 {NULL}},
43 pc[]={
44 {" &Previous ",MIDDLE-6,FDOWN-2},
45 {" &Cancel ",MIDDLE+6,FDOWN-2},
46 {NULL}},
47 nc[]={
48 {" &Next ",MIDDLE-6,FDOWN-2},
49 {" &Cancel ",MIDDLE+6,FDOWN-2},
50 {NULL}};
51 WIN *HelpWin;
52 int page=0;
53 int backward=0,res,line;
54
55 HelpWin=CreateWin(MIDDLE,MIDDLE,42,21,HELP_WIN_ATTR,title,0);
56 DisplayWin(HelpWin);
57
58 do
59 {
60 Clear();
61 for(line=2; line<Upper->h-4 && h[page][line-2]; line++)
62 PutStr(2,line,h[page][line-2]);
63 if(page==0 && !h[1])
64 res=ReadMenu(c,HORIZ,HELP_WIN_ATTR,CURR_BUTTON_ATTR);
65 else if(page==0)
66 res=ReadMenu(nc,HORIZ,HELP_WIN_ATTR,CURR_BUTTON_ATTR);
67 else if(!h[page+1])
68 res=ReadMenu(pc,HORIZ,HELP_WIN_ATTR,CURR_BUTTON_ATTR);
69 else
70 res=ReadMenu(backward?pnc:npc,HORIZ,HELP_WIN_ATTR,CURR_BUTTON_ATTR);
71 switch(res)
72 {
73 case('C'):
74 res=0;
75 break;
76 case('N'):
77 page++;
78 backward=0;
79 break;
80 case('P'):
81 page--;
82 backward=1;
83 break;
84 }
85 }
86 while(res);
87
88 CloseWin();
89 DestroyWin(HelpWin);
90 }
91 #endif //0
92
LoadHelp(const char * tag)93 static char *LoadHelp(const char *tag)
94 {
95 FILE *hf=fopen(PKGDATADIR "/le.hlp","r");
96 if(!hf)
97 return 0;
98
99 int help_size=0;
100 char *help=0;
101 char *help_end=0;
102
103 char buf[256];
104 char this_tag[256];
105 bool tag_match=false;
106 buf[255]=0;
107 while(fgets(buf,sizeof(buf)-1,hf)!=0)
108 {
109 if(1==sscanf(buf,"[%[^]]]",this_tag))
110 {
111 if(tag_match) {
112 fclose(hf);
113 return help;
114 }
115 if(!strcasecmp(tag,this_tag))
116 tag_match=true;
117 continue;
118 }
119 if(tag_match)
120 {
121 int buf_len=strlen(buf);
122 if(!help || help_end-help>help_size-buf_len-1)
123 {
124 // allocate more memory
125 int help_len=help_end-help;
126 help_size=(help_size?help_size*2:0x10000);
127 char *new_help=(char*)realloc(help,help_size);
128 if(!new_help)
129 {
130 // out of memory
131 fclose(hf);
132 return help;
133 }
134 help=new_help;
135 help_end=help+help_len;
136 }
137 char *subst=strchr(buf,'$');
138 if(subst && subst[1]=='{') {
139 char *end_brace=strchr(subst+2,'}');
140 if(end_brace) {
141 char action[256];
142 memcpy(action,subst+2,end_brace-subst-2);
143 action[end_brace-subst-2]=0;
144 char *fmt_len_ptr=strchr(action,':');
145 int fmt_len=0;
146 if(fmt_len_ptr) {
147 *fmt_len_ptr=0;
148 fmt_len=atoi(fmt_len_ptr+1);
149 }
150 const char *code=ShortcutPrettyPrint(FindActionCode(action),NULL);
151 int code_len=strlen(code);
152 int final_width=(code_len>fmt_len?code_len:fmt_len);
153 memmove(subst+final_width,end_brace+1,strlen(end_brace));
154 memcpy(subst,code,code_len);
155 if(code_len<fmt_len)
156 memset(subst+code_len,' ',fmt_len-code_len);
157 buf_len=strlen(buf);
158 }
159 }
160 memcpy(help_end,buf,buf_len+1);
161 help_end+=buf_len;
162 }
163 }
164 fclose(hf);
165 if(tag_match)
166 return help;
167 free(help);
168 return 0;
169 }
170
Help(const char * helpf,const char * title)171 void Help(const char *helpf,const char *title)
172 {
173 char *help=LoadHelp(helpf);
174 if(!help)
175 return;
176 const char *ptr=help;
177 WIN *HelpWin;
178 const int v_m=1;
179 const int h_m=2;
180
181 HelpWin=CreateWin(MIDDLE,MIDDLE,48,22,HELP_WIN_ATTR,title,0);
182 DisplayWin(HelpWin);
183
184 for(;;)
185 {
186 int line=v_m;
187 const char *c;
188
189 SetAttr(HELP_WIN_ATTR);
190 for(c=ptr; *c; c++)
191 {
192 if(line >= HelpWin->h-v_m)
193 break;
194 int col=h_m;
195 for( ; *c && *c!='\n'; c++)
196 {
197 if(col >= HelpWin->w-h_m)
198 break;
199
200 PutCh(col++,line,(unsigned char)*c);
201 }
202 while(col < HelpWin->w-h_m)
203 PutCh(col++,line,' ');
204 c=strchr(c,'\n');
205 if(!c)
206 break;
207 line++;
208 }
209 while(line < HelpWin->h-v_m)
210 {
211 for(int col=h_m; col<HelpWin->w-h_m; col++)
212 PutCh(col,line,' ');
213 line++;
214 }
215 Message("Use Up,Down,PageUp,PageDown to scroll help text. Ctrl-X - cancel");
216 curs_set(0);
217 move(LINES-1,COLS-1);
218
219 int action=GetNextAction();
220 int i;
221 switch(action)
222 {
223 case(LINE_DOWN):
224 c=strchr(ptr,'\n');
225 if(!c)
226 break;
227 ptr=c+1;
228 break;
229 case(NEXT_PAGE):
230 c=ptr;
231 for(i=HelpWin->h-v_m*2-1; i>0; i--)
232 {
233 c=strchr(c,'\n');
234 if(!c)
235 break;
236 c++;
237 }
238 if(c)
239 ptr=c;
240 break;
241 case(LINE_UP):
242 if(ptr==help)
243 break;
244 ptr--;
245 while(ptr>help && ptr[-1]!='\n')
246 ptr--;
247 break;
248 case(PREV_PAGE):
249 c=ptr;
250 for(i=HelpWin->h-v_m*2-1; i>0; i--)
251 {
252 if(c==help)
253 break;
254 c--;
255 while(c>help && c[-1]!='\n') c--;
256 }
257 ptr=c;
258 break;
259 case(NEWLINE):
260 case(QUIT_EDITOR):
261 goto quit;
262 }
263 c=help+strlen(help);
264 for(i=HelpWin->h-v_m*2-1; i>0; i--)
265 {
266 if(c>help && c[-1]=='\n')
267 c--;
268 while(c>help && c[-1]!='\n')
269 c--;
270 }
271 if(c<ptr)
272 ptr=c;
273 }
274 quit:
275 CloseWin();
276 DestroyWin(HelpWin);
277 free(help);
278 }
279