clevic 0.13.0.b9 → 0.13.0.b10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
data/History.txt CHANGED
@@ -1,3 +1,6 @@
1
+ == 0.13.0.b10
2
+ * allow better separation between Field id and attribute
3
+
1
4
  == 0.13.0.b6
2
5
  * switch to MrBones
3
6
  * All dependencies are now gems. bsearch is a gem. So is qtbindings.
@@ -7,7 +7,7 @@ collections of actions more rubyish. It must have
7
7
  - separator, which returns something which is_a? Separator
8
8
  - create_action( &block ), which creates an Action object
9
9
  - action_method_or_block( action, options, &block ) which handles events
10
-
10
+
11
11
  Menus are generally made up of a collection of actions.
12
12
 
13
13
  Once included, it's intended to be called as follows:
@@ -27,14 +27,14 @@ Once included, it's intended to be called as follows:
27
27
  action :action_row, 'New Ro&w', :shortcut => 'Ctrl+N', :method => :row
28
28
  action :action_refresh, '&Refresh', :shortcut => 'Ctrl+R', :method => :refresh
29
29
  action :action_delete_rows, 'Delete Rows', :shortcut => 'Ctrl+Delete', :method => :delete_rows
30
-
30
+
31
31
  if $options[:debug]
32
32
  action :action_dump, 'D&ump', :shortcut => 'Ctrl+Shift+D' do
33
33
  puts model.collection[current_index.row].inspect
34
34
  end
35
35
  end
36
36
  end
37
-
37
+
38
38
  separator
39
39
  end
40
40
  end
@@ -66,7 +66,7 @@ module ActionBuilder
66
66
  raise NotImplementedError, "#{including_module.class.name} must have an add_action method"
67
67
  end
68
68
  end
69
-
69
+
70
70
  # Outer block for the build process.
71
71
  def build_actions( &block )
72
72
  raise 'a block must be present' if block.nil?
@@ -76,11 +76,11 @@ module ActionBuilder
76
76
  yield self
77
77
  end
78
78
  end
79
-
79
+
80
80
  def group_names
81
81
  @group_names ||= []
82
82
  end
83
-
83
+
84
84
  # Create and return a list of actions. The actions are grouped together,
85
85
  # ie live together on the menu with a separator between groups.
86
86
  # A method called "#{group_name}_actions" will be added to self, which will return the
@@ -94,16 +94,16 @@ module ActionBuilder
94
94
  end
95
95
  end
96
96
  self.collect_actions = []
97
-
97
+
98
98
  yield( self )
99
99
  # copy actions to the right instance variable
100
100
  eval "@#{group_name.to_s}_actions = collect_actions"
101
-
101
+
102
102
  # reset these, just for cleanliness
103
103
  @group_name = nil
104
104
  self.collect_actions = []
105
105
  end
106
-
106
+
107
107
  # Create a new Action and
108
108
  # 1. pass it to add_action
109
109
  # 1. add it to the collect_actions collection.
@@ -119,7 +119,7 @@ module ActionBuilder
119
119
  if options.has_key?( :method ) && !block.nil?
120
120
  raise "you can't specify both :method and a block"
121
121
  end
122
-
122
+
123
123
  create_action do |action|
124
124
  action.name = name.to_s
125
125
  action.text = text
@@ -131,14 +131,14 @@ module ActionBuilder
131
131
  action.send( "#{k.to_s}=", v )
132
132
  end
133
133
  end
134
-
134
+
135
135
  # add action
136
136
  add_action action
137
-
137
+
138
138
  # add actions for list. Yes, it's a side-effect.
139
139
  # TODO is there a better way to do this?
140
140
  collect_actions << action
141
-
141
+
142
142
  action_method_or_block( action, options, &block )
143
143
  end
144
144
  end
@@ -150,11 +150,11 @@ protected
150
150
  def collect_actions
151
151
  @collect_actions ||= []
152
152
  end
153
-
153
+
154
154
  def collect_actions=( arr )
155
155
  @collect_actions = arr
