File: tk/validation.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Tk#6
extends
  Encoding ( Unknown-Module )
  Tk   
includes
  TkCore   
  module: ValidateConfigure#7
has properties
module method: __def_validcmd / 3 #8
method: __validcmd_call / 4 #17
method: __validation_class_list #31
method: __get_validate_key2class #36
method: __conv_vcmd_on_hash_kv / 1 #46
method: create_self / 1 #63
method: configure / 2 #68
  module: ItemValidateConfigure#110
has properties
module method: __def_validcmd / 3 #111
method: __item_validcmd_call / 5 #120
method: __item_validation_class_list / 1 #134
method: __get_item_validate_key2class / 1 #139
method: __conv_item_vcmd_on_hash_kv / 1 #148
method: itemconfigure / 3 #165
  class: TkValidateCommand#208
extends
  TkComm   
includes
  TkComm   
inherits from
  Object ( Builtin-Module )
has properties
class method: _config_keys #291
method: _initialize_for_cb_class / 3 #296
method: initialize / 2 #334
method: to_eval #338
  class: ValidateArgs#212
inherits from
  CallbackSubst ( TkUtil )
has properties
constant: KEY_TBL #213
constant: PROC_TBL #225
class method: ret_val / 1 #284
  module: TkValidation#343
includes
  ValidateConfigure ( Tk )
has properties
method: __validation_class_list #360
  class: ValidateCmd#346
inherits from
  TkValidateCommand   
  module: Action#347
has properties
constant: Insert #348
constant: Delete #349
constant: Others #350
constant: Focus #351
constant: Forced #352
constant: Textvariable #353
constant: TextVariable #354

Class Hierarchy

