# # tktext.rb - Tk text classes # $Date$ # by Yukihiro Matsumoto require 'tk.rb' require 'tkfont' module TkTreatTextTagFont def tagfont_configinfo(tag) if tag.kind_of? TkTextTag pathname = self.path + ';' + tag.id else pathname = self.path + ';' + tag end ret = TkFont.used_on(pathname) if ret == nil ret = TkFont.init_widget_font(pathname, self.path, 'tag', 'configure', tag) end ret end alias tagfontobj tagfont_configinfo def tagfont_configure(tag, slot) if tag.kind_of? TkTextTag pathname = self.path + ';' + tag.id else pathname = self.path + ';' + tag end if (fnt = slot.delete('font')) if fnt.kind_of? TkFont return fnt.call_font_configure(pathname, self.path,'tag','configure',tag,slot) else latintagfont_configure(tag, fnt) if fnt end end if (ltn = slot.delete('latinfont')) latintagfont_configure(tag, ltn) if ltn end if (ltn = slot.delete('asciifont')) latintagfont_configure(tag, ltn) if ltn end if (knj = slot.delete('kanjifont')) kanjitagfont_configure(tag, knj) if knj end tk_call(self.path, 'tag', 'configure', tag, *hash_kv(slot)) if slot != {} self end def latintagfont_configure(tag, ltn, keys=nil) fobj = tagfontobj(tag) if ltn.kind_of? TkFont conf = {} ltn.latin_configinfo.each{|key,val| conf[key] = val if val != []} if conf == {} fobj.latin_replace(ltn) fobj.latin_configure(keys) if keys elsif keys fobj.latin_configure(conf.update(keys)) else fobj.latin_configure(conf) end else fobj.latin_replace(ltn) end end alias asciitagfont_configure latintagfont_configure def kanjitagfont_configure(tag, knj, keys=nil) fobj = tagfontobj(tag) if knj.kind_of? TkFont conf = {} knj.kanji_configinfo.each{|key,val| conf[key] = val if val != []} if conf == {} fobj.kanji_replace(knj) fobj.kanji_configure(keys) if keys elsif keys fobj.kanji_configure(conf.update(keys)) else fobj.kanji_configure(conf) end else fobj.kanji_replace(knj) end end def tagfont_copy(tag, window, wintag=nil) if wintag window.tagfontobj(wintag).configinfo.each{|key,value| tagfontobj(tag).configure(key,value) } tagfontobj(tag).replace(window.tagfontobj(wintag).latin_font, window.tagfontobj(wintag).kanji_font) else window.tagfont(wintag).configinfo.each{|key,value| tagfontobj(tag).configure(key,value) } tagfontobj(tag).replace(window.fontobj.latin_font, window.fontobj.kanji_font) end end def latintagfont_copy(tag, window, wintag=nil) if wintag tagfontobj(tag).latin_replace(window.tagfontobj(wintag).latin_font) else tagfontobj(tag).latin_replace(window.fontobj.latin_font) end end alias asciitagfont_copy latintagfont_copy def kanjitagfont_copy(tag, window, wintag=nil) if wintag tagfontobj(tag).kanji_replace(window.tagfontobj(wintag).kanji_font) else tagfontobj(tag).kanji_replace(window.fontobj.kanji_font) end end end class TkTextval}) else tk_send 'tag', 'configure', tag, "-#{key}", val end end end def tag_configinfo(tag, key=nil) if key conf = tk_split_list(tk_send('tag','configure',tag,"-#{key}")) conf[0] = conf[0][1..-1] conf else tk_split_list(tk_send('tag', 'configure', tag)).collect{|conf| conf[0] = conf[0][1..-1] conf } end end def tag_raise(tag, above=None) tk_send 'tag', 'raise', tag, above end def tag_lower(tag, below=None) tk_send 'tag', 'lower', tag, below end def tag_remove(tag, *index) tk_send 'tag', 'remove', tag, *index end def tag_ranges(tag) l = tk_split_simplelist(tk_send('tag', 'ranges', tag)) r = [] while key=l.shift r.push [key, l.shift] end r end def tag_nextrange(tag, first, last=None) tk_split_simplelist(tk_send('tag', 'nextrange', tag, first, last)) end def tag_prevrange(tag, first, last=None) tk_split_simplelist(tk_send('tag', 'prevrange', tag, first, last)) end def search_with_length(pat,start,stop=None) pat = pat.char if pat.kind_of? Integer if stop != None return ["", 0] if compare(start,'>=',stop) txt = get(start,stop) if (pos = txt.index(pat)) pos = txt[0..(pos-1)].split('').length if pos > 0 if pat.kind_of? String return [index(start + " + #{pos} chars"), pat.split('').length] else return [index(start + " + #{pos} chars"), $&.split('').length] end else return ["", 0] end else txt = get(start,'end - 1 char') if (pos = txt.index(pat)) pos = txt[0..(pos-1)].split('').length if pos > 0 if pat.kind_of? String return [index(start + " + #{pos} chars"), pat.split('').length] else return [index(start + " + #{pos} chars"), $&.split('').length] end else txt = get('1.0','end - 1 char') if (pos = txt.index(pat)) pos = txt[0..(pos-1)].split('').length if pos > 0 if pat.kind_of? String return [index("1.0 + #{pos} chars"), pat.split('').length] else return [index("1.0 + #{pos} chars"), $&.split('').length] end else return ["", 0] end end end end def search(pat,start,stop=None) search_with_length(pat,start,stop)[0] end def rsearch_with_length(pat,start,stop=None) pat = pat.char if pat.kind_of? Integer if stop != None return ["", 0] if compare(start,'<=',stop) txt = get(stop,start) if (pos = txt.rindex(pat)) pos = txt[0..(pos-1)].split('').length if pos > 0 if pat.kind_of? String return [index(stop + " + #{pos} chars"), pat.split('').length] else return [index(stop + " + #{pos} chars"), $&.split('').length] end else return ["", 0] end else txt = get('1.0',start) if (pos = txt.rindex(pat)) pos = txt[0..(pos-1)].split('').length if pos > 0 if pat.kind_of? String return [index("1.0 + #{pos} chars"), pat.split('').length] else return [index("1.0 + #{pos} chars"), $&.split('').length] end else txt = get('1.0','end - 1 char') if (pos = txt.rindex(pat)) pos = txt[0..(pos-1)].split('').length if pos > 0 if pat.kind_of? String return [index("1.0 + #{pos} chars"), pat.split('').length] else return [index("1.0 + #{pos} chars"), $&.split('').length] end else return ["", 0] end end end end def rsearch(pat,start,stop=None) rsearch_with_length(pat,start,stop)[0] end end class TkTextTag 0 tk_call @t.path, 'window', 'configure', @index, *hash_kv(slot) end else @id = value if slot == 'window' if slot == 'create' self.create=value else tk_call @t.path, 'window', 'configure', @index, "-#{slot}", value end end end def window @id end def window=(value) tk_call @t.path, 'window', 'configure', @index, '-window', value @id = value end def create @p_create end def create=(value) @p_create = value if @p_create.kind_of? Proc value = install_cmd(proc{@id = @p_create.call}) end tk_call @t.path, 'window', 'configure', @index, '-create', value end def configinfo(slot = nil) if slot conf = tk_split_list(tk_call @t.path, 'window', 'configure', @index, "-#{slot}") conf[0] = conf[0][1..-1] conf else tk_split_list(tk_call @t.path, 'window', 'configure', @index).collect{|conf| conf[0] = conf[0][1..-1] conf } end end def _dump(type, *index) str = tk_send('dump', type, *index) result = [] sel = nil i = 0 while i < str.size # retrieve key idx = str.index(/ /, i) result.push str[i..(idx-1)] i = idx + 1 # retrieve value case result[-1] when 'text' if str[i] == ?{ # text formed as {...} val, i = _retrieve_braced_text(str, i) result.push val else # text which may contain backslahes val, i = _retrieve_backslashed_text(str, i) result.push val end else idx = str.index(/ /, i) val = str[i..(idx-1)] case result[-1] when 'mark' case val when 'insert' result.push TkTextMarkInsert.new(self) when 'current' result.push TkTextMarkCurrent.new(self) when 'anchor' result.push TkTextMarkAnchor.new(self) else result.push tk_tcl2rb(val) end when 'tagon' if val == 'sel' if sel result.push sel else result.push TkTextTagSel.new(self) end else result.push tk_tcl2rb val end when 'tagoff' result.push tk_tcl2rb sel when 'window' result.push tk_tcl2rb val end i = idx + 1 end # retrieve index idx = str.index(/ /, i) if idx result.push str[i..(idx-1)] i = idx + 1 else result.push str[i..-1] break end end kvis = [] until result.empty? kvis.push [result.shift, result.shift, result.shift] end kvis # result is [[key1, value1, index1], [key2, value2, index2], ...] end private :_dump def _retrieve_braced_text(str, i) cnt = 0 idx = i while idx < str.size case str[idx] when ?{ cnt += 1 when ?} cnt -= 1 if cnt == 0 break end end idx += 1 end return str[i+1..idx-1], idx + 2 end private :_retrieve_braced_text def _retrieve_backslashed_text(str, i) j = i idx = nil loop { idx = str.index(/ /, j) if str[idx-1] == ?\\ j += 1 else break end } val = str[i..(idx-1)] val.gsub!(/\\( |\{|\})/, '\1') return val, idx + 1 end private :_retrieve_backslashed_text def dump_all(*index) _dump('-all', *index) end def dump_mark(*index) _dump('-mark', *index) end def dump_tag(*index) _dump('-tag', *index) end def dump_text(*index) _dump('-text', *index) end def dump_window(*index) _dump('-window', *index) end end class TkTextImage