File selection dialog for Tile

TR - This is a file selection dialog for Tile as a replacement for tk_getOpenFile, tk_getSaveFile, tk_chooseDirectory and even more! It was coded by Schelte Bron.

Note: This page describes version 1.0 of the package. For current instructions, please see the documentation on chiselapp

Commands

 ttk::getOpenFile
 ttk::getSaveFile
 ttk::chooseDirectory
 ttk::getAppendFile <- explain this one

sbron I added the getAppendFile version of the dialog because I needed a dialog that allows the user to select a log file. It is perfectly fine if the selected file did or did not exist. The other dialogs would either give a confusing warning for an existing file or not allow non-existing files at all. This command has been obsoleted by the -confirmoverwrite option.


Example (using xfce4 on Linux)

 package require tile
 tile::setTheme clam
 ttk::getOpenFile

http://tcl.typoscriptics.de/misc/fsdialog.gif


The project is now hosted on chiselapp

Get the latest version here: https://chiselapp.com/user/schelte/repository/fsdialog/tarball/fsdialog.tar.gz?uuid=trunk

Installation instructions: Dump the files in the package (not the fsdialog directory) in a directory that is listed in $auto_path, or lappend the directory containing the files to auto_path.


TLu: 2006-12-30 In line 1594 should be '-mustexist' instead '-mustexists', because ttk::chooseDirectory has parameter '-mustexist'


MSH: 08/06/2006 Hi, This is a great widget I have included it into one of my programs and have a few comments: The standard dialogs have a '-multiple' option which I use to select multiple files for opening I have looked at the code but do not have the time to understand it to add this function do you have the intention of adding this ? Pressing ESCAPE on the standard dialogs will cancel the dialog. I downloaded the file at home for another project and discovered that the code had changed, is it possible to add a few comments to the code or even better a quick message here to signal any changes, so that any users can recover the latest. Thanks again I was preparing to develop something (almost certainly not as pretty) for my linux versions as the default dialogs don't look good on a tiled interface.


TR - There is a bug in the widget. When you resize it, you can no longer select a file. I will try to fix this if I get the time to dig into the code ...

MSH - Another bug is in the tk_chooseDirectory replacement which works great under linux but not under windows (at least 2000).

sbron - That's not a bug. It simply wasn't designed for windows. No compromises were made to support operating systems that don't have the proper capabilities needed for a timely display of the directory structure.

MG I admit I've not actually looked at these yet, but I wonder: is it worth using them on Windows? Since the aim of Tile is to provide a native look, and "real" native dialogs are already used on Windows, it seems a little strange to code up another version made to look exactly like the one we already use...

SEH 20060625 -- having good widgets like this is important and useful for every platform, because they can see files in Tcl virtual filesystems, while the native dialogs can't. For those working with vfs's, they're crucial.

MG Working with Tcl's vfs's is something I'd not thought of, and is a good point. Thanks :)

peterc 2008-08-28: On the flipside, outside the proprietory choosers provided by Windows & Mac OS X, is there a method to hide or disallow the browsing of particular locations or vfs filesystems? I'd much prefer it if X11 users weren't able to casually browse the directory structure of my starpack executibles ;-).


sbron 20070923 -- I have posted a new version that should address most of the issues raised above, and some others too:

  • Added -multiple option
  • Pressing ESC cancels the dialog
  • Using msgcat for the text strings (thanks to Mats Bengtsson, who also provided a Swedish translation catalog)
  • The -filetypes option no longer defaults to information from a previous call
  • Files can now also be selected after resizing
  • The selected file(s) remain highlighted after resizing or changing settings
  • Corrected typo in spelling of ttk::chooseDirectory -mustexist option

Adding the -multiple option was actually quite complicated and the code has become a bit of a mess as a result. It should probably be cleaned up and could also use more comments, but I have decided to publish it as is for now so people can start using it.


DKF: The Tk 8.5 file dialog (on Unix) uses Ttk widgets, and (tries to) style the standard Tk widgets that it uses to look like the current theme.


josevr 20080826 -- The array that stores the windows data is always the same: set dataName __ttk_filedialog. On the other hand, the window name depends on the parent: set w $data(-parent).$dataName. So when a new parent is used, a new window is created and cached for later usage. This creates a conflict when different dialogs are created with different parents: they will overwrite each other's dataName arrays!


