clevic 0.13.0.b9 → 0.13.0.b10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/History.txt +3 -0
  2. data/lib/clevic/action_builder.rb +16 -16
  3. data/lib/clevic/ar_methods.rb +22 -22
  4. data/lib/clevic/attribute_list.rb +5 -5
  5. data/lib/clevic/cache_table.rb +18 -18
  6. data/lib/clevic/dataset_roller.rb +3 -3
  7. data/lib/clevic/default_view.rb +4 -4
  8. data/lib/clevic/delegate.rb +8 -8
  9. data/lib/clevic/delegates/combo_delegate.rb +22 -22
  10. data/lib/clevic/delegates/distinct_delegate.rb +5 -5
  11. data/lib/clevic/delegates/relational_delegate.rb +6 -6
  12. data/lib/clevic/delegates/set_delegate.rb +3 -3
  13. data/lib/clevic/dirty.rb +1 -1
  14. data/lib/clevic/emitter.rb +3 -3
  15. data/lib/clevic/extensions.rb +4 -4
  16. data/lib/clevic/field.rb +68 -68
  17. data/lib/clevic/field_valuer.rb +26 -26
  18. data/lib/clevic/filter_command.rb +6 -6
  19. data/lib/clevic/framework.rb +3 -3
  20. data/lib/clevic/generic_format.rb +2 -2
  21. data/lib/clevic/many_field.rb +3 -3
  22. data/lib/clevic/model_builder.rb +88 -84
  23. data/lib/clevic/model_column.rb +13 -13
  24. data/lib/clevic/ordered_dataset.rb +7 -7
  25. data/lib/clevic/qt/action_builder.rb +3 -3
  26. data/lib/clevic/qt/browser.rb +28 -28
  27. data/lib/clevic/qt/clipboard.rb +5 -5
  28. data/lib/clevic/qt/combo_delegate.rb +12 -12
  29. data/lib/clevic/qt/distinct_delegate.rb +1 -1
  30. data/lib/clevic/qt/extensions.rb +4 -4
  31. data/lib/clevic/qt/qt_combo_box.rb +7 -7
  32. data/lib/clevic/qt/relational_delegate.rb +5 -5
  33. data/lib/clevic/qt/search_dialog.rb +15 -15
  34. data/lib/clevic/qt/simplest_delegate.rb +2 -2
  35. data/lib/clevic/qt/table_model.rb +46 -46
  36. data/lib/clevic/qt/table_view.rb +48 -48
  37. data/lib/clevic/qt/text_delegate.rb +9 -9
  38. data/lib/clevic/rails_models_loaders.rb +3 -3
  39. data/lib/clevic/record.rb +8 -8
  40. data/lib/clevic/sampler.rb +6 -6
  41. data/lib/clevic/sequel_ar_adapter.rb +22 -22
  42. data/lib/clevic/sequel_clevic.rb +10 -10
  43. data/lib/clevic/sequel_meta.rb +5 -5
  44. data/lib/clevic/sequel_naked.rb +4 -4
  45. data/lib/clevic/swing/action.rb +20 -20
  46. data/lib/clevic/swing/action_builder.rb +2 -2
  47. data/lib/clevic/swing/boolean_delegate.rb +3 -3
  48. data/lib/clevic/swing/browser.rb +37 -37
  49. data/lib/clevic/swing/cell_editor.rb +13 -13
  50. data/lib/clevic/swing/cell_renderer.rb +7 -7
  51. data/lib/clevic/swing/clipboard.rb +19 -19
  52. data/lib/clevic/swing/combo_delegate.rb +26 -26
  53. data/lib/clevic/swing/confirm_dialog.rb +7 -7
  54. data/lib/clevic/swing/delegate.rb +4 -4
  55. data/lib/clevic/swing/extensions.rb +24 -24
  56. data/lib/clevic/swing/field.rb +1 -1
  57. data/lib/clevic/swing/relational_delegate.rb +2 -2
  58. data/lib/clevic/swing/row_header.rb +32 -32
  59. data/lib/clevic/swing/search_dialog.rb +31 -31
  60. data/lib/clevic/swing/selection_model.rb +12 -12
  61. data/lib/clevic/swing/swing_table_index.rb +6 -6
  62. data/lib/clevic/swing/table_model.rb +30 -30
  63. data/lib/clevic/swing/table_view.rb +54 -54
  64. data/lib/clevic/swing/table_view_focus.rb +4 -4
  65. data/lib/clevic/swing/tag_delegate.rb +14 -14
  66. data/lib/clevic/swing/tag_editor.rb +4 -4
  67. data/lib/clevic/swing/text_area_delegate.rb +6 -6
  68. data/lib/clevic/swing/text_delegate.rb +4 -4
  69. data/lib/clevic/table_index.rb +14 -14
  70. data/lib/clevic/table_model.rb +30 -30
  71. data/lib/clevic/table_searcher.rb +19 -19
  72. data/lib/clevic/table_view.rb +92 -92
  73. data/lib/clevic/table_view_paste.rb +19 -19
  74. data/lib/clevic/version.rb +1 -1
  75. data/lib/clevic/view.rb +22 -22
  76. data/models/accounts_models.rb +10 -10
  77. data/models/examples.rb +2 -2
  78. data/models/times_models.rb +32 -32
  79. data/models/values_models.rb +2 -2
  80. data/test/test_cache_table.rb +15 -15
  81. data/test/test_helper.rb +7 -7
  82. data/test/test_model_index_extensions.rb +6 -6
  83. data/test/test_table_model.rb +6 -6
  84. data/test/test_table_searcher.rb +25 -25
  85. metadata +33 -35
