{$M+} {$E+} PROGRAM Mock; {$I i:\opus.i} {$I i:\gctv.inc} {$I i:\gemsubs.def} {$I i:\globsubs.def} {$I i:\vdi_aes.def} {$I d:\pascal\opus\gemdos.def} {$I d:\pascal\opus\resource.def} {$I d:\pascal\opus\graphout.def} {$I d:\pascal\opus\stringfn.def} PROCEDURE DO_PRINT ( s_row,f_row,s_col,f_col : INTEGER; hdl : INTEGER ); EXTERNAL; PROCEDURE HILIGHT_BLOCK; { either does inverse the block or restores it to normal depending on whether already inversed or not } VAR i,j : INTEGER; BEGIN Hide_Mouse; Work_Rect(act_hdl,x_1,y_1,w_1,h_1); Set_Clip(x_1,y_1,w_1,h_1); FOR i := start_row TO virtual_f_row DO FOR j := start_col TO virtual_f_col DO IF (i >= b_s_row) AND (i <= b_e_row) AND (j >= b_s_col) AND (j <= b_e_col) THEN toggle_inverse(Black,i,j); IF n_hdls = 2 THEN BEGIN switch_window; Send_Redraw(FALSE,0,0,screen_width,screen_height); switch_window END; Show_Mouse END; { HILIGHT_BLOCK } FUNCTION START_BLOCK : BOOLEAN; VAR temp : INTEGER; BEGIN IF block_set THEN hilight_block; b_s_row := data_row; b_s_col := data_col; block_st_set := TRUE; IF block_end_set THEN BEGIN IF b_s_row > b_e_row THEN BEGIN temp := b_e_row; b_e_row := b_s_row; b_s_row := temp END; IF b_s_col > b_e_col THEN BEGIN temp := b_e_col; b_e_col := b_s_col; b_s_col := temp END; block_set := TRUE; hilight_block; adjust_menu(TRUE) END; start_block := block_set END; { START_BLOCK } FUNCTION END_BLOCK : BOOLEAN; VAR temp : INTEGER; BEGIN IF block_set THEN hilight_block; b_e_row := data_row; b_e_col := data_col; block_end_set := TRUE; IF block_st_set THEN BEGIN IF b_s_row > b_e_row THEN BEGIN temp := b_e_row; b_e_row := b_s_row; b_s_row := temp END; IF b_s_col > b_e_col THEN BEGIN temp := b_e_col; b_e_col := b_s_col; b_s_col := temp END; block_set := TRUE; hilight_block; adjust_menu(TRUE) END; end_block := block_set END; { END_BLOCK } FUNCTION DESELECT_BLOCK : BOOLEAN; VAR i,j,row,col : INTEGER; BEGIN IF block_set THEN hilight_block; adjust_menu(FALSE); block_set := FALSE; block_st_set := FALSE; block_end_set := FALSE; deselect_block := TRUE END; { DESELECT_BLOCK } PROCEDURE DELETE_BLOCK; VAR i,j : INTEGER; successful : BOOLEAN; BEGIN temp := CONCAT('[3][Do you really wish to DELETE|' , 'the block? Data will be|' , 'irreversibly lost!]', '[ Cancel |OK]'); IF Do_Alert(temp,2) = 2 THEN BEGIN Set_Mouse(M_Bee); delete_range(b_s_row,b_s_col,b_e_row,b_e_col,TRUE); successful := deselect_block; block_set := FALSE; block_st_set := FALSE; block_end_set := FALSE; Set_Mouse(M_Arrow) END END; { DELETE_BLOCK } FUNCTION DO_PASTE ( src_row, { nominally the row of origin } dest_row, { row number to be pasted to } dest_col, { col number to be pasted at } st_r,st_c, { definitions of the source block } e_r,e_c : INTEGER; do_relative, draw : BOOLEAN ) : BOOLEAN; { This function is used by SHIFT_BLOCK and LOAD_FILE when "load block at cursor" was chosen. It assumes that a buffer row has been built in row 0, and src_row should equal the current row number within the source block. It operates ONE row at a time. } VAR col,offset : INTEGER; quit : BOOLEAN; ptr,ptr1,ptr2 : CellPtr; BEGIN offset := dest_col-st_c; quit := FALSE; ptr1 := data[0]; WHILE (ptr1 <> NIL) AND (NOT quit) DO BEGIN col := ptr1^.c+offset; IF comp_assign(0,ptr1^.c,dest_row,col,FALSE) THEN BEGIN ptr2 := locate_cell(dest_row,col); IF ptr2 <> NIL THEN IF (ptr2^.class = Expr) AND (ptr2^.status <> Empty) THEN BEGIN IF do_relative THEN { adjust refs within block } IF adjust_expr(adj_refs,ptr2,src_row,ptr1^.c, dest_row,col, st_r,st_c,e_r,e_c) <> OK THEN quit := TRUE; { OutOfRange error } IF NOT quit THEN all_lists(add,ptr2,dest_row,col); END END ELSE BEGIN Set_Mouse ( M_Arrow ); out_mem_cell(dest_row,ptr1^.c,'pasted to'); alert := Do_Alert(temp,1); quit := TRUE END; IF draw THEN cell_on_screen(1,dest_row,col,TRUE); delete_cell(0,ptr1^.c,FALSE); { free slot in buffer } ptr1 := data[0] { start of list } END; { WHILE } do_paste := NOT quit; clear_buffer END; { DO_PASTE } PROCEDURE SHIFT_BLOCK ( action, dest_r,dest_c, st_r,st_c,e_r,e_c : INTEGER ); { procedure physically moves/copies and redraws a block defined by the block bouds parameters. Called by transport block with action of mmove, mcopy; called by sheet_insert with action of mmove to insert a row or column } LABEL 1; VAR i,j,m,n,r,offset, b_row_begin,b_row_end, d_row_begin,d_row_end, row_inc,num_rows,num_cols : INTEGER; do_relative,dummy,done : BOOLEAN; ptr : CellPtr; { use a work_cell because we need to use comp_assign which expects whole cell arguments and since the source str may be altered if it is an Expr and contains relative cell refs; this way, the source is left alone, which is what we want if say, we're copying } BEGIN { SHIFT_BLOCK } num_rows := e_r-st_r+1; num_cols := e_c-st_c+1; temp:='[2][Treat cell references as:][ Absolute | Relative ]'; IF Do_Alert(temp,2) = 2 THEN do_relative := TRUE ELSE do_relative := FALSE; IF st_r > dest_r THEN BEGIN b_row_begin := st_r; b_row_end := e_r; d_row_begin := dest_r; d_row_end := dest_r+num_rows-1; row_inc := 1; END ELSE BEGIN b_row_begin := e_r; b_row_end := st_r; d_row_begin := dest_r+num_rows-1; d_row_end := dest_r; row_inc := -1; END; done := FALSE; Set_Mouse(M_Bee); m := b_row_begin; i := d_row_begin; offset := dest_c-st_c; clear_buffer; WHILE NOT done DO BEGIN { build buffer area } ptr := data[m]; WHILE ptr <> NIL DO BEGIN IF (ptr^.c >= st_c) AND (ptr^.c <= e_c) THEN BEGIN IF NOT comp_assign(m,ptr^.c,0,ptr^.c,FALSE) THEN BEGIN int_to_string(m,temp); temp := CONCAT('[3][Not enough memory to build|' , 'buffer row therefore row|' , temp , ' was not pasted.][ Cancel ]'); alert := Do_Alert(temp,1); GOTO 1 END END; ptr := ptr^.next END; { wait to delete source row until buffer row is constructed since if out of mem occurred, and we deleted as we went along, the row up to that point would be gone } IF action = mmove THEN delete_range(m,st_c,m,e_c,TRUE); { delete the dest row } delete_range(i,dest_c,i,dest_c+num_cols-1,TRUE); { finally do the paste, deleting the buffer as we go, so chances of an out of mem error are exceedingly small } IF NOT do_paste(m,i,dest_c,st_r,st_c,e_r,e_c, do_relative,TRUE) THEN GOTO 1; IF i = d_row_end THEN done := TRUE ELSE BEGIN i := i+row_inc; m := m+row_inc END END; { WHILE NOT done } 1: clear_buffer; { just in case } Set_Mouse(M_Arrow) END; { SHIFT_BLOCK } FUNCTION TRANSPORT_BLOCK ( action : INTEGER ) : BOOLEAN; { depending on action, copies or moves a marked block to another location, beginning at the current cell. Also copies cell_format regardless of action. Possible values are: mmove, mcopy } LABEL 2; VAR num_rows,num_cols : INTEGER; a,b : STR10; dummy : BOOLEAN; BEGIN num_rows := b_e_row-b_s_row+1; num_cols := b_e_col-b_s_col+1; transport_block := FALSE; IF (data_row+num_rows-1 <= n_rows) AND (data_col+num_cols-1 <= n_cols) THEN BEGIN IF (data_row = b_s_row) AND (data_col = b_s_col) THEN BEGIN temp := CONCAT('[3][You may not copy or move|' , 'a block to itself! Move the|' , 'cursor to a position other|' , 'than the start of the block.][ OK ]'); alert := Do_Alert(temp,1); GOTO 2 { exit } END; IF action = mmove THEN temp := 'MOVE' ELSE temp := 'COPY'; temp := CONCAT('[2][Really ' , temp , ' block?][ Cancel |OK]'); IF Do_Alert(temp,2) = 2 THEN BEGIN shift_block(action,data_row,data_col,b_s_row,b_s_col, b_e_row,b_e_col); IF action = mmove THEN BEGIN dummy := deselect_block; block_set := TRUE; block_st_set := TRUE; block_end_set := TRUE; b_s_row := data_row; b_s_col := data_col; b_e_row := data_row+num_rows-1; b_e_col := data_col+num_cols-1; adjust_menu(TRUE); hilight_block END END ELSE { falls through } END ELSE BEGIN a := col_name[n_cols-num_cols+1]; int_to_string(n_rows-num_rows+1,b); block_too_big(a,b); transport_block := FALSE END; 2: END; { TRANSPORT_BLOCK } (************************************************************************) (* File IO *) (************************************************************************) PROCEDURE ACTION_BANNER ( action : STR10 ); BEGIN Hide_Mouse; fo_x := 512; IF rez = 1 THEN fo_y := 57 ELSE fo_y := 29; Form_Anywhere(action_ptr,fo_x,fo_y,fo_w,fo_h); fo_x := fo_x-3; { now account for outline around dialog, since } fo_y := fo_y-3; { the width and height in the object def don't } fo_w := fo_w+6; fo_h := fo_h+6; Set_Text(action_ptr,actwhat,action,s1,10); Form_Dial(0,0,0,0,0,fo_x,fo_y,fo_w,fo_h); Obj_Draw(action_ptr,Root,Max_Depth,fo_x,fo_y,fo_w,fo_h); Show_Mouse END; { ACTION_BANNER } FUNCTION FILE_TO_C ( VAR whole_name : STRING; VAR c_name : C_STRING; what : DiskIoOps ) : BOOLEAN; { GEMDOS wants a "C" type string } BEGIN IF POS('.',whole_name) = 0 THEN IF what = SaveText THEN whole_name := CONCAT(whole_name,'.DOC') ELSE whole_name := CONCAT(whole_name,'.OPS'); IF Filename(whole_name) THEN BEGIN Pascal_To_C(whole_name,c_name); file_to_c := TRUE END ELSE file_to_c := FALSE END; { FILE_TO_C } FUNCTION GET_FILE_NAME ( VAR c_name : C_STRING; what : DiskIoOps ) : BOOLEAN; { present file selector } VAR i : INTEGER; BEGIN get_file_name := FALSE; IF what = SaveText THEN i := 2 ELSE i := 1; IF Get_In_File(default_path[i],current_file) THEN { user pressed OK } IF file_to_c(current_file,c_name,what) THEN { valid file name? } get_file_name := TRUE ELSE { oh oh } alert := Do_Alert('[1][Bad path/file name.][ Cancel ]',1) END; { GET_FILE_NAME } FUNCTION CREATE_FILE ( VAR c_name : C_STRING; VAR handle : INTEGER ) : BOOLEAN; BEGIN handle := TOS_Create(c_name,0); IF handle >= 0 THEN create_file := TRUE ELSE BEGIN create_file := FALSE; Form_Error(handle) END END; { CREATE_FILE } FUNCTION OPEN_FILE ( VAR c_name : C_STRING; VAR handle : INTEGER ) : BOOLEAN; BEGIN handle := TOS_Open(c_name,0); IF handle >= 0 THEN open_file := TRUE ELSE BEGIN open_file := FALSE; Form_Error(handle) END END; { OPEN_FILE } PROCEDURE CLOSE_FILE ( handle : INTEGER ); BEGIN handle := TOS_Close(handle); IF handle < 0 THEN { probably will never happen } Form_Error(handle) END; { CLOSE_FILE } PROCEDURE SAVE_FILE ( what : DiskIoOps; s_r,s_c,e_r,e_c : INTEGER ); LABEL 1; VAR count : BYTE; i,j,k,m,handle,result : INTEGER; quit : BOOLEAN; c_name : C_STRING; converter : Switcheroo; int_buffer : HundredInts; byte_buffer : ThreeHundredBytes; ptr : CellPtr; FUNCTION Int_Write ( handle : INTEGER; n : LONG_INTEGER; VAR buf : HundredInts ) : LONG_INTEGER; GEMDOS ($40); PROCEDURE WRITE_BYTES ( n : LONG_INTEGER; VAR buffer : ThreeHundredBytes ); VAR bytes_written : LONG_INTEGER; BEGIN bytes_written := TOS_Write(handle,n,buffer); IF bytes_written <> n THEN BEGIN IF bytes_written >= 0 THEN alert := Do_Alert('[1][Not enough room on disk.][ Cancel ]',1) ELSE Form_Error(bytes_written); GOTO 1 { quick exit } END END; { WRITE_BYTES } PROCEDURE WRITE_INTS ( n : LONG_INTEGER; VAR buffer : HundredInts ); VAR ints_written : LONG_INTEGER; BEGIN ints_written := Int_Write(handle,n,buffer); IF ints_written <> n THEN BEGIN IF ints_written >= 0 THEN alert := Do_Alert('[1][Not enough room on disk.][ Cancel ]',1) ELSE Form_Error(ints_written); GOTO 1 { quick exit } END END; { WRITE_BYTES } BEGIN IF what = SaveFile THEN { let user know what he's doing } action_banner('Save Sheet') ELSE action_banner('Save Block'); IF get_file_name(c_name,what) THEN { valid file name? } IF create_file(c_name,handle) THEN BEGIN { able to write to disk? } Set_Mouse(M_Bee); byte_buffer[1] := 1; { write some numbers to indicate it's our } byte_buffer[2] := 14; { file } byte_buffer[3] := 85; byte_buffer[4] := 10; byte_buffer[5] := 22; byte_buffer[6] := 84; write_bytes(6,byte_buffer); converter.str := p_title_1; { save the printer titles } write_bytes(LENGTH(p_title_1)+1,converter.switched); converter.str := p_title_2; write_bytes(LENGTH(p_title_2)+1,converter.switched); converter.str := header; write_bytes(LENGTH(header)+1,converter.switched); converter.str := footer; write_bytes(LENGTH(footer)+1,converter.switched); byte_buffer[1] := ORD(p_row_col); { print dialog variables } byte_buffer[2] := ORD(print_formulas); byte_buffer[3] := ORD(condensed_print); byte_buffer[4] := ORD(draft_final); byte_buffer[5] := ORD(grid_flag); { system variables } byte_buffer[6] := ORD(small_text); byte_buffer[7] := ORD(form_flag); byte_buffer[8] := ORD(auto_cursor); byte_buffer[9] := ORD(auto_recalc); byte_buffer[10] := ORD(natural); byte_buffer[11] := ORD(cursor_direction); FOR i := 12 TO n_cols+11 DO { column widths } byte_buffer[i] := col_width[i-11,spaces]; write_bytes(n_cols+11,byte_buffer); { and write it to disk } int_buffer[1] := default_format; int_buffer[2] := s_r; { the coordinates of block we are writing } int_buffer[3] := s_c; int_buffer[4] := e_r; int_buffer[5] := e_c; i := 1; { prepare to save marks } j := 6; WHILE i < 5 DO BEGIN int_buffer[j] := marks[i].row; j := j+1; int_buffer[j] := marks[i].col; j := j+1; i := i+1 END; int_buffer[14] := freeze_row; int_buffer[15] := freeze_col; write_ints(30,int_buffer); FOR i := 1 TO n_rows DO BEGIN { do this way so a block may be } ptr := data[i]; { easily loaded as if it was an } count := 0; { entire sheet. No extra data is } WHILE ptr <> NIL DO BEGIN { saved, beyond count for each row } IF (i >= s_r) AND (i <= e_r) AND (ptr^.c >= s_c) AND (ptr^.c <= e_c) THEN count := count+1; ptr := ptr^.next END; byte_buffer[1] := count; { so each row 1..999 has a count } write_bytes(1,byte_buffer); { of number cells in itself } IF (count > 0) AND { only write to disk if we are in range } (i >= s_r) AND (i <= e_r) THEN BEGIN quit := FALSE; ptr := data[i]; WHILE (ptr <> NIL) AND (NOT (quit)) DO BEGIN WITH ptr^ DO IF (c >= s_c) AND (c <= e_c) THEN BEGIN converter.c := c; write_bytes(2,converter.switched); converter.format := format; write_bytes(2,converter.switched); converter.class := class; write_bytes(2,converter.switched); converter.status := status; write_bytes(2,converter.switched); IF ((class = Val) OR (class = Expr)) AND (status = Full) THEN BEGIN converter.number := num; write_bytes(6,converter.switched); END; IF str <> NIL THEN BEGIN converter.str := str^; write_bytes(LENGTH(str^)+1,converter.switched) END ELSE BEGIN byte_buffer[1] := 0; write_bytes(1,byte_buffer) END END ELSE IF c > e_c THEN quit := TRUE; ptr := ptr^.next END { WHILE } END { IF } END; { FOR } 1: close_file(handle); Set_Mouse(M_Arrow) END; { IF create_file } Form_Dial(3,0,0,0,0,fo_x,fo_y,fo_w,fo_h) END; { SAVE_FILE } PROCEDURE LOAD_FILE ( what : DiskIoOps ); LABEL 1,2; VAR count : BYTE; d,i,j,handle,result,s_r,s_c,e_r,e_c : INTEGER; did_load,at_cursor : BOOLEAN; a,b : STR10; c_name : C_STRING; converter : Switcheroo; int_buffer : HundredInts; byte_buffer : ThreeHundredBytes; ptr : CellPtr; FUNCTION Int_Read ( handle : INTEGER; n : LONG_INTEGER; VAR buf : HundredInts ) : LONG_INTEGER; GEMDOS ($3F); PROCEDURE MY_SEEK; { Seeks back one byte after finding a string length > 0 } VAR dis : LONG_INTEGER; BEGIN dis := TOS_Seek(-1,handle,1); IF dis < 0 THEN BEGIN Form_Error(dis); GOTO 1 END END; { MY_SEEK } PROCEDURE READ_BYTES ( n : LONG_INTEGER; VAR buffer : ThreeHundredBytes ); VAR bytes_read : LONG_INTEGER; BEGIN bytes_read := TOS_Read(handle,n,buffer); IF bytes_read <> n THEN BEGIN IF bytes_read >= 0 THEN Form_Error(-11) ELSE Form_Error(bytes_read); GOTO 1 END END; { READ_BYTES } PROCEDURE READ_INTS ( n : LONG_INTEGER; VAR buffer : HundredInts ); VAR ints_read : LONG_INTEGER; BEGIN ints_read := Int_Read(handle,n,buffer); IF ints_read <> n THEN BEGIN IF ints_read >= 0 THEN Form_Error(-11) ELSE Form_Error(ints_read); GOTO 1 END END; { READ_INTS } PROCEDURE OUT_OF_MEM ( c : INTEGER ); BEGIN Set_Mouse(M_Arrow); out_mem_cell(i,c,'loaded'); GOTO 1 END; { OUT_OF_MEM } PROCEDURE SET_FLAGS ( flag : BOOLEAN; menu_id : INTEGER ); BEGIN IF flag THEN Menu_Check(main_menu,menu_id,TRUE) ELSE Menu_Check(main_menu,menu_id,FALSE) END; BEGIN { LOAD_FILE } did_load := FALSE; at_cursor := FALSE; IF what = LoadFile THEN action_banner ('Load Sheet') ELSE action_banner ('Load Block'); IF get_file_name(c_name,what) THEN IF open_file(c_name,handle) THEN BEGIN IF what = LoadBlock THEN BEGIN temp := CONCAT('[2][1. Load at original position|' , '2. Load at cursor][Cancel|1|2]' ); alert := Do_Alert(temp,1); IF alert = 1 THEN GOTO 2 ELSE at_cursor := alert = 3 END; Set_Mouse(M_Bee); read_bytes(6,byte_buffer); { read the header } IF (byte_buffer[1] <> 1) OR (byte_buffer[2] <> 14) OR (byte_buffer[3] <> 85) OR (byte_buffer[4] <> 10) OR (byte_buffer[5] <> 22) OR (byte_buffer[6] <> 84) THEN BEGIN temp := CONCAT ('[3][Incorrect file-type or|' , 'corrupted file.][ Cancel ]'); alert := Do_Alert(temp,1); GOTO 1 END; IF what = LoadFile THEN clear_worksheet; block_set := FALSE; block_st_set := FALSE; block_end_set := FALSE; adjust_menu(FALSE); read_bytes(1,byte_buffer); IF byte_buffer[1] > 0 THEN BEGIN my_seek; read_bytes(byte_buffer[1]+1,converter.switched); IF what = LoadFile THEN p_title_1 := converter.str END ELSE IF what = LoadFile THEN p_title_1 := ''; read_bytes(1,byte_buffer); IF byte_buffer[1] > 0 THEN BEGIN my_seek; read_bytes(byte_buffer[1]+1,converter.switched); IF what = LoadFile THEN p_title_2 := converter.str END ELSE IF what = LoadFile THEN p_title_2 := ''; read_bytes(1,byte_buffer); IF byte_buffer[1] > 0 THEN BEGIN my_seek; read_bytes(byte_buffer[1]+1,converter.switched); IF what = LoadFile THEN header := converter.str END ELSE IF what = LoadFile THEN header := ''; read_bytes(1,byte_buffer); IF byte_buffer[1] > 0 THEN BEGIN my_seek; read_bytes(byte_buffer[1]+1,converter.switched); IF what = LoadFile THEN footer := converter.str END ELSE IF what = LoadFile THEN footer := ''; read_bytes(n_cols+11,byte_buffer); IF what = LoadFile THEN BEGIN p_row_col := byte_buffer[1] = 1; print_formulas := byte_buffer[2] = 1; condensed_print := byte_buffer[3] = 1; draft_final := byte_buffer[4] = 1; grid_flag := byte_buffer[5] = 1; small_text := byte_buffer[6] = 1; form_flag := byte_buffer[7] = 1; auto_cursor := byte_buffer[8] = 1; auto_recalc := byte_buffer[9] = 1; natural := byte_buffer[10] = 1; IF byte_buffer[11] = 1 THEN cursor_direction := CursorRight ELSE cursor_direction := CursorDown; set_flags(grid_flag,mshowgri); set_flags(form_flag,mshowfor); set_flags(auto_cursor,mautocur); set_flags(auto_recalc,mautorec); set_flags(natural,mnatural); FOR i := 12 TO n_cols+11 DO BEGIN col_width[i-11,spaces] := byte_buffer[i]; col_width[i-11,pixels] := byte_buffer[i]*8 END END; read_ints(30,int_buffer); s_r := int_buffer[2]; s_c := int_buffer[3]; e_r := int_buffer[4]; e_c := int_buffer[5]; IF (what = LoadBlock) AND (at_cursor) THEN IF (data_row+e_r-s_r > n_rows) OR (data_col+e_c-s_c > n_cols) THEN BEGIN a := col_name[n_cols-(e_c-s_c)]; int_to_string(n_rows-(e_r-s_r),b); block_too_big(a,b); GOTO 1 END; IF what = LoadFile THEN BEGIN default_format := int_buffer[1]; i := 1; j := 6; WHILE i < 5 DO BEGIN marks[i].row := int_buffer[j]; j := j+1; marks[i].col := int_buffer[j]; i := i+1; j := j+1 END; m1s := marks[1].row > 0; m2s := marks[2].row > 0; m3s := marks[3].row > 0; m4s := marks[4].row > 0; IF m1s THEN Menu_Enable(main_menu,mg1) ELSE Menu_Disable(main_menu,mg1); IF m2s THEN Menu_Enable(main_menu,mg2) ELSE Menu_Disable(main_menu,mg2); IF m3s THEN Menu_Enable(main_menu,mg3) ELSE Menu_Disable(main_menu,mg3); IF m4s THEN Menu_Enable(main_menu,mg4) ELSE Menu_Disable(main_menu,mg4); freeze_row := int_buffer[14]; freeze_col := int_buffer[15]; logical_row_1 := freeze_row+1; logical_col_1 := freeze_col+1; start_row := logical_row_1; start_col := logical_col_1; data_row := start_row; data_col :=start_col; IF freeze_row > 0 THEN y_margin := two_cell_h-1 ELSE y_margin := cell_height-1; IF freeze_col > 0 THEN x_margin := 39+col_width[freeze_col,pixels] ELSE x_margin := 38; { must do this so that switch will save correct finish_row & col so that return_attr can recalc correct v & h_entry. Failure to do this can lead to a crash when handle_message tries to calculate slider positions and these entry values equal n_rows or n_cols due to a non-updated finish row or col } get_num_scr_entries(ExRight); IF n_hdls = 2 THEN BEGIN switch_window; start_row := logical_row_1; start_col := logical_col_1; data_row := start_row; data_col := start_col; get_num_scr_entries(ExRight); switch_window END END; IF what = LoadBlock THEN IF at_cursor THEN delete_range(data_row,data_col, data_row+e_r-s_r,data_col+e_c-s_c,FALSE) ELSE IF (s_r = 1) AND (s_c = 1) AND { just in case... } (e_r = n_rows) AND (e_c = n_cols) THEN clear_worksheet ELSE delete_range(s_r,s_c,e_r,e_c,FALSE); clear_buffer; FOR i := 1 TO n_rows DO BEGIN read_bytes(1,byte_buffer); count := byte_buffer[1]; FOR j := 1 TO count DO BEGIN read_bytes(2,converter.switched); IF (what = LoadBlock) AND (at_cursor) THEN ptr := new_cell(0,converter.c) ELSE ptr := new_cell(i,converter.c); IF ptr <> NIL THEN WITH ptr^ DO BEGIN c := converter.c; read_bytes(2,converter.switched); format := converter.format; read_bytes(2,converter.switched); class := converter.class; read_bytes(2,converter.switched); status := converter.status; IF ((class = Val) OR (class = Expr)) AND (status = Full) THEN BEGIN read_bytes(6,converter.switched); num := converter.number END; read_bytes(1,byte_buffer); IF byte_buffer[1] > 0 THEN BEGIN IF str = NIL THEN IF request_memory(AString) THEN NEW(str) ELSE out_of_mem(c); my_seek; read_bytes(byte_buffer[1]+1,converter.switched); str^ := converter.str; IF NOT ((what = LoadBlock) AND (at_cursor)) THEN all_lists(add,ptr,i,c) END END ELSE out_of_mem(converter.c) END; { FOR j } IF (what = LoadBlock) AND (at_cursor) THEN IF count > 0 THEN IF NOT do_paste(i,data_row+i-s_r,data_col, s_r,s_c,e_r,e_c,at_cursor,FALSE) THEN GOTO 1; END; { FOR i } IF rez = 1 THEN BEGIN { do like this since the message handler flips small_text from TRUE to FALSE and vice-versa } small_text := NOT small_text; simulate_message(MN_Selected,moptions,msmall) END ELSE small_text := FALSE; did_load := TRUE; 1: close_file(handle); Set_Mouse(M_Arrow) END; { IF open_file } 2: Form_Dial(3,0,0,0,0,0,0,screen_width,screen_height); clear_buffer END; { LOAD_FILE } PROCEDURE SAVE_TEXT ( s_r,s_c,e_r,e_c : INTEGER ); VAR handle,x,y,w,h : INTEGER; c_name : C_STRING; BEGIN print_spreadsheet(FALSE,'Save as Text',s_r,s_c,e_r,e_c); IF s_r > 0 THEN BEGIN action_banner('Save Text'); x := fo_x; { because do_print will wipe out these for its own } y := fo_y; { nefarious purposes, i.e. displaying the page # } w := fo_w; h := fo_h; IF get_file_name(c_name,SaveText) THEN IF create_file(c_name,handle) THEN BEGIN do_print(s_r,e_r,s_c,e_c,handle); close_file(handle) END; Form_Dial(3,0,0,0,0,x,y,w,h) END END; { SAVE_TEXT } PROCEDURE DISK_IO ( what : DiskIoOps ); VAR s_r,s_c,e_r,e_c : INTEGER; BEGIN CASE what OF LoadFile : load_file(LoadFile); SaveFile : save_file(SaveFile,1,1,n_rows,n_cols); LoadBlock : load_file(LoadBlock); SaveBlock : IF ask_for_range(s_r,s_c,e_r,e_c,'Save Block') THEN save_file(SaveBlock,s_r,s_c,e_r,e_c); SaveText : save_text(s_r,s_c,e_r,e_c) END END; { DISK_IO } BEGIN END.