156
156
  end
157
-
157
+
158
158
  # If parent doesn't define this, add it so that
159
159
  # our action_method_or_block will work.
160
160
  unless instance_methods.include?( :action_triggered )
@@ -165,7 +165,7 @@ protected
165
165
  puts $!.backtrace
166
166
  end
167
167
  end
168
-
168
+
169
169
  end
170
170
 
171
171
  end # Clevic
@@ -16,23 +16,23 @@ module Sequel
16
16
  # workaround for Sequel's refusal to do offset without limit
17
17
  # not sure we need :all for >= 3.13.0
18
18
  dataset.limit( options[:limit] || :all, value )
19
-
19
+
20
20
  when :order
21
21
  orders = value.split(/, */ ).map do |x|
22
22
  case x
23
23
  when /^(\w+) +(asc|desc)$/i
24
24
  $1.to_sym.send( $2 )
25
-
25
+
26
26
  when /^\w+$/i
27
27
  x.to_sym
28
-
28
+
29
29
  else
30
30
  x.lit
31
-
31
+
32
32
  end
33
33
  end
34
34
  dataset.order( *orders )
35
-
35
+
36
36
  when :conditions
37
37
  # this translation is not adequate for all use cases of the AR api
38
38
  # specifically where value contains a SQL expression
@@ -43,10 +43,10 @@ module Sequel
43
43
  else
44
44
  value
45
45
  end
46
-
46
+
47
47
  dataset.filter( possible_literal )
48
48
  end
49
-
49
+
50
50
  when :include
51
51
  # this is the class to join
52
52
  joined_class = eval( model.reflections[value][:class_name] )
@@ -55,18 +55,18 @@ module Sequel
55
55
  joined_class,
56
56
  joined_class.primary_key => model.reflections[value][:key]
57
57
  ).select( model.table_name.* )
58
-
58
+
59
59
  else
60
60
  raise "#{key} not implemented"
61
61
  # make sure at least it's unchanged, in case options is empty
62
62
  end || dataset
63
63
  end
64
-
64
+
65
65
  rescue Exception => e
66
66
  raise RuntimeError, "#{self} #{options.inspect} #{e.message}", caller(0)
67
67
  end
68
68
  end
69
-
69
+
70
70
  module Plugins
71
71
  module ArMethods
72
72
  # plugin :ar_methods calls this.
@@ -78,33 +78,33 @@ module Sequel
78
78
  # store model-related stuff here
79
79
  end
80
80
  end
81
-
81
+
82
82
  module ClassMethods
83
83
  # Copy the necessary class instance variables to the subclass.
84
84
  def inherited(subclass)
85
85
  super
86
86
  end
87
-
87
+
88
88
  def translate( options )
89
89
  dataset.translate( options )
90
90
  end
91
-
91
+
92
92
  def find_ar( *args )
93
93
  # copied from ActiveRecord::Base.find
94
94
  options = args.extract_options!
95
95
  #~ validate_find_options(options)
96
96
  #~ set_readonly_option!(options)
97
-
97
+
98
98
  case args.first
99
99
  when :first
100
100
  dataset.translate(options).first
101
-
101
+
102
102
  when :last
103
103
  dataset.translate(options).last
104
-
104
+
105
105
  when :all
106
106
  dataset.translate(options).all
107
-
107
+
108
108
  else
109
109
  if args.size == 1
110
110
  dataset.translate(options).filter( :id.qualify( table_name ) => args.first ).first
@@ -113,21 +113,21 @@ module Sequel
113
113
  end
114
114
  end
115
115
  end
116
-
116
+
117
117
  def count_ar( *args )
118
118
  options = args.extract_options!
119
119
  attribute = args.first
120
-
120
+
121
121
  dataset = dataset.translate( options )
122
-
122
+
123
123
  unless attribute.nil?
124
124
  dataset = dataset.select( attribute )
125
125
  end
126
126
  dataset.count
127
127
  end
128
-
128
+
129
129
  end
