home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / apps / spread / opusprg / opussrc / m.pas < prev    next >
Pascal/Delphi Source File  |  1988-05-12  |  44KB  |  1,003 lines

  1.  
  2.  
  3. {$M+}
  4. {$E+}
  5.  
  6. PROGRAM Mock;
  7.  
  8. {$I i:\opus.i}
  9. {$I i:\gctv.inc}
  10.  
  11. {$I i:\globsubs.def}
  12. {$I i:\gemsubs.def}
  13. {$I i:\vdi_aes.def}
  14. {$I d:\pascal\opus\resource.def}
  15. {$I d:\pascal\opus\bf.def}
  16. {$I d:\pascal\opus\graphout.def}
  17.  
  18. PROCEDURE EVALUATE_FORMULA ( row,col  : INTEGER;
  19.                              force,
  20.                              new_form : BOOLEAN;
  21.                              cell     : CellPtr );
  22.    EXTERNAL;
  23.  
  24. PROCEDURE HANDLE_MESSAGE;
  25.     LABEL 9;
  26.     VAR
  27.         i,j,dummy                       : INTEGER;
  28.         redraw,sci                      : BOOLEAN;
  29.         num_ptr                         : PtrToReal;
  30.         str_ptr                         : PtrToString;
  31.         ptr                             : CellPtr;
  32.  
  33. (* in all these following routines, slider positions are changed by a
  34.    subsequent call to RESET_WINDOW *)
  35.  
  36. { extent is the variable that determines which part of the screen is to be
  37.   redrawn; it is initialized to WholeSheet and stays WholeSheet unless
  38.   something changes it. Of course, depending on the action, the sheet may
  39.   not be redrawn at all... }
  40.   
  41.     PROCEDURE PAGE_UP;
  42.        BEGIN
  43.            start_row := start_row-v_entry;
  44.            IF start_row < logical_row_1 THEN
  45.               start_row := logical_row_1;
  46.            data_row := start_row+scr_row-1
  47.        END; { PAGE_UP }
  48.  
  49.     PROCEDURE PAGE_DOWN;
  50.         BEGIN
  51.             start_row := start_row+v_entry;
  52.             IF start_row+v_entry-1 > n_rows THEN
  53.                start_row := n_rows-v_entry+1;
  54.             data_row := start_row+scr_row-1
  55.         END; { PAGE_DOWN }
  56.  
  57.     PROCEDURE ROW_UP;
  58.         BEGIN
  59.             { toggle because we are going to blit, and we need to toggle based
  60.               on the current cells position, which is about to change, and
  61.               since we aren't doing a complete screen redraw }
  62.             Hide_Mouse;
  63.             toggle_inverse(Black,data_row,data_col);
  64.             Show_Mouse;
  65.             start_row := start_row-1;
  66.             data_row := data_row-1
  67.         END; { ROW_UP }
  68.  
  69.     PROCEDURE ROW_DOWN;
  70.         BEGIN
  71.             { toggle because we are going to blit, and we need to toggle based
  72.               on the current cells position, which is about to change, and
  73.               since we aren't doing a complete screen redraw }
  74.             Hide_Mouse;
  75.             toggle_inverse(Black,data_row,data_col);
  76.             Show_Mouse;
  77.             start_row := start_row+1;
  78.             data_row := data_row+1
  79.         END; { ROW_DOWN }
  80.  
  81.     PROCEDURE MOVE_V_SLIDER;
  82.         VAR old_slider_pos : INTEGER;
  83.         BEGIN
  84.             v_slider_pos := msg_area[4];
  85.             Wind_Get(act_hdl,WF_VSlide,old_slider_pos,dummy,dummy,dummy);
  86.             IF (v_slider_pos >= ROUND(old_slider_pos+v_slide_inc)) OR
  87.                (v_slider_pos <= ROUND(old_slider_pos-v_slide_inc))
  88.             THEN BEGIN
  89.                start_row := ROUND(v_slider_pos/v_slide_inc)+1;
  90.                IF start_row+v_entry-1 > n_rows THEN
  91.                   start_row := n_rows-v_entry+1;
  92.                IF start_row < logical_row_1 THEN
  93.                   start_row := logical_row_1;
  94.                data_row := start_row+scr_row-1
  95.             END
  96.             ELSE
  97.                GOTO 9
  98.         END;     (* MOVE_V_SLIDER *)
  99.  
  100.     PROCEDURE COL_RIGHT;
  101.        BEGIN
  102.            { toggle because we are going to blit, and we need to toggle based
  103.              on the current cells position, which is about to change, and
  104.              since we aren't doing a complete screen redraw }
  105.            Hide_Mouse;
  106.            toggle_inverse(Black,data_row,data_col);
  107.            Show_Mouse;
  108.            finish_col := finish_col+1;
  109.            data_col := data_col+1;
  110.            get_num_scr_entries(ExLeft) 
  111.        END; { COL_RIGHT }
  112.                           
  113.     PROCEDURE COL_LEFT;
  114.        BEGIN
  115.            Hide_Mouse;
  116.            toggle_inverse(Black,data_row,data_col);
  117.            Show_Mouse;
  118.            start_col := start_col-1;
  119.            data_col := data_col-1 { don't need to get_num_scr_entries }
  120.        END; { COL_LEFT }
  121.  
  122.     PROCEDURE PAGE_RIGHT;
  123.        VAR rel_pos : REAL;
  124.        BEGIN
  125.            rel_pos := scr_col/h_entry;
  126.            start_col := start_col+h_entry;
  127.            get_num_scr_entries(ExRight);
  128.            data_col := start_col+ROUND(rel_pos*h_entry)-1
  129.        END; { PAGE_RIGHT }
  130.  
  131.     PROCEDURE PAGE_LEFT;
  132.        VAR rel_pos : REAL;
  133.        BEGIN
  134.            rel_pos := scr_col/h_entry;
  135.            finish_col := start_col-1;
  136.            get_num_scr_entries(ExLeft);
  137.            data_col := start_col+ROUND(rel_pos*h_entry)-1
  138.        END; { PAGE_LEFT }
  139.  
  140.     PROCEDURE MOVE_H_SLIDER;
  141.         VAR old_slider_pos : INTEGER;
  142.             rel_pos        : REAL;
  143.         BEGIN
  144.             rel_pos := scr_col/h_entry;
  145.             h_slider_pos := msg_area[4];
  146.             Wind_Get(act_hdl,WF_HSlide,old_slider_pos,dummy,dummy,dummy);
  147.             IF (h_slider_pos >= ROUND(old_slider_pos+h_slide_inc)) OR
  148.                (h_slider_pos <= ROUND(old_slider_pos-h_slide_inc))
  149.             THEN BEGIN
  150.                start_col := ROUND(h_slider_pos/h_slide_inc)+1;
  151.                get_num_scr_entries(ExRight);
  152.                data_col := start_col+ROUND(rel_pos*h_entry)-1
  153.             END
  154.             ELSE
  155.                GOTO 9
  156.         END;     (* MOVE_H_SLIDER *)
  157.  
  158.     PROCEDURE MOVED_WINDOW;
  159.        VAR new_x,new_y,new_w,new_h : INTEGER;
  160.        BEGIN
  161.            new_x := msg_area[4]; { AES blits here- no need to redraw }
  162.            new_y := msg_area[5];
  163.            new_w := msg_area[6];
  164.            new_h := msg_area[7];
  165.            new_x := 8*((new_x+4) DIV 8); { this aligns by bytes }
  166.            { note the following code assumes that the width of the window is
  167.              legal; since the max width is the entire screen, we needn't
  168.              check that in resize_sheet, since windows can't be resized
  169.              off-screen. }
  170.            IF new_x+new_w > o_x+max_w THEN { off screen to the right }
  171.               new_x := o_x+max_w-new_w;
  172.            IF new_y < o_y THEN
  173.               new_y := o_y;
  174.            IF new_y+new_h > o_y+max_h THEN { off screen below }
  175.               new_y := o_y+max_h-new_h;
  176.            Set_WSize(act_hdl,new_x,new_y,new_w,new_h);
  177.            def_sheet_area { must reset vert_grid }
  178.        END; (* MOVED_WINDOW *)
  179.  
  180.     PROCEDURE RESIZED_WINDOW;
  181.        VAR new_x,new_y,new_w,new_h,x,y,w,h : INTEGER;
  182.        BEGIN
  183.            Border_Rect(act_hdl,x,y,w,h);
  184.            new_x := msg_area[4];
  185.            new_y := msg_area[5];
  186.            new_w := msg_area[6];
  187.            new_h := msg_area[7];
  188.            { make sure that at least 20 characters can be displayed on one
  189.              line in the edit line so we can limit the size of the blit buffer;
  190.              max length string to be displayed there is 60. Height really
  191.              doesn't matter given this constraint and since GEM itself limits
  192.              it. Also limit the size so that the widest column can fit in the
  193.              smallest window; i.e. 30 columns. Do this so won't have to check
  194.              whether or not a column is too big to fit, by itself, in a
  195.              window. }
  196.            IF new_w < half_scr_width-5 THEN
  197.               new_w := half_scr_width-5;
  198.            Set_WSize(act_hdl,new_x,new_y,new_w,new_h);
  199.            def_sheet_area;
  200.            write_cell_name;
  201.            Send_Redraw(FALSE,new_x,new_y,new_w,new_h)
  202.        END; (* RESIZED_WINDOW *)
  203.  
  204.     PROCEDURE FULLED_WINDOW;
  205.        VAR x,y,w,h,p_x,p_y,p_w,p_h : INTEGER;
  206.        BEGIN
  207.            Border_Rect(act_hdl,x,y,w,h);
  208.            IF (w = max_w) AND (h = max_h) THEN BEGIN
  209.               Wind_Get(act_hdl,WF_PrevXYWH,p_x,p_y,p_w,p_h);
  210.               IF (p_w <> max_w) OR (p_h <> max_h) THEN BEGIN
  211.                  Set_WSize(act_hdl,p_x,p_y,p_w,p_h);
  212.                  Send_Redraw(FALSE,p_x,p_y,p_w,p_h)
  213.               END
  214.            END
  215.            ELSE 
  216.               Set_WSize(act_hdl,o_x,o_y,max_w,max_h);
  217.            def_sheet_area;
  218.            write_cell_name
  219.        END; (* FULLED_WINDOW *)
  220.  
  221.     PROCEDURE TOPPED_WINDOW;
  222.        BEGIN
  223.            IF (n_hdls = 2) AND (msg_area[3] <> act_hdl) THEN
  224.               switch_window;
  225.            Bring_To_Front(act_hdl);
  226.            write_cell_name;
  227.            cell_on_screen(1,data_row,data_col,TRUE)
  228.        END; { TOPPED_WINDOW }
  229.  
  230.     FUNCTION REALLY_QUIT : BOOLEAN;
  231.        BEGIN
  232.            temp:='[3][Have you saved your work?][ Cancel |Quit]';
  233.            IF Do_Alert(temp,2) = 2 THEN
  234.               really_quit := TRUE
  235.            ELSE
  236.               really_quit := FALSE
  237.        END; { REALLY_QUIT }
  238.     
  239.     PROCEDURE MANUAL_RECALC;
  240.        VAR i   : INTEGER;
  241.            ptr : CellPtr;
  242.        BEGIN
  243.            did_recalc := TRUE;
  244.            { recalc nominally in row-major order }
  245.            FOR i := 1 TO n_rows DO BEGIN
  246.                ptr := data[i];
  247.                WHILE ptr <> NIL DO BEGIN
  248.                   IF (ptr^.class = Expr) AND
  249.                      (ptr^.format & recalc_mask = 0) AND 
  250.                      (ptr^.format & pending_mask = 0) THEN
  251.                      evaluate_formula(i,ptr^.c,TRUE,FALSE,ptr);
  252.                   ptr := ptr^.next
  253.                END
  254.            END;
  255.            cell_on_screen(1,data_row,data_col,TRUE)
  256.        END; { MANUAL_RECALC }  
  257.      
  258.     PROCEDURE DO_MENU;
  259.        VAR d,menu_title,i,j,
  260.            s_r,s_c,e_r,e_c,default : INTEGER;
  261.            dummy,found,over,quit   : BOOLEAN;
  262.            a                       : AssignedStatus;
  263.            ptr                     : CellPtr;
  264.        PROCEDURE CHANGE_CLASS ( new_class : ClassType );
  265.           VAR ptr : CellPtr;
  266.           BEGIN
  267.               delete_range(data_row,data_col,data_row,data_col,TRUE);
  268.               ptr := new_cell(data_row,data_col);
  269.               IF ptr <> NIL THEN BEGIN
  270.                  ptr^.class := new_class;
  271.                  ptr^.format := default_format;
  272.                  IF new_class = Labl THEN
  273.                     ptr^.format := (ptr^.format & no_just_mask) | $0010
  274.               END
  275.           END; { CHANGE_CLASS }
  276.        PROCEDURE GOTO_MARK ( which : INTEGER );
  277.           BEGIN
  278.               WITH marks[which] DO
  279.                  IF (row >= logical_row_1) AND 
  280.                     (col >= logical_col_1) THEN BEGIN
  281.                     data_row := row;
  282.                     data_col := col;
  283.                     start_row := row;
  284.                     start_col := col;
  285.                     Send_Redraw(FALSE,0,0,screen_width,screen_height)
  286.                  END
  287.           END; { GOTO_MARK }       
  288.        PROCEDURE SHEET_INSERT_AND_DELETE ( action,which : INTEGER );
  289.           VAR i,j,k,m : INTEGER;
  290.               a1,a2   : STRING;
  291.           BEGIN
  292.               IF action = 1 THEN
  293.                  temp := 'INSERT '
  294.               ELSE
  295.                  temp := 'DELETE ';
  296.               IF which = 1 THEN
  297.                  temp := CONCAT(temp,'row')
  298.               ELSE
  299.                  temp := CONCAT(temp,'column');
  300.               a2 := CONCAT('[2][' , temp ,
  301.                            ' mode:       ][Cancel|Partial|Whole]');
  302.               a1 := CONCAT('[1][You can not ' , temp ,
  303.                               '|because you are at a|' ,
  304.                                'worksheet border.][  OK  ]');
  305.               IF block_set THEN                 
  306.                  default := 2
  307.               ELSE
  308.                  default := 3;
  309.               alert := Do_Alert(a2,default);      
  310.               IF alert <> 1 THEN
  311.                  IF which = 1 THEN { row }
  312.                     IF data_row = n_rows THEN
  313.                        alert := Do_Alert(a1,1)
  314.                     ELSE IF alert = 2 THEN { partial }
  315.                        IF block_set THEN
  316.                           IF b_e_row = n_rows THEN
  317.                              alert := Do_Alert(a1,1)
  318.                           ELSE IF action = 1 THEN { insert }
  319.                              shift_block(mmove,b_s_row+1,b_s_col,
  320.                                          b_s_row,b_s_col,n_rows-1,b_e_col)
  321.                           ELSE { delete }
  322.                              shift_block(mmove,b_s_row,b_s_col,
  323.                                          b_s_row+1,b_s_col,n_rows,b_e_col)
  324.                        ELSE IF action = 1 THEN { insert }
  325.                           shift_block(mmove,data_row+1,data_col,
  326.                                       data_row,data_col,n_rows-1,n_cols)
  327.                        ELSE { delete }
  328.                           shift_block(mmove,data_row,data_col,
  329.                                       data_row+1,data_col,n_rows,n_cols)
  330.                     ELSE IF action = 1 THEN { insert } { whole row }
  331.                        shift_block(mmove,data_row+1,1,
  332.                                    data_row,1,n_rows-1,n_cols)
  333.                     ELSE { delete }
  334.                        shift_block(mmove,data_row,1,
  335.                                    data_row+1,1,n_rows,n_cols)
  336.                  ELSE { column }
  337.                     IF data_col = n_cols THEN
  338.                        alert := Do_Alert(a1,1)
  339.                     ELSE BEGIN
  340.                        IF alert = 2 THEN { partial }
  341.                           IF block_set THEN
  342.                              IF b_e_col = n_cols THEN
  343.                                 alert := Do_Alert(a1,1)
  344.                              ELSE IF action = 1 THEN { insert }
  345.                                 shift_block(mmove,b_s_row,b_s_col+1,
  346.                                             b_s_row,b_s_col,b_e_row,n_cols-1 )
  347.                              ELSE { delete }
  348.                                 shift_block(mmove,b_s_row,b_s_col,
  349.                                             b_s_row,b_s_col+1,b_e_row,n_cols)
  350.                           ELSE IF action = 1 THEN { insert }
  351.                              shift_block(mmove,data_row,data_col+1,
  352.                                          data_row,data_col,n_rows,n_cols-1)
  353.                           ELSE { delete }
  354.                              shift_block(mmove,data_row,data_col,
  355.                                          data_row,data_col+1,n_rows,n_cols)
  356.                        ELSE IF action = 1 THEN { insert whole col }
  357.                           shift_block(mmove,1,data_col+1,
  358.                                       1,data_col,n_rows,n_cols-1)
  359.                        ELSE
  360.                           shift_block(mmove,1,data_col,
  361.                                       1,data_col+1,n_rows,n_cols);
  362.                        IF action = 1 THEN { insert }
  363.                           FOR i := n_cols-1 DOWNTO data_col DO BEGIN
  364.                               IF col_width[i+1,spaces] <> col_width[i,spaces]
  365.                               THEN BEGIN
  366.                                  col_width[i+1,spaces] := col_width[i,spaces];
  367.                                  col_width[i+1,pixels] := col_width[i,pixels];
  368.                                  redraw := TRUE
  369.                               END
  370.                           END
  371.                        ELSE { delete }
  372.                           FOR i := data_col TO n_cols-1 DO BEGIN
  373.                               IF col_width[i+1,spaces] <> col_width[i,spaces]
  374.                               THEN BEGIN
  375.                                  col_width[i,spaces] := col_width[i+1,spaces];
  376.                                  col_width[i,pixels] := col_width[i+1,pixels];
  377.                                  redraw := TRUE
  378.                               END
  379.                           END;
  380.                        IF redraw THEN
  381.                           Send_Redraw(TRUE,0,0,screen_width,screen_height)
  382.                     END { ELSE }
  383.           END; { SHEET_INSERT_AND_DELETE }
  384.        BEGIN { DO_MENU }
  385.            menu_title := msg_area[3];
  386.            CASE menu_title OF
  387.               Desk  : BEGIN
  388.                  Obj_SetState(info_ptr,aboutok,Normal,FALSE);
  389.                  indx := form_begin(info_ptr,Root);
  390.                  form_end
  391.               END;   
  392.               mfile :
  393.                  CASE msg_area[4] OF
  394.                     mloadws : disk_io(LoadFile);
  395.                     msavews : disk_io(SaveFile);
  396.                     mloadbl : disk_io(LoadBlock);
  397.                     msavebl : disk_io(SaveBlock);
  398.                     msavetxt : disk_io(SaveText);
  399.                     mprintsp : print_spreadsheet(TRUE,'Print WorkSheet',
  400.                                                  s_r,s_c,e_r,e_c);
  401.                     mopenw : BEGIN
  402.                        d := New_Window(G_All,t_2,0,0,0,0);
  403.                        IF d > No_Window THEN BEGIN { window available }
  404.                           Set_WSize(act_hdl,o_x,o_y,half_scr_width-5,max_h);
  405.                           sheet_redraw(WholeSheet,FALSE,None);
  406.                           act_hdl := d;
  407.                           Open_Window(act_hdl,half_scr_width+4,o_y,
  408.                                       half_scr_width-5,max_h);
  409.                           n_hdls := 2;
  410.                           w_idx := 2;
  411.                           w_pos[2] := w_pos[1];
  412.                           w_pos[2,w_hdl] := act_hdl;
  413.                           return_attr; { redraw_msg only does this if act_hdl }
  414.                                        { <> handle sent to it; here, it is = }
  415.                           Menu_Disable(main_menu,mopenw)
  416.                        END
  417.                        ELSE BEGIN
  418.                           temp := CONCAT('[1][GEM is out of windows. You|' ,
  419.                                              'must close one before you|' ,
  420.                                              'may open another.][  OK  ]' );
  421.                           alert := Do_Alert(temp,1)
  422.                        END
  423.                     END;
  424.                     mclosew :
  425.                        IF n_hdls = 2 THEN BEGIN
  426.                           { generates a redraw message }
  427.                           Close_Window(act_hdl);
  428.                           Delete_Window(act_hdl);
  429.                           t_1 := ' WorkSheet1 '; { restore these because    }
  430.                           t_2 := ' WorkSheet2 '; { PASGEM had -> 'C'-string }
  431.                           IF w_idx = 1 THEN { closed window 1? }
  432.                              w_pos[1] := w_pos[2] { including handle }
  433.                           ELSE
  434.                              w_idx := 1;
  435.                           return_attr; { retrieve attributes, including hdl }
  436.                           Set_WName(act_hdl,t_1);
  437.                           n_hdls := 1;
  438.                           Menu_Enable(main_menu,mopenw)
  439.                        END
  440.                        ELSE IF really_quit THEN
  441.                           user_quit := TRUE;
  442.                     mainquit : IF really_quit THEN
  443.                                   user_quit := TRUE { quit maximize }
  444.               END; { mfile }
  445.               mformat :
  446.                  CASE msg_area[4] OF
  447.                     mnum : change_class(Val);
  448.                     mlabel : change_class(Labl);
  449.                     mform : change_class(Expr);
  450.                     mcolwid : change_format(CWCall);
  451.                     mjust : change_format(JustCall);
  452.                     mdollar : change_format(DollarCall);
  453.                     mpercent : change_format(PercCall);
  454.                     mprec : change_format(PrecCall);
  455.                     mstyle : change_format(StyleCall);
  456.                     mglobalf : change_format(GlobalCall);
  457.                     mviewfor : view_format
  458.               END;
  459.               mblock :
  460.                  CASE msg_area[4] OF
  461.                     mstartbl : dummy := start_block;
  462.                     mendbl : dummy := end_block;
  463.                     mcopy : dummy := transport_block(mcopy);
  464.                     mmove : dummy := transport_block(mmove);
  465.                     mdesel : dummy := deselect_block;
  466.                     mdelete : delete_block;
  467.                     minsertr : sheet_insert_and_delete(1,1); { insert,row }
  468.                     minsertc : sheet_insert_and_delete(1,2); { insert,col }
  469.                     mdeleter : sheet_insert_and_delete(2,1); { delete,row }
  470.                     mdeletec : sheet_insert_and_delete(2,2); { delete,col }
  471.                     mdatafil : data_fill;
  472.                     mrep : replicate_cell;
  473.                     msort : sort
  474.               END; { mblock }
  475.               mmark :
  476.                  CASE msg_area[4] OF
  477.                     ms1 : 
  478.                        WITH marks[1] DO BEGIN
  479.                           row := data_row;
  480.                           col := data_col;
  481.                           m1s := TRUE;
  482.                           Menu_Enable(main_menu,mg1)
  483.                        END;   
  484.                     ms2 : 
  485.                        WITH marks[2] DO BEGIN
  486.                           row := data_row;
  487.                           col := data_col;
  488.                           m2s := TRUE;
  489.                           Menu_Enable(main_menu,mg2)
  490.                        END;   
  491.                     ms3 : 
  492.                        WITH marks[3] DO BEGIN
  493.                           row := data_row;
  494.                           col := data_col;
  495.                           m3s := TRUE;
  496.                           Menu_Enable(main_menu,mg3)
  497.                        END;   
  498.                     ms4 : 
  499.                        WITH marks[4] DO BEGIN
  500.                           row := data_row;
  501.                           col := data_col;
  502.                           m4s := TRUE;
  503.                           Menu_Enable(main_menu,mg4)
  504.                        END;   
  505.                     mg1 : goto_mark(1);
  506.                     mg2 : goto_mark(2);
  507.                     mg3 : goto_mark(3);
  508.                     mg4 : goto_mark(4);
  509.                     mcmarks : BEGIN
  510.                        Menu_Disable(main_menu,mg1);    
  511.                        Menu_Disable(main_menu,mg2);    
  512.                        Menu_Disable(main_menu,mg3);    
  513.                        Menu_Disable(main_menu,mg4);
  514.                        m1s := FALSE;
  515.                        m2s := FALSE;
  516.                        m3s := FALSE;
  517.                        m4s := FALSE;
  518.                        FOR i := 1 TO 4 DO BEGIN
  519.                            marks[i].row := 0;
  520.                            marks[i].col := 0
  521.                        END
  522.                     END;
  523.                     mfirstc : BEGIN
  524.                        IF block_set THEN BEGIN
  525.                           start_row := b_s_row;
  526.                           start_col := b_s_col;
  527.                           data_row := start_row;
  528.                           data_col := start_col
  529.                        END
  530.                        ELSE IF find_first_and_last(TRUE) THEN
  531.                           goto_mark(5)
  532.                        ELSE
  533.                           home_cursor(Origin);
  534.                        Send_Redraw(FALSE,0,0,screen_width,screen_height)
  535.                     END;   
  536.                     mlastc : BEGIN
  537.                        IF block_set THEN BEGIN
  538.                           data_row := b_e_row;
  539.                           data_col := b_e_col;
  540.                           start_row := b_e_row-v_entry+1;
  541.                           finish_col := b_e_col;
  542.                           get_num_scr_entries(ExLeft)
  543.                        END   
  544.                        ELSE IF find_first_and_last(TRUE) THEN BEGIN
  545.                           WITH marks[6] DO BEGIN
  546.                              data_row := row;
  547.                              data_col := col;
  548.                              start_row := row-v_entry+1;
  549.                              finish_col := col
  550.                           END;
  551.                           get_num_scr_entries(ExLeft)
  552.                        END
  553.                        ELSE
  554.                           home_cursor(Origin);
  555.                        Send_Redraw(FALSE,0,0,screen_width,screen_height)
  556.                     END;   
  557.                     mgoto : BEGIN
  558.                        redraw := goto_cell;
  559.                        IF redraw THEN
  560.                           Send_Redraw(FALSE,0,0,screen_width,screen_height)
  561.                     END
  562.               END; { mmark }
  563.               moptions :
  564.                  CASE msg_area[4] OF
  565.                     msetauto : BEGIN
  566.                        IF cursor_direction = CursorDown THEN
  567.                           default := 2
  568.                        ELSE
  569.                           default := 1;
  570.                        temp := CONCAT('[2][Auto-cursor direction:]' ,
  571.                                       '[ Right | Down ]');
  572.                        IF Do_Alert(temp,default) = 2 THEN
  573.                           cursor_direction := CursorDown
  574.                        ELSE
  575.                           cursor_direction := CursorRight
  576.                     END;
  577.                     mautocur : BEGIN
  578.                        IF auto_cursor THEN
  579.                           Menu_Check(main_menu,mautocur,FALSE)
  580.                        ELSE   
  581.                           Menu_Check(main_menu,mautocur,TRUE);
  582.                        auto_cursor := NOT auto_cursor   
  583.                     END;
  584.                     msmall : BEGIN { only available if high rez }
  585.                        IF small_text THEN BEGIN
  586.                           cell_height := 17;
  587.                           two_cell_h := 34;
  588.                           three_cell_h := 51;
  589.                           IF freeze_row > 0 THEN
  590.                              y_margin := two_cell_h-1
  591.                           ELSE
  592.                              y_margin := cell_height-1;
  593.                           Set_Char_Height(13); { 8x16 font }
  594.                           Menu_Check(main_menu,msmall,FALSE)
  595.                        END
  596.                        ELSE BEGIN
  597.                           cell_height := 9;
  598.                           two_cell_h := 18;
  599.                           three_cell_h := 27;
  600.                           IF freeze_row > 0 THEN
  601.                              y_margin := two_cell_h-1
  602.                           ELSE
  603.                              y_margin := cell_height-1;
  604.                           Set_Char_Height(6); { 8x8 font }
  605.                           Menu_Check(main_menu,msmall,TRUE)
  606.                        END;
  607.                        small_text := NOT small_text;
  608.                        redraw := TRUE;
  609.                        Send_Redraw(TRUE,0,0,screen_width,screen_height)
  610.                     END;
  611.                     mshowfor : BEGIN
  612.                        IF form_flag THEN
  613.                           Menu_Check(main_menu,mshowfor,FALSE)
  614.                        ELSE   
  615.                           Menu_Check(main_menu,mshowfor,TRUE);
  616.                        form_flag := NOT form_flag;
  617.                        Set_Mouse(M_Bee);
  618.                        FOR i := 1 TO n_rows DO BEGIN
  619.                            ptr := data[i];
  620.                            WHILE ptr <> NIL DO BEGIN
  621.                               IF ptr^.class = Expr THEN
  622.                                  cell_on_screen(1,i,ptr^.c,TRUE);
  623.                               ptr := ptr^.next
  624.                            END
  625.                        END;
  626.                        Set_Mouse(M_Arrow)
  627.                     END;
  628.                     mclearws : BEGIN
  629.                        temp := CONCAT('[3][Do you REALLY wish to CLEAR|' ,
  630.                                           'the worksheet? "Number"|' ,
  631.                                           'means that only numeric|' ,
  632.                                           'cells will be cleared.]' ,
  633.                                           '[Cancel|Number|OK]');
  634.                        alert := Do_Alert(temp,3);                   
  635.                        IF alert = 3 THEN BEGIN
  636.                           Set_Mouse(M_Bee);
  637.                           clear_worksheet;
  638.                           Set_Mouse(M_Arrow);
  639.                           redraw := TRUE
  640.                        END
  641.                        ELSE IF alert = 2 THEN BEGIN
  642.                           Set_Mouse(M_Bee);
  643.                           FOR i := 1 TO n_rows DO BEGIN
  644.                               ptr := data[i];
  645.                               WHILE ptr <> NIL DO BEGIN
  646.                                  IF ptr^.class = Val THEN
  647.                                     ptr^.status := Empty;
  648.                                  ptr := ptr^.next
  649.                               END
  650.                           END;
  651.                           Set_Mouse(M_Arrow);
  652.                           redraw := TRUE;
  653.                           Send_Redraw(TRUE,0,0,screen_width,screen_height)
  654.                        END
  655.                     END;
  656.                     mstats : stats;
  657.                     mfreeze : redraw := do_freeze;
  658.                     mmanrec : BEGIN
  659.                        Set_Mouse(M_Bee);
  660.                        manual_recalc;  
  661.                        Set_Mouse(M_Arrow)
  662.                     END;
  663.                     mautorec : BEGIN
  664.                        IF auto_recalc THEN
  665.                           Menu_Check(main_menu,mautorec,FALSE)
  666.                        ELSE
  667.                           Menu_Check(main_menu,mautorec,TRUE);
  668.                        auto_recalc := NOT auto_recalc   
  669.                     END;
  670.                     mnatural : BEGIN
  671.                        IF natural THEN
  672.                           Menu_Check(main_menu,mnatural,FALSE)
  673.                        ELSE   
  674.                           Menu_Check(main_menu,mnatural,TRUE);
  675.                        natural := NOT natural
  676.                     END;
  677.                     mrefresh : BEGIN
  678.                        temp := CONCAT('[2][Choose one of the following:]',
  679.                                          '[Cancel|Window|Data]');
  680.                        alert := Do_Alert(temp,3);
  681.                        IF alert = 3 THEN BEGIN
  682.                           Set_Mouse(M_Bee);
  683.                           FOR i := start_row TO finish_row DO BEGIN   
  684.                               found := FALSE;
  685.                               quit := FALSE;
  686.                               ptr := data[i];
  687.                               WHILE (ptr <> NIL) AND (NOT found) AND (NOT quit) DO 
  688.                                  IF (ptr^.c >= start_col) AND 
  689.                                     (ptr^.c <= finish_col) THEN
  690.                                     found := TRUE
  691.                                  ELSE IF ptr^.c > finish_col THEN
  692.                                     quit := TRUE
  693.                                  ELSE
  694.                                     ptr := ptr^.next;
  695.                               over := FALSE;
  696.                               IF found THEN 
  697.                                  WHILE (ptr <> NIL) AND (NOT over) DO BEGIN
  698.                                     cell_on_screen(1,i,ptr^.c,TRUE);
  699.                                     ptr := ptr^.next;
  700.                                     IF ptr <> NIL THEN
  701.                                        IF ptr^.c > finish_col THEN
  702.                                           over := TRUE
  703.                                  END
  704.                           END;
  705.                           cell_on_screen(1,data_row,data_col,TRUE);
  706.                           Set_Mouse(M_Arrow)
  707.                        END   
  708.                        ELSE IF alert = 2 THEN
  709.                           Send_Redraw(FALSE,0,0,screen_width,screen_height)
  710.                     END;      
  711.                     mshowgri : BEGIN
  712.                        IF grid_flag THEN
  713.                           Menu_Check(main_menu,mshowgri,FALSE)
  714.                        ELSE   
  715.                           Menu_Check(main_menu,mshowgri,TRUE);
  716.                        grid_flag := NOT grid_flag;
  717.                        Send_Redraw(TRUE,0,0,screen_width,screen_height)
  718.                     END
  719.               END; { moptions }
  720.               { MHELP is handled within window_input so that help may
  721.                 be obtained without losing any typed information in edit
  722.                  area }
  723.               OTHERWISE : ;
  724.            END; { CASE menu_title }
  725.            Menu_Normal(main_menu,menu_title)
  726.        END; { DO_MENU }
  727.        
  728.     FUNCTION Addr ( VAR data : DataTable ) : LONG_INTEGER;
  729.        EXTERNAL;
  730.     FUNCTION MFDB_ADDR ( which : INTEGER ) : LONG_INTEGER;
  731.        FUNCTION Addr ( VAR a : Mfdb ) : LONG_INTEGER;
  732.           EXTERNAL;
  733.        BEGIN
  734.           IF which > 0 THEN
  735.              mfdb_addr := Addr(mem_mfdb)
  736.           ELSE
  737.              mfdb_addr := Addr(screen_mfdb)   
  738.        END;
  739.     FUNCTION PTR_TO_LONG ( ptr : CellPtr ) : LONG_INTEGER;
  740.        VAR swap : RECORD
  741.                      CASE BYTE OF
  742.                         1 : ( a : CellPtr );
  743.                         2 : ( b : LONG_INTEGER )
  744.                      END;
  745.        BEGIN
  746.            swap.a := ptr;
  747.            ptr_to_long := swap.b
  748.        END; { PTR_TO_LONG }
  749.     FUNCTION RealPtr ( where : LONG_INTEGER ) : PtrToReal;
  750.        FUNCTION Ptr ( where : LONG_INTEGER ) : PtrToReal;
  751.           EXTERNAL;
  752.        BEGIN
  753.            RealPtr := Ptr(where)
  754.        END;
  755.     FUNCTION StrPtr ( where : LONG_INTEGER ) : PtrToString;
  756.        FUNCTION Ptr ( where : LONG_INTEGER ) : PtrToString;
  757.           EXTERNAL;
  758.        BEGIN
  759.            StrPtr := Ptr(where)
  760.        END;
  761.     
  762.     PROCEDURE SEND_MSG ( msg_type : INTEGER );
  763.        BEGIN
  764.            msg[0] := msg_type;
  765.            msg[1] := ap_id;
  766.            msg[2] := 0;
  767.            Write_Message(msg_area[1],16,msg)
  768.        END; { SEND_MSG } 
  769.  
  770.     BEGIN  (* handle_message *)
  771.  
  772.                { save for BLITs in SHEET_REDRAW }
  773.  
  774.                old_vert_grid := vert_grid;
  775.  
  776.                find_screen_pos(data_row,data_col,scr_row,scr_col);
  777.  
  778.                o_scr_row := scr_row;
  779.                o_scr_col := scr_col;
  780.                o_s_row := start_row;
  781.                o_f_row := finish_row;
  782.                o_s_col := start_col;
  783.                o_f_col := finish_col;
  784.                
  785.                message_type := msg_area[0];
  786.                extent := WholeSheet;
  787.                v_slide_inc := 1000/(n_rows-v_entry); { / number off-screen }
  788.                h_slide_inc := 1000/(n_cols-h_entry);
  789.  
  790.                redraw := FALSE;
  791.  
  792.                CASE message_type OF
  793.                   WM_Arrowed  : BEGIN
  794.                        CASE msg_area[4] OF
  795.                           0 : IF start_row > logical_row_1 THEN
  796.                                  page_up
  797.                               ELSE
  798.                                  GOTO 9;   
  799.                           1 : IF finish_row < n_rows THEN
  800.                                  page_down
  801.                               ELSE
  802.                                  GOTO 9;   
  803.                           2 : IF start_row > logical_row_1 THEN
  804.                                  row_up
  805.                               ELSE
  806.                                  GOTO 9;
  807.                           3 : IF finish_row < n_rows THEN
  808.                                  row_down
  809.                               ELSE
  810.                                  GOTO 9;
  811.                           4 : IF start_col > logical_col_1 THEN
  812.                                  page_left
  813.                               ELSE
  814.                                  GOTO 9;   
  815.                           5 : IF finish_col < n_cols THEN
  816.                                  page_right
  817.                               ELSE
  818.                                  GOTO 9;   
  819.                           6 : IF start_col > logical_col_1 THEN
  820.                                  col_left
  821.                               ELSE
  822.                                  GOTO 9;
  823.                           7 : IF finish_col < n_cols THEN
  824.                                  col_right
  825.                               ELSE
  826.                                  GOTO 9
  827.                        END;
  828.                        CASE msg_area[4] OF
  829.                           0,1,2,3 : extent := NoColNames;
  830.                           4,5,6,7 : extent := NoRowNames
  831.                        END
  832.                   END;
  833.                   WM_VSlid    : BEGIN
  834.                      move_v_slider;
  835.                      extent := NoColNames
  836.                   END;
  837.                   WM_HSlid    : BEGIN
  838.                      move_h_slider;
  839.                      extent := NoRowNames
  840.                   END;
  841.                   WM_Moved    : moved_window;
  842.                   WM_Sized    : resized_window;
  843.                   WM_Fulled   : fulled_window;
  844.                   WM_Topped   : topped_window;
  845.                   { code for redraw_message is in globsubs.pas since
  846.                     clean_up_after_dialog needs access to it }
  847.                   WM_Redraw   : redraw_message(msg_area[3],msg_area[4],
  848.                                                msg_area[5],msg_area[6],
  849.                                                msg_area[7]);
  850.                   MN_Selected : IF Front_Window = act_hdl THEN
  851.                                    do_menu
  852.                                 ELSE BEGIN
  853.                                    redraw := TRUE;
  854.                                    Menu_Normal(main_menu,msg_area[3])
  855.                                 END;   
  856.                   WM_Closed   :         { note sim. calls handle_message }
  857.                      IF n_hdls = 2 THEN { a recursive call }
  858.                         simulate_message(MN_Selected,mfile,mclosew)
  859.                      ELSE IF really_quit THEN
  860.                         user_quit := TRUE;
  861.                         
  862.                   { Desk Accessory requests }
  863.                   
  864.                   PresentMsg : BEGIN
  865.                      msg[3] := data_row; { always > 0 }
  866.                      msg[4] := data_col;
  867.                      send_msg(PresentReply)
  868.                   END;
  869.                   AssignedMsg : BEGIN
  870.                      msg[5] := ORD(assigned(msg_area[3],msg_area[4],ptr));
  871.                      data_addr := ptr_to_long(ptr);
  872.                      msg[3] := ShR(data_addr,16);
  873.                      msg[4] := data_addr & $0000FFFF;
  874.                      send_msg(AssignedReply)
  875.                   END;   
  876.                   RedrawMsg : BEGIN
  877.                      Send_Redraw(TRUE,0,0,screen_width,screen_height);
  878.                      send_msg(RedrawReply)
  879.                   END;
  880.                   DataMsg : BEGIN
  881.                      data_addr := Addr(data);
  882.                      msg[3] := ShR(data_addr,16); { high }
  883.                      msg[4] := data_addr & $0000FFFF; { low }
  884.                      send_msg(DataReply)
  885.                   END;
  886.                   NewMsg : BEGIN
  887.                      ptr := new_cell(msg_area[3],msg_area[4]);
  888.                      data_addr := ptr_to_long(ptr);
  889.                      msg[3] := ShR(data_addr,16);
  890.                      msg[4] := data_addr & $0000FFFF;
  891.                      send_msg(NewReply)
  892.                   END;
  893.                   DeleteMsg : BEGIN
  894.                       delete_cell(msg_area[3],msg_area[4],FALSE);
  895.                       send_msg(DeleteReply)
  896.                   END;
  897.                   LocateMsg : BEGIN
  898.                      ptr := locate_cell(msg_area[3],msg_area[4]);
  899.                      data_addr := ptr_to_long(ptr);
  900.                      msg[3] := ShR(data_addr,16);
  901.                      msg[4] := data_addr & $0000FFFF;
  902.                      send_msg(LocateReply)
  903.                   END;
  904.                   DefRangeMsg : BEGIN
  905.                      IF block_set THEN BEGIN
  906.                         msg[3] := b_s_row;
  907.                         msg[4] := b_s_col;
  908.                         msg[5] := b_e_row;
  909.                         msg[6] := b_e_col
  910.                      END
  911.                      ELSE
  912.                         msg[3] := 0;
  913.                      send_msg(DefRangeReply)
  914.                   END;
  915.                   GetRangeMsg : BEGIN
  916.                      IF ask_for_range(msg[3],msg[4],msg[5],msg[6],
  917.                                       'Accessory') THEN
  918.                         msg[7] := 1
  919.                      ELSE
  920.                         msg[7] := 0;
  921.                      send_msg(GetRangeReply)   
  922.                   END;
  923.                   MfdbAddrMsg : BEGIN
  924.                      data_addr := mfdb_addr(1);       { Memory MFDB }
  925.                      msg[3] := ShR(data_addr,16);
  926.                      msg[4] := data_addr & $0000FFFF;
  927.                      data_addr := mfdb_addr(0);       { Screen MFDB }
  928.                      msg[5] := ShR(data_addr,16);
  929.                      msg[6] := data_addr & $0000FFFF;
  930.                      send_msg(MfdbAddrReply)
  931.                   END;
  932.                   RealToStrMsg : BEGIN
  933.                      data_addr := msg_area[3];
  934.                      data_addr := ShL(data_addr,16) | msg_area[4];
  935.                      num_ptr := RealPtr(data_addr);
  936.                      data_addr := msg_area[5];
  937.                      data_addr := ShL(data_addr,16) | msg_area[6];
  938.                      str_ptr := StrPtr(data_addr);
  939.                      IF msg_area[7] & $8000 <> 0 THEN
  940.                         sci := TRUE
  941.                      ELSE
  942.                         sci := FALSE;
  943.                      i := msg_area[7] & $7FFF;
  944.                      real_to_string(num_ptr^,str_ptr^,i,sci);
  945.                      send_msg(RealToStrReply)
  946.                   END;
  947.                   StrToRealMsg : BEGIN
  948.                      data_addr := msg_area[3];
  949.                      data_addr := ShL(data_addr,16) | msg_area[4];
  950.                      str_ptr := StrPtr(data_addr);
  951.                      data_addr := msg_area[5];
  952.                      data_addr := ShL(data_addr,16) | msg_area[6];
  953.                      num_ptr := RealPtr(data_addr);
  954.                      num_ptr^ := string_to_real(str_ptr^);
  955.                      send_msg(StrToRealReply)
  956.                   END;
  957.                   TranslateMsg : BEGIN
  958.                      data_addr := msg_area[3];
  959.                      data_addr := ShL(data_addr,16) | msg_area[4];
  960.                      str_ptr := StrPtr(data_addr);
  961.                      i := 1;
  962.                      IF translate_cell(str_ptr^,i,LENGTH(str_ptr^),
  963.                                        msg[3],msg[4],sci,sci) = OK THEN
  964.                         msg[5] := 1
  965.                      ELSE
  966.                         msg[5] := 0;
  967.                      send_msg(TranslateReply)
  968.                   END;
  969.                   StringaCellMsg : BEGIN
  970.                      data_addr := msg_area[5];
  971.                      data_addr := ShL(data_addr,16) | msg_area[6];
  972.                      str_ptr := StrPtr(data_addr);
  973.                      string_a_cell(msg_area[3],msg_area[4],str_ptr^);
  974.                      send_msg(StringaCellReply)
  975.                   END;
  976.                   RecalcMsg : BEGIN
  977.                      Set_Mouse(M_Bee);
  978.                      manual_recalc;
  979.                      Set_Mouse(M_Arrow);
  980.                      send_msg(RecalcReply)
  981.                   END;
  982.                   
  983.                END; (* CASE message_type *)
  984.  
  985.                CASE message_type OF
  986.                   WM_VSlid,WM_HSlid : sheet_redraw(extent,FALSE,None);
  987.                   MN_Selected : IF NOT redraw THEN
  988.                                    write_cell_name;
  989.                   WM_Arrowed : CASE msg_area[4] OF
  990.                                   0,1,4,5 : sheet_redraw(extent,FALSE,None);
  991.                                   2       : sheet_redraw(extent,TRUE,Up);
  992.                                   3       : sheet_redraw(extent,TRUE,Down);
  993.                                   6       : sheet_redraw(extent,TRUE,Left);
  994.                                   7       : sheet_redraw(extent,TRUE,Right)
  995.                   END
  996.                END;
  997.  
  998. 9:  END; (* HANDLE_MESSAGE *)
  999.  
  1000. BEGIN
  1001. END.
  1002.  
  1003.