@@ -12,7 +12,8 @@ package Tk::Entry;
12
12
# This program is free software; you can redistribute it and/or
13
13
14
14
use vars qw( $VERSION) ;
15
- $VERSION = sprintf ' 4.%03d' ,q$ Revision: #16 $ =~ / #(\d +)/ ;
15
+ use strict;
16
+ $VERSION = sprintf ' 4.%03d' ,q$ Revision: #17 $ =~ / #(\d +)/ ;
16
17
17
18
# modify it under the same terms as Perl itself, subject
18
19
# to additional disclaimer in license.terms due to partial
@@ -79,7 +80,21 @@ sub ClassInit
79
80
80
81
$class -> SUPER::ClassInit($mw );
81
82
83
+ # <<Cut>>, <<Copy>> and <<Paste>> defined in Tk::Clipboard
84
+ $mw -> bind ($class ,' <<Clear>>' => sub {
85
+ my $w = shift ;
86
+ $w -> delete (" sel.first" , " sel.last" );
87
+ });
88
+ $mw -> bind ($class ,' <<PasteSelection>>' => [sub {
89
+ my ($w , $x ) = @_ ;
90
+ # XXX logic in Tcl/Tk version screwed up?
91
+ if (!$Tk::strictMotif && !$Tk::mouseMoved ) {
92
+ $w -> Paste($x );
93
+ }
94
+ }, Ev(' x' )]);
95
+
82
96
# Standard Motif bindings:
97
+ # The <Escape> binding is different from the Tcl/Tk version:
83
98
$mw -> bind ($class ,' <Escape>' ,' selectionClear' );
84
99
85
100
$mw -> bind ($class ,' <1>' ,[' Button1' ,Ev(' x' ),Ev(' y' )]);
@@ -136,8 +151,18 @@ sub ClassInit
136
151
$mw -> bind ($class ,' <Return>' ,' NoOp' );
137
152
$mw -> bind ($class ,' <KP_Enter>' ,' NoOp' );
138
153
$mw -> bind ($class ,' <Tab>' ,' NoOp' );
154
+ if ($mw -> windowingsystem =~ / ^(?:classic|aqua)$ / )
155
+ {
156
+ $mw -> bind ($class ,' <Command-KeyPress>' , ' NoOp' );
157
+ }
158
+
159
+ # On Windows, paste is done using Shift-Insert. Shift-Insert already
160
+ # generates the <<Paste>> event, so we don't need to do anything here.
161
+ if ($Tk::platform ne ' MSWin32' )
162
+ {
163
+ $mw -> bind ($class ,' <Insert>' ,' InsertSelection' );
164
+ }
139
165
140
- $mw -> bind ($class ,' <Insert>' ,' InsertSelection' );
141
166
if (!$Tk::strictMotif )
142
167
{
143
168
# Additional emacs-like bindings:
@@ -151,20 +176,23 @@ sub ClassInit
151
176
152
177
$mw -> bind ($class ,' <Control-t>' ,' Transpose' );
153
178
179
+ # XXX The original Tcl/Tk bindings use NextWord/PreviousWord instead
154
180
$mw -> bind ($class ,' <Meta-b>' ,[' SetCursor' ,Ev([' wordstart' ])]);
155
181
$mw -> bind ($class ,' <Meta-d>' ,[' delete' ,' insert' ,Ev([' wordend' ])]);
156
182
$mw -> bind ($class ,' <Meta-f>' ,[' SetCursor' ,Ev([' wordend' ])]);
157
183
$mw -> bind ($class ,' <Meta-BackSpace>' ,[' delete' ,Ev([' wordstart' ]),' insert' ]);
184
+ $mw -> bind ($class ,' <Meta-Delete>' ,[' delete' ,Ev([' wordstart' ]),' insert' ]);
158
185
159
186
# A few additional bindings from John Ousterhout.
160
- $mw -> bind ($class ,' <Control-w>' ,[' delete' ,Ev([' wordstart' ]),' insert' ]);
187
+ # XXX conflicts with <<Copy>>: $mw->bind($class,'<Control-w>',['delete',Ev(['wordstart']),'insert']);
161
188
$mw -> bind ($class ,' <2>' ,' Button_2' );
162
189
$mw -> bind ($class ,' <B2-Motion>' ,' B2_Motion' );
163
- $mw -> bind ($class ,' <ButtonRelease-2>' ,' ButtonRelease_2' );
190
+ # XXX superseded by <<PasteSelection>>: $mw->bind($class,'<ButtonRelease-2>','ButtonRelease_2');
164
191
}
165
192
return $class ;
166
193
}
167
194
195
+
168
196
sub Shift_1
169
197
{
170
198
my $w = shift ;
@@ -199,10 +227,11 @@ sub Delete
199
227
sub InsertSelection
200
228
{
201
229
my $w = shift ;
202
- eval {local $SIG {__DIE__ }; $w -> Insert($w -> SelectionGet )}
230
+ eval {local $SIG {__DIE__ }; $w -> Insert($w -> GetSelection )}
203
231
}
204
232
205
233
234
+ # Original is ::tk::EntryScanMark
206
235
sub Button_2
207
236
{
208
237
my $w = shift ;
@@ -214,10 +243,14 @@ sub Button_2
214
243
}
215
244
216
245
246
+ # Original is ::tk::EntryScanDrag
217
247
sub B2_Motion
218
248
{
219
249
my $w = shift ;
220
250
my $Ev = $w -> XEvent;
251
+ # Make sure these exist, as some weird situations can trigger the
252
+ # motion binding without the initial press. [Tcl/Tk Bug #220269]
253
+ if (!defined $Tk::x ) { $Tk::x = $Ev -> x }
221
254
if (abs(($Ev -> x-$Tk::x )) > 2)
222
255
{
223
256
$Tk::mouseMoved = 1
@@ -226,6 +259,7 @@ sub B2_Motion
226
259
}
227
260
228
261
262
+ # XXX Not needed anymore
229
263
sub ButtonRelease_2
230
264
{
231
265
my $w = shift ;
@@ -245,6 +279,26 @@ sub Button1Release
245
279
shift -> CancelRepeat;
246
280
}
247
281
282
+ # ::tk::EntryClosestGap --
283
+ # Given x and y coordinates, this procedure finds the closest boundary
284
+ # between characters to the given coordinates and returns the index
285
+ # of the character just after the boundary.
286
+ #
287
+ # Arguments:
288
+ # w - The entry window.
289
+ # x - X-coordinate within the window.
290
+ sub ClosestGap
291
+ {
292
+ my ($w , $x ) = @_ ;
293
+ my $pos = $w -> index (' @' .$x );
294
+ my @bbox = $w -> bbox($pos );
295
+ if ($x - $bbox [0] < $bbox [2] / 2)
296
+ {
297
+ return $pos ;
298
+ }
299
+ $pos + 1;
300
+ }
301
+
248
302
# Button1 --
249
303
# This procedure is invoked to handle button-1 presses in entry
250
304
# widgets. It moves the insertion cursor, sets the selection anchor,
@@ -257,14 +311,13 @@ sub Button1
257
311
{
258
312
my $w = shift ;
259
313
my $x = shift ;
260
- my $y = shift ;
261
314
$Tk::selectMode = ' char' ;
262
315
$Tk::mouseMoved = 0;
263
316
$Tk::pressX = $x ;
264
- $w -> icursor(' @ ' . $x );
265
- $w -> selectionFrom(' @ ' . $x );
317
+ $w -> icursor($w -> ClosestGap( $x ) );
318
+ $w -> selectionFrom(' insert ' );
266
319
$w -> selectionClear;
267
- if ($w -> cget(' -state' ) eq ' normal ' )
320
+ if ($w -> cget(' -state' ) ne ' disabled ' )
268
321
{
269
322
$w -> focus()
270
323
}
@@ -273,6 +326,7 @@ sub Button1
273
326
sub Motion
274
327
{
275
328
my ($w ,$x ,$y ) = @_ ;
329
+ $Tk::x = $x ; # XXX ?
276
330
$w -> MouseSelect($x );
277
331
}
278
332
@@ -291,13 +345,13 @@ sub MouseSelect
291
345
292
346
my $w = shift ;
293
347
my $x = shift ;
294
- return if ref ($w ) eq ' Tk::Spinbox' and $w -> {_element } ne ' entry' ;
348
+ return if UNIVERSAL::isa ($w , ' Tk::Spinbox' ) and $w -> {_element } ne ' entry' ;
295
349
$Tk::selectMode = shift if (@_ );
296
- my $cur = $w -> index (' @ ' . $x );
350
+ my $cur = $w -> index ($w -> ClosestGap( $x ) );
297
351
return unless defined $cur ;
298
352
my $anchor = $w -> index (' anchor' );
299
353
return unless defined $anchor ;
300
- $Tk::pressX ||= $x ;
354
+ $Tk::pressX ||= $x ; # XXX Better use "if !defined $Tk::pressX"?
301
355
if (($cur != $anchor ) || (abs($Tk::pressX - $x ) >= 3))
302
356
{
303
357
$Tk::mouseMoved = 1
@@ -306,6 +360,7 @@ sub MouseSelect
306
360
return unless $mode ;
307
361
if ($mode eq ' char' )
308
362
{
363
+ # The Tcl version uses selectionRange here XXX
309
364
if ($Tk::mouseMoved )
310
365
{
311
366
if ($cur < $anchor )
@@ -320,6 +375,7 @@ sub MouseSelect
320
375
}
321
376
elsif ($mode eq ' word' )
322
377
{
378
+ # The Tcl version uses tcl_wordBreakBefore/After here XXX
323
379
if ($cur < $w -> index (' anchor' ))
324
380
{
325
381
$w -> selectionRange($w -> wordstart($cur ),$w -> wordend($anchor -1))
@@ -340,6 +396,26 @@ sub MouseSelect
340
396
}
341
397
$w -> idletasks;
342
398
}
399
+ # ::tk::EntryPaste --
400
+ # This procedure sets the insertion cursor to the current mouse position,
401
+ # pastes the selection there, and sets the focus to the window.
402
+ #
403
+ # Arguments:
404
+ # w - The entry window.
405
+ # x - X position of the mouse.
406
+ sub Paste
407
+ {
408
+ my ($w , $x ) = @_ ;
409
+ $w -> icursor($w -> ClosestGap($x ));
410
+ eval { local $SIG {__DIE__ };
411
+ $w -> insert(" insert" , $w -> GetSelection);
412
+ $w -> SeeInsert; # Perl/Tk extension
413
+ };
414
+ if ($w -> cget(-state) ne ' disabled' )
415
+ {
416
+ $w -> focus;
417
+ }
418
+ }
343
419
# AutoScan --
344
420
# This procedure is invoked when the mouse leaves an entry window
345
421
# with button 1 down. It scrolls the window left or right,
@@ -354,6 +430,7 @@ sub AutoScan
354
430
{
355
431
my $w = shift ;
356
432
my $x = shift ;
433
+ return if !Tk::Exists($w );
357
434
if ($x >= $w -> width)
358
435
{
359
436
$w -> xview(' scroll' ,2,' units' )
@@ -434,6 +511,7 @@ sub Backspace
434
511
{
435
512
my $x = $w -> index (' insert' )-1;
436
513
$w -> delete ($x ) if ($x >= 0);
514
+ # XXX Missing repositioning part from Tcl/Tk source
437
515
}
438
516
}
439
517
# SeeInsert
@@ -513,6 +591,12 @@ sub tabFocus
513
591
$w -> SUPER::tabFocus;
514
592
}
515
593
594
+ # ::tk::EntryGetSelection --
595
+ #
596
+ # Returns the selected text of the entry with respect to the -show option.
597
+ #
598
+ # Arguments:
599
+ # w - The entry window from which the text to get
516
600
sub getSelected
517
601
{
518
602
my $w = shift ;
@@ -525,8 +609,7 @@ sub getSelected
525
609
return substr ($str ,$s ,$e -$s );
526
610
}
527
611
612
+
528
613
1;
529
614
530
615
__END__
531
-
532
-
0 commit comments