proc ilist { {begin {.}} {listf {winfo children}} {maxdepth {100}} {ident {0}} {isleaf {}} } { # isleaf function defined means not-leafs themselves are filtered out # and that puts of the results is turned off if {$maxdepth <1} return set de {}; set o {} for {set i 0} {$i < $ident} {incr i} {append de " "} foreach i [eval "$listf $begin"] { if {$isleaf == {}} { lappend o $i puts "$de $i" eval lappend o [ilist [list $i] $listf [expr $maxdepth-1] [expr $ident +1] $isleaf] } { if {[isleaf $i]} { lappend o $i } { eval lappend o [ilist [list $i] $listf [expr $maxdepth-1] [expr $ident +1] $isleaf] } } } return $o } # for which we need the functions: proc files {d} {if [catch {glob $d/*} r] {return {}} {return $r} } proc isleaf {f} {if [file isdir $f] {return 0} {return 1}}To make the 'Medium' preview directories automatically:
foreach i [ilist c:/Memorystick/ files] { if [file isdir $i] { if ![file exists [file join $i Medium]] { file mkdir [file join $i Medium] } { puts "Error: file exists $i/Medium" } } }Making a database of image filesThis sets up the dbase using bwise routines
set dbvar {} ;# initialize the database list to empty dbaccess ;# opens a picture and data window dbcontrol mydatabase.tcl ;# opens a db load/save/new entry windowSome named functions would make this clearer (bwise should automatically decompose this...), but this lists the right image files in the database variable dbvar, using the format function image_todb:
proc image_todb { {im} } { global ic dbvar incr ic set medium [file join [file dirname $im] Medium [file tail $im]] exec djpeg -scale 2/8 $im | cjpeg -q 80 -outfile $medium lappend dbvar [list [list File $im] [list Image $medium] [list Id [file rootname [file tail $im]] ] Name Description Date [list Size [lrange [exec djpeg $im | head -3] 1 2]] ] } set dbvar {}; set ic 0 ; foreach i [ilist c:/Memorystick files 100 0 isleaf] { if {[string equal [string tolower [file extension $i]] .jpg] && \ ![file exists [eval file join [lrange [file split [file dirname $i]] 0 end-1] [list [file tail $i]]] ] } { image_todb $i } }Sorting the database based on picture ID in another variable:
set dbvarunsorted $dbvar ; puts fin ; print something to prevent very large return value in console proc sp {a b} { return [string compare [lindex [lindex $a 2] 1] [lindex [lindex $b 2] 1]] } set dbvar [lsort -command sp $dbvarunsorted] ; puts fin dbform [lindex $dbvar 0] ; # update or show the viewer ; # without updating dbvar with the previous window data !No doubt there are dbase systems which can do stuff like this elegantly (I know dbase, and have worked with ms and msql), but for me this is not bad insightwise, and certainly not efficiencywise, and freedomwise.We can now edit the data fields in out database fairly comfortably however, and 'stepping through' the dbase with image can be done at high speed on a recent machine.Simply edit the text fields, and use Next/Prev and the index in between (followed by Return) to navigate. The selection and cursor will be in the field with the same name (when it exists) during navigating, so typing data for images on a row can be efficient. Possibly bind a function key to the prev and next buttons.The database can easily be compressed by some zipper very efficiency, but is small compared to image size, and of course these fields are just examples, and for each entry a completely different, and dynamically changeable number and type of fields can be used and searched through the dbsearch procedure. Basically [lindex $dbvar $index] returns a list of all fields of an entry, organized mainly as pairs (list with 2 elements) of name/value.Now we can make a link with the server. I set the docroot directory to the top of the image tree in the tclhttp resource file (or in the main tcl script), so that in principle we can server the images by relative path, and because we've got all the data we want about them in the dbvar global variable, it is easy enough to make a
Direct_Url /test testwhich uses a procedure test which must return a webpage when it is called when a browser acccesses the page /test on the (probably for this test local) webserver.This non-production proc prints the raw contents of the next database entry in text form, and show the accompanying image in a webpage. It uses the dbform window, and pushes it's next button every time the page is reloaded:
proc test { {args} } { global dbcurrent dbvar;# send $args; for debugging use when setup is also fitted with pcom for remote management
.dbf.wb.ne invoke ; return "<html>$dbcurrent<p><img src=\"[eval file join [lrange [file split [lindex [lindex $dbcurrent 1] 1]] 2 end]]\"></html>" }Updating the fields in the .bdf window can be done this way, and will be recorded automatically in dbvar, which can be saved by pressing 'Save' in the Database Control window, without asking for overwrite confirm....
To start the whole setup automatically, I use the following startup script:
console show source e:/Theo/bwiseprocs0343.tcl bwise update wm geom . 636x350+9+4 #update # comment out when no more need.. welcome package require Img dbcontrol e:/Theo/dbimages2sort.tcl set defaultprocs {} unset defaultprocs get_procvanilla c:/Theo/tcl/tclhttpd3.4.1/bin/defaultprocs.tcl procs_window update wm geom .f 355x351+658+4 .f.fu.l conf -font {{MS Sans Serif} 10} .f.ft.t conf -font {{MS Sans Serif} 12} source c:/Theo/tcl/tclhttpd3.4.1/bin/tryserv.tclPress the Database Control 'load' button to get the previously saved version back. And make a index.html file to point to the /test semi-cgi.