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.
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.
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 popupproc selectCmd {filename} { puts "You have selected $filename" }
(Figure 5-1) Using the TixFileSelectDialog
(Figure 5-2) The Composition of a TixFileSelectDialog Widget
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.
(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.
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.
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:
When we call the command*myapp*FileDialog: tixExFileSelectDialog
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 popupproc 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.
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 .dproc selectDir {dir} { puts "now you select $dir" }
(Figure 5-5) Using the TixDirList widget
DirTree
DirList (Figure 5-6) The DirTree and DirList Widgets