OSDN Git Service

FIRST REPOSITORY
[eos/hostdependOTHERS.git] / ALPHALINUX5 / util / ALPHALINUX5 / lib / ruby / 1.6 / tktext.rb
1 #
2 #               tktext.rb - Tk text classes
3 #                       $Date: 2002/02/01 06:35:37 $
4 #                       by Yukihiro Matsumoto <matz@caelum.co.jp>
5
6 require 'tk.rb'
7 require 'tkfont'
8
9 module TkTreatTextTagFont
10   def tagfont_configinfo(tag)
11     if tag.kind_of? TkTextTag
12       pathname = self.path + ';' + tag.id
13     else
14       pathname = self.path + ';' + tag
15     end
16     ret = TkFont.used_on(pathname)
17     if ret == nil
18       ret = TkFont.init_widget_font(pathname, 
19                                     self.path, 'tag', 'configure', tag)
20     end
21     ret
22   end
23   alias tagfontobj tagfont_configinfo
24
25   def tagfont_configure(tag, slot)
26     if tag.kind_of? TkTextTag
27       pathname = self.path + ';' + tag.id
28     else
29       pathname = self.path + ';' + tag
30     end
31     if (fnt = slot.delete('font'))
32       if fnt.kind_of? TkFont
33         return fnt.call_font_configure(pathname, 
34                                        self.path,'tag','configure',tag,slot)
35       else
36         latintagfont_configure(tag, fnt) if fnt
37       end
38     end
39     if (ltn = slot.delete('latinfont'))
40       latintagfont_configure(tag, ltn) if ltn
41     end
42     if (ltn = slot.delete('asciifont'))
43       latintagfont_configure(tag, ltn) if ltn
44     end
45     if (knj = slot.delete('kanjifont'))
46       kanjitagfont_configure(tag, knj) if knj
47     end
48
49     tk_call(self.path, 'tag', 'configure', tag, *hash_kv(slot)) if slot != {}
50     self
51   end
52
53   def latintagfont_configure(tag, ltn, keys=nil)
54     fobj = tagfontobj(tag)
55     if ltn.kind_of? TkFont
56       conf = {}
57       ltn.latin_configinfo.each{|key,val| conf[key] = val if val != []}
58       if conf == {}
59         fobj.latin_replace(ltn)
60         fobj.latin_configure(keys) if keys
61       elsif keys
62         fobj.latin_configure(conf.update(keys))
63       else
64         fobj.latin_configure(conf)
65       end
66     else
67       fobj.latin_replace(ltn)
68     end
69   end
70   alias asciitagfont_configure latintagfont_configure
71
72   def kanjitagfont_configure(tag, knj, keys=nil)
73     fobj = tagfontobj(tag)
74     if knj.kind_of? TkFont
75       conf = {}
76       knj.kanji_configinfo.each{|key,val| conf[key] = val if val != []}
77       if conf == {}
78         fobj.kanji_replace(knj)
79         fobj.kanji_configure(keys) if keys
80       elsif keys
81         fobj.kanji_configure(conf.update(keys))
82       else
83         fobj.kanji_configure(conf)
84       end
85     else
86       fobj.kanji_replace(knj)
87     end
88   end
89
90   def tagfont_copy(tag, window, wintag=nil)
91     if wintag
92       window.tagfontobj(wintag).configinfo.each{|key,value|
93         tagfontobj(tag).configure(key,value)
94       }
95       tagfontobj(tag).replace(window.tagfontobj(wintag).latin_font, 
96                               window.tagfontobj(wintag).kanji_font)
97     else
98       window.tagfont(wintag).configinfo.each{|key,value|
99         tagfontobj(tag).configure(key,value)
100       }
101       tagfontobj(tag).replace(window.fontobj.latin_font, 
102                               window.fontobj.kanji_font)
103     end
104   end
105
106   def latintagfont_copy(tag, window, wintag=nil)
107     if wintag
108       tagfontobj(tag).latin_replace(window.tagfontobj(wintag).latin_font)
109     else
110       tagfontobj(tag).latin_replace(window.fontobj.latin_font)
111     end
112   end
113   alias asciitagfont_copy latintagfont_copy
114
115   def kanjitagfont_copy(tag, window, wintag=nil)
116     if wintag
117       tagfontobj(tag).kanji_replace(window.tagfontobj(wintag).kanji_font)
118     else
119       tagfontobj(tag).kanji_replace(window.fontobj.kanji_font)
120     end
121   end
122 end
123
124 class TkText<TkTextWin
125   include TkTreatTextTagFont
126   include Scrollable
127
128   WidgetClassName = 'Text'.freeze
129   WidgetClassNames[WidgetClassName] = self
130
131   def self.to_eval
132     WidgetClassName
133   end
134
135   def self.new(*args, &block)
136     obj = super(*args){}
137     obj.init_instance_variable
138     obj.instance_eval &block if defined? yield
139     obj
140   end
141
142   def init_instance_variable
143     @tags = {}
144   end
145
146   def create_self
147     tk_call 'text', @path
148     init_instance_variable
149   end
150
151   def index(index)
152     tk_send 'index', index
153   end
154
155   def value
156     tk_send 'get', "1.0", "end - 1 char"
157   end
158
159   def value= (val)
160     tk_send 'delete', "1.0", 'end'
161     tk_send 'insert', "1.0", val
162   end
163
164   def _addcmd(cmd)
165     @cmdtbl.push cmd
166   end
167
168   def _addtag(name, obj)
169     @tags[name] = obj
170   end
171
172   def tagid2obj(tagid)
173     if not @tags[tagid]
174       tagid
175     else
176       @tags[tagid]
177     end
178   end
179
180   def tag_names(index=None)
181     tk_split_list(tk_send('tag', 'names', index)).collect{|elt|
182       tagid2obj(elt)
183     }
184   end
185
186   def mark_names
187     tk_split_list(tk_send('mark', 'names')).collect{|elt|
188       tagid2obj(elt)
189     }
190   end
191
192   def mark_next(index)
193     tagid2obj(tk_send('mark', 'next', index))
194   end
195
196   def mark_previous(index)
197     tagid2obj(tk_send('mark', 'previous', index))
198   end
199
200   def window_names
201     tk_send('window', 'names').collect{|elt|
202       tagid2obj(elt)
203     }
204   end
205
206   def image_names
207     tk_send('image', 'names').collect{|elt|
208       tagid2obj(elt)
209     }
210   end
211
212   def set_insert(index)
213     tk_send 'mark', 'set', 'insert', index
214   end
215
216   def set_current(index)
217     tk_send 'mark', 'set', 'current', index
218   end
219
220   def insert(index, chars, *tags)
221     super index, chars, tags.collect{|x|_get_eval_string(x)}.join(' ')
222   end
223
224   def destroy
225     @tags = {} unless @tags
226     @tags.each_value do |t|
227       t.destroy
228     end
229     super
230   end
231
232   def backspace
233     self.delete 'insert'
234   end
235
236   def compare(idx1, op, idx2)
237     bool(tk_send('compare', idx1, op, idx2))
238   end
239
240   def debug
241     bool(tk_send('debug'))
242   end
243   def debug=(boolean)
244     tk_send 'debug', boolean
245   end
246
247   def bbox(index)
248     inf = tk_send('bbox', index)
249     (inf == "")?  [0,0,0,0]: inf
250   end
251   def dlineinfo(index)
252     inf = tk_send('dlineinfo', index)
253     (inf == "")?  [0,0,0,0,0]: inf
254   end
255
256   def yview_pickplace(*what)
257     tk_send 'yview', '-pickplace', *what
258   end
259
260   def xview_pickplace(*what)
261     tk_send 'xview', '-pickplace', *what
262   end
263
264   def tag_add(tag, index1, index2=None)
265     tk_send 'tag', 'add', tag, index1, index2
266   end
267
268   def tag_bind(tag, seq, cmd=Proc.new, args=nil)
269     _bind(['tag', 'bind', tag], seq, cmd, args)
270   end
271
272   def tag_bind_append(tag, seq, cmd=Proc.new, args=nil)
273     _bind_append(['tag', 'bind', tag], seq, cmd, args)
274   end
275
276   def tag_bindinfo(tag, context=nil)
277     _bindinfo(['tag', 'bind', tag], context)
278   end
279
280   def tag_cget(tag, key)
281     case key
282     when 'text', 'label', 'show', 'data', 'flie'
283       tk_call @path, 'tag', 'cget', tag, "-#{key}"
284     else
285       tk_tcl2ruby tk_call @path, 'tag', 'cget', tag, "-#{key}"
286     end
287   end
288
289   def tag_configure(tag, key, val=None)
290     if key.kind_of? Hash
291       if ( key['font'] || key['kanjifont'] \
292           || key['latinfont'] || key['asciifont'] )
293         tagfont_configure(tag, key.dup)
294       else
295         tk_send 'tag', 'configure', tag, *hash_kv(key)
296       end
297
298     else
299       if  key == 'font' || key == 'kanjifont' ||
300           key == 'latinfont' || key == 'asciifont'
301         tagfont_configure({key=>val})
302       else
303         tk_send 'tag', 'configure', tag, "-#{key}", val
304       end
305     end
306   end
307
308   def tag_configinfo(tag, key=nil)
309     if key
310       case key
311       when 'text', 'label', 'show', 'data', 'flie'
312         conf = tk_split_simplelist(tk_send('tag','configure',tag,"-#{key}"))
313       else
314         conf = tk_split_list(tk_send('tag','configure',tag,"-#{key}"))
315       end
316       conf[0] = conf[0][1..-1]
317       conf
318     else
319       tk_split_simplelist(tk_send('tag', 'configure', tag)).collect{|conflist|
320         conf = tk_split_simplelist(conflist)
321         conf[0] = conf[0][1..-1]
322         case conf[0]
323         when 'text', 'label', 'show', 'data', 'flie'
324         else
325           if conf[3]
326             if conf[3].index('{')
327               conf[3] = tk_split_list(conf[3]) 
328             else
329               conf[3] = tk_tcl2ruby(conf[3]) 
330             end
331           end
332           if conf[4]
333             if conf[4].index('{')
334               conf[4] = tk_split_list(conf[4]) 
335             else
336               conf[4] = tk_tcl2ruby(conf[4]) 
337             end
338           end
339         end
340         conf
341       }
342     end
343   end
344
345   def tag_raise(tag, above=None)
346     tk_send 'tag', 'raise', tag, above
347   end
348
349   def tag_lower(tag, below=None)
350     tk_send 'tag', 'lower', tag, below
351   end
352
353   def tag_remove(tag, *index)
354     tk_send 'tag', 'remove', tag, *index
355   end
356
357   def tag_ranges(tag)
358     l = tk_split_simplelist(tk_send('tag', 'ranges', tag))
359     r = []
360     while key=l.shift
361       r.push [key, l.shift]
362     end
363     r
364   end
365
366   def tag_nextrange(tag, first, last=None)
367     tk_split_simplelist(tk_send('tag', 'nextrange', tag, first, last))
368   end
369
370   def tag_prevrange(tag, first, last=None)
371     tk_split_simplelist(tk_send('tag', 'prevrange', tag, first, last))
372   end
373
374   def _ktext_length(txt)
375     if $KCODE !~ /n/i
376       return txt.gsub(/[^\Wa-zA-Z_\d]/, ' ').length
377     end
378
379     # $KCODE == 'NONE'
380     if JAPANIZED_TK
381       tk_call('kstring', 'length', txt).to_i
382     else
383       begin
384         tk_call('encoding', 'convertto', 'ascii', txt).length
385       rescue StandardError, NameError
386         # sorry, I have no plan
387         txt.length
388       end
389     end
390   end
391   private :_ktext_length
392
393   def search_with_length(pat,start,stop=None)
394     pat = pat.chr if pat.kind_of? Integer
395     if stop != None
396       return ["", 0] if compare(start,'>=',stop)
397       txt = get(start,stop)
398       if (pos = txt.index(pat))
399         match = $&
400         #pos = txt[0..(pos-1)].split('').length if pos > 0
401         pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
402         if pat.kind_of? String
403           #return [index(start + " + #{pos} chars"), pat.split('').length]
404           return [index(start + " + #{pos} chars"), 
405                   _ktext_length(pat), pat.dup]
406         else
407           #return [index(start + " + #{pos} chars"), $&.split('').length]
408           return [index(start + " + #{pos} chars"), 
409                   _ktext_length(match), match]
410         end
411       else
412         return ["", 0]
413       end
414     else
415       txt = get(start,'end - 1 char')
416       if (pos = txt.index(pat))
417         match = $&
418         #pos = txt[0..(pos-1)].split('').length if pos > 0
419         pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
420         if pat.kind_of? String
421           #return [index(start + " + #{pos} chars"), pat.split('').length]
422           return [index(start + " + #{pos} chars"), 
423                   _ktext_length(pat), pat.dup]
424         else
425           #return [index(start + " + #{pos} chars"), $&.split('').length]
426           return [index(start + " + #{pos} chars"), 
427                   _ktext_length(match), match]
428         end
429       else
430         txt = get('1.0','end - 1 char')
431         if (pos = txt.index(pat))
432           match = $&
433           #pos = txt[0..(pos-1)].split('').length if pos > 0
434           pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
435           if pat.kind_of? String
436             #return [index("1.0 + #{pos} chars"), pat.split('').length]
437             return [index("1.0 + #{pos} chars"), 
438                     _ktext_length(pat), pat.dup]
439           else
440             #return [index("1.0 + #{pos} chars"), $&.split('').length]
441             return [index("1.0 + #{pos} chars"), _ktext_length(match), match]
442           end
443         else
444           return ["", 0]
445         end
446       end
447     end
448   end
449
450   def search(pat,start,stop=None)
451     search_with_length(pat,start,stop)[0]
452   end
453
454   def rsearch_with_length(pat,start,stop=None)
455     pat = pat.chr if pat.kind_of? Integer
456     if stop != None
457       return ["", 0] if compare(start,'<=',stop)
458       txt = get(stop,start)
459       if (pos = txt.rindex(pat))
460         match = $&
461         #pos = txt[0..(pos-1)].split('').length if pos > 0
462         pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
463         if pat.kind_of? String
464           #return [index(stop + " + #{pos} chars"), pat.split('').length]
465           return [index(stop + " + #{pos} chars"), _ktext_length(pat), pat.dup]
466         else
467           #return [index(stop + " + #{pos} chars"), $&.split('').length]
468           return [index(stop + " + #{pos} chars"), _ktext_length(match), match]
469         end
470       else
471         return ["", 0]
472       end
473     else
474       txt = get('1.0',start)
475       if (pos = txt.rindex(pat))
476         match = $&
477         #pos = txt[0..(pos-1)].split('').length if pos > 0
478         pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
479         if pat.kind_of? String
480           #return [index("1.0 + #{pos} chars"), pat.split('').length]
481           return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup]
482         else
483           #return [index("1.0 + #{pos} chars"), $&.split('').length]
484           return [index("1.0 + #{pos} chars"), _ktext_length(match), match]
485         end
486       else
487         txt = get('1.0','end - 1 char')
488         if (pos = txt.rindex(pat))
489           match = $&
490           #pos = txt[0..(pos-1)].split('').length if pos > 0
491           pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
492           if pat.kind_of? String
493             #return [index("1.0 + #{pos} chars"), pat.split('').length]
494             return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup]
495           else
496             #return [index("1.0 + #{pos} chars"), $&.split('').length]
497             return [index("1.0 + #{pos} chars"), _ktext_length(match), match]
498           end
499         else
500           return ["", 0]
501         end
502       end
503     end
504   end
505
506   def rsearch(pat,start,stop=None)
507     rsearch_with_length(pat,start,stop)[0]
508   end
509
510   def dump(type_info, *index, &block)
511     args = type_info.collect{|inf| '-' + inf}
512     args << '-command' << Proc.new(&block) if iterator?
513     str = tk_send('dump', *(args + index))
514     result = []
515     sel = nil
516     i = 0
517     while i < str.size
518       # retrieve key
519       idx = str.index(/ /, i)
520       result.push str[i..(idx-1)]
521       i = idx + 1
522       
523       # retrieve value
524       case result[-1]
525       when 'text'
526         if str[i] == ?{
527           # text formed as {...}
528           val, i = _retrieve_braced_text(str, i)
529           result.push val
530         else
531           # text which may contain backslahes
532           val, i = _retrieve_backslashed_text(str, i)
533           result.push val
534         end
535       else
536         idx = str.index(/ /, i)
537         val = str[i..(idx-1)]
538         case result[-1]
539         when 'mark'
540           case val
541           when 'insert'
542             result.push TkTextMarkInsert.new(self)
543           when 'current'
544             result.push TkTextMarkCurrent.new(self)
545           when 'anchor'
546             result.push TkTextMarkAnchor.new(self)
547           else
548             result.push tk_tcl2ruby(val)
549           end
550         when 'tagon'
551           if val == 'sel'
552             if sel
553               result.push sel
554             else
555               result.push TkTextTagSel.new(self)
556             end
557           else
558             result.push tk_tcl2ruby(val)
559           end
560         when 'tagoff'
561             result.push tk_tcl2ruby(sel)
562         when 'window'
563           result.push tk_tcl2ruby(val)
564         end
565         i = idx + 1
566       end
567
568       # retrieve index
569       idx = str.index(/ /, i)
570       if idx
571         result.push str[i..(idx-1)]
572         i = idx + 1
573       else
574         result.push str[i..-1]
575         break
576       end
577     end
578     
579     kvis = []
580     until result.empty?
581       kvis.push [result.shift, result.shift, result.shift]
582     end
583     kvis  # result is [[key1, value1, index1], [key2, value2, index2], ...]
584   end
585
586   def _retrieve_braced_text(str, i)
587     cnt = 0
588     idx = i
589     while idx < str.size
590       case str[idx]
591       when ?{
592         cnt += 1
593       when ?}
594         cnt -= 1
595         if cnt == 0
596           break
597         end
598       end
599       idx += 1
600     end
601     return str[i+1..idx-1], idx + 2
602   end
603   private :_retrieve_braced_text
604
605   def _retrieve_backslashed_text(str, i)
606     j = i
607     idx = nil
608     loop {
609       idx = str.index(/ /, j)
610       if str[idx-1] == ?\\
611         j += 1
612       else
613         break
614       end
615     }
616     val = str[i..(idx-1)]
617     val.gsub!(/\\( |\{|\})/, '\1')
618     return val, idx + 1
619   end
620   private :_retrieve_backslashed_text
621
622   def dump_all(*index, &block)
623     dump(['all'], *index, &block)
624   end
625   def dump_mark(*index, &block)
626     dump(['mark'], *index, &block)
627   end
628   def dump_tag(*index, &block)
629     dump(['tag'], *index, &block)
630   end
631   def dump_text(*index, &block)
632     dump(['text'], *index, &block)
633   end
634   def dump_window(*index, &block)
635     dump(['window'], *index, &block)
636   end
637   def dump_image(*index, &block)
638     dump(['image'], *index, &block)
639   end
640 end
641
642 class TkTextTag<TkObject
643   include TkTreatTagFont
644
645   Tk_TextTag_ID = ['tag0000']
646
647   def initialize(parent, *args)
648     if not parent.kind_of?(TkText)
649       fail format("%s need to be TkText", parent.inspect)
650     end
651     @parent = @t = parent
652     @path = @id = Tk_TextTag_ID[0]
653     Tk_TextTag_ID[0] = Tk_TextTag_ID[0].succ
654     #tk_call @t.path, "tag", "configure", @id, *hash_kv(keys)
655     if args != [] then
656       keys = args.pop
657       if keys.kind_of? Hash then
658         add(*args) if args != []
659         configure(keys)
660       else
661         args.push keys
662         add(*args)
663       end
664     end
665     @t._addtag id, self
666   end
667
668   def id
669     return @id
670   end
671
672   def first
673     @id + '.first'
674   end
675
676   def last
677     @id + '.last'
678   end
679
680   def add(*index)
681     tk_call @t.path, 'tag', 'add', @id, *index
682   end
683
684   def remove(*index)
685     tk_call @t.path, 'tag', 'remove', @id, *index
686   end
687
688   def ranges
689     l = tk_split_simplelist(tk_call(@t.path, 'tag', 'ranges', @id))
690     r = []
691     while key=l.shift
692       r.push [key, l.shift]
693     end
694     r
695   end
696
697   def nextrange(first, last=None)
698     tk_split_simplelist(tk_call(@t.path, 'tag', 'nextrange', @id, first, last))
699   end
700
701   def prevrange(first, last=None)
702     tk_split_simplelist(tk_call(@t.path, 'tag', 'prevrange', @id, first, last))
703   end
704
705   def [](key)
706     cget key
707   end
708
709   def []=(key,val)
710     configure key, val
711   end
712
713   def cget(key)
714     case key
715     when 'text', 'label', 'show', 'data', 'flie'
716       tk_call @t.path, 'tag', 'cget', @id, "-#{key}"
717     else
718       tk_tcl2ruby tk_call @t.path, 'tag', 'cget', @id, "-#{key}"
719     end
720   end
721
722   def configure(key, val=None)
723     @t.tag_configure @id, key, val
724   end
725 #  def configure(key, val=None)
726 #    if key.kind_of? Hash
727 #      tk_call @t.path, 'tag', 'configure', @id, *hash_kv(key)
728 #    else
729 #      tk_call @t.path, 'tag', 'configure', @id, "-#{key}", val
730 #    end
731 #  end
732 #  def configure(key, value)
733 #    if value == FALSE
734 #      value = "0"
735 #    elsif value.kind_of? Proc
736 #      value = install_cmd(value)
737 #    end
738 #    tk_call @t.path, 'tag', 'configure', @id, "-#{key}", value
739 #  end
740
741   def configinfo(key=nil)
742     @t.tag_configinfo @id, key
743   end
744
745   def bind(seq, cmd=Proc.new, args=nil)
746     _bind([@t.path, 'tag', 'bind', @id], seq, cmd, args)
747   end
748
749   def bind_append(seq, cmd=Proc.new, args=nil)
750     _bind_append([@t.path, 'tag', 'bind', @id], seq, cmd, args)
751   end
752
753   def bindinfo(context=nil)
754     _bindinfo([@t.path, 'tag', 'bind', @id], context)
755   end
756
757   def raise(above=None)
758     tk_call @t.path, 'tag', 'raise', @id, above
759   end
760
761   def lower(below=None)
762     tk_call @t.path, 'tag', 'lower', @id, below
763   end
764
765   def destroy
766     tk_call @t.path, 'tag', 'delete', @id
767   end
768 end
769
770 class TkTextTagSel<TkTextTag
771   def initialize(parent, keys=nil)
772     if not parent.kind_of?(TkText)
773       fail format("%s need to be TkText", parent.inspect)
774     end
775     @t = parent
776     @path = @id = 'sel'
777     #tk_call @t.path, "tag", "configure", @id, *hash_kv(keys)
778     configure(keys) if keys
779     @t._addtag id, self
780   end
781 end
782
783 class TkTextMark<TkObject
784   Tk_TextMark_ID = ['mark0000']
785   def initialize(parent, index)
786     if not parent.kind_of?(TkText)
787       fail format("%s need to be TkText", parent.inspect)
788     end
789     @t = parent
790     @path = @id = Tk_TextMark_ID[0]
791     Tk_TextMark_ID[0] = Tk_TextMark_ID[0].succ
792     tk_call @t.path, 'mark', 'set', @id, index
793     @t._addtag id, self
794   end
795   def id
796     return @id
797   end
798
799   def set(where)
800     tk_call @t.path, 'mark', 'set', @id, where
801   end
802
803   def unset
804     tk_call @t.path, 'mark', 'unset', @id
805   end
806   alias destroy unset
807
808   def gravity
809     tk_call @t.path, 'mark', 'gravity', @id
810   end
811
812   def gravity=(direction)
813     tk_call @t.path, 'mark', 'gravity', @id, direction
814   end
815
816   def next(index)
817     @t.tagid2obj(tk_call(@t.path, 'mark', 'next', index))
818   end
819
820   def previous(index)
821     @t.tagid2obj(tk_call(@t.path, 'mark', 'previous', index))
822   end
823 end
824
825 class TkTextMarkInsert<TkTextMark
826   def initialize(parent, index=nil)
827     if not parent.kind_of?(TkText)
828       fail format("%s need to be TkText", parent.inspect)
829     end
830     @t = parent
831     @path = @id = 'insert'
832     tk_call @t.path, 'mark', 'set', @id, index if index
833     @t._addtag id, self
834   end
835 end
836
837 class TkTextMarkCurrent<TkTextMark
838   def initialize(parent,index=nil)
839     if not parent.kind_of?(TkText)
840       fail format("%s need to be TkText", parent.inspect)
841     end
842     @t = parent
843     @path = @id = 'current'
844     tk_call @t.path, 'mark', 'set', @id, index if index
845     @t._addtag id, self
846   end
847 end
848
849 class TkTextMarkAnchor<TkTextMark
850   def initialize(parent,index=nil)
851     if not parent.kind_of?(TkText)
852       fail format("%s need to be TkText", parent.inspect)
853     end
854     @t = parent
855     @path = @id = 'anchor'
856     tk_call @t.path, 'mark', 'set', @id, index if index
857     @t._addtag id, self
858   end
859 end
860
861 class TkTextWindow<TkObject
862   def initialize(parent, index, keys)
863     if not parent.kind_of?(TkText)
864       fail format("%s need to be TkText", parent.inspect)
865     end
866     @t = parent
867     if index == 'end'
868       @path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
869     elsif index.kind_of? TkTextMark
870       if tk_call(@t.path,'index',index.path) == tk_call(@t.path,'index','end')
871         @path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
872       else
873         @path = TkTextMark.new(@t, tk_call(@t.path, 'index', index.path))
874       end
875     else
876       @path = TkTextMark.new(@t, tk_call(@t.path, 'index', index))
877     end
878     @path.gravity = 'left'
879     @index = @path.path
880     @id = keys['window']
881     if keys['create']
882       @p_create = keys['create']
883       if @p_create.kind_of? Proc
884         keys['create'] = install_cmd(proc{@id = @p_create.call; @id.path})
885       end
886     end
887     tk_call @t.path, 'window', 'create', @index, *hash_kv(keys)
888   end
889
890   def [](slot)
891     cget(slot)
892   end
893   def []=(slot, value)
894     configure(slot, value)
895   end
896
897   def cget(slot)
898     case slot
899     when 'text', 'label', 'show', 'data', 'flie'
900       tk_call @t.path, 'window', 'cget', @index, "-#{slot}"
901     else
902       tk_tcl2ruby tk_call @t.path, 'window', 'cget', @index, "-#{slot}"
903     end
904   end
905
906   def configure(slot, value=None)
907     if slot.kind_of? Hash
908       @id = slot['window'] if slot['window']
909       if slot['create']
910         self.create=value
911         slot['create']=nil
912       end
913       if slot.size > 0
914         tk_call @t.path, 'window', 'configure', @index, *hash_kv(slot)
915       end
916     else
917       @id = value if slot == 'window'
918       if slot == 'create'
919         self.create=value
920       else
921         tk_call @t.path, 'window', 'configure', @index, "-#{slot}", value
922       end
923     end
924   end
925
926   def window
927     @id
928   end
929
930   def window=(value)
931     tk_call @t.path, 'window', 'configure', @index, '-window', value
932     @id = value
933   end
934
935   def create
936     @p_create
937   end
938
939   def create=(value)
940     @p_create = value
941     if @p_create.kind_of? Proc
942       value = install_cmd(proc{@id = @p_create.call})
943     end
944     tk_call @t.path, 'window', 'configure', @index, '-create', value
945   end
946
947   def configinfo(slot = nil)
948     if slot
949       case slot
950       when 'text', 'label', 'show', 'data', 'flie'
951         conf = tk_split_simplelist(tk_call @t.path, 'window', 'configure', 
952                                    @index, "-#{slot}")
953       else
954         conf = tk_split_list(tk_call @t.path, 'window', 'configure', 
955                              @index, "-#{slot}")
956       end
957       conf[0] = conf[0][1..-1]
958       conf
959     else
960       tk_split_simplelist(tk_call @t.path, 'window', 'configure', 
961                           @index).collect{|conflist|
962         conf = tk_split_simplelist(conflist)
963         conf[0] = conf[0][1..-1]
964         case conf[0]
965         when 'text', 'label', 'show', 'data', 'flie'
966         else
967           if conf[3]
968             if conf[3].index('{')
969               conf[3] = tk_split_list(conf[3]) 
970             else
971               conf[3] = tk_tcl2ruby(conf[3]) 
972             end
973           end
974           if conf[4]
975             if conf[4].index('{')
976               conf[4] = tk_split_list(conf[4]) 
977             else
978               conf[4] = tk_tcl2ruby(conf[4]) 
979             end
980           end
981         end
982         conf
983       }
984     end
985   end
986
987 end
988
989 class TkTextImage<TkObject
990   def initialize(parent, index, keys)
991     if not parent.kind_of?(TkText)
992       fail format("%s need to be TkText", parent.inspect)
993     end
994     @t = parent
995     if index == 'end'
996       @path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
997     elsif index.kind_of? TkTextMark
998       if tk_call(@t.path,'index',index.path) == tk_call(@t.path,'index','end')
999         @path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
1000       else
1001         @path = TkTextMark.new(@t, tk_call(@t.path, 'index', index.path))
1002       end
1003     else
1004       @path = TkTextMark.new(@t, tk_call(@t.path, 'index', index))
1005     end
1006     @path.gravity = 'left'
1007     @index = @path.path
1008     @id = tk_call(@t.path, 'image', 'create', @index, *hash_kv(keys))
1009   end
1010
1011   def [](slot)
1012     cget(slot)
1013   end
1014   def []=(slot, value)
1015     configure(slot, value)
1016   end
1017
1018   def cget(slot)
1019     case slot
1020     when 'text', 'label', 'show', 'data', 'flie'
1021       tk_call @t.path, 'image', 'cget', @index, "-#{slot}"
1022     else
1023       tk_tcl2ruby tk_call @t.path, 'image', 'cget', @index, "-#{slot}"
1024     end
1025   end
1026
1027   def configure(slot, value=None)
1028     if slot.kind_of? Hash
1029       tk_call @t.path, 'image', 'configure', @index, *hash_kv(slot)
1030     else
1031       tk_call @t.path, 'image', 'configure', @index, "-#{slot}", value
1032     end
1033   end
1034 #  def configure(slot, value)
1035 #    tk_call @t.path, 'image', 'configure', @index, "-#{slot}", value
1036 #  end
1037
1038   def image
1039     tk_call @t.path, 'image', 'configure', @index, '-image'
1040   end
1041
1042   def image=(value)
1043     tk_call @t.path, 'image', 'configure', @index, '-image', value
1044   end
1045
1046   def configinfo(slot = nil)
1047     if slot
1048       case slot
1049       when 'text', 'label', 'show', 'data', 'flie'
1050         conf = tk_split_simplelist(tk_call @t.path, 'image', 'configure', 
1051                                    @index, "-#{slot}")
1052       else
1053         conf = tk_split_list(tk_call @t.path, 'image', 'configure', 
1054                              @index, "-#{slot}")
1055       end
1056       conf[0] = conf[0][1..-1]
1057       conf
1058     else
1059       tk_split_simplelist(tk_call @t.path, 'image', 'configure', 
1060                           @index).collect{|conflist|
1061         conf = tk_split_simplelist(conflist)
1062         conf[0] = conf[0][1..-1]
1063         case conf[0]
1064         when 'text', 'label', 'show', 'data', 'flie'
1065         else
1066           if conf[3]
1067             if conf[3].index('{')
1068               conf[3] = tk_split_list(conf[3]) 
1069             else
1070               conf[3] = tk_tcl2ruby(conf[3]) 
1071             end
1072           end
1073           if conf[4]
1074             if conf[4].index('{')
1075               conf[4] = tk_split_list(conf[4]) 
1076             else
1077               conf[4] = tk_tcl2ruby(conf[4]) 
1078             end
1079           end
1080         end
1081         conf
1082       }
1083     end
1084   end
1085 end