130
-
130
+
131
131
  module InstanceMethods
132
132
  end
133
133
  end
@@ -9,7 +9,7 @@ module Clevic
9
9
  @attribute, @attribute_value, @find_options = attribute, attribute_value, find_options
10
10
  end
11
11
  attr_reader :entity_class, :attribute, :attribute_value, :find_options
12
-
12
+
13
13
  # because Sequel::Dataset won't .filter with {}
14
14
  def conditions( dataset )
15
15
  # make sure the current attribute value is included if there's a filter
@@ -17,7 +17,7 @@ module Clevic
17
17
  if find_options.has_key?( :conditions )
18
18
  find_options[:conditions].lit | { attribute => attribute_value }
19
19
  end
20
-
20
+
21
21
  # filter if necessary
22
22
  unless rv.nil?
23
23
  dataset.filter( rv )
@@ -25,7 +25,7 @@ module Clevic
25
25
  dataset
26
26
  end
27
27
  end
28
-
28
+
29
29
  # sorts by attribute
30
30
  def dataset_by_description
31
31
  # must have attribute equality test first, otherwise if find_options
@@ -37,7 +37,7 @@ module Clevic
37
37
  .distinct
38
38
  conditions( ds )
39
39
  end
40
-
40
+
41
41
  # sorts by first letter then most frequent, instead of pure alphabetical
42
42
  def dataset_by_frequency
43
43
  ds = entity_class.naked \
@@ -46,7 +46,7 @@ module Clevic
46
46
  .order( :substr.sql_function( attribute,1,1 ), :count.sql_function( attribute ).desc )
47
47
  conditions( ds )
48
48
  end
49
-
49
+
50
50
  # by_frequency is the default
51
51
  def dataset( by_description, by_frequency )
52
52
  case
@@ -24,30 +24,30 @@ TODO figure out how to handle situations where the character set ordering
24
24
  in the db and in Ruby are different.
25
25
  =end
26
26
  class CacheTable < Array
27
-
27
+
28
28
  include OrderedDataset
29
-
29
+
30
30
  # the number of records loaded in one call to the db
31
31
  attr_accessor :preload_count
32
32
  attr_reader :entity_class
33
-
33
+
34
34
  def initialize( entity_class, dataset = nil )
35
35
  @preload_count = 30
36
36
  @entity_class = entity_class
37
37
  # defined in OrderAttributes
38
38
  self.dataset = dataset || entity_class.dataset
39
-
39
+
40
40
  # size the array and fill it with nils. They'll be filled
41
41
  # in by the [] operator
42
42
  super( sql_count )
43
43
  end
44
-
44
+
45
45
  # The count of the records according to the db, which may be different to
46
46
  # the records in the cache
47
47
  def sql_count
48
48
  dataset.count
49
49
  end
50
-
50
+
51
51
  # Execute the block with the specified preload_count,
52
52
  # and restore the existing one when done.
53
53
  # Return the value of the block
@@ -58,28 +58,28 @@ class CacheTable < Array
58
58
  self.preload_count = old_limit
59
59
  retval
60
60
  end
61
-
61
+
62
62
  # Fetch the entity for the given index from the db, and store it
63
63
  # in the array. Also, preload preload_count records to avoid subsequent
64
64
  # hits on the db
65
65
  def fetch_entity( index )
66
66
  # calculate negative indices for the SQL offset
67
67
  offset = index < 0 ? index + sql_count : index
68
-
68
+
69
69
  # fetch self.preload_count records
70
70
  records = dataset.limit( preload_count, offset )
71
71
  records.each_with_index {|x,i| self[i+index] = x if !cached_at?( i+index )}
72
-
72
+
73
73
  # return the first one
74
74
  records.first
75
75
  end
76
-
76
+
77
77
  # return the entity at the given index. Fetch it from the
78
78
  # db if it isn't in this array yet
79
79
  def []( index )
80
80
  super( index ) || fetch_entity( index )
81
81
  end
82
-
82
+
83
83
  # Make a new instance based on the current dataset.
