DEFINITIONS
This source file includes following functions.
1 #
2 # tkcanvas.rb - Tk canvas classes
3 # $Date: 2002/06/28 14:40:25 $
4 # by Yukihiro Matsumoto <matz@caelum.co.jp>
5 # $Date: 2002/06/28 14:40:25 $
6 # by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>
7
8 require "tk"
9 require 'tkfont'
10
11 module TkTreatCItemFont
12 include TkTreatItemFont
13
14 ItemCMD = ['itemconfigure', TkComm::None]
15 def __conf_cmd(idx)
16 ItemCMD[idx]
17 end
18
19 def __item_pathname(tagOrId)
20 if tagOrId.kind_of?(TkcItem) || tagOrId.kind_of?(TkcTag)
21 self.path + ';' + tagOrId.id.to_s
22 else
23 self.path + ';' + tagOrId.to_s
24 end
25 end
26 end
27
28 class TkCanvas<TkWindow
29 include TkTreatCItemFont
30 include Scrollable
31
32 WidgetClassName = 'Canvas'.freeze
33 WidgetClassNames[WidgetClassName] = self
34 def self.to_eval
35 WidgetClassName
36 end
37
38 def create_self(keys)
39 if keys and keys != None
40 tk_call 'canvas', @path, *hash_kv(keys)
41 else
42 tk_call 'canvas', @path
43 end
44 end
45
46 def tagid(tag)
47 if tag.kind_of?(TkcItem) || tag.kind_of?(TkcTag)
48 tag.id
49 else
50 tag
51 end
52 end
53 private :tagid
54
55 def addtag(tag, mode, *args)
56 tk_send 'addtag', tagid(tag), mode, *args
57 end
58 def addtag_above(tagOrId, target)
59 addtag(tagOrId, 'above', tagid(target))
60 end
61 def addtag_all(tagOrId)
62 addtag(tagOrId, 'all')
63 end
64 def addtag_below(tagOrId, target)
65 addtag(tagOrId, 'below', tagid(target))
66 end
67 def addtag_closest(tagOrId, x, y, halo=None, start=None)
68 addtag(tagOrId, 'closest', x, y, halo, start)
69 end
70 def addtag_enclosed(tagOrId, x1, y1, x2, y2)
71 addtag(tagOrId, 'enclosed', x1, y1, x2, y2)
72 end
73 def addtag_overlapping(tagOrId, x1, y1, x2, y2)
74 addtag(tagOrId, 'overlapping', x1, y1, x2, y2)
75 end
76 def addtag_withtag(tagOrId, tag)
77 addtag(tagOrId, 'withtag', tagid(tag))
78 end
79
80 def bbox(tagOrId, *tags)
81 list(tk_send('bbox', tagid(tagOrId), *tags.collect{|t| tagid(t)}))
82 end
83
84 def itembind(tag, context, cmd=Proc.new, args=nil)
85 _bind([path, "bind", tagid(tag)], context, cmd, args)
86 end
87
88 def itembind_append(tag, context, cmd=Proc.new, args=nil)
89 _bind_append([path, "bind", tagid(tag)], context, cmd, args)
90 end
91
92 def itembindinfo(tag, context=nil)
93 _bindinfo([path, "bind", tagid(tag)], context)
94 end
95
96 def canvasx(x, *args)
97 tk_tcl2ruby(tk_send('canvasx', x, *args))
98 end
99 def canvasy(y, *args)
100 tk_tcl2ruby(tk_send('canvasy', y, *args))
101 end
102
103 def coords(tag, *args)
104 if args == []
105 tk_split_list(tk_send('coords', tagid(tag)))
106 else
107 tk_send('coords', tagid(tag), *args)
108 end
109 end
110
111 def dchars(tag, first, last=None)
112 tk_send 'dchars', tagid(tag), first, last
113 end
114
115 def delete(*args)
116 tk_send 'delete', *args.collect{|t| tagid(t)}
117 end
118 alias remove delete
119
120 def dtag(tag, tag_to_del=None)
121 tk_send 'dtag', tagid(tag), tag_to_del
122 end
123
124 def find(mode, *args)
125 list(tk_send('find', mode, *args)).collect!{|id|
126 TkcItem.id2obj(self, id)
127 }
128 end
129 def find_above(target)
130 find('above', tagid(target))
131 end
132 def find_all
133 find('all')
134 end
135 def find_below(target)
136 find('below', tagid(target))
137 end
138 def find_closest(x, y, halo=None, start=None)
139 find('closest', x, y, halo, start)
140 end
141 def find_enclosed(x1, y1, x2, y2)
142 find('enclosed', x1, y1, x2, y2)
143 end
144 def find_overlapping(x1, y1, x2, y2)
145 find('overlapping', x1, y1, x2, y2)
146 end
147 def find_withtag(tag)
148 find('withtag', tag)
149 end
150
151 def itemfocus(tagOrId=nil)
152 if tagOrId
153 tk_send 'focus', tagid(tagOrId)
154 else
155 ret = tk_send('focus')
156 if ret == ""
157 nil
158 else
159 TkcItem.id2obj(self, ret)
160 end
161 end
162 end
163
164 def gettags(tagOrId)
165 list(tk_send('gettags', tagid(tagOrId))).collect{|tag|
166 TkcTag.id2obj(self, tag)
167 }
168 end
169
170 def icursor(tagOrId, index)
171 tk_send 'icursor', tagid(tagOrId), index
172 end
173
174 def index(tagOrId, index)
175 tk_send 'index', tagid(tagOrId), index
176 end
177
178 def insert(tagOrId, index, string)
179 tk_send 'insert', tagid(tagOrId), index, string
180 end
181
182 def itemcget(tagOrId, option)
183 case option.to_s
184 when 'dash', 'activedash', 'disableddash'
185 conf = tk_send('itemcget', tagid(tagOrId), "-#{option}")
186 if conf =~ /^[0-9]/
187 list(conf)
188 else
189 conf
190 end
191 when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
192 tk_send 'itemcget', tagid(tagOrId), "-#{option}"
193 else
194 tk_tcl2ruby tk_send('itemcget', tagid(tagOrId), "-#{option}")
195 end
196 end
197
198 def itemconfigure(tagOrId, key, value=None)
199 if key.kind_of? Hash
200 key = _symbolkey2str(key)
201 if ( key['font'] || key['kanjifont'] \
202 || key['latinfont'] || key['asciifont'] )
203 tagfont_configure(tagOrId, key.dup)
204 else
205 tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key)
206 end
207
208 else
209 if ( key == 'font' || key == :font ||
210 key == 'kanjifont' || key == :kanjifont ||
211 key == 'latinfont' || key == :latinfont ||
212 key == 'asciifont' || key == :asciifont )
213 tagfont_configure(tagid(tagOrId), {key=>value})
214 else
215 tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value
216 end
217 end
218 end
219 # def itemconfigure(tagOrId, key, value=None)
220 # if key.kind_of? Hash
221 # tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key)
222 # else
223 # tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value
224 # end
225 # end
226 # def itemconfigure(tagOrId, keys)
227 # tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(keys)
228 # end
229
230 def itemconfiginfo(tagOrId, key=nil)
231 if key
232 case key.to_s
233 when 'dash', 'activedash', 'disableddash'
234 conf = tk_split_simplelist(tk_send('itemconfigure',
235 tagid(tagOrId), "-#{key}"))
236 if conf[3] && conf[3] =~ /^[0-9]/
237 conf[3] = list(conf[3])
238 end
239 if conf[4] && conf[4] =~ /^[0-9]/
240 conf[4] = list(conf[4])
241 end
242 when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
243 conf = tk_split_simplelist(tk_send('itemconfigure',
244 tagid(tagOrId), "-#{key}"))
245 else
246 conf = tk_split_list(tk_send('itemconfigure',
247 tagid(tagOrId), "-#{key}"))
248 end
249 conf[0] = conf[0][1..-1]
250 conf
251 else
252 tk_split_simplelist(tk_send('itemconfigure',
253 tagid(tagOrId))).collect{|conflist|
254 conf = tk_split_simplelist(conflist)
255 conf[0] = conf[0][1..-1]
256 case conf[0]
257 when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
258 when 'dash', 'activedash', 'disableddash'
259 if conf[3] && conf[3] =~ /^[0-9]/
260 conf[3] = list(conf[3])
261 end
262 if conf[4] && conf[4] =~ /^[0-9]/
263 conf[4] = list(conf[4])
264 end
265 else
266 if conf[3]
267 if conf[3].index('{')
268 conf[3] = tk_split_list(conf[3])
269 else
270 conf[3] = tk_tcl2ruby(conf[3])
271 end
272 end
273 if conf[4]
274 if conf[4].index('{')
275 conf[4] = tk_split_list(conf[4])
276 else
277 conf[4] = tk_tcl2ruby(conf[4])
278 end
279 end
280 end
281 conf
282 }
283 end
284 end
285
286 def lower(tag, below=None)
287 tk_send 'lower', tagid(tag), tagid(below)
288 end
289
290 def move(tag, x, y)
291 tk_send 'move', tagid(tag), x, y
292 end
293
294 def postscript(keys)
295 tk_send "postscript", *hash_kv(keys)
296 end
297
298 def raise(tag, above=None)
299 tk_send 'raise', tagid(tag), tagid(above)
300 end
301
302 def scale(tag, x, y, xs, ys)
303 tk_send 'scale', tagid(tag), x, y, xs, ys
304 end
305
306 def scan_mark(x, y)
307 tk_send 'scan', 'mark', x, y
308 end
309 def scan_dragto(x, y)
310 tk_send 'scan', 'dragto', x, y
311 end
312
313 def select(mode, *args)
314 tk_send 'select', mode, *args
315 end
316 def select_adjust(tagOrId, index)
317 select('adjust', tagid(tagOrId), index)
318 end
319 def select_clear
320 select('clear')
321 end
322 def select_from(tagOrId, index)
323 select('from', tagid(tagOrId), index)
324 end
325 def select_item
326 select('item')
327 end
328 def select_to(tagOrId, index)
329 select('to', tagid(tagOrId), index)
330 end
331
332 def itemtype(tag)
333 TkcItem.type2class(tk_send('type', tagid(tag)))
334 end
335 end
336
337 module TkcTagAccess
338 include TkComm
339 include TkTreatTagFont
340
341 def addtag(tag)
342 @c.addtag(tag, 'with', @id)
343 end
344
345 def bbox
346 @c.bbox(@id)
347 end
348
349 def bind(seq, cmd=Proc.new, args=nil)
350 @c.itembind @id, seq, cmd, args
351 end
352
353 def bindinfo(seq=nil)
354 @c.itembindinfo @id, seq
355 end
356
357 def cget(option)
358 @c.itemcget @id, option
359 end
360
361 def configure(key, value=None)
362 @c.itemconfigure @id, key, value
363 end
364 # def configure(keys)
365 # @c.itemconfigure @id, keys
366 # end
367
368 def configinfo(key=nil)
369 @c.itemconfiginfo @id, key
370 end
371
372 def coords(*args)
373 @c.coords @id, *args
374 end
375
376 def dchars(first, last=None)
377 @c.dchars @id, first, last
378 end
379
380 def dtag(tag_to_del=None)
381 @c.dtag @id, tag_to_del
382 end
383
384 def find
385 @c.find 'withtag', @id
386 end
387 alias list find
388
389 def focus
390 @c.itemfocus @id
391 end
392
393 def gettags
394 @c.gettags @id
395 end
396
397 def icursor(index)
398 @c.icursor @id, index
399 end
400
401 def index(index)
402 @c.index @id, index
403 end
404
405 def insert(beforethis, string)
406 @c.insert @id, beforethis, string
407 end
408
409 def lower(belowthis=None)
410 @c.lower @id, belowthis
411 end
412
413 def move(xamount, yamount)
414 @c.move @id, xamount, yamount
415 end
416
417 def raise(abovethis=None)
418 @c.raise @id, abovethis
419 end
420
421 def scale(xorigin, yorigin, xscale, yscale)
422 @c.scale @id, xorigin, yorigin, xscale, yscale
423 end
424
425 def select_adjust(index)
426 @c.select('adjust', @id, index)
427 end
428 def select_from(index)
429 @c.select('from', @id, index)
430 end
431 def select_to(index)
432 @c.select('to', @id, index)
433 end
434
435 def itemtype
436 @c.itemtype @id
437 end
438
439 # Following operators support logical expressions of canvas tags
440 # (for Tk8.3+).
441 # If tag1.path is 't1' and tag2.path is 't2', then
442 # ltag = tag1 & tag2; ltag.path => "(t1)&&(t2)"
443 # ltag = tag1 | tag2; ltag.path => "(t1)||(t2)"
444 # ltag = tag1 ^ tag2; ltag.path => "(t1)^(t2)"
445 # ltag = - tag1; ltag.path => "!(t1)"
446 def & (tag)
447 if tag.kind_of? TkObject
448 TkcTagString.new(@c, '(' + @id + ')&&(' + tag.path + ')')
449 else
450 TkcTagString.new(@c, '(' + @id + ')&&(' + tag.to_s + ')')
451 end
452 end
453
454 def | (tag)
455 if tag.kind_of? TkObject
456 TkcTagString.new(@c, '(' + @id + ')||(' + tag.path + ')')
457 else
458 TkcTagString.new(@c, '(' + @id + ')||(' + tag.to_s + ')')
459 end
460 end
461
462 def ^ (tag)
463 if tag.kind_of? TkObject
464 TkcTagString.new(@c, '(' + @id + ')^(' + tag.path + ')')
465 else
466 TkcTagString.new(@c, '(' + @id + ')^(' + tag.to_s + ')')
467 end
468 end
469
470 def -@
471 TkcTagString.new(@c, '!(' + @id + ')')
472 end
473 end
474
475 class TkcTag<TkObject
476 include TkcTagAccess
477
478 CTagID_TBL = {}
479 Tk_CanvasTag_ID = ['ctag0000']
480
481 def TkcTag.id2obj(canvas, id)
482 cpath = canvas.path
483 return id unless CTagID_TBL[cpath]
484 CTagID_TBL[cpath][id]? CTagID_TBL[cpath][id]: id
485 end
486
487 def initialize(parent, mode=nil, *args)
488 if not parent.kind_of?(TkCanvas)
489 fail format("%s need to be TkCanvas", parent.inspect)
490 end
491 @c = parent
492 @cpath = parent.path
493 @path = @id = Tk_CanvasTag_ID[0]
494 CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
495 CTagID_TBL[@cpath][@id] = self
496 Tk_CanvasTag_ID[0] = Tk_CanvasTag_ID[0].succ
497 if mode
498 tk_call @c.path, "addtag", @id, mode, *args
499 end
500 end
501 def id
502 return @id
503 end
504
505 def delete
506 @c.delete @id
507 CTagID_TBL[@cpath][@id] = nil if CTagID_TBL[@cpath]
508 end
509 alias remove delete
510 alias destroy delete
511
512 def set_to_above(target)
513 @c.addtag_above(@id, target)
514 end
515 alias above set_to_above
516
517 def set_to_all
518 @c.addtag_all(@id)
519 end
520 alias all set_to_all
521
522 def set_to_below(target)
523 @c.addtag_below(@id, target)
524 end
525 alias below set_to_below
526
527 def set_to_closest(x, y, halo=None, start=None)
528 @c.addtag_closest(@id, x, y, halo, start)
529 end
530 alias closest set_to_closest
531
532 def set_to_enclosed(x1, y1, x2, y2)
533 @c.addtag_enclosed(@id, x1, y1, x2, y2)
534 end
535 alias enclosed set_to_enclosed
536
537 def set_to_overlapping(x1, y1, x2, y2)
538 @c.addtag_overlapping(@id, x1, y1, x2, y2)
539 end
540 alias overlapping set_to_overlapping
541
542 def set_to_withtag(target)
543 @c.addtag_withtag(@id, target)
544 end
545 alias withtag set_to_withtag
546 end
547
548 class TkcTagString<TkcTag
549 def self.new(parent, name, *args)
550 if CTagID_TBL[parent.path] && CTagID_TBL[parent.path][name]
551 return CTagID_TBL[parent.path][name]
552 else
553 super(parent, name, *args)
554 end
555 end
556
557 def initialize(parent, name, mode=nil, *args)
558 if not parent.kind_of?(TkCanvas)
559 fail format("%s need to be TkCanvas", parent.inspect)
560 end
561 @c = parent
562 @cpath = parent.path
563 @path = @id = name
564 CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
565 CTagID_TBL[@cpath][@id] = self
566 if mode
567 tk_call @c.path, "addtag", @id, mode, *args
568 end
569 end
570 end
571 TkcNamedTag = TkcTagString
572
573 class TkcTagAll<TkcTag
574 def initialize(parent)
575 if not parent.kind_of?(TkCanvas)
576 fail format("%s need to be TkCanvas", parent.inspect)
577 end
578 @c = parent
579 @cpath = parent.path
580 @path = @id = 'all'
581 CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
582 CTagID_TBL[@cpath][@id] = self
583 end
584 end
585
586 class TkcTagCurrent<TkcTag
587 def initialize(parent)
588 if not parent.kind_of?(TkCanvas)
589 fail format("%s need to be TkCanvas", parent.inspect)
590 end
591 @c = parent
592 @cpath = parent.path
593 @path = @id = 'current'
594 CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
595 CTagID_TBL[@cpath][@id] = self
596 end
597 end
598
599 class TkcGroup<TkcTag
600 Tk_cGroup_ID = ['tkcg00000']
601 def create_self(parent, *args)
602 if not parent.kind_of?(TkCanvas)
603 fail format("%s need to be TkCanvas", parent.inspect)
604 end
605 @c = parent
606 @cpath = parent.path
607 @path = @id = Tk_cGroup_ID[0]
608 CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
609 CTagID_TBL[@cpath][@id] = self
610 Tk_cGroup_ID[0] = Tk_cGroup_ID[0].succ
611 add(*args) if args != []
612 end
613
614 def include(*tags)
615 for i in tags
616 i.addtag @id
617 end
618 end
619
620 def exclude(*tags)
621 for i in tags
622 i.delete @id
623 end
624 end
625 end
626
627 class TkcItem<TkObject
628 include TkcTagAccess
629
630 CItemTypeToClass = {}
631 CItemID_TBL = {}
632
633 def TkcItem.type2class(type)
634 CItemTypeToClass[type]
635 end
636
637 def TkcItem.id2obj(canvas, id)
638 cpath = canvas.path
639 return id unless CItemID_TBL[cpath]
640 CItemID_TBL[cpath][id]? CItemID_TBL[cpath][id]: id
641 end
642
643 def initialize(parent, *args)
644 if not parent.kind_of?(TkCanvas)
645 fail format("%s need to be TkCanvas", parent.inspect)
646 end
647 @parent = @c = parent
648 @path = parent.path
649 fontkeys = {}
650 if args.size == 1 && args[0].kind_of?(Hash)
651 args[0] = _symbolkey2str(args[0])
652 coords = args[0].delete('coords')
653 if not coords.kind_of?(Array)
654 fail "coords parameter must be given by an Array"
655 end
656 args[0,0] = coords.flatten
657 end
658 if args[-1].kind_of? Hash
659 keys = _symbolkey2str(args.pop)
660 ['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key|
661 fontkeys[key] = keys.delete(key) if keys.key?(key)
662 }
663 args += hash_kv(keys)
664 end
665 @id = create_self(*args).to_i ;# 'canvas item id' is integer number
666 CItemID_TBL[@path] = {} unless CItemID_TBL[@path]
667 CItemID_TBL[@path][@id] = self
668 font_configure(fontkeys) unless fontkeys.empty?
669
670 ######## old version
671 # if args[-1].kind_of? Hash
672 # keys = args.pop
673 # end
674 # @id = create_self(*args).to_i ;# 'canvas item id' is integer number
675 # CItemID_TBL[@path] = {} unless CItemID_TBL[@path]
676 # CItemID_TBL[@path][@id] = self
677 # if keys
678 # # tk_call @path, 'itemconfigure', @id, *hash_kv(keys)
679 # configure(keys) if keys
680 # end
681 ########
682 end
683 def create_self(*args); end
684 private :create_self
685 def id
686 return @id
687 end
688
689 def delete
690 @c.delete @id
691 CItemID_TBL[@path][@id] = nil if CItemID_TBL[@path]
692 end
693 alias remove delete
694 alias destroy delete
695 end
696
697 class TkcArc<TkcItem
698 CItemTypeToClass['arc'] = self
699 def create_self(*args)
700 tk_call(@path, 'create', 'arc', *args)
701 end
702 end
703 class TkcBitmap<TkcItem
704 CItemTypeToClass['bitmap'] = self
705 def create_self(*args)
706 tk_call(@path, 'create', 'bitmap', *args)
707 end
708 end
709 class TkcImage<TkcItem
710 CItemTypeToClass['image'] = self
711 def create_self(*args)
712 tk_call(@path, 'create', 'image', *args)
713 end
714 end
715 class TkcLine<TkcItem
716 CItemTypeToClass['line'] = self
717 def create_self(*args)
718 tk_call(@path, 'create', 'line', *args)
719 end
720 end
721 class TkcOval<TkcItem
722 CItemTypeToClass['oval'] = self
723 def create_self(*args)
724 tk_call(@path, 'create', 'oval', *args)
725 end
726 end
727 class TkcPolygon<TkcItem
728 CItemTypeToClass['polygon'] = self
729 def create_self(*args)
730 tk_call(@path, 'create', 'polygon', *args)
731 end
732 end
733 class TkcRectangle<TkcItem
734 CItemTypeToClass['rectangle'] = self
735 def create_self(*args)
736 tk_call(@path, 'create', 'rectangle', *args)
737 end
738 end
739 class TkcText<TkcItem
740 CItemTypeToClass['text'] = self
741 def create_self(*args)
742 tk_call(@path, 'create', 'text', *args)
743 end
744 end
745 class TkcWindow<TkcItem
746 CItemTypeToClass['window'] = self
747 def create_self(*args)
748 tk_call(@path, 'create', 'window', *args)
749 end
750 end
751
752 class TkImage<TkObject
753 include Tk
754
755 Tk_IMGTBL = {}
756
757 Tk_Image_ID = ['i00000']
758 def initialize(keys=nil)
759 @path = Tk_Image_ID[0]
760 Tk_Image_ID[0] = Tk_Image_ID[0].succ
761 tk_call 'image', 'create', @type, @path, *hash_kv(keys)
762 Tk_IMGTBL[@path] = self
763 end
764
765 def delete
766 Tk_IMGTBL[@id] = nil if @id
767 tk_call('image', 'delete', @path)
768 end
769 def height
770 number(tk_call('image', 'height', @path))
771 end
772 def inuse
773 bool(tk_call('image', 'inuse', @path))
774 end
775 def itemtype
776 tk_call('image', 'type', @path)
777 end
778 def width
779 number(tk_call('image', 'width', @path))
780 end
781
782 def TkImage.names
783 Tk.tk_call('image', 'names').split.collect!{|id|
784 (Tk_IMGTBL[id])? Tk_IMGTBL[id] : id
785 }
786 end
787
788 def TkImage.types
789 Tk.tk_call('image', 'types').split
790 end
791 end
792
793 class TkBitmapImage<TkImage
794 def initialize(*args)
795 @type = 'bitmap'
796 super
797 end
798 end
799
800 class TkPhotoImage<TkImage
801 def initialize(*args)
802 @type = 'photo'
803 super
804 end
805
806 def blank
807 tk_send 'blank'
808 end
809
810 def cget(option)
811 case option.to_s
812 when 'data', 'file'
813 tk_send 'cget', option
814 else
815 tk_tcl2ruby tk_send('cget', option)
816 end
817 end
818
819 def copy(source, *opts)
820 args = opts.collect{|term|
821 if term.kind_of?(String) && term.include?(?\s)
822 term.split
823 else
824 term
825 end
826 }.flatten
827
828 tk_send 'copy', source, *args
829 end
830
831 def data(keys=nil)
832 tk_send 'data', *hash_kv(keys)
833 end
834
835 def get(x, y)
836 tk_send 'get', x, y
837 end
838
839 def put(data, *to)
840 if to == []
841 tk_send 'put', data
842 else
843 tk_send 'put', data, '-to', *to
844 end
845 end
846
847 def read(file, *opts)
848 args = opts.collect{|term|
849 if term.kind_of?(String) && term.include?(?\s)
850 term.split
851 else
852 term
853 end
854 }.flatten
855
856 tk_send 'read', file, *args
857 end
858
859 def redither
860 tk_send 'redither'
861 end
862
863 def write(file, *opts)
864 args = opts.collect{|term|
865 if term.kind_of?(String) && term.include?(?\s)
866 term.split
867 else
868 term
869 end
870 }.flatten
871
872 tk_send 'write', file, *args
873 end
874 end