REM >ExpandMenu

PROCtaskwindow

PRINT "Expand BackMenu file"'
PRINT "Shift-Drag files to input their paths if running in a task window"'
INPUT " Input  : "f$
PRINT '"Press Return for """f$+"<"""'
INPUT " Output : "o$:IF o$="" o$=f$+"<"
PRINT

lf$=CHR$10
q$=CHR$34
tab$=STRING$(4," ")
tab2$=STRING$(8," ")
SYS "OS_File",5,f$ TO ,,,,len
DIM mem len
SYS "OS_File",&FF,f$,mem
DIM menu$(256),count(256)
menus=0
duplicates=FALSE
PROCcollate("",0)
SYS "OS_CLI","Create "+o$
throwback=FALSE
IF duplicates THEN
 SYS "XOS_SWINumberFromString",,"DDEUtils_ThrowbackStart" TO ;v
 throwback=(v AND 1)=0
 IF throwback THEN
  DIM canon 256
  SYS "OS_FSControl",37,o$,canon,,,256
  SYS "DDEUtils_ThrowbackStart"
  SYS "DDEUtils_ThrowbackSend",0,,canon
 ENDIF
ENDIF
out=OPENOUT(o$)
ON ERROR: ON ERROR OFF: PRINT REPORT$;" at ";ERL: CLOSE#out: END
out_line=0
PROCbput("|Start "+f$+lf$)
first_menu=TRUE
PROCshow_menu(0)
PROCbput(lf$)
PROCbput("|End"+lf$)
IF throwback SYS "DDEUtils_ThrowbackEnd"
ON ERROR OFF
CLOSE #out
SYS "OS_CLI","SetType "+o$+" Obey"
PRINT'"Done"'
PRINT "You will probably need to edit the file by hand now to"
PRINT "1) Replace %%0 with <MenuText> and %% with % or <37>"
PRINT "   in parameterised Menus"
PRINT "2) Delete key shortcuts from option texts (-key adds"
PRINT "   them for you)"'
END
:
DEF PROCcollate(root$,start)
LOCAL ptr,sub(),s,i,name$
DIM sub(50)
s=0
name$=$(mem+start)
PROCadd_menu(name$)
ptr=mem+start+28
REM PRINT MID$(root$+"."+name$,2)
REPEAT
 last=FNbit(7,!ptr)
 IF ptr!4<>-1 s+=1:sub(s)=ptr!4
 ptr+=24
UNTIL last
IF s>0 THEN
 FOR i=1 TO s
  PROCcollate(root$+"."+name$,sub(i))
 NEXT
ENDIF
ENDPROC
:
DEF PROCshow_menu(start)
LOCAL ptr,a,last,sub(),s,i
DIM sub(50)
s=0
ptr=mem+start
name$=$ptr
PROCbput(lf$)
PROCbput("Menu "+FNquoted(name$))
IF first_menu THEN
  PROCbput(" Pinboard")
  first_menu=FALSE
ENDIF
PROCbput(lf$)
PROCcheck("Duplicated definition of",name$)

title_fg=ptr?12
title_bg=ptr?13
work_fg=ptr?14
work_bg=ptr?15
width=ptr!16
height=ptr!20
gap=ptr!24
a=ptr+28
REPEAT
 tick=FNbit(0,!a)
 line=FNbit(1,!a)
 write=FNbit(2,!a)
 last=FNbit(7,!a)
 sub=a!4
 flags=a!8
 text_bg=(flags>>28) AND 15
 text_fg=(flags>>24) AND 15
 text=mem+a!12
 command=mem+a!16+1 : REM all have a &07 at the start!
 type=a!20-1
 keys=command+LEN$command+1
 keys=keys+LEN$keys
 keys=(keys+1+3)ANDNOT3
 IF sub<>-1 s+=1:sub(s)=sub
 PROCbput(tab$+"Option "+FNquoted($text))

 IF $command<>"" THEN command1$=FNcom($command) ELSE command1$=""
 IF type=0 THEN command2$=FNcom($(command+LEN$command+1)) ELSE command2$=""
 IF command2$="" AND LEFT$(command1$,10)="Filer_Run " AND INSTR(command1$,"|M")=0 AND sub=-1 THEN
   PROCbput(" -path "+MID$(command1$,11))
   command1$=""
 ENDIF

 IF sub<>-1 THEN
  PROCbput(" -sub ")
  sub$=$(mem+sub)
  IF sub$<>$text PROCbput(FNquoted(sub$)) ELSE PROCbput("*")
 ENDIF
 IF sub<>-1 PROCcheck("Call to submenu",sub$)

 FOR i=0 TO 3
  key=keys!(i*4)
  IF key<>&FF THEN
    IF i=0 THEN
      PROCbput(" -key "+FNkey(key))
    ELSE
      PRINT "Can't assign key ";FNkey(key)
    ENDIF
  ENDIF
 NEXT

 IF tick PROCbput(" -tick")
 IF text_bg<>0 OR text_fg<>7 PROCbput(" -bg "+STR$ text_bg+" -fg "+STR$ text_fg)
 IF type>0 PROCbput(" -len "+STR$ type)
 PROCbput(lf$)

 IF command1$<>"" THEN PROCbput(tab2$+"Command "+command1$+lf$)
 IF command2$<>"" THEN PROCbput(tab2$+"Command "+command2$+lf$)

 IF line PROCbput("Dash"+lf$)
 a+=24
