From: Toshihiko Ichida Date: 2016-08-19T19:19:12+09:00 Subject: [ruby-list:50377] Re: [再]Re: TkDND での日本語名の扱い こんにちは、市田です。 On 2016/07/23 7:23, Toshihiko Ichida wrote: > 他の環境、Ruby/Tkのアプリ内のDND動作は見られていません。 この休みに ubuntu 16.04 日本語Remixで見てみました。 1. text/plain tkdnd.rb に渡ってくるのは utf-8 文字列で、Encoding が ASCII-8BITとなって いるものです。(Windowsと同じ挙動) Windows と異なり、text/plain を指定してもファイル名のDropは可能です。 2. text/uri-list tkdnd.rb に渡ってくるのは utf-8 -> iso8859-1 に変換されたものです。 よって、正しく扱うには一段逆変換を行い、かつ utf-8 に force_encoding が 必要。 VirtualBox で動かしているせいもあるのでしょうが、ファイル名のドロップは かなり反応が鈍いです。 以上を踏まえて TclTkLib::WINDOWING_SYSTEM で win32, x11 を判定し、それぞ れ処理するようにしたものが次の内容となります。 --- tkdnd.rb.orig Mon Mar 14 11:24:12 2016 +++ tkdnd.rb Fri Aug 19 19:03:26 2016 @@ -80,6 +80,53 @@ _setup_subst_table(KEY_TBL, PROC_TBL); end + class DND_SubstText < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?D, ?d, :data ], + nil + ] + + PROC_TBL = [ + [ ?d, proc do |s| + case TclTkLib::WINDOWING_SYSTEM + when 'x11', 'win32' + s.force_encoding('utf-8') + end + s + end + ], + nil + ] + _setup_subst_table(KEY_TBL, PROC_TBL); + end + + class DND_SubstFileList < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?D, ?d, :data ], + nil + ] + + PROC_TBL = [ + [ ?d, proc do |s| + case TclTkLib::WINDOWING_SYSTEM + when 'win32' + s.force_encoding('utf-8') + TkComm.simplelist(s).map { |x| x.tr('\\', '/') } + when 'x11' + s = s.encode('iso8859-1', 'utf-8') + s.force_encoding('utf-8') + TkComm.simplelist(s) + else + TkComm.simplelist(s) + end + end + ], + nil + ] + _setup_subst_table(KEY_TBL, PROC_TBL); + end + + module DND def self.version begin @@ -113,6 +160,14 @@ #end def dnd_bindtarget(type, event, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + klass = case type + when 'text/plain' + DND_SubstText + when 'text/uri-list' + DND_SubstFileList + else + DND_Subst + end if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else @@ -125,11 +180,11 @@ event = tk_event_sequence(event) if prior.kind_of?(Numeric) tk_call('dnd', 'bindtarget', @path, type, event, - install_bind_for_event_class(DND_Subst, cmd, *args), + install_bind_for_event_class(klass, cmd, *args), prior) else tk_call('dnd', 'bindtarget', @path, type, event, - install_bind_for_event_class(DND_Subst, cmd, prior, *args)) + install_bind_for_event_class(klass, cmd, prior, *args)) end self end