1 #
2 # tk/textmark.rb - methods for treating text marks
3 #
4 require 'tk'
5 require 'tk/text'
6
7 class TkTextMark<TkObject
8 include Tk::Text::IndexModMethods
9
10 TMarkID_TBL = TkCore::INTERP.create_table
11
12 (Tk_TextMark_ID = ['mark'.freeze, '00000'.taint]).instance_eval{
13 @mutex = Mutex.new
14 def mutex; @mutex; end
15 freeze
16 }
17
18 TkCore::INTERP.init_ip_env{
19 TMarkID_TBL.mutex.synchronize{ TMarkID_TBL.clear }
20 }
21
22 def TkTextMark.id2obj(text, id)
23 tpath = text.path
24 TMarkID_TBL.mutex.synchronize{
25 if TMarkID_TBL[tpath]
26 TMarkID_TBL[tpath][id]? TMarkID_TBL[tpath][id]: id
27 else
28 id
29 end
30 }
31 end
32
33 def initialize(parent, index)
34 #unless parent.kind_of?(Tk::Text)
35 # fail ArgumentError, "expect Tk::Text for 1st argument"
36 #end
37 @parent = @t = parent
38 @tpath = parent.path
39 Tk_TextMark_ID.mutex.synchronize{
40 # @path = @id = Tk_TextMark_ID.join('')
41 @path = @id = Tk_TextMark_ID.join(TkCore::INTERP._ip_id_).freeze
42 Tk_TextMark_ID[1].succ!
43 }
44 TMarkID_TBL.mutex.synchronize{
45 TMarkID_TBL[@id] = self
46 TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath]
47 TMarkID_TBL[@tpath][@id] = self
48 }
49 tk_call_without_enc(@t.path, 'mark', 'set', @id,
50 _get_eval_enc_str(index))
51 @t._addtag id, self
52 end
53
54 def id
55 Tk::Text::IndexString.new(@id)
56 end
57
58 def exist?
59 #if ( tk_split_simplelist(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'names'))).find{|id| id == @id } )
60 if ( tk_split_simplelist(tk_call_without_enc(@t.path, 'mark', 'names'), false, true).find{|id| id == @id } )
61 true
62 else
63 false
64 end
65 end
66
67 =begin
68 # move to Tk::Text::IndexModMethods module
69 def +(mod)
70 return chars(mod) if mod.kind_of?(Numeric)
71
72 mod = mod.to_s
73 if mod =~ /^\s*[+-]?\d/
74 Tk::Text::IndexString.new(@id + ' + ' + mod)
75 else
76 Tk::Text::IndexString.new(@id + ' ' + mod)
77 end
78 end
79
80 def -(mod)
81 return chars(-mod) if mod.kind_of?(Numeric)
82
83 mod = mod.to_s
84 if mod =~ /^\s*[+-]?\d/
85 Tk::Text::IndexString.new(@id + ' - ' + mod)
86 elsif mod =~ /^\s*[-]\s+(\d.*)$/
87 Tk::Text::IndexString.new(@id + ' - -' + $1)
88 else
89 Tk::Text::IndexString.new(@id + ' ' + mod)
90 end
91 end
92 =end
93
94 def pos
95 @t.index(@id)
96 end
97
98 def pos=(where)
99 set(where)
100 end
101
102 def set(where)
103 tk_call_without_enc(@t.path, 'mark', 'set', @id,
104 _get_eval_enc_str(where))
105 self
106 end
107
108 def unset
109 tk_call_without_enc(@t.path, 'mark', 'unset', @id)
110 self
111 end
112 alias destroy unset
113
114 def gravity
115 tk_call_without_enc(@t.path, 'mark', 'gravity', @id)
116 end
117
118 def gravity=(direction)
119 tk_call_without_enc(@t.path, 'mark', 'gravity', @id, direction)
120 #self
121 direction
122 end
123
124 def next(index = nil)
125 if index
126 @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'next', _get_eval_enc_str(index))))
127 else
128 @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'next', @id)))
129 end
130 end
131
132 def previous(index = nil)
133 if index
134 @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'previous', _get_eval_enc_str(index))))
135 else
136 @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'previous', @id)))
137 end
138 end
139 end
140 TktMark = TkTextMark
141
142 class TkTextNamedMark<TkTextMark
143 def self.new(parent, name, index=nil)
144 TMarkID_TBL.mutex.synchronize{
145 if TMarkID_TBL[parent.path] && TMarkID_TBL[parent.path][name]
146 obj = TMarkID_TBL[parent.path][name]
147 else
148 # super(parent, name, *args)
149 (obj = self.allocate).instance_eval{
150 @parent = @t = parent
151 @tpath = parent.path
152 @path = @id = name
153 TMarkID_TBL[@id] = self
154 TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath]
155 TMarkID_TBL[@tpath][@id] = self unless TMarkID_TBL[@tpath][@id]
156 @t._addtag @id, self
157 }
158 obj
159 end
160
161 if obj && index
162 tk_call_without_enc(parent.path, 'mark', 'set', name,
163 _get_eval_enc_str(index))
164 end
165 obj
166 }
167 end
168
169 def initialize(parent, name, index=nil)
170 # dummy:: not called by 'new' method
171
172 #unless parent.kind_of?(Tk::Text)
173 # fail ArgumentError, "expect Tk::Text for 1st argument"
174 #end
175 @parent = @t = parent
176 @tpath = parent.path
177 @path = @id = name
178 tk_call_without_enc(@t.path, 'mark', 'set', @id,
179 _get_eval_enc_str(index)) if index
180 @t._addtag @id, self
181 end
182 end
183 TktNamedMark = TkTextNamedMark
184
185 class TkTextMarkInsert<TkTextNamedMark
186 def self.new(parent,*args)
187 super(parent, 'insert', *args)
188 end
189 end
190 TktMarkInsert = TkTextMarkInsert
191
192 class TkTextMarkCurrent<TkTextNamedMark
193 def self.new(parent,*args)
194 super(parent, 'current', *args)
195 end
196 end
197 TktMarkCurrent = TkTextMarkCurrent
198
199 class TkTextMarkAnchor<TkTextNamedMark
200 def self.new(parent,*args)
201 super(parent, 'anchor', *args)
202 end
203 end
204 TktMarkAnchor = TkTextMarkAnchor