5 Selecting Files and Directories

One task that an application has to perform frequently is to ask the user to select files or directories. To select files, you can use the Tix File Selection Widgets: TixFileSelectDialog and TixExFileSelectDialog. To select directories, you can use the Tix Directory Selection Widgets: TixDirList and TixDirTree.

5.1 File Selection Dialog Widgets

There are two file dialog widgets inside Tix: the TixFileSelectDialog (figure 5-2 ) is similar to the FileSelectionDialog widget in Motif; TixExFileSelectDialog (figure 5-3 ) looks like its conunterpart in MS Windows. Both widgets let the user navigate through the file system directories and select a file.

One advanced feature of both types of file selection boxes is they use ComboBoxes to store the files, directories and patterns the user has selected in the past. If the user wants to select the same files again, he can simply open the ComboBoxes and click on his past inputs. This saves a lot of keystrokes and is especially useful when the user needs to switch among several files or directories.

5.1.1 Using the TixFileSelectDialog Widget

An example of using the TixFileSelectDialog widget is in figure 5-1 . At line 1, we create a TixFileSelectDialog widget and set the title of the dialog to ``Select A File'' using the -title option. We also use the -command option to specify that the procedure selectCmd should be called when the user has selected a file. selectCmd will be called with one parameter, the filename selected by the user. When the TixFileSelectDialog widget is created, it is initially not shown on the screen. Therefore, at line 3, we call its popup widget command to place the widget on the screen.

tixFileSelectDialog .file -title "Select A File" -command selectCmd
.file subwidget fsbox config -pattern "*.txt" -directory /usr/info
.file popup

proc selectCmd {filename} { puts "You have selected $filename" }

(Figure 5-1) Using the TixFileSelectDialog

(Figure 5-2) The Composition of a TixFileSelectDialog Widget

5.1.2 The Subwidget in the TixFileSelectDialog

We may also want to set other options for the file dialog such as its file filter and working directory. To do this, we must know the composition of the TixFileSelectDialog widget. As shown in figure 5-2 , the TixFileSelectDialog contains a subwidget fsbox of the type TixFileSelectBox and a subwidget bbox of the type TixStdButtonBox.

The fsbox subwidget supports the -pattern and -directory options. At line 2 of figure 5-1 , we use the -directory option to tell the fsbox subwidget to display files in the directory /usr/info; we also use the -pattern option to specify we only want the filenames that has the txt extension.

The fsbox subwidget also supports the -selection option, which stores the filename currently selected by the user. We can query this value by the cget widget command of the fsbox subwidget.

Remember that the -pattern, -directory and -selection options do not belong to the TixFileSelectDialog widget. A common mistake that people make is to try to configure the non-existent -pattern option of the TixFileSelectDialog, which causes much despair, long error messages and great loss of self-confidence. Always remember:, when you want to configure an option, find out whether it belongs to the widget or its subwidgets.

5.1.3 The TixExFileSelectDialog Widget

(Figure 5-3) The ExFileSelectDialog Widget

The TixExFileSelectDialog widget is very similar to the TixFileSelectDialog widget. It supports all the options and widget commands of the latter, so essentially we can just take the program 5-1 and replace the command tixFileSelectDialog in the first line to tixExFileSelectDialog.

The composition of the TixExFileSelectDialog widget is a bit different: it contains one contains one subwidget, which is also called fsbox, of the type TixExFileSelectBox widget (figure 5-3 ). Again this fsbox widgets supports all widget options and commands of the fsbox subwidget in TixFileSelectDialog, so the line 2 of program 5-1 can work for TixExFileSelectDialog widgets without any change.

5.1.4 Specifying File Types for TixExFileSelectDialog

The TixExFileSelectBox widget has a ComboBox subwidget marked as ``Select Files of Type:'' (see figure 5-3 ). This widget contains some pre-set types of files for the user to choose from. For example, a word processor program can include choices such as ``Microsoft Word Documents'' and ``WordPerfect Documents''.

The TixExFileSelectBox widget has a -filetypes option for this purpose. As shown in line 3 through 7 in program 5-4 , the value for the -filetypes option is a list. Each item in the list should contain two parts. The first part is a list of file patterns and the second part is the textual name for this type of files.

5.1.5 The tix filedialog Command

TixExFileSelectDialog and TixFileSelectDialog are very similar to each other. So which one should we use? That is just a matter of taste. However, since we know that programmers usually have bad taste, clever programmers would rather step aside and let the users exercise their own taste. To do this, we can use the tix filedialog command.

For any programs based on Tix, the user can choose his preferred type of file dialog by setting the X resource FileDialog to either tixFileSelectDialog or tixExFileSelectDialog. This can usually be done by inserting a line similar to the following into the user's .Xdefaults file:

*myapp*FileDialog: tixExFileSelectDialog
When we call the command tix filedialog, it will return a file dialog widget of the user's preferred type.

The advantage of using tix filedialog is it makes coding flexible. If the management suddenly mandates that we dump the Motif look-and-feel in favor of the MS Windows look-and-feel, we don't need to dig up every line of tixFileSelectDialog calls and replace it with tixExFileSelectDialog. Also, tix filedialog creates only one copy of the file dialog, which can be shared by different parts of the program. Therefore, we can avoid creating a separate file dialog widget for each of the ``Open'', ``Save'' and ``Save As'' commands in our application. This way, we can save resource since a file dialog is a large widget and it takes up quite a bit of space.

set dialog [tix filedialog]
$dialog -title "Select A File" -command selectCmd
$dialog subwidget fsbox config -pattern "*.txt" -directory /usr/info
if {[winfo class $dialog] == "TixExFileSelectDialog"} {
    $dialog subwidget fsbox config -filetypes {
        {{*}            {*     -- All files}}
        {{*.txt}        {*.txt -- Text files}}
        {{*.c}          {*.c   -- C source files}}
$dialog popup

proc selectCmd {filename} { puts "You have selected $filename" }

(Figure 5-4) Using the tix dialog command

The use of the tix filedialog command is shown in program 5-4 . This program is very similar to what we saw in program 5-1 , except now we aren't really sure which type of file dialog the user have chosen. Therefore, if we want to do something allowed for only one type of file dialogs, we have to be careful. At line 4 of program 5-4 , we use the winfo command to see whether the type of the file dialog is TixExFileSelectDialog. If so, we set the value for the -filetypes option of its fsbox subwidget.

5.2 Selecting Directories with the TixDirTree and TixDirList Widgets

There are two Tix widgets for selecting a directory: TixDirList (figure 5-6 ) and TixDirTree (figure 5-6 ). Both of them display the directories in a hierarchical format. The display in the TixDirList widget is more compact: it shows only the parent- and child-directories of a particular directory. The TixDirTree widget, on the other hand, can display the whole tree structure of the file system.

The programming interface of these two widgets are the same and you can choose the which one to use depending on your application. As shown in the following example, you can use the -directory option of the TixDirList widget to specify a directory to display. In the example, we set -directory to be /home/ioi/dev. As a result, the TixDirList widget displays all the subdirectories and all the ancestor directories of /home/ioi/dev. You can use the -command and -browsecmd options to handle the user events: a double click or Return key-stroke will trigger the -command option and a single click or space bar key stroke will trigger the -browsecmd option. Normally, you would handle both type of events in the same manner, as we have done in program 5-5

tixDirList .d -value /home/ioi/dev 
-command "selectDir" -browsecmd "selectDir" pack .d

proc selectDir {dir} { puts "now you select $dir" }

(Figure 5-5) Using the TixDirList widget



(Figure 5-6) The DirTree and DirList Widgets