1 | TMGIOUTL ;TMG/kst/IO Utilities -- File browser ;05/16/09
|
---|
2 | ;;1.0;TMG-LIB;**1**;05/16/09
|
---|
3 |
|
---|
4 | ;"TMG IO UTILITIES
|
---|
5 | ;"Kevin Toppenberg MD
|
---|
6 | ;"GNU General Public License (GPL) applies
|
---|
7 | ;"5/16/09
|
---|
8 |
|
---|
9 | ;"=======================================================================
|
---|
10 | ;" API -- Public Functions.
|
---|
11 | ;"=======================================================================
|
---|
12 | ;"FBrowse(Option,OutPath,OutName) query the user to select a filename
|
---|
13 |
|
---|
14 | ;"=======================================================================
|
---|
15 | ;"Private API calls
|
---|
16 | ;"=======================================================================
|
---|
17 | ;"LoadDir(pArray,curDir,TMGMask,Option) -- load curDir entries into pArray
|
---|
18 | ;"HndOnSel(pArray,Option,Info) -- handle ON SELECT event from Scroller
|
---|
19 | ;"HndlOnCmd(pArray,Option,Info) -- handle ON SELECT event from Scroller
|
---|
20 | ;"ShowHelp -- show help for file browser
|
---|
21 |
|
---|
22 | ;"=======================================================================
|
---|
23 |
|
---|
24 | test
|
---|
25 | new option
|
---|
26 | set option("MSG")="Hello there!"
|
---|
27 | set option("PATH")="/home/kdt0p"
|
---|
28 | set option("SELECT DIR")=0
|
---|
29 | write $$FBrowse(.option)
|
---|
30 | quit
|
---|
31 |
|
---|
32 | FBrowse(Option,OutPath,OutName)
|
---|
33 | ;"SCOPE: PUBLIC
|
---|
34 | ;"Purpose: To query the user, to get a filename back
|
---|
35 | ;" Supplies optional directory listing.
|
---|
36 | ;"Input: Option [OPTIONAL]. Format as follows. All entries are optional
|
---|
37 | ;" Option("MSG") A message to show user prior to name prompt.
|
---|
38 | ;" May contain "\n" character for line wrapping.
|
---|
39 | ;" Option("PATH") Initial default path
|
---|
40 | ;" Option("NAME") Initial default filename
|
---|
41 | ;" Option("NodeDiv") The character that separates folders (e.g. "/")
|
---|
42 | ;" If not supplied, then default value is "/"
|
---|
43 | ;" Option("MATCH","*.m")="" -- e.g. use filter '*.m'
|
---|
44 | ;" Option("MATCH","*.txt")="" -- e.g. use filter '*.txt"
|
---|
45 | ;" NOTE: Filters are combined by AND, i.e. files matching one of the specified matches
|
---|
46 | ;" Option("PROMPT") A prompt for user to enter filename/directory name
|
---|
47 | ;" Option("SHOW HIDDEN")=1 Show files hidden (e.g. '.name')
|
---|
48 | ;" Option("SELECT DIR")=1 if 1 then mode is to select directories, not files
|
---|
49 | ;" OutPath: [OPTIONAL] Pass by reference, filled with selected path
|
---|
50 | ;" OutName: [OPTIONAL] Pass by reference, filled with selected name
|
---|
51 | ;"Result: returns user specified filename (with path), or "" if aborted
|
---|
52 |
|
---|
53 | write # ;"clear screen
|
---|
54 | new ScrlFiles,done
|
---|
55 | new selDir set selDir=+$get(Option("SELECT DIR"))
|
---|
56 | new width set width=60
|
---|
57 | new line set $piece(line,"-",width-2)="-"
|
---|
58 | set Option("HEADER",1)="+"_line_"+"
|
---|
59 | new banner set banner="--== Please Select "_$select(selDir:"Directory",1:"File")_" ==--"
|
---|
60 | set Option("HEADER",2)="|"_$$CJ^XLFSTR(banner,width-2)_"|"
|
---|
61 | set Option("FOOTER",1)="Enter ? for help"
|
---|
62 | if $get(Option("PROMPT"))'="" set Option("FOOTER",2)=Option("PROMPT")
|
---|
63 | set Option("SCRN WIDTH")=width
|
---|
64 | set Option("ON SELECT")="HndOnSel^TMGIOUT2" ;"code to call based on user input
|
---|
65 | set Option("ON CMD")="HndlOnCmd^TMGIOUT2" ;"code to execute for number entry
|
---|
66 |
|
---|
67 | new msg set msg=$get(Option("MSG"))
|
---|
68 | if msg'="" do
|
---|
69 | . do PopupBox^TMGUSRIF("Message:",msg)
|
---|
70 | . do PressToCont^TMGUSRIF
|
---|
71 |
|
---|
72 | new StackCaller set StackCaller=$$Caller^TMGMISC
|
---|
73 | new nodeDiv set nodeDiv=$get(Option("nodeDiv"),"/")
|
---|
74 | set Option("nodeDiv")=nodeDiv ;" in case it wasn't there initially
|
---|
75 | new curDir set curDir=$get(Option("PATH"))
|
---|
76 | if (curDir="")&($data(^TMG("TMP","SETTINGS","FBrowse",StackCaller))) do
|
---|
77 | . set curDir=$get(^TMG("TMP","SETTINGS","FBrowse",StackCaller))
|
---|
78 | if curDir="" set curDir=nodeDiv
|
---|
79 | set curDir=$$EnsureTrailDiv^TMGIOUTL(curDir,nodeDiv)
|
---|
80 | if $$IsDir^TMGKERNL(curDir)=0 set curDir=nodeDiv
|
---|
81 |
|
---|
82 | new TMGSelect set TMGSelect=""
|
---|
83 | L1 do LoadDir("ScrlFiles",curDir,.Option)
|
---|
84 | set Option("HEADER",3)="|"_$$CJ^XLFSTR("Current Dir: "_curDir,width-2)_"|"
|
---|
85 | set TMGSelect=""
|
---|
86 | do Scroller^TMGUSRIF("ScrlFiles",.Option) ;"Event handler should set TMGSelect
|
---|
87 | if TMGSelect="" goto LQ
|
---|
88 | if selDir set done=0 do goto:done LQ
|
---|
89 | . new Menu,UsrSlct
|
---|
90 | . set Menu(0)="What do you want to do with this directory?"
|
---|
91 | . set Menu(1)="Choose "_TMGSelect_" as selected directory"_$char(9)_"done"
|
---|
92 | . set Menu(2)="Browse INTO it"_$char(9)_"into"
|
---|
93 | . write !
|
---|
94 | . set UsrSlct=$$Menu^TMGUSRIF(.Menu,2)
|
---|
95 | . write #
|
---|
96 | . if UsrSlct="done" set done=1
|
---|
97 | if $$IsDir^TMGKERNL(TMGSelect) set curDir=TMGSelect goto L1 ;"browse into directory
|
---|
98 | do SplitFNamePath^TMGIOUTL(TMGSelect,.OutPath,.OutName,nodeDiv)
|
---|
99 |
|
---|
100 | set ^TMG("TMP","SETTINGS","FBrowse",StackCaller)=OutPath ;"store for future use.
|
---|
101 | LQ write # ;"clear screen
|
---|
102 | quit TMGSelect
|
---|
103 |
|
---|
104 | LoadDir(pArray,curDir,Option)
|
---|
105 | ;"Purpose: load curDir entries into pArray
|
---|
106 | ;"Input: pArray -- PASS BY NAME. An OUT PARAMETER. Filled in as follows
|
---|
107 | ;" @pArray@(1,DisplayText)=Return Text <-- note: must be numbered 1,2,3 etc.
|
---|
108 | ;" @pArray@(2,DisplayText)=Return Text
|
---|
109 | ;" @pArray@(3,DisplayText)=Return Text
|
---|
110 | ;" curDir -- the directory to get files from
|
---|
111 | ;" TMGMask -- PASS BY REFERENCE. The mask array (See FBrowse)
|
---|
112 | ;" Option [OPTIONAL]. Format as follows. All entries are optional
|
---|
113 | ;" Option("MATCH","*.m")="" -- e.g. use filter '*.m'
|
---|
114 | ;" Option("MATCH","*.txt")="" -- e.g. use filter '*.txt"
|
---|
115 | ;" NOTE: Filters are combined by AND, i.e. files matching one of the specified matches
|
---|
116 | ;" Option("NodeDiv") The character that separates folders (e.g. "/")
|
---|
117 | ;" If not supplied, then default value is "/"
|
---|
118 | ;" Option("SHOW HIDDEN")=1 Show files hidden (e.g. '.name')
|
---|
119 | ;" Option("SELECT DIR")=1 if 1 then mode is to select directories, not files
|
---|
120 | ;" nodeDiv -- The character that separates folders (e.g. "/")
|
---|
121 | ;" ShowHidden -- OPTIONAL. Default=0 If 1, then show hidden files
|
---|
122 | ;"Results: none
|
---|
123 | ;
|
---|
124 | new TMGFiles,tempFiles
|
---|
125 | new count set count=1
|
---|
126 | kill @pArray
|
---|
127 | new nodeDiv set nodeDiv=$get(Option("nodeDiv"),"/")
|
---|
128 | set nodeDiv=$get(nodDiv,"/")
|
---|
129 | set ShowHidden=+$get(Option("SHOW HIDDEN"))
|
---|
130 | new selDir set selDir=+$get(Option("SELECT DIR"))
|
---|
131 | set curDir=$get(curDir,nodeDiv)
|
---|
132 | set curDir=$$EnsureTrailDiv^TMGIOUTL(curDir,nodeDiv)
|
---|
133 | if $$IsDir^TMGKERNL(curDir)=0 goto LDQuit
|
---|
134 | ;"Note: Filter/Mask would apply to directory names too, so must
|
---|
135 | ;" ask for list of files with mask applied **AND** also with
|
---|
136 | ;" a mask of '*' to be sure to get directory names
|
---|
137 | new tempMask set tempMask("*")=""
|
---|
138 | if $$LIST^%ZISH(curDir,"tempMask","TMGFiles")=0 goto LDQuit
|
---|
139 | new index set index=""
|
---|
140 | for set index=$order(TMGFiles(index)) quit:(index="") do
|
---|
141 | . if ($extract(index,1)=".")&(ShowHidden=0) quit
|
---|
142 | . new FName,FPName
|
---|
143 | . set FName=index
|
---|
144 | . set FPName=curDir_FName
|
---|
145 | . if $$IsDir^TMGKERNL(FPName) set tempFiles("DIRS","<"_FName_">")=FPName
|
---|
146 | . else set tempFiles("FILES",FName)=FPName
|
---|
147 | ;
|
---|
148 | ;"Now get files again with user-supplied filter
|
---|
149 | merge TMGMask=Option("MATCH")
|
---|
150 | if $data(TMGMask)=0 goto LD2 ;"use FILES node already created
|
---|
151 | kill tempFiles("FILES") ;"needs to be reloaded with mask applied.
|
---|
152 | if $$LIST^%ZISH(curDir,"TMGMask","TMGFiles")=0 goto LDQuit
|
---|
153 | new index set index=""
|
---|
154 | for set index=$order(TMGFiles(index)) quit:(index="") do
|
---|
155 | . if ($extract(index,1)=".")&(ShowHidden=0) quit
|
---|
156 | . new FName,FPName
|
---|
157 | . set FName=index
|
---|
158 | . set FPName=curDir_FName
|
---|
159 | . if $get(tempFiles("DIRS","<"_FName_">"))'="" quit
|
---|
160 | . set tempFiles("FILES",FName)=FPName
|
---|
161 | ;
|
---|
162 | LD2 set index=""
|
---|
163 | if curDir'=nodeDiv do
|
---|
164 | . set @pArray@(count,".. <UP>")=$$UpPath^TMGIOUTL(curDir)
|
---|
165 | . set count=count+1
|
---|
166 | for set index=$order(tempFiles("DIRS",index)) quit:(index="") do
|
---|
167 | . set @pArray@(count,index)=$get(tempFiles("DIRS",index))
|
---|
168 | . set count=count+1
|
---|
169 | if selDir=1 goto LDQuit ;"skip showing files.
|
---|
170 | ;
|
---|
171 | set index=""
|
---|
172 | for set index=$order(tempFiles("FILES",index)) quit:(index="") do
|
---|
173 | . set @pArray@(count,index)=$get(tempFiles("FILES",index))
|
---|
174 | . set count=count+1
|
---|
175 | ;
|
---|
176 | LDQuit quit
|
---|
177 |
|
---|
178 | HndOnSel(pArray,Option,Info)
|
---|
179 | ;"Purpose: handle ON SELECT event from Scroller
|
---|
180 | ;"Input: pArray,Option,Info -- see documentation in Scroller
|
---|
181 | ;" Info has this:
|
---|
182 | ;" Info("CURRENT LINE","NUMBER")=number currently highlighted line
|
---|
183 | ;" Info("CURRENT LINE","TEXT")=Text of currently highlighted line
|
---|
184 | ;" Info("CURRENT LINE","RETURN")=return value of currently highlighted line
|
---|
185 | ;"Globally-scoped var used: TMGSelect,TMGSCLRMSG
|
---|
186 | new text set text=$get(Info("CURRENT LINE","TEXT"))
|
---|
187 | set TMGSelect=$get(Info("CURRENT LINE","RETURN"))
|
---|
188 | set TMGSCLRMSG="^"
|
---|
189 | quit
|
---|
190 |
|
---|
191 | HndlOnCmd(pArray,Option,Info)
|
---|
192 | ;"Purpose: handle ON SELECT event from Scroller
|
---|
193 | ;"Input: pArray,Option,Info -- see documentation in Scroller
|
---|
194 | ;" Info has this:
|
---|
195 | ;" Info("USER INPUT")=input
|
---|
196 | ;" Info("CURRENT LINE","NUMBER")=number currently highlighted line
|
---|
197 | ;" Info("CURRENT LINE","TEXT")=Text of currently highlighted line
|
---|
198 | ;" Info("CURRENT LINE","RETURN")=return value of currently highlighted line
|
---|
199 | new done set done=0
|
---|
200 | new rtn set rtn=$get(Info("CURRENT LINE","RETURN"))
|
---|
201 | new path set path=rtn
|
---|
202 | new UsrInput set UsrInput=$get(Info("USER INPUT"))
|
---|
203 | new cmd set cmd=$$UP^XLFSTR($piece(UsrInput," ",1))
|
---|
204 | if $extract(path,$length(path))'=nodeDiv do
|
---|
205 | . set path=$$UpPath^TMGIOUTL(path) ;"Trim off filename
|
---|
206 | if cmd="CD" do goto:done HOCDone
|
---|
207 | . new newDir set newDir=$piece(UsrInput," ",2)
|
---|
208 | . if newDir=".." set UsrInput=".." quit
|
---|
209 | . set done=1
|
---|
210 | . if $extract(newDir,1)'="/" set newDir=path_newDir
|
---|
211 | . if $$IsDir^TMGKERNL(newDir)=0 do quit
|
---|
212 | . . write newDir," is not a valid existing directory.",!
|
---|
213 | . . do PressToCont^TMGUSRIF
|
---|
214 | . set TMGSelect=newDir
|
---|
215 | . set TMGSCLRMSG="^"
|
---|
216 | if cmd="MKDIR" do goto:done HOCDone
|
---|
217 | . new newDir set newDir=$piece(UsrInput," ",2)
|
---|
218 | . set done=1
|
---|
219 | . if $extract(newDir,1)'="/" set newDir=path_newDir
|
---|
220 | . write !,"Create NEW directory: ",newDir
|
---|
221 | . new % set %=2
|
---|
222 | . do YN^DICN write !
|
---|
223 | . if %=1 if $$mkdir^TMGKERNL(newDir)
|
---|
224 | . write #
|
---|
225 | . set TMGSelect=path
|
---|
226 | . set TMGSCLRMSG="^"
|
---|
227 | if cmd="RMDIR" do goto:done HOCDone
|
---|
228 | . new newDir set newDir=$piece(UsrInput," ",2)
|
---|
229 | . set done=1
|
---|
230 | . if $extract(newDir,1)'="/" set newDir=path_newDir
|
---|
231 | . write !,"DELETE directory: ",newDir
|
---|
232 | . new % set %=2
|
---|
233 | . do YN^DICN write !
|
---|
234 | . if %=1 if $$rmdir^TMGKERNL(newDir)
|
---|
235 | . set TMGSelect=path
|
---|
236 | . set TMGSCLRMSG="^"
|
---|
237 | . write #
|
---|
238 | if (UsrInput="{LEFT}")!(UsrInput="..") do goto HOCDone
|
---|
239 | . new nodeDiv set nodeDiv=$get(Option("nodeDiv"),"/") ;"extra info passed
|
---|
240 | . set TMGSelect=$$UpPath^TMGIOUTL(path)
|
---|
241 | . set TMGSCLRMSG="^"
|
---|
242 | if UsrInput="{RIGHT}" do goto HOCDone
|
---|
243 | . set TMGSelect=$get(Info("CURRENT LINE","RETURN"))
|
---|
244 | . set TMGSCLRMSG="^"
|
---|
245 | ;"Later, I could put some stuff here to let the command line choose filters etc.
|
---|
246 | ;"or perhaps jump to a given directory etc. Perhaps later...
|
---|
247 | if UsrInput["?" do goto HOCDone
|
---|
248 | . do ShowHelp(.Option)
|
---|
249 | else do
|
---|
250 | . new newName set newName=path_UsrInput
|
---|
251 | . new % set %=2
|
---|
252 | . if $$FileExists^TMGIOUTL(newName) set %=1
|
---|
253 | . else do
|
---|
254 | . . write !,"Use NEW filename: ",newName
|
---|
255 | . . do YN^DICN write !
|
---|
256 | . . if %'=1 write #
|
---|
257 | . if %=1 do
|
---|
258 | . . set TMGSelect=newName
|
---|
259 | . . set TMGSCLRMSG="^"
|
---|
260 | HOCDone quit
|
---|
261 |
|
---|
262 |
|
---|
263 | ShowHelp(Option)
|
---|
264 | ;"Purpose: show help for file browser
|
---|
265 | ;"Input: Option -- see documentation in Scroller
|
---|
266 | write !
|
---|
267 | write "Use [UP], [DOWN], [PgUp], or [PgDown] keys to scroll",!
|
---|
268 | write "Use [ENTER] to select file name",!
|
---|
269 | write "Use [ENTER] or [RIGHT] key to browse into a directory",!
|
---|
270 | write "Use [LEFT] key to back up one level",!
|
---|
271 | write "Use ^ to abort without selecting a file",!
|
---|
272 | if $get(Option("SELECT DIR"))'=1 do
|
---|
273 | . write "To create/select a NEW file, just type new name and [ENTER]",!
|
---|
274 | write "type: 'cd <DirName>' to change directory",!
|
---|
275 | write "type: 'mkdir <DirName>' to create a NEW directory",!
|
---|
276 | write "type: 'rmdir <DirName>' to DELETE a new directory",!
|
---|
277 | do PressToCont^TMGUSRIF
|
---|
278 | write #
|
---|
279 | quit
|
---|