UNTIL last
PROCbput("EndMenu"+lf$)
IF s>0 THEN
 FOR i=1 TO s
  PROCshow_menu(sub(i))
 NEXT
ENDIF
ENDPROC
:
DEF PROCbput(o$)
BPUT #out,o$;
IF RIGHT$(o$,1)=lf$ out_line+=1
ENDPROC
:
DEF FNquoted(a$)
  IF INSTR(a$," ") OR a$="" THEN =""""+a$+""""
=a$
:
DEF FNbit(b,n)
=(n AND (1<<b))>0
:
DEF FNkey(key)
 LOCAL m$
 m$=""
 IF key >= &180 AND key <= &1FF THEN
   IF key AND &10 THEN m$+=CHR$139
   IF key AND &20 THEN m$+="^"
   key = key AND NOT &30
 ENDIF
 IF key >= ASC"a" AND key <= ASC"z" THEN key = key - 64

 CASE key OF
   WHEN &01E: =m$+"Home"
   WHEN &01D: =m$+"Return"
   WHEN &01C: =m$+"Backspace"
   WHEN &020: =m$+"Space"
   WHEN &07F: =m$+"Delete"
   WHEN &01B: =m$+"Esc"
   WHEN &180: =m$+"Print"
   WHEN &181: =m$+"F1"
   WHEN &182: =m$+"F2"
   WHEN &183: =m$+"F3"
   WHEN &184: =m$+"F4"
   WHEN &185: =m$+"F5"
   WHEN &186: =m$+"F6"
   WHEN &187: =m$+"F7"
   WHEN &188: =m$+"F8"
   WHEN &189: =m$+"F9"
   WHEN &18A: =m$+"Tab"
   WHEN &18B: =m$+"Copy"
   WHEN &18C: =m$+"Left"
   WHEN &18D: =m$+"Right"
   WHEN &18E: =m$+"Down"
   WHEN &18F: =m$+"Up"
   WHEN &1CA: =m$+"F10"
   WHEN &1CB: =m$+"F11"
   WHEN &1CC: =m$+"F12"
   WHEN &1CD: =m$+"Insert"
   OTHERWISE:
     IF (key >= 33 AND key <= 126) OR (key >= 128 AND key <= 255) THEN
       =CHR$(k)
     ELSE
       IF key >= 0 AND key <= 31
         ="^"+CHR$(key + 64)
       ENDIF
     ENDIF
 ENDCASE
 PRINT "Unknown key &";~key
=""
:
DEF FNcom(c$)
LOCAL o$,i
o$=""
REPEAT
 i=INSTR(c$,"%")
 IF i=0 THEN
  o$+=c$
 ELSE
  o$+=LEFT$(c$,i)+"%"
  c$=MID$(c$,i+1)
 ENDIF
UNTIL i=0
=o$
:
DEF PROCadd_menu(n$)
LOCAL i
i=0
WHILE i<menus AND n$<>menu$(i)
 i+=1
ENDWHILE
IF n$<>menu$(i) menu$(i)=n$:menus+=1 ELSE duplicates=TRUE
count(i)+=1
ENDPROC
:
DEF PROCcheck(err$,n$)
LOCAL i
i=0
WHILE i<menus AND menu$(i)<>n$
 i+=1
ENDWHILE
IF count(i)>1 THEN
 IF throwback THEN
  SYS "DDEUtils_ThrowbackSend",1,,canon,out_line,0,err$+" "+n$+""
 ELSE
  PRINT err$+" "+n$+" at line ";out_line
 ENDIF
ENDIF
ENDPROC
:
DEF PROCtaskwindow
DIM buf 256
SYS "OS_GetEnv" TO env$
SYS "XOS_ReadArgs","quit/k,task/S,,,,,",env$,buf,256 TO ;v
IF v AND 1 ENDPROC
IF !buf<>0 THEN
 n$="":i=!buf:WHILE ?i>31:n$+=CHR$?i:i+=1:ENDWHILE
 l$="":i=LEN n$:WHILE MID$(n$,i,1)<>".":l$=MID$(n$,i,1)+l$:i-=1:ENDWHILE
 IF buf!4=0 SYS "OS_CLI","TaskWindow -quit -name "+l$+" ""Run "+n$+" -task"""
ENDIF
ENDPROC
