This source file includes following definitions.
- dialog_textbox
- back_lines
- print_page
- print_line
- get_line
- print_position
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include "dialog.h"
23
24 static void back_lines (int n);
25 static void print_page (WINDOW * win, int height, int width);
26 static void print_line (WINDOW * win, int row, int width);
27 static char *get_line (void);
28 static void print_position (WINDOW * win, int height, int width);
29
30 static int hscroll = 0, fd, file_size, bytes_read;
31 static int begin_reached = 1, end_reached = 0, page_length;
32 static char *buf, *page;
33
34
35
36
37 int
38 dialog_textbox (const char *title, const char *file, int height, int width)
39 {
40 int i, x, y, cur_x, cur_y, fpos, key = 0;
41 int passed_end;
42 char search_term[MAX_LEN + 1];
43 WINDOW *dialog, *text;
44
45 search_term[0] = '\0';
46
47
48 if ((fd = open (file, O_RDONLY)) == -1) {
49 endwin ();
50 fprintf (stderr,
51 "\nCan't open input file in dialog_textbox().\n");
52 exit (-1);
53 }
54
55
56 if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
57 endwin ();
58 fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
59 exit (-1);
60 }
61
62 if (lseek (fd, 0, SEEK_SET) == -1) {
63 endwin ();
64 fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
65 exit (-1);
66 }
67
68 if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
69 endwin ();
70 fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
71 exit (-1);
72 }
73 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
74 endwin ();
75 fprintf (stderr, "\nError reading file in dialog_textbox().\n");
76 exit (-1);
77 }
78 buf[bytes_read] = '\0';
79 page = buf;
80
81
82 x = (COLS - width) / 2;
83 y = (LINES - height) / 2;
84
85
86 draw_shadow (stdscr, y, x, height, width);
87
88 dialog = newwin (height, width, y, x);
89 keypad (dialog, TRUE);
90
91
92 text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
93
94 keypad (text, TRUE);
95
96
97 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
98
99 wattrset (dialog, border_attr);
100 mvwaddch (dialog, height-3, 0, ACS_LTEE);
101 for (i = 0; i < width - 2; i++)
102 waddch (dialog, ACS_HLINE);
103 wattrset (dialog, dialog_attr);
104 waddch (dialog, ACS_RTEE);
105
106 if (title != NULL) {
107 wattrset (dialog, title_attr);
108 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
109 waddstr (dialog, (char *)title);
110 waddch (dialog, ' ');
111 }
112 print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
113 wnoutrefresh (dialog);
114 getyx (dialog, cur_y, cur_x);
115
116
117 attr_clear (text, height - 4, width - 2, dialog_attr);
118 print_page (text, height - 4, width - 2);
119 print_position (dialog, height, width);
120 wmove (dialog, cur_y, cur_x);
121 wrefresh (dialog);
122
123 while ((key != ESC) && (key != '\n')) {
124 key = wgetch (dialog);
125 switch (key) {
126 case 'E':
127 case 'e':
128 case 'X':
129 case 'x':
130 delwin (dialog);
131 free (buf);
132 close (fd);
133 return 0;
134 case 'g':
135 case KEY_HOME:
136 if (!begin_reached) {
137 begin_reached = 1;
138
139 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
140 endwin ();
141 fprintf (stderr,
142 "\nError moving file pointer in dialog_textbox().\n");
143 exit (-1);
144 }
145 if (fpos > bytes_read) {
146 if (lseek (fd, 0, SEEK_SET) == -1) {
147 endwin ();
148 fprintf (stderr, "\nError moving file pointer in "
149 "dialog_textbox().\n");
150 exit (-1);
151 }
152 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
153 endwin ();
154 fprintf (stderr,
155 "\nError reading file in dialog_textbox().\n");
156 exit (-1);
157 }
158 buf[bytes_read] = '\0';
159 }
160 page = buf;
161 print_page (text, height - 4, width - 2);
162 print_position (dialog, height, width);
163 wmove (dialog, cur_y, cur_x);
164 wrefresh (dialog);
165 }
166 break;
167 case 'G':
168 case KEY_END:
169
170 end_reached = 1;
171
172 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
173 endwin ();
174 fprintf (stderr,
175 "\nError moving file pointer in dialog_textbox().\n");
176 exit (-1);
177 }
178 if (fpos < file_size) {
179 if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
180 endwin ();
181 fprintf (stderr,
182 "\nError moving file pointer in dialog_textbox().\n");
183 exit (-1);
184 }
185 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
186 endwin ();
187 fprintf (stderr,
188 "\nError reading file in dialog_textbox().\n");
189 exit (-1);
190 }
191 buf[bytes_read] = '\0';
192 }
193 page = buf + bytes_read;
194 back_lines (height - 4);
195 print_page (text, height - 4, width - 2);
196 print_position (dialog, height, width);
197 wmove (dialog, cur_y, cur_x);
198 wrefresh (dialog);
199 break;
200 case 'K':
201 case 'k':
202 case KEY_UP:
203 if (!begin_reached) {
204 back_lines (page_length + 1);
205
206
207
208
209
210
211 scrollok (text, TRUE);
212 wscrl (text, -1);
213 scrollok (text, FALSE);
214 page_length = 0;
215 passed_end = 0;
216 for (i = 0; i < height - 4; i++) {
217 if (!i) {
218
219 print_line (text, 0, width - 2);
220 wnoutrefresh (text);
221 } else
222
223 get_line ();
224 if (!passed_end)
225 page_length++;
226 if (end_reached && !passed_end)
227 passed_end = 1;
228 }
229
230 print_position (dialog, height, width);
231 wmove (dialog, cur_y, cur_x);
232 wrefresh (dialog);
233 }
234 break;
235 case 'B':
236 case 'b':
237 case KEY_PPAGE:
238 if (begin_reached)
239 break;
240 back_lines (page_length + height - 4);
241 print_page (text, height - 4, width - 2);
242 print_position (dialog, height, width);
243 wmove (dialog, cur_y, cur_x);
244 wrefresh (dialog);
245 break;
246 case 'J':
247 case 'j':
248 case KEY_DOWN:
249 if (!end_reached) {
250 begin_reached = 0;
251 scrollok (text, TRUE);
252 scroll (text);
253 scrollok (text, FALSE);
254 print_line (text, height - 5, width - 2);
255 wnoutrefresh (text);
256 print_position (dialog, height, width);
257 wmove (dialog, cur_y, cur_x);
258 wrefresh (dialog);
259 }
260 break;
261 case KEY_NPAGE:
262 case ' ':
263 if (end_reached)
264 break;
265
266 begin_reached = 0;
267 print_page (text, height - 4, width - 2);
268 print_position (dialog, height, width);
269 wmove (dialog, cur_y, cur_x);
270 wrefresh (dialog);
271 break;
272 case '0':
273 case 'H':
274 case 'h':
275 case KEY_LEFT:
276 if (hscroll <= 0)
277 break;
278
279 if (key == '0')
280 hscroll = 0;
281 else
282 hscroll--;
283
284 back_lines (page_length);
285 print_page (text, height - 4, width - 2);
286 wmove (dialog, cur_y, cur_x);
287 wrefresh (dialog);
288 break;
289 case 'L':
290 case 'l':
291 case KEY_RIGHT:
292 if (hscroll >= MAX_LEN)
293 break;
294 hscroll++;
295
296 back_lines (page_length);
297 print_page (text, height - 4, width - 2);
298 wmove (dialog, cur_y, cur_x);
299 wrefresh (dialog);
300 break;
301 case ESC:
302 break;
303 }
304 }
305
306 delwin (dialog);
307 free (buf);
308 close (fd);
309 return -1;
310 }
311
312
313
314
315
316 static void
317 back_lines (int n)
318 {
319 int i, fpos;
320
321 begin_reached = 0;
322
323
324
325
326 if (!end_reached) {
327
328 if (page == buf) {
329 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
330 endwin ();
331 fprintf (stderr, "\nError moving file pointer in "
332 "back_lines().\n");
333 exit (-1);
334 }
335 if (fpos > bytes_read) {
336
337
338
339
340
341
342 if (fpos < BUF_SIZE / 2 + bytes_read) {
343
344 if (lseek (fd, 0, SEEK_SET) == -1) {
345 endwin ();
346 fprintf (stderr, "\nError moving file pointer in "
347 "back_lines().\n");
348 exit (-1);
349 }
350 page = buf + fpos - bytes_read;
351 } else {
352 if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
353 == -1) {
354 endwin ();
355 fprintf (stderr, "\nError moving file pointer "
356 "in back_lines().\n");
357 exit (-1);
358 }
359 page = buf + BUF_SIZE / 2;
360 }
361 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
362 endwin ();
363 fprintf (stderr, "\nError reading file in back_lines().\n");
364 exit (-1);
365 }
366 buf[bytes_read] = '\0';
367 } else {
368 begin_reached = 1;
369 return;
370 }
371 }
372 if (*(--page) != '\n') {
373
374 endwin ();
375 fprintf (stderr, "\nInternal error in back_lines().\n");
376 exit (-1);
377 }
378 }
379
380 for (i = 0; i < n; i++)
381 do {
382 if (page == buf) {
383 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
384 endwin ();
385 fprintf (stderr,
386 "\nError moving file pointer in back_lines().\n");
387 exit (-1);
388 }
389 if (fpos > bytes_read) {
390
391 if (fpos < BUF_SIZE / 2 + bytes_read) {
392
393 if (lseek (fd, 0, SEEK_SET) == -1) {
394 endwin ();
395 fprintf (stderr, "\nError moving file pointer "
396 "in back_lines().\n");
397 exit (-1);
398 }
399 page = buf + fpos - bytes_read;
400 } else {
401 if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
402 SEEK_CUR) == -1) {
403 endwin ();
404 fprintf (stderr, "\nError moving file pointer"
405 " in back_lines().\n");
406 exit (-1);
407 }
408 page = buf + BUF_SIZE / 2;
409 }
410 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
411 endwin ();
412 fprintf (stderr, "\nError reading file in "
413 "back_lines().\n");
414 exit (-1);
415 }
416 buf[bytes_read] = '\0';
417 } else {
418 begin_reached = 1;
419 return;
420 }
421 }
422 } while (*(--page) != '\n');
423 page++;
424 }
425
426
427
428
429 static void
430 print_page (WINDOW * win, int height, int width)
431 {
432 int i, passed_end = 0;
433
434 page_length = 0;
435 for (i = 0; i < height; i++) {
436 print_line (win, i, width);
437 if (!passed_end)
438 page_length++;
439 if (end_reached && !passed_end)
440 passed_end = 1;
441 }
442 wnoutrefresh (win);
443 }
444
445
446
447
448 static void
449 print_line (WINDOW * win, int row, int width)
450 {
451 int i, y, x;
452 char *line;
453
454 line = get_line ();
455 line += MIN (strlen (line), hscroll);
456 wmove (win, row, 0);
457 waddch (win, ' ');
458 waddnstr (win, line, MIN (strlen (line), width - 2));
459
460 getyx (win, y, x);
461
462 for (i = 0; i < width - x; i++)
463 waddch (win, ' ');
464 }
465
466
467
468
469
470
471 static char *
472 get_line (void)
473 {
474 int i = 0, fpos;
475 static char line[MAX_LEN + 1];
476
477 end_reached = 0;
478 while (*page != '\n') {
479 if (*page == '\0') {
480
481 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
482 endwin ();
483 fprintf (stderr, "\nError moving file pointer in "
484 "get_line().\n");
485 exit (-1);
486 }
487 if (fpos < file_size) {
488
489
490 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
491 endwin ();
492 fprintf (stderr, "\nError reading file in get_line().\n");
493 exit (-1);
494 }
495 buf[bytes_read] = '\0';
496 page = buf;
497 } else {
498 if (!end_reached)
499 end_reached = 1;
500 break;
501 }
502 } else if (i < MAX_LEN)
503 line[i++] = *(page++);
504 else {
505
506 if (i == MAX_LEN)
507 line[i++] = '\0';
508 page++;
509 }
510 }
511 if (i <= MAX_LEN)
512 line[i] = '\0';
513 if (!end_reached)
514 page++;
515
516 return line;
517 }
518
519
520
521
522 static void
523 print_position (WINDOW * win, int height, int width)
524 {
525 int fpos, percent;
526
527 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
528 endwin ();
529 fprintf (stderr, "\nError moving file pointer in print_position().\n");
530 exit (-1);
531 }
532 wattrset (win, position_indicator_attr);
533 percent = !file_size ?
534 100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
535 wmove (win, height - 3, width - 9);
536 wprintw (win, "(%3d%%)", percent);
537 }