@@ -11,37 +11,37 @@ class Delegate
11
11
  super()
12
12
  @field = field
13
13
  end
14
-
14
+
15
15
  # This is the ORM entity instance for which this delegate
16
16
  # is editing a single field. It needs to be the entire entity
17
17
  # so we can set the edited field value on it.
18
18
  attr_accessor :entity
19
-
19
+
20
20
  # The parent widget of this delegate / this delegate's widget
21
21
  attr_accessor :parent
22
-
22
+
23
23
  # the Clevic::Field instance which this delegate edits.
24
24
  attr_reader :field
25
-
25
+
26
26
  def attribute
27
27
  field.attribute
28
28
  end
29
-
29
+
30
30
  def entity_class
31
31
  field.entity_class
32
32
  end
33
-
33
+
34
34
  # assume this is not a combo delegate. That will come later.
35
35
  def is_combo?
36
36
  false
37
37
  end
38
-
38
+
39
39
  # change the visual state of the editor to the biggest / most
40
40
  # space-consuming it can be. This grew out of combo boxes having
41
41
  # a drop-down that can show or hide.
42
42
  def full_edit
43
43
  end
44
-
44
+
45
45
  # change the visual state of the editor to the smallest / least
46
46
  # space-consuming it can be. This grew out of combo boxes having
47
47
  # a drop-down that can show or hide.
@@ -12,23 +12,23 @@ class ComboDelegate
12
12
  # in some cases.
13
13
  # if editor is a combo it must support no_insert=( bool )
14
14
  attr_reader :editor
15
-
15
+
16
16
  # Return a string to be shown to the user.
17
17
  # model_value is an item stored in the combo box model.
18
18
  def display_for( model_value )
19
19
  field.transform_attribute( model_value )
20
20
  end
21
-
21
+
22
22
  # Some GUIs (Qt) can just set this. Swing can't.
23
23
  def configure_prefix
24
24
  end
25
-
25
+
26
26
  # TODO kinda redundant because all combos must be editable
27
27
  # to support prefix matching
28
28
  def configure_editable
29
29
  editor.editable = true
30
30
  end
31
-
31
+
32
32
  # this will create the actual combo box widget
33
33
  framework_responsibility :create_combo_box
34
34
 
@@ -38,13 +38,13 @@ class ComboDelegate
38
38
  # to the combo box without having to deal with events triggered
39
39
  # by setup code.
40
40
  framework_responsibility :framework_setup
