diff options
Diffstat (limited to 'tk/library/text.tcl')
-rw-r--r-- | tk/library/text.tcl | 461 |
1 files changed, 265 insertions, 196 deletions
diff --git a/tk/library/text.tcl b/tk/library/text.tcl index 7e68e669499..70f6b8c74f0 100644 --- a/tk/library/text.tcl +++ b/tk/library/text.tcl @@ -14,7 +14,7 @@ # #------------------------------------------------------------------------- -# Elements of tkPriv that are used in this file: +# Elements of ::tk::Priv that are used in this file: # # afterId - If non-null, it means that auto-scanning is underway # and it gives the "after" id for the next auto-scan @@ -36,118 +36,116 @@ #------------------------------------------------------------------------- #------------------------------------------------------------------------- -# The code below creates the default class bindings for entries. +# The code below creates the default class bindings for text widgets. #------------------------------------------------------------------------- # Standard Motif bindings: bind Text <1> { - tkTextButton1 %W %x %y + tk::TextButton1 %W %x %y %W tag remove sel 0.0 end } bind Text <B1-Motion> { - set tkPriv(x) %x - set tkPriv(y) %y - tkTextSelectTo %W %x %y + set tk::Priv(x) %x + set tk::Priv(y) %y + tk::TextSelectTo %W %x %y } bind Text <Double-1> { - set tkPriv(selectMode) word - tkTextSelectTo %W %x %y + set tk::Priv(selectMode) word + tk::TextSelectTo %W %x %y catch {%W mark set insert sel.last} - catch {%W mark set anchor sel.first} } bind Text <Triple-1> { - set tkPriv(selectMode) line - tkTextSelectTo %W %x %y + set tk::Priv(selectMode) line + tk::TextSelectTo %W %x %y catch {%W mark set insert sel.last} - catch {%W mark set anchor sel.first} } bind Text <Shift-1> { - tkTextResetAnchor %W @%x,%y - set tkPriv(selectMode) char - tkTextSelectTo %W %x %y + tk::TextResetAnchor %W @%x,%y + set tk::Priv(selectMode) char + tk::TextSelectTo %W %x %y } bind Text <Double-Shift-1> { - set tkPriv(selectMode) word - tkTextSelectTo %W %x %y 1 + set tk::Priv(selectMode) word + tk::TextSelectTo %W %x %y 1 } bind Text <Triple-Shift-1> { - set tkPriv(selectMode) line - tkTextSelectTo %W %x %y + set tk::Priv(selectMode) line + tk::TextSelectTo %W %x %y } bind Text <B1-Leave> { - set tkPriv(x) %x - set tkPriv(y) %y - tkTextAutoScan %W + set tk::Priv(x) %x + set tk::Priv(y) %y + tk::TextAutoScan %W } bind Text <B1-Enter> { - tkCancelRepeat + tk::CancelRepeat } bind Text <ButtonRelease-1> { - tkCancelRepeat + tk::CancelRepeat } bind Text <Control-1> { %W mark set insert @%x,%y } bind Text <Left> { - tkTextSetCursor %W insert-1c + tk::TextSetCursor %W insert-1c } bind Text <Right> { - tkTextSetCursor %W insert+1c + tk::TextSetCursor %W insert+1c } bind Text <Up> { - tkTextSetCursor %W [tkTextUpDownLine %W -1] + tk::TextSetCursor %W [tk::TextUpDownLine %W -1] } bind Text <Down> { - tkTextSetCursor %W [tkTextUpDownLine %W 1] + tk::TextSetCursor %W [tk::TextUpDownLine %W 1] } bind Text <Shift-Left> { - tkTextKeySelect %W [%W index {insert - 1c}] + tk::TextKeySelect %W [%W index {insert - 1c}] } bind Text <Shift-Right> { - tkTextKeySelect %W [%W index {insert + 1c}] + tk::TextKeySelect %W [%W index {insert + 1c}] } bind Text <Shift-Up> { - tkTextKeySelect %W [tkTextUpDownLine %W -1] + tk::TextKeySelect %W [tk::TextUpDownLine %W -1] } bind Text <Shift-Down> { - tkTextKeySelect %W [tkTextUpDownLine %W 1] + tk::TextKeySelect %W [tk::TextUpDownLine %W 1] } bind Text <Control-Left> { - tkTextSetCursor %W [tkTextPrevPos %W insert tcl_startOfPreviousWord] + tk::TextSetCursor %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord] } bind Text <Control-Right> { - tkTextSetCursor %W [tkTextNextWord %W insert] + tk::TextSetCursor %W [tk::TextNextWord %W insert] } bind Text <Control-Up> { - tkTextSetCursor %W [tkTextPrevPara %W insert] + tk::TextSetCursor %W [tk::TextPrevPara %W insert] } bind Text <Control-Down> { - tkTextSetCursor %W [tkTextNextPara %W insert] + tk::TextSetCursor %W [tk::TextNextPara %W insert] } bind Text <Shift-Control-Left> { - tkTextKeySelect %W [tkTextPrevPos %W insert tcl_startOfPreviousWord] + tk::TextKeySelect %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord] } bind Text <Shift-Control-Right> { - tkTextKeySelect %W [tkTextNextWord %W insert] + tk::TextKeySelect %W [tk::TextNextWord %W insert] } bind Text <Shift-Control-Up> { - tkTextKeySelect %W [tkTextPrevPara %W insert] + tk::TextKeySelect %W [tk::TextPrevPara %W insert] } bind Text <Shift-Control-Down> { - tkTextKeySelect %W [tkTextNextPara %W insert] + tk::TextKeySelect %W [tk::TextNextPara %W insert] } bind Text <Prior> { - tkTextSetCursor %W [tkTextScrollPages %W -1] + tk::TextSetCursor %W [tk::TextScrollPages %W -1] } bind Text <Shift-Prior> { - tkTextKeySelect %W [tkTextScrollPages %W -1] + tk::TextKeySelect %W [tk::TextScrollPages %W -1] } bind Text <Next> { - tkTextSetCursor %W [tkTextScrollPages %W 1] + tk::TextSetCursor %W [tk::TextScrollPages %W 1] } bind Text <Shift-Next> { - tkTextKeySelect %W [tkTextScrollPages %W 1] + tk::TextKeySelect %W [tk::TextScrollPages %W 1] } bind Text <Control-Prior> { %W xview scroll -1 page @@ -157,34 +155,36 @@ bind Text <Control-Next> { } bind Text <Home> { - tkTextSetCursor %W {insert linestart} + tk::TextSetCursor %W {insert linestart} } bind Text <Shift-Home> { - tkTextKeySelect %W {insert linestart} + tk::TextKeySelect %W {insert linestart} } bind Text <End> { - tkTextSetCursor %W {insert lineend} + tk::TextSetCursor %W {insert lineend} } bind Text <Shift-End> { - tkTextKeySelect %W {insert lineend} + tk::TextKeySelect %W {insert lineend} } bind Text <Control-Home> { - tkTextSetCursor %W 1.0 + tk::TextSetCursor %W 1.0 } bind Text <Control-Shift-Home> { - tkTextKeySelect %W 1.0 + tk::TextKeySelect %W 1.0 } bind Text <Control-End> { - tkTextSetCursor %W {end - 1 char} + tk::TextSetCursor %W {end - 1 char} } bind Text <Control-Shift-End> { - tkTextKeySelect %W {end - 1 char} + tk::TextKeySelect %W {end - 1 char} } bind Text <Tab> { - tkTextInsert %W \t - focus %W - break + if { [string equal [%W cget -state] "normal"] } { + tk::TextInsert %W \t + focus %W + break + } } bind Text <Shift-Tab> { # Needed only to keep <Tab> binding from triggering; doesn't @@ -198,10 +198,11 @@ bind Text <Control-Shift-Tab> { focus [tk_focusPrev %W] } bind Text <Control-i> { - tkTextInsert %W \t + tk::TextInsert %W \t } bind Text <Return> { - tkTextInsert %W \n + tk::TextInsert %W \n + if {[%W cget -autoseparators]} {%W edit separator} } bind Text <Delete> { if {[string compare [%W tag nextrange sel 1.0 end] ""]} { @@ -227,12 +228,12 @@ bind Text <Select> { %W mark set anchor insert } bind Text <Control-Shift-space> { - set tkPriv(selectMode) char - tkTextKeyExtend %W insert + set tk::Priv(selectMode) char + tk::TextKeyExtend %W insert } bind Text <Shift-Select> { - set tkPriv(selectMode) char - tkTextKeyExtend %W insert + set tk::Priv(selectMode) char + tk::TextKeyExtend %W insert } bind Text <Control-slash> { %W tag add sel 1.0 end @@ -253,15 +254,16 @@ bind Text <<Clear>> { catch {%W delete sel.first sel.last} } bind Text <<PasteSelection>> { - if {!$tkPriv(mouseMoved) || $tk_strictMotif} { - tkTextPaste %W %x %y + if {$tk_strictMotif || ![info exists tk::Priv(mouseMoved)] + || !$tk::Priv(mouseMoved)} { + tk::TextPasteSelection %W %x %y } } bind Text <Insert> { - catch {tkTextInsert %W [selection get -displayof %W]} + catch {tk::TextInsert %W [::tk::GetSelection %W PRIMARY]} } bind Text <KeyPress> { - tkTextInsert %W %A + tk::TextInsert %W %A } # Ignore all Alt, Meta, and Control keypresses unless explicitly bound. @@ -274,7 +276,8 @@ bind Text <Meta-KeyPress> {# nothing} bind Text <Control-KeyPress> {# nothing} bind Text <Escape> {# nothing} bind Text <KP_Enter> {# nothing} -if {[string equal $tcl_platform(platform) "macintosh"]} { +if {[string equal [tk windowingsystem] "classic"] + || [string equal [tk windowingsystem] "aqua"]} { bind Text <Command-KeyPress> {# nothing} } @@ -282,12 +285,12 @@ if {[string equal $tcl_platform(platform) "macintosh"]} { bind Text <Control-a> { if {!$tk_strictMotif} { - tkTextSetCursor %W {insert linestart} + tk::TextSetCursor %W {insert linestart} } } bind Text <Control-b> { if {!$tk_strictMotif} { - tkTextSetCursor %W insert-1c + tk::TextSetCursor %W insert-1c } } bind Text <Control-d> { @@ -297,12 +300,12 @@ bind Text <Control-d> { } bind Text <Control-e> { if {!$tk_strictMotif} { - tkTextSetCursor %W {insert lineend} + tk::TextSetCursor %W {insert lineend} } } bind Text <Control-f> { if {!$tk_strictMotif} { - tkTextSetCursor %W insert+1c + tk::TextSetCursor %W insert+1c } } bind Text <Control-k> { @@ -316,7 +319,7 @@ bind Text <Control-k> { } bind Text <Control-n> { if {!$tk_strictMotif} { - tkTextSetCursor %W [tkTextUpDownLine %W 1] + tk::TextSetCursor %W [tk::TextUpDownLine %W 1] } } bind Text <Control-o> { @@ -327,63 +330,72 @@ bind Text <Control-o> { } bind Text <Control-p> { if {!$tk_strictMotif} { - tkTextSetCursor %W [tkTextUpDownLine %W -1] + tk::TextSetCursor %W [tk::TextUpDownLine %W -1] } } bind Text <Control-t> { if {!$tk_strictMotif} { - tkTextTranspose %W + tk::TextTranspose %W } } +bind Text <<Undo>> { + catch { %W edit undo } +} + +bind Text <<Redo>> { + catch { %W edit redo } +} + if {[string compare $tcl_platform(platform) "windows"]} { bind Text <Control-v> { if {!$tk_strictMotif} { - tkTextScrollPages %W 1 + tk::TextScrollPages %W 1 } } } bind Text <Meta-b> { if {!$tk_strictMotif} { - tkTextSetCursor %W [tkTextPrevPos %W insert tcl_startOfPreviousWord] + tk::TextSetCursor %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord] } } bind Text <Meta-d> { if {!$tk_strictMotif} { - %W delete insert [tkTextNextWord %W insert] + %W delete insert [tk::TextNextWord %W insert] } } bind Text <Meta-f> { if {!$tk_strictMotif} { - tkTextSetCursor %W [tkTextNextWord %W insert] + tk::TextSetCursor %W [tk::TextNextWord %W insert] } } bind Text <Meta-less> { if {!$tk_strictMotif} { - tkTextSetCursor %W 1.0 + tk::TextSetCursor %W 1.0 } } bind Text <Meta-greater> { if {!$tk_strictMotif} { - tkTextSetCursor %W end-1c + tk::TextSetCursor %W end-1c } } bind Text <Meta-BackSpace> { if {!$tk_strictMotif} { - %W delete [tkTextPrevPos %W insert tcl_startOfPreviousWord] insert + %W delete [tk::TextPrevPos %W insert tcl_startOfPreviousWord] insert } } bind Text <Meta-Delete> { if {!$tk_strictMotif} { - %W delete [tkTextPrevPos %W insert tcl_startOfPreviousWord] insert + %W delete [tk::TextPrevPos %W insert tcl_startOfPreviousWord] insert } } # Macintosh only bindings: # if text black & highlight black -> text white, other text the same -if {[string equal $tcl_platform(platform) "macintosh"]} { +if {[string equal [tk windowingsystem] "classic"] + || [string equal [tk windowingsystem] "aqua"]} { bind Text <FocusIn> { %W tag configure sel -borderwidth 0 %W configure -selectbackground systemHighlight -selectforeground systemHighlightText @@ -393,28 +405,28 @@ bind Text <FocusOut> { %W configure -selectbackground white -selectforeground black } bind Text <Option-Left> { - tkTextSetCursor %W [tkTextPrevPos %W insert tcl_startOfPreviousWord] + tk::TextSetCursor %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord] } bind Text <Option-Right> { - tkTextSetCursor %W [tkTextNextWord %W insert] + tk::TextSetCursor %W [tk::TextNextWord %W insert] } bind Text <Option-Up> { - tkTextSetCursor %W [tkTextPrevPara %W insert] + tk::TextSetCursor %W [tk::TextPrevPara %W insert] } bind Text <Option-Down> { - tkTextSetCursor %W [tkTextNextPara %W insert] + tk::TextSetCursor %W [tk::TextNextPara %W insert] } bind Text <Shift-Option-Left> { - tkTextKeySelect %W [tkTextPrevPos %W insert tcl_startOfPreviousWord] + tk::TextKeySelect %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord] } bind Text <Shift-Option-Right> { - tkTextKeySelect %W [tkTextNextWord %W insert] + tk::TextKeySelect %W [tk::TextNextWord %W insert] } bind Text <Shift-Option-Up> { - tkTextKeySelect %W [tkTextPrevPara %W insert] + tk::TextKeySelect %W [tk::TextPrevPara %W insert] } bind Text <Shift-Option-Down> { - tkTextKeySelect %W [tkTextNextPara %W insert] + tk::TextKeySelect %W [tk::TextNextPara %W insert] } # End of Mac only bindings @@ -432,23 +444,15 @@ bind Text <Control-h> { } bind Text <2> { if {!$tk_strictMotif} { - %W scan mark %x %y - set tkPriv(x) %x - set tkPriv(y) %y - set tkPriv(mouseMoved) 0 + tk::TextScanMark %W %x %y } } bind Text <B2-Motion> { if {!$tk_strictMotif} { - if {(%x != $tkPriv(x)) || (%y != $tkPriv(y))} { - set tkPriv(mouseMoved) 1 - } - if {$tkPriv(mouseMoved)} { - %W scan dragto %x %y - } + tk::TextScanDrag %W %x %y } } -set tkPriv(prevPos) {} +set ::tk::Priv(prevPos) {} # The MouseWheel will typically only fire on Windows. However, # someone could use the "event generate" command to produce one @@ -458,7 +462,7 @@ bind Text <MouseWheel> { %W yview scroll [expr {- (%D / 120) * 4}] units } -if {[string equal "unix" $tcl_platform(platform)]} { +if {[string equal "x11" [tk windowingsystem]]} { # Support for mousewheels on Linux/Unix commonly comes through mapping # the wheel to the extended buttons. If you have a mousewheel, find # Linux configuration info at: @@ -475,7 +479,7 @@ if {[string equal "unix" $tcl_platform(platform)]} { } } -# tkTextClosestGap -- +# ::tk::TextClosestGap -- # Given x and y coordinates, this procedure finds the closest boundary # between characters to the given coordinates and returns the index # of the character just after the boundary. @@ -485,7 +489,7 @@ if {[string equal "unix" $tcl_platform(platform)]} { # x - X-coordinate within the window. # y - Y-coordinate within the window. -proc tkTextClosestGap {w x y} { +proc ::tk::TextClosestGap {w x y} { set pos [$w index @$x,$y] set bbox [$w bbox $pos] if {[string equal $bbox ""]} { @@ -497,7 +501,7 @@ proc tkTextClosestGap {w x y} { $w index "$pos + 1 char" } -# tkTextButton1 -- +# ::tk::TextButton1 -- # This procedure is invoked to handle button-1 presses in text # widgets. It moves the insertion cursor, sets the selection anchor, # and claims the input focus. @@ -507,18 +511,22 @@ proc tkTextClosestGap {w x y} { # x - The x-coordinate of the button press. # y - The x-coordinate of the button press. -proc tkTextButton1 {w x y} { - global tkPriv +proc ::tk::TextButton1 {w x y} { + variable ::tk::Priv - set tkPriv(selectMode) char - set tkPriv(mouseMoved) 0 - set tkPriv(pressX) $x - $w mark set insert [tkTextClosestGap $w $x $y] + set Priv(selectMode) char + set Priv(mouseMoved) 0 + set Priv(pressX) $x + $w mark set insert [TextClosestGap $w $x $y] $w mark set anchor insert - if {[string equal [$w cget -state] "normal"]} {focus $w} + # Allow focus in any case on Windows, because that will let the + # selection be displayed even for state disabled text widgets. + if {[string equal $::tcl_platform(platform) "windows"] \ + || [string equal [$w cget -state] "normal"]} {focus $w} + if {[$w cget -autoseparators]} {$w edit separator} } -# tkTextSelectTo -- +# ::tk::TextSelectTo -- # This procedure is invoked to extend the selection, typically when # dragging it with the mouse. Depending on the selection mode (character, # word, line) it selects in different-sized units. This procedure @@ -530,18 +538,19 @@ proc tkTextButton1 {w x y} { # x - Mouse x position. # y - Mouse y position. -proc tkTextSelectTo {w x y {extend 0}} { - global tkPriv tcl_platform +proc ::tk::TextSelectTo {w x y {extend 0}} { + global tcl_platform + variable ::tk::Priv - set cur [tkTextClosestGap $w $x $y] + set cur [TextClosestGap $w $x $y] if {[catch {$w index anchor}]} { $w mark set anchor $cur } set anchor [$w index anchor] - if {[$w compare $cur != $anchor] || (abs($tkPriv(pressX) - $x) >= 3)} { - set tkPriv(mouseMoved) 1 + if {[$w compare $cur != $anchor] || (abs($Priv(pressX) - $x) >= 3)} { + set Priv(mouseMoved) 1 } - switch $tkPriv(selectMode) { + switch $Priv(selectMode) { char { if {[$w compare $cur < anchor]} { set first $cur @@ -553,16 +562,16 @@ proc tkTextSelectTo {w x y {extend 0}} { } word { if {[$w compare $cur < anchor]} { - set first [tkTextPrevPos $w "$cur + 1c" tcl_wordBreakBefore] + set first [TextPrevPos $w "$cur + 1c" tcl_wordBreakBefore] if { !$extend } { - set last [tkTextNextPos $w "anchor" tcl_wordBreakAfter] + set last [TextNextPos $w "anchor" tcl_wordBreakAfter] } else { set last anchor } } else { - set last [tkTextNextPos $w "$cur - 1c" tcl_wordBreakAfter] + set last [TextNextPos $w "$cur - 1c" tcl_wordBreakAfter] if { !$extend } { - set first [tkTextPrevPos $w anchor tcl_wordBreakBefore] + set first [TextPrevPos $w anchor tcl_wordBreakBefore] } else { set first anchor } @@ -578,21 +587,16 @@ proc tkTextSelectTo {w x y {extend 0}} { } } } - if {$tkPriv(mouseMoved) || [string compare $tkPriv(selectMode) "char"]} { - if {[string compare $tcl_platform(platform) "unix"] \ - && [$w compare $cur < anchor]} { - $w mark set insert $first - } else { - $w mark set insert $last - } - $w tag remove sel 0.0 $first + if {$Priv(mouseMoved) || [string compare $Priv(selectMode) "char"]} { + $w tag remove sel 0.0 end + $w mark set insert $cur $w tag add sel $first $last $w tag remove sel $last end update idletasks } } -# tkTextKeyExtend -- +# ::tk::TextKeyExtend -- # This procedure handles extending the selection from the keyboard, # where the point to extend to is really the boundary between two # characters rather than a particular character. @@ -601,8 +605,7 @@ proc tkTextSelectTo {w x y {extend 0}} { # w - The text window. # index - The point to which the selection is to be extended. -proc tkTextKeyExtend {w index} { - global tkPriv +proc ::tk::TextKeyExtend {w index} { set cur [$w index $index] if {[catch {$w index anchor}]} { @@ -621,7 +624,7 @@ proc tkTextKeyExtend {w index} { $w tag remove sel $last end } -# tkTextPaste -- +# ::tk::TextPasteSelection -- # This procedure sets the insertion cursor to the mouse position, # inserts the selection, and sets the focus to the window. # @@ -629,42 +632,53 @@ proc tkTextKeyExtend {w index} { # w - The text window. # x, y - Position of the mouse. -proc tkTextPaste {w x y} { - $w mark set insert [tkTextClosestGap $w $x $y] - catch {$w insert insert [selection get -displayof $w]} +proc ::tk::TextPasteSelection {w x y} { + $w mark set insert [TextClosestGap $w $x $y] + if {![catch {::tk::GetSelection $w PRIMARY} sel]} { + set oldSeparator [$w cget -autoseparators] + if {$oldSeparator} { + $w configure -autoseparators 0 + $w edit separator + } + $w insert insert $sel + if {$oldSeparator} { + $w edit separator + $w configure -autoseparators 1 + } + } if {[string equal [$w cget -state] "normal"]} {focus $w} } -# tkTextAutoScan -- +# ::tk::TextAutoScan -- # This procedure is invoked when the mouse leaves a text window # with button 1 down. It scrolls the window up, down, left, or right, # depending on where the mouse is (this information was saved in -# tkPriv(x) and tkPriv(y)), and reschedules itself as an "after" +# ::tk::Priv(x) and ::tk::Priv(y)), and reschedules itself as an "after" # command so that the window continues to scroll until the mouse # moves back into the window or the mouse button is released. # # Arguments: # w - The text window. -proc tkTextAutoScan {w} { - global tkPriv +proc ::tk::TextAutoScan {w} { + variable ::tk::Priv if {![winfo exists $w]} return - if {$tkPriv(y) >= [winfo height $w]} { + if {$Priv(y) >= [winfo height $w]} { $w yview scroll 2 units - } elseif {$tkPriv(y) < 0} { + } elseif {$Priv(y) < 0} { $w yview scroll -2 units - } elseif {$tkPriv(x) >= [winfo width $w]} { + } elseif {$Priv(x) >= [winfo width $w]} { $w xview scroll 2 units - } elseif {$tkPriv(x) < 0} { + } elseif {$Priv(x) < 0} { $w xview scroll -2 units } else { return } - tkTextSelectTo $w $tkPriv(x) $tkPriv(y) - set tkPriv(afterId) [after 50 [list tkTextAutoScan $w]] + TextSelectTo $w $Priv(x) $Priv(y) + set Priv(afterId) [after 50 [list tk::TextAutoScan $w]] } -# tkTextSetCursor +# ::tk::TextSetCursor # Move the insertion cursor to a given position in a text. Also # clears the selection, if there is one in the text, and makes sure # that the insertion cursor is visible. Also, don't let the insertion @@ -674,8 +688,7 @@ proc tkTextAutoScan {w} { # w - The text window. # pos - The desired new position for the cursor in the window. -proc tkTextSetCursor {w pos} { - global tkPriv +proc ::tk::TextSetCursor {w pos} { if {[$w compare $pos == end]} { set pos {end - 1 chars} @@ -683,9 +696,10 @@ proc tkTextSetCursor {w pos} { $w mark set insert $pos $w tag remove sel 1.0 end $w see insert + if {[$w cget -autoseparators]} {$w edit separator} } -# tkTextKeySelect +# ::tk::TextKeySelect # This procedure is invoked when stroking out selections using the # keyboard. It moves the cursor to a new position, then extends # the selection to that position. @@ -695,8 +709,7 @@ proc tkTextSetCursor {w pos} { # new - A new position for the insertion cursor (the cursor hasn't # actually been moved to this position yet). -proc tkTextKeySelect {w new} { - global tkPriv +proc ::tk::TextKeySelect {w new} { if {[string equal [$w tag nextrange sel 1.0 end] ""]} { if {[$w compare $new < insert]} { @@ -722,7 +735,7 @@ proc tkTextKeySelect {w new} { update idletasks } -# tkTextResetAnchor -- +# ::tk::TextResetAnchor -- # Set the selection anchor to whichever end is farthest from the # index argument. One special trick: if the selection has two or # fewer characters, just leave the anchor where it is. In this @@ -736,11 +749,13 @@ proc tkTextKeySelect {w new} { # index - Position at which mouse button was pressed, which determines # which end of selection should be used as anchor point. -proc tkTextResetAnchor {w index} { - global tkPriv +proc ::tk::TextResetAnchor {w index} { if {[string equal [$w tag ranges sel] ""]} { - $w mark set anchor $index + # Don't move the anchor if there is no selection now; this makes + # the widget behave "correctly" when the user clicks once, then + # shift-clicks somewhere -- ie, the area between the two clicks will be + # selected. [Bug: 5929]. return } set a [$w index $index] @@ -776,7 +791,7 @@ proc tkTextResetAnchor {w index} { } } -# tkTextInsert -- +# ::tk::TextInsert -- # Insert a string into a text at the point of the insertion cursor. # If there is a selection in the text, and it covers the point of the # insertion cursor, then delete the selection before inserting. @@ -785,21 +800,32 @@ proc tkTextResetAnchor {w index} { # w - The text window in which to insert the string # s - The string to insert (usually just a single character) -proc tkTextInsert {w s} { +proc ::tk::TextInsert {w s} { if {[string equal $s ""] || [string equal [$w cget -state] "disabled"]} { return } + set compound 0 catch { if {[$w compare sel.first <= insert] \ && [$w compare sel.last >= insert]} { + set oldSeparator [$w cget -autoseparators] + if { $oldSeparator } { + $w configure -autoseparators 0 + $w edit separator + set compound 1 + } $w delete sel.first sel.last } } $w insert insert $s $w see insert + if { $compound && $oldSeparator } { + $w edit separator + $w configure -autoseparators 1 + } } -# tkTextUpDownLine -- +# ::tk::TextUpDownLine -- # Returns the index of the character one line above or below the # insertion cursor. There are two tricky things here. First, # we want to maintain the original column across repeated operations, @@ -812,23 +838,23 @@ proc tkTextInsert {w s} { # n - The number of lines to move: -1 for up one line, # +1 for down one line. -proc tkTextUpDownLine {w n} { - global tkPriv +proc ::tk::TextUpDownLine {w n} { + variable ::tk::Priv set i [$w index insert] scan $i "%d.%d" line char - if {[string compare $tkPriv(prevPos) $i]} { - set tkPriv(char) $char + if {[string compare $Priv(prevPos) $i]} { + set Priv(char) $char } - set new [$w index [expr {$line + $n}].$tkPriv(char)] + set new [$w index [expr {$line + $n}].$Priv(char)] if {[$w compare $new == end] || [$w compare $new == "insert linestart"]} { set new $i } - set tkPriv(prevPos) $new + set Priv(prevPos) $new return $new } -# tkTextPrevPara -- +# ::tk::TextPrevPara -- # Returns the index of the beginning of the paragraph just before a given # position in the text (the beginning of a paragraph is the first non-blank # character after a blank line). @@ -837,7 +863,7 @@ proc tkTextUpDownLine {w n} { # w - The text window in which the cursor is to move. # pos - Position at which to start search. -proc tkTextPrevPara {w pos} { +proc ::tk::TextPrevPara {w pos} { set pos [$w index "$pos linestart"] while {1} { if {([string equal [$w get "$pos - 1 line"] "\n"] \ @@ -855,7 +881,7 @@ proc tkTextPrevPara {w pos} { } } -# tkTextNextPara -- +# ::tk::TextNextPara -- # Returns the index of the beginning of the paragraph just after a given # position in the text (the beginning of a paragraph is the first non-blank # character after a blank line). @@ -864,7 +890,7 @@ proc tkTextPrevPara {w pos} { # w - The text window in which the cursor is to move. # start - Position at which to start search. -proc tkTextNextPara {w start} { +proc ::tk::TextNextPara {w start} { set pos [$w index "$start linestart + 1 line"] while {[string compare [$w get $pos] "\n"]} { if {[$w compare $pos == end]} { @@ -885,7 +911,7 @@ proc tkTextNextPara {w start} { return $pos } -# tkTextScrollPages -- +# ::tk::TextScrollPages -- # This is a utility procedure used in bindings for moving up and down # pages and possibly extending the selection along the way. It scrolls # the view in the widget by the number of pages, and it returns the @@ -897,7 +923,7 @@ proc tkTextNextPara {w start} { # count - Number of pages forward to scroll; may be negative # to scroll backwards. -proc tkTextScrollPages {w count} { +proc ::tk::TextScrollPages {w count} { set bbox [$w bbox insert] $w yview scroll $count pages if {[string equal $bbox ""]} { @@ -906,7 +932,7 @@ proc tkTextScrollPages {w count} { return [$w index @[lindex $bbox 0],[lindex $bbox 1]] } -# tkTextTranspose -- +# ::tk::TextTranspose -- # This procedure implements the "transpose" function for text widgets. # It tranposes the characters on either side of the insertion cursor, # unless the cursor is at the end of the line. In this case it @@ -916,7 +942,7 @@ proc tkTextScrollPages {w count} { # Arguments: # w - Text window in which to transpose. -proc tkTextTranspose w { +proc ::tk::TextTranspose w { set pos insert if {[$w compare $pos != "$pos lineend"]} { set pos [$w index "$pos + 1 char"] @@ -930,21 +956,21 @@ proc tkTextTranspose w { $w see insert } -# tk_textCopy -- +# ::tk_textCopy -- # This procedure copies the selection from a text widget into the # clipboard. # # Arguments: # w - Name of a text widget. -proc tk_textCopy w { +proc ::tk_textCopy w { if {![catch {set data [$w get sel.first sel.last]}]} { clipboard clear -displayof $w clipboard append -displayof $w $data } } -# tk_textCut -- +# ::tk_textCut -- # This procedure copies the selection from a text widget into the # clipboard, then deletes the selection (if it exists in the given # widget). @@ -952,7 +978,7 @@ proc tk_textCopy w { # Arguments: # w - Name of a text widget. -proc tk_textCut w { +proc ::tk_textCut w { if {![catch {set data [$w get sel.first sel.last]}]} { clipboard clear -displayof $w clipboard append -displayof $w $data @@ -960,26 +986,33 @@ proc tk_textCut w { } } -# tk_textPaste -- +# ::tk_textPaste -- # This procedure pastes the contents of the clipboard to the insertion # point in a text widget. # # Arguments: # w - Name of a text widget. -proc tk_textPaste w { +proc ::tk_textPaste w { global tcl_platform - catch { - if {[string compare $tcl_platform(platform) "unix"]} { - catch { - $w delete sel.first sel.last - } + if {![catch {::tk::GetSelection $w CLIPBOARD} sel]} { + set oldSeparator [$w cget -autoseparators] + if { $oldSeparator } { + $w configure -autoseparators 0 + $w edit separator + } + if {[string compare [tk windowingsystem] "x11"]} { + catch { $w delete sel.first sel.last } + } + $w insert insert $sel + if { $oldSeparator } { + $w edit separator + $w configure -autoseparators 1 } - $w insert insert [selection get -displayof $w -selection CLIPBOARD] } } -# tkTextNextWord -- +# ::tk::TextNextWord -- # Returns the index of the next word position after a given position in the # text. The next word is platform dependent and may be either the next # end-of-word position or the next start-of-word position after the next @@ -990,17 +1023,17 @@ proc tk_textPaste w { # start - Position at which to start search. if {[string equal $tcl_platform(platform) "windows"]} { - proc tkTextNextWord {w start} { - tkTextNextPos $w [tkTextNextPos $w $start tcl_endOfWord] \ + proc ::tk::TextNextWord {w start} { + TextNextPos $w [TextNextPos $w $start tcl_endOfWord] \ tcl_startOfNextWord } } else { - proc tkTextNextWord {w start} { - tkTextNextPos $w $start tcl_endOfWord + proc ::tk::TextNextWord {w start} { + TextNextPos $w $start tcl_endOfWord } } -# tkTextNextPos -- +# ::tk::TextNextPos -- # Returns the index of the next position after the given starting # position in the text as computed by a specified function. # @@ -1009,7 +1042,7 @@ if {[string equal $tcl_platform(platform) "windows"]} { # start - Position at which to start search. # op - Function to use to find next position. -proc tkTextNextPos {w start op} { +proc ::tk::TextNextPos {w start op} { set text "" set cur $start while {[$w compare $cur < end]} { @@ -1029,7 +1062,7 @@ proc tkTextNextPos {w start op} { return end } -# tkTextPrevPos -- +# ::tk::TextPrevPos -- # Returns the index of the previous position before the given starting # position in the text as computed by a specified function. # @@ -1038,7 +1071,7 @@ proc tkTextNextPos {w start op} { # start - Position at which to start search. # op - Function to use to find next position. -proc tkTextPrevPos {w start op} { +proc ::tk::TextPrevPos {w start op} { set text "" set cur $start while {[$w compare $cur > 0.0]} { @@ -1064,4 +1097,40 @@ proc tkTextPrevPos {w start op} { return 0.0 } +# ::tk::TextScanMark -- +# +# Marks the start of a possible scan drag operation +# +# Arguments: +# w - The text window from which the text to get +# x - x location on screen +# y - y location on screen +proc ::tk::TextScanMark {w x y} { + $w scan mark $x $y + set ::tk::Priv(x) $x + set ::tk::Priv(y) $y + set ::tk::Priv(mouseMoved) 0 +} + +# ::tk::TextScanDrag -- +# +# Marks the start of a possible scan drag operation +# +# Arguments: +# w - The text window from which the text to get +# x - x location on screen +# y - y location on screen + +proc ::tk::TextScanDrag {w x y} { + # Make sure these exist, as some weird situations can trigger the + # motion binding without the initial press. [Bug #220269] + if {![info exists ::tk::Priv(x)]} { set ::tk::Priv(x) $x } + if {![info exists ::tk::Priv(y)]} { set ::tk::Priv(y) $y } + if {($x != $::tk::Priv(x)) || ($y != $::tk::Priv(y))} { + set ::tk::Priv(mouseMoved) 1 + } + if {[info exists ::tk::Priv(mouseMoved)] && $::tk::Priv(mouseMoved)} { + $w scan dragto $x $y + } +} |