\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#67: Allow Subclassing of tk\_getOpenFile, tk\_getSaveFile on UNIX}
\date{October 09, 2001}
\author{Chris Nelson, Al Zielaskowski}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#67}&\textbf{Allow Subclassing of tk\_getOpenFile, tk\_getSaveFile on UNIX}\\\hline
Author&

Chris Nelson \tipmail{nelson}{pinebush.com}
\par
Al Zielaskowski \tipmail{zielasko}{pinebush.com}
\\
Created&Tuesday, \(\text{9}^{\text{th}}\) October 2001\\
Type&Project\\
Tcl Version&\(8.5\)\\
State&Withdrawn\\
Vote&Pending\\
Version&\tipversion$Revision: 1.5 $\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

On Microsoft Windows it is possible to ``subclass'' a standard dialog and add controls to it. This TIP proposes adding that feature to the \textit{tk\_getOpenFile} and \textit{tk\_getSaveFile} dialogs for non-Windows systems (wherever \textit{tkfbox.tcl} and \textit{xmfbox.tcl} are used for these dialogs).
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

In our work with Tk, we have need to save files in various formats and give the user control over more than just the file name when saving. While it is possible to have two separate dialogs --- one for specifying the file name and location and another for other attributes --- this is unwieldy and not very user friendly: all the related information should be in one dialog

On Microsoft Windows, it is possible to add controls to standard dialogs (indeed any window) via ``subclassing'' (cf \url{http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/commdlg_4qlv.asp}). (This requires C programming but it is, at least, possible.)

On UNIX, no generic technique like subclassing exists. Even if we wished to invade the ``standard dialog,'' --- learning about the window's organization, adding widgets here and there --- calling \textit{tk\_getSaveFile} blocks the caller and then returns a value after the dialog is destroyed so we have no opportunity to manipulate the dialog. To work around this, we need to have \textit{tk\_getSaveFile} call back into user code to add controls when the dialog is built.

\section{Specification}

We add a \textit{-subclass} option to \textit{tk\_getSaveFile} and \textit{tk\_getOpenFile} (on UNIX only). The value of the \textit{-subclass} option is a Tcl command to evaluate to fill an extra frame near the bottom of the dialog. When the dialog is constructed, the subclass command, if any, is evaluated with the path to the frame appended as an additional argument. The subclass command can then fill the frame as needed.

No additional semantic changes are needed for these additional controls to communicate with the program as such communication can be done through side effects. For example, user interaction with a checkbox created by the subclass command can be detected after the \textit{tk\_getSaveFile} dialog is closed by examining the value of the checkbox's global variable.

\section{Reference Implementation}

This proposal has been implemented by Al Zielaskowski. A patch relative to Tk 8.4a3 follows:
\begingroup\small\begin{verbatim}
Index: tkfbox.tcl
===================================================================
RCS file: /pti/prod/mrd/CvsRepository/tcl/tk/library/tkfbox.tcl,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 tkfbox.tcl
--- tkfbox.tcl  2001/09/04 23:51:12     1.1.1.1
+++ tkfbox.tcl  2001/10/09 19:47:50
@@ -898,6 +898,7 @@
        {-initialfile "" "" ""}
        {-parent "" "" "."}
        {-title "" "" ""}
+       {-subclass "" "" ""}
     }
 
     # The "-multiple" option is only available for the "open" file dialog.
@@ -1087,9 +1088,22 @@
     # Pack all the frames together. We are done with widget construction.
     #
     pack $f1 -side top -fill x -pady 4
+
+    #
+    # Add the user's subclass frame if one was specified
+    #
+    if {[string length $data(-subclass)]} {
+       frame $w.subclass -bd 0
+       pack $w.subclass -side bottom -fill x \
+                -padx [list [expr [winfo reqwidth $data(typeMenuLab)] + 8] \
+               [expr [winfo reqwidth $data(okBtn)] + 8]]
+       eval $data(-subclass) $w.subclass
+    }
+
     pack $f3 -side bottom -fill x
     pack $f2 -side bottom -fill x
     pack $data(icons) -expand yes -fill both -padx 4 -pady 1
+
 
     # Set up the event handlers that are common to Directory and File Dialogs
     #
Index: xmfbox.tcl
===================================================================
RCS file: /pti/prod/mrd/CvsRepository/tcl/tk/library/xmfbox.tcl,v
retrieving revision 1.1.1.1
diff -u -w -r1.1.1.1 xmfbox.tcl
--- xmfbox.tcl  2001/09/04 23:51:12     1.1.1.1
+++ xmfbox.tcl  2001/10/09 19:05:57
@@ -216,6 +216,7 @@
        {-initialfile "" "" ""}
        {-parent "" "" "."}
        {-title "" "" ""}
+       {-subclass "" "" ""}
     }
     if { [string equal $type "open"] } {
        lappend specs {-multiple "" "" "0"}
@@ -277,6 +278,7 @@
     if {![winfo exists $data(-parent)]} {
        error "bad window path name \"$data(-parent)\""
     }
+
 }
 
 # ::tk::MotifFDialog_BuildUI --
@@ -360,6 +362,17 @@
 
     pack $bot.ok $bot.filter $bot.cancel -padx 10 -pady 10 -expand yes \
        -side left
+
+
+    #
+    # Add the user's subclass frame if one was specified
+    #
+    if {[string length $data(-subclass)]} {
+       frame $f3.subclass -bd 0
+       pack $f3.subclass -side bottom -fill x -padx 4 -pady 4
+       eval $data(-subclass) $f3.subclass
+    }
+
 
     # Create the bindings:
     #
\end{verbatim}
\endgroup

\section{Notice of Withdrawal}

This TIP was Withdrawn by the TIP Editor following discussion on the tcl-core mailing list. The following is a summary of reasons for withdrawal:

\begin{quote}
This would make porting code between platforms obscenely difficult as there is no way for the subclassing to work the same way on all platforms. Better for people to roll their own, perhaps starting from the foundations of the UNIX file browsing code if they wish.
\end{quote}

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\end{document}