41
-
41
+
42
42
  # This is called by the combo box to convert an item
43
43
  # to something that the combo can insert into
44
44
  # itself. Usually this will be a display value
45
45
  # and a storage value.
46
46
  framework_responsibility :item_to_editor
47
-
47
+
48
48
  # This is called by the combo box when it needs to convert a
49
49
  # storage value to an item, which is something that the delegate
50
50
  # will understand.
@@ -59,26 +59,26 @@ class ComboDelegate
59
59
  if needs_combo?
60
60
  @editor = create_combo_box( *args )
61
61
  @editor.delegate = self
62
-
62
+
63
63
  # add all entries from population
64
64
  population.each do |item|
65
65
  editor << item
66
66
  end
67
-
67
+
68
68
  # create a nil entry if necessary
69
69
  if allow_null? && !editor.include?( nil )
70
70
  editor << nil
71
71
  end
72
-
72
+
73
73
  # don't allow inserts if the delegate is restricted
74
74
  editor.no_insert = restricted?
75
-
75
+
76
76
  # set the correct value in the list
77
77
  editor.selected_item = entity.nil? ? nil : attribute_value
78
-
78
+
79
79
  # set up prefix matching when typing in the editor
80
80
  configure_prefix
81
-
81
+
82
82
  framework_setup( *args )
83
83
  else
84
84
  @editor =
@@ -93,26 +93,26 @@ class ComboDelegate
93
93
  end
94
94
  editor
95
95
  end
96
-
96
+
97
97
  # open the combo box, just like if F4 was pressed
98
98
  framework_responsibility :full_edit
99
-
99
+
100
100
  # show only the text editor part, not the drop-down
101
101
  def minimal_edit
102
102
  editor.hide_popup if is_combo?
103
103
  end
104
-
104
+
105
105
  # returns true if the editor allows values outside of a predefined
106
106
  # range, false otherwise.
107
107
  def restricted?
108
108
  false
109
109
  end
110
-
110
+
111
111
  # TODO fetch this from the model definition
112
112
  def allow_null?
113
113
  true
114
114
  end
115
-
115
+
116
116
  # Subclasses should override this to prove a list of
117
117
  # values to be used by the combo box. Values could
118
118
  # be pretty much anything, depending on the delegate.
@@ -120,7 +120,7 @@ class ComboDelegate
120
120
  # of entity objects, most other delegates will have collections
121
121
  # of strings.
122
122
  subclass_responsibility :population
123
-
123
+
124
124
  # Return true if this delegate needs a combo, false otherwise
125
125
  # ie if there are no values yet and it's not restricted, then a
126
126
  # full combo doesn't make sense
@@ -129,23 +129,23 @@ class ComboDelegate
129
129
  # return true if this delegate has/needs a combo widget
130
130
  # or false if it's a plain text field.
131
131
  framework_responsibility :is_combo?
132
-
132
+
133
133
  # return true if this field has no data (needs_combo? is false)
134
134
  # and is at the same time restricted (ie needs data from somewhere else)
135
135
  def empty_set?
136
136
  !needs_combo? && restricted?
137
137
  end
138
-
138
+
139
139
  # the message to display if the set is empty, and
140
140
  # the delegate is restricted to a predefined set.
141
141
  subclass_responsibility :empty_set_message
142
-
142
+
143
143
  # if this delegate has an empty set, return the message, otherwise
144
144
  # return nil.
145
145
  def if_empty_message
146
146
  empty_set_message if empty_set?
147
147
  end
148
-
148
+
149
149
  # the value represented by the combo, ie either
150
150
  # the current attribute_value of the field
151
151
  # this combo is editing, or an object that could
@@ -7,12 +7,12 @@ module Clevic
7
7
  # :frequency can be set as an option. Boolean. If it's true
8
8
  # the options are sorted in order of most frequently used first.
9
9
  class DistinctDelegate
10
-
10
+
11
11
  def needs_combo?
12
12
  # works except when there is a null in the column
13
13
  dataset.count > 0
14
14
  end
15
-
15
+
16
16
  # TODO move away from ar_methods. Partly done.
