home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / tagbet.zip / CONFIG.CMD next >
OS/2 REXX Batch file  |  1995-03-12  |  22KB  |  750 lines

  1. /* OffTag tagger.cfg Configuration Program                            */
  2.  
  3. /*Constants*/
  4.  
  5. /*Color Values*/
  6. BLACK  =0
  7. RED    =1
  8. GREEN  =2
  9. BROWN  =3
  10. BLUE   =4
  11. MAGENTA=5
  12. CYAN   =6
  13. LIGHTGRAY   =7
  14. DARKGRAY    =8
  15. LIGHTRED    =9
  16. LIGHTGREEN  =10
  17. YELLOW      =11
  18. LIGHTBLUE   =12
  19. LIGHTMAGENTA=13
  20. LIGHTCYAN   =14
  21. WHITE       =15
  22.  
  23. collist="BLACK RED GREEN BROWN BLUE MAGENTA CYAN LIGHTGRAY DARKGRAY "
  24. collist=collist"LIGHTRED LIGHTGREEN YELLOW LIGHTBLUE LIGHTMAGENTA LIGHTCYAN "
  25. collist=collist"WHITE "
  26.  
  27. syscols="BLACK BLUE GREEN CYAN RED MAGENTA BROWN LIGHTGRAY DARKGRAY "
  28. syscols=syscols" LIGHTBLUE LIGHTGREEN LIGHTCYAN LIGHTRED LIGHMAGENTA YELLOW WHITE "
  29.  
  30. /*ANSI Codes*/
  31. CLREOL=D2C(27)"[K"
  32. CLRSCR=D2C(27)"[2J"
  33. CRLF=D2C(13)D2C(10)
  34.  
  35. /*Keyboard Codes*/
  36. UP_KEY   =D2C(0)D2C(72)
  37. DOWN_KEY =D2C(0)D2C(80)
  38. LEFT_KEY =D2C(0)D2C(75)
  39. RIGHT_KEY=D2C(0)D2C(77)
  40. HOME_KEY =D2C(0)D2C(71)
  41. END_KEY  =D2C(0)D2C(79)
  42. PGUP_KEY =D2C(0)D2C(73)
  43. PGDN_KEY =D2C(0)D2C(81)
  44. INS_KEY  =D2C(0)D2C(82)
  45. DEL_KEY  =D2C(0)D2C(83)
  46. F1_KEY   =D2C(0)D2C(59)
  47. F2_KEY   =D2C(0)D2C(60)
  48. F3_KEY   =D2C(0)D2C(61)
  49. F4_KEY   =D2C(0)D2C(62)
  50. F5_KEY   =D2C(0)D2C(63)
  51. F6_KEY   =D2C(0)D2C(64)
  52. F7_KEY   =D2C(0)D2C(65)
  53. F8_KEY   =D2C(0)D2C(66)
  54. F9_KEY   =D2C(0)D2C(67)
  55. F10_KEY  =D2C(0)D2C(68)
  56. ALTX_KEY =D2C(0)D2C(45)
  57. STAB_KEY =D2C(0)D2C(15)
  58. CR=D2C(13)
  59. ESC=D2C(27)
  60. TAB=D2C(9)
  61. BS=D2C(8)
  62.  
  63. /*Global Variables*/
  64. lastkey=""
  65. winx1=0
  66. winy1=0
  67. winx2=79
  68. winy2=24
  69. EditHigh=21
  70. Foreground=LIGHTGRAY
  71. Background=BLACK
  72. datafile="confinfo.dat"
  73. taggercfg="tagger.cfg"
  74. taggercfgnew="tagger.cf$"
  75. sections="PARAMETERS FILEPATHS COLORS MISCELLANEOUS SPEEDADAPT PROTOCOLS FILEMANAGER EXTERNAL"
  76. /*Exposure list for global variables/constants*/
  77.  
  78. globals="lastkey winx1 winy1 winx2 winy2 Foreground Background "
  79. globals=globals"datafile CInfo. EditHigh Sections "
  80.  
  81. globals=globals"CLREOL CLRSCR CRLF "collist" syscols collist taggercfg taggercfgnew "
  82.  
  83. globals=globals"UP_KEY DOWN_KEY LEFT_KEY RIGHT_KEY HOME_KEY END_KEY "
  84. globals=globals"PGUP_KEY PGDN_KEY INS_KEY DEL_KEY F1_KEY F2_KEY F3_KEY "
  85. globals=globals"F4_KEY F5_KEY F6_KEY F7_KEY F8_KEY F9_KEY F10_KEY "
  86. globals=globals"ALTX_KEY STAB_KEY CR ESC TAB BS "
  87.  
  88.  
  89.  
  90. call RxFuncAdd "SysFileTree", "RexxUtil", "SysFileTree"
  91. call RxFuncAdd "SysCurPos", "RexxUtil", "SysCurPos"
  92. call RxFuncAdd "SysGetKey", "RexxUtil", "SysGetKey"
  93.  
  94.  
  95. sections="PARAMETERS FILEPATHS COLORS MISCELLANEOUS SPEEDADAPT PROTOCOLS FILEMANAGER EXTERNAL"
  96. men.values=sections
  97. men.0=4
  98. men.1="Parameters"
  99. men.Info.1="permanently used run-time parameters"
  100. men.2="Filepaths"
  101. men.Info.2="locations and names of used files"
  102. men.3="Colors"
  103. men.Info.3="colors of Tagger-display"
  104. men.4="Miscellaneous"
  105. men.Info.4="limits,formats,etc."
  106. men.5="SpeedAdapt"
  107. men.Info.5="how the Tagger-display adapts to BPS-rates"
  108. men.6="Protocols"
  109. men.Info.6="download-protocol menu and actions"
  110. men.7="Filemanager"
  111. men.Info.7="settings for the Filemanager-mode"
  112. men.8="External"
  113. men.Info.8="external per-file programs/scripts, archive-viewer, vircheck, touch, etc."
  114.  
  115. rc=InitCInfo()
  116. rc=ReadConfig()
  117.  
  118. do until lastkey<>ESC
  119.   lastkey=""
  120.   do until lastkey=ESC
  121.     rc=Charout(,SetColor(Black,LightGray)CLRSCR""SetColor(Red,LightGray))
  122.     say "  ╓─────┐          ┌──╥──┐            ─╖    ─╖    ╓─────┐ "
  123.     say "  ║     │             ║                ║     ║    ║       "
  124.     say "  ║     │ ╥──┐ ╥──┐   ║    ╓──┐ ╓──┐   ║     ║    ╙─────┐ ╥──┐ ╓─╥─┐ ╥  ┬ ╥──┐"
  125.     say "  ║     │ ╟─   ╟─     ║    ╟──┤ ║ ─┐   ║     ║          │ ╟─     ║   ║  │ ╟──┘"
  126.     say "  ╙─────┘ ╨    ╨      ╨    ╨  ┴ ╙──┘  ─╨─ o ─╨─   ╙─────┘ ╨──┘   ╨   ╙──┘ ╨   "
  127.  
  128.     rc=Charout(,At(1,22)SetColor(Blue,LightGray)"look here for specific info ───────────┐")
  129.     rc=Charout(,At(40,23)"")
  130.     rc=Charout(,At(70,23)SetColor(DarkGray,LightGray)"(pure REXX)")
  131.     Sec=VerMenu("Select the section to configure:",1,White,Blue)
  132.     if lastkey<>ESC then do
  133.       rc=EditSection(Sec)
  134.       lastkey=""
  135.     end  
  136.   end  
  137.   rc=Charout(,SetColor(Black,LightGray)CLRSCR)
  138.   SaveIt=Decision("Save Configuration ?","Save  Forget", "Save", White, Blue )
  139. end
  140. if SaveIt="Save" then do
  141.   rc=WriteConfig()
  142.   say SetColor(White,Black)CLRSCR""At(1,3)"Configuration saved in Tagger.CFG"
  143. end
  144. else  
  145.   say SetColor(White,Black)CLRSCR""At(1,3)"Configuration NOT saved."
  146.  
  147. Exit
  148. /*********************************************************************/
  149.  
  150. /*Init the Field-Info Structure*/
  151.  
  152. InitCInfo:
  153.   do while lines(datafile)
  154.     line=linein(datafile)
  155. /*    trace intermediate*/
  156.     parse upper value line with Sec "|"
  157.     if Sec<>";" & Sec<>"" then do
  158.       if(Symbol("Cinfo.Sec.Num")="LIT") then do
  159.         Cinfo.Sec.Num=0
  160.         CInfo.Sec.Idx=""
  161.       end  
  162.       Cinfo.Sec.Num=Cinfo.Sec.Num+1
  163.       count=Cinfo.Sec.Num  
  164.       parse value line with name "|" CInfo.Sec.Token.count "|" CInfo.Sec.Type.count "|" CInfo.Sec.Default.count "|" CInfo.Sec.Info.count "|" CInfo.Sec.Help.count
  165.  
  166.       CInfo.Sec.Idx=CInfo.Sec.Idx""CInfo.Sec.Token.count" "
  167.  
  168.       CInfo.Sec.Value.count=CInfo.Sec.Default.count
  169.       CInfo.Sec.Active.count=0
  170. /*      say CInfo.Sec.Info.count*/
  171.     end
  172.   end
  173.   rc=lineout(datafile)  
  174.   return count<>0
  175.  
  176. WriteConfig: Procedure Expose (globals)
  177.   "@if exist "taggercfgnew" del "taggercfgnew
  178.   sec=""
  179.   do while lines(taggercfg)
  180.     orgline=linein(taggercfg)
  181.     line=Strip(orgline)
  182.     if substr(line,1,1)<>";" & line<>"" then do
  183.       Keyword=Translate(word(line,1))
  184.       if sec="" then do   /*no active Section -> Section starting ?*/
  185.         If WordPos(Keyword,sections)>0 then do
  186.           sec=Keyword
  187.           rc=lineout(taggercfgnew,orgline)
  188.         end  
  189.       end
  190.       else do  /*active Section -> Section Ending ?*/
  191.         if Keyword="END" then do
  192.           If Symbol("Cinfo.Sec.Num")<>"LIT" then
  193.             do c=1 to CInfo.Sec.Num /*Write new Keywords before End*/
  194.               if CInfo.Sec.Active.c=1 then 
  195.                 rc=lineout(taggercfgnew,"  "Left(Cinfo.Sec.Token.c,18)" "CInfo.Sec.Value.c)
  196.             end
  197.           rc=lineout(taggercfgnew,orgline)
  198.           sec=""
  199.         end  
  200.         else do
  201.           c=WordPos(Keyword,CInfo.Sec.Idx)  /*known Keyword ?*/         
  202.           If c>0 then do
  203.             if CInfo.Sec.Active.c=1 then do
  204.               CInfo.Sec.Active.c=0 /*Set inactive and write Keyw+Value*/
  205.               rc=lineout(taggercfgnew,"  "Left(word(line,1),18)" "CInfo.Sec.Value.c)
  206.             end  
  207.           end
  208.           else rc=lineout(taggercfgnew,orgline) /*write unknown keyword back ??*/
  209.         end  
  210.       end
  211.     end
  212.     else 
  213.       rc=lineout(taggercfgnew,orgline)
  214.   end  
  215.   rc=lineout(taggercfgnew)
  216.   rc=lineout(taggercfg)
  217.   "@del "taggercfg
  218.   "@ren "taggercfgnew" "taggercfg
  219.   return 0
  220.   
  221. ReadConfig: Procedure Expose (globals)
  222.   sec=""
  223.   do while lines(taggercfg)
  224.     line=Strip(linein(taggercfg))
  225.     if substr(line,1,1)<>";" & line<>"" then do
  226.       Keyword=Translate(word(line,1))
  227.       if sec="" then do   /*no active Section -> Section starting ?*/
  228.         If WordPos(Keyword,sections)>0 then
  229.           sec=Keyword
  230.       end
  231.       else do  /*active Section -> Section Ending ?*/
  232.         if Keyword="END" then 
  233.           sec=""
  234.         c=WordPos(Keyword,CInfo.Sec.Idx)  /*known Keyword ?*/
  235.         If c>0 then do
  236.           CInfo.Sec.Active.c=1 /*Set active and read value*/
  237.           If length(Word(line,2))>0 then do
  238.             CInfo.Sec.Value.c=SubStr(line,WordIndex(line,2),length(line)-WordIndex(line,2)+1)
  239.  
  240.             if Sec="COLORS" then do  /*still Number ? -> convert*/
  241.               if Datatype(CInfo.Sec.Value.c,"N") then do
  242.                 myfore=CInfo.Sec.Value.c // 16
  243.                 myback=(CInfo.Sec.Value.c-myfore) %  16
  244.                 CInfo.Sec.Value.c=word(syscols,myfore+1)" ON "word(syscols,myback+1)
  245.               end
  246.             end
  247.  
  248.           end
  249.           else
  250.             CInfo.Sec.Value.c=""  
  251.         end
  252.       end
  253.     end
  254.   end  
  255.   rc=lineout(taggercfg)
  256.   return 0
  257.   
  258. /*********************************************************************/
  259.  
  260. EditSection: Procedure Expose (globals)
  261.   parse arg sec
  262.  
  263.   rebuild=1
  264.   top=0
  265.   line=1
  266.   lastkey=""
  267.   win=SaveWinCoords()
  268.   rc=Frame(" "Sec" Section ",1,1,80,23,LightCyan,Blue)
  269.   do until lastkey=ESC
  270.     if rebuild=1 then do
  271.       rc=ShowSection(sec,top)
  272.       rebuild=0
  273.     end
  274.     rebuild=EditField(sec,top+line,line)
  275.     c=top+line
  276.     select
  277.       when length(lastkey)=1 & lastkey=" " then do
  278.         if CInfo.Sec.Active.c=1 then
  279.           CInfo.Sec.Active.c=0
  280.         else
  281.           CInfo.Sec.Active.c=1
  282.         rc=ShowField(Sec,c,line)
  283.       end  
  284.       when lastkey=DOWN_KEY then
  285.         if top+line<CInfo.Sec.Num then do       
  286.           line=line+1
  287.           if line>EditHigh then do
  288.             line=1
  289.             top=top+EditHigh
  290.             rebuild=1
  291.           end
  292.         end  
  293.       when lastkey=UP_KEY then
  294.         if top+line>1 then do       
  295.           line=line-1
  296.           if line<=0 then do
  297.             line=EditHigh
  298.             top=top-EditHigh
  299.             rebuild=1
  300.           end
  301.         end  
  302.       when lastkey=PGUP_KEY then
  303.         if top>0 then do
  304.           top=top-EditHigh
  305.           rebuild=1
  306.         end
  307.         else line=1
  308.       when lastkey=PGDN_KEY then
  309.         if top+EditHigh<=CInfo.Sec.Num then do
  310.           top=top+EditHigh
  311.           if top+line>CInfo.Sec.Num then
  312.             line=CInfo.Sec.Num-Top
  313.           rebuild=1
  314.         end          
  315.         else line=CInfo.Sec.Num-Top
  316.             
  317.       Otherwise  
  318.     end  
  319.   end
  320.   rc=RestoreWinCoords(win)
  321.   return 0
  322.  
  323. ShowSection: Procedure Expose (globals)
  324.   parse arg sec,top
  325.   
  326.   do i=1 to EditHigh
  327.     if top+i<=CInfo.Sec.Num then
  328.       rc=ShowField(sec,top+i,i)
  329.     else do
  330.       rc=CharOut(,at(1,i)SetColor(LightCyan,Blue))
  331.       rc=SpaceEol()
  332.     end  
  333.   end
  334.   return 0
  335.  
  336. /*Show Fieldtext and Value*/
  337. ShowField: Procedure Expose (globals)
  338.   parse arg sec,c,line
  339.   
  340.   if CInfo.Sec.Active.c=1 then do
  341.     rc=CharOut(,At(1,line)SetColor(LightCyan,Blue)" "Left(CInfo.Sec.Info.c,21)"  ")
  342.     rc=SpaceEol()
  343.     rc=ShowFieldValue(CInfo.Sec.Type.c,CInfo.Sec.Value.c,1,line)
  344.   end
  345.   else do  
  346.     rc=CharOut(,At(1,line)SetColor(DarkGray,Blue)"("Left(CInfo.Sec.Info.c,21)") ")
  347.     rc=SpaceEol()
  348.     rc=ShowFieldValue(CInfo.Sec.Type.c,CInfo.Sec.Default.c,0,line)
  349.   end  
  350.   return 0
  351.  
  352. /*Display Fieldvalue, depending on Type*/  
  353. ShowFieldValue: Procedure Expose (globals)
  354.   parse arg type,val,active,line
  355.   
  356.   rc=Charout(,at(25,line))
  357.   Select
  358.     when type="C" then do/*Color*/
  359.       rc=CharOut(,SetColorFromString(val)"XXXXXXX")
  360.     end
  361.     when type="F" then do/*Flag*/
  362.       rc=CharOut(,SetColor(White,Blue))
  363.       if Active=1 then
  364.         rc=CharOut(,"ON ")
  365.       else
  366.         rc=CharOut(,"OFF")
  367.     end
  368.     when Substr(type,1,1)="S" then do /*String+Length*/
  369.       len=substr(type,2,length(type)-1)
  370.       rc=CharOut(,SetColor(Black,Cyan)Left(val,len))
  371.     end
  372.     when Substr(type,1,1)="N" then do /*String+Length*/
  373.       len=substr(type,2,length(type)-1)
  374.       rc=CharOut(,SetColor(Black,Cyan)Right(val,len))
  375.     end
  376.     Otherwise
  377.   end
  378.   return 0
  379.  
  380. /*Edits a given field, Returns 1 if Screen has to be rebuilt*/
  381. EditField: Procedure Expose (globals)
  382.   parse arg sec,c,line
  383.   
  384.   rc=helpline("Select Field:   Pg Pg │ Set Value with <┘ | ON/OFF = SPACE │ Abort = ESC")
  385.   rebuild=0
  386.   rc=InfoLine(CInfo.Sec.Help.c)
  387.   Select
  388.     when CInfo.Sec.Type.c="C" then do
  389.       rc=CharOut(,at(25,line)) /*Position Cursor*/
  390.       key=GetKey()
  391.       if key=CR then do
  392.         win=SaveWinCoords()
  393.         CInfo.Sec.Value.c=EditColor(CInfo.Sec.Value.c)
  394.         rc=RestoreWinCoords(win)
  395.  
  396. /*        rc=CharOut(,SetColor(White,Black))
  397.         trace intermediate*/
  398.         
  399.         CInfo.Sec.Active.c=1       
  400.         rc=ShowField(sec,c,line)
  401.         lastkey=""
  402.       end  
  403.     end
  404.     when CInfo.Sec.Type.c="F" then do
  405.       rc=CharOut(,at(25,line)) /*Position Cursor*/
  406.       key=GetKey()
  407.       if key=CR then do
  408.         if CInfo.Sec.Active.c=1 then
  409.           CInfo.Sec.Active.c=0
  410.         else
  411.           CInfo.Sec.Active.c=1
  412.         rc=ShowField(sec,c,line)
  413.         lastkey=""
  414.       end  
  415.     end
  416.     when Substr(CInfo.Sec.Type.c,1,1)="S" | Substr(CInfo.Sec.Type.c,1,1)="N"  then do
  417.       rc=CharOut(,at(25,line)) /*Position Cursor*/
  418.       key=GetKey()
  419.       if key=CR then do
  420.         len=substr(CInfo.Sec.Type.c,2,length(CInfo.Sec.Type.c)-1)
  421.         If Substr(CInfo.Sec.Type.c,1,1)="N" then
  422.           CInfo.Sec.Value.c=InputNumber(CInfo.Sec.Value.c,25,line,len,White,Red)
  423.         else
  424.           CInfo.Sec.Value.c=Input(CInfo.Sec.Value.c,25,line,len,White,Red)
  425.         CInfo.Sec.Active.c=1       
  426.         rc=ShowField(sec,c,line)
  427.         lastkey=""
  428.       end  
  429.     end  
  430.     Otherwise
  431.   end
  432.   return rebuild    
  433.  
  434.  
  435. EditColor: Procedure Expose (globals)
  436.   parse upper arg fore "ON" back
  437.   
  438.   rc=Helpline("Select Color with "D2C(17)" "D2C(16)" "D2C(24)" "D2C(25)" │ Save with <┘ | Abort with ESC")
  439.   rc=frame("Set Color",39,6,60,15,Black,LightGray)
  440.   do yp=0 to 7
  441.     line=at(3,yp+1)
  442.     do xp=0 to 15
  443.       line=line""SetColor(xp,yp)"X"
  444.     end
  445.     rc=CharOut(,line)
  446.   end
  447.   
  448.   xp=WordPos(fore,collist)-1
  449.   if xp<0 then xp=0
  450.   yp=WordPos(back,collist)-1
  451.   if yp<0 then yp=0
  452.   key=""
  453.   do until key=CR | key=ESC
  454.     cx=xp+2
  455.     cy=yp+1
  456.     rc=Charout(,SetColor(Black,Cyan)at(cx,cy)">"at(cx+2,cy)"<")
  457.     key=GetKey()
  458.     if xp-1>=0 then
  459.       rc=CharOut(,at(cx,cy)SetColor(xp-1,yp)"X")
  460.     else
  461.       rc=CharOut(,at(cx,cy)SetColor(Black,LightGray)" ")
  462.       
  463.     if xp+1<=15 then
  464.       rc=CharOut(,at(cx+2,cy)SetColor(xp+1,yp)"X")
  465.     else
  466.       rc=CharOut(,at(cx+2,cy)SetColor(Black,LightGray)" ")
  467.     
  468.     select
  469.       when key=UP_KEY then
  470.         if yp>0 then yp=yp-1
  471.       when key=DOWN_KEY then
  472.         if yp<7 then yp=yp+1
  473.       when key=LEFT_KEY then
  474.         if xp>0 then xp=xp-1
  475.       when key=RIGHT_KEY then
  476.         if xp<15 then xp=xp+1
  477.       otherwise
  478.     end  
  479.   end
  480.   rc=frame("",39,6,60,15,Blue,Blue)
  481.   if key=CR then
  482.     return Word(Collist,xp+1)" ON "Word(Collist,yp+1)
  483.   else
  484.     return fore" ON "back  
  485.   
  486. SetColorFromString: Procedure Expose (globals)
  487. /*  parse upper arg fore "ON" back*/
  488.   parse arg color
  489.   
  490.   fore=Translate(word(color,1))
  491.   back=Translate(word(color,3))
  492.   return SetColor(WordPos(fore,collist)-1,WordPos(back,collist)-1)
  493.  
  494.  
  495. /***************************************************************************/
  496. /* Console I/O handling: */
  497.  
  498. /*Update the 2nd lowest Line*/
  499. Infoline: Procedure Expose (globals)
  500.   parse arg str
  501.   
  502.   win=SaveWinCoords()
  503.   fore=Foreground
  504.   back=Background
  505.   rc=Window(1,24,80,24)
  506.   rc=Charout(,at(1,1)SetColor(White,Black)ClrEol)
  507.   rc=Charout(,at(Centerx(str),1)str)
  508.   rc=RestoreWinCoords(win)
  509.   rc=Charout(,SetColor(fore,back))
  510.   return 0
  511.  
  512. /*Updates the lowest Line*/
  513. Helpline: Procedure Expose (globals)
  514.   parse arg str
  515.   
  516.   win=SaveWinCoords()
  517.   y2=winy2
  518.   fore=Foreground
  519.   back=Background
  520.   rc=Window(1,25,80,25)
  521.   rc=Charout(,at(1,1)SetColor(Black,Cyan)ClrEol)
  522.   rc=Charout(,at(Centerx(str),1)str)
  523.   rc=RestoreWinCoords(win)
  524.   rc=Charout(,SetColor(fore,back))
  525.   return 0
  526.  
  527. SaveWinCoords:
  528.   return winx1+1" "winy1+1" "winx2+1" "winy2+1
  529.   
  530. RestoreWinCoords:
  531.   rc=Window(Word(arg(1),1),Word(arg(1),2),Word(arg(1),3),Word(arg(1),4))
  532.   return 0
  533.  
  534. VerMenu: Procedure Expose (globals) men.
  535.   parse arg title,cItem,Fore,Back 
  536.  
  537.   win=SaveWinCoords()
  538.   line=WordPos(cItem,men.values)
  539.   if line=0 then line=1
  540.   rc=Helpline("Choose with "D2C(24)" "D2C(25)" │ Select with <┘ | Abort with ESC")
  541.   width=length(title)
  542.   do i=1 to Men.0
  543.     if length(Men.i)>width then
  544.       width=length(Men.i)
  545.   end    
  546.   width=width+5
  547.   rc=Frame(title,CenterX(left("",width)),11-(Men.0 % 2),CenterX(Left("",width))+width-1,11-(Men.0 %2)+Men.0+3,Fore,Back)
  548.   do i=1 to Men.0
  549.     rc=Charout(,At(CenterX(Men.i),i+1)Men.i)
  550.   end  
  551.   lastkey="" 
  552.   do until lastkey=CR | lastkey=ESC
  553.     rc=InfoLine(men.Info.line)
  554.     rc=Charout(,At(2,line+1)SetColor(Black,Cyan)Left("",width-5)At(CenterX(Men.line),line+1)Men.line)
  555.     key=GetKey()
  556.     rc=Charout(,At(2,line+1)SetColor(Fore,Back)Left("",width-5)At(CenterX(Men.line),line+1)Men.line) 
  557.     select
  558.       when key=DOWN_KEY then
  559.         if line<men.0 then
  560.           line=line+1
  561.         else
  562.           line=1
  563.       when key=UP_KEY then
  564.         if line>1 then
  565.           line=line-1
  566.         else
  567.            line=men.0
  568.       Otherwise
  569.     end           
  570.   end  
  571.   rc=RestoreWinCoords(win)
  572.   if lastkey=CR then
  573.     return Word(men.Values,line)
  574.   else
  575.     return cItem
  576.  
  577. /* Displays a Framed window with a horizontal Menu*/
  578. Decision: Procedure Expose (globals)
  579.   parse arg title,Items,cItem,Fore,Back 
  580.  
  581.   win=SaveWinCoords()
  582.   rc=Helpline("Choose with "D2C(17)" "D2C(16)" │ Select with <┘ | Abort with ESC")
  583.   width=length(Title)
  584.   if length(Items)>width then
  585.     width=length(Items)
  586.   width=width+6
  587.   width=Left("",width)
  588.   rc=Frame(title,CenterX(width),10,CenterX(width)+length(width)-1,14,Fore,Back)
  589.   lastkey=""
  590.   do until lastkey=CR | lastkey=ESC
  591.    cItem=HorMenu(Items,cItem,CenterX(Items),2)
  592.   end  
  593.   rc=RestoreWinCoords(win)
  594.   return cItem
  595.  
  596. /*gibt die Anzahl der Spaces zurueck, die das Bild bis zum rechten Fenster auffuellen*/
  597. SpaceEol: Procedure Expose(globals)
  598.  
  599.   parse value SysCurPos() with ypos xpos
  600.   rc=CharOut(,Left("",winx2-xpos+1," "))
  601.   return 0
  602.  
  603. /*returns the xpos for the string to be placed centered in the window*/
  604. CenterX: Procedure Expose (globals)
  605.   parse arg str
  606.   
  607.   len=length(str)
  608.   r=(winx2-winx1+1) % 2 - (len % 2) + 1
  609.   if r<1 then
  610.     return 1
  611.   else
  612.     return r   
  613.  
  614. /*Horizontal Menu, returns the selected string or ""*/
  615. HorMenu: Procedure Expose (globals)
  616.   parse arg Items,cItem,x1,y1
  617.   
  618.   if cItem="" then 
  619.     choice=1
  620.   else
  621.     choice=WordPos(cItem" ",Items)
  622.   oldfore=Foreground
  623.   oldback=Background 
  624.   rc=Helpline("Move: HOME END "D2C(17)" "D2C(16)" │ Ok =  <┘   | Abort = ESC")
  625.   do until key=CR | key=ESC | key=UP_KEY | key=DOWN_KEY | key=TAB | key=STAB_KEY
  626.     rc=CharOut(,SetColor(oldfore,oldback)at(x1,y1)" "Items" ")
  627.     rc=CharOut(,SetColor(BLACK,CYAN)at(x1+WordIndex(Items,Choice)-1,y1)" "Word(Items,Choice)" ")
  628.     key=GetKey()
  629.     Select
  630.       when Key=LEFT_KEY then
  631.         if choice>1 then
  632.           choice=choice-1
  633.         else
  634.           choice=words(Items)
  635.       when Key=RIGHT_KEY then
  636.         if choice<words(Items) then
  637.           choice=choice+1
  638.         else
  639.           choice=1
  640.       Otherwise
  641.     end   
  642.   end
  643.   rc=CharOut(,SetColor(oldfore,oldback))
  644.   if Key=ESC then
  645.     return ""
  646.   else
  647.     return Word(Items,choice)
  648. end
  649.  
  650. /*Gets a Keycode (also extended), lastkey is global*/
  651. GetKey: Procedure Expose (globals)
  652.   lastkey=SysGetKey("NOECHO")
  653.   if lastkey=X2C("E0") then
  654.     lastkey=D2C(0)
  655.   if lastkey=D2C(0) then
  656.     lastkey=lastkey""SysGetKey("NOECHO")
  657.   return lastkey
  658.  
  659. /*Input a string*/
  660. Input: procedure Expose (globals)
  661.   parse arg fval,x1,y1,len,fore,back
  662.   return InputAll(fval,x1,y1,len,fore,back,"N")
  663.  
  664. /*Input a number*/
  665. InputNumber: procedure Expose (globals)
  666.   parse arg fval,x1,y1,len,fore,back
  667.   return InputAll(fval,x1,y1,len,fore,back,"J")
  668.  
  669. InputAll: procedure Expose (globals)
  670.   parse arg fval,x1,y1,len,fore,back,numbers
  671.   orgfval=fval
  672.   epos=length(fval)
  673.   rc=CharOut(,SetColor(fore,back))
  674.   key=""
  675.   do until key=CR | key=ESC | key=TAB | key=STAB_KEY | key=UP_KEY | key=DOWN_KEY
  676.     rc=Charout(,At(x1,y1)Left(fval,len," ")At(x1+epos,y1))
  677.     key=GetKey()
  678.     Select
  679.       when length(key)=1 & C2D(Key)>=32 & C2D(Key)<=255 then
  680.         if numbers="N" | (key>='0' & key<='9') then
  681.           if length(fval)<len & epos<len then do
  682.             fval=Insert(key,fval,epos)
  683.             epos=epos+1
  684.           end
  685.       when Key=BS then
  686.         if epos>0 then do
  687.           epos=epos-1
  688.           fval=DelStr(fval,epos+1,1)
  689.         end  
  690.       when Key=DEL_KEY then
  691.         fval=DelStr(fval,epos+1,1)
  692.       when Key=LEFT_KEY then
  693.         if epos>0 then epos=epos-1        
  694.       when Key=RIGHT_KEY then
  695.         if (numbers="N" & epos<len) | epos<length(fval) then epos=epos+1
  696.       when Key=END_KEY then
  697.         epos=length(fval)
  698.       when Key=HOME_KEY then
  699.         epos=0    
  700.       Otherwise
  701.     end    
  702.   end
  703.   trace off
  704.   if key<>ESC then
  705.     return fval
  706.   else
  707.     return orgfval
  708.  
  709. /*Set window coordinates for relative at()-command*/
  710. Window: Procedure Expose (Globals)
  711.   parse arg x1,y1,x2,y2
  712.   winx1=x1-1
  713.   winy1=y1-1
  714.   winx2=x2-1
  715.   winy2=y2-1
  716.   return 0
  717.     
  718. /*draw frame, fill it with the color and set the window-coords*/
  719. Frame: procedure Expose (globals)
  720.   parse arg title,x1,y1,x2,y2,fore,back 
  721.   rc=window(1,1,80,25)
  722.   rc=CharOut(,at(x1,y1)SetColor(fore,back)"┌"left("",x2-x1-1,"─")"┐");
  723.   i=y1+1
  724.   do while i<y2
  725.     rc=CharOut(,at(x1,i)"│"left("",x2-x1-1," ")"│")
  726.     i=i+1
  727.   end
  728.   rc=CharOut(,at(x1,y2)"└"left("",x2-x1-1,"─")"┘");
  729.   rc=Window(x1+1,y1+1,x2-1,y2-1)
  730.   rc=CharOut(,at(Centerx(title),0)title""at(1,1))
  731. return 0
  732.  
  733. /*returns an ansi-string which sets a color*/
  734. SetColor: procedure Expose (globals)
  735.   parse arg Fore,Back
  736.   Foreground=Fore
  737.   Background=Back
  738.   if Back<0 then Back=0
  739.   if Fore<0 then Fore=0
  740.   if Fore>7 then 
  741.     return D2C(27)"[1;"Fore+22";"Back+40"m"
  742.   else 
  743.     return D2C(27)"[0;"Fore+30";"Back+40"m"
  744.  
  745. /*returns an ansi-string which positions the cursor*/
  746. At: procedure Expose (globals)
  747.   parse arg xpos,ypos
  748.   return D2C(27)"["ypos+winy1";"xpos+winx1"H"
  749.  
  750.