1# 2# tk/textmark.rb - methods for treating text marks 3# 4require 'tk' 5require 'tk/text' 6 7class TkTextMark<TkObject 8 include Tk::Text::IndexModMethods 9 10 TMarkID_TBL = TkCore::INTERP.create_table 11 12 (Tk_TextMark_ID = ['mark'.freeze, TkUtil.untrust('00000')]).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 139end 140TktMark = TkTextMark 141 142class 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 182end 183TktNamedMark = TkTextNamedMark 184 185class TkTextMarkInsert<TkTextNamedMark 186 def self.new(parent,*args) 187 super(parent, 'insert', *args) 188 end 189end 190TktMarkInsert = TkTextMarkInsert 191 192class TkTextMarkCurrent<TkTextNamedMark 193 def self.new(parent,*args) 194 super(parent, 'current', *args) 195 end 196end 197TktMarkCurrent = TkTextMarkCurrent 198 199class TkTextMarkAnchor<TkTextNamedMark 200 def self.new(parent,*args) 201 super(parent, 'anchor', *args) 202 end 203end 204TktMarkAnchor = TkTextMarkAnchor 205