17
17
  # TODO ordering by either recentness, or frequency. OR both.
18
18
  # TODO make sure nil is in the list. And the current item is at the top.
@@ -31,7 +31,7 @@ class DistinctDelegate
31
31
  else
32
32
  field.dataset_roller.dataset
33
33
  end
34
-
34
+
35
35
  # now pull out the field and the distinct values
36
36
  base_dataset. \
37
37
  distinct. \
@@ -39,11 +39,11 @@ class DistinctDelegate
39
39
  order( field.attribute ). \
40
40
  naked
41
41
  end
42
-
42
+
43
43
  def population
44
44
  dataset.map( field.attribute )
45
45
  end
46
-
46
+
47
47
  end
48
48
 
49
49
  end
@@ -9,18 +9,18 @@ class RelationalDelegate
9
9
  def needs_combo?
10
10
  dataset.count > 0
11
11
  end
12
-
12
+
13
13
  def empty_set_message
14
14
  "There must be records in #{field.related_class} for this field to be editable."
15
15
  end
16
-
16
+
17
17
  def population
18
18
  # dataset contains the set of all possible related entities,
19
-
19
+
20
20
  # dataset is defined in Delegate
21
21
  # entity is set in init_component
22
22
  # field and entity are used by FieldValuer
23
-
23
+
24
24
  # including the current entity.
25
25
  # Could also use
26
26
  # dataset.or( entity_class.primary_key => entity_key.pk )
@@ -35,7 +35,7 @@ class RelationalDelegate
35
35
  values.unshift( attribute_value )
36
36
  end
37
37
  end
38
-
38
+
39
39
  # don't allow new values
40
40
  def restricted?; true; end
41
41
 
@@ -53,7 +53,7 @@ protected
53
53
  field.dataset_roller.dataset
54
54
  end
55
55
  end
56
-
56
+
57
57
  end
58
58
 
59
59
  end
@@ -11,15 +11,15 @@ class SetDelegate
11
11
  raise "SetDelegate must have a :set in options" if field.set.nil?
12
12
  super
13
13
  end
14
-
14
+
15
15
  def needs_combo?
16
16
  true
17
17
  end
18
-
18
+
19
19
  def restricted?
20
20
  field.restricted || false
21
21
  end
22
-
22
+
23
23
  # Items here could either be single values,
24
24
  # or two-value arrays (from a hash-like set), so use key as db value
25
25
  # and value as display value
data/lib/clevic/dirty.rb CHANGED
@@ -46,7 +46,7 @@ module ActiveRecord
46
46
  end
47
47
 
48
48
  private
49
-
49
+
50
50
  # Map of change attr => original value.
51
51
  def changed_attributes
52
52
  @changed_attributes ||= {}
@@ -6,14 +6,14 @@ module Clevic
6
6
  def self.included( base )
7
7
  base.extend( ClassMethods )
8
8
  end
9
-
9
+
10
10
  module ClassMethods
11
11
  def emitter( emitter_name )
12
12
  line, st = __LINE__, <<-EOF
13
13
  def #{emitter_name}_listeners
14
14
  @#{emitter_name}_listeners ||= Set.new
15
15
  end
16
-
16
+
17
17
  # If msg is provided, yield to stored block.
18
18
  # If block is provided, store it for later.
19
19
  def emit_#{emitter_name}( *args, &notifier_block )
@@ -26,7 +26,7 @@ module Clevic
26
26
  end
27
27
  end
28
28
  end
29
-
29
+
30
30
  def remove_#{emitter_name}( &notifier_block )
31
31
  #{emitter_name}_listeners.delete( notifier_block )
32
32
  end
@@ -9,7 +9,7 @@ class Object
9
9
  value.nil? ? nil : value.send( att )
10
10
  end
11
11
  end
12
-
12
+
13
13
  # pass self to the block and return the results of the block.
14
14
  def with( &block )
15
15
  yield( self )
@@ -59,7 +59,7 @@ class Array
59
59
  index if include?( index )
60
60
  end
61
61
  end
62
-
62
+
63
63
  def section