sbron 20081228 -- I have updated the zip file mentioned above (twice today, as I found out soon after posting that ttk::messageBox is no longer needed). New in the latest version:

  • Allow the style command to be in either the global namespace or in ::ttk.
  • File name missing in warning for overwriting an existing file.
  • Add the -typevariable option introduced in 8.5 to the file selection dialogs.
  • Fix error when using the dialog with different parents.
  • File dialogs should use theme colors instead of their own hardcoded ones.
  • Fix error for some warning message dialogs.
  • Make sure the font isn't too big resulting in files not being visible.
  • Fix errors when opening the file selection dialog multiple times before selecting a file.

Martyn Smith 20090119 I have a user who is complaining that the scroll bars do not work properly. Example If you have long filenames, and you resize the filelist pane, as soon as you cover the last letters of the long filenames the scrollbar resizes in half (to scroll the canvas I presume) but the scroll bar cannot be moved because there is only one column !! Is this a simple fix ?

This seems to work properly in mixed mode and detailed mode, so the problem is in separate/files/folders short view mode only. I've started to look at the code and will post any more findings.

sbron 20090315 -- You didn't indicate how you would like to see this issue fixed, so I have adjusted the scrollbar display. I really prefer the files to always be aligned to the left side of the window and not allow free horizontal scrolling.

The changes in this version:

  • Correct scrollbar display when filenames are too long to fit in the window.
  • Fix error when navigating to a directory without having the proper permissions (new attempt).
  • Use nicer images if PNG support is available (Tk 8.6!)

Martyn Smith 20090324 Thanks for the fix. I did not have a preference for the fix, just that the scrollbar width and the filename width rest coherent.


sbron 20090703 -- The previous version breaks lassign on Tcl 8.5, so I fixed that. Also a German translation catalog has been added, thanks to Christian Rapp.


alexandra - 2010-08-13 16:55:36

Hello,

i have a question to Schelte Bron's fsdialog.tcl. It's a very great alternate for the old fileselectiondialog ! But how can i set the flag for select only directory ?

Or must i use the ttk::chooseDirectory ?

I think ttk::getOpenFile looks like better...

I hope for help..

my tcl projekt is a mp3 player and multimedia system for car pc's [L1 ]

thank you

alexandra

sbron 20100814 -- There is no option to select a directory with ttk::getOpenFile, that's what ttk::chooseDirectory is for. It's the same as the tk_getOpenFile and tk_chooseDirectory commands included in Tk.


Martyn Smith - 2010-09-28 15:30 Hello, I have started using the ttk::chooseDirectory and would like to be able to create a new directory and select it, the standard windows dialog allows a 'new directory', at the moment enter the new path at the top and in my code create the path if it is missing. Are there any plans to allow creating a new directory, I notice that it is possible in the open file dialogs.

sbron: I did not have any plans to allow creating a new directory. But it is a good idea, I'll try to look into it.


nico Bats - 2011-04-04 ' just to mention that in proc ::ttk::dialog::file::Update i had to wrap the cwd variable around { } in eval glob function, otherwise directory with space in the name are not well processed (at least following ones)

sbron: The command being eval-ed is built up as a proper list, so it should not cause any problems. And in fact I don't see any issues when I try to access a file in a directory with spaces. Can you describe a little bit more about under which conditions there is a problem?

nico Bats let's say a path like that /Users/nico/some path/some show/myshow.xxx if i don't wrap the mentioned variable around {}, i can access to "some path", but "some show" is not visible (and myshow.xxx unreachable). at least it happens here TclTk 8.5.9 / MacOS X 10.6.7


Martyn Smith - 2012-06-28 I recently needed to ask the user for a file but the name must not exist so I added the following

    if {$type eq "save"} {
        lappend specs {-mustnotexist "" "" "0"}
    }

to the Config procedure just after the test for open, and

    if {$data(type) eq "save"} {
        if {$data(-mustnotexist)} {
            if {[lindex $path 0] ne [file join $data(-initialdir) $data(-initialfile)]} {
                set str {File "%s" already exists. Choose another name}
                set reply [MessageDlg .fsdialog -parent $w -icon warning -type user -buttons [list [mc "OK"]] -message [mc $str [lindex $path 0]]]
                return
            }
        } else {
            set str {File "%s" already exists. Do you want to overwrite it?}
            set reply [MessageDlg .fsdialog -parent $w -icon warning -type user -buttons [list [mc "Yes"] [mc "No"]] -message [mc $str [lindex $path 0]]]
            if {$reply == 1} {return}
        }
    }