Code

   1  #
   2  #  tk/validation.rb - validation support module for entry, spinbox, and so on
   3  #
   4  require 'tk'
   5 
   6  module Tk
   7    module ValidateConfigure
   8      def self.__def_validcmd(scope, klass, keys=nil)
   9        keys = klass._config_keys unless keys
  10        keys.each{|key|
  11          eval("def #{key}(*args, &b)
  12                   __validcmd_call(#{klass.name}, '#{key}', *args, &b)
  13                end", scope)
  14        }
  15      end
  16 
  17      def __validcmd_call(klass, key, *args, &b)
  18        return cget(key) if args.empty? && !b
  19 
  20        cmd = (b)? proc(&b) : args.shift
  21 
  22        if cmd.kind_of?(klass)
  23          configure(key, cmd)
  24        elsif !args.empty?
  25          configure(key, [cmd, args])
  26        else
  27          configure(key, cmd)
  28        end
  29      end
  30 
  31      def __validation_class_list
  32        # maybe need to override
  33        []
  34      end
  35 
  36      def __get_validate_key2class
  37        k2c = {}
  38        __validation_class_list.each{|klass|
  39          klass._config_keys.each{|key|
  40            k2c[key.to_s] = klass
  41          }
  42        }
  43        k2c
  44      end
  45 
  46      def __conv_vcmd_on_hash_kv(keys)
  47        key2class = __get_validate_key2class
  48 
  49        keys = _symbolkey2str(keys)
  50        key2class.each{|key, klass|
  51          if keys[key].kind_of?(Array)
  52            cmd, *args = keys[key]
  53            #keys[key] = klass.new(cmd, args.join(' '))
  54            keys[key] = klass.new(cmd, *args)
  55          # elsif keys[key].kind_of?(Proc) ||  keys[key].kind_of?(Method)
  56          elsif TkComm._callback_entry?(keys[key])
  57            keys[key] = klass.new(keys[key])
  58          end
  59        }
  60        keys
  61      end
  62 
  63      def create_self(keys)
  64        super(__conv_vcmd_on_hash_kv(keys))
  65      end
  66      private :create_self
  67 
  68      def configure(slot, value=TkComm::None)
  69        if slot.kind_of?(Hash)
  70          super(__conv_vcmd_on_hash_kv(slot))
  71        else
  72          super(__conv_vcmd_on_hash_kv(slot=>value))
  73        end
  74        self
  75      end
  76  =begin
  77      def configure(slot, value=TkComm::None)
  78        key2class = __get_validate_key2class
  79 
  80        if slot.kind_of?(Hash)
  81          slot = _symbolkey2str(slot)
  82          key2class.each{|key, klass|
  83            if slot[key].kind_of?(Array)
  84              cmd, *args = slot[key]
  85              slot[key] = klass.new(cmd, args.join(' '))
  86            elsif slot[key].kind_of?(Proc) || slot[key].kind_of?(Method)
  87              slot[key] = klass.new(slot[key])
  88            end
  89          }
  90          super(slot)
  91 
  92        else
  93          slot = slot.to_s
  94          if (klass = key2class[slot])
  95            if value.kind_of?(Array)
  96              cmd, *args = value
  97              value = klass.new(cmd, args.join(' '))
  98            elsif value.kind_of?(Proc) || value.kind_of?(Method)
  99              value = klass.new(value)
 100            end
 101          end
 102          super(slot, value)
 103        end
 104 
 105        self
 106      end
 107  =end
 108    end
 109 
 110    module ItemValidateConfigure
 111      def self.__def_validcmd(scope, klass, keys=nil)
 112        keys = klass._config_keys unless keys
 113        keys.each{|key|
 114          eval("def item_#{key}(id, *args, &b)
 115                   __item_validcmd_call(#{klass.name}, '#{key}', id, *args, &b)
 116                end", scope)
 117        }
 118      end
 119 
 120      def __item_validcmd_call(tagOrId, klass, key, *args, &b)
 121        return itemcget(tagid(tagOrId), key) if args.empty? && !b
 122 
 123        cmd = (b)? proc(&b) : args.shift
 124 
 125        if cmd.kind_of?(klass)
 126          itemconfigure(tagid(tagOrId), key, cmd)
 127        elsif !args.empty?
 128          itemconfigure(tagid(tagOrId), key, [cmd, args])
 129        else
 130          itemconfigure(tagid(tagOrId), key, cmd)
 131        end
 132      end
 133 
 134      def __item_validation_class_list(id)
 135        # maybe need to override
 136        []
 137      end
 138 
 139      def __get_item_validate_key2class(id)
 140        k2c = {}
 141        __item_validation_class_list(id).each{|klass|
 142          klass._config_keys.each{|key|
 143            k2c[key.to_s] = klass
 144          }
 145        }
 146      end
 147 
 148      def __conv_item_vcmd_on_hash_kv(keys)
 149        key2class = __get_item_validate_key2class(tagid(tagOrId))
 150 
 151        keys = _symbolkey2str(keys)
 152        key2class.each{|key, klass|
 153          if keys[key].kind_of?(Array)
 154            cmd, *args = keys[key]
 155            #keys[key] = klass.new(cmd, args.join(' '))
 156            keys[key] = klass.new(cmd, *args)
 157          # elsif keys[key].kind_of?(Proc) || keys[key].kind_of?(Method)
 158          elsif TkComm._callback_entry?(keys[key])
 159            keys[key] = klass.new(keys[key])
 160          end
 161        }
 162        keys
 163      end
 164 
 165      def itemconfigure(tagOrId, slot, value=TkComm::None)
 166        if slot.kind_of?(Hash)
 167          super(__conv_item_vcmd_on_hash_kv(slot))
 168        else
 169          super(__conv_item_vcmd_on_hash_kv(slot=>value))
 170        end
 171        self
 172      end
 173  =begin
 174      def itemconfigure(tagOrId, slot, value=TkComm::None)
 175        key2class = __get_item_validate_key2class(tagid(tagOrId))
 176 
 177        if slot.kind_of?(Hash)
 178          slot = _symbolkey2str(slot)
 179          key2class.each{|key, klass|
 180            if slot[key].kind_of?(Array)
 181              cmd, *args = slot[key]
 182              slot[key] = klass.new(cmd, args.join(' '))
 183            elsif slot[key].kind_of?(Proc) ||  slot[key].kind_of?(Method)
 184              slot[key] = klass.new(slot[key])
 185            end
 186          }
 187          super(slot)
 188 
 189        else
 190          slot = slot.to_s
 191          if (klass = key2class[slot])
 192            if value.kind_of?(Array)
 193              cmd, *args = value
 194              value = klass.new(cmd, args.join(' '))
 195            elsif value.kind_of?(Proc) || value.kind_of?(Method)
 196              value = klass.new(value)
 197            end
 198          end
 199          super(slot, value)
 200        end
 201 
 202        self
 203      end
 204  =end
 205    end
 206  end
 207 
 208  class TkValidateCommand
 209    include TkComm
 210    extend  TkComm
 211 
 212    class ValidateArgs < TkUtil::CallbackSubst
 213      KEY_TBL = [
 214        [ ?d, ?n, :action ], 
 215        [ ?i, ?x, :index ], 
 216        [ ?s, ?e, :current ], 
 217        [ ?v, ?s, :type ], 
 218        [ ?P, ?e, :value ], 
 219        [ ?S, ?e, :string ], 
 220        [ ?V, ?s, :triggered ], 
 221        [ ?W, ?w, :widget ], 
 222        nil
 223      ]
 224 
 225      PROC_TBL = [
 226        [ ?n, TkComm.method(:number) ], 
 227        [ ?s, TkComm.method(:string) ], 
 228        [ ?w, TkComm.method(:window) ], 
 229 
 230        [ ?e, proc{|val|
 231            #enc = Tk.encoding
 232            enc = ((Tk.encoding)? Tk.encoding : Tk.encoding_system)
 233            if enc
 234              Tk.fromUTF8(TkComm::string(val), enc)
 235            else
 236              TkComm::string(val)
 237            end
 238          }
 239        ], 
 240 
 241        [ ?x, proc{|val|
 242            idx = TkComm::number(val)
 243            if idx < 0
 244              nil
 245            else
 246              idx
 247            end
 248          }
 249        ], 
 250 
 251        nil
 252      ]
 253 
 254  =begin
 255      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
 256      KEY_TBL.map!{|inf|
 257        if inf.kind_of?(Array)
 258          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
 259          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
 260        end
 261        inf
 262      }
 263 
 264      PROC_TBL.map!{|inf|
 265        if inf.kind_of?(Array)
 266          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
 267        end
 268        inf
 269      }
 270  =end
 271 
 272      _setup_subst_table(KEY_TBL, PROC_TBL);
 273 
 274      #
 275      # NOTE: The order of parameters which passed to callback procedure is 
 276      #        <extra_arg>, <extra_arg>, ... , <subst_arg>, <subst_arg>, ...
 277      #
 278 
 279      #def self._get_extra_args_tbl
 280      #  # return an array of convert procs
 281      #  []
 282      #end
 283 
 284      def self.ret_val(val)
 285        (val)? '1': '0'
 286      end
 287    end
 288 
 289    ###############################################
 290 
 291    def self._config_keys
 292      # array of config-option key (string or symbol)
 293      ['vcmd', 'validatecommand', 'invcmd', 'invalidcommand']
 294    end
 295 
 296    def _initialize_for_cb_class(klass, cmd = Proc.new, *args)
 297      extra_args_tbl = klass._get_extra_args_tbl
 298 
 299      if args.compact.size > 0
 300        args.map!{|arg| klass._sym2subst(arg)}
 301        args = args.join(' ')
 302        keys = klass._get_subst_key(args)
 303        if cmd.kind_of?(String)
 304          id = cmd
 305        elsif cmd.kind_of?(TkCallbackEntry)
 306          @id = install_cmd(cmd)
 307        else
 308          @id = install_cmd(proc{|*arg|
 309               ex_args = []
 310               extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)}
 311               klass.ret_val(cmd.call(
 312                 *(ex_args.concat(klass.scan_args(keys, arg)))
 313               ))
 314          }) + ' ' + args
 315        end
 316      else
 317        keys, args = klass._get_all_subst_keys
 318        if cmd.kind_of?(String)
 319          id = cmd
 320        elsif cmd.kind_of?(TkCallbackEntry)
 321          @id = install_cmd(cmd)
 322        else
 323          @id = install_cmd(proc{|*arg|
 324               ex_args = []
 325               extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)}
 326               klass.ret_val(cmd.call(
 327                 *(ex_args << klass.new(*klass.scan_args(keys, arg)))
 328               ))
 329          }) + ' ' + args
 330        end
 331      end
 332    end
 333 
 334    def initialize(cmd = Proc.new, *args)
 335      _initialize_for_cb_class(self.class::ValidateArgs, cmd, *args)
 336    end
 337 
 338    def to_eval
 339      @id
 340    end
 341  end
 342 
 343  module TkValidation
 344    include Tk::ValidateConfigure
 345 
 346    class ValidateCmd < TkValidateCommand
 347      module Action
 348        Insert = 1
 349        Delete = 0
 350        Others = -1
 351        Focus  = -1
 352        Forced = -1
 353        Textvariable = -1
 354        TextVariable = -1
 355      end
 356    end
 357 
 358    #####################################
 359 
 360    def __validation_class_list
 361      super() << ValidateCmd
 362    end
 363 
 364    Tk::ValidateConfigure.__def_validcmd(binding, ValidateCmd)
 365 
 366  =begin
 367    def validatecommand(cmd = Proc.new, args = nil)
 368      if cmd.kind_of?(ValidateCmd)
 369        configure('validatecommand', cmd)
 370      elsif args
 371        configure('validatecommand', [cmd, args])
 372      else
 373        configure('validatecommand', cmd)
 374      end
 375    end
 376  =end
 377  #  def validatecommand(*args, &b)
 378  #    __validcmd_call(ValidateCmd, 'validatecommand', *args, &b)
 379  #  end
 380  #  alias vcmd validatecommand
 381 
 382  =begin
 383    def invalidcommand(cmd = Proc.new, args = nil)
 384      if cmd.kind_of?(ValidateCmd)
 385        configure('invalidcommand', cmd)
 386      elsif args
 387        configure('invalidcommand', [cmd, args])
 388      else
 389        configure('invalidcommand', cmd)
 390      end
 391    end
 392  =end
 393  #  def invalidcommand(*args, &b)
 394  #    __validcmd_call(ValidateCmd, 'invalidcommand', *args, &b)
 395  #  end
 396  #  alias invcmd invalidcommand
 397  end