64
64
  return [] if empty?
65
65
  rv = [first]
@@ -69,7 +69,7 @@ class Array
69
69
  end
70
70
  rv
71
71
  end
72
-
72
+
73
73
  # group by ascending values
74
74
  def group
75
75
  parts = []
@@ -81,7 +81,7 @@ class Array
81
81
  parts + self[section.size..-1].group
82
82
  end
83
83
  end
84
-
84
+
85
85
  def range
86
86
  first..last
87
87
  end
data/lib/clevic/field.rb CHANGED
@@ -19,10 +19,10 @@ will allow
19
19
 
20
20
  # reader
21
21
  instance.ixnay
22
-
22
+
23
23
  # writer
24
24
  instance.ixnay = 'nix, baby'
25
-
25
+
26
26
  # writer
27
27
  instance.ixnay 'nix baby'
28
28
 
@@ -42,10 +42,10 @@ And so it the #-- above.
42
42
  class Field
43
43
  # For defining properties
44
44
  include Gather
45
-
45
+
46
46
  # for formatting values
47
47
  include GenericFormat
48
-
48
+
49
49
  ##
50
50
  # :attr:
51
51
  # The value to be displayed after being optionally format-ed
@@ -62,33 +62,33 @@ class Field
62
62
  #
63
63
  # Defaults to nil, in other words the value of the attribute for this field.
64
64
  property :display
65
-
65
+
66
66
  ##
67
67
  # :attr:
68
68
  # The label to be displayed in the column headings. Defaults to the humanised field name.
69
69
  property :label
70
-
70
+
71
71
  ##
72
72
  # :attr:
73
73
  # One of the alignment specifiers - :left, :centre, :right or :justified.
74
74
  # Defaults to right for numeric fields, centre for boolean, and left for
75
75
  # other values.
76
76
  property :alignment
77
-
77
+
78
78
  ##
79
79
  # :attr:
80
80
  # something to do with the icon that Qt displays. Not implemented yet.
81
81
  property :decoration
82
-
82
+
83
83
  ##
84
84
  # :attr:
85
85
  # This defines how to format the value returned by :display. It takes a string or a Proc.
86
- # Generally the string is something
87
- # that can be understood by strftime (for time and date fields) or understood
88
- # by % (for everything else). It can also be a Proc that has one parameter -
86
+ # Generally the string is something
87
+ # that can be understood by strftime (for time and date fields) or understood
88
+ # by % (for everything else). It can also be a Proc that has one parameter -
89
89
  # the current entity. There are sensible defaults for common field types.
90
90
  property :format
91
-
91
+
92
92
  ##
93
93
  # :attr:
94
94
  # This is just like format, except that it's used to format the value just
@@ -96,12 +96,12 @@ class Field
96
96
  # but edit them with a 4 digit year.
97
97
  # Defaults to a sensible value for some fields, for others it will default to the value of :format.
98
98
  property :edit_format
99
-
99
+
100
100
  ##
101
101
  # :attr:
102
102
  # Whether the field is currently visible or not.
103
103
  property :visible
104
-
104
+
105
105
  ##
106
106
  # :attr:
107
107
  # Sample is used if the programmer wishes to provide a value (that will be converted
@@ -111,12 +111,12 @@ class Field
111
111
  # doesn't always work properly. So we
112
112
  # have the option to override that if we wish.
113
113
  property :sample
114
-
114
+
115
115
  ##
116
116
  # :attr:
117
117
  # Takes a boolean. Set the field to read-only.
118
118
  property :read_only
119
-
119
+
120
120
  ##
121
121
  # :attr:
122
122
  # The foreground and background colors.
@@ -125,10 +125,10 @@ class Field
125
125
  # - A String is treated as a constant which may be one of the string constants understood by Qt::Color
126
126
  # - A symbol is treated as a method to be call on an entity
127
127
  #
128
- # The result can be a Qt::Color, or one of the strings in
128
+ # The result can be a Qt::Color, or one of the strings in
129
129
  # http://www.w3.org/TR/SVG/types.html#ColorKeywords.
