Courses/Name1
Courses/Name2
I would like Name1 and Name2 (and so on) to become sub-menus of the
Courses top level menu.
Courses
Name1
Name2
That way a user can create another directory and it will automatically
be added. Eventually I will have files in those directories that will
sub-menu names etc. So if you create a directory name of "Test" and add
files called "test1.txt" and "text2.txt" then the menu would look like:
Courses
Name1
Name2
Test
test1 # this will open the file into the application
test2 # ditto
I have the home of the script set like:
set home [file dirname [info script]]
So I guess I can do a foreach on "$home/Courses/" to get the dir names
and file names? I am not sure how to build a menu with that though.
Anyone done something like this?
Robert
> So I guess I can do a foreach on "$home/Courses/" to get the dir names
> and file names? I am not sure how to build a menu with that though.
>
> Anyone done something like this?
>From http://en.wikibooks.org/wiki/Programming:Tcl_Tk#menu
To add a menu to a GUI application, take steps of three kinds:
Create the toplevel horizontal menu (needed only once):
. configure -menu [menu .m]
For each item in the top menu, create a cascaded submenu, e.g.
.m add cascade -label File -menu [menu .m.mFile]
For each entry in a submenu, add it like this:
.m.mFile add command -label Open -command {openFile ...}
or
.m.mFile add separator
In your case, add a cascade for each directory, and a command for each
file that [glob] brings you.
Great! I did it and it works. : D
Robert
> Great! I did it and it works. : D
That was a cool development cycle - from question asked to solution
confirmed, 17 minutes :D
I got the directories down:
foreach cDir [lsort -dictionary [glob $home/Courses/*]] {
.m.mLessons add cascade -label [file tail $cDir]
}
That does what I want it to do, so thanks for that suggestion. What do
those cascade names become assuming the foreach brings back directory
names of dir1, dir2, dir3. Do they become: .m.mLessons.dir1
.m.mLessons.dir2 and .m.mLessons.dir3
Robert
Oops! I am not that smart. : D
> That does what I want it to do, so thanks for that suggestion. What do
> those cascade names become assuming the foreach brings back directory
> names of dir1, dir2, dir3. Do they become: .m.mLessons.dir1
> .m.mLessons.dir2 and .m.mLessons.dir3
Hmm..
Tcl/Tk is very simple. But some reading man pages (in this case, menu)
still helps.
As my (maybe too brief) explanation showed, to add a cascade you'd best
specify a new menu. How to call this is up to you - just make sure its
name doesn't start with an uppercase letter (that's why I put a "m" in
front).
You can call [glob] separately for subdirectories (-type d) and files
(-type f). I'd suggest first to do the directories, create a cascade
for each,
.m.whatever.m$dir create cascade -label $subdir -menu [menu
.m.whatever.m$dir.m$subdir]
and recurse into them (call the same procedure for each again). Then do
the files, adding a simple command to the current menu.
Thank you very much!
Robert
Bruce
Yes, I am not sure what I want to do here. The file format is going to
be a set one. I may create a simple ini file with something like
title=blah as the key/value then a user would just have to drop in the
file and update the ini file and I only have to parse that. Come to
think of it that is what i will do. It saves me from having to do
globbing and such to get directory and file names. I can use the
key/value to get the file name and title of the lesson and I can use
the section to denote the directory it resides in. I could even build a
wizard in the app to help create the ini section itself.
Hmmm, I will try that.
Robert
> Yes, I am not sure what I want to do here. The file format is going to
> be a set one. I may create a simple ini file with something like
> title=blah as the key/value then a user would just have to drop in the
> file and update the ini file and I only have to parse that. Come to
> think of it that is what i will do. It saves me from having to do
> globbing and such to get directory and file names. I can use the
> key/value to get the file name and title of the lesson and I can use
> the section to denote the directory it resides in. I could even build a
> wizard in the app to help create the ini section itself.
>
> Hmmm, I will try that.
>
> Robert
>
That seems like a more troublesome implementation. You are forcing the
user to a) create an ini file, b) create some files on disk, and c) keep
the two in sync. Or am I reading something wrong?
If you just build your menu straight from the disk, all the user has to
do is b) create some files on disk.
I think I missed part of the thread -- why is doing the globbing so
difficult?
Here's a quick example of how to create a menu based on a folder
hierarchy and a file spec. It needs some error checking and perhaps some
sanity checking (eg: don't create cascade menus for directories with no
*.txt files), but it shows the general idea.
proc makeMenu {dir menu} {
set count 0
# create cascade menus for subfolders, and recurse
foreach subfolder [lsort [glob -nocomplain \
-directory $dir -type d *]] {
if {$subfolder eq "." || $subfolder eq ".."} continue
set name [file tail $subfolder]
set submenu [menu $menu.menu[incr count]]
$menu add cascade -label [string totitle $name] -menu $submenu
makeMenu $subfolder $submenu
}
# create commands for each .txt file
foreach file [lsort [glob -nocomplain \
-directory $dir -type f *.txt]] {
set name [file tail $file]
$menu add command -label [string totitle $name] \
-command [list showFile $file]
}
}
menu .menubar
. configure -menu .menubar
menu .menubar.courses
.menubar add cascade -label Courses -menu .menubar.courses
makeMenu [pwd]/Courses .menubar.courses