Changeset 4276 for trunk/gui


Ignore:
Timestamp:
Mar 26, 2014 1:32:32 PM (10 years ago)
Author:
gah
Message:

fix: race condition in _layout, finalize called when widgets deleted

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gui/scripts/textentry.tcl

    r3700 r4276  
    6464    private variable _icon ""       ;# size hint from XML
    6565}
    66                                                                                
     66
    6767itk::usual TextEntry {
    6868    keep -foreground -background -textbackground -font -cursor
     
    246246        }
    247247
     248        # Set the _layout here because unpacking the widgets triggers
     249        # the "_edit finalize" method (focus change).
     250
     251        set _layout $newlayout
     252
    248253        # take down any existing widget
    249254        foreach win [pack slaves $itk_interior] {
     
    254259
    255260        switch -- $newlayout {
    256           entry {
    257             # don't have the entry widget yet? then create it
    258             if {![winfo exists $itk_interior.entry]} {
    259                 itk_component add entry {
    260                     entry $itk_interior.entry
    261                 } {
    262                     usual
    263                     rename -background -textbackground textBackground Background
    264                     rename -foreground -textforeground textForeground Foreground
     261            entry {
     262                # don't have the entry widget yet? then create it
     263                if {![winfo exists $itk_interior.entry]} {
     264                    itk_component add entry {
     265                        entry $itk_interior.entry
     266                    } {
     267                        usual
     268                        rename -background -textbackground textBackground Background
     269                        rename -foreground -textforeground textForeground Foreground
     270                    }
     271                    $itk_component(entry) configure \
     272                        -background $itk_option(-textbackground) \
     273                        -foreground $itk_option(-textforeground)
     274
     275                    # Make sure these event bindings occur after the class bindings.
     276                    # Otherwise you'll always get the entry value before the edit.
     277                    bind textentry-$this <KeyPress> \
     278                        [itcl::code $this _newValue]
     279                    bind textentry-$this <KeyPress-Return> \
     280                        [itcl::code $this _edit finalize]
     281                    bind textentry-$this <Control-KeyPress-a> \
     282                        "[list $itk_component(entry) selection range 0 end]; break"
     283                    bind textentry-$this <FocusOut> \
     284                        [itcl::code $this _edit finalize]
     285                    bind textentry-$this <Unmap> \
     286                        [itcl::code $this _edit finalize]
     287                    set bindtags [bindtags $itk_component(entry)]
     288                    lappend bindtags textentry-$this
     289                    bindtags $itk_component(entry) $bindtags
     290
     291                    itk_component add emenu {
     292                        menu $itk_component(entry).menu -tearoff 0
     293                    }
     294                    $itk_component(emenu) add command \
     295                        -label "Cut" -accelerator "^X" \
     296                        -command [itcl::code $this _edit action entry cut]
     297                    $itk_component(emenu) add command \
     298                        -label "Copy" -accelerator "^C" \
     299                        -command [itcl::code $this _edit action entry copy]
     300                    $itk_component(emenu) add command \
     301                        -label "Paste" -accelerator "^V" \
     302                        -command [itcl::code $this _edit action entry paste]
     303                    $itk_component(emenu) add command \
     304                        -label "Select All" -accelerator "^A" \
     305                        -command [itcl::code $this _edit action entry selectall]
     306                    bind $itk_component(entry) <<PopupMenu>> \
     307                        [itcl::code $this _edit menu emenu %X %Y]
    265308                }
    266                 $itk_component(entry) configure \
    267                     -background $itk_option(-textbackground) \
    268                     -foreground $itk_option(-textforeground)
    269 
    270                 # Make sure these event bindings occur after the class bindings.
    271                 # Otherwise you'll always get the entry value before the edit.
    272                 bind textentry-$this <KeyPress> \
    273                     [itcl::code $this _newValue]
    274                 bind textentry-$this <KeyPress-Return> \
    275                     [itcl::code $this _edit finalize]
    276                 bind textentry-$this <Control-KeyPress-a> \
    277                     "[list $itk_component(entry) selection range 0 end]; break"
    278                 bind textentry-$this <FocusOut> \
    279                     [itcl::code $this _edit finalize]
    280                 bind textentry-$this <Unmap> \
    281                     [itcl::code $this _edit finalize]
    282                 set bindtags [bindtags $itk_component(entry)]
    283                 lappend bindtags textentry-$this
    284                 bindtags $itk_component(entry) $bindtags
    285 
    286                 itk_component add emenu {
    287                     menu $itk_component(entry).menu -tearoff 0
     309
     310                # show the entry widget
     311                pack $itk_component(entry) -expand yes -fill both
     312
     313                # load any previous value
     314                regsub -all "\n" $oldval "" oldval
     315                $itk_component(entry) delete 0 end
     316                $itk_component(entry) insert end $oldval
     317            }
     318
     319            text {
     320                if {![winfo exists $itk_interior.scrl]} {
     321                    itk_component add scrollbars {
     322                        Rappture::Scroller $itk_interior.scrl \
     323                            -xscrollmode auto -yscrollmode auto
     324                    }
     325
     326                    itk_component add text {
     327                        text $itk_component(scrollbars).text \
     328                            -width 1 -height 1 -wrap char
     329                    } {
     330                        usual
     331                        ignore -highlightthickness -highlightcolor
     332                        rename -background -textbackground textBackground Background
     333                        rename -foreground -textforeground textForeground Foreground
     334                        rename -font -codefont codeFont CodeFont
     335                    }
     336                    $itk_component(text) configure \
     337                        -background $itk_option(-textbackground) \
     338                        -foreground $itk_option(-textforeground) \
     339                        -font $itk_option(-codefont) \
     340                        -highlightthickness 1
     341                    $itk_component(scrollbars) contents $itk_component(text)
     342
     343                    # Make sure these event bindings occur after the class bindings.
     344                    # Otherwise you'll always get the text value before the edit.
     345                    bind textentry-$this <KeyPress> \
     346                        [itcl::code $this _newValue]
     347                    # leave [Return] key alone for multi-line text so the user
     348                    # can enter newlines and keep editing
     349                    bind textentry-$this <Control-KeyPress-a> \
     350                        "[list $itk_component(text) tag add sel 1.0 end]; break"
     351                    bind textentry-$this <FocusOut> \
     352                        [itcl::code $this _edit finalize]
     353                    bind textentry-$this <Unmap> \
     354                        [itcl::code $this _edit finalize]
     355                    set bindtags [bindtags $itk_component(text)]
     356                    lappend bindtags textentry-$this
     357                    bindtags $itk_component(text) $bindtags
     358
     359                    itk_component add tmenu {
     360                        menu $itk_component(text).menu -tearoff 0
     361                    }
     362                    $itk_component(tmenu) add command \
     363                        -label "Cut" -accelerator "^X" \
     364                        -command [itcl::code $this _edit action text cut]
     365                    $itk_component(tmenu) add command \
     366                        -label "Copy" -accelerator "^C" \
     367                        -command [itcl::code $this _edit action text copy]
     368                    $itk_component(tmenu) add command \
     369                        -label "Paste" -accelerator "^V" \
     370                        -command [itcl::code $this _edit action text paste]
     371                    $itk_component(tmenu) add command \
     372                        -label "Select All" -accelerator "^A" \
     373                        -command [itcl::code $this _edit action text selectall]
     374                    $itk_component(tmenu) add separator
     375
     376                    $itk_component(tmenu) add command \
     377                        -label [Rappture::filexfer::label upload] \
     378                        -command [itcl::code $this _uploadValue -start]
     379                    $itk_component(tmenu) add command \
     380                        -label [Rappture::filexfer::label download] \
     381                        -command [itcl::code $this _downloadValue]
     382
     383                    bind $itk_component(text) <<PopupMenu>> \
     384                        [itcl::code $this _edit menu tmenu %X %Y]
    288385                }
    289                 $itk_component(emenu) add command \
    290                     -label "Cut" -accelerator "^X" \
    291                     -command [itcl::code $this _edit action entry cut]
    292                 $itk_component(emenu) add command \
    293                     -label "Copy" -accelerator "^C" \
    294                     -command [itcl::code $this _edit action entry copy]
    295                 $itk_component(emenu) add command \
    296                     -label "Paste" -accelerator "^V" \
    297                     -command [itcl::code $this _edit action entry paste]
    298                 $itk_component(emenu) add command \
    299                     -label "Select All" -accelerator "^A" \
    300                     -command [itcl::code $this _edit action entry selectall]
    301                 bind $itk_component(entry) <<PopupMenu>> \
    302                     [itcl::code $this _edit menu emenu %X %Y]
    303             }
    304 
    305             # show the entry widget
    306             pack $itk_component(entry) -expand yes -fill both
    307 
    308             # load any previous value
    309             regsub -all "\n" $oldval "" oldval
    310             $itk_component(entry) delete 0 end
    311             $itk_component(entry) insert end $oldval
    312           }
    313 
    314           text {
    315             if {![winfo exists $itk_interior.scrl]} {
    316                 itk_component add scrollbars {
    317                     Rappture::Scroller $itk_interior.scrl \
    318                          -xscrollmode auto -yscrollmode auto
     386
     387                # show the text editor widget
     388                pack $itk_component(scrollbars) -expand yes -fill both
     389                $itk_component(text) configure -width $w -height $h
     390
     391                # load any previous value
     392                $itk_component(text) delete 1.0 end
     393                $itk_component(text) insert end $oldval
     394            }
     395
     396            binary {
     397                if {![winfo exists $itk_interior.bin]} {
     398                    itk_component add binary {
     399                        frame $itk_interior.bin
     400                    }
     401                    set icon $_icon
     402                    if { $icon == "" } {
     403                        set icon [Rappture::icon binary]
     404                    }
     405                    itk_component add binicon {
     406                        ::label $itk_component(binary).binicon \
     407                            -image $icon -borderwidth 0
     408                    }
     409                    pack $itk_component(binicon) -side left
     410
     411                    itk_component add bininfo {
     412                        ::label $itk_component(binary).bininfo \
     413                            -text "Empty\n0 bytes" \
     414                            -width 5 -justify left -anchor w -borderwidth 0
     415                    }
     416                    pack $itk_component(bininfo) -side left -expand yes -fill x -padx 4
     417
     418                    itk_component add bmenu {
     419                        menu $itk_component(binary).menu -tearoff 0
     420                    }
     421                    $itk_component(bmenu) add command \
     422                        -label [Rappture::filexfer::label upload] \
     423                        -command [itcl::code $this _uploadValue -start]
     424                    $itk_component(bmenu) add command \
     425                        -label [Rappture::filexfer::label download] \
     426                        -command [itcl::code $this _downloadValue]
     427
     428                    bind $itk_component(binicon) <<PopupMenu>> \
     429                        [itcl::code $this _edit menu bmenu %X %Y]
     430                    bind $itk_component(bininfo) <<PopupMenu>> \
     431                        [itcl::code $this _edit menu bmenu %X %Y]
    319432                }
    320433
    321                 itk_component add text {
    322                     text $itk_component(scrollbars).text \
    323                         -width 1 -height 1 -wrap char
    324                 } {
    325                     usual
    326                     ignore -highlightthickness -highlightcolor
    327                     rename -background -textbackground textBackground Background
    328                     rename -foreground -textforeground textForeground Foreground
    329                     rename -font -codefont codeFont CodeFont
    330                 }
    331                 $itk_component(text) configure \
    332                     -background $itk_option(-textbackground) \
    333                     -foreground $itk_option(-textforeground) \
    334                     -font $itk_option(-codefont) \
    335                     -highlightthickness 1
    336                 $itk_component(scrollbars) contents $itk_component(text)
    337 
    338                 # Make sure these event bindings occur after the class bindings.
    339                 # Otherwise you'll always get the text value before the edit.
    340                 bind textentry-$this <KeyPress> \
    341                     [itcl::code $this _newValue]
    342                 # leave [Return] key alone for multi-line text so the user
    343                 # can enter newlines and keep editing
    344                 bind textentry-$this <Control-KeyPress-a> \
    345                     "[list $itk_component(text) tag add sel 1.0 end]; break"
    346                 bind textentry-$this <FocusOut> \
    347                     [itcl::code $this _edit finalize]
    348                 bind textentry-$this <Unmap> \
    349                     [itcl::code $this _edit finalize]
    350                 set bindtags [bindtags $itk_component(text)]
    351                 lappend bindtags textentry-$this
    352                 bindtags $itk_component(text) $bindtags
    353 
    354                 itk_component add tmenu {
    355                     menu $itk_component(text).menu -tearoff 0
    356                 }
    357                 $itk_component(tmenu) add command \
    358                     -label "Cut" -accelerator "^X" \
    359                     -command [itcl::code $this _edit action text cut]
    360                 $itk_component(tmenu) add command \
    361                     -label "Copy" -accelerator "^C" \
    362                     -command [itcl::code $this _edit action text copy]
    363                 $itk_component(tmenu) add command \
    364                     -label "Paste" -accelerator "^V" \
    365                     -command [itcl::code $this _edit action text paste]
    366                 $itk_component(tmenu) add command \
    367                     -label "Select All" -accelerator "^A" \
    368                     -command [itcl::code $this _edit action text selectall]
    369                 $itk_component(tmenu) add separator
    370 
    371                 $itk_component(tmenu) add command \
    372                     -label [Rappture::filexfer::label upload] \
    373                     -command [itcl::code $this _uploadValue -start]
    374                 $itk_component(tmenu) add command \
    375                     -label [Rappture::filexfer::label download] \
    376                     -command [itcl::code $this _downloadValue]
    377 
    378                 bind $itk_component(text) <<PopupMenu>> \
    379                     [itcl::code $this _edit menu tmenu %X %Y]
    380             }
    381 
    382             # show the text editor widget
    383             pack $itk_component(scrollbars) -expand yes -fill both
    384             $itk_component(text) configure -width $w -height $h
    385 
    386             # load any previous value
    387             $itk_component(text) delete 1.0 end
    388             $itk_component(text) insert end $oldval
    389           }
    390 
    391           binary {
    392             if {![winfo exists $itk_interior.bin]} {
    393                 itk_component add binary {
    394                     frame $itk_interior.bin
    395                 }
    396                 set icon $_icon
    397                 if { $icon == "" } {
    398                     set icon [Rappture::icon binary]
    399                 }
    400                 itk_component add binicon {
    401                     ::label $itk_component(binary).binicon \
    402                         -image $icon -borderwidth 0
    403                 }
    404                 pack $itk_component(binicon) -side left
    405 
    406                 itk_component add bininfo {
    407                     ::label $itk_component(binary).bininfo \
    408                         -text "Empty\n0 bytes" \
    409                         -width 5 -justify left -anchor w -borderwidth 0
    410                 }
    411                 pack $itk_component(bininfo) -side left -expand yes -fill x -padx 4
    412 
    413                 itk_component add bmenu {
    414                     menu $itk_component(binary).menu -tearoff 0
    415                 }
    416                 $itk_component(bmenu) add command \
    417                     -label [Rappture::filexfer::label upload] \
    418                     -command [itcl::code $this _uploadValue -start]
    419                 $itk_component(bmenu) add command \
    420                     -label [Rappture::filexfer::label download] \
    421                     -command [itcl::code $this _downloadValue]
    422 
    423                 bind $itk_component(binicon) <<PopupMenu>> \
    424                     [itcl::code $this _edit menu bmenu %X %Y]
    425                 bind $itk_component(bininfo) <<PopupMenu>> \
    426                     [itcl::code $this _edit menu bmenu %X %Y]
    427             }
    428 
    429             # show the binary mode rep
    430             pack $itk_component(binary) -side top -fill x
    431 
    432           }
    433           default {
    434               error "don't know how to handle mode \"$newlayout\" for string editor"
    435           }
    436         }
    437         set _layout $newlayout
     434                # show the binary mode rep
     435                pack $itk_component(binary) -side top -fill x
     436
     437            }
     438            default {
     439                error "don't know how to handle mode \"$newlayout\" for string editor"
     440            }
     441        }
    438442    }
    439443
     
    529533                selectall {
    530534                    switch -- $widget {
    531                       entry { $itk_component(entry) selection range 0 end }
    532                       text  { $itk_component(text) tag add sel 1.0 end }
    533                       default { error "don't know how to select for $widget" }
     535                        entry { $itk_component(entry) selection range 0 end }
     536                        text  { $itk_component(text) tag add sel 1.0 end }
     537                        default { error "don't know how to select for $widget" }
    534538                    }
    535539                }
Note: See TracChangeset for help on using the changeset viewer.