130
130
  property :foreground, :background
131
-
131
+
132
132
  ##
133
133
  # :attr:
134
134
  # Can take a Proc, a string, or a symbol.
@@ -136,7 +136,7 @@ class Field
136
136
  # - A String is treated as a constant
137
137
  # - A symbol is treated as a method to be call on an entity
138
138
  property :tooltip
139
-
139
+
140
140
  ##
141
141
  # :attr:
142
142
  # An Enumerable of allowed values for restricted fields. If each yields
@@ -144,7 +144,7 @@ class Field
144
144
  # first will be stored in the db, and the second displayed in the UI.
145
145
  # If it's a proc, that must return an Enumerable as above.
146
146
  property :set
147
-
147
+
148
148
  ##
149
149
  # :attr:
150
150
  # When this is true, only the values in the combo may be entered.
@@ -152,7 +152,7 @@ class Field
152
152
  # non-listed values. Default is true if a set is explicitly specified.
153
153
  # Otherwise depends on the field type.
154
154
  property :restricted
155
-
155
+
156
156
  ##
157
157
  # :attr:
158
158
  # Only for the distinct field type. The values will be sorted either with the
@@ -160,21 +160,21 @@ class Field
160
160
  # alphabetical order (:description => true).
161
161
  # FIXME re-implement this with Dataset
162
162
  property :frequency, :description
163
-
163
+
164
164
  ##
165
165
  # :attr:
166
166
  # Default value for this field for new records.
167
167
  # Can be a Proc or a value. A value will just be
168
168
  # set, a proc will be executed with the entity as a parameter.
169
169
  property :default
170
-
170
+
171
171
  ##
172
172
  # :attr:
173
173
  # The property used for finding the field, ie by TableModel#field_column.
174
174
  # Defaults to the attribute. If there are several display fields based on
175
175
  # one db field, their attribute will be the same, but their id must be different.
176
176
  property :id
177
-
177
+
178
178
  ##
179
179
  # :attr:
180
180
  # Called when the data in this field changes.
@@ -189,13 +189,13 @@ class Field
189
189
  def dataset
190
190
  dataset_roller
191
191
  end
192
-
192
+
193
193
  # TODO Still getting the Builder/Built conflict
194
194
  def dataset_roller
195
195
  # related class if it's an association, entity_class otherwise
196
196
  @dataset_roller ||= DatasetRoller.new( ( association? ? related_class : entity_class ).dataset )
197
197
  end
198
-
198
+
199
199
  # The list of properties for ActiveRecord options.
200
200
  # There are actually from ActiveRecord::Base.VALID_FIND_OPTIONS, but it's protected.
201
201
  # Each element becomes a property.
@@ -203,7 +203,7 @@ class Field
203
203
  # TODO warn or raise if these are used together with a dataset call
204
204
  AR_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group, :from, :lock ]
205
205
  AR_FIND_OPTIONS.each{|x| property x}
206
-
206
+
207
207
  # Return a list of find options and their values, but only
208
208
  # if the values are not nil
209
209
  def find_options
@@ -215,25 +215,25 @@ class Field
215
215
  ha
216
216
  end
217
217
  end
218
-
218
+
219
219
  # The model object (eg TableModel) this field is part of.
220
220
  # Set to TableModel by ModelBuilder#build
221
221
  attr_accessor :model
222
-
222
+
223
223
  # The UI delegate class for the field. The delegate class knows how to create a UI
224
224
  # for this field using whatever GUI toolkit is selected
225
225
  attr_accessor :delegate
226
-
226
+
227
227
  # The attribute on the entity that forms the basis for this field.
228
228
  # Accessing the returned attribute (using send, or the [] method on an entity)
229
229
  # will give a simple value, or another entity in the case of relational fields.
230
230
  # In other words, this is *not* the same as the name of the field in the DB, which
231
231
  # would normally have an _id suffix for relationships.
232
232
  attr_accessor :attribute
233
-
233
+
234
234
  # The Object Relational Model this field uses to get data from.
235
235
  attr_reader :entity_class
