ffi-tk 2009.11.29
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +748 -0
- data/MANIFEST +188 -0
- data/README.md +85 -0
- data/Rakefile +47 -0
- data/TODO.md +62 -0
- data/bin/rwish +33 -0
- data/doc/MIT_LICENSE +18 -0
- data/doc/TCL_LICENSE +39 -0
- data/example/choose_color.rb +22 -0
- data/example/choose_directory.rb +22 -0
- data/example/dialog.rb +37 -0
- data/example/hello.rb +11 -0
- data/example/message_box.rb +26 -0
- data/example/option_menu.rb +17 -0
- data/example/popup.rb +24 -0
- data/example/set_palette.rb +32 -0
- data/example/text.rb +47 -0
- data/example/tile/kroc_demo_small.rb +123 -0
- data/example/tile/kroc_rb_demo.rb +135 -0
- data/example/tile/notebook.rb +48 -0
- data/example/tile/theme_hello.rb +38 -0
- data/example/tile/treeview.rb +71 -0
- data/example/various.rb +25 -0
- data/example/wait.rb +16 -0
- data/ffi-tk.gemspec +33 -0
- data/lib/ffi-tk.rb +76 -0
- data/lib/ffi-tk/command.rb +39 -0
- data/lib/ffi-tk/command/after.rb +36 -0
- data/lib/ffi-tk/command/bell.rb +34 -0
- data/lib/ffi-tk/command/bind.rb +11 -0
- data/lib/ffi-tk/command/bindtags.rb +69 -0
- data/lib/ffi-tk/command/cget.rb +92 -0
- data/lib/ffi-tk/command/choose_color.rb +29 -0
- data/lib/ffi-tk/command/choose_directory.rb +45 -0
- data/lib/ffi-tk/command/clipboard.rb +102 -0
- data/lib/ffi-tk/command/configure.rb +88 -0
- data/lib/ffi-tk/command/destroy.rb +12 -0
- data/lib/ffi-tk/command/dialog.rb +54 -0
- data/lib/ffi-tk/command/event.rb +79 -0
- data/lib/ffi-tk/command/focus.rb +70 -0
- data/lib/ffi-tk/command/font.rb +124 -0
- data/lib/ffi-tk/command/get_open_file.rb +85 -0
- data/lib/ffi-tk/command/get_save_file.rb +83 -0
- data/lib/ffi-tk/command/grab.rb +141 -0
- data/lib/ffi-tk/command/grid.rb +246 -0
- data/lib/ffi-tk/command/image.rb +79 -0
- data/lib/ffi-tk/command/lower.rb +23 -0
- data/lib/ffi-tk/command/message_box.rb +65 -0
- data/lib/ffi-tk/command/option_menu.rb +8 -0
- data/lib/ffi-tk/command/pack.rb +99 -0
- data/lib/ffi-tk/command/place.rb +91 -0
- data/lib/ffi-tk/command/popup.rb +14 -0
- data/lib/ffi-tk/command/raise.rb +25 -0
- data/lib/ffi-tk/command/scrollable.rb +151 -0
- data/lib/ffi-tk/command/selection.rb +132 -0
- data/lib/ffi-tk/command/set_palette.rb +9 -0
- data/lib/ffi-tk/command/tk_cmd.rb +155 -0
- data/lib/ffi-tk/command/vars.rb +82 -0
- data/lib/ffi-tk/command/wait.rb +39 -0
- data/lib/ffi-tk/command/winfo.rb +668 -0
- data/lib/ffi-tk/command/wm.rb +1025 -0
- data/lib/ffi-tk/core_extensions.rb +154 -0
- data/lib/ffi-tk/event/data.rb +60 -0
- data/lib/ffi-tk/event/handler.rb +44 -0
- data/lib/ffi-tk/ffi/tcl.rb +92 -0
- data/lib/ffi-tk/ffi/tcl/cmd_proc.rb +10 -0
- data/lib/ffi-tk/ffi/tcl/eval_result.rb +148 -0
- data/lib/ffi-tk/ffi/tcl/interp.rb +95 -0
- data/lib/ffi-tk/ffi/tcl/obj.rb +89 -0
- data/lib/ffi-tk/ffi/tcl/time.rb +36 -0
- data/lib/ffi-tk/ffi/tk.rb +35 -0
- data/lib/ffi-tk/geometry.rb +32 -0
- data/lib/ffi-tk/thread_sender.rb +26 -0
- data/lib/ffi-tk/tk.rb +222 -0
- data/lib/ffi-tk/variable.rb +46 -0
- data/lib/ffi-tk/widget.rb +68 -0
- data/lib/ffi-tk/widget/button.rb +41 -0
- data/lib/ffi-tk/widget/canvas.rb +806 -0
- data/lib/ffi-tk/widget/canvas/arc.rb +18 -0
- data/lib/ffi-tk/widget/canvas/bitmap.rb +13 -0
- data/lib/ffi-tk/widget/canvas/image.rb +10 -0
- data/lib/ffi-tk/widget/canvas/item.rb +170 -0
- data/lib/ffi-tk/widget/canvas/line.rb +16 -0
- data/lib/ffi-tk/widget/canvas/oval.rb +15 -0
- data/lib/ffi-tk/widget/canvas/polygon.rb +16 -0
- data/lib/ffi-tk/widget/canvas/rectangle.rb +15 -0
- data/lib/ffi-tk/widget/canvas/text.rb +15 -0
- data/lib/ffi-tk/widget/canvas/window.rb +11 -0
- data/lib/ffi-tk/widget/checkbutton.rb +63 -0
- data/lib/ffi-tk/widget/entry.rb +208 -0
- data/lib/ffi-tk/widget/frame.rb +12 -0
- data/lib/ffi-tk/widget/label.rb +26 -0
- data/lib/ffi-tk/widget/labelframe.rb +7 -0
- data/lib/ffi-tk/widget/listbox.rb +192 -0
- data/lib/ffi-tk/widget/menu.rb +318 -0
- data/lib/ffi-tk/widget/menubutton.rb +7 -0
- data/lib/ffi-tk/widget/message.rb +36 -0
- data/lib/ffi-tk/widget/panedwindow.rb +164 -0
- data/lib/ffi-tk/widget/radiobutton.rb +43 -0
- data/lib/ffi-tk/widget/root.rb +8 -0
- data/lib/ffi-tk/widget/scale.rb +44 -0
- data/lib/ffi-tk/widget/scrollbar.rb +114 -0
- data/lib/ffi-tk/widget/spinbox.rb +198 -0
- data/lib/ffi-tk/widget/text.rb +893 -0
- data/lib/ffi-tk/widget/text/peer.rb +10 -0
- data/lib/ffi-tk/widget/tile.rb +70 -0
- data/lib/ffi-tk/widget/tile/button.rb +8 -0
- data/lib/ffi-tk/widget/tile/checkbutton.rb +8 -0
- data/lib/ffi-tk/widget/tile/combobox.rb +43 -0
- data/lib/ffi-tk/widget/tile/entry.rb +8 -0
- data/lib/ffi-tk/widget/tile/frame.rb +13 -0
- data/lib/ffi-tk/widget/tile/label.rb +9 -0
- data/lib/ffi-tk/widget/tile/labelframe.rb +8 -0
- data/lib/ffi-tk/widget/tile/menubutton.rb +8 -0
- data/lib/ffi-tk/widget/tile/notebook.rb +93 -0
- data/lib/ffi-tk/widget/tile/panedwindow.rb +9 -0
- data/lib/ffi-tk/widget/tile/progressbar.rb +59 -0
- data/lib/ffi-tk/widget/tile/radiobutton.rb +8 -0
- data/lib/ffi-tk/widget/tile/scale.rb +8 -0
- data/lib/ffi-tk/widget/tile/scrollbar.rb +41 -0
- data/lib/ffi-tk/widget/tile/separator.rb +23 -0
- data/lib/ffi-tk/widget/tile/sizegrip.rb +24 -0
- data/lib/ffi-tk/widget/tile/style.rb +114 -0
- data/lib/ffi-tk/widget/tile/treeview.rb +414 -0
- data/lib/ffi-tk/widget/toplevel.rb +14 -0
- data/spec/ffi-tk/command/bindtags.rb +18 -0
- data/spec/ffi-tk/command/clipboard.rb +18 -0
- data/spec/ffi-tk/command/font.rb +67 -0
- data/spec/ffi-tk/command/grid.rb +6 -0
- data/spec/ffi-tk/command/image.rb +26 -0
- data/spec/ffi-tk/command/pack.rb +20 -0
- data/spec/ffi-tk/command/place.rb +20 -0
- data/spec/ffi-tk/command/selection.rb +13 -0
- data/spec/ffi-tk/command/vars.rb +32 -0
- data/spec/ffi-tk/command/winfo.rb +233 -0
- data/spec/ffi-tk/command/wm.rb +185 -0
- data/spec/ffi-tk/event.rb +95 -0
- data/spec/ffi-tk/tile/button.rb +51 -0
- data/spec/ffi-tk/tile/checkbutton.rb +13 -0
- data/spec/ffi-tk/tile/combobox.rb +65 -0
- data/spec/ffi-tk/tile/entry.rb +61 -0
- data/spec/ffi-tk/tile/frame.rb +65 -0
- data/spec/ffi-tk/tile/label.rb +17 -0
- data/spec/ffi-tk/tile/labelframe.rb +13 -0
- data/spec/ffi-tk/tile/menubutton.rb +13 -0
- data/spec/ffi-tk/tile/notebook.rb +103 -0
- data/spec/ffi-tk/tile/panedwindow.rb +13 -0
- data/spec/ffi-tk/tile/progressbar.rb +78 -0
- data/spec/ffi-tk/tile/radiobutton.rb +13 -0
- data/spec/ffi-tk/tile/scale.rb +13 -0
- data/spec/ffi-tk/tile/scrollbar.rb +43 -0
- data/spec/ffi-tk/tile/separator.rb +22 -0
- data/spec/ffi-tk/tile/sizegrip.rb +13 -0
- data/spec/ffi-tk/tile/style.rb +161 -0
- data/spec/ffi-tk/tile/treeview.rb +101 -0
- data/spec/ffi-tk/variable.rb +24 -0
- data/spec/ffi-tk/widget/button.rb +22 -0
- data/spec/ffi-tk/widget/canvas.rb +169 -0
- data/spec/ffi-tk/widget/checkbutton.rb +44 -0
- data/spec/ffi-tk/widget/entry.rb +155 -0
- data/spec/ffi-tk/widget/frame.rb +8 -0
- data/spec/ffi-tk/widget/label.rb +16 -0
- data/spec/ffi-tk/widget/labelframe.rb +12 -0
- data/spec/ffi-tk/widget/listbox.rb +19 -0
- data/spec/ffi-tk/widget/menu.rb +12 -0
- data/spec/ffi-tk/widget/menubutton.rb +12 -0
- data/spec/ffi-tk/widget/message.rb +12 -0
- data/spec/ffi-tk/widget/panedwindow.rb +12 -0
- data/spec/ffi-tk/widget/radiobutton.rb +12 -0
- data/spec/ffi-tk/widget/root.rb +9 -0
- data/spec/ffi-tk/widget/scale.rb +12 -0
- data/spec/ffi-tk/widget/scrollbar.rb +12 -0
- data/spec/ffi-tk/widget/spinbox.rb +12 -0
- data/spec/ffi-tk/widget/text.rb +246 -0
- data/spec/ffi-tk/widget/toplevel.rb +12 -0
- data/spec/helper.rb +3 -0
- data/tasks/authors.rake +21 -0
- data/tasks/bacon.rake +66 -0
- data/tasks/changelog.rake +18 -0
- data/tasks/gem.rake +22 -0
- data/tasks/gem_setup.rake +113 -0
- data/tasks/grancher.rake +12 -0
- data/tasks/manifest.rake +4 -0
- data/tasks/rcov.rake +17 -0
- data/tasks/release.rake +65 -0
- data/tasks/reversion.rake +8 -0
- data/tasks/setup.rake +12 -0
- data/tasks/ycov.rake +84 -0
- metadata +261 -0
@@ -0,0 +1,893 @@
|
|
1
|
+
module Tk
|
2
|
+
class Text < Widget
|
3
|
+
include Cget, Configure, Scrollable
|
4
|
+
|
5
|
+
def self.tk_command; 'text'; end
|
6
|
+
|
7
|
+
autoload :Peer, 'ffi-tk/widget/text/peer'
|
8
|
+
|
9
|
+
SEARCH_MUTEX = Mutex.new
|
10
|
+
|
11
|
+
def initialize(parent = Tk.root, options = None)
|
12
|
+
@tag_commands = {}
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def value
|
17
|
+
get '1.0', :end
|
18
|
+
end
|
19
|
+
|
20
|
+
def value=(string)
|
21
|
+
clear
|
22
|
+
insert :end, string
|
23
|
+
end
|
24
|
+
|
25
|
+
def clear
|
26
|
+
delete '0.0', :end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns a list of four elements describing the screen area of the
|
30
|
+
# character given by index.
|
31
|
+
# The first two elements of the list give the x and y coordinates of the
|
32
|
+
# upper-left corner of the area occupied by the character, and the last two
|
33
|
+
# elements give the width and height of the area.
|
34
|
+
# If the character is only partially visible on the screen, then the return
|
35
|
+
# value reflects just the visible part.
|
36
|
+
# If the character is not visible on the screen then the return value is an
|
37
|
+
# empty list.
|
38
|
+
def bbox(index)
|
39
|
+
execute('bbox', index)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Compares the indices given by index1 and index2 according to the
|
43
|
+
# relational operator given by op, and returns 1 if the relationship is
|
44
|
+
# satisfied and 0 if it is not.
|
45
|
+
# Op must be one of the operators <, <=, ==, >=, >, or !=.
|
46
|
+
# If op is == then true is returned if the two indices refer to the same
|
47
|
+
# character, if op is < then true is returned if index1 refers to an earlier
|
48
|
+
# character in the text than index2, and so on.
|
49
|
+
def compare(index1, op, index2)
|
50
|
+
execute('compare', index1, op, index2).to_boolean
|
51
|
+
end
|
52
|
+
|
53
|
+
# Counts the number of relevant things between the two indices.
|
54
|
+
# If index1 is after index2, the result will be a negative number (and this
|
55
|
+
# holds for each of the possible options).
|
56
|
+
# The actual items which are counted depend on the options given.
|
57
|
+
# The result is a list of integers, one for the result of each counting option given.
|
58
|
+
#
|
59
|
+
# Valid counting options are :chars, :displaychars, :displayindices,
|
60
|
+
# :displaylines, :indices, :lines, :xpixels and :ypixels.
|
61
|
+
# The default value, if no option is specified, is :indices.
|
62
|
+
# There is an additional possible option :update which is a modifier.
|
63
|
+
# If given, then all subsequent options ensure that any possible out of date
|
64
|
+
# information is recalculated.
|
65
|
+
# This currently only has any effect for the :ypixels count (which, if
|
66
|
+
# :update is not given, will use the text widget's current cached value for
|
67
|
+
# each line).
|
68
|
+
# The count options are interpreted as follows:
|
69
|
+
#
|
70
|
+
# :chars
|
71
|
+
# count all characters, whether elided or not. Do not count embedded
|
72
|
+
# windows or images.
|
73
|
+
# :displaychars
|
74
|
+
# count all non-elided characters.
|
75
|
+
# :displayindices
|
76
|
+
# count all non-elided characters, windows and images.
|
77
|
+
# :displaylines
|
78
|
+
# count all display lines (i.e. counting one for each time a line wraps)
|
79
|
+
# from the line of the first index up to, but not including the display
|
80
|
+
# line of the second index. Therefore if they are both on the same display
|
81
|
+
# line, zero will be returned. By definition displaylines are visible and
|
82
|
+
# therefore this only counts portions of actual visible lines.
|
83
|
+
# :indices
|
84
|
+
# count all characters and embedded windows or images (i.e. everything
|
85
|
+
# which counts in text-widget index space), whether they are elided or
|
86
|
+
# not.
|
87
|
+
# :lines
|
88
|
+
# count all logical lines (irrespective of wrapping) from the line of the
|
89
|
+
# first index up to, but not including the line of the second index.
|
90
|
+
# Therefore if they are both on the same line, zero will be returned.
|
91
|
+
# Logical lines are counted whether they are currently visible
|
92
|
+
# (non-elided) or not.
|
93
|
+
# :xpixels
|
94
|
+
# count the number of horizontal pixels from the first pixel of the first
|
95
|
+
# index to (but not including) the first pixel of the second index. To
|
96
|
+
# count the total desired width of the text widget (assuming wrapping is
|
97
|
+
# not enabled), first find the longest line and then use
|
98
|
+
# `text.count("#{line}.0", "#{line}.0", :xpixels)`.
|
99
|
+
# :ypixels
|
100
|
+
# count the number of vertical pixels from the first pixel of the first
|
101
|
+
# index to (but not including) the first pixel of the second index. If
|
102
|
+
# both indices are on the same display line, zero will be returned. To
|
103
|
+
# count the total number of vertical pixels in the text widget, use
|
104
|
+
# `text.count('1.0', 'end', :ypixels)`, and to ensure this is up to date,
|
105
|
+
# use `text.count('1.0', 'end', :update, :ypixels)`.
|
106
|
+
#
|
107
|
+
# The command returns a positive or negative integer corresponding to the
|
108
|
+
# number of items counted between the two indices. One such integer is
|
109
|
+
# returned for each counting option given, so a list is returned if more
|
110
|
+
# than one option was supplied. For example `text.count('1.3', '4.5',
|
111
|
+
# :xpixels, :ypixels` is perfectly valid and will return a list of two
|
112
|
+
# elements.
|
113
|
+
def count(index1, index2, *options)
|
114
|
+
args = options.map{|option| option.to_tcl_option }
|
115
|
+
execute('count', *args, index1, index2)
|
116
|
+
end
|
117
|
+
|
118
|
+
# If boolean is specified, then it must have one of the true or false values
|
119
|
+
# accepted by Tcl_GetBoolean.
|
120
|
+
# If the value is a true one then internal consistency checks will be turned
|
121
|
+
# on in the B-tree code associated with text widgets.
|
122
|
+
# If boolean has a false value then the debugging checks will be turned off.
|
123
|
+
# In either case the command returns an empty string.
|
124
|
+
# If boolean is not specified then the command returns on or off to indicate
|
125
|
+
# whether or not debugging is turned on.
|
126
|
+
# There is a single debugging switch shared by all text widgets: turning
|
127
|
+
# debugging on or off in any widget turns it on or off for all widgets.
|
128
|
+
# For widgets with large amounts of text, the consistency checks may cause a
|
129
|
+
# noticeable slow-down.
|
130
|
+
# When debugging is turned on, the drawing routines of the text widget set
|
131
|
+
# the global variables tk_textRedraw and tk_textRelayout to the lists of
|
132
|
+
# indices that are redrawn.
|
133
|
+
# The values of these variables are tested by Tk's test suite.
|
134
|
+
def debug(boolean = None)
|
135
|
+
if boolean == None
|
136
|
+
execute('debug') == 1
|
137
|
+
else
|
138
|
+
execute_only('debug', boolean ? true : false)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def debug?
|
143
|
+
execute('debug') == 1
|
144
|
+
end
|
145
|
+
|
146
|
+
# Delete a range of characters from the text.
|
147
|
+
# If both index1 and index2 are specified, then delete all the characters
|
148
|
+
# starting with the one given by index1 and stopping just before index2
|
149
|
+
# (i.e. the character at index2 is not deleted).
|
150
|
+
# If index2 does not specify a position later in the text than index1 then
|
151
|
+
# no characters are deleted.
|
152
|
+
# If index2 is not specified then the single character at index1 is deleted.
|
153
|
+
# It is not allowable to delete characters in a way that would leave the
|
154
|
+
# text without a newline as the last character.
|
155
|
+
# The command returns an empty string.
|
156
|
+
# If more indices are given, multiple ranges of text will be deleted.
|
157
|
+
# All indices are first checked for validity before any deletions are made.
|
158
|
+
# They are sorted and the text is removed from the last range to the first
|
159
|
+
# range to deleted text does not cause an undesired index shifting
|
160
|
+
# side-effects.
|
161
|
+
# If multiple ranges with the same start index are given, then the longest
|
162
|
+
# range is used.
|
163
|
+
# If overlapping ranges are given, then they will be merged into spans that
|
164
|
+
# do not cause deletion of text outside the given ranges due to text shifted
|
165
|
+
# during deletion.
|
166
|
+
def delete(index1, *rest)
|
167
|
+
execute('delete', index1, *rest)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Returns a list with five elements describing the area occupied by the
|
171
|
+
# display line containing index.
|
172
|
+
# The first two elements of the list give the x and y coordinates of the
|
173
|
+
# upper-left corner of the area occupied by the line, the third and fourth
|
174
|
+
# elements give the width and height of the area, and the fifth element
|
175
|
+
# gives the position of the baseline for the line, measured down from the
|
176
|
+
# top of the area.
|
177
|
+
# All of this information is measured in pixels.
|
178
|
+
# If the current wrap mode is none and the line extends beyond the
|
179
|
+
# boundaries of the window, the area returned reflects the entire area of
|
180
|
+
# the line, including the portions that are out of the window.
|
181
|
+
# If the line is shorter than the full width of the window then the area
|
182
|
+
# returned reflects just the portion of the line that is occupied by
|
183
|
+
# characters and embedded windows.
|
184
|
+
# If the display line containing index is not visible on the screen then the
|
185
|
+
# return value is an empty list.
|
186
|
+
def dlineinfo(index)
|
187
|
+
info = execute('dlineinfo', index).to_a
|
188
|
+
info.empty? ? nil : info.map(&:to_i)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Return the contents of the text widget from index1 up to, but not
|
192
|
+
# including index2, including the text and information about marks, tags,
|
193
|
+
# and embedded windows. If index2 is not specified, then it defaults to one
|
194
|
+
# character past index1. The information is returned in the following
|
195
|
+
# format:
|
196
|
+
#
|
197
|
+
# pathName dump ?switches? index1 ?index2?
|
198
|
+
def dump(*arguments, given_index)
|
199
|
+
arguments = arguments.dup
|
200
|
+
invocation = []
|
201
|
+
indices = [given_index]
|
202
|
+
|
203
|
+
while arg = arguments.shift
|
204
|
+
case arg.to_tcl
|
205
|
+
when '-command'
|
206
|
+
command = arguments.shift
|
207
|
+
invocation << ['-command', command]
|
208
|
+
when /^-(all|image|mark|tag|text|window)$/
|
209
|
+
invocation << tcl_option(arg)
|
210
|
+
else
|
211
|
+
indices.unshift(arg)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
execute('dump', *invocation, *indices)
|
216
|
+
end
|
217
|
+
|
218
|
+
# If boolean is not specified, returns the modified flag of the widget.
|
219
|
+
# The insert, delete, edit undo and edit redo commands or the user can set
|
220
|
+
# or clear the modified flag.
|
221
|
+
# If boolean is specified, sets the modified flag of the widget to boolean.
|
222
|
+
def edit_modified(boolean = None)
|
223
|
+
if boolean == None
|
224
|
+
execute('edit', 'modified')
|
225
|
+
else
|
226
|
+
execute_only('edit', 'modified', boolean ? true : false)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def edit_modified?
|
231
|
+
execute('edit', 'modified').to_boolean
|
232
|
+
end
|
233
|
+
|
234
|
+
# When the -undo option is true, reapplies the last undone edits provided no
|
235
|
+
# other edits were done since then.
|
236
|
+
# Generates an error when the redo stack is empty.
|
237
|
+
# Does nothing when the -undo option is false.
|
238
|
+
def edit_redo
|
239
|
+
execute_only('edit', 'redo')
|
240
|
+
end
|
241
|
+
|
242
|
+
# Clears the undo and redo stacks.
|
243
|
+
def edit_reset
|
244
|
+
execute_only('edit', 'reset')
|
245
|
+
end
|
246
|
+
|
247
|
+
# Inserts a separator (boundary) on the undo stack. Does nothing when the
|
248
|
+
# -undo option is false.
|
249
|
+
def edit_separator
|
250
|
+
execute_only('edit', 'separator')
|
251
|
+
end
|
252
|
+
|
253
|
+
# Undoes the last edit action when the -undo option is true.
|
254
|
+
# An edit action is defined as all the insert and delete commands that are
|
255
|
+
# recorded on the undo stack in between two separators.
|
256
|
+
# Generates an error when the undo stack is empty.
|
257
|
+
# Does nothing when the -undo option is false.
|
258
|
+
def edit_undo
|
259
|
+
execute_only('edit', 'undo')
|
260
|
+
end
|
261
|
+
|
262
|
+
# Return a range of characters from the text.
|
263
|
+
#
|
264
|
+
# The return value will be all the characters in the text starting with the
|
265
|
+
# one whose index is index1 and ending just before the one whose index is
|
266
|
+
# index2 (the character at index2 will not be returned).
|
267
|
+
#
|
268
|
+
# If index2 is omitted then the single character at index1 is returned.
|
269
|
+
# If there are no characters in the specified range (e.g. index1 is past the
|
270
|
+
# end of the file or index2 is less than or equal to index1) then an empty
|
271
|
+
# string is returned.
|
272
|
+
#
|
273
|
+
# If the specified range contains embedded windows, no information about
|
274
|
+
# them is included in the returned string.
|
275
|
+
# If multiple index pairs are given, multiple ranges of text will be
|
276
|
+
# returned in a list.
|
277
|
+
# Invalid ranges will not be represented with empty strings in the list.
|
278
|
+
# The ranges are returned in the order passed to [get].
|
279
|
+
#
|
280
|
+
# @see get_displaychars
|
281
|
+
def get(index, *indices)
|
282
|
+
execute('get', index, *indices).to_s
|
283
|
+
end
|
284
|
+
|
285
|
+
# Same as [get], but within each range, only those characters which are not
|
286
|
+
# elided will be returned.
|
287
|
+
# This may have the effect that some of the returned ranges are empty
|
288
|
+
# strings.
|
289
|
+
def get_displaychars(index, *indices)
|
290
|
+
execute('get', '-displaychars', index, *indices)
|
291
|
+
end
|
292
|
+
|
293
|
+
def image_cget(index, option)
|
294
|
+
option = tcl_option(option)
|
295
|
+
Cget.option_to_ruby(option, execute('image', 'cget', index))
|
296
|
+
end
|
297
|
+
|
298
|
+
# Query or modify the configuration options for an embedded image.
|
299
|
+
# If no option is specified, returns a list describing all of the available
|
300
|
+
# options for the embedded image at index (see Tk_ConfigureInfo for
|
301
|
+
# information on the format of this list).
|
302
|
+
# If option is specified with no value, then the command returns a list
|
303
|
+
# describing the one named option (this list will be identical to the
|
304
|
+
# corresponding sublist of the value returned if no option is specified).
|
305
|
+
# If one or more option-value pairs are specified, then the command modifies
|
306
|
+
# the given option(s) to have the given value(s); in this case the command
|
307
|
+
# returns an empty string.
|
308
|
+
# See EMBEDDED IMAGES for information on the options that are supported.
|
309
|
+
def image_configure(index, options = None)
|
310
|
+
common_configure([:image, :configure, index], options)
|
311
|
+
end
|
312
|
+
|
313
|
+
# This command creates a new image annotation, which will appear in the text
|
314
|
+
# at the position given by index.
|
315
|
+
# Any number of option-value pairs may be specified to configure the
|
316
|
+
# annotation.
|
317
|
+
# Returns a unique identifier that may be used as an index to refer to this
|
318
|
+
# image.
|
319
|
+
# See EMBEDDED IMAGES for information on the options that are supported, and
|
320
|
+
# a description of the identifier returned.
|
321
|
+
def image_create(index, options = {})
|
322
|
+
execute('image', 'create', index, options.to_tcl_options)
|
323
|
+
end
|
324
|
+
|
325
|
+
def image_names
|
326
|
+
execute('image', 'names')
|
327
|
+
end
|
328
|
+
|
329
|
+
# Returns the position corresponding to index in the form line.char where
|
330
|
+
# line is the line number and char is the character number. Index may have
|
331
|
+
# any of the forms described under INDICES above.
|
332
|
+
def index(index)
|
333
|
+
execute('index', index)
|
334
|
+
end
|
335
|
+
|
336
|
+
# Inserts all of the chars arguments just before the character at index.
|
337
|
+
#
|
338
|
+
# If index refers to the end of the text (the character after the last
|
339
|
+
# newline) then the new text is inserted just before the last newline
|
340
|
+
# instead.
|
341
|
+
# If there is a single chars argument and no tagList, then the new text will
|
342
|
+
# receive any tags that are present on both the character before and the
|
343
|
+
# character after the insertion point; if a tag is present on only one of
|
344
|
+
# these characters then it will not be applied to the new text.
|
345
|
+
# If tagList is specified then it consists of a list of tag names; the new
|
346
|
+
# characters will receive all of the tags in this list and no others,
|
347
|
+
# regardless of the tags present around the insertion point.
|
348
|
+
# If multiple chars-tagList argument pairs are present, they produce the
|
349
|
+
# same effect as if a separate pathName insert widget command had been
|
350
|
+
# issued for each pair, in order.
|
351
|
+
# The last tagList argument may be omitted.
|
352
|
+
def insert(index, string, taglist = nil, *rest)
|
353
|
+
execute_only('insert', index, *[string, taglist, *rest].compact)
|
354
|
+
end
|
355
|
+
|
356
|
+
# If direction is not specified, returns left or right to indicate which of
|
357
|
+
# its adjacent characters markName is attached to.
|
358
|
+
# If direction is specified, it must be left or right; the gravity of
|
359
|
+
# markName is set to the given value.
|
360
|
+
def mark_gravity(name, direction = None)
|
361
|
+
if direction == None
|
362
|
+
execute('mark', 'gravity', name).to_sym?
|
363
|
+
else
|
364
|
+
execute_only('mark', 'gravity', name, direction)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
# Returns a list whose elements are the names of all the marks that are
|
369
|
+
# currently set.
|
370
|
+
def mark_names
|
371
|
+
execute('mark', 'names').to_a.map(&:to_sym)
|
372
|
+
end
|
373
|
+
|
374
|
+
# Returns the name of the next mark at or after index.
|
375
|
+
# If index is specified in numerical form, then the search for the next mark
|
376
|
+
# begins at that index.
|
377
|
+
# If index is the name of a mark, then the search for the next mark begins
|
378
|
+
# immediately after that mark.
|
379
|
+
# This can still return a mark at the same position if there are multiple
|
380
|
+
# marks at the same index.
|
381
|
+
# These semantics mean that the mark next operation can be used to step
|
382
|
+
# through all the marks in a text widget in the same order as the mark
|
383
|
+
# information returned by the pathName dump operation.
|
384
|
+
# If a mark has been set to the special end index, then it appears to be
|
385
|
+
# after end with respect to the pathName mark next operation.
|
386
|
+
# nil is returned if there are no marks after index.
|
387
|
+
def mark_next(index)
|
388
|
+
execute('mark', 'next', index).to_sym?
|
389
|
+
end
|
390
|
+
|
391
|
+
# Returns the name of the mark at or before index.
|
392
|
+
# If index is specified in numerical form, then the search for the previous
|
393
|
+
# mark begins with the character just before that index.
|
394
|
+
# If index is the name of a mark, then the search for the next mark begins
|
395
|
+
# immediately before that mark.
|
396
|
+
# This can still return a mark at the same position if there are multiple
|
397
|
+
# marks at the same index.
|
398
|
+
# These semantics mean that the pathName mark previous operation can be used
|
399
|
+
# to step through all the marks in a text widget in the reverse order as the
|
400
|
+
# mark information returned by the pathName dump operation.
|
401
|
+
# nil is returned if there are no marks before index.
|
402
|
+
def mark_previous(index)
|
403
|
+
execute('mark', 'previous', index).to_sym?
|
404
|
+
end
|
405
|
+
|
406
|
+
# Sets the mark named markName to a position just before the character at
|
407
|
+
# index.
|
408
|
+
# If markName already exists, it is moved from its old position; if it does
|
409
|
+
# not exist, a new mark is created.
|
410
|
+
def mark_set(name, index)
|
411
|
+
execute_only('mark', 'set', name, index)
|
412
|
+
end
|
413
|
+
|
414
|
+
# Remove the mark corresponding to each of the markName arguments.
|
415
|
+
# The removed marks will not be usable in indices and will not be returned
|
416
|
+
# by future calls to [mark_names].
|
417
|
+
def mark_unset(*names)
|
418
|
+
execute_only('mark', 'unset', *names)
|
419
|
+
end
|
420
|
+
|
421
|
+
# Creates a peer text widget, and any optional standard configuration
|
422
|
+
# options (as for the text command).
|
423
|
+
# By default the peer will have the same start and end line as the parent
|
424
|
+
# widget, but these can be overridden with the standard configuration
|
425
|
+
# options.
|
426
|
+
def peer_create(options = {})
|
427
|
+
Peer.new(self, options)
|
428
|
+
end
|
429
|
+
|
430
|
+
# Returns a list of peers of this widget (this does not include the widget
|
431
|
+
# itself). The order within this list is undefined.
|
432
|
+
def peer_names
|
433
|
+
execute('peer', 'names').to_a.map(&:to_s)
|
434
|
+
end
|
435
|
+
|
436
|
+
# Replaces the range of characters between +index1+ and +index2+ with the
|
437
|
+
# given characters and tags.
|
438
|
+
# See the section on [insert] for an explanation of the handling of taglist
|
439
|
+
# arguments, and the docs of [delete] for an explanation of the handling of
|
440
|
+
# the indices.
|
441
|
+
# If +index2+ corresponds to an index earlier in the text than +index1+, an
|
442
|
+
# error will be generated.
|
443
|
+
# The deletion and insertion are arranged so that no unnecessary scrolling
|
444
|
+
# of the window or movement of insertion cursor occurs.
|
445
|
+
# In addition the undo/redo stack are correctly modified, if undo operations
|
446
|
+
# are active in the text widget.
|
447
|
+
# The command returns nil.
|
448
|
+
def replace(index1, index2, chars, *taglists_and_chars)
|
449
|
+
execute_only(:replace, index1, index2, chars, *taglists_and_chars)
|
450
|
+
end
|
451
|
+
|
452
|
+
# Records +x+ and +y+ and the current view in the text window, for use in
|
453
|
+
# conjunction with later pathName scan dragto commands.
|
454
|
+
# Typically this command is associated with a mouse button press in the
|
455
|
+
# widget.
|
456
|
+
# It returns nil.
|
457
|
+
def scan_mark(x, y)
|
458
|
+
execute_only(:scan, :mark, x, y)
|
459
|
+
end
|
460
|
+
|
461
|
+
# This command computes the difference between its +x+ and +y+ arguments and
|
462
|
+
# the +x+ and +y+ arguments to the last pathName scan mark command for the
|
463
|
+
# widget. It then adjusts the view by 10 times the difference in
|
464
|
+
# coordinates. This command is typically associated with mouse motion events
|
465
|
+
# in the widget, to produce the effect of dragging the text at high speed
|
466
|
+
# through the window.
|
467
|
+
# The return value is nil.
|
468
|
+
def scan_dargto(x, y)
|
469
|
+
execute_only(:scan, :dragto, x, y)
|
470
|
+
end
|
471
|
+
|
472
|
+
# Searches the text starting at index for a range of characters that matches
|
473
|
+
# pattern.
|
474
|
+
# If a match is found, the index of the first character in the match is
|
475
|
+
# returned as result; otherwise an empty string is returned.
|
476
|
+
# One or more of the following switches may be specified to control the
|
477
|
+
# search:
|
478
|
+
#
|
479
|
+
# :forwards
|
480
|
+
# The search will proceed forward through the text, finding the first
|
481
|
+
# matching range starting at or after the position given by index.
|
482
|
+
# This is the default.
|
483
|
+
#
|
484
|
+
# :backwards
|
485
|
+
# The search will proceed backward through the text, finding the
|
486
|
+
# matching range closest to index whose first character is before index
|
487
|
+
# (it is not allowed to be at index).
|
488
|
+
# Note that, for a variety of reasons, backwards searches can be
|
489
|
+
# substantially slower than forwards searches (particularly when using
|
490
|
+
# :regexp), so it is recommended that performance-critical code use
|
491
|
+
# forward searches.
|
492
|
+
#
|
493
|
+
# :exact
|
494
|
+
# Use exact matching: the characters in the matching range must be
|
495
|
+
# identical to those in pattern.
|
496
|
+
# This is the default.
|
497
|
+
#
|
498
|
+
# :regexp
|
499
|
+
# Treat pattern as a regular expression and match it against the text
|
500
|
+
# using the rules for regular expressions (see the regexp command for
|
501
|
+
# details). The default matching automatically passes both the
|
502
|
+
# :lineanchor and :linestop options to the regexp engine (unless
|
503
|
+
# :nolinestop is used), so that "^", "$" match beginning and end of
|
504
|
+
# line, and ".", "[^" sequences will never match the newline character
|
505
|
+
# "\n".
|
506
|
+
#
|
507
|
+
# :nolinestop
|
508
|
+
# This allows "." and "[^" sequences to match the newline character "\n",
|
509
|
+
# which they will otherwise not do (see the regexp command for details).
|
510
|
+
# This option is only meaningful if :regexp is also given, and an error
|
511
|
+
# will be thrown otherwise.
|
512
|
+
# For example, to match the entire text, use `text.search(/.*/m)`.
|
513
|
+
#
|
514
|
+
# :nocase
|
515
|
+
# Ignore case differences between the pattern and the text.
|
516
|
+
#
|
517
|
+
# :count varName
|
518
|
+
# The argument following :count gives the name of a variable; if a match
|
519
|
+
# is found, the number of index positions between beginning and end of
|
520
|
+
# the matching range will be stored in the variable.
|
521
|
+
# If there are no embedded images or windows in the matching range (and
|
522
|
+
# there are no elided characters if :elide is not given), this is
|
523
|
+
# equivalent to the number of characters matched.
|
524
|
+
# In either case, the range matchIdx to matchIdx + $count chars will
|
525
|
+
# return the entire matched text.
|
526
|
+
#
|
527
|
+
# :all
|
528
|
+
# Find all matches in the given range and return a list of the indices of
|
529
|
+
# the first character of each match.
|
530
|
+
#
|
531
|
+
# If a :count switch is given, then the returned array has two elements
|
532
|
+
# in the form of `[index, count]` for each successful match.
|
533
|
+
# Note that, even for exact searches, the elements of this list may be
|
534
|
+
# different, if there are embedded images, windows or hidden text.
|
535
|
+
# Searches with :all behave very similarly to the Tcl command regexp
|
536
|
+
# :all, in that overlapping matches are not normally returned.
|
537
|
+
# For example, applying an :all search of the pattern `\w+` against
|
538
|
+
# "hello there" will just match twice, once for each word, and
|
539
|
+
# matching `Z[a-z]+Z` against "ZooZooZoo" will just match once.
|
540
|
+
#
|
541
|
+
# :overlap
|
542
|
+
# When performing :all searches, the normal behaviour is that matches
|
543
|
+
# which overlap an already-found match will not be returned.
|
544
|
+
# This switch changes that behaviour so that all matches which are not
|
545
|
+
# totally enclosed within another match are returned.
|
546
|
+
# For example, applying an :overlap search of the pattern `\w+`
|
547
|
+
# against "hello there" will just match twice (i.e.
|
548
|
+
# no different to just :all), but matching `Z[a-z]+Z` against
|
549
|
+
# "ZooZooZoo" will now match twice.
|
550
|
+
# An error will be thrown if this switch is used without :all.
|
551
|
+
#
|
552
|
+
# :strictlimits
|
553
|
+
# When performing any search, the normal behaviour is that the start and
|
554
|
+
# stop limits are checked with respect to the start of the matching
|
555
|
+
# text. With the :strictlimits flag, the entire matching range must lie
|
556
|
+
# inside the start and stop limits specified for the match to be valid.
|
557
|
+
#
|
558
|
+
# :elide
|
559
|
+
# Find elided (hidden) text as well.
|
560
|
+
# By default only displayed text is searched.
|
561
|
+
#
|
562
|
+
# --
|
563
|
+
# This switch has no effect except to terminate the list of switches:
|
564
|
+
# the next argument will be treated as pattern even if it starts with -.
|
565
|
+
#
|
566
|
+
# The matching range may be within a single line of text, or run across
|
567
|
+
# multiple lines (if parts of the pattern can match a new-line).
|
568
|
+
# For regular expression matching one can use the various newline-matching
|
569
|
+
# features such as $ to match the end of a line, "^" to match the beginning
|
570
|
+
# of a line, and to control whether "." is allowed to match a new-line.
|
571
|
+
# If stop_index is specified, the search stops at that index: for forward
|
572
|
+
# searches, no match at or after stop_index will be considered; for backward
|
573
|
+
# searches, no match earlier in the text than stop_index will be considered.
|
574
|
+
# If stop_index is omitted, the entire text will be searched: when the
|
575
|
+
# beginning or end of the text is reached, the search continues at the other
|
576
|
+
# end until the starting location is reached again; if stop_index is
|
577
|
+
# specified, no wrap-around will occur.
|
578
|
+
# This means that, for example, if the search is :forwards but stop_index is
|
579
|
+
# earlier in the text than start_index, nothing will ever be found.
|
580
|
+
# See KNOWN BUGS in [Text] for a number of minor limitations of [search] method.
|
581
|
+
#
|
582
|
+
# pathName search ?switches? pattern index ?stopIndex?
|
583
|
+
#
|
584
|
+
# FUNNY: stdlib tk simply gets the text into the ruby side and performs
|
585
|
+
# matches using the core regexp methods, but doesn't give any way to
|
586
|
+
# call the tcl/tk search function, this is new land!
|
587
|
+
def search(pattern, from, to = None, *switches)
|
588
|
+
switches << :regexp if pattern.class < CoreExtensions::Regexp
|
589
|
+
to = :end if None == to
|
590
|
+
|
591
|
+
switches.map!{|switch| switch.to_s.to_tcl_option }
|
592
|
+
switches.uniq!
|
593
|
+
|
594
|
+
if switches.include?('-all') && switches.delete('-count')
|
595
|
+
count_all = 'RubyFFI::Text_search_count'
|
596
|
+
switches << '-count' << count_all
|
597
|
+
elsif switches.delete('-count')
|
598
|
+
count = 'RubyFFI::Text_search_count'
|
599
|
+
switches << '-count' << count
|
600
|
+
end
|
601
|
+
|
602
|
+
sep = TclString.new('--')
|
603
|
+
|
604
|
+
if count
|
605
|
+
SEARCH_MUTEX.synchronize do
|
606
|
+
list = execute(:search, *switches, sep, pattern, from, to).to_a
|
607
|
+
return list if list.empty?
|
608
|
+
count_value = Tk.execute('set', count)
|
609
|
+
[*list, count_value]
|
610
|
+
end
|
611
|
+
elsif count_all
|
612
|
+
SEARCH_MUTEX.synchronize do
|
613
|
+
list = execute(:search, *switches, sep, pattern, from, to).to_a
|
614
|
+
return list if list.empty?
|
615
|
+
count_list = Tk.execute('set', count_all)
|
616
|
+
list.zip(count_list)
|
617
|
+
end
|
618
|
+
else
|
619
|
+
execute(:search, *switches, sep, pattern, from, to).to_a
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
def rsearch(pattern, from, to, *switches)
|
624
|
+
search(pattern, from, to, *switches, :backwards)
|
625
|
+
end
|
626
|
+
|
627
|
+
# Adjusts the view in the window so that the character given by +index+ is
|
628
|
+
# completely visible.
|
629
|
+
# If +index+ is already visible then the command does nothing.
|
630
|
+
# If +index+ is a short distance out of view, the command adjusts the view
|
631
|
+
# just enough to make +index+ visible at the edge of the window.
|
632
|
+
# If +index+ is far out of view, then the command centers +index+ in the
|
633
|
+
# window.
|
634
|
+
def see(index)
|
635
|
+
execute_only(:see, index)
|
636
|
+
end
|
637
|
+
|
638
|
+
# Associate the tag tagName with all of the characters starting with index1
|
639
|
+
# and ending just before index2 (the character at index2 is not tagged).
|
640
|
+
# A single command may contain any number of index1-index2 pairs.
|
641
|
+
# If the last index2 is omitted then the single character at index1 is
|
642
|
+
# tagged. If there are no characters in the specified range (e.g.
|
643
|
+
# index1 is past the end of the file or index2 is less than or equal to
|
644
|
+
# index1) then the command has no effect.
|
645
|
+
def tag_add(tag_name, index1, index2 = None, *indices)
|
646
|
+
execute_only(:tag, :add, tag_name, index1, index2, *indices)
|
647
|
+
end
|
648
|
+
|
649
|
+
# This command associates script with the tag given by tagName.
|
650
|
+
# Whenever the event sequence given by sequence occurs for a character that
|
651
|
+
# has been tagged with tagName, the script will be invoked.
|
652
|
+
# This widget command is similar to the bind command except that it
|
653
|
+
# operates on characters in a text rather than entire widgets.
|
654
|
+
# See the bind manual entry for complete details on the syntax of sequence
|
655
|
+
# and the substitutions performed on script before invoking it.
|
656
|
+
# If all arguments are specified then a new binding is created, replacing
|
657
|
+
# any existing binding for the same sequence and tagName (if the first
|
658
|
+
# character of script is “+” then script augments an existing binding
|
659
|
+
# rather than replacing it).
|
660
|
+
# In this case the return value is an empty string.
|
661
|
+
# If script is omitted then the command returns the script associated
|
662
|
+
# with tagName and sequence (an error occurs if there is no such binding).
|
663
|
+
# If both script and sequence are omitted then the command returns a list
|
664
|
+
# of all the sequences for which bindings have been defined for tagName.
|
665
|
+
# The only events for which bindings may be specified are those related to
|
666
|
+
# the mouse and keyboard (such as Enter, Leave, ButtonPress, Motion, and
|
667
|
+
# KeyPress) or virtual events.
|
668
|
+
# Event bindings for a text widget use the current mark described under
|
669
|
+
# MARKS above.
|
670
|
+
# An Enter event triggers for a tag when the tag first becomes present on
|
671
|
+
# the current character, and a Leave event triggers for a tag when it
|
672
|
+
# ceases to be present on the current character.
|
673
|
+
# Enter and Leave events can happen either because the current mark moved
|
674
|
+
# or because the character at that position changed.
|
675
|
+
# Note that these events are different than Enter and Leave events for
|
676
|
+
# windows. Mouse and keyboard events are directed to the current character.
|
677
|
+
# If a virtual event is used in a binding, that binding can trigger only if
|
678
|
+
# the virtual event is defined by an underlying mouse-related or
|
679
|
+
# keyboard-related event.
|
680
|
+
# It is possible for the current character to have multiple tags, and for
|
681
|
+
# each of them to have a binding for a particular event sequence.
|
682
|
+
# When this occurs, one binding is invoked for each tag, in order from
|
683
|
+
# lowest-priority to highest priority.
|
684
|
+
# If there are multiple matching bindings for a single tag, then the most
|
685
|
+
# specific binding is chosen (see the manual entry for the bind command
|
686
|
+
# for details).
|
687
|
+
# continue and break commands within binding scripts are processed in the
|
688
|
+
# same way as for bindings created with the bind command.
|
689
|
+
# If bindings are created for the widget as a whole using the bind command,
|
690
|
+
# then those bindings will supplement the tag bindings.
|
691
|
+
# The tag bindings will be invoked first, followed by bindings for the
|
692
|
+
# window as a whole.
|
693
|
+
def tag_bind(tag_name, sequence = None, &script)
|
694
|
+
unless script
|
695
|
+
if None == sequence
|
696
|
+
return Tk.execute(:tag, :bind, tag_name)
|
697
|
+
else
|
698
|
+
return Tk.execute(:tag, :bind, tag_name, sequence)
|
699
|
+
end
|
700
|
+
end
|
701
|
+
|
702
|
+
# create name for command
|
703
|
+
name = "#{tk_pathname}_#{tag_name}".scan(/\w+/).join('_')
|
704
|
+
@events ||= {}
|
705
|
+
unregister_event(name)
|
706
|
+
|
707
|
+
Event::Handler.register_custom(script) do |id|
|
708
|
+
code = "%s tag bind %s %s { ::RubyFFI::event %d '' %s }"
|
709
|
+
props = Event::Data::PROPERTIES.transpose[0].join(' ')
|
710
|
+
tcl = code % [tk_pathname, tag_name, sequence, id, props]
|
711
|
+
Tk.interp.eval(tcl)
|
712
|
+
@events[name] = id
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
def unregister_event(name, id = @events[name])
|
717
|
+
return unless id
|
718
|
+
@events.delete(id)
|
719
|
+
Event::Handler.unregister(id)
|
720
|
+
end
|
721
|
+
|
722
|
+
# This command returns the current value of the option named option
|
723
|
+
# associated with the tag given by tagName.
|
724
|
+
# Option may have any of the values accepted by the pathName tag
|
725
|
+
# configure widget command.
|
726
|
+
def tag_cget(tag_name, option)
|
727
|
+
execute(:tag, :cget, tag_name, option.to_tcl_option)
|
728
|
+
end
|
729
|
+
|
730
|
+
# This command is similar to the pathName configure widget command except
|
731
|
+
# that it modifies options associated with the tag given by tagName instead
|
732
|
+
# of modifying options for the overall text widget.
|
733
|
+
# If no option is specified, the command returns a list describing all of
|
734
|
+
# the available options for tagName (see Tk_ConfigureInfo for information
|
735
|
+
# on the format of this list).
|
736
|
+
# If option is specified with no value, then the command returns a list
|
737
|
+
# describing the one named option (this list will be identical to the
|
738
|
+
# corresponding sublist of the value returned if no option is specified).
|
739
|
+
# If one or more option-value pairs are specified, then the command
|
740
|
+
# modifies the given option(s) to have the given value(s) in tagName; in
|
741
|
+
# this case the command returns an empty string.
|
742
|
+
# See TAGS above for details on the options available for tags.
|
743
|
+
def tag_configure(tag_name, options = None)
|
744
|
+
common_configure([:tag, :configure, tag_name], options)
|
745
|
+
end
|
746
|
+
|
747
|
+
# Deletes all tag information for each of the tagName arguments.
|
748
|
+
# The command removes the tags from all characters in the file and also
|
749
|
+
# deletes any other information associated with the tags, such as
|
750
|
+
# bindings and display information.
|
751
|
+
# The command returns an empty string.
|
752
|
+
def tag_delete(tag_name, *tag_names)
|
753
|
+
execute_only(:tag, :delete, tag_name, *tag_names)
|
754
|
+
end
|
755
|
+
|
756
|
+
# Changes the priority of tag tagName so that it is just lower in priority
|
757
|
+
# than the tag whose name is belowThis.
|
758
|
+
# If belowThis is omitted, then tagName's priority is changed to make it
|
759
|
+
# lowest priority of all tags.
|
760
|
+
def tag_lower(tag_name, below = None)
|
761
|
+
execute_only(:tag, :lower, tag_name, below)
|
762
|
+
end
|
763
|
+
|
764
|
+
# Returns a list whose elements are the names of all the tags that are
|
765
|
+
# active at the character position given by index.
|
766
|
+
# If index is omitted, then the return value will describe all of the tags
|
767
|
+
# that exist for the text (this includes all tags that have been named in a
|
768
|
+
# “pathName tag” widget command but have not been deleted by a “pathName
|
769
|
+
# tag delete” widget command, even if no characters are currently marked
|
770
|
+
# with the tag).
|
771
|
+
# The list will be sorted in order from lowest priority to highest
|
772
|
+
# priority.
|
773
|
+
def tag_names(index = None)
|
774
|
+
execute(:tag, :names, index).to_a
|
775
|
+
end
|
776
|
+
|
777
|
+
# This command searches the text for a range of characters tagged with
|
778
|
+
# tagName where the first character of the range is no earlier than the
|
779
|
+
# character at index1 and no later than the character just before index2 (a
|
780
|
+
# range starting at index2 will not be considered).
|
781
|
+
# If several matching ranges exist, the first one is chosen.
|
782
|
+
# The command's return value is a list containing two elements, which are
|
783
|
+
# the index of the first character of the range and the index of the
|
784
|
+
# character just after the last one in the range.
|
785
|
+
# If no matching range is found then the return value is an empty string.
|
786
|
+
# If index2 is not given then it defaults to the end of the text.
|
787
|
+
def tag_nextrange(tag_name, index1, index2 = None)
|
788
|
+
execute(:tag, :nextrange, tag_name, index1, index2).to_a
|
789
|
+
end
|
790
|
+
|
791
|
+
# This command searches the text for a range of characters tagged with
|
792
|
+
# tagName where the first character of the range is before the character at
|
793
|
+
# index1 and no earlier than the character at index2 (a range starting at
|
794
|
+
# index2 will be considered).
|
795
|
+
# If several matching ranges exist, the one closest to index1 is chosen.
|
796
|
+
# The command's return value is a list containing two elements, which are
|
797
|
+
# the index of the first character of the range and the index of the
|
798
|
+
# character just after the last one in the range.
|
799
|
+
# If no matching range is found then the return value is an empty string.
|
800
|
+
# If index2 is not given then it defaults to the beginning of the text.
|
801
|
+
def tag_prevrange(tag_name, index1, index2 = None)
|
802
|
+
execute(:tag, :prevrange, tag_name, index1, index2).to_a
|
803
|
+
end
|
804
|
+
|
805
|
+
# Changes the priority of tag tagName so that it is just higher in priority
|
806
|
+
# than the tag whose name is aboveThis.
|
807
|
+
# If aboveThis is omitted, then tagName's priority is changed to make it
|
808
|
+
# highest priority of all tags.
|
809
|
+
def tag_raise(tag_name, above = None)
|
810
|
+
execute_only(:tag, :raise, tag_name, above)
|
811
|
+
end
|
812
|
+
|
813
|
+
# Returns a list describing all of the ranges of text that have been tagged
|
814
|
+
# with tagName.
|
815
|
+
# The first two elements of the list describe the first tagged range in the
|
816
|
+
# text, the next two elements describe the second range, and so on.
|
817
|
+
# The first element of each pair contains the index of the first character
|
818
|
+
# of the range, and the second element of the pair contains the index of
|
819
|
+
# the character just after the last one in the range.
|
820
|
+
# If there are no characters tagged with tag then an empty string is
|
821
|
+
# returned.
|
822
|
+
def tag_ranges(tag_name)
|
823
|
+
[*execute(:tag, :ranges, tag_name)].each_slice(2).to_a
|
824
|
+
end
|
825
|
+
|
826
|
+
# Remove the tag tagName from all of the characters starting at index1 and
|
827
|
+
# ending just before index2 (the character at index2 is not affected).
|
828
|
+
# A single command may contain any number of index1-index2 pairs.
|
829
|
+
# If the last index2 is omitted then the tag is removed from the single
|
830
|
+
# character at index1.
|
831
|
+
# If there are no characters in the specified range (e.g.
|
832
|
+
# index1 is past the end of the file or index2 is less than or equal to
|
833
|
+
# index1) then the command has no effect.
|
834
|
+
# This command returns an empty string.
|
835
|
+
def tag_remove(tag_name, index1, index2 = None, *indices)
|
836
|
+
execute_only(:tag, :remove, tag_name, index1, index2, *indices)
|
837
|
+
end
|
838
|
+
|
839
|
+
# Returns the value of a configuration option for an embedded window.
|
840
|
+
# Index identifies the embedded window, and option specifies a particular
|
841
|
+
# configuration option, which must be one of the ones listed in the section
|
842
|
+
# EMBEDDED WINDOWS.
|
843
|
+
def window_cget(index, option)
|
844
|
+
execute(:window, :cget, index, option.to_tcl_option)
|
845
|
+
end
|
846
|
+
|
847
|
+
# Query or modify the configuration options for an embedded window.
|
848
|
+
# If no option is specified, returns a list describing all of the available
|
849
|
+
# options for the embedded window at index (see Tk_ConfigureInfo for
|
850
|
+
# information on the format of this list).
|
851
|
+
# If option is specified with no value, then the command returns a list
|
852
|
+
# describing the one named option (this list will be identical to the
|
853
|
+
# corresponding sublist of the value returned if no option is specified).
|
854
|
+
# If one or more option-value pairs are specified, then the command
|
855
|
+
# modifies the given option(s) to have the given value(s); in this case the
|
856
|
+
# command returns an empty string.
|
857
|
+
# See EMBEDDED WINDOWS for information on the options that are supported.
|
858
|
+
def window_configure(index, options = None)
|
859
|
+
common_configure([:window, :configure, index], options)
|
860
|
+
end
|
861
|
+
|
862
|
+
# This command creates a new window annotation, which will appear in the
|
863
|
+
# text at the position given by index.
|
864
|
+
# Any number of option-value pairs may be specified to configure the
|
865
|
+
# annotation. See EMBEDDED WINDOWS for information on the options that are
|
866
|
+
# supported. Returns an empty string.
|
867
|
+
def window_create(index, options = None)
|
868
|
+
if None == argument
|
869
|
+
execute(:window, :create, index)
|
870
|
+
else
|
871
|
+
execute(:window, :create, index, options.to_tcl_options)
|
872
|
+
end
|
873
|
+
end
|
874
|
+
|
875
|
+
# Returns a list whose elements are the names of all windows currently
|
876
|
+
# embedded in window.
|
877
|
+
def window_names
|
878
|
+
execute(:window, :names).to_a
|
879
|
+
end
|
880
|
+
|
881
|
+
def copy
|
882
|
+
Tk.execute(:tk_textCopy, self)
|
883
|
+
end
|
884
|
+
|
885
|
+
def cut
|
886
|
+
Tk.execute(:tk_textCut, self)
|
887
|
+
end
|
888
|
+
|
889
|
+
def paste
|
890
|
+
Tk.execute(:tk_textPaste, self)
|
891
|
+
end
|
892
|
+
end
|
893
|
+
end
|