class HinnerFileDialog
Constants
- SAVE_FILE_MODE
- SELECT_DIR_MODE
- SELECT_FILE_MODE
Public Class Methods
new(mode=SELECT_FILE_MODE, must_exist=nil, label=nil, side='top',args=nil)
click to toggle source
Calls superclass method
HinnerDialog::new
# File lib/a-tkcommons.rb, line 3408 def initialize(mode=SELECT_FILE_MODE, must_exist=nil, label=nil, side='top',args=nil) super(side, args) @mode = mode if must_exist.nil? must_exist = mode != SAVE_FILE_MODE end @must_exist = must_exist @label = label build_gui @closed = false end
Public Instance Methods
build_gui()
click to toggle source
# File lib/a-tkcommons.rb, line 3420 def build_gui @font = Arcadia.conf('edit.font') @font_bold = "#{Arcadia.conf('edit.font')} bold" @font_metrics = TkFont.new(@font).metrics @font_metrics_bold = TkFont.new(@font_bold).metrics if !@label.nil? Arcadia.wf.label(self, 'text' => @label).pack('side' =>'left') end @dir_text = TkText.new(self, Arcadia.style('text').update({"height"=>'1',"highlightcolor"=>Arcadia.conf('panel.background'), "bg"=>Arcadia.conf('panel.background')})).pack('side' =>'left','padx'=>5, 'pady'=>5, 'fill'=>'x', 'expand'=>'1') #{"bg"=>'white', "height"=>'1', "borderwidth"=>0, 'font'=>@font} @dir_text.bind_append("Enter", proc{ @dir_text.set_insert("end")}) #@dir_text.tag_configure("entry",'foreground'=> "red",'borderwidth'=>0, 'relief'=>'flat', 'underline'=>true) @tag_file_exist = "file_exist" @dir_text.tag_configure(@tag_file_exist,'background'=> Arcadia.conf("hightlight.selected.background"), 'borderwidth'=>0, 'relief'=>'flat', 'underline'=>true) @tag_selected = "link_selected" @dir_text.tag_configure(@tag_selected,'borderwidth'=>0, 'relief'=>'flat', 'underline'=>true) @dir_text.tag_bind(@tag_selected,"ButtonRelease-1", proc{ self.release Tk.callback_break } ) @dir_text.tag_bind(@tag_selected,"Enter", proc{@dir_text.configure('cursor'=> 'hand2')}) @dir_text.tag_bind(@tag_selected,"Leave", proc{@dir_text.configure('cursor'=> @cursor)}) _self=self @dir_text.bind_append('KeyPress', "%K"){|_keysym| case _keysym when 'Escape','Tab' i1 = @dir_text.index("insert") raise_candidates(i1, @dir_text.get("#{i1} linestart", i1)) when "Return" if (@mode == SELECT_FILE_MODE || @mode == SAVE_FILE_MODE) && @must_exist str_file = @dir_text.get('1.0','end') if str_file && str_file.length > 0 && File.exists?(str_file.strip) && File.ftype(str_file.strip) == 'file' _self.release end Tk.callback_break elsif @mode == SELECT_DIR_MODE && @must_exist str_file = @dir_text.get('1.0','end') if str_file && str_file.length > 0 && File.exists?(str_file.strip) && File.ftype(str_file.strip) == 'directory' _self.release end Tk.callback_break else _self.release end end } @dir_text.bind_append('KeyRelease', "%K"){|_keysym| case _keysym when 'Escape','Tab', "Return" else @dir_text.tag_remove(@tag_selected,'1.0','end') i1 = @dir_text.index("insert - 1 chars wordstart") while @dir_text.get("#{i1} -1 chars",i1) != File::SEPARATOR && @dir_text.get("#{i1} - 1 chars",i1) != "" i1 = @dir_text.index("#{i1} - 1 chars") end i2 = @dir_text.index("insert") @dir_text.tag_add(@tag_selected ,i1,i2) if @mode == SAVE_FILE_MODE if File.exists?(@dir_text.get('1.0',i2)) @dir_text.tag_add(@tag_file_exist ,i1,i2) @dir_text.tag_add(@tag_selected ,i1,i2) if @mode == SELECT_FILE_MODE && File.ftype(@dir_text.get('1.0',i2)) == 'file' @dir_text.tag_add(@tag_selected ,i1,i2) if @mode == SELECT_DIR_MODE && File.ftype(@dir_text.get('1.0',i2)) == 'directory' else @dir_text.tag_remove(@tag_file_exist,'1.0','end') end end } @dir_text.bind_append("Control-KeyPress", "%K"){|_keysym| case _keysym when 'd' _self.close Tk.callback_break end } #@select_button = Tk::BWidget::Button.new(self, Arcadia.style('toolbarbutton')){ @select_button = Arcadia.wf.toolbutton(self){ command proc{_self.close} image Arcadia.image_res(CLOSE_FRAME_GIF) }.pack('side' =>'right','padx'=>5, 'pady'=>0) end
close()
click to toggle source
# File lib/a-tkcommons.rb, line 3520 def close @closed=true self.release destroy end
dir(_dir)
click to toggle source
# File lib/a-tkcommons.rb, line 3516 def dir(_dir) file(_dir) end
file(_dir)
click to toggle source
# File lib/a-tkcommons.rb, line 3506 def file(_dir) set_dir(_dir) show_modal(false) if @closed == false file_selected = @dir_text.get("0.1","end").strip destroy file_selected end end
last_candidate_is_dir?(_name)
click to toggle source
# File lib/a-tkcommons.rb, line 3609 def last_candidate_is_dir?(_name) @last_candidates_dir && @last_candidates_dir.include?(_name) end
last_candidate_is_file?(_name)
click to toggle source
# File lib/a-tkcommons.rb, line 3605 def last_candidate_is_file?(_name) @last_candidates_file && @last_candidates_file.include?(_name) end
load_from_dir(_dir)
click to toggle source
# File lib/a-tkcommons.rb, line 3844 def load_from_dir(_dir) childrens = Dir.entries(_dir) childrens_dir = Array.new childrens_file = Array.new childrens.sort.each{|c| if c != '.' && c != '..' child = File.join(_dir,c) fty = File.ftype(child) if fty == "file" childrens_file << c #childrens_file << child elsif fty == "directory" #childrens_dir << child childrens_dir << c end end } return childrens_dir,childrens_file end
raise_candidates(_inx, _dir)
click to toggle source
# File lib/a-tkcommons.rb, line 3577 def raise_candidates(_inx, _dir) if _dir[-1..-1] != File::SEPARATOR && _dir !=nil && _dir.length > 0 len = _dir.split(File::SEPARATOR)[-1].length+1 _dir = _dir[0..-len] _inx = "#{_inx} - #{len-1} chars" end _dir=Dir.pwd if !File.exists?(_dir) @dir_text.set_insert("end") dirs_and_files=load_from_dir(_dir) if dirs_and_files[0].length + dirs_and_files[1].length == 1 if dirs_and_files[0].length == 1 one = "#{_dir}#{dirs_and_files[0][0]}" else one = "#{_dir}#{dirs_and_files[1][0]}" end set_dir(one) elsif dirs_and_files[0].length + dirs_and_files[1].length == 0 # do not raise else if @mode == SELECT_DIR_MODE raise_dir(_inx, _dir, dirs_and_files[0], []) else raise_dir(_inx, _dir, dirs_and_files[0], dirs_and_files[1]) end end Tk.callback_break end
raise_dir(_index, _dir, _candidates_dir, _candidates_file=nil)
click to toggle source
# File lib/a-tkcommons.rb, line 3613 def raise_dir(_index, _dir, _candidates_dir, _candidates_file=nil) @raised_listbox_frame.destroy if @raised_listbox_frame != nil @last_candidates_dir = _candidates_dir @last_candidates_file = _candidates_file _index_now = @dir_text.index('insert') _index_for_raise = @dir_text.index("#{_index} wordstart") _candidates = [] _candidates.concat(_candidates_dir) if _candidates_dir _candidates.concat(_candidates_file) if _candidates_file if _candidates.length >= 1 _rx, _ry, _width, heigth = @dir_text.bbox(_index_for_raise); _x = _rx + TkWinfo.rootx(@dir_text) _y = _ry + TkWinfo.rooty(@dir_text) + @font_metrics[2][1] _xroot = _x _yroot = _y max_width = TkWinfo.screenwidth(Arcadia.layout.root) - _x @raised_listbox_frame = TkFrame.new(Arcadia.layout.root, { :padx=>"1", :pady=>"1", :background=> "yellow" }) @raised_listbox = TkTextListBox.new(@raised_listbox_frame, { :takefocus=>true}.update(Arcadia.style('listbox'))) @raised_listbox.tag_configure('file','foreground'=> Arcadia.conf('hightlight.link.foreground'),'borderwidth'=>0, 'relief'=>'flat') _char_height = @font_metrics[2][1] _width = 0 _docs_entries = Hash.new _item_num = 0 _select_value = proc{ if @raised_listbox.selected_line && @raised_listbox.selected_line.strip.length>0 #_value = @raised_listbox.selected_line.split('-')[0].strip seldir = File.join(_dir,@raised_listbox.selected_line) set_dir(seldir) @raised_listbox_frame.grab("release") @raised_listbox_frame.destroy end } _update_list = proc{|_in| _in.strip! @raised_listbox.clear _length = 0 _candidates.each{|value| _doc = value.strip _class, _key, _arity = _doc.split('#') if _key && _arity args = arity_to_str(_arity.to_i) if args.length > 0 _key = "#{_key}(#{args})" end end if _key && _class && _key.strip.length > 0 && _class.strip.length > 0 _item = "#{_key.strip} #{TkTextListBox::SEP} #{_class.strip}" elsif _key && _key.strip.length > 0 _item = "#{_key.strip}" else _key = "#{_doc.strip}" _item = "#{_doc.strip}" end array_include = proc{|_a, _str, _asterisk_first_char| ret = true str = _str _a.each_with_index{|x, j| next if x.length == 0 if j == 0 && !_asterisk_first_char ret = ret && str[0..x.length-1] == x else ret = ret && str.include?(x) end if ret i = str.index(x) str = str[i+x.length..-1] else break end } ret } if _in.nil? || _in.strip.length == 0 || _item[0.._in.length-1] == _in || (_in.include?('*') && array_include.call(_in.split("*"), _item, _in[0..1]=='*')) # (_in[0..0] == '*' && _item.include?(_in[1..-1])) _docs_entries[_item]= _doc # @raised_listbox.insert('end', _item) if last_candidate_is_dir?(_item) @raised_listbox.add(_item, 'file') else @raised_listbox.add(_item) end _temp_length = _item.length _length = _temp_length if _temp_length > _length _item_num = _item_num+1 _last_valid_key = _key end } _width = _length*8 if @raised_listbox.length == 0 @raised_listbox.grab("release") @raised_listbox_frame.destroy @dir_text.focus Tk.callback_break #Tk.event_generate(@raised_listbox, "KeyPress" , :keysym=>"Escape") if TkWinfo.mapped?(@raised_listbox) else @raised_listbox.select(1) Tk.event_generate(@raised_listbox, "1") if TkWinfo.mapped?(@raised_listbox) end } get_filter = proc{ filter = "" if @dir_text.get("insert -1 chars", "insert") != File::SEPARATOR file_str = @dir_text.get("insert linestart", "insert") parts = file_str.split(File::SEPARATOR) if _dir == File::SEPARATOR original_parts = [""] else original_parts = _dir.split(File::SEPARATOR) end if parts && parts.length == original_parts.length + 1 filter = parts[-1] end end filter = "" if filter.nil? filter } #filter = @dir_text.get("insert -1 chars wordstart", "insert") @raised_listbox.bind_append('KeyPress', "%K %A"){|_keysym, _char| is_list_for_update = false case _keysym when 'a'..'z','A'..'Z','0'..'9' @dir_text.insert('end', _keysym) @dir_text.see("end") is_list_for_update = true when 'minus' @dir_text.insert('end', _char) @dir_text.see("end") is_list_for_update = true when 'period' @dir_text.insert('end', '.') @dir_text.see("end") is_list_for_update = true when 'BackSpace' if @dir_text.get("insert -1 chars", "insert") != File::SEPARATOR @dir_text.delete('end -2 chars','end') end is_list_for_update = true when 'Escape' @raised_listbox.grab("release") @raised_listbox_frame.destroy @dir_text.focus Tk.callback_break when "Next","Prior" when "Down","Up" Tk.callback_break else Tk.callback_break end _update_list.call(get_filter.call) if is_list_for_update @raised_listbox.focus Tk.callback_break if !["Next","Prior"].include?(_keysym) } @raised_listbox.bind_append('Shift-KeyPress', "%K %A"){|_keysym, _char| is_list_for_update = false case _keysym when 'asterisk','underscore' @dir_text.insert('end', _char) @dir_text.see("end") is_list_for_update = true when 'a'..'z','A'..'Z' @dir_text.insert('end', _keysym) @dir_text.see("end") is_list_for_update = true end _update_list.call(get_filter.call) if is_list_for_update @raised_listbox.focus Tk.callback_break } @raised_listbox.bind_append('KeyRelease', "%K"){|_keysym| case _keysym when 'Return' _select_value.call end } _update_list.call(get_filter.call) if @raised_listbox.length == 1 _select_value.call else _width = _width + 30 _width = max_width if _width > max_width _height = 15*_char_height @raised_listbox_frame.place('x'=>_x,'y'=>_ry, 'width'=>_width, 'height'=>_height) @raised_listbox.extend(TkScrollableWidget).show(0,0) @raised_listbox.place('x'=>0,'y'=>0, 'relwidth'=>1, 'relheight'=>1) @raised_listbox.focus @raised_listbox.select(1) Tk.update @raised_listbox_frame.grab("set") @raised_listbox.bind_append("Double-ButtonPress-1", proc{|x,y| _select_value.call Tk.callback_break }, "%x %y") end elsif _candidates.length == 1 && _candidates[0].length>0 @dir_text.set_dir(_candidates[0]) end end
set_dir(_dir)
click to toggle source
# File lib/a-tkcommons.rb, line 3526 def set_dir(_dir) _dir=Dir.pwd if !File.exists?(_dir) #load_from_dir(_dir) @dir_text.state("normal") @dir_text.delete("0.1","end") @cursor = @dir_text.cget('cursor') dir_seg = _dir.split(File::SEPARATOR) incr_dir = "" get_dir = proc{|i| res = "" 0.upto(i){|j| if res == File::SEPARATOR res=res+dir_seg[j] elsif res.length == 0 && dir_seg[j].length == 0 res=File::SEPARATOR+dir_seg[j] elsif res.length == 0 && dir_seg[j].length > 0 res=dir_seg[j] else res=res+File::SEPARATOR+dir_seg[j] end } is_dir = File.ftype(res) == "directory" res=res+File::SEPARATOR if is_dir && res[-1..-1]!=File::SEPARATOR res } dir_seg.each_with_index{|seg,i| tag_name = "link#{i}" @dir_text.tag_configure(tag_name,'foreground'=> Arcadia.conf('hightlight.link.foreground'),'borderwidth'=>0, 'relief'=>'flat', 'underline'=>true) dir = get_dir.call(i) if File.ftype(dir) == "directory" @dir_text.insert("end", seg, tag_name) @dir_text.insert("end", "#{File::SEPARATOR}") @dir_text.tag_bind(tag_name,"ButtonRelease-1", proc{ inx = @dir_text.index("insert wordend +1 chars") @dir_text.set_insert("end") raise_candidates(inx, dir) } ) @dir_text.tag_bind(tag_name,"Enter", proc{@dir_text.configure('cursor'=> 'hand2')}) @dir_text.tag_bind(tag_name,"Leave", proc{@dir_text.configure('cursor'=> @cursor)}) else @dir_text.insert("end", seg, @tag_selected) end } @dir_text.focus @dir_text.set_insert("end") @dir_text.see("end") end