236
-
236
+
237
237
  # Create a new Field object that displays the contents of a database field in
238
238
  # the UI using the given parameters.
239
239
  # - attribute is the symbol for the attribute on the entity_class.
@@ -244,11 +244,11 @@ class Field
244
244
  unless attribute.is_a?( Symbol )
245
245
  raise "attribute #{attribute.inspect} must be a symbol"
246
246
  end
247
-
247
+
248
248
  unless entity_class.ancestors.include?( Clevic.base_entity_class )
249
249
  raise "#{entity_class} is not a Clevic.base_entity_class: #{Clevic.base_entity_class}"
250
250
  end
251
-
251
+
252
252
  # TODO this comes down to method_defined, really
253
253
  unless entity_class.has_attribute?( attribute ) or entity_class.method_defined?( attribute )
254
254
  raise <<EOF
@@ -256,20 +256,20 @@ class Field
256
256
  #{entity_class.attribute_names.inspect}
257
257
  EOF
258
258
  end
259
-
259
+
260
260
  # instance variables
261
261
  @attribute = attribute
262
262
  # default to attribute, can be overwritten later
263
263
  @id = attribute
264
264
  @entity_class = entity_class
265
265
  @visible = true
266
-
266
+
267
267
  # initialise
268
268
  @value_cache = {}
269
-
269
+
270
270
  # handle options
271
271
  gather( options, &block )
272
-
272
+
273
273
  # set various sensible defaults. They're not lazy accessors because
274
274
  # they might stay nil, and we don't want to keep evaluating them.
275
275
  default_label!
@@ -278,7 +278,7 @@ EOF
278
278
  default_alignment!
279
279
  default_display! if association?
280
280
  end
281
-
281
+
282
282
  # Return the attribute value for the given Object Relational Model instance, or nil
283
283
  # if entity is nil. Will call transform_attribute.
284
284
  def value_for( entity )
@@ -290,7 +290,7 @@ EOF
290
290
  puts e.backtrace
291
291
  end
292
292
  end
293
-
293
+
294
294
  # Apply the value of the display property to the given
295
295
  # attribute value. Otherwise just return the
296
296
  # attribute_value itself.
@@ -299,47 +299,47 @@ EOF
299
299
  case display
300
300
  when Proc
301
301
  display.call( attribute_value )
302
-
302
+
303
303
  when String
304
304
  attribute_value.evaluate_path( display.split( '.' ) )
305
-
305
+
306
306
  when Symbol
307
307
  attribute_value.send( display )
308
-
308
+
309
309
  else
310
310
  attribute_value
311
311
  end
312
312
  end
313
-
313
+
314
314
  # return true if this is a field for a related table, false otherwise.
315
315
  def association?
316
316
  meta.andand.association?
317
317
  end
318
-
318
+
319
319
  # Clevic::ModelColumn object
320
320
  def meta
321
321
  entity_class.meta[attribute] || ModelColumn.new( attribute, {} )
322
322
  end
323
-
323
+
324
324
  # return true if this field can be used in a filter
325
325
  # virtual fields (ie those that don't exist in this field's
326
326
  # table) can't be used to filter on.
327
327
  def filterable?
328
328
  !meta.nil?
329
329
  end
330
-
330
+
331
331
  # return the result of the attribute + the path
332
332
  def column
333
333
  [attribute.to_s, path].compact.join('.')
334
334
  end
335
-
335
+
336
336
  # Return the class object of a related class if this is a relational
337
337
  # field, otherwise nil.
338
338
  def related_class
339
339
  return nil unless association? && entity_class.meta.has_key?( attribute )
340
340
  @related_class ||= eval( entity_class.meta[attribute].class_name || attribute.to_s.classify )
341
341
  end
342
-
342
+
343
343
  # return an array of the various attribute parts
344
344
  # TODO not used much. Deprecate and remove.
345
345
  def attribute_path
@@ -347,23 +347,23 @@ EOF
347
347
  pieces.concat( display.to_s.split( '.' ) ) unless display.is_a? Proc
348
348
  pieces.map{|x| x.to_sym}
