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
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