/**********************************************************************/ /* (c) Copyright IBM Corporation 1987, 2020 */ /* This programming example is to be used as a sample program only. */ /* Although this program may have been reviewed by IBM */ /* for accuracy in a specific environment, there is no */ /* guarantee that the same or similar results will be obtained */ /* elsewhere. The code is being provided on an 'As is' basis */ /* without any warranty express or implied. */ /* */ /* Function: This program will present a window in which data can */ /* be entered, changed, or deleted. */ /* */ /* Author: Alan Altmark, IBM */ /* */ /*--------------------------- SYNTAX -------------------------------*/ /* Parameter: name determines the name of notepad to */ /* be viewed. The data is contained */ /* in a file called 'name NOTEPAD A'. */ /* Default: your userid */ /* */ /* Options: COLOR c1 c2 c1 is the color of the data area. */ /* c2 is the color of the border. */ /* Reverse video will be used. */ /* Default: TURQUOISE WHITE */ /* */ /* If you want to change the color, */ /* edit the last line of the NOTEPAD */ /* file. */ /* */ /* SIZE rows cols The dimensions of the notepad */ /* data area. */ /* Default: 20 40 */ /* This program sets a rather arbitrary */ /* minimum of 20 rows and a maximum of */ /* 75 colums. It was originally */ /* written when 24x80 was standard. */ /* */ /* PAGES n The number of pages the notepad */ /* will have. */ /* Default: 4 pages */ /* */ /* Control: PF1 Exit, leaving the notepad displayed. */ /* PF2 Add a line */ /* PF3 Exit, drop the window */ /* PF7 Scroll backward (also PA1) */ /* PF8 Scroll forward (also PA2) */ /* PF10 Delete a line */ /* PF12 Exit, cancel any updates made */ /* ATTN Pop Window Manager window */ /**********************************************************************/ address command arg padname padtype . "(" options ")" trc padname = word(padname userid() , 1) padtype = word(padtype "NOTEPAD", 1) padfile = padname padtype "A" if trc <> "" then do Address CMS Call Trace strip(trc) end /* If this is a pre-existing notepad, get data from the */ /* last line. It contains info on the parameters that */ /* were used to create it. */ "ESTATE" padfile padfile_exists = (rc = 0) if padfile_exists then do "PIPE <" padfile, "| take last 1", "| var opts_from_file" if opts_from_file = "" then do say "Unable to display notepad. File corrupted." exit 24 end else options = opts_from_file end else options = GenOpts( options ) "LASTPAGE 1" Parse var options , =1 "COLOR" color bord . , =1 "SIZE" rows cols . , =1 "PAGES" maxpage . , =1 "LASTPAGE" page . /* OK. Now ready to start building the window. First, get rid of */ /* any pre-exisitng windows. */ "WINDOW DELETE" padname "VSCREEN DELETE" padname /* Calculate the size of the VSCREEN. It must be able to hold ALL */ /* of the data. Most of it is invisible. The WINDOW slides up and */ /* down over the VSCREEN in "page" sized chunks. */ vrows = rows * maxpage "VSCREEN DEFINE" padname vrows cols+2 "1 1 (REV" color /* Window has 2 extra columns to allow for SF at start and end */ /* Has 2 extra rows to account for top & bottom reserved lines */ /* It looks a little wonky beause of the use of reverse video, */ /* but this program is for learning, not a contest. */ "WINDOW DEFINE" padname rows+2 cols+3 "4 38 (NOBORDER" "SET LOCATION" padname "OFF" /* Don't want built-in beacon. */ /* Yep. Old school. This was written back in the 1980s. */ /* Create the file. */ if \padfile_exists then "EXECIO" vrows "DISKW" padfile "1 F" cols "(FINIS STRING " /* Populate the VSCREEN from the data file. */ "VSCREEN GET" padname padfile "1" vrows /* Header and footer setup */ "VSCREEN WRITE" padname " 1 1" cols+1 "(RESERVED" bord "REV PROT FIELD " "VSCREEN WRITE" padname "-1 1" cols+1 "(RESERVED" bord "REV PROT FIELD " /* Place the window on top of the VSCREEN. Whatever is behind it shows through. */ "WINDOW SHOW" padname "ON" padname "1 1" "VSCREEN CURSOR" padname "1 2" errmsg = "" /* Now just process input from the window */ do until quit = yes header = justify("Notepad:_"padname "Page_"page, cols) header = translate(header, " ", "_") footer = "2=Add 3=Quit 7=Back 8=Fwd 10=Del 12=Cncl" if errmsg <> "" then /* Sound the alarm for errors */ do "VSCREEN ALARM" padname footer = errmsg end "VSCREEN WRITE" padname "1 1" cols "(RESERVED DATA" header "VSCREEN WRITE" padname "-1 1" cols "(RESERVED DATA" left(footer, cols) "VSCREEN WRITE" padname "-1 1" cols "(RESERVED COLOR" , copies("2", length(errmsg)) || copies("0",cols-length(errmsg)) errmsg = "" /* Wait for the user to do something */ "VSCREEN WAITREAD" padname /*2*/ if rc <> 0 then exit rc parse var WAITREAD.1 keytype keynum . /* Find out where the cursor is. */ "QUERY CURSOR (STACK LIFO" pull "IN " vcurs cursorpos . "(" rcursor . /* msi */ /* Map PF13-24 to PF1-12 */ if keynum > 12 then keynum = keynum - 12 keyhit = keytype || keynum quit = no /* If we're not cancelling, write any changed data to the */ /* VSCREEN. */ if find("UNKNOWN PFKEY12", keyhit) = 0 then do do i = 3 to WAITREAD.0 parse var WAITREAD.i dtype r c data "VSCREEN WRITE" padname r c cols "(DATA" strip(data, "T") end end /* Position the cursor and update the VSCREEN with the data */ "VSCREEN CURSOR" padname "1 2" /*2*/ "VSCREEN WAITT" padname /*2*/ /* Now process the key that was pressed */ Select when keyhit = "UNKNOWN" then "WINDOW POP WM" when keyhit = "ENTER" then nop /* PF2: Insert a line. Whatever is at the bottom of the */ /* VSCREEN will be rolled off and deleted. */ when keyhit = "PFKEY2" & vcurs = padname then do if rcursor = "RESERVED" then cursorpos = "0" Call Update "LOCATE :"cursorpos"#ADD 1#LOCATE :*#DELETE 1" "VSCREEN CURSOR" padname cursorpos+1 "2" /*2*/ end /* PF3: Quit. Remember the attributes of this notepad in the */ /* last line of the file. */ when keyhit = "PFKEY3" then do quit = yes lastline = "* DO NOT DELETE *", "COLOR" color bord "SIZE" rows cols "PAGES" maxpage , "LASTPAGE" page Call Update "LOCATE :*#DELETE 1#INPUT" lastline end /* PF7: Go back one page. Wrap to the last page if already at the */ /* top. */ when keyhit = "PFKEY7" then do if page > 1 then do page = page - 1 "WINDOW BACKWARD" padname "WINDOW UP" padname end else /* Wrap to bottom */ do page = maxpage "WINDOW BOTTOM" padname "WINDOW BACKWARD" padname errmsg = "Wrapped..." end "VSCREEN CURSOR" padname "1 2" /*2*/ end /* PF7: Go forward one page. Wrap to the top if we're already on */ /* the last page. */ when keyhit = "PFKEY8" then do if page = maxpage then do page = 1 "WINDOW TOP" padname /*2*/ errmsg = "Wrapped..." end else do page = page + 1 "WINDOW FORWARD" padname "WINDOW DOWN" padname end "VSCREEN CURSOR" padname (page-1)*(rows)+1 "2" /*2*/ end /* PF10: Delete a line. A blank line will be added to the bottom of */ /* the notepad to make up for it. */ when keyhit = "PFKEY10" & rcursor = "DATA" & vcurs = padname then do Call Update "LOCATE :"cursorpos"#DELETE 1#LOCATE :*#ADD 1" "VSCREEN CURSOR" padname cursorpos "2" /*2*/ end /* PF12: Quit without processing any changes on the current page. */ when keyhit = "PFKEY12" then quit = yes when vcurs ^= padname | rcursor = "RESERVED" then /* msi */ errmsg = "Invalid cursor location" otherwise errmsg = keytype keynum "not defined" end end "WINDOW DELETE" padname "VSCREEN DELETE" padname exit UPDATE: /* Write the VSCREEN contents back to the NOTEPAD file */ arg updparm "ERASE" padfile "VSCREEN PUT" padname padfile if updparm ^= "" then do /* queue updparm"#SET LRECL" cols "#SET RECFM F#FILE" */ queue updparm"#COMMAND FILE" "XEDIT" padfile "(NOPROF" end if quit = yes then return "VSCREEN CLEAR" padname /*2*/ "VSCREEN GET" padname padfile "1" vrows "VSCREEN WAITT" padname return GenOpts: Procedure Call Trace 'OFF' arg options parse value options "COLOR TURQ WHITE" with "COLOR" filea border . parse value options "SIZE 20 40" with "SIZE" rows cols . parse value options "PAGES 4" with "PAGES" pages . if rows < 20 then rows = 20 /* Minimum */ if cols > 75 then cols = 75 return "SIZE" rows cols "COLOR" filea border "PAGES" pages