# 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

> ####
> DirTree

> ####
> DirList

> ### (Figure 5-6) The DirTree and DirList Widgets