comdlg.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:7k
源码类别:

通讯编程

开发平台:

Visual C++

  1. # comdlg.tcl --
  2. #
  3. # Some functions needed for the common dialog boxes. Probably need to go
  4. # in a different file.
  5. #
  6. # RCS: @(#) $Id: comdlg.tcl,v 1.9.2.1 2006/01/25 18:21:41 dgp Exp $
  7. #
  8. # Copyright (c) 1996 Sun Microsystems, Inc.
  9. #
  10. # See the file "license.terms" for information on usage and redistribution
  11. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12. #
  13. # tclParseConfigSpec --
  14. #
  15. # Parses a list of "-option value" pairs. If all options and
  16. # values are legal, the values are stored in
  17. # $data($option). Otherwise an error message is returned. When
  18. # an error happens, the data() array may have been partially
  19. # modified, but all the modified members of the data(0 array are
  20. # guaranteed to have valid values. This is different than
  21. # Tk_ConfigureWidget() which does not modify the value of a
  22. # widget record if any error occurs.
  23. #
  24. # Arguments:
  25. #
  26. # w = widget record to modify. Must be the pathname of a widget.
  27. #
  28. # specs = {
  29. #    {-commandlineswitch resourceName ResourceClass defaultValue verifier}
  30. #    {....}
  31. # }
  32. #
  33. # flags = currently unused.
  34. #
  35. # argList = The list of  "-option value" pairs.
  36. #
  37. proc tclParseConfigSpec {w specs flags argList} {
  38.     upvar #0 $w data
  39.     # 1: Put the specs in associative arrays for faster access
  40.     #
  41.     foreach spec $specs {
  42. if {[llength $spec] < 4} {
  43.     error ""spec" should contain 5 or 4 elements"
  44. }
  45. set cmdsw [lindex $spec 0]
  46. set cmd($cmdsw) ""
  47. set rname($cmdsw)   [lindex $spec 1]
  48. set rclass($cmdsw)  [lindex $spec 2]
  49. set def($cmdsw)     [lindex $spec 3]
  50. set verproc($cmdsw) [lindex $spec 4]
  51.     }
  52.     if {[llength $argList] & 1} {
  53. set cmdsw [lindex $argList end]
  54. if {![info exists cmd($cmdsw)]} {
  55.     error "bad option "$cmdsw": must be [tclListValidFlags cmd]"
  56. }
  57. error "value for "$cmdsw" missing"
  58.     }
  59.     # 2: set the default values
  60.     #
  61.     foreach cmdsw [array names cmd] {
  62. set data($cmdsw) $def($cmdsw)
  63.     }
  64.     # 3: parse the argument list
  65.     #
  66.     foreach {cmdsw value} $argList {
  67. if {![info exists cmd($cmdsw)]} {
  68.     error "bad option "$cmdsw": must be [tclListValidFlags cmd]"
  69. }
  70. set data($cmdsw) $value
  71.     }
  72.     # Done!
  73. }
  74. proc tclListValidFlags {v} {
  75.     upvar $v cmd
  76.     set len [llength [array names cmd]]
  77.     set i 1
  78.     set separator ""
  79.     set errormsg ""
  80.     foreach cmdsw [lsort [array names cmd]] {
  81. append errormsg "$separator$cmdsw"
  82. incr i
  83. if {$i == $len} {
  84.     set separator ", or "
  85. } else {
  86.     set separator ", "
  87. }
  88.     }
  89.     return $errormsg
  90. }
  91. #----------------------------------------------------------------------
  92. #
  93. # Focus Group
  94. #
  95. # Focus groups are used to handle the user's focusing actions inside a
  96. # toplevel.
  97. #
  98. # One example of using focus groups is: when the user focuses on an
  99. # entry, the text in the entry is highlighted and the cursor is put to
  100. # the end of the text. When the user changes focus to another widget,
  101. # the text in the previously focused entry is validated.
  102. #
  103. #----------------------------------------------------------------------
  104. # ::tk::FocusGroup_Create --
  105. #
  106. # Create a focus group. All the widgets in a focus group must be
  107. # within the same focus toplevel. Each toplevel can have only
  108. # one focus group, which is identified by the name of the
  109. # toplevel widget.
  110. #
  111. proc ::tk::FocusGroup_Create {t} {
  112.     variable ::tk::Priv
  113.     if {[winfo toplevel $t] ne $t} {
  114. error "$t is not a toplevel window"
  115.     }
  116.     if {![info exists Priv(fg,$t)]} {
  117. set Priv(fg,$t) 1
  118. set Priv(focus,$t) ""
  119. bind $t <FocusIn>  [list tk::FocusGroup_In  $t %W %d]
  120. bind $t <FocusOut> [list tk::FocusGroup_Out $t %W %d]
  121. bind $t <Destroy>  [list tk::FocusGroup_Destroy $t %W]
  122.     }
  123. }
  124. # ::tk::FocusGroup_BindIn --
  125. #
  126. # Add a widget into the "FocusIn" list of the focus group. The $cmd will be
  127. # called when the widget is focused on by the user.
  128. #
  129. proc ::tk::FocusGroup_BindIn {t w cmd} {
  130.     variable FocusIn
  131.     variable ::tk::Priv
  132.     if {![info exists Priv(fg,$t)]} {
  133. error "focus group "$t" doesn't exist"
  134.     }
  135.     set FocusIn($t,$w) $cmd
  136. }
  137. # ::tk::FocusGroup_BindOut --
  138. #
  139. # Add a widget into the "FocusOut" list of the focus group. The
  140. # $cmd will be called when the widget loses the focus (User
  141. # types Tab or click on another widget).
  142. #
  143. proc ::tk::FocusGroup_BindOut {t w cmd} {
  144.     variable FocusOut
  145.     variable ::tk::Priv
  146.     if {![info exists Priv(fg,$t)]} {
  147. error "focus group "$t" doesn't exist"
  148.     }
  149.     set FocusOut($t,$w) $cmd
  150. }
  151. # ::tk::FocusGroup_Destroy --
  152. #
  153. # Cleans up when members of the focus group is deleted, or when the
  154. # toplevel itself gets deleted.
  155. #
  156. proc ::tk::FocusGroup_Destroy {t w} {
  157.     variable FocusIn
  158.     variable FocusOut
  159.     variable ::tk::Priv
  160.     if {$t eq $w} {
  161. unset Priv(fg,$t)
  162. unset Priv(focus,$t) 
  163. foreach name [array names FocusIn $t,*] {
  164.     unset FocusIn($name)
  165. }
  166. foreach name [array names FocusOut $t,*] {
  167.     unset FocusOut($name)
  168. }
  169.     } else {
  170. if {[info exists Priv(focus,$t)] && $Priv(focus,$t) eq $w} {
  171.     set Priv(focus,$t) ""
  172. }
  173. unset -nocomplain FocusIn($t,$w) FocusOut($t,$w)
  174.     }
  175. }
  176. # ::tk::FocusGroup_In --
  177. #
  178. # Handles the <FocusIn> event. Calls the FocusIn command for the newly
  179. # focused widget in the focus group.
  180. #
  181. proc ::tk::FocusGroup_In {t w detail} {
  182.     variable FocusIn
  183.     variable ::tk::Priv
  184.     if {$detail ne "NotifyNonlinear" && $detail ne "NotifyNonlinearVirtual"} {
  185. # This is caused by mouse moving out&in of the window *or*
  186. # ordinary keypresses some window managers (ie: CDE [Bug: 2960]).
  187. return
  188.     }
  189.     if {![info exists FocusIn($t,$w)]} {
  190. set FocusIn($t,$w) ""
  191. return
  192.     }
  193.     if {![info exists Priv(focus,$t)]} {
  194. return
  195.     }
  196.     if {$Priv(focus,$t) eq $w} {
  197. # This is already in focus
  198. #
  199. return
  200.     } else {
  201. set Priv(focus,$t) $w
  202. eval $FocusIn($t,$w)
  203.     }
  204. }
  205. # ::tk::FocusGroup_Out --
  206. #
  207. # Handles the <FocusOut> event. Checks if this is really a lose
  208. # focus event, not one generated by the mouse moving out of the
  209. # toplevel window.  Calls the FocusOut command for the widget
  210. # who loses its focus.
  211. #
  212. proc ::tk::FocusGroup_Out {t w detail} {
  213.     variable FocusOut
  214.     variable ::tk::Priv
  215.     if {$detail ne "NotifyNonlinear" && $detail ne "NotifyNonlinearVirtual"} {
  216. # This is caused by mouse moving out of the window
  217. return
  218.     }
  219.     if {![info exists Priv(focus,$t)]} {
  220. return
  221.     }
  222.     if {![info exists FocusOut($t,$w)]} {
  223. return
  224.     } else {
  225. eval $FocusOut($t,$w)
  226. set Priv(focus,$t) ""
  227.     }
  228. }
  229. # ::tk::FDGetFileTypes --
  230. #
  231. # Process the string given by the -filetypes option of the file
  232. # dialogs. Similar to the C function TkGetFileFilters() on the Mac
  233. # and Windows platform.
  234. #
  235. proc ::tk::FDGetFileTypes {string} {
  236.     foreach t $string {
  237. if {[llength $t] < 2 || [llength $t] > 3} {
  238.     error "bad file type "$t", should be "typeName {extension ?extensions ...?} ?{macType ?macTypes ...?}?""
  239. }
  240. eval lappend [list fileTypes([lindex $t 0])] [lindex $t 1]
  241.     }
  242.     set types {}
  243.     foreach t $string {
  244. set label [lindex $t 0]
  245. set exts {}
  246. if {[info exists hasDoneType($label)]} {
  247.     continue
  248. }
  249. set name "$label ("
  250. set sep ""
  251. set doAppend 1
  252. foreach ext $fileTypes($label) {
  253.     if {$ext eq ""} {
  254. continue
  255.     }
  256.     regsub {^[.]} $ext "*." ext
  257.     if {![info exists hasGotExt($label,$ext)]} {
  258. if {$doAppend} {
  259.     if {[string length $sep] && [string length $name]>40} {
  260. set doAppend 0
  261. append name $sep...
  262.     } else {
  263. append name $sep$ext
  264.     }
  265. }
  266. lappend exts $ext
  267. set hasGotExt($label,$ext) 1
  268.     }
  269.     set sep ","
  270. }
  271. append name ")"
  272. lappend types [list $name $exts]
  273. set hasDoneType($label) 1
  274.     }
  275.     return $types
  276. }