00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "dialog.h"
00023
00024 static void back_lines (int n);
00025 static void print_page (WINDOW * win, int height, int width);
00026 static void print_line (WINDOW * win, int row, int width);
00027 static char *get_line (void);
00028 static void print_position (WINDOW * win, int height, int width);
00029
00030 static int hscroll = 0, fd, file_size, bytes_read;
00031 static int begin_reached = 1, end_reached = 0, page_length;
00032 static char *buf, *page;
00033
00034
00035
00036
00037 int
00038 dialog_textbox (const char *title, const char *file, int height, int width)
00039 {
00040 int i, x, y, cur_x, cur_y, fpos, key = 0;
00041 int passed_end;
00042 char search_term[MAX_LEN + 1];
00043 WINDOW *dialog, *text;
00044
00045 search_term[0] = '\0';
00046
00047
00048 if ((fd = open (file, O_RDONLY)) == -1) {
00049 endwin ();
00050 fprintf (stderr,
00051 "\nCan't open input file in dialog_textbox().\n");
00052 exit (-1);
00053 }
00054
00055
00056 if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
00057 endwin ();
00058 fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
00059 exit (-1);
00060 }
00061
00062 if (lseek (fd, 0, SEEK_SET) == -1) {
00063 endwin ();
00064 fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
00065 exit (-1);
00066 }
00067
00068 if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
00069 endwin ();
00070 fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
00071 exit (-1);
00072 }
00073 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
00074 endwin ();
00075 fprintf (stderr, "\nError reading file in dialog_textbox().\n");
00076 exit (-1);
00077 }
00078 buf[bytes_read] = '\0';
00079 page = buf;
00080
00081
00082 x = (COLS - width) / 2;
00083 y = (LINES - height) / 2;
00084
00085
00086 draw_shadow (stdscr, y, x, height, width);
00087
00088 dialog = newwin (height, width, y, x);
00089 keypad (dialog, TRUE);
00090
00091
00092 text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
00093 wattrset (text, dialog_attr);
00094 wbkgdset (text, dialog_attr & A_COLOR);
00095
00096 keypad (text, TRUE);
00097
00098
00099 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
00100
00101 wattrset (dialog, border_attr);
00102 mvwaddch (dialog, height-3, 0, ACS_LTEE);
00103 for (i = 0; i < width - 2; i++)
00104 waddch (dialog, ACS_HLINE);
00105 wattrset (dialog, dialog_attr);
00106 wbkgdset (dialog, dialog_attr & A_COLOR);
00107 waddch (dialog, ACS_RTEE);
00108
00109 if (title != NULL && strlen(title) >= width-2 ) {
00110
00111 char * title2 = malloc(width-2+1);
00112 memcpy( title2, title, width-2 );
00113 title2[width-2] = '\0';
00114 title = title2;
00115 }
00116
00117 if (title != NULL) {
00118 wattrset (dialog, title_attr);
00119 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
00120 waddstr (dialog, (char *)title);
00121 waddch (dialog, ' ');
00122 }
00123 print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
00124 wnoutrefresh (dialog);
00125 getyx (dialog, cur_y, cur_x);
00126
00127
00128 attr_clear (text, height - 4, width - 2, dialog_attr);
00129 print_page (text, height - 4, width - 2);
00130 print_position (dialog, height, width);
00131 wmove (dialog, cur_y, cur_x);
00132 wrefresh (dialog);
00133
00134 while ((key != ESC) && (key != '\n')) {
00135 key = wgetch (dialog);
00136 switch (key) {
00137 case 'E':
00138 case 'e':
00139 case 'X':
00140 case 'x':
00141 delwin (dialog);
00142 free (buf);
00143 close (fd);
00144 return 0;
00145 case 'g':
00146 case KEY_HOME:
00147 if (!begin_reached) {
00148 begin_reached = 1;
00149
00150 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
00151 endwin ();
00152 fprintf (stderr,
00153 "\nError moving file pointer in dialog_textbox().\n");
00154 exit (-1);
00155 }
00156 if (fpos > bytes_read) {
00157 if (lseek (fd, 0, SEEK_SET) == -1) {
00158 endwin ();
00159 fprintf (stderr, "\nError moving file pointer in "
00160 "dialog_textbox().\n");
00161 exit (-1);
00162 }
00163 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
00164 endwin ();
00165 fprintf (stderr,
00166 "\nError reading file in dialog_textbox().\n");
00167 exit (-1);
00168 }
00169 buf[bytes_read] = '\0';
00170 }
00171 page = buf;
00172 print_page (text, height - 4, width - 2);
00173 print_position (dialog, height, width);
00174 wmove (dialog, cur_y, cur_x);
00175 wrefresh (dialog);
00176 }
00177 break;
00178 case 'G':
00179 case KEY_END:
00180
00181 end_reached = 1;
00182
00183 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
00184 endwin ();
00185 fprintf (stderr,
00186 "\nError moving file pointer in dialog_textbox().\n");
00187 exit (-1);
00188 }
00189 if (fpos < file_size) {
00190 if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
00191 endwin ();
00192 fprintf (stderr,
00193 "\nError moving file pointer in dialog_textbox().\n");
00194 exit (-1);
00195 }
00196 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
00197 endwin ();
00198 fprintf (stderr,
00199 "\nError reading file in dialog_textbox().\n");
00200 exit (-1);
00201 }
00202 buf[bytes_read] = '\0';
00203 }
00204 page = buf + bytes_read;
00205 back_lines (height - 4);
00206 print_page (text, height - 4, width - 2);
00207 print_position (dialog, height, width);
00208 wmove (dialog, cur_y, cur_x);
00209 wrefresh (dialog);
00210 break;
00211 case 'K':
00212 case 'k':
00213 case KEY_UP:
00214 if (!begin_reached) {
00215 back_lines (page_length + 1);
00216
00217
00218
00219
00220
00221
00222 scrollok (text, TRUE);
00223 wscrl (text, -1);
00224 scrollok (text, FALSE);
00225 page_length = 0;
00226 passed_end = 0;
00227 for (i = 0; i < height - 4; i++) {
00228 if (!i) {
00229
00230 print_line (text, 0, width - 2);
00231 wnoutrefresh (text);
00232 } else
00233
00234 get_line ();
00235 if (!passed_end)
00236 page_length++;
00237 if (end_reached && !passed_end)
00238 passed_end = 1;
00239 }
00240
00241 print_position (dialog, height, width);
00242 wmove (dialog, cur_y, cur_x);
00243 wrefresh (dialog);
00244 }
00245 break;
00246 case 'B':
00247 case 'b':
00248 case KEY_PPAGE:
00249 if (begin_reached)
00250 break;
00251 back_lines (page_length + height - 4);
00252 print_page (text, height - 4, width - 2);
00253 print_position (dialog, height, width);
00254 wmove (dialog, cur_y, cur_x);
00255 wrefresh (dialog);
00256 break;
00257 case 'J':
00258 case 'j':
00259 case KEY_DOWN:
00260 if (!end_reached) {
00261 begin_reached = 0;
00262 scrollok (text, TRUE);
00263 scroll (text);
00264 scrollok (text, FALSE);
00265 print_line (text, height - 5, width - 2);
00266 wnoutrefresh (text);
00267 print_position (dialog, height, width);
00268 wmove (dialog, cur_y, cur_x);
00269 wrefresh (dialog);
00270 }
00271 break;
00272 case KEY_NPAGE:
00273 case ' ':
00274 if (end_reached)
00275 break;
00276
00277 begin_reached = 0;
00278 print_page (text, height - 4, width - 2);
00279 print_position (dialog, height, width);
00280 wmove (dialog, cur_y, cur_x);
00281 wrefresh (dialog);
00282 break;
00283 case '0':
00284 case 'H':
00285 case 'h':
00286 case KEY_LEFT:
00287 if (hscroll <= 0)
00288 break;
00289
00290 if (key == '0')
00291 hscroll = 0;
00292 else
00293 hscroll--;
00294
00295 back_lines (page_length);
00296 print_page (text, height - 4, width - 2);
00297 wmove (dialog, cur_y, cur_x);
00298 wrefresh (dialog);
00299 break;
00300 case 'L':
00301 case 'l':
00302 case KEY_RIGHT:
00303 if (hscroll >= MAX_LEN)
00304 break;
00305 hscroll++;
00306
00307 back_lines (page_length);
00308 print_page (text, height - 4, width - 2);
00309 wmove (dialog, cur_y, cur_x);
00310 wrefresh (dialog);
00311 break;
00312 case ESC:
00313 break;
00314 }
00315 }
00316
00317 delwin (dialog);
00318 free (buf);
00319 close (fd);
00320 return -1;
00321 }
00322
00323
00324
00325
00326
00327 static void
00328 back_lines (int n)
00329 {
00330 int i, fpos;
00331
00332 begin_reached = 0;
00333
00334
00335
00336
00337 if (!end_reached) {
00338
00339 if (page == buf) {
00340 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
00341 endwin ();
00342 fprintf (stderr, "\nError moving file pointer in "
00343 "back_lines().\n");
00344 exit (-1);
00345 }
00346 if (fpos > bytes_read) {
00347
00348
00349
00350
00351
00352
00353 if (fpos < BUF_SIZE / 2 + bytes_read) {
00354
00355 if (lseek (fd, 0, SEEK_SET) == -1) {
00356 endwin ();
00357 fprintf (stderr, "\nError moving file pointer in "
00358 "back_lines().\n");
00359 exit (-1);
00360 }
00361 page = buf + fpos - bytes_read;
00362 } else {
00363 if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
00364 == -1) {
00365 endwin ();
00366 fprintf (stderr, "\nError moving file pointer "
00367 "in back_lines().\n");
00368 exit (-1);
00369 }
00370 page = buf + BUF_SIZE / 2;
00371 }
00372 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
00373 endwin ();
00374 fprintf (stderr, "\nError reading file in back_lines().\n");
00375 exit (-1);
00376 }
00377 buf[bytes_read] = '\0';
00378 } else {
00379 begin_reached = 1;
00380 return;
00381 }
00382 }
00383 if (*(--page) != '\n') {
00384
00385 endwin ();
00386 fprintf (stderr, "\nInternal error in back_lines().\n");
00387 exit (-1);
00388 }
00389 }
00390
00391 for (i = 0; i < n; i++)
00392 do {
00393 if (page == buf) {
00394 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
00395 endwin ();
00396 fprintf (stderr,
00397 "\nError moving file pointer in back_lines().\n");
00398 exit (-1);
00399 }
00400 if (fpos > bytes_read) {
00401
00402 if (fpos < BUF_SIZE / 2 + bytes_read) {
00403
00404 if (lseek (fd, 0, SEEK_SET) == -1) {
00405 endwin ();
00406 fprintf (stderr, "\nError moving file pointer "
00407 "in back_lines().\n");
00408 exit (-1);
00409 }
00410 page = buf + fpos - bytes_read;
00411 } else {
00412 if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
00413 SEEK_CUR) == -1) {
00414 endwin ();
00415 fprintf (stderr, "\nError moving file pointer"
00416 " in back_lines().\n");
00417 exit (-1);
00418 }
00419 page = buf + BUF_SIZE / 2;
00420 }
00421 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
00422 endwin ();
00423 fprintf (stderr, "\nError reading file in "
00424 "back_lines().\n");
00425 exit (-1);
00426 }
00427 buf[bytes_read] = '\0';
00428 } else {
00429 begin_reached = 1;
00430 return;
00431 }
00432 }
00433 } while (*(--page) != '\n');
00434 page++;
00435 }
00436
00437
00438
00439
00440 static void
00441 print_page (WINDOW * win, int height, int width)
00442 {
00443 int i, passed_end = 0;
00444
00445 page_length = 0;
00446 for (i = 0; i < height; i++) {
00447 print_line (win, i, width);
00448 if (!passed_end)
00449 page_length++;
00450 if (end_reached && !passed_end)
00451 passed_end = 1;
00452 }
00453 wnoutrefresh (win);
00454 }
00455
00456
00457
00458
00459 static void
00460 print_line (WINDOW * win, int row, int width)
00461 {
00462 int y, x;
00463 char *line;
00464
00465 line = get_line ();
00466 line += MIN (strlen (line), hscroll);
00467 wmove (win, row, 0);
00468 waddch (win, ' ');
00469 waddnstr (win, line, MIN (strlen (line), width - 2));
00470
00471 getyx (win, y, x);
00472
00473 #if OLD_NCURSES
00474 {
00475 int i;
00476 for (i = 0; i < width - x; i++)
00477 waddch (win, ' ');
00478 }
00479 #else
00480 wclrtoeol(win);
00481 #endif
00482 }
00483
00484
00485
00486
00487
00488
00489 static char *
00490 get_line (void)
00491 {
00492 int i = 0, fpos;
00493 static char line[MAX_LEN + 1];
00494
00495 end_reached = 0;
00496 while (*page != '\n') {
00497 if (*page == '\0') {
00498
00499 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
00500 endwin ();
00501 fprintf (stderr, "\nError moving file pointer in "
00502 "get_line().\n");
00503 exit (-1);
00504 }
00505 if (fpos < file_size) {
00506
00507
00508 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
00509 endwin ();
00510 fprintf (stderr, "\nError reading file in get_line().\n");
00511 exit (-1);
00512 }
00513 buf[bytes_read] = '\0';
00514 page = buf;
00515 } else {
00516 if (!end_reached)
00517 end_reached = 1;
00518 break;
00519 }
00520 } else if (i < MAX_LEN)
00521 line[i++] = *(page++);
00522 else {
00523
00524 if (i == MAX_LEN)
00525 line[i++] = '\0';
00526 page++;
00527 }
00528 }
00529 if (i <= MAX_LEN)
00530 line[i] = '\0';
00531 if (!end_reached)
00532 page++;
00533
00534 return line;
00535 }
00536
00537
00538
00539
00540 static void
00541 print_position (WINDOW * win, int height, int width)
00542 {
00543 int fpos, percent;
00544
00545 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
00546 endwin ();
00547 fprintf (stderr, "\nError moving file pointer in print_position().\n");
00548 exit (-1);
00549 }
00550 wattrset (win, position_indicator_attr);
00551 wbkgdset (win, position_indicator_attr & A_COLOR);
00552 percent = !file_size ?
00553 100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
00554 wmove (win, height - 3, width - 9);
00555 wprintw (win, "(%3d%%)", percent);
00556 }