home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / utilities / dirutils / visualshell / src / view.c < prev   
C/C++ Source or Header  |  1992-10-29  |  15KB  |  498 lines

  1.         /*********************************
  2.          *                               *
  3.          *   Visual Shell v1.17  10/92   *
  4.          *                               *
  5.          *     by Torsten Jürgeleit      *
  6.          *                               *
  7.          *          view part            *
  8.          *                               *
  9.          *********************************/
  10.  
  11.     /* Includes */
  12.  
  13. #include "includes.h"
  14. #include "imports.h"
  15. #include "protos.h"
  16.  
  17.     /* View file as ASCII or hex dump */
  18.  
  19.    VOID
  20. action_view(VOID)
  21. {
  22.    struct FileRequest  *freq = &file_req[active_freq];
  23.    struct FileNode     *fnode;
  24.  
  25.    if ((freq->fr_Mode == FREQ_MODE_NORMAL || freq->fr_Mode ==
  26.                  FREQ_MODE_FIND) && freq->fr_CursorLine != -1) {
  27.       fnode = get_file_node_under_cursor(freq);
  28.       if (fnode->fn_Type == ENTRY_TYPE_FILE) {   /* file selected ? */
  29.      print_status(view_file(freq, fnode));
  30.       }
  31.    }
  32. }
  33.     /* View selected file */
  34.  
  35.    SHORT
  36. view_file(struct FileRequest  *freq, struct FileNode  *fnode)
  37. {
  38.    struct ViewRequest  *vreq = &view_req;
  39.    SHORT error = VSH_STATUS_NORMAL;
  40.  
  41.    print_status(VSH_STATUS_READ_FILE);
  42.    hcomp_freq_cursor(freq);
  43.    print_info_line(INFO_LINE_MODE_EMPTY);
  44.    print_fkey_text(FKEY_MODE_NONE);
  45.    if ((error = read_view_file(freq, fnode, vreq)) == VSH_STATUS_NORMAL) {
  46.       USHORT vlines = vreq->vr_Display.d_VisibleLines;
  47.  
  48.       print_view_page(vreq);
  49.       do {
  50.      ULONG signals = Wait(SIGF_INTUITION | SIGF_ACTION);
  51.  
  52.      if (signals & SIGF_INTUITION) {   /* timing events from Intuition */
  53.         struct IntuiMessage  *msg;
  54.  
  55.         if (msg = (struct IntuiMessage *)GetMsg(con_window->UserPort)) {
  56.            ULONG class = msg->Class;
  57.  
  58.            ReplyMsg((struct Message *)msg);
  59.            switch (class) {
  60.           case REFRESHWINDOW :
  61.              print_view_page(vreq);
  62.              break;
  63.           case INTUITICKS :
  64.              if (status != VSH_STATUS_NORMAL) {
  65.             if (error_delay-- < 0) {   /* remove error msg in status line */
  66.                print_vreq_status(vreq);
  67.                status = VSH_STATUS_NORMAL;
  68.             }
  69.              }
  70.              if (auto_repeat) {
  71.             scroll_view_req();
  72.              }
  73.              break;
  74.            }
  75.         }
  76.      }
  77.      if (signals & SIGF_ACTION) {
  78.         if (vreq->vr_MarkedEntries) {
  79.            print_vreq_lines(vreq, vreq->vr_Display.d_FirstVisibleNode,
  80.                              (USHORT)0, vlines);
  81.            vreq->vr_MarkedEntries = 0;
  82.         }
  83.         switch (action) {
  84.            case VSH_ACTION_F1 :   /* jump to line */
  85.           jump_to_view_line(vreq);
  86.           break;
  87.            case VSH_ACTION_F2 :   /* start searching */
  88.           search_view_line(vreq, VIEW_SEARCH_MODE_FIRST);
  89.           break;
  90.            case VSH_ACTION_F3 :   /* continue searching */
  91.           search_view_line(vreq, VIEW_SEARCH_MODE_NEXT);
  92.           break;
  93.            case VSH_ACTION_F4 :   /* change view mode */
  94.           error = change_view_mode(vreq);
  95.           break;
  96.            case VSH_ACTION_F5 :   /* print current page */
  97.           print_view_text(vreq, PRINT_MODE_PAGE);
  98.           break;
  99.            case VSH_ACTION_F6 :   /* print whole text */
  100.           print_view_text(vreq, PRINT_MODE_ALL);
  101.           break;
  102.            case VSH_ACTION_SCROLL_UP :
  103.            case VSH_ACTION_SCROLL_DOWN :
  104.            case VSH_ACTION_SCROLL_PAGE_UP :
  105.            case VSH_ACTION_SCROLL_PAGE_DOWN :
  106.            case VSH_ACTION_SCROLL_TOP :
  107.            case VSH_ACTION_SCROLL_BOTTOM :
  108.           scroll_view_req();
  109.           break;
  110.         }
  111.      }
  112.       } while (error == VSH_STATUS_NORMAL && action != VSH_ACTION_QUIT &&
  113.                           action != VSH_ACTION_ESC);
  114.       print_status(VSH_STATUS_FREE_LINE_LIST);
  115.       free_list(vreq->vr_Display.d_List, (LONG)sizeof(struct LineNode));
  116.       FreeMem(vreq->vr_Buffer, vreq->vr_BufferSize);
  117.       draw_requesters(DRAW_MODE_CLEAR);
  118.    } else {
  119.       hcomp_freq_cursor(freq);
  120.       print_info_line(INFO_LINE_MODE_NORMAL);
  121.    }
  122.    change_fkey_text();
  123.    return(error);
  124. }
  125.     /* Display view page */
  126.  
  127.    VOID
  128. print_view_page(struct ViewRequest  *vreq)
  129. {
  130.    SetAPen(con_rport, (LONG)COLOR0);
  131.    RectFill(con_rport, (LONG)(BORDER_LEFT - 2), (LONG)(BORDER_TOP_HIDDEN
  132.       - 1), (LONG)(vsh_width - BORDER_RIGHT    + 1), (LONG)(cli_vpos - 3));
  133.    draw_line(COLOR1, (USHORT)2, (USHORT)(BORDER_TOP_HIDDEN - 2), (USHORT)
  134.               (vsh_width - 3), (USHORT)(BORDER_TOP_HIDDEN - 2));
  135.    print_vreq_lines(vreq, vreq->vr_Display.d_FirstVisibleNode, (USHORT)0,
  136.                        vreq->vr_Display.d_VisibleLines);
  137.    draw_line(COLOR1, (USHORT)2, (USHORT)(cli_vpos - 2), (USHORT)
  138.                    (vsh_width - 3), (USHORT)(cli_vpos - 2));
  139.    print_fkey_text((USHORT)(FKEY_MODE_VIEW + vreq->vr_Mode));
  140.    print_vreq_status(vreq);
  141. }
  142.     /* Read view file into buffer, check view mode and build line list */
  143.  
  144.    SHORT
  145. read_view_file(struct FileRequest  *freq, struct FileNode  *fnode,
  146.                           struct ViewRequest  *vreq)
  147. {
  148.    USHORT len;
  149.    BPTR   lock;
  150.    ULONG  size;
  151.    BYTE   *buffer;
  152.    BPTR   fhandle;
  153.    SHORT  error;
  154.  
  155.    if (freq->fr_Mode == FREQ_MODE_FIND) {
  156.       strcpy(&path1_buffer[0], fnode->fn_Path);
  157.    } else {
  158.       strcpy(&path1_buffer[0], &freq->fr_DirName[0]);   /* build path name */
  159.    }
  160.    len = strlen(&path1_buffer[0]);
  161.    if (path1_buffer[len - 1] != ':') {
  162.       path1_buffer[len] = '/';
  163.       len++;
  164.    }
  165.    vreq->vr_FileName = &path1_buffer[len];
  166.    strncpy(&path1_buffer[len], &fnode->fn_Text[0], (size_t)fnode->fn_NameLen);
  167.    path1_buffer[len + fnode->fn_NameLen] = '\0';
  168.    if (!(lock = quiet_lock(&path1_buffer[0], (LONG)SHARED_LOCK))) {
  169.       error = VSH_ERROR_LOCK_FAILED;
  170.    } else {
  171.       if (Examine(lock, fib) == DOSFALSE) {
  172.      error = VSH_ERROR_EXAMINE_FAILED;
  173.       } else {
  174.      if (!(size = fib->fib_Size)) {
  175.         error = VSH_ERROR_EMPTY_FILE;
  176.      } else {
  177.         if (!(buffer = AllocMem(size, MEMF_PUBLIC))) {
  178.            error = VSH_ERROR_OUT_OF_MEM;
  179.         } else {
  180.            if (!(fhandle = (BPTR)Open(&path1_buffer[0], (LONG)
  181.                                MODE_OLDFILE))) {
  182.           error = VSH_ERROR_OPEN_FAILED;
  183.            } else {
  184.           if (Read(fhandle, buffer, size) == -1) {
  185.              error = VSH_ERROR_READ_FAILED;
  186.           } else {
  187.              vreq->vr_Buffer        = buffer;
  188.              vreq->vr_BufferSize    = size;
  189.              vreq->vr_MarkedEntries = 0;
  190.              print_status(VSH_STATUS_BUILD_LINE_LIST);
  191.              if (build_view_line_list(vreq, get_view_mode(vreq)) ==
  192.                                     FALSE) {
  193.             error = VSH_ERROR_OUT_OF_MEM;
  194.              } else {
  195.             vreq->vr_Display.d_FirstVisibleNode = vreq->vr_Display.d_List->mlh_Head;
  196.             Close(fhandle);
  197.             UnLock(lock);
  198.             return(VSH_STATUS_NORMAL);
  199.              }
  200.              free_list(vreq->vr_Display.d_List, (LONG)
  201.                            sizeof(struct LineNode));
  202.           }
  203.           Close(fhandle);
  204.            }
  205.            FreeMem(buffer, size);
  206.         }
  207.      }
  208.       }
  209.       UnLock(lock);
  210.    }
  211.    return(error);
  212. }
  213.     /* Jump to an line of viewed text or hex dump */
  214.  
  215.    VOID
  216. jump_to_view_line(struct ViewRequest  *vreq)
  217. {
  218.    struct MinNode  *lnode;
  219.    ULONG  line, num_entries = vreq->vr_Display.d_NumEntries;
  220.    USHORT vlines = vreq->vr_Display.d_VisibleLines;
  221.  
  222.    if (num_entries > vlines) {
  223.       if (!get_input(INPUT_MODE_VIEW_LINE, NULL)) {
  224.      print_vreq_status(vreq);
  225.       } else {
  226.      line = gadget_info.LongInt;
  227.      if (! line || line > num_entries) {
  228.         print_status(VSH_ERROR_INVALID_LINE_NUM);
  229.      } else {
  230.         if (line > (num_entries - vlines)) {
  231.            line = num_entries - vlines + 1;
  232.         }
  233.         lnode = get_list_node(vreq->vr_Display.d_List,
  234.                        vreq->vr_Display.d_NumEntries, line);
  235.         vreq->vr_Display.d_FirstVisibleNode = lnode;
  236.         print_vreq_lines(vreq, lnode, (USHORT)0, vlines);
  237.         print_vreq_status(vreq);
  238.      }
  239.       }
  240.       print_fkey_text((USHORT)(FKEY_MODE_VIEW + vreq->vr_Mode));
  241.    }
  242. }
  243.     /* Search first line with specified text in viewed text or hex dump */
  244.  
  245.    VOID
  246. search_view_line(struct ViewRequest  *vreq, USHORT mode)
  247. {
  248.    struct LineNode  *lnode = (struct LineNode *)
  249.                     vreq->vr_Display.d_FirstVisibleNode;
  250.    BYTE   hi, lo, *ptr, *string = &vreq->vr_LastSearchString[0];
  251.    ULONG  num_entries = vreq->vr_Display.d_NumEntries;
  252.    USHORT i, len, vlines = vreq->vr_Display.d_VisibleLines;
  253.    SHORT  error = VSH_STATUS_NORMAL;
  254.  
  255.    if (mode == VIEW_SEARCH_MODE_FIRST) {
  256.       if (!(ptr = get_input(INPUT_MODE_VIEW_SEARCH, string))) {
  257.      len = 0;
  258.       } else {
  259.      if (len = strlen(ptr)) {
  260.  
  261.         /* Save new search text */
  262.         strcpy(string, ptr);
  263.      }
  264.       }
  265.    } else {
  266.       print_fkey_text(FKEY_MODE_NONE);
  267.       if ((lnode->ln_Pos + vlines) < num_entries) {
  268.      lnode = (struct LineNode *)lnode->ln_Node.mln_Succ;
  269.       }
  270.       len = strlen(string);
  271.    }
  272.    if (len) {
  273.  
  274.       /* Hex search ? */
  275.       if (*string == '$') {
  276.      if (len == 1 || !(len & 1)) {
  277.         error = VSH_ERROR_INVALID_HEX_NUM;
  278.      } else {
  279.  
  280.         /* Convert hex to binary */
  281.         for (i = 1; i < len; i += 2) {
  282.            hi = toupper(*++string);
  283.            if (hi >= 'A' && hi <= 'F') {
  284.           hi -= 'A' - 10;
  285.            } else {
  286.           if (hi >= '0' && hi <= '9') {
  287.              hi -= '0';
  288.           } else {
  289.              error = VSH_ERROR_INVALID_HEX_NUM;
  290.              break;
  291.           }
  292.            }
  293.            lo = toupper(*++string);
  294.            if (lo >= 'A' && lo <= 'F') {
  295.           lo -= 'A' - 10;
  296.            } else {
  297.           if (lo >= '0' && lo <= '9') {
  298.              lo -= '0';
  299.           } else {
  300.              error = VSH_ERROR_INVALID_HEX_NUM;
  301.              break;
  302.           }
  303.            }
  304.            *ptr++ = (hi << 4) + lo;
  305.         }
  306.         len    = (i - 1) / 2;
  307.         string = &gadget_buffer[0];
  308.      }
  309.       }
  310.       if (error == VSH_STATUS_NORMAL) {
  311.  
  312.      /* Search and mark view lines */
  313.      if (!(lnode = search_line_node(lnode, string, len))) {
  314.         error = VSH_ERROR_SEARCH_FAILED;
  315.      } else {
  316.         mark_search_view_lines(vreq, lnode, string, len);
  317.      }
  318.       }
  319.    }
  320.    print_fkey_text((USHORT)(FKEY_MODE_VIEW + vreq->vr_Mode));
  321.    if (error == VSH_STATUS_NORMAL) {
  322.       print_vreq_status(vreq);
  323.    } else {
  324.       print_status(error);
  325.    }
  326. }
  327.     /* Mark search view lines */
  328.  
  329.    VOID
  330. mark_search_view_lines(struct ViewRequest  *vreq, struct LineNode  *lnode,
  331.                            BYTE *string, USHORT len)
  332. {
  333.    struct MinNode  *fv_lnode = (struct MinNode *)lnode;
  334.    ULONG  fv_pos, num_entries = vreq->vr_Display.d_NumEntries;
  335.    USHORT i, vlines = vreq->vr_Display.d_VisibleLines;
  336.  
  337.    if (num_entries > vlines) {
  338.       if (lnode->ln_Pos > (num_entries - vlines)) {
  339.      for (i = lnode->ln_Pos - (num_entries - vlines) - 1; i; i--) {
  340.         fv_lnode = fv_lnode->mln_Pred;
  341.      }
  342.       }
  343.       vreq->vr_Display.d_FirstVisibleNode = fv_lnode;
  344.       print_vreq_lines(vreq, fv_lnode, (USHORT)0, vlines);
  345.    } else {
  346.       fv_lnode = vreq->vr_Display.d_FirstVisibleNode;
  347.    }
  348.    fv_pos = ((struct LineNode *)fv_lnode)->ln_Pos;
  349.    do {
  350.       hcomp_vreq_line(vreq, (USHORT)(lnode->ln_Pos - fv_pos));
  351.       vreq->vr_MarkedEntries++;
  352.       lnode = search_line_node((struct LineNode *)lnode->ln_Node.mln_Succ,
  353.                                    string, len);
  354.    } while (lnode && (lnode->ln_Pos - fv_pos) < vlines);
  355. }
  356.     /* Change view mode */
  357.  
  358.    SHORT
  359. change_view_mode(struct ViewRequest  *vreq)
  360. {
  361.    struct LineNode  *fv_node;
  362.    ULONG  num_entries, old_offset  = ((struct LineNode *)
  363.                 vreq->vr_Display.d_FirstVisibleNode)->ln_Offset;
  364.    USHORT i, vlines = vreq->vr_Display.d_VisibleLines;
  365.    SHORT  error = VSH_STATUS_NORMAL;
  366.  
  367.    print_status(VSH_STATUS_CHANGE_VIEW_MODE);
  368.    print_fkey_text(FKEY_MODE_NONE);
  369.    SetAPen(con_rport, (LONG)COLOR0);
  370.    RectFill(con_rport, (LONG)(BORDER_LEFT - 2), (LONG)(BORDER_TOP_HIDDEN -
  371.         1), (LONG)(vsh_width - BORDER_RIGHT + 1), (LONG)(cli_vpos - 3));
  372.    vreq->vr_Mode = (vreq->vr_Mode == VIEW_MODE_ASCII ? VIEW_MODE_HEX :
  373.                                VIEW_MODE_ASCII);
  374.    free_list(vreq->vr_Display.d_List, (LONG)sizeof(struct LineNode));
  375.    if (build_view_line_list(vreq, vreq->vr_Mode) == FALSE) {
  376.       error  = VSH_ERROR_OUT_OF_MEM;
  377.       action = VSH_ACTION_QUIT;   /* quit view */
  378.    } else {
  379.       num_entries = vreq->vr_Display.d_NumEntries;
  380.       if (num_entries > vlines) {
  381.      fv_node = get_first_visible_line(vreq, old_offset);
  382.      if ((num_entries - fv_node->ln_Pos + 1) < vlines) {
  383.         for (i = vlines - (num_entries - fv_node->ln_Pos + 1); i; i--) {
  384.            fv_node = (struct LineNode *)fv_node->ln_Node.mln_Pred;
  385.         }
  386.      }
  387.       } else {
  388.      fv_node = (struct LineNode *)vreq->vr_Display.d_List->mlh_Head;
  389.       }
  390.       vreq->vr_Display.d_FirstVisibleNode = (struct MinNode *)fv_node;
  391.       print_vreq_lines(vreq, (struct MinNode *)fv_node, (USHORT)0,
  392.                        vreq->vr_Display.d_VisibleLines);
  393.       print_fkey_text((USHORT)(FKEY_MODE_VIEW + vreq->vr_Mode));
  394.       print_vreq_status(vreq);
  395.    }
  396.    return(error);
  397. }
  398.     /* Print viewed text as ASCII or hex dump */
  399.  
  400.    VOID
  401. print_view_text(struct ViewRequest  *vreq, USHORT mode)
  402. {
  403.    struct LineNode  *lnode;
  404.    ULONG i, end;
  405.    BPTR  fh;
  406.    SHORT error = VSH_STATUS_NORMAL;
  407.  
  408.    print_status(VSH_STATUS_PRINT_TEXT);
  409.    print_fkey_text(FKEY_MODE_NONE);
  410.    if (mode == PRINT_MODE_PAGE) {
  411.       lnode = (struct LineNode *)vreq->vr_Display.d_FirstVisibleNode;
  412.       end   = vreq->vr_Display.d_NumEntries - lnode->ln_Pos + 1;
  413.  
  414.       /* Check if fewer lines are available than possible to view on page */
  415.       if (end > vreq->vr_Display.d_VisibleLines) {
  416.      end = vreq->vr_Display.d_VisibleLines;
  417.       }
  418.    } else {
  419.       lnode = (struct LineNode *)vreq->vr_Display.d_List->mlh_Head;
  420.       end   = vreq->vr_Display.d_NumEntries;
  421.    }
  422.    if (!(fh = (BPTR)Open("PRT:", (LONG)MODE_NEWFILE))) {
  423.       error = VSH_ERROR_NO_PRINTER;
  424.    } else {
  425.       enable_abort = 1;
  426.       for (i = 0; i < end && error == VSH_STATUS_NORMAL; i++) {
  427.      if (CheckAbort(NULL)) {
  428.         error = VSH_ERROR_ABORTED;
  429.      } else {
  430.         if (FPrintf(fh, "%s\n", build_vreq_line(vreq, lnode,
  431.                           LINE_MODE_NO_FILL)) < 0) {
  432.            error = VSH_ERROR_PRINTING_FAILED;
  433.         } else {
  434.            lnode = (struct LineNode *)lnode->ln_Node.mln_Succ;
  435.         }
  436.      }
  437.       }
  438.       enable_abort = 0;
  439.       Close(fh);
  440.    }
  441.    print_fkey_text((USHORT)(FKEY_MODE_VIEW + vreq->vr_Mode));
  442.    if (error != VSH_STATUS_NORMAL) {
  443.       print_status(error);
  444.    } else {
  445.       print_vreq_status(vreq);
  446.    }
  447. }
  448.     /* Print quick view */
  449.  
  450.    VOID
  451. print_quick_view(struct FileRequest  *freq1)
  452. {
  453.    struct FileRequest  *freq2 = (&file_req[0] == freq1 ? &file_req[1] :
  454.                                   &file_req[0]);
  455.    struct FileNode     *fnode;
  456.    BPTR   fhandle;
  457.    BYTE   *buffer, *file = &path1_buffer[0];
  458.    USHORT len = 0;
  459.    LONG   buffer_size = freq2->fr_Display.d_VisibleLines *
  460.                            MAX_QVIEW_BYTES_PER_LINE;
  461.    SHORT  error = VSH_STATUS_NORMAL;
  462.  
  463.    if (!(buffer = AllocMem(buffer_size, MEMF_PUBLIC))) {
  464.       error = VSH_ERROR_OUT_OF_MEM;
  465.    } else {
  466.  
  467.       /* Valid file requester mode? */
  468.       if (freq2->fr_Mode != FREQ_MODE_DEVS_ASN) {
  469.  
  470.      /* Empty file requester? */
  471.      if (fnode = get_file_node_under_cursor(freq2)) {
  472.  
  473.         /* File selected */
  474.         if (fnode->fn_Type == ENTRY_TYPE_FILE) {
  475.  
  476.            /* Read start of file into allocated buffer */
  477.            build_path_name_from_file_node(file, freq2, fnode);
  478.            if (!(fhandle = (BPTR)Open(file, (LONG)MODE_OLDFILE))) {
  479.           error = VSH_ERROR_OPEN_FAILED;
  480.            } else {
  481.           if (Read(fhandle, buffer, buffer_size) != buffer_size) {
  482.              error = VSH_ERROR_READ_FAILED;
  483.           } else {
  484.              len = buffer_size;
  485.           }
  486.           Close(fhandle);
  487.            }
  488.         }
  489.          }
  490.       }
  491.       print_quick_view_lines(freq1, buffer, len);
  492.       FreeMem(buffer, buffer_size);
  493.    }
  494.    if (event_mode != EVENT_MODE_INPUT) {
  495.       print_status(error);
  496.    }
  497. }
  498.