1# -*- coding: utf-8 -*- 2# 3# Text Search widget demo (called by 'widget') 4# 5 6# textLoadFile -- 7# This method below loads a file into a text widget, discarding 8# the previous contents of the widget. Tags for the old widget are 9# not affected, however. 10# 11# Arguments: 12# w - The window into which to load the file. Must be a 13# text widget. 14# file - The name of the file to load. Must be readable. 15 16def textLoadFile(w,file) 17 w.delete('1.0', 'end') 18 f = open(file, 'r') 19 while(!f.eof?) 20 w.insert('end', f.read(1000)) 21 end 22 f.close 23end 24 25# textSearch -- 26# Search for all instances of a given string in a text widget and 27# apply a given tag to each instance found. 28# 29# Arguments: 30# w - The window in which to search. Must be a text widget. 31# string - The string to search for. The search is done using 32# exact matching only; no special characters. 33# tag - Tag to apply to each instance of a matching string. 34 35def textSearch(w, string, tag) 36 tag.remove('0.0', 'end') 37 return if string == "" 38 cur = '1.0' 39 loop { 40 cur, len = w.search_with_length(string, cur, 'end') 41 break if cur == "" 42 tag.add(cur, "#{cur} + #{len} char") 43 cur = w.index("#{cur} + #{len} char") 44 } 45end 46 47# textToggle -- 48# This method is invoked repeatedly to invoke two commands at 49# periodic intervals. It normally reschedules itself after each 50# execution but if an error occurs (e.g. because the window was 51# deleted) then it doesn't reschedule itself. 52# 53# Arguments: 54# cmd1 - Command to execute when method is called. 55# sleep1 - Ms to sleep after executing cmd1 before executing cmd2. 56# cmd2 - Command to execute in the *next* invocation of this method. 57# sleep2 - Ms to sleep after executing cmd2 before executing cmd1 again. 58 59def textToggle(cmd1,sleep1,cmd2,sleep2) 60 sleep_list = [sleep2, sleep1] 61 TkAfter.new(proc{sleep = sleep_list.shift; sleep_list.push(sleep); sleep}, 62 -1, cmd1, cmd2).start(sleep1) 63end 64 65# toplevel widget が存在すれば削除する 66if defined?($search_demo) && $search_demo 67 $search_demo.destroy 68 $search_demo = nil 69end 70 71# demo 用の toplevel widget を生成 72$search_demo = TkToplevel.new {|w| 73 title("Text Demonstration - Search and Highlight") 74 iconname("search") 75 positionWindow(w) 76} 77 78base_frame = TkFrame.new($search_demo).pack(:fill=>:both, :expand=>true) 79 80# frame 生成 81$search_buttons = TkFrame.new(base_frame) {|frame| 82 TkButton.new(frame) { 83 #text '了解' 84 text '閉じる' 85 command proc{ 86 tmppath = $search_demo 87 $search_demo = nil 88 tmppath.destroy 89 } 90 }.pack('side'=>'left', 'expand'=>'yes') 91 92 TkButton.new(frame) { 93 text 'コード参照' 94 command proc{showCode 'search'} 95 }.pack('side'=>'left', 'expand'=>'yes') 96} 97$search_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') 98 99# frame 生成 100TkFrame.new(base_frame) {|f| 101 TkLabel.new(f, 'text'=>'ファイル名:', 102 'width'=>13, 'anchor'=>'w').pack('side'=>'left') 103 $search_fileName = TkVariable.new 104 TkEntry.new(f, 'width'=>40, 105 'textvariable'=>$search_fileName) { 106 pack('side'=>'left') 107 bind('Return', proc{textLoadFile($search_text, $search_fileName.value) 108 $search_string_entry.focus}) 109 focus 110 } 111 TkButton.new(f, 'text'=>'読み込み', 112 'command'=>proc{textLoadFile($search_text, 113 $search_fileName.value)})\ 114 .pack('side'=>'left', 'pady'=>5, 'padx'=>10) 115}.pack('side'=>'top', 'fill'=>'x') 116 117TkFrame.new(base_frame) {|f| 118 TkLabel.new(f, 'text'=>'検索文字列:', 119 'width'=>13, 'anchor'=>'w').pack('side'=>'left') 120 $search_searchString = TkVariable.new 121 $search_string_entry = TkEntry.new(f, 'width'=>40, 122 'textvariable'=>$search_searchString) { 123 pack('side'=>'left') 124 bind('Return', proc{textSearch($search_text, $search_searchString.value, 125 $search_Tag)}) 126 } 127 TkButton.new(f, 'text'=>'反転', 128 'command'=>proc{textSearch($search_text, 129 $search_searchString.value, 130 $search_Tag)}) { 131 pack('side'=>'left', 'pady'=>5, 'padx'=>10) 132 } 133}.pack('side'=>'top', 'fill'=>'x') 134 135$search_text = TkText.new(base_frame, 'setgrid'=>true) {|t| 136 $search_Tag = TkTextTag.new(t) 137 TkScrollbar.new(base_frame, 'command'=>proc{|*args| t.yview(*args)}) {|sc| 138 t.yscrollcommand(proc{|first,last| sc.set first,last}) 139 pack('side'=>'right', 'fill'=>'y') 140 } 141 pack('expand'=>'yes', 'fill'=>'both') 142} 143 144# Set up display styles for text highlighting. 145 146if TkWinfo.depth($search_demo) > 1 147 textToggle(proc{ 148 $search_Tag.configure('background'=>'#ce5555', 149 'foreground'=>'white') 150 }, 151 800, 152 proc{ 153 $search_Tag.configure('background'=>'', 'foreground'=>'') 154 }, 155 200 ) 156else 157 textToggle(proc{ 158 $search_Tag.configure('background'=>'black', 159 'foreground'=>'white') 160 }, 161 800, 162 proc{ 163 $search_Tag.configure('background'=>'', 'foreground'=>'') 164 }, 165 200 ) 166end 167$search_text.insert('1.0', "\ 168このウィンドウは検索機構を実現するのにテキスト widget のタグ機能がどの \ 169ように使われるのかをデモするものです。まず上のエントリにファイル名を入 \ 170れ、<リターン> を押すか「ロード」ボタンを押してください。次にその下の \ 171エントリに文字列を入力し、<リターン> を押すか「反転」ボタンを押してく \ 172ださい。するとファイル中の、検索文字列と一致する部分に全て \"search_Tag\" \ 173というタグがつけられ、タグの表示属性としてその文字列が点滅するように \ 174設定されます。\n") 175$search_text.insert('end', "\ 176ファイル読み込みのカレントディレクトリは \"#{Dir.pwd}\" です。\ 177") 178$search_text.set_insert '0.0' 179 180$search_fileName.value = '' 181$search_searchString.value = '' 182 183$search_text.width = 60 184$search_text.height = 20 185