Class: Clevic::Field
- Includes:
- GenericFormat, Gather
- Defined in:
- lib/clevic/field.rb,
lib/clevic/qt/field.rb,
lib/clevic/swing/field.rb
Overview
This defines a field in the UI, and how it hooks up to a field in the DB.
Some attributes are DSL-style accessors, where the value can be set with either an assignment or by passing a parameter. For example:
property :ixnay
will allow
# reader
instance.ixnay
# writer
instance.ixnay = 'nix, baby'
# writer
instance.ixnay 'nix baby'
# store the block for later
instance.ixnay do |*args|
# block stuff here
end
Generally properties are for options that can be passed to the field creation method in ModelBuilder, whereas ruby attributes are for the internal workings.
#– Yes, the blank line before class Field is really necessary. And so it the #– above.
Constant Summary collapse
- AR_FIND_OPTIONS =
The list of properties for ActiveRecord options. There are actually from ActiveRecord::Base.VALID_FIND_OPTIONS, but it’s protected. Each element becomes a property. TODO deprecate these TODO warn or raise if these are used together with a dataset call
[ :conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group, :from, :lock ]
Instance Attribute Summary collapse
-
#attribute ⇒ Object
The attribute on the entity that forms the basis for this field.
-
#delegate ⇒ Object
The UI delegate class for the field.
-
#entity_class ⇒ Object
readonly
The Object Relational Model this field uses to get data from.
-
#model ⇒ Object
The model object (eg TableModel) this field is part of.
Instance Method Summary collapse
-
#alignment ⇒ Object
:attr: One of the alignment specifiers - :left, :centre, :right or :justified.
-
#association? ⇒ Boolean
return true if this is a field for a related table, false otherwise.
-
#attribute_path ⇒ Object
return an array of the various attribute parts TODO not used much.
-
#background_for(entity) ⇒ Object
Called by Clevic::TableModel to get the background color value.
-
#column ⇒ Object
return the result of the attribute + the path.
-
#dataset ⇒ Object
This is the dataset of related objects.
-
#dataset_roller ⇒ Object
TODO Still getting the Builder/Built conflict.
-
#decoration ⇒ Object
:attr: something to do with the icon that Qt displays.
-
#decoration_for(entity) ⇒ Object
TODO Doesn’t do anything useful yet.
-
#default ⇒ Object
:attr: Default value for this field for new records.
-
#display ⇒ Object
:attr: The value to be displayed after being optionally format-ed.
-
#do_edit_format(value) ⇒ Object
Called by Clevic::FieldValuer to format the field to a string value that can be used for editing.
-
#do_format(value) ⇒ Object
Called by Clevic::FieldValuer (and others) to format the display value.
-
#edit_format ⇒ Object
:attr: This is just like format, except that it’s used to format the value just before it’s edited.
-
#filterable? ⇒ Boolean
return true if this field can be used in a filter virtual fields (ie those that don’t exist in this field’s table) can’t be used to filter on.
-
#find_options ⇒ Object
Return a list of find options and their values, but only if the values are not nil.
-
#foreground ⇒ Object
:attr: The foreground and background colors.
-
#foreground_for(entity) ⇒ Object
Called by Clevic::TableModel to get the foreground color value.
-
#format ⇒ Object
:attr: This defines how to format the value returned by :display.
-
#frequency ⇒ Object
:attr: Only for the distinct field type.
-
#id ⇒ Object
:attr: The property used for finding the field, ie by TableModel#field_column.
-
#initialize(attribute, entity_class, options, &block) ⇒ Field
constructor
Create a new Field object that displays the contents of a database field in the UI using the given parameters.
- #inspect ⇒ Object
-
#label ⇒ Object
:attr: The label to be displayed in the column headings.
-
#meta ⇒ Object
Clevic::ModelColumn object.
-
#notify_data_changed ⇒ Object
:attr: Called when the data in this field changes.
-
#read_only ⇒ Object
:attr: Takes a boolean.
-
#read_only? ⇒ Boolean
Return true if the field is read-only.
-
#related_class ⇒ Object
Return the class object of a related class if this is a relational field, otherwise nil.
-
#restricted ⇒ Object
:attr: When this is true, only the values in the combo may be entered.
-
#sample(*args) ⇒ Object
Set or return a sample for the field which can be used to size the UI field widget.
-
#set ⇒ Object
:attr: An Enumerable of allowed values for restricted fields.
-
#set_default_for(entity) ⇒ Object
called when a new entity object is created to set default values specified by the default property.
-
#set_for(entity) ⇒ Object
fetch the permitted set of values for a restricted field.
-
#string_or_color(s_or_c) ⇒ Object
Convert a color name understood by java.awt.Color, or a 0xddccee style string to a java.awt.Color.
- #swing_alignment ⇒ Object
- #to_s ⇒ Object
-
#tooltip ⇒ Object
:attr: Can take a Proc, a string, or a symbol.
-
#tooltip_for(entity) ⇒ Object
Called by Clevic::TableModel to get the tooltip value.
-
#transform_attribute(attribute_value) ⇒ Object
Apply the value of the display property to the given attribute value.
-
#value_for(entity) ⇒ Object
Return the attribute value for the given Object Relational Model instance, or nil if entity is nil.
-
#visible ⇒ Object
:attr: Whether the field is currently visible or not.
Methods included from GenericFormat
#do_generic_format, #is_date_time?
Constructor Details
#initialize(attribute, entity_class, options, &block) ⇒ Field
Create a new Field object that displays the contents of a database field in the UI using the given parameters.
-
attribute is the symbol for the attribute on the entity_class.
-
entity_class is the Object Relational Model which this Field talks to.
-
options is a hash of writable attributes in Field, which can be any of the properties defined in this class.
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/clevic/field.rb', line 242 def initialize( attribute, entity_class, , &block ) # sanity checking unless attribute.is_a?( Symbol ) raise "attribute #{attribute.inspect} must be a symbol" end unless entity_class.ancestors.include?( Clevic.base_entity_class ) raise "#{entity_class} is not a Clevic.base_entity_class: #{Clevic.base_entity_class}" end # TODO this comes down to method_defined, really unless entity_class.has_attribute?( attribute ) or entity_class.method_defined?( attribute ) raise <<EOF #{attribute.inspect} not found in #{entity_class.name}. Possibilities are: #{entity_class.attribute_names.inspect} EOF end # instance variables @attribute = attribute # default to attribute, can be overwritten later @id = attribute @entity_class = entity_class @visible = true # initialise @value_cache = {} # handle options gather( , &block ) # set various sensible defaults. They're not lazy accessors because # they might stay nil, and we don't want to keep evaluating them. default_label! default_format! default_edit_format! default_alignment! default_display! if association? end |
Instance Attribute Details
#attribute ⇒ Object
The attribute on the entity that forms the basis for this field. Accessing the returned attribute (using send, or the [] method on an entity) will give a simple value, or another entity in the case of relational fields. In other words, this is not the same as the name of the field in the DB, which would normally have an _id suffix for relationships.
232 233 234 |
# File 'lib/clevic/field.rb', line 232 def attribute @attribute end |
#delegate ⇒ Object
The UI delegate class for the field. The delegate class knows how to create a UI for this field using whatever GUI toolkit is selected
225 226 227 |
# File 'lib/clevic/field.rb', line 225 def delegate @delegate end |
#entity_class ⇒ Object (readonly)
The Object Relational Model this field uses to get data from.
235 236 237 |
# File 'lib/clevic/field.rb', line 235 def entity_class @entity_class end |
#model ⇒ Object
The model object (eg TableModel) this field is part of. Set to TableModel by ModelBuilder#build
221 222 223 |
# File 'lib/clevic/field.rb', line 221 def model @model end |
Instance Method Details
#alignment ⇒ Object
:attr: One of the alignment specifiers - :left, :centre, :right or :justified. Defaults to right for numeric fields, centre for boolean, and left for other values.
76 |
# File 'lib/clevic/field.rb', line 76 property :alignment |
#association? ⇒ Boolean
return true if this is a field for a related table, false otherwise.
315 316 317 |
# File 'lib/clevic/field.rb', line 315 def association? .andand.association? end |
#attribute_path ⇒ Object
return an array of the various attribute parts TODO not used much. Deprecate and remove.
345 346 347 348 349 |
# File 'lib/clevic/field.rb', line 345 def attribute_path pieces = [ attribute.to_s ] pieces.concat( display.to_s.split( '.' ) ) unless display.is_a? Proc pieces.map{|x| x.to_sym} end |
#background_for(entity) ⇒ Object
Called by Clevic::TableModel to get the background color value
409 410 411 |
# File 'lib/clevic/field.rb', line 409 def background_for( entity ) cache_value_for( :background, entity ) {|x| string_or_color(x)} end |
#column ⇒ Object
return the result of the attribute + the path
332 333 334 |
# File 'lib/clevic/field.rb', line 332 def column [attribute.to_s, path].compact.join('.') end |
#dataset ⇒ Object
This is the dataset of related objects. Called in configuration for a field that works with a relationship.
dataset.filter( :blah => 'etc' ).order( :interesting_field )
189 190 191 |
# File 'lib/clevic/field.rb', line 189 def dataset dataset_roller end |
#dataset_roller ⇒ Object
TODO Still getting the Builder/Built conflict
194 195 196 197 |
# File 'lib/clevic/field.rb', line 194 def dataset_roller # related class if it's an association, entity_class otherwise @dataset_roller ||= DatasetRoller.new( ( association? ? : entity_class ).dataset ) end |
#decoration ⇒ Object
:attr: something to do with the icon that Qt displays. Not implemented yet.
81 |
# File 'lib/clevic/field.rb', line 81 property :decoration |
#decoration_for(entity) ⇒ Object
TODO Doesn’t do anything useful yet.
399 400 401 |
# File 'lib/clevic/field.rb', line 399 def decoration_for( entity ) nil end |
#default ⇒ Object
:attr: Default value for this field for new records. Can be a Proc or a value. A value will just be set, a proc will be executed with the entity as a parameter.
169 |
# File 'lib/clevic/field.rb', line 169 property :default |
#display ⇒ Object
:attr: The value to be displayed after being optionally format-ed
Takes a String, a Symbol, or a Proc.
A String will be a dot-separated path of attributes starting on the object returned by attribute. Paths longer than 1 element haven’t been tested much.
A Symbol refers to a method to be called on the current entity
A Proc will be passed the current entity. This can be used to display ‘virtual’ fields from related tables, or calculated fields.
Defaults to nil, in other words the value of the attribute for this field.
64 |
# File 'lib/clevic/field.rb', line 64 property :display |
#do_edit_format(value) ⇒ Object
Called by Clevic::FieldValuer to format the field to a string value that can be used for editing.
363 364 365 |
# File 'lib/clevic/field.rb', line 363 def do_edit_format( value ) do_generic_format( edit_format, value ) end |
#do_format(value) ⇒ Object
Called by Clevic::FieldValuer (and others) to format the display value.
357 358 359 |
# File 'lib/clevic/field.rb', line 357 def do_format( value ) do_generic_format( format, value ) end |
#edit_format ⇒ Object
:attr: This is just like format, except that it’s used to format the value just before it’s edited. A good use of this is to display dates with a 2-digit year but edit them with a 4 digit year. Defaults to a sensible value for some fields, for others it will default to the value of :format.
98 |
# File 'lib/clevic/field.rb', line 98 property :edit_format |
#filterable? ⇒ Boolean
return true if this field can be used in a filter virtual fields (ie those that don’t exist in this field’s table) can’t be used to filter on.
327 328 329 |
# File 'lib/clevic/field.rb', line 327 def filterable? !.nil? end |
#find_options ⇒ Object
Return a list of find options and their values, but only if the values are not nil
209 210 211 212 213 214 215 216 217 |
# File 'lib/clevic/field.rb', line 209 def AR_FIND_OPTIONS.inject(Hash.new) do |ha,x| option_value = self.send(x) unless option_value.nil? ha[x] = option_value end ha end end |
#foreground ⇒ Object
:attr: The foreground and background colors. Can take a Proc, a string, or a symbol.
-
A Proc is called with an entity
-
A String is treated as a constant which may be one of the string constants understood by Qt::Color
-
A symbol is treated as a method to be call on an entity
The result can be a Qt::Color, or one of the strings in www.w3.org/TR/SVG/types.html#ColorKeywords.
130 |
# File 'lib/clevic/field.rb', line 130 property :foreground, :background |
#foreground_for(entity) ⇒ Object
Called by Clevic::TableModel to get the foreground color value
404 405 406 |
# File 'lib/clevic/field.rb', line 404 def foreground_for( entity ) cache_value_for( :foreground, entity ) {|x| string_or_color(x)} end |
#format ⇒ Object
:attr: This defines how to format the value returned by :display. It takes a string or a Proc. Generally the string is something that can be understood by strftime (for time and date fields) or understood by % (for everything else). It can also be a Proc that has one parameter - the current entity. There are sensible defaults for common field types.
90 |
# File 'lib/clevic/field.rb', line 90 property :format |
#frequency ⇒ Object
:attr: Only for the distinct field type. The values will be sorted either with the most used values first (:frequency => true) or in alphabetical order (:description => true). FIXME re-implement this with Dataset
162 |
# File 'lib/clevic/field.rb', line 162 property :frequency, :description |
#id ⇒ Object
:attr: The property used for finding the field, ie by TableModel#field_column. Defaults to the attribute. If there are several display fields based on one db field, their attribute will be the same, but their id must be different.
176 |
# File 'lib/clevic/field.rb', line 176 property :id |
#inspect ⇒ Object
450 451 452 |
# File 'lib/clevic/field.rb', line 450 def inspect "#<Clevic::Field #{entity_class} id=#{id} attribute=#{attribute}>" end |
#label ⇒ Object
:attr: The label to be displayed in the column headings. Defaults to the humanised field name.
69 |
# File 'lib/clevic/field.rb', line 69 property :label |
#meta ⇒ Object
Clevic::ModelColumn object
320 321 322 |
# File 'lib/clevic/field.rb', line 320 def entity_class.[attribute] || ModelColumn.new( attribute, {} ) end |
#notify_data_changed ⇒ Object
:attr: Called when the data in this field changes. Either a proc( clevic_view, table_view, model_index ) or a symbol for a method( view, model_index ) on the Clevic::View object.
183 |
# File 'lib/clevic/field.rb', line 183 property :notify_data_changed |
#read_only ⇒ Object
:attr: Takes a boolean. Set the field to read-only.
118 |
# File 'lib/clevic/field.rb', line 118 property :read_only |
#read_only? ⇒ Boolean
Return true if the field is read-only. Defaults to false.
352 353 354 |
# File 'lib/clevic/field.rb', line 352 def read_only? @read_only || false end |
#related_class ⇒ Object
Return the class object of a related class if this is a relational field, otherwise nil.
338 339 340 341 |
# File 'lib/clevic/field.rb', line 338 def return nil unless association? && entity_class..has_key?( attribute ) @related_class ||= eval( entity_class.[attribute].class_name || attribute.to_s.classify ) end |
#restricted ⇒ Object
:attr: When this is true, only the values in the combo may be entered. Otherwise the text-entry part of the combo can be used to enter non-listed values. Default is true if a set is explicitly specified. Otherwise depends on the field type.
154 |
# File 'lib/clevic/field.rb', line 154 property :restricted |
#sample(*args) ⇒ Object
Set or return a sample for the field which can be used to size the UI field widget. If this is called as an accessor, and there is no value yet, a Clevic::Sampler instance is created to compute a sample.
113 |
# File 'lib/clevic/field.rb', line 113 property :sample |
#set ⇒ Object
:attr: An Enumerable of allowed values for restricted fields. If each yields two values (like it does for a Hash), the first will be stored in the db, and the second displayed in the UI. If it’s a proc, that must return an Enumerable as above.
146 |
# File 'lib/clevic/field.rb', line 146 property :set |
#set_default_for(entity) ⇒ Object
called when a new entity object is created to set default values specified by the default property.
415 416 417 418 419 420 421 422 423 424 425 426 427 428 |
# File 'lib/clevic/field.rb', line 415 def set_default_for( entity ) begin entity[attribute] = case default when String default when Proc default.call( entity ) end rescue Exception => e puts e. puts e.backtrace end end |
#set_for(entity) ⇒ Object
fetch the permitted set of values for a restricted field.
431 432 433 434 435 436 437 438 439 440 441 442 443 444 |
# File 'lib/clevic/field.rb', line 431 def set_for( entity ) case set when Proc # the Proc should return an enumerable set.call( entity ) when Symbol entity.send( set ) else # assume its an Enumerable set end end |
#string_or_color(s_or_c) ⇒ Object
Convert a color name understood by java.awt.Color, or a 0xddccee style string to a java.awt.Color
6 7 8 9 10 11 12 13 14 15 |
# File 'lib/clevic/qt/field.rb', line 6 def string_or_color( s_or_c ) case s_or_c when NilClass nil when Qt::Color s_or_c else Qt::Color.new( s_or_c.to_s ) end end |
#swing_alignment ⇒ Object
25 26 27 28 29 30 31 32 |
# File 'lib/clevic/swing/field.rb', line 25 def swing_alignment case alignment when :left; javax.swing.SwingConstants::LEFT when :right; javax.swing.SwingConstants::RIGHT when :centre, :center; javax.swing.SwingConstants::CENTER else javax.swing.SwingConstants::LEADING end end |
#to_s ⇒ Object
446 447 448 |
# File 'lib/clevic/field.rb', line 446 def to_s "#{entity_class}.#{id}" end |
#tooltip ⇒ Object
:attr: Can take a Proc, a string, or a symbol.
-
A Proc is called with an entity
-
A String is treated as a constant
-
A symbol is treated as a method to be call on an entity
138 |
# File 'lib/clevic/field.rb', line 138 property :tooltip |
#tooltip_for(entity) ⇒ Object
Called by Clevic::TableModel to get the tooltip value
394 395 396 |
# File 'lib/clevic/field.rb', line 394 def tooltip_for( entity ) cache_value_for( :tooltip, entity ) end |
#transform_attribute(attribute_value) ⇒ Object
Apply the value of the display property to the given attribute value. Otherwise just return the attribute_value itself.
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/clevic/field.rb', line 297 def transform_attribute( attribute_value ) return nil if attribute_value.nil? case display when Proc display.call( attribute_value ) when String attribute_value.evaluate_path( display.split( '.' ) ) when Symbol attribute_value.send( display ) else attribute_value end end |
#value_for(entity) ⇒ Object
Return the attribute value for the given Object Relational Model instance, or nil if entity is nil. Will call transform_attribute.
284 285 286 287 288 289 290 291 292 |
# File 'lib/clevic/field.rb', line 284 def value_for( entity ) begin return nil if entity.nil? transform_attribute( entity.send( attribute ) ) rescue Exception => e puts "error for #{entity}.#{entity.send( attribute ).inspect} in value_for: #{e.}" puts e.backtrace end end |
#visible ⇒ Object
:attr: Whether the field is currently visible or not.
103 |
# File 'lib/clevic/field.rb', line 103 property :visible |