home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / a / hdsetup / dialog-0.4-1 / dialog-0 / dialog-0.4-slackware / src / textbox.c-3d < prev    next >
Encoding:
Text File  |  1994-06-09  |  22.2 KB  |  710 lines

  1. /*
  2.  *  textbox.c -- implements the text box
  3.  *
  4.  *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
  5.  *
  6.  *  This program is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU General Public License
  8.  *  as published by the Free Software Foundation; either version 2
  9.  *  of the License, or (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21.  
  22. #include "dialog.h"
  23.  
  24.  
  25. static void back_lines(int n);
  26. static void print_page(WINDOW *win, int height, int width);
  27. static void print_line(WINDOW *win, int row, int width);
  28. static unsigned char *get_line(void);
  29. static int get_search_term(WINDOW *win, unsigned char *search_term, int height, int width);
  30. static void print_position(WINDOW *win, int height, int width);
  31.  
  32.  
  33. static int hscroll = 0, fd, file_size, bytes_read, begin_reached = 1,
  34.            end_reached = 0, page_length;
  35. static unsigned char *buf, *page;
  36.  
  37.  
  38. /*
  39.  * Display text from a file in a dialog box.
  40.  */
  41. int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width)
  42. {
  43.   int i, x, y, cur_x, cur_y, fpos, key = 0, dir, temp, temp1;
  44. #ifdef HAVE_NCURSES
  45.   int passed_end;
  46. #endif
  47.   unsigned char search_term[MAX_LEN+1], *tempptr, *found;
  48.   WINDOW *dialog, *text;
  49.  
  50.   search_term[0] = '\0';    /* no search term entered yet */
  51.  
  52.   /* Open input file for reading */
  53.   if ((fd = open(file, O_RDONLY)) == -1) {
  54.     endwin();
  55.     fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
  56.     exit(-1);
  57.   }
  58.   /* Get file size. Actually, 'file_size' is the real file size - 1,
  59.      since it's only the last byte offset from the beginning */
  60.   if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
  61.     endwin();
  62.     fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
  63.     exit(-1);
  64.   }
  65.   /* Restore file pointer to beginning of file after getting file size */
  66.   if (lseek(fd, 0, SEEK_SET) == -1) {
  67.     endwin();
  68.     fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  69.     exit(-1);
  70.   }
  71.   /* Allocate space for read buffer */
  72.   if ((buf = malloc(BUF_SIZE+1)) == NULL) {
  73.     endwin();
  74.     fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
  75.     exit(-1);
  76.   }
  77.   if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  78.     endwin();
  79.     fprintf(stderr, "\nError reading file in dialog_textbox().\n");
  80.     exit(-1);
  81.   }
  82.   buf[bytes_read] = '\0';    /* mark end of valid data */
  83.   page = buf;    /* page is pointer to start of page to be displayed */
  84.  
  85.   /* center dialog box on screen */
  86.   x = (COLS - width)/2;
  87.   y = (LINES - height)/2;
  88.  
  89. #ifdef HAVE_NCURSES
  90.   if (use_shadow)
  91.     draw_shadow(stdscr, y, x, height, width);
  92. #endif
  93.   dialog = newwin(height, width, y, x);
  94.   keypad(dialog, TRUE);
  95.  
  96.   /* Create window for text region, used for scrolling text */
  97. /*  text = newwin(height-4, width-2, y+1, x+1); */
  98.   text = subwin(dialog, height-4, width-2, y+1, x+1);
  99.   keypad(text, TRUE);
  100.  
  101.   draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
  102.  
  103.   wattrset(dialog, border_attr);
  104.   wmove(dialog, height-3, 0);
  105.   waddch(dialog, ACS_LTEE);
  106.   for (i = 0; i < width-2; i++)
  107.     waddch(dialog, ACS_HLINE);
  108.   wattrset(dialog, dialog_attr);
  109.   waddch(dialog, ACS_RTEE);
  110.   wmove(dialog, height-2, 1);
  111.   for (i = 0; i < width-2; i++)
  112.     waddch(dialog, ' ');
  113.  
  114.   if (title != NULL) {
  115.     wattrset(dialog, title_attr);
  116.     wmove(dialog, 0, (width - strlen(title))/2 - 1);
  117.     waddch(dialog, ' ');
  118.     waddstr(dialog, title);
  119.     waddch(dialog, ' ');
  120.   }
  121.   print_button(dialog, " EXIT ", height-2, width/2-4, TRUE);
  122.   wnoutrefresh(dialog);
  123.   getyx(dialog, cur_y, cur_x);    /* Save cursor position */
  124.  
  125.   /* Print first page of text */
  126.   attr_clear(text, height-4, width-2, dialog_attr);
  127.   print_page(text, height-4, width-2);
  128.   print_position(dialog, height, width);
  129.   wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  130.   wrefresh(dialog);
  131.  
  132.   while ((key != ESC) && (key != '\n')) {
  133.     key = wgetch(dialog);
  134.     switch (key) {
  135.       case 'E':    /* Exit */
  136.       case 'e':
  137.         delwin(dialog);
  138.         free(buf);
  139.         close(fd);
  140.         return 0;
  141.       case 'g':    /* First page */
  142.       case KEY_HOME:
  143.         if (!begin_reached) {
  144.           begin_reached = 1;
  145.           /* First page not in buffer? */
  146.           if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  147.             endwin();
  148.             fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  149.             exit(-1);
  150.           }
  151.           if (fpos > bytes_read) {    /* Yes, we have to read it in */
  152.             if (lseek(fd, 0, SEEK_SET) == -1) {
  153.               endwin();
  154.               fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  155.               exit(-1);
  156.             }
  157.             if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  158.               endwin();
  159.               fprintf(stderr, "\nError reading file in dialog_textbox().\n");
  160.               exit(-1);
  161.             }
  162.             buf[bytes_read] = '\0';
  163.           }
  164.           page = buf;
  165.           print_page(text, height-4, width-2);
  166.           print_position(dialog, height, width);
  167.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  168.           wrefresh(dialog);
  169.         }
  170.         break;
  171.       case 'G':    /* Last page */
  172. #ifdef HAVE_NCURSES
  173.       case KEY_END:
  174. #endif
  175.         end_reached = 1;
  176.         /* Last page not in buffer? */
  177.         if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  178.           endwin();
  179.           fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  180.           exit(-1);
  181.         }
  182.         if (fpos < file_size) {    /* Yes, we have to read it in */
  183.           if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
  184.             endwin();
  185.             fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  186.             exit(-1);
  187.           }
  188.           if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  189.             endwin();
  190.             fprintf(stderr, "\nError reading file in dialog_textbox().\n");
  191.             exit(-1);
  192.           }
  193.           buf[bytes_read] = '\0';
  194.         }
  195.         page = buf + bytes_read;
  196.         back_lines(height-4);
  197.         print_page(text, height-4, width-2);
  198.         print_position(dialog, height, width);
  199.         wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  200.         wrefresh(dialog);
  201.         break;
  202.       case 'K':    /* Previous line */
  203.       case 'k':
  204.       case KEY_UP:
  205.         if (!begin_reached) {
  206.           back_lines(page_length+1);
  207. #ifdef HAVE_NCURSES
  208.           /* We don't call print_page() here but use scrolling to ensure
  209.              faster screen update. However, 'end_reached' and 'page_length'
  210.              should still be updated, and 'page' should point to start of
  211.              next page. This is done by calling get_line() in the following
  212.              'for' loop. */
  213.           scrollok(text, TRUE);
  214.           wscrl(text, -1);    /* Scroll text region down one line */
  215.           scrollok(text, FALSE);
  216.           page_length = 0;
  217.           passed_end = 0;
  218.           for (i = 0; i < height-4; i++) {
  219.             if (!i) {
  220.               print_line(text, 0, width-2);    /* print first line of page */
  221.               wnoutrefresh(text);
  222.             }
  223.             else
  224.               get_line();    /* Called to update 'end_reached' and 'page' */
  225.             if (!passed_end)
  226.               page_length++;
  227.             if (end_reached && !passed_end)
  228.               passed_end = 1;
  229.           }
  230. #else
  231.           print_page(text, height-4, width-2);
  232. #endif
  233.           print_position(dialog, height, width);
  234.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  235.           wrefresh(dialog);
  236.         }
  237.         break;
  238.       case 'B':    /* Previous page */
  239.       case 'b':
  240.       case KEY_PPAGE:
  241.         if (!begin_reached) {
  242.           back_lines(page_length + height-4);
  243.           print_page(text, height-4, width-2);
  244.           print_position(dialog, height, width);
  245.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  246.           wrefresh(dialog);
  247.         }
  248.         break;
  249.       case 'J':    /* Next line */
  250.       case 'j':
  251.       case KEY_DOWN:
  252.         if (!end_reached) {
  253.           begin_reached = 0;
  254.           scrollok(text, TRUE);
  255.           scroll(text);    /* Scroll text region up one line */
  256.           scrollok(text, FALSE);
  257.           print_line(text, height-5, width-2);
  258. #ifndef HAVE_NCURSES
  259.           wmove(text, height-5, 0);
  260.           waddch(text, ' ');
  261.           wmove(text, height-5, width-3);
  262.           waddch(text, ' ');
  263. #endif
  264.           wnoutrefresh(text);
  265.           print_position(dialog, height, width);
  266.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  267.           wrefresh(dialog);
  268.         }
  269.         break;
  270.       case ' ':    /* Next page */
  271.       case KEY_NPAGE:
  272.         if (!end_reached) {
  273.           begin_reached = 0;
  274.           print_page(text, height-4, width-2);
  275.           print_position(dialog, height, width);
  276.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  277.           wrefresh(dialog);
  278.         }
  279.         break;
  280.       case '0':    /* Beginning of line */
  281.       case 'H':    /* Scroll left */
  282.       case 'h':
  283.       case KEY_LEFT:
  284.         if (hscroll > 0) {
  285.           if (key == '0')
  286.             hscroll = 0;
  287.           else
  288.             hscroll--;
  289.           /* Reprint current page to scroll horizontally */
  290.           back_lines(page_length);
  291.           print_page(text, height-4, width-2);
  292.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  293.           wrefresh(dialog);
  294.         }
  295.         break;
  296.       case 'L':    /* Scroll right */
  297.       case 'l':
  298.       case KEY_RIGHT:
  299.         if (hscroll < MAX_LEN) {
  300.           hscroll++;
  301.           /* Reprint current page to scroll horizontally */
  302.           back_lines(page_length);
  303.           print_page(text, height-4, width-2);
  304.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  305.           wrefresh(dialog);
  306.         }
  307.         break;
  308.       case '/':    /* Forward search */
  309.       case 'n':    /* Repeat forward search */
  310.       case '?':    /* Backward search */
  311.       case 'N':    /* Repeat backward search */
  312.         /* set search direction */
  313.         dir = (key == '/' || key == 'n') ? 1 : 0;
  314.         if (dir ? !end_reached : !begin_reached) {
  315.           if (key == 'n' || key == 'N') {
  316.             if (search_term[0] == '\0') {    /* No search term yet */
  317.               fprintf(stderr, "\a");    /* beep */
  318.               break;
  319.             }
  320.       }
  321.           else    /* Get search term from user */
  322.             if (get_search_term(text, search_term, height-4, width-2) == -1) {
  323.               /* ESC pressed in get_search_term(). Reprint page to clear box */
  324.               wattrset(text, dialog_attr);
  325.               back_lines(page_length);
  326.               print_page(text, height-4, width-2);
  327.               wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  328.               wrefresh(dialog);
  329.               break;
  330.             }
  331.           /* Save variables for restoring in case search term can't be found */
  332.           tempptr = page;
  333.           temp = begin_reached;
  334.           temp1 = end_reached;
  335.           if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  336.             endwin();
  337.             fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  338.             exit(-1);
  339.           }
  340.           fpos -= bytes_read;
  341.           /* update 'page' to point to next (previous) line before
  342.              forward (backward) searching */
  343.           back_lines(dir ? page_length-1 : page_length+1);
  344.           found = NULL;
  345.           if (dir)    /* Forward search */
  346.             while((found = strstr(get_line(), search_term)) == NULL) {
  347.               if (end_reached)
  348.                 break;
  349.         }
  350.           else    /* Backward search */
  351.             while((found = strstr(get_line(), search_term)) == NULL) {
  352.               if (begin_reached)
  353.                 break;
  354.               back_lines(2);
  355.             }
  356.           if (found == NULL) {    /* not found */
  357.             fprintf(stderr, "\a");    /* beep */
  358.             /* Restore program state to that before searching */
  359.             if (lseek(fd, fpos, SEEK_SET) == -1) {
  360.               endwin();
  361.               fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  362.               exit(-1);
  363.             }
  364.             if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  365.               endwin();
  366.               fprintf(stderr, "\nError reading file in dialog_textbox().\n");
  367.               exit(-1);
  368.             }
  369.             buf[bytes_read] = '\0';
  370.             page = tempptr;
  371.             begin_reached = temp;
  372.             end_reached = temp1;
  373.             /* move 'page' to point to start of current page in order to
  374.                re-print current page. Note that 'page' always points to
  375.                start of next page, so this is necessary */
  376.             back_lines(page_length);
  377.           }
  378.           else    /* Search term found */
  379.             back_lines(1);
  380.           /* Reprint page */
  381.           wattrset(text, dialog_attr);
  382.           print_page(text, height-4, width-2);
  383.           if (found != NULL)
  384.             print_position(dialog, height, width);
  385.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  386.           wrefresh(dialog);
  387.         }
  388.         else    /* no need to find */
  389.           fprintf(stderr, "\a");    /* beep */
  390.         break;
  391.       case ESC:
  392.         break;
  393.     }
  394.   }
  395.  
  396.   delwin(dialog);
  397.   free(buf);
  398.   close(fd);
  399.   return -1;    /* ESC pressed */
  400. }
  401. /* End of dialog_textbox() */
  402.  
  403.  
  404. /*
  405.  * Go back 'n' lines in text file. Called by dialog_textbox().
  406.  * 'page' will be updated to point to the desired line in 'buf'.
  407.  */
  408. static void back_lines(int n)
  409. {
  410.   int i, fpos;
  411.  
  412.   begin_reached = 0;
  413.   /* We have to distinguish between end_reached and !end_reached since at end
  414.      of file, the line is not ended by a '\n'. The code inside 'if' basically
  415.      does a '--page' to move one character backward so as to skip '\n' of the
  416.      previous line */
  417.   if (!end_reached) {
  418.     /* Either beginning of buffer or beginning of file reached? */
  419.     if (page == buf) {
  420.       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  421.         endwin();
  422.         fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  423.         exit(-1);
  424.       }
  425.       if (fpos > bytes_read) {    /* Not beginning of file yet */
  426.         /* We've reached beginning of buffer, but not beginning of file yet,
  427.            so read previous part of file into buffer. Note that we only
  428.            move backward for BUF_SIZE/2 bytes, but not BUF_SIZE bytes to
  429.            avoid re-reading again in print_page() later */
  430.         /* Really possible to move backward BUF_SIZE/2 bytes? */
  431.         if (fpos < BUF_SIZE/2 + bytes_read) {
  432.           /* No, move less then */
  433.           if (lseek(fd, 0, SEEK_SET) == -1) {
  434.             endwin();
  435.             fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  436.             exit(-1);
  437.           }
  438.           page = buf + fpos - bytes_read;
  439.         }
  440.         else {    /* Move backward BUF_SIZE/2 bytes */
  441.           if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
  442.             endwin();
  443.             fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  444.             exit(-1);
  445.           }
  446.           page = buf + BUF_SIZE/2;
  447.         }
  448.         if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  449.           endwin();
  450.           fprintf(stderr, "\nError reading file in back_lines().\n");
  451.           exit(-1);
  452.         }
  453.         buf[bytes_read] = '\0';
  454.       }
  455.       else {    /* Beginning of file reached */
  456.         begin_reached = 1;
  457.         return;
  458.       }
  459.     }
  460.     if (*(--page) != '\n') {    /* '--page' here */
  461.       /* Something's wrong... */
  462.       endwin();
  463.       fprintf(stderr, "\nInternal error in back_lines().\n");
  464.       exit(-1);
  465.     }
  466.   }
  467.  
  468.   /* Go back 'n' lines */
  469.   for (i = 0; i < n; i++)
  470.     do {
  471.       if (page == buf) {
  472.         if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  473.           endwin();
  474.           fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  475.           exit(-1);
  476.         }
  477.         if (fpos > bytes_read) {
  478.           /* Really possible to move backward BUF_SIZE/2 bytes? */
  479.           if (fpos < BUF_SIZE/2 + bytes_read) {
  480.             /* No, move less then */
  481.             if (lseek(fd, 0, SEEK_SET) == -1) {
  482.               endwin();
  483.               fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  484.               exit(-1);
  485.             }
  486.             page = buf + fpos - bytes_read;
  487.           }
  488.           else {    /* Move backward BUF_SIZE/2 bytes */
  489.             if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
  490.               endwin();
  491.               fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  492.               exit(-1);
  493.             }
  494.             page = buf + BUF_SIZE/2;
  495.           }
  496.           if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  497.             endwin();
  498.             fprintf(stderr, "\nError reading file in back_lines().\n");
  499.             exit(-1);
  500.           }
  501.           buf[bytes_read] = '\0';
  502.         }
  503.         else {    /* Beginning of file reached */
  504.           begin_reached = 1;
  505.           return;
  506.         }
  507.       }
  508.     } while (*(--page) != '\n');
  509.   page++;
  510. }
  511. /* End of back_lines() */
  512.  
  513.  
  514. /*
  515.  * Print a new page of text. Called by dialog_textbox().
  516.  */
  517. static void print_page(WINDOW *win, int height, int width)
  518. {
  519.   int i, passed_end = 0;
  520.  
  521.   page_length = 0;
  522.   for (i = 0; i < height; i++) {
  523.     print_line(win, i, width);
  524.     if (!passed_end)
  525.       page_length++;
  526.     if (end_reached && !passed_end)
  527.       passed_end = 1;
  528.   }
  529.   wnoutrefresh(win);
  530. }
  531. /* End of print_page() */
  532.  
  533.  
  534. /*
  535.  * Print a new line of text. Called by dialog_textbox() and print_page().
  536.  */
  537. static void print_line(WINDOW *win, int row, int width)
  538. {
  539.   int i, y, x;
  540.   unsigned char *line;
  541.  
  542.   line = get_line();
  543.   line += MIN(strlen(line),hscroll);    /* Scroll horizontally */
  544.   wmove(win, row, 0);    /* move cursor to correct line */
  545.   waddch(win,' ');
  546. #ifdef HAVE_NCURSES
  547.   waddnstr(win, line, MIN(strlen(line),width-2));
  548. #else
  549.   line[MIN(strlen(line),width-2)] = '\0';
  550.   waddstr(win, line);
  551. #endif
  552.  
  553.   getyx(win, y, x);
  554.   /* Clear 'residue' of previous line */
  555.   for (i = 0; i < width-x; i++)
  556.     waddch(win, ' ');
  557. }
  558. /* End of print_line() */
  559.  
  560.  
  561. /*
  562.  * Return current line of text. Called by dialog_textbox() and print_line().
  563.  * 'page' should point to start of current line before calling, and will be
  564.  * updated to point to start of next line.
  565.  */
  566. static unsigned char *get_line(void)
  567. {
  568.   int i = 0, fpos;
  569.   static unsigned char line[MAX_LEN+1];
  570.  
  571.   end_reached = 0;
  572.   while (*page != '\n') {
  573.     if (*page == '\0') {    /* Either end of file or end of buffer reached */
  574.       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  575.         endwin();
  576.         fprintf(stderr, "\nError moving file pointer in get_line().\n");
  577.         exit(-1);
  578.       }
  579.       if (fpos < file_size) {    /* Not end of file yet */
  580.         /* We've reached end of buffer, but not end of file yet, so read next
  581.            part of file into buffer */
  582.         if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  583.           endwin();
  584.           fprintf(stderr, "\nError reading file in get_line().\n");
  585.           exit(-1);
  586.         }
  587.         buf[bytes_read] = '\0';
  588.         page = buf;
  589.       }
  590.       else {
  591.         if (!end_reached)
  592.           end_reached = 1;
  593.         break;
  594.       }
  595.     }
  596.     else
  597.       if (i < MAX_LEN)
  598.         line[i++] = *(page++);
  599.       else {
  600.         if (i == MAX_LEN)  /* Truncate lines longer than MAX_LEN characters */
  601.           line[i++] = '\0';
  602.         page++;
  603.       }
  604.   }
  605.   if (i <= MAX_LEN)
  606.     line[i] = '\0';
  607.   if (!end_reached)
  608.     page++;    /* move pass '\n' */
  609.  
  610.   return line;
  611. }
  612. /* End of get_line() */
  613.  
  614.  
  615. /*
  616.  * Display a dialog box and get the search term from user
  617.  */
  618. static int get_search_term(WINDOW *win, unsigned char *search_term, int height, int width)
  619. {
  620.   int i, x, y, input_x = 0, scroll = 0, key = 0,
  621.       box_height = 3, box_width = 30;
  622.  
  623.   x = (width - box_width)/2;
  624.   y = (height - box_height)/2;
  625. #ifdef HAVE_NCURSES
  626.   if (use_shadow)
  627.     draw_shadow(win, y, x, box_height, box_width);
  628. #endif
  629.   draw_box(win, y, x, box_height, box_width, dialog_attr, searchbox_border_attr);
  630.   wattrset(win, searchbox_title_attr);
  631.   wmove(win, y, x+box_width/2-4);
  632.   waddstr(win, " Search ");
  633.  
  634.   box_width -= 2;
  635.   wmove(win, y+1, x+1);
  636.   wrefresh(win);
  637.   search_term[0] = '\0';
  638.   wattrset(win, searchbox_attr);
  639.   while (key != ESC) {
  640.     key = wgetch(win);
  641.     switch (key) {
  642.       case '\n':
  643.         if (search_term[0] != '\0')
  644.           return 0;
  645.         break;
  646.       case KEY_BACKSPACE:
  647.         if (input_x || scroll) {
  648.           if (!input_x) {
  649.             scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
  650.             wmove(win, y+1, x+1);
  651.             for (i = 0; i < box_width; i++)
  652.               waddch(win, search_term[scroll+input_x+i] ?
  653.                             search_term[scroll+input_x+i] : ' ');
  654.             input_x = strlen(search_term) - scroll;
  655.           }
  656.           else
  657.             input_x--;
  658.           search_term[scroll+input_x] = '\0';
  659.           wmove(win, y+1, input_x + x+1);
  660.           waddch(win, ' ');
  661.           wmove(win, y+1, input_x + x+1);
  662.           wrefresh(win);
  663.         }
  664.         break;
  665.       case ESC:
  666.         break;
  667.       default:
  668.         if (isprint(key))
  669.           if (scroll+input_x < MAX_LEN) {
  670.             search_term[scroll+input_x] = key;
  671.             search_term[scroll+input_x+1] = '\0';
  672.             if (input_x == box_width-1) {
  673.               scroll++;
  674.               wmove(win, y+1, x+1);
  675.               for (i = 0; i < box_width-1; i++)
  676.                 waddch(win, search_term[scroll+i]);
  677.             }
  678.             else {
  679.               wmove(win, y+1, input_x++ + x+1);
  680.               waddch(win, key);
  681.             }
  682.             wrefresh(win);
  683.           }
  684.     }
  685.   }
  686.  
  687.   return -1;    /* ESC pressed */
  688. }
  689. /* End of get_search_term() */
  690.  
  691.  
  692. /*
  693.  * Print current position
  694.  */
  695. static void print_position(WINDOW *win, int height, int width)
  696. {
  697.   int fpos, percent;
  698.  
  699.   if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  700.     endwin();
  701.     fprintf(stderr, "\nError moving file pointer in print_position().\n");
  702.     exit(-1);
  703.   }
  704.   wattrset(win, position_indicator_attr);
  705.   percent = !file_size ? 100 : ((fpos-bytes_read+page-buf)*100)/file_size;
  706.   wmove(win, height-3, width-9);
  707.   wprintw(win, "(%3d%%)", percent);
  708. }
  709. /* End of print_position() */
  710.