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.
- data/History.txt +3 -0
- data/lib/clevic/action_builder.rb +16 -16
- data/lib/clevic/ar_methods.rb +22 -22
- data/lib/clevic/attribute_list.rb +5 -5
- data/lib/clevic/cache_table.rb +18 -18
- data/lib/clevic/dataset_roller.rb +3 -3
- data/lib/clevic/default_view.rb +4 -4
- data/lib/clevic/delegate.rb +8 -8
- data/lib/clevic/delegates/combo_delegate.rb +22 -22
- data/lib/clevic/delegates/distinct_delegate.rb +5 -5
- data/lib/clevic/delegates/relational_delegate.rb +6 -6
- data/lib/clevic/delegates/set_delegate.rb +3 -3
- data/lib/clevic/dirty.rb +1 -1
- data/lib/clevic/emitter.rb +3 -3
- data/lib/clevic/extensions.rb +4 -4
- data/lib/clevic/field.rb +68 -68
- data/lib/clevic/field_valuer.rb +26 -26
- data/lib/clevic/filter_command.rb +6 -6
- data/lib/clevic/framework.rb +3 -3
- data/lib/clevic/generic_format.rb +2 -2
- data/lib/clevic/many_field.rb +3 -3
- data/lib/clevic/model_builder.rb +88 -84
- data/lib/clevic/model_column.rb +13 -13
- data/lib/clevic/ordered_dataset.rb +7 -7
- data/lib/clevic/qt/action_builder.rb +3 -3
- data/lib/clevic/qt/browser.rb +28 -28
- data/lib/clevic/qt/clipboard.rb +5 -5
- data/lib/clevic/qt/combo_delegate.rb +12 -12
- data/lib/clevic/qt/distinct_delegate.rb +1 -1
- data/lib/clevic/qt/extensions.rb +4 -4
- data/lib/clevic/qt/qt_combo_box.rb +7 -7
- data/lib/clevic/qt/relational_delegate.rb +5 -5
- data/lib/clevic/qt/search_dialog.rb +15 -15
- data/lib/clevic/qt/simplest_delegate.rb +2 -2
- data/lib/clevic/qt/table_model.rb +46 -46
- data/lib/clevic/qt/table_view.rb +48 -48
- data/lib/clevic/qt/text_delegate.rb +9 -9
- data/lib/clevic/rails_models_loaders.rb +3 -3
- data/lib/clevic/record.rb +8 -8
- data/lib/clevic/sampler.rb +6 -6
- data/lib/clevic/sequel_ar_adapter.rb +22 -22
- data/lib/clevic/sequel_clevic.rb +10 -10
- data/lib/clevic/sequel_meta.rb +5 -5
- data/lib/clevic/sequel_naked.rb +4 -4
- data/lib/clevic/swing/action.rb +20 -20
- data/lib/clevic/swing/action_builder.rb +2 -2
- data/lib/clevic/swing/boolean_delegate.rb +3 -3
- data/lib/clevic/swing/browser.rb +37 -37
- data/lib/clevic/swing/cell_editor.rb +13 -13
- data/lib/clevic/swing/cell_renderer.rb +7 -7
- data/lib/clevic/swing/clipboard.rb +19 -19
- data/lib/clevic/swing/combo_delegate.rb +26 -26
- data/lib/clevic/swing/confirm_dialog.rb +7 -7
- data/lib/clevic/swing/delegate.rb +4 -4
- data/lib/clevic/swing/extensions.rb +24 -24
- data/lib/clevic/swing/field.rb +1 -1
- data/lib/clevic/swing/relational_delegate.rb +2 -2
- data/lib/clevic/swing/row_header.rb +32 -32
- data/lib/clevic/swing/search_dialog.rb +31 -31
- data/lib/clevic/swing/selection_model.rb +12 -12
- data/lib/clevic/swing/swing_table_index.rb +6 -6
- data/lib/clevic/swing/table_model.rb +30 -30
- data/lib/clevic/swing/table_view.rb +54 -54
- data/lib/clevic/swing/table_view_focus.rb +4 -4
- data/lib/clevic/swing/tag_delegate.rb +14 -14
- data/lib/clevic/swing/tag_editor.rb +4 -4
- data/lib/clevic/swing/text_area_delegate.rb +6 -6
- data/lib/clevic/swing/text_delegate.rb +4 -4
- data/lib/clevic/table_index.rb +14 -14
- data/lib/clevic/table_model.rb +30 -30
- data/lib/clevic/table_searcher.rb +19 -19
- data/lib/clevic/table_view.rb +92 -92
- data/lib/clevic/table_view_paste.rb +19 -19
- data/lib/clevic/version.rb +1 -1
- data/lib/clevic/view.rb +22 -22
- data/models/accounts_models.rb +10 -10
- data/models/examples.rb +2 -2
- data/models/times_models.rb +32 -32
- data/models/values_models.rb +2 -2
- data/test/test_cache_table.rb +15 -15
- data/test/test_helper.rb +7 -7
- data/test/test_model_index_extensions.rb +6 -6
- data/test/test_table_model.rb +6 -6
- data/test/test_table_searcher.rb +25 -25
- metadata +33 -35
data/History.txt
CHANGED
@@ -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
|
data/lib/clevic/ar_methods.rb
CHANGED
@@ -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
|
data/lib/clevic/cache_table.rb
CHANGED
@@ -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
|
data/lib/clevic/default_view.rb
CHANGED
@@ -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
|