diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-07-07 07:36:34 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-07-07 07:36:34 +0000 |
commit | 441546edcfbb1b346c87b69c5f578d1a0e522e06 (patch) | |
tree | 04f606a008baebc445f38944ad37e87468da29ea /ruby_1_8_6/ext/tk/lib/tk/text.rb | |
parent | fa93611c0f9a6db146341c792bfe3b7322ec00e2 (diff) |
add tag v1_8_6_269
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_8_6_269@17937 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ruby_1_8_6/ext/tk/lib/tk/text.rb')
-rw-r--r-- | ruby_1_8_6/ext/tk/lib/tk/text.rb | 1550 |
1 files changed, 1550 insertions, 0 deletions
diff --git a/ruby_1_8_6/ext/tk/lib/tk/text.rb b/ruby_1_8_6/ext/tk/lib/tk/text.rb new file mode 100644 index 0000000000..49d4b5625b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/text.rb @@ -0,0 +1,1550 @@ +# +# tk/text.rb - Tk text classes +# $Date$ +# by Yukihiro Matsumoto <matz@caelum.co.jp> +require 'tk' +require 'tk/itemfont' +require 'tk/itemconfig' +require 'tk/scrollable' +require 'tk/txtwin_abst' + +module TkTextTagConfig + include TkTreatItemFont + include TkItemConfigMethod + + def __item_cget_cmd(id) # id := [ type, tagOrId ] + [self.path, id[0], 'cget', id[1]] + end + private :__item_cget_cmd + + def __item_config_cmd(id) # id := [ type, tagOrId ] + [self.path, id[0], 'configure', id[1]] + end + private :__item_config_cmd + + def __item_pathname(id) + if id.kind_of?(Array) + id = tagid(id[1]) + end + [self.path, id].join(';') + end + private :__item_pathname + + def tag_cget(tagOrId, option) + itemcget(['tag', tagOrId], option) + end + def tag_configure(tagOrId, slot, value=None) + itemconfigure(['tag', tagOrId], slot, value) + end + def tag_configinfo(tagOrId, slot=nil) + itemconfigure(['tag', tagOrId], slot) + end + def current_tag_configinfo(tagOrId, slot=nil) + itemconfigure(['tag', tagOrId], slot) + end + + def window_cget(tagOrId, option) + itemcget(['window', tagOrId], option) + end + def window_configure(tagOrId, slot, value=None) + itemconfigure(['window', tagOrId], slot, value) + end + def window_configinfo(tagOrId, slot=nil) + itemconfigure(['window', tagOrId], slot) + end + def current_window_configinfo(tagOrId, slot=nil) + itemconfigure(['window', tagOrId], slot) + end + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo +end + +class TkText<TkTextWin + ItemConfCMD = ['tag'.freeze, 'configure'.freeze].freeze + #include TkTreatTextTagFont + include TkTextTagConfig + include Scrollable + + ####################################### + + module IndexModMethods + def +(mod) + return chars(mod) if mod.kind_of?(Numeric) + + mod = mod.to_s + if mod =~ /^\s*[+-]?\d/ + TkText::IndexString.new(String.new(id) << ' + ' << mod) + else + TkText::IndexString.new(String.new(id) << ' ' << mod) + end + end + + def -(mod) + return chars(-mod) if mod.kind_of?(Numeric) + + mod = mod.to_s + if mod =~ /^\s*[+-]?\d/ + TkText::IndexString.new(String.new(id) << ' - ' << mod) + elsif mod =~ /^\s*[-]\s+(\d.*)$/ + TkText::IndexString.new(String.new(id) << ' - -' << $1) + else + TkText::IndexString.new(String.new(id) << ' ' << mod) + end + end + + def chars(mod) + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' chars') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' chars') + end + end + alias char chars + + def display_chars(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display chars') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display chars') + end + end + alias display_char display_chars + + def any_chars(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any chars') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any chars') + end + end + alias any_char any_chars + + def indices(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' indices') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' indices') + end + end + + def display_indices(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display indices') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display indices') + end + end + + def any_indices(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any indices') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any indices') + end + end + + def lines(mod) + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' lines') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' lines') + end + end + alias line lines + + def display_lines(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display_lines') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display lines') + end + end + alias display_line display_lines + + def any_lines(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any_lines') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any lines') + end + end + alias any_line any_lines + + def linestart + TkText::IndexString.new(String.new(id) << ' linestart') + end + def lineend + TkText::IndexString.new(String.new(id) << ' lineend') + end + + def display_linestart + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display linestart') + end + def display_lineend + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display lineend') + end + + def wordstart + TkText::IndexString.new(String.new(id) << ' wordstart') + end + def wordend + TkText::IndexString.new(String.new(id) << ' wordend') + end + + def display_wordstart + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display wordstart') + end + def display_wordend + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display wordend') + end + end + + class IndexString < String + include IndexModMethods + + def self.at(x,y) + self.new("@#{x},#{y}") + end + + def self.new(str) + if str.kind_of?(String) + super(str) + elsif str.kind_of?(Symbol) + super(str.to_s) + else + str + end + end + + def id + self + end + end + + ####################################### + + TkCommandNames = ['text'.freeze].freeze + WidgetClassName = 'Text'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.new(*args, &block) + obj = super(*args){} + obj.init_instance_variable + obj.instance_eval(&block) if defined? yield + obj + end + + def init_instance_variable + @cmdtbl = [] + @tags = {} + end + + def __destroy_hook__ + TkTextTag::TTagID_TBL.delete(@path) + TkTextMark::TMarkID_TBL.delete(@path) + end + + def create_self(keys) + #if keys and keys != None + # #tk_call_without_enc('text', @path, *hash_kv(keys, true)) + # tk_call_without_enc(self.class::TkCommandNames[0], @path, + # *hash_kv(keys, true)) + #else + # #tk_call_without_enc('text', @path) + # tk_call_without_enc(self.class::TkCommandNames[0], @path) + #end + super(keys) + init_instance_variable + end + private :create_self + + def __strval_optkeys + super() << 'inactiveseletcionbackground' + end + private :__strval_optkeys + + def self.at(x, y) + TkText::IndexString.at(x, y) + end + + def at(x, y) + TkText::IndexString.at(x, y) + end + + def index(idx) + TkText::IndexString.new(tk_send_without_enc('index', + _get_eval_enc_str(idx))) + end + + def get_displaychars(*index) + # Tk8.5 feature + get('-displaychars', *index) + end + + def value + _fromUTF8(tk_send_without_enc('get', "1.0", "end - 1 char")) + end + + def value= (val) + tk_send_without_enc('delete', "1.0", 'end') + tk_send_without_enc('insert', "1.0", _get_eval_enc_str(val)) + val + end + + def clear + tk_send_without_enc('delete', "1.0", 'end') + self + end + alias erase clear + + def _addcmd(cmd) + @cmdtbl.push cmd + end + + def _addtag(name, obj) + @tags[name] = obj + end + + def tagid(tag) + if tag.kind_of?(TkTextTag) \ + || tag.kind_of?(TkTextMark) \ + || tag.kind_of?(TkTextImage) \ + || tag.kind_of?(TkTextWindow) + tag.id + else + tag # maybe an Array of configure paramters + end + end + private :tagid + + def tagid2obj(tagid) + if @tags[tagid] + @tags[tagid] + else + tagid + end + end + + def tag_names(index=None) + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag', 'names', _get_eval_enc_str(index)))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('tag', 'names', _get_eval_enc_str(index)), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def mark_names + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('mark', 'names'))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('mark', 'names'), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def mark_gravity(mark, direction=nil) + if direction + tk_send_without_enc('mark', 'gravity', + _get_eval_enc_str(mark), direction) + self + else + tk_send_without_enc('mark', 'gravity', _get_eval_enc_str(mark)) + end + end + + def mark_set(mark, index) + tk_send_without_enc('mark', 'set', _get_eval_enc_str(mark), + _get_eval_enc_str(index)) + self + end + alias set_mark mark_set + + def mark_unset(*marks) + tk_send_without_enc('mark', 'unset', + *(marks.collect{|mark| _get_eval_enc_str(mark)})) + self + end + alias unset_mark mark_unset + + def mark_next(index) + tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'next', + _get_eval_enc_str(index)))) + end + alias next_mark mark_next + + def mark_previous(index) + tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'previous', + _get_eval_enc_str(index)))) + end + alias previous_mark mark_previous + + def image_cget(index, slot) + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + _fromUTF8(tk_send_without_enc('image', 'cget', + _get_eval_enc_str(index), "-#{slot}")) + else + tk_tcl2ruby(_fromUTF8(tk_send_without_enc('image', 'cget', + _get_eval_enc_str(index), + "-#{slot}"))) + end + end + + def image_configure(index, slot, value=None) + if slot.kind_of?(Hash) + _fromUTF8(tk_send_without_enc('image', 'configure', + _get_eval_enc_str(index), + *hash_kv(slot, true))) + else + _fromUTF8(tk_send_without_enc('image', 'configure', + _get_eval_enc_str(index), + "-#{slot}", + _get_eval_enc_str(value))) + end + self + end + + def image_configinfo(index, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + #conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), false, true) + else + #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), 0, false, true) + end + conf[0] = conf[0][1..-1] + conf + else + # tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).collect{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).collect{|conflist| + conf = tk_split_simplelist(conflist, false, true) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + #conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), false, true) + else + #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), 0, false, true) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).each{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).each{|conflist| + conf = tk_split_simplelist(conflist, false, true) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + ret + end + end + end + + def current_image_configinfo(index, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + conf = image_configinfo(index, slot) + {conf[0] => conf[4]} + else + ret = {} + image_configinfo(index).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + image_configinfo(index, slot).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end + + def image_names + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'names'))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('image', 'names'), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def set_insert(index) + tk_send_without_enc('mark','set','insert', _get_eval_enc_str(index)) + self + end + + def set_current(index) + tk_send_without_enc('mark','set','current', _get_eval_enc_str(index)) + self + end + + def insert(index, chars, *tags) + if tags[0].kind_of?(Array) + # multiple chars-taglist argument :: str, [tag,...], str, [tag,...], ... + args = [chars] + while tags.size > 0 + args << tags.shift.collect{|x|_get_eval_string(x)}.join(' ') # taglist + args << tags.shift if tags.size > 0 # chars + end + super(index, *args) + else + # single chars-taglist argument :: str, tag, tag, ... + if tags.size == 0 + super(index, chars) + else + super(index, chars, tags.collect{|x|_get_eval_string(x)}.join(' ')) + end + end + end + + def destroy + @tags = {} unless @tags + @tags.each_value do |t| + t.destroy + end + super() + end + + def backspace + self.delete 'insert' + end + + def bbox(index) + list(tk_send_without_enc('bbox', _get_eval_enc_str(index))) + end + + def compare(idx1, op, idx2) + bool(tk_send_without_enc('compare', _get_eval_enc_str(idx1), + op, _get_eval_enc_str(idx2))) + end + + def count(idx1, idx2, *opts) + # opts are Tk8.5 feature + cnt = 0 + args = opts.collect{|opt| + str = opt.to_s + cnt += 1 if str != 'update' + '-' + str + } + args << _get_eval_enc_str(idx1) << _get_eval_enc_str(idx2) + if cnt <= 1 + number(tk_send_without_enc('count', *opts)) + else + list(tk_send_without_enc('count', *opts)) + end + end + + def count_info(idx1, idx2, update=true) + # Tk8.5 feature + opts = [ + :chars, :displaychars, :displayindices, :displaylines, + :indices, :lines, :xpixels, :ypixels + ] + if update + lst = count(idx1, idx2, :update, *opts) + else + lst = count(idx1, idx2, *opts) + end + info = {} + opts.each_with_index{|key, idx| info[key] = lst[idx]} + info + end + + def peer_names() + # Tk8.5 feature + list(tk_send_without_enc('peer', 'names')) + end + + def replace(idx1, idx2, *opts) + tk_send('replace', idx1, idx2, *opts) + self + end + + def debug + bool(tk_send_without_enc('debug')) + end + def debug=(boolean) + tk_send_without_enc('debug', boolean) + #self + boolean + end + + def dlineinfo(index) + list(tk_send_without_enc('dlineinfo', _get_eval_enc_str(index))) + end + + def modified? + bool(tk_send_without_enc('edit', 'modified')) + end + def modified(mode) + tk_send_without_enc('edit', 'modified', mode) + self + end + def modified=(mode) + modified(mode) + mode + end + + def edit_redo + tk_send_without_enc('edit', 'redo') + self + end + def edit_reset + tk_send_without_enc('edit', 'reset') + self + end + def edit_separator + tk_send_without_enc('edit', 'separator') + self + end + def edit_undo + tk_send_without_enc('edit', 'undo') + self + end + + def xview_pickplace(index) + tk_send_without_enc('xview', '-pickplace', _get_eval_enc_str(index)) + self + end + + def yview_pickplace(index) + tk_send_without_enc('yview', '-pickplace', _get_eval_enc_str(index)) + self + end + + def text_copy + # Tk8.4 feature + tk_call_without_enc('tk_textCopy', @path) + self + end + + def text_cut + # Tk8.4 feature + tk_call_without_enc('tk_textCut', @path) + self + end + + def text_paste + # Tk8.4 feature + tk_call_without_enc('tk_textPaste', @path) + self + end + + def tag_add(tag, index1, index2=None) + tk_send_without_enc('tag', 'add', _get_eval_enc_str(tag), + _get_eval_enc_str(index1), + _get_eval_enc_str(index2)) + self + end + alias addtag tag_add + alias add_tag tag_add + + def tag_delete(*tags) + tk_send_without_enc('tag', 'delete', + *(tags.collect{|tag| _get_eval_enc_str(tag)})) + if TkTextTag::TTagID_TBL[@path] + tags.each{|tag| + if tag.kind_of?(TkTextTag) + TkTextTag::TTagID_TBL[@path].delete(tag.id) + else + TkTextTag::TTagID_TBL[@path].delete(tag) + end + } + end + self + end + alias deltag tag_delete + alias delete_tag tag_delete + + #def tag_bind(tag, seq, cmd=Proc.new, *args) + # _bind([@path, 'tag', 'bind', tag], seq, cmd, *args) + # self + #end + def tag_bind(tag, seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([@path, 'tag', 'bind', tag], seq, cmd, *args) + self + end + + #def tag_bind_append(tag, seq, cmd=Proc.new, *args) + # _bind_append([@path, 'tag', 'bind', tag], seq, cmd, *args) + # self + #end + def tag_bind_append(tag, seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@path, 'tag', 'bind', tag], seq, cmd, *args) + self + end + + def tag_bind_remove(tag, seq) + _bind_remove([@path, 'tag', 'bind', tag], seq) + self + end + + def tag_bindinfo(tag, context=nil) + _bindinfo([@path, 'tag', 'bind', tag], context) + end + +=begin + def tag_cget(tag, key) + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + tk_call_without_enc(@path, 'tag', 'cget', + _get_eval_enc_str(tag), "-#{key}") + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('tag', 'cget', tag, "-#{key}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('tag','cget',_get_eval_enc_str(tag),'-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(tag, fnt) + end + if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(_fromUTF8(tk_call_without_enc(@path,'tag','cget',_get_eval_enc_str(tag),"-#{key}"))) + end + end + + def tag_configure(tag, key, val=None) + if key.kind_of?(Hash) + key = _symbolkey2str(key) + if ( key['font'] || key['kanjifont'] \ + || key['latinfont'] || key['asciifont'] ) + tagfont_configure(tag, key) + else + tk_send_without_enc('tag', 'configure', _get_eval_enc_str(tag), + *hash_kv(key, true)) + end + + else + if key == 'font' || key == :font || + key == 'kanjifont' || key == :kanjifont || + key == 'latinfont' || key == :latinfont || + key == 'asciifont' || key == :asciifont + if val == None + tagfontobj(tag) + else + tagfont_configure(tag, {key=>val}) + end + else + tk_send_without_enc('tag', 'configure', _get_eval_enc_str(tag), + "-#{key}", _get_eval_enc_str(val)) + end + end + self + end + + def tag_configinfo(tag, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + conf[4] = tagfont_configinfo(tag, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + end + conf[0] = conf[0][1..-1] + conf + else + ret = tk_split_simplelist(_fromUTF8(tk_send('tag','configure',_get_eval_enc_str(tag)))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + fontconf = ret.assoc('font') + if fontconf + ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} + fontconf[4] = tagfont_configinfo(tag, fontconf[4]) + ret.push(fontconf) + else + ret + end + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + conf[4] = tagfont_configinfo(tag, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send('tag','configure',_get_eval_enc_str(tag)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + fontconf = ret['font'] + if fontconf + ret.delete('font') + ret.delete('kanjifont') + fontconf[3] = tagfont_configinfo(tag, fontconf[3]) + ret['font'] = fontconf + end + ret + end + end + end + + def current_tag_configinfo(tag, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = tag_configinfo(tag, key) + {conf[0] => conf[4]} + else + ret = {} + tag_configinfo(tag).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + tag_configinfo(tag, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +=end + + def tag_raise(tag, above=None) + tk_send_without_enc('tag', 'raise', _get_eval_enc_str(tag), + _get_eval_enc_str(above)) + self + end + + def tag_lower(tag, below=None) + tk_send_without_enc('tag', 'lower', _get_eval_enc_str(tag), + _get_eval_enc_str(below)) + self + end + + def tag_remove(tag, *indices) + tk_send_without_enc('tag', 'remove', _get_eval_enc_str(tag), + *(indices.collect{|idx| _get_eval_enc_str(idx)})) + self + end + + def tag_ranges(tag) + #l = tk_split_simplelist(tk_send_without_enc('tag', 'ranges', + # _get_eval_enc_str(tag))) + l = tk_split_simplelist(tk_send_without_enc('tag', 'ranges', + _get_eval_enc_str(tag)), + false, true) + r = [] + while key=l.shift + r.push [TkText::IndexString.new(key), TkText::IndexString.new(l.shift)] + end + r + end + + def tag_nextrange(tag, first, last=None) + simplelist(tk_send_without_enc('tag', 'nextrange', + _get_eval_enc_str(tag), + _get_eval_enc_str(first), + _get_eval_enc_str(last))).collect{|idx| + TkText::IndexString.new(idx) + } + end + + def tag_prevrange(tag, first, last=None) + simplelist(tk_send_without_enc('tag', 'prevrange', + _get_eval_enc_str(tag), + _get_eval_enc_str(first), + _get_eval_enc_str(last))).collect{|idx| + TkText::IndexString.new(idx) + } + end + +=begin + def window_cget(index, slot) + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + _fromUTF8(tk_send_without_enc('window', 'cget', + _get_eval_enc_str(index), "-#{slot}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('window', 'cget', _get_eval_enc_str(index), '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(index, fnt) + end + if slot.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(_fromUTF8(tk_send_without_enc('window', 'cget', _get_eval_enc_str(index), "-#{slot}"))) + end + end + + def window_configure(index, slot, value=None) + if index.kind_of?(TkTextWindow) + index.configure(slot, value) + else + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + win = slot['window'] + # slot['window'] = win.epath if win.kind_of?(TkWindow) + slot['window'] = _epath(win) if win + if slot['create'] + p_create = slot['create'] + if p_create.kind_of?(Proc) +#=begin + slot['create'] = install_cmd(proc{ + id = p_create.call + if id.kind_of?(TkWindow) + id.epath + else + id + end + }) +#=end + slot['create'] = install_cmd(proc{_epath(p_create.call)}) + end + end + tk_send_without_enc('window', 'configure', + _get_eval_enc_str(index), + *hash_kv(slot, true)) + else + if slot == 'window' || slot == :window + # id = value + # value = id.epath if id.kind_of?(TkWindow) + value = _epath(value) + end + if slot == 'create' || slot == :create + p_create = value + if p_create.kind_of?(Proc) +#=begin + value = install_cmd(proc{ + id = p_create.call + if id.kind_of?(TkWindow) + id.epath + else + id + end + }) +#=end + value = install_cmd(proc{_epath(p_create.call)}) + end + end + tk_send_without_enc('window', 'configure', + _get_eval_enc_str(index), + "-#{slot}", _get_eval_enc_str(value)) + end + end + self + end + + def window_configinfo(win, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + else + conf = tk_split_list(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + end + conf[0] = conf[0][1..-1] + conf + else + tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win)))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + else + conf = tk_split_list(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + ret + end + end + end + + def current_window_configinfo(win, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + conf = window_configinfo(win, slot) + {conf[0] => conf[4]} + else + ret = {} + window_configinfo(win).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + window_configinfo(win, slot).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +=end + + def window_names + # tk_split_simplelist(_fromUTF8(tk_send_without_enc('window', 'names'))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('window', 'names'), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def _ktext_length(txt) + if $KCODE !~ /n/i + return txt.gsub(/[^\Wa-zA-Z_\d]/, ' ').length + end + + # $KCODE == 'NONE' + if JAPANIZED_TK + tk_call_without_enc('kstring', 'length', + _get_eval_enc_str(txt)).to_i + else + begin + tk_call_without_enc('encoding', 'convertto', 'ascii', + _get_eval_enc_str(txt)).length + rescue StandardError, NameError + # sorry, I have no plan + txt.length + end + end + end + private :_ktext_length + + def tksearch(*args) + # call 'search' subcommand of text widget + # args ::= [<array_of_opts>] <pattern> <start_index> [<stop_index>] + # If <pattern> is regexp, then it must be a regular expression of Tcl + nocase = false + if args[0].kind_of?(Array) + opts = args.shift.collect{|opt| + s_opt = opt.to_s + nocase = true if s_opt == 'nocase' + '-' + s_opt + } + else + opts = [] + end + + if args[0].kind_of?(Regexp) + regexp = args.shift + if !nocase && (regexp.options & Regexp::IGNORECASE) != 0 + opts << '-nocase' + end + args.unshift(regexp.source) + end + + opts << '--' + + ret = tk_send('search', *(opts + args)) + if ret == "" + nil + else + TkText::IndexString.new(ret) + end + end + + def tksearch_with_count(*args) + # call 'search' subcommand of text widget + # args ::= [<array_of_opts>] <var> <pattern> <start_index> [<stop_index>] + # If <pattern> is regexp, then it must be a regular expression of Tcl + nocase = false + if args[0].kind_of?(Array) + opts = args.shift.collect{|opt| + s_opt = opt.to_s + nocase = true if s_opt == 'nocase' + '-' + s_opt + } + else + opts = [] + end + + opts << '-count' << args.shift + + if args[0].kind_of?(Regexp) + regexp = args.shift + if !nocase && (regexp.options & Regexp::IGNORECASE) != 0 + opts << '-nocase' + end + args.unshift(regexp.source) + end + + opts << '--' + + ret = tk_send('search', *(opts + args)) + if ret == "" + nil + else + TkText::IndexString.new(ret) + end + end + + def search_with_length(pat,start,stop=None) + pat = pat.chr if pat.kind_of?(Integer) + if stop != None + return ["", 0] if compare(start,'>=',stop) + txt = get(start,stop) + if (pos = txt.index(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index(start + " + #{pos} chars"), pat.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(pat), pat.dup] + else + #return [index(start + " + #{pos} chars"), $&.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(match), match] + end + else + return ["", 0] + end + else + txt = get(start,'end - 1 char') + if (pos = txt.index(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index(start + " + #{pos} chars"), pat.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(pat), pat.dup] + else + #return [index(start + " + #{pos} chars"), $&.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(match), match] + end + else + txt = get('1.0','end - 1 char') + if (pos = txt.index(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index("1.0 + #{pos} chars"), pat.split('').length] + return [index("1.0 + #{pos} chars"), + _ktext_length(pat), pat.dup] + else + #return [index("1.0 + #{pos} chars"), $&.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(match), match] + 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.chr if pat.kind_of?(Integer) + if stop != None + return ["", 0] if compare(start,'<=',stop) + txt = get(stop,start) + if (pos = txt.rindex(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index(stop + " + #{pos} chars"), pat.split('').length] + return [index(stop + " + #{pos} chars"), _ktext_length(pat), pat.dup] + else + #return [index(stop + " + #{pos} chars"), $&.split('').length] + return [index(stop + " + #{pos} chars"), _ktext_length(match), match] + end + else + return ["", 0] + end + else + txt = get('1.0',start) + if (pos = txt.rindex(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index("1.0 + #{pos} chars"), pat.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup] + else + #return [index("1.0 + #{pos} chars"), $&.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(match), match] + end + else + txt = get('1.0','end - 1 char') + if (pos = txt.rindex(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index("1.0 + #{pos} chars"), pat.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup] + else + #return [index("1.0 + #{pos} chars"), $&.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(match), match] + end + else + return ["", 0] + end + end + end + end + + def rsearch(pat,start,stop=None) + rsearch_with_length(pat,start,stop)[0] + end + + def dump(type_info, *index, &block) + if type_info.kind_of?(Symbol) + type_info = [ type_info.to_s ] + elsif type_info.kind_of?(String) + type_info = [ type_info ] + end + args = type_info.collect{|inf| '-' + inf} + args << '-command' << block if block + str = tk_send('dump', *(args + 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_tcl2ruby(val) + end + when 'tagon' + if val == 'sel' + if sel + result.push sel + else + result.push TkTextTagSel.new(self) + end + else + result.push tk_tcl2ruby(val) + end + when 'tagoff' + result.push tk_tcl2ruby(val) + when 'window' + result.push tk_tcl2ruby(val) + when 'image' + result.push tk_tcl2ruby(val) + end + i = idx + 1 + end + + # retrieve index + idx = str.index(/ /, i) + if idx + result.push(TkText::IndexString.new(str[i..(idx-1)])) + i = idx + 1 + else + result.push(TkText::IndexString.new(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 + + 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, &block) + dump(['all'], *index, &block) + end + def dump_mark(*index, &block) + dump(['mark'], *index, &block) + end + def dump_tag(*index, &block) + dump(['tag'], *index, &block) + end + def dump_text(*index, &block) + dump(['text'], *index, &block) + end + def dump_window(*index, &block) + dump(['window'], *index, &block) + end + def dump_image(*index, &block) + dump(['image'], *index, &block) + end +end + +####################################### + +class TkText::Peer < TkText + # Tk8.5 feature + def initialize(text, parent=nil, keys={}) + unless text.kind_of?(TkText) + fail ArgumentError, "TkText is expected for 1st argument" + end + @src_text = text + super(parent, keys) + end + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(@src_text.path, 'peer', 'create', @path) + else + tk_call_without_enc(@src_text.path, 'peer', 'create', @path) + end + end + private :create_self +end |