349
349
  end
350
-
350
+
351
351
  # Return true if the field is read-only. Defaults to false.
352
352
  def read_only?
353
353
  @read_only || false
354
354
  end
355
-
355
+
356
356
  # Called by Clevic::FieldValuer (and others) to format the display value.
357
357
  def do_format( value )
358
358
  do_generic_format( format, value )
359
359
  end
360
-
360
+
361
361
  # Called by Clevic::FieldValuer to format the field to a string value
362
362
  # that can be used for editing.
363
363
  def do_edit_format( value )
364
364
  do_generic_format( edit_format, value )
365
365
  end
366
-
366
+
367
367
  # Set or return a sample for the field which can be used to size the UI field widget.
368
368
  # If this is called as an accessor, and there is no value yet, a Clevic::Sampler
369
369
  # instance is created to compute a sample.
@@ -389,7 +389,7 @@ EOF
389
389
  @sample
390
390
  end
391
391
  end
392
-
392
+
393
393
  # Called by Clevic::TableModel to get the tooltip value
394
394
  def tooltip_for( entity )
395
395
  cache_value_for( :tooltip, entity )
@@ -399,22 +399,22 @@ EOF
399
399
  def decoration_for( entity )
400
400
  nil
401
401
  end
402
-
402
+
403
403
  # Called by Clevic::TableModel to get the foreground color value
404
404
  def foreground_for( entity )
405
405
  cache_value_for( :foreground, entity ) {|x| string_or_color(x)}
406
406
  end
407
-
407
+
408
408
  # Called by Clevic::TableModel to get the background color value
409
409
  def background_for( entity )
410
410
  cache_value_for( :background, entity ) {|x| string_or_color(x)}
411
411
  end
412
-
412
+
413
413
  # called when a new entity object is created to set default values
414
414
  # specified by the default property.
415
415
  def set_default_for( entity )
416
416
  begin
417
- entity[attribute] =
417
+ entity[attribute] =
418
418
  case default
419
419
  when String
420
420
  default
@@ -426,31 +426,31 @@ EOF
426
426
  puts e.backtrace
427
427
  end
428
428
  end
429
-
429
+
430
430
  # fetch the permitted set of values for a restricted field.
431
431
  def set_for( entity )
432
432
  case set
433
433
  when Proc
434
434
  # the Proc should return an enumerable
435
435
  set.call( entity )
436
-
436
+
437
437
  when Symbol
438
438
  entity.send( set )
439
-
439
+
440
440
  else
441
441
  # assume its an Enumerable
442
442
  set
443
443
  end
444
444
  end
445
-
445
+
446
446
  def to_s
447
447
  "#{entity_class}.#{id}"
448
448
  end
449
-
449
+
450
450
  def inspect
451
451
  "#<Clevic::Field #{entity_class} id=#{id} attribute=#{attribute}>"
452
452
  end
453
-
453
+
454
454
  protected
455
455
 
456
456
  # call the conversion_block with the value, or just return the
@@ -462,7 +462,7 @@ protected
462
462
  conversion_block.call( value )
463
463
  end
464
464
  end
465
-
465
+
466
466
  # symbol is the property name to fetch a value for.
467
467
  # It can be a Proc, a symbol, or a value responding to to_s.
468
468
  # In all cases, conversion block will be called
@@ -478,10 +478,10 @@ protected
478
478
  else; @value_cache[symbol] ||=convert_or_identity( value, &conversion_block )
479
479
  end
480
480
  end
481
-
481
+
482
482
  # the label if it's not defined. Based on the attribute.
483
483
  def default_label!
484
- @label ||= attribute.to_s.humanize
484
+ @label ||= ( id || attribute ).to_s.humanize
485
485
  end
486
486
 
487
487
  # sensible display format defaults if they're not defined.
@@ -494,7 +494,7 @@ protected
494
494
  when :decimal, :float; "%.2f"
495
495
  end
496
496
  end
497
-
497
+
498
498
  # sensible edit format defaults if they're not defined.
499
499
  def default_edit_format!
500
500
  @edit_format ||=