in the Done procedure, this neatly solved our problem. I do not remember ever seeing this option anywhere. I also found a minor annoyance when changing directory in a save dialog the filename is emptied out. I added the following if

    if {$data(type) ne "save"} {
        set data(selectFile) ""
    }

back to the code in the ChangeDir procedure, which i found in a previous fsdialog.


sbron 20120819 -- I posted a new version with the following changes:

  • Fix problems with directory- and file names starting with ~
  • Fix getting stuck in tkwait if toplevel window is destroyed
  • Provide a button for creating a directory from ttk::chooseDirectory
  • Added the change of not clearing out the file name on save dialogs suggested by Martyn

SimonB - 2013-02-08 11:34:52

Is anyone else noticing that when using ttk::getOpenFile in a directory with a large number of files (~24000) that the function is stuck with 100% cpu usage?

RLE (2013-02-08): Doing much of anything in a single directory containing ~24000 files is going to be slow. The 100% cpu usage would result from at least two places:

  1. just obtaining the list of the 24000 files
  2. the work necessary to "draw" entries for all 24000 files

With that many files in one directory, your better option is to find a way to reorganize them into a better arrangement of several smaller directories first.

SimonB (2013-02-15): Thanks. It's just that tk_getOpenFile is virtually instant when opening the same directory.

RLE (2013-02-16): That tidbit of information would have been worth knowing sooner. That says that somewhere in the implementation of ttk::getOpenFile is an inefficient algorithm in the face of 24,000 files where no such inefficiency exists in tk_getOpenFile. What differs between the two is the next question to be answered.

MG What OS? On Windows (and MacOS?), tk_getOpenFile is a native dialog, whereas on Linux it's a Tcl dialog like ttk::getOpenFile is. That may explain the difference.

SimonB (2013-02-25): Apologies. We are running on Linux. We can't easily make smaller directories as we are in the motion picture business where it is commonplace (and indeed, the industry standard) to work with directories of up to 32000 files (corresponding to 20 minutes of film). I just tested a directory with 22340 files and tk_getOpenFile listed the files in around 2 seconds. ttk::getOpenFile, while prettier and much more usable, still has no file listing after 5 minutes.

MG In that case, I'd suggest looking at the code for the Tcl-only tk_getOpenFile dialog (in tcl/lib/tk8.6/tkfbox.tcl) and comparing it to the code for the ttk dialog; if the time difference is that extreme, there must be something pretty different happening under the hood. (My guess would be that the ttk one is trying to process the entire file list before updating the display, while the tk one updates regularly to keep the display alive. Just a guess, though.)

sbron It's probably the part of the code that calculates the space needed for each file name to determine the column width to use.


DrS This is a great tcl-only file selection dialog but unfortunately is not cross-platform. Specifically, on Windows, it limits itself to the C:/ drive only. I have modified the original fsdialog to remove this restriction. The modification enables the dialog to list available volumes when it reaches the root of the filesystem. Everything else should work as before. Please feel free to test and see how it performs. Here is the change as reported by diff:

351c351,358
<     set data(selectPath) [file normalize [JoinFile $cwd $dir]]
---
>
>     if {[string equal $dir $cwd] || [string equal "." "$dir$cwd"]} {
>        ;## NOTE: USE EMPTY DIR TO INDICATE THAT VOLUMES SHOULD BE LISTED
>        set dir ""
>        set data(selectPath) $dir
>     } else {
>        set data(selectPath) [file normalize [JoinFile $cwd $dir]]
>     }
418c425,432
<     if {[catch [linsert $pattern 0 glob -nocomplain -tails \
---
>     if {[string length $cwd] == 0} {
>        ;## SHOW VOLUMES
>        set list [list]
>        foreach v [file volumes] {
>           catch { if {[file readable $v]} { lappend list $v } }
>        }
>
>     } elseif {[catch [linsert $pattern 0 glob -nocomplain -tails \

sbron This dialog was never intended to be cross-platform. On windows and mac tk_getOpenFile uses native dialogs. Only on *nix it was using a Tcl script that produced a very limited and ugly dialog. This is an alternative for that Tcl script.

sbron Seeing that people sometimes have reasons to use these dialogs on windows as well, I have made some improvements on windows support. For the disk volumes I chose a bit different method than the one suggested by DrS. The volumes can be selected from the combo box at the top of the dialog.

The ttk::getOpenFile dialog has a new option -choosedir, that allows you to use it as an alternative for tk_ChooseDirectory.