84
84
  # Unless new_dataset is specified, pass the dataset
85
85
  # to the block, and use the return
@@ -93,14 +93,14 @@ class CacheTable < Array
93
93
  if new_dataset && block_given?
94
94
  raise "Passing a new dataset and a modification block doesn't make sense."
95
95
  end
96
-
96
+
97
97
  if block_given?
98
98
  self.class.new( entity_class, block.call( dataset ) )
99
99
  else
100
100
  self.class.new( entity_class, new_dataset || dataset )
101
101
  end
102
102
  end
103
-
103
+
104
104
  # key is what we're searching for. candidate
105
105
  # is what the current candidate is. direction is 1
106
106
  # for sorted ascending, and -1 for sorted descending
@@ -124,14 +124,14 @@ class CacheTable < Array
124
124
  # reverse the result if we're searching a desc attribute,
125
125
  # where direction will be -1
126
126
  end
127
-
127
+
128
128
  # find the index for the given entity, using a binary search algorithm (bsearch).
129
129
  # The order_by ActiveRecord style options are used to do the binary search.
130
130
  # nil is returned if the entity is nil
131
131
  # nil is returned if the array is empty
132
132
  def index_for_entity( entity )
133
133
  return nil if size == 0 || entity.nil?
134
-
134
+
135
135
  # only load one record at a time, because mostly we only
136
136
  # need one for the binary seach. No point in pulling several out.
137
137
  preload_limit( 1 ) do
@@ -145,10 +145,10 @@ class CacheTable < Array
145
145
  if result == 0
146
146
  # compare taking ordering direction into account
147
147
  retval = compare( entity.send( key ), candidate.send( key ), direction )
148
-
148
+
149
149
  # exit now because we have a difference
150
150
  next( retval ) if retval != 0
151
-
151
+
152
152
  # otherwise try with the next order attribute
153
153
  retval
154
154
  else
@@ -170,7 +170,7 @@ class Array
170
170
  def cached_at?( index )
171
171
  !at(index).nil?
172
172
  end
173
-
173
+
174
174
  def search
175
175
  raise "not implemented"
176
176
  end
@@ -7,16 +7,16 @@ module Clevic
7
7
  def initialize( original_dataset )
8
8
  @rolling_dataset = original_dataset
9
9
  end
10
-
10
+
11
11
  def dataset
12
12
  @rolling_dataset
13
13
  end
14
-
14
+
15
15
  def method_missing(meth, *args, &block)
16
16
  @rolling_dataset = @rolling_dataset.send( meth, *args, &block )
17
17
  self
18
18
  end
19
19
  end
20
-
20
+
21
21
 
22
22
  end
@@ -17,7 +17,7 @@ module Clevic
17
17
  super
18
18
  end
19
19
  end
20
-
20
+
21
21
  def title
22
22
  @title ||= entity_class.name.demodulize.tableize.humanize
23
23
  end
@@ -32,7 +32,7 @@ module Clevic
32
32
  super
33
33
  end
34
34
  end
35
-
35
+
36
36
  def notify_data_changed( table_view, top_left_model_index, bottom_right_model_index )
37
37
  if entity_class.respond_to?( :data_changed )
38
38
  puts "Deprecated: #{entity_class.name}.data_changed( top_left, bottom_right, table_view ). Use notify_data_changed( table_view, top_left_model_index, bottom_right_model_index ) instead."
@@ -43,7 +43,7 @@ module Clevic
43
43
  super
44
44
  end
45
45
  end
46
-
46
+
47
47
  def notify_key_press( table_view, key_press_event, current_model_index )
48
48
  if entity_class.respond_to?( :key_press_event )
49
49
  puts "Deprecated: #{entity_class.name}.key_press_event( key_press_event, current_model_index, table_view ). Use notify_key_press( table_view, key_press_event, current_model_index ) instead."
@@ -55,5 +55,5 @@ module Clevic
55
55
  end
56
56
  end
57
57
  end
58
-
58
+
59
59
  end