home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / entryfield.itk < prev    next >
Text File  |  2003-09-01  |  21KB  |  604 lines

  1. #
  2. # Entryfield
  3. # ----------------------------------------------------------------------
  4. # Implements an enhanced text entry widget.
  5. #
  6. # ----------------------------------------------------------------------
  7. #   AUTHOR:  Sue Yockey               E-mail: yockey@acm.org
  8. #            Mark L. Ulferts          E-mail: mulferts@austin.dsccc.com
  9. #
  10. #   @(#) $Id: entryfield.itk,v 1.6 2001/09/17 19:24:46 smithc Exp $
  11. # ----------------------------------------------------------------------
  12. #            Copyright (c) 1995 DSC Technologies Corporation
  13. # ======================================================================
  14. # Permission to use, copy, modify, distribute and license this software 
  15. # and its documentation for any purpose, and without fee or written 
  16. # agreement with DSC, is hereby granted, provided that the above copyright 
  17. # notice appears in all copies and that both the copyright notice and 
  18. # warranty disclaimer below appear in supporting documentation, and that 
  19. # the names of DSC Technologies Corporation or DSC Communications 
  20. # Corporation not be used in advertising or publicity pertaining to the 
  21. # software without specific, written prior permission.
  22. # DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
  23. # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
  24. # INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
  25. # AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, 
  26. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL 
  27. # DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 
  28. # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  29. # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
  30. # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
  31. # SOFTWARE.
  32. # ======================================================================
  33.  
  34. #
  35. # Usual options.
  36. #
  37. itk::usual Entryfield {
  38.     keep -background -borderwidth -cursor -foreground -highlightcolor \
  39.      -highlightthickness -insertbackground -insertborderwidth \
  40.      -insertofftime -insertontime -insertwidth -labelfont \
  41.      -selectbackground -selectborderwidth -selectforeground \
  42.      -textbackground -textfont
  43. }
  44.  
  45. # ------------------------------------------------------------------
  46. #                            ENTRYFIELD
  47. # ------------------------------------------------------------------
  48. itcl::class iwidgets::Entryfield {
  49.     inherit iwidgets::Labeledwidget 
  50.     
  51.     constructor {args} {}
  52.  
  53.     itk_option define -childsitepos childSitePos Position e
  54.     itk_option define -command command Command {}
  55.     itk_option define -fixed fixed Fixed 0
  56.     itk_option define -focuscommand focusCommand Command {}
  57.     itk_option define -invalid invalid Command {bell}
  58.     itk_option define -pasting pasting Behavior 1
  59.     itk_option define -validate validate Command {}
  60.     
  61.     public {
  62.     method childsite {}
  63.     method get {}
  64.     method delete {args}
  65.     method icursor {args}
  66.     method index {args}
  67.     method insert {args}
  68.     method scan {args}
  69.     method selection {args}
  70.     method xview {args}
  71.     method clear {}
  72.     }
  73.  
  74.     proc numeric {char} {}
  75.     proc integer {string} {}
  76.     proc alphabetic {char} {}
  77.     proc alphanumeric {char} {}
  78.     proc hexidecimal {string} {}
  79.     proc real {string} {}
  80.  
  81.     protected {
  82.     method _focusCommand {}
  83.     method _keyPress {char sym state}
  84.     }
  85.  
  86.     private method _peek {char}
  87.     private method _checkLength {}
  88. }
  89.  
  90. #
  91. # Provide a lowercased access method for the Entryfield class.
  92. proc ::iwidgets::entryfield {pathName args} {
  93.     uplevel ::iwidgets::Entryfield $pathName $args
  94. }
  95.  
  96. # ------------------------------------------------------------------
  97. #                        CONSTRUCTOR
  98. # ------------------------------------------------------------------
  99. itcl::body iwidgets::Entryfield::constructor {args} {
  100.     component hull configure -borderwidth 0
  101.     
  102.     itk_component add entry {
  103.     entry $itk_interior.entry
  104.     } {
  105.     keep -borderwidth -cursor -exportselection \
  106.         -foreground -highlightcolor \
  107.         -highlightthickness -insertbackground -insertborderwidth \
  108.         -insertofftime -insertontime -insertwidth -justify \
  109.         -relief -selectbackground -selectborderwidth \
  110.         -selectforeground -show -state -textvariable -width
  111.     
  112.     rename -font -textfont textFont Font
  113.     rename -highlightbackground -background background Background
  114.     rename -background -textbackground textBackground Background
  115.     }
  116.     
  117.     #
  118.     # Create the child site widget.
  119.     #
  120.     itk_component add -protected efchildsite {
  121.     frame $itk_interior.efchildsite
  122.     } 
  123.     set itk_interior $itk_component(efchildsite)
  124.     
  125.     #
  126.     # Entryfield instance bindings.
  127.     #
  128.     bind $itk_component(entry) <KeyPress> [itcl::code $this _keyPress %A %K %s]
  129.     bind $itk_component(entry) <FocusIn> [itcl::code $this _focusCommand]
  130.  
  131.     #
  132.     # Initialize the widget based on the command line options.
  133.     #
  134.     eval itk_initialize $args
  135. }
  136.  
  137. # ------------------------------------------------------------------
  138. #                             OPTIONS
  139. # ------------------------------------------------------------------
  140.  
  141. # ------------------------------------------------------------------
  142. # OPTION: -command
  143. #
  144. # Command associated upon detection of Return key press event
  145. # ------------------------------------------------------------------
  146. itcl::configbody iwidgets::Entryfield::command {}
  147.  
  148. # ------------------------------------------------------------------
  149. # OPTION: -focuscommand
  150. #
  151. # Command associated upon detection of focus.
  152. # ------------------------------------------------------------------
  153. itcl::configbody iwidgets::Entryfield::focuscommand {}
  154.  
  155. # ------------------------------------------------------------------
  156. # OPTION: -validate
  157. #
  158. # Specify a command to executed for the validation of Entryfields.
  159. # ------------------------------------------------------------------
  160. itcl::configbody iwidgets::Entryfield::validate {
  161.     switch $itk_option(-validate) {
  162.     {} {
  163.         set itk_option(-validate) {}
  164.     }
  165.     numeric {
  166.         set itk_option(-validate) "::iwidgets::Entryfield::numeric %c"
  167.     }
  168.     integer {
  169.         set itk_option(-validate) "::iwidgets::Entryfield::integer %P"
  170.     }
  171.     hexidecimal {
  172.         set itk_option(-validate) "::iwidgets::Entryfield::hexidecimal %P"
  173.     }
  174.     real {
  175.         set itk_option(-validate) "::iwidgets::Entryfield::real %P"
  176.     }
  177.     alphabetic {
  178.         set itk_option(-validate) "::iwidgets::Entryfield::alphabetic %c"
  179.     }
  180.     alphanumeric {
  181.         set itk_option(-validate) "::iwidgets::Entryfield::alphanumeric %c"
  182.     }
  183.     }
  184. }
  185.  
  186. # ------------------------------------------------------------------
  187. # OPTION: -invalid
  188. #
  189. # Specify a command to executed should the current Entryfield contents
  190. # be proven invalid.
  191. # ------------------------------------------------------------------
  192. itcl::configbody iwidgets::Entryfield::invalid {}
  193.  
  194. # ------------------------------------------------------------------
  195. # OPTION: -pasting
  196. #
  197. # Allows the developer to enable and disable pasting into the entry
  198. # component of the entryfield.  This is done to avoid potential stack
  199. # dumps when using the -validate configuration option.  Plus, it's just
  200. # a good idea to have complete control over what you allow the user
  201. # to enter into the entryfield.
  202. # ------------------------------------------------------------------
  203. itcl::configbody iwidgets::Entryfield::pasting {
  204.   set oldtags [bindtags $itk_component(entry)]
  205.   if {[lindex $oldtags 0] != "pastetag"} {
  206.     bindtags $itk_component(entry) [linsert $oldtags 0 pastetag] 
  207.   }
  208.  
  209.   if ($itk_option(-pasting)) {
  210.     bind pastetag <ButtonRelease-2> [itcl::code $this _checkLength]
  211.     bind pastetag <Control-v> [itcl::code $this _checkLength]
  212.     bind pastetag <Insert> [itcl::code $this _checkLength]
  213.     bind pastetag <KeyPress> {}
  214.   } else {
  215.     bind pastetag <ButtonRelease-2> {break}
  216.     bind pastetag <Control-v> {break}
  217.     bind pastetag <Insert> {break}
  218.     bind pastetag <KeyPress> {
  219.       # Disable function keys > F9.
  220.       if {[regexp {^F[1,2][0-9]+$} "%K"]} {
  221.     break
  222.       }
  223.     }
  224.   }
  225. }
  226.  
  227. # ------------------------------------------------------------------
  228. # OPTION: -fixed
  229. #
  230. # Restrict entry to 0 (unlimited) chars.  The value is the maximum 
  231. # number of chars the user may type into the field, regardles of 
  232. # field width, i.e. the field width may be 20, but the user will 
  233. # only be able to type -fixed number of characters into it (or 
  234. # unlimited if -fixed = 0).
  235. # ------------------------------------------------------------------
  236. itcl::configbody iwidgets::Entryfield::fixed {
  237.     if {[regexp {[^0-9]} $itk_option(-fixed)] || \
  238.         ($itk_option(-fixed) < 0)} {
  239.     error "bad fixed option \"$itk_option(-fixed)\",\
  240.         should be positive integer"
  241.     }
  242. }
  243.  
  244. # ------------------------------------------------------------------
  245. # OPTION: -childsitepos
  246. #
  247. # Specifies the position of the child site in the widget.
  248. # ------------------------------------------------------------------
  249. itcl::configbody iwidgets::Entryfield::childsitepos {
  250.     set parent [winfo parent $itk_component(entry)]
  251.  
  252.     switch $itk_option(-childsitepos) {
  253.     n {
  254.         grid $itk_component(efchildsite) -row 0 -column 0 -sticky ew
  255.         grid $itk_component(entry) -row 1 -column 0 -sticky nsew
  256.  
  257.         grid rowconfigure $parent 0 -weight 0
  258.         grid rowconfigure $parent 1 -weight 1
  259.         grid columnconfigure $parent 0 -weight 1
  260.         grid columnconfigure $parent 1 -weight 0
  261.     }
  262.     
  263.     e {
  264.         grid $itk_component(efchildsite) -row 0 -column 1 -sticky ns
  265.         grid $itk_component(entry) -row 0 -column 0 -sticky nsew
  266.  
  267.         grid rowconfigure $parent 0 -weight 1
  268.         grid rowconfigure $parent 1 -weight 0
  269.         grid columnconfigure $parent 0 -weight 1
  270.         grid columnconfigure $parent 1 -weight 0
  271.     }
  272.     
  273.     s {
  274.         grid $itk_component(efchildsite) -row 1 -column 0 -sticky ew
  275.         grid $itk_component(entry) -row 0 -column 0 -sticky nsew
  276.  
  277.         grid rowconfigure $parent 0 -weight 1
  278.         grid rowconfigure $parent 1 -weight 0
  279.         grid columnconfigure $parent 0 -weight 1
  280.         grid columnconfigure $parent 1 -weight 0
  281.     }
  282.     
  283.     w {
  284.         grid $itk_component(efchildsite) -row 0 -column 0 -sticky ns
  285.         grid $itk_component(entry) -row 0 -column 1 -sticky nsew
  286.  
  287.         grid rowconfigure $parent 0 -weight 1
  288.         grid rowconfigure $parent 1 -weight 0
  289.         grid columnconfigure $parent 0 -weight 0
  290.         grid columnconfigure $parent 1 -weight 1
  291.     }
  292.     
  293.     default {
  294.         error "bad childsite option\
  295.             \"$itk_option(-childsitepos)\":\
  296.             should be n, e, s, or w"
  297.     }
  298.     }
  299. }
  300.  
  301. # ------------------------------------------------------------------
  302. #                            METHODS
  303. # ------------------------------------------------------------------
  304.  
  305. # ------------------------------------------------------------------
  306. # METHOD: childsite
  307. #
  308. # Returns the path name of the child site widget.
  309. # ------------------------------------------------------------------
  310. itcl::body iwidgets::Entryfield::childsite {} {
  311.     return $itk_component(efchildsite)
  312. }
  313.  
  314. # ------------------------------------------------------------------
  315. # METHOD: get 
  316. #
  317. # Thin wrap of the standard entry widget get method.
  318. # ------------------------------------------------------------------
  319. itcl::body iwidgets::Entryfield::get {} {
  320.     return [$itk_component(entry) get]
  321. }
  322.  
  323. # ------------------------------------------------------------------
  324. # METHOD: delete
  325. #
  326. # Thin wrap of the standard entry widget delete method.
  327. # ------------------------------------------------------------------
  328. itcl::body iwidgets::Entryfield::delete {args} {
  329.     return [eval $itk_component(entry) delete $args]
  330. }
  331.  
  332. # ------------------------------------------------------------------
  333. # METHOD: icursor 
  334. #
  335. # Thin wrap of the standard entry widget icursor method.
  336. # ------------------------------------------------------------------
  337. itcl::body iwidgets::Entryfield::icursor {args} {
  338.     return [eval $itk_component(entry) icursor $args]
  339. }
  340.  
  341. # ------------------------------------------------------------------
  342. # METHOD: index 
  343. #
  344. # Thin wrap of the standard entry widget index method.
  345. # ------------------------------------------------------------------
  346. itcl::body iwidgets::Entryfield::index {args} {
  347.     return [eval $itk_component(entry) index $args]
  348. }
  349.  
  350. # ------------------------------------------------------------------
  351. # METHOD: insert 
  352. #
  353. # Thin wrap of the standard entry widget index method.
  354. # ------------------------------------------------------------------
  355. itcl::body iwidgets::Entryfield::insert {args} {
  356.     return [eval $itk_component(entry) insert $args]
  357. }
  358.  
  359. # ------------------------------------------------------------------
  360. # METHOD: scan 
  361. #
  362. # Thin wrap of the standard entry widget scan method.
  363. # ------------------------------------------------------------------
  364. itcl::body iwidgets::Entryfield::scan {args} {
  365.     return [eval $itk_component(entry) scan $args]
  366. }
  367.  
  368. # ------------------------------------------------------------------
  369. # METHOD: selection
  370. #
  371. # Thin wrap of the standard entry widget selection method.
  372. # ------------------------------------------------------------------
  373. itcl::body iwidgets::Entryfield::selection {args} {
  374.     return [eval $itk_component(entry) selection $args]
  375. }
  376.  
  377. # ------------------------------------------------------------------
  378. # METHOD: xview 
  379. #
  380. # Thin wrap of the standard entry widget xview method.
  381. # ------------------------------------------------------------------
  382. itcl::body iwidgets::Entryfield::xview {args} {
  383.     return [eval $itk_component(entry) xview $args]
  384. }
  385.  
  386. # ------------------------------------------------------------------
  387. # METHOD: clear 
  388. #
  389. # Delete the current entry contents.
  390. # ------------------------------------------------------------------
  391. itcl::body iwidgets::Entryfield::clear {} {
  392.     $itk_component(entry) delete 0 end
  393.     icursor 0
  394. }
  395.  
  396. # ------------------------------------------------------------------
  397. # PROCEDURE: numeric char
  398. #
  399. # The numeric procedure validates character input for a given 
  400. # Entryfield to be numeric and returns the result.
  401. # ------------------------------------------------------------------
  402. itcl::body iwidgets::Entryfield::numeric {char} {
  403.     return [regexp {[0-9]} $char]
  404. }
  405.  
  406. # ------------------------------------------------------------------
  407. # PROCEDURE: integer string
  408. #
  409. # The integer procedure validates character input for a given 
  410. # Entryfield to be integer and returns the result.
  411. # ------------------------------------------------------------------
  412. itcl::body iwidgets::Entryfield::integer {string} {
  413.     return [regexp {^[-+]?[0-9]*$} $string]
  414. }
  415.  
  416. # ------------------------------------------------------------------
  417. # PROCEDURE: alphabetic char
  418. #
  419. # The alphabetic procedure validates character input for a given 
  420. # Entryfield to be alphabetic and returns the result.
  421. # ------------------------------------------------------------------
  422. itcl::body iwidgets::Entryfield::alphabetic {char} {
  423.     return [regexp -nocase {[a-z]} $char]
  424. }
  425.  
  426. # ------------------------------------------------------------------
  427. # PROCEDURE: alphanumeric char
  428. #
  429. # The alphanumeric procedure validates character input for a given 
  430. # Entryfield to be alphanumeric and returns the result.
  431. # ------------------------------------------------------------------
  432. itcl::body iwidgets::Entryfield::alphanumeric {char} {
  433.     return [regexp -nocase {[0-9a-z]} $char]
  434. }
  435.  
  436. # ------------------------------------------------------------------
  437. # PROCEDURE: hexadecimal string
  438. #
  439. # The hexidecimal procedure validates character input for a given 
  440. # Entryfield to be hexidecimal and returns the result.
  441. # ------------------------------------------------------------------
  442. itcl::body iwidgets::Entryfield::hexidecimal {string} {
  443.     return [regexp {^(0x)?[0-9a-fA-F]*$} $string]
  444. }
  445.  
  446. # ------------------------------------------------------------------
  447. # PROCEDURE: real string
  448. #
  449. # The real procedure validates character input for a given Entryfield
  450. # to be real and returns the result.
  451. # ------------------------------------------------------------------
  452. itcl::body iwidgets::Entryfield::real {string} {
  453.     return [regexp {^[-+]?[0-9]*\.?[0-9]*([0-9]\.?[eE][-+]?[0-9]*)?$} $string]
  454. }
  455.  
  456. # ------------------------------------------------------------------
  457. # PRIVATE METHOD: _peek char
  458. #
  459. # The peek procedure returns the value of the Entryfield with the
  460. # char inserted at the insert position.
  461. # ------------------------------------------------------------------
  462. itcl::body iwidgets::Entryfield::_peek {char} {
  463.     set str [get]
  464.  
  465.     set insertPos [index insert] 
  466.     set firstPart [string range $str 0 [expr {$insertPos - 1}]]
  467.     set lastPart [string range $str $insertPos end]
  468.  
  469.     regsub -all {\\} "$char" {\\\\} char
  470.     append rtnVal $firstPart $char $lastPart
  471.     return $rtnVal
  472. }
  473.  
  474. # ------------------------------------------------------------------
  475. # PROTECTED METHOD: _focusCommand
  476. #
  477. # Method bound to focus event which evaluates the current command
  478. # specified in the focuscommand option
  479. # ------------------------------------------------------------------
  480. itcl::body iwidgets::Entryfield::_focusCommand {} {
  481.     uplevel #0 $itk_option(-focuscommand)
  482. }
  483.  
  484. # ------------------------------------------------------------------
  485. # PROTECTED METHOD: _keyPress 
  486. #
  487. # Monitor the key press event checking for return keys, fixed width
  488. # specification, and optional validation procedures.
  489. # ------------------------------------------------------------------
  490. itcl::body iwidgets::Entryfield::_keyPress {char sym state} {
  491.     #
  492.     # A Return key invokes the optionally specified command option.
  493.     #
  494.     if {$sym == "Return"} {
  495.     uplevel #0 $itk_option(-command)
  496.     return -code break 1
  497.     } 
  498.     
  499.     #
  500.     # Tabs, BackSpace, and Delete are passed on for other bindings.
  501.     #
  502.     if {($sym == "Tab") || ($sym == "BackSpace") || ($sym == "Delete")} {
  503.     return -code continue 1
  504.     }
  505.  
  506.     # 
  507.     # Character is not printable or the state is greater than one which
  508.     # means a modifier was used such as a control, meta key, or control
  509.     # or meta key with numlock down.
  510.     #
  511.     #-----------------------------------------------------------
  512.     # BUG FIX: csmith (Chad Smith: csmith@adc.com), 3/15/99
  513.     #-----------------------------------------------------------
  514.     # The following conditional used to hardcode specific state values, such
  515.     # as "4" and "8".  These values are used to detect <Ctrl>, <Shift>, etc.
  516.     # key combinations.  On the windows platform, the <Alt> key is state
  517.     # 16, and on the unix platform, the <Alt> key is state 8.  All <Ctrl>
  518.     # and <Alt> combinations should be masked out, regardless of the
  519.     # <NumLock> or <CapsLock> status, and regardless of platform.
  520.     #-----------------------------------------------------------
  521.     set CTRL 4
  522.     global tcl_platform
  523.     if {$tcl_platform(platform) == "unix"} {
  524.       set ALT 8
  525.     } elseif {$tcl_platform(platform) == "windows"} {
  526.       set ALT 16
  527.     } else {
  528.       # This is something other than UNIX or WINDOWS.  Default to the
  529.       # old behavior (UNIX).
  530.       set ALT 8
  531.     }
  532.     # Thanks to Rolf Schroedter for the following elegant conditional.  This
  533.     # masks out all <Ctrl> and <Alt> key combinations.
  534.     if {($char == "") || ($state & ($CTRL | $ALT))} {
  535.       return -code continue 1
  536.     }
  537.  
  538.     #
  539.     # If the fixed length option is not zero, then verify that the
  540.     # current length plus one will not exceed the limit.  If so then
  541.     # invoke the invalid command procedure.
  542.     #
  543.     if {$itk_option(-fixed) != 0} {
  544.     if {[string length [get]] >= $itk_option(-fixed)} {
  545.         uplevel #0 $itk_option(-invalid)
  546.         return -code break 0
  547.     }
  548.     } 
  549.     
  550.     #
  551.     # The validate option may contain a keyword (numeric, alphabetic),
  552.     # the name of a procedure, or nothing.  The numeric and alphabetic
  553.     # keywords engage typical base level checks.  If a command procedure
  554.     # is specified, then invoke it with the object and character passed
  555.     # as arguments.  If the validate procedure returns false, then the 
  556.     # invalid procedure is called.
  557.     #
  558.     if {$itk_option(-validate) != {}} {
  559.     set cmd $itk_option(-validate)
  560.  
  561.     regsub -all "%W" "$cmd" $itk_component(hull) cmd
  562.     regsub -all "%P" "$cmd" [list [_peek $char]] cmd
  563.     regsub -all "%S" "$cmd" [list [get]] cmd
  564.     regsub -all "%c" "$cmd" [list $char] cmd
  565.         regsub -all {\\} "$cmd" {\\\\} cmd
  566.  
  567.     set valid [uplevel #0 $cmd]
  568.     
  569.     if {($valid == "") || ([regexp 0|false|off|no $valid])} {
  570.         uplevel #0 $itk_option(-invalid)
  571.         return -code break 0
  572.     }
  573.     }
  574.     
  575.     return -code continue 1
  576. }
  577.  
  578. # ------------------------------------------------------------------
  579. # PRIVATE METHOD: _checkLength
  580. #
  581. # This method was added by csmith for SF ticket 227912. We need to
  582. # to check the clipboard content before allowing any pasting into
  583. # the entryfield to disallow text that is longer than the value
  584. # specified by the -fixed option.
  585. # ------------------------------------------------------------------
  586. itcl::body iwidgets::Entryfield::_checkLength {} {
  587.   if {$itk_option(-fixed) != 0} {
  588.     if [catch {::selection get -selection CLIPBOARD} pending] {
  589.       # Nothing in the clipboard.  Check the primary selection.
  590.       if [catch {::selection get -selection PRIMARY} pending] {
  591.         # Nothing here either.  Goodbye.
  592.         return
  593.       }
  594.     }
  595.     set len [expr {[string length $pending] + [string length [get]]}]
  596.     if {$len > $itk_option(-fixed)} {
  597.       uplevel #0 $itk_option(-invalid)
  598.       return -code break 0
  599.     }
  600.   }
  601. }
  602.