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/lib/clevic/model_column.rb
CHANGED
@@ -8,9 +8,9 @@ a hash instead of a class.
|
|
8
8
|
class ModelColumn
|
9
9
|
# these are from AR
|
10
10
|
attr_accessor :primary, :scale, :sql_type, :name, :precision, :default, :type, :meta
|
11
|
-
|
11
|
+
|
12
12
|
attr_writer :limit
|
13
|
-
|
13
|
+
|
14
14
|
# if it's not here, it's probably from Sequel, so figure it out from
|
15
15
|
# the db_type
|
16
16
|
def limit
|
@@ -20,22 +20,22 @@ class ModelColumn
|
|
20
20
|
end
|
21
21
|
@limit
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# these are from Sequel::Model.columns_hash
|
25
25
|
attr_accessor :ruby_default, :primary_key, :allow_null, :db_type
|
26
|
-
|
26
|
+
|
27
27
|
# sequel::Model.reflections
|
28
28
|
attr_accessor :key, :eager_block, :type, :eager_grapher, :before_add, :model, :graph_join_type, :class_name, :before_remove, :eager_loader, :uses_composite_keys, :order_eager_graph, :dataset, :cartesian_product_number, :after_add, :cache, :keys, :after_remove, :extend, :graph_conditions, :name, :orig_opts, :after_load, :before_set, :after_set, :reciprocal, :reciprocal_type
|
29
|
-
|
29
|
+
|
30
30
|
# for many_to_one targets
|
31
31
|
attr_accessor :primary_keys
|
32
|
-
|
32
|
+
|
33
33
|
# TODO not sure where these are from
|
34
34
|
attr_accessor :order, :class, :conditions
|
35
|
-
|
35
|
+
|
36
36
|
# a enw one in sequel 3.25.0
|
37
37
|
attr_accessor :block
|
38
|
-
|
38
|
+
|
39
39
|
# For Sequel many_to_many
|
40
40
|
attr_accessor :left_key,
|
41
41
|
:left_keys,
|
@@ -50,25 +50,25 @@ class ModelColumn
|
|
50
50
|
:left_key_alias,
|
51
51
|
:graph_join_table_conditions,
|
52
52
|
:graph_join_table_join_type
|
53
|
-
|
53
|
+
|
54
54
|
# added by us
|
55
55
|
attr_accessor :association
|
56
56
|
def association?; association; end
|
57
|
-
|
57
|
+
|
58
58
|
def initialize( name, hash )
|
59
59
|
@hash = hash
|
60
60
|
@hash.each do |key,value|
|
61
61
|
send( "#{key}=", value )
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
# must be after hash so it takes precedence
|
65
65
|
@name = name
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
def name
|
69
69
|
@name
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
def related_class
|
73
73
|
@related_class ||= eval class_name
|
74
74
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Clevic
|
2
|
-
|
2
|
+
|
3
3
|
# Provides a nice way of getting to Sequel::Dataset's
|
4
4
|
# opts[:order] information
|
5
5
|
#
|
6
6
|
# Including class must call dataset= before calling order_attributes
|
7
7
|
module OrderedDataset
|
8
|
-
|
8
|
+
|
9
9
|
# returns a collection of [ attribute, (1|-1) ]
|
10
10
|
# where 1 is forward/asc (>) and -1 is backward/desc (<)
|
11
11
|
def order_attributes
|
@@ -15,10 +15,10 @@ module Clevic
|
|
15
15
|
case order_expr
|
16
16
|
when Symbol
|
17
17
|
[ order_expr, 1 ]
|
18
|
-
|
18
|
+
|
19
19
|
when Sequel::SQL::OrderedExpression
|
20
20
|
[ order_expr.expression, order_expr.descending ? -1 : 1 ]
|
21
|
-
|
21
|
+
|
22
22
|
else
|
23
23
|
raise "unknown order_expr: #{order_expr.inspect}"
|
24
24
|
end
|
@@ -26,9 +26,9 @@ module Clevic
|
|
26
26
|
end
|
27
27
|
@order_attributes
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
attr_reader :dataset
|
31
|
-
|
31
|
+
|
32
32
|
# Set default dataset ordering to primary key if it doesn't
|
33
33
|
# already have an order.
|
34
34
|
def dataset=( other )
|
@@ -39,7 +39,7 @@ module Clevic
|
|
39
39
|
other
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
end
|
44
44
|
|
45
45
|
end
|
@@ -9,11 +9,11 @@ module ActionBuilder
|
|
9
9
|
collect_actions << action
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def create_action( &block )
|
14
14
|
Qt::Action.new( parent, &block )
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
# TODO move this into Action, like the swing adapter
|
18
18
|
def create_key_sequence( sequence )
|
19
19
|
Qt::KeySequence.new( sequence )
|
@@ -22,7 +22,7 @@ module ActionBuilder
|
|
22
22
|
# set up the code to be executed when an action is triggered,
|
23
23
|
def action_method_or_block( qt_action, options, &block )
|
24
24
|
signal_name = "triggered(#{options.has_key?( :checkable ) ? 'bool' : ''})"
|
25
|
-
|
25
|
+
|
26
26
|
# connect the action to some code
|
27
27
|
if options.has_key?( :method )
|
28
28
|
qt_action.connect SIGNAL( signal_name ) do |active|
|
data/lib/clevic/qt/browser.rb
CHANGED
@@ -12,29 +12,29 @@ added.
|
|
12
12
|
=end
|
13
13
|
class Browser < Qt::Widget
|
14
14
|
slots *%w{dump() refresh_table() filter_by_current(bool) next_tab() previous_tab() current_changed(int)}
|
15
|
-
|
15
|
+
|
16
16
|
attr_reader :tables_tab
|
17
|
-
|
17
|
+
|
18
18
|
def initialize( main_window )
|
19
19
|
super( main_window )
|
20
|
-
|
20
|
+
|
21
21
|
# do menus and widgets
|
22
22
|
@layout = Ui::Browser.new
|
23
23
|
@layout.setup_ui( main_window )
|
24
|
-
|
24
|
+
|
25
25
|
# set icon. MUST come after call to setup_ui
|
26
26
|
icon_path = Pathname.new( __FILE__ ).parent + "../icons/icon.png"
|
27
27
|
Kernel::raise "icon.png not found" unless icon_path.file?
|
28
28
|
main_window.window_icon = Qt::Icon.new( icon_path.realpath.to_s )
|
29
|
-
|
29
|
+
|
30
30
|
# add the tables tab
|
31
31
|
@tables_tab = Qt::TabWidget.new( @layout.main_widget )
|
32
32
|
@layout.main_widget.layout.add_widget @tables_tab
|
33
33
|
@tables_tab.tab_bar.focus_policy = Qt::NoFocus
|
34
|
-
|
34
|
+
|
35
35
|
# hide the file menu, for now
|
36
36
|
@layout.menubar.remove_action( @layout.menu_file.menu_action )
|
37
|
-
|
37
|
+
|
38
38
|
# tab navigation
|
39
39
|
@layout.action_next.connect SIGNAL( 'triggered()' ), &method( :next_tab )
|
40
40
|
@layout.action_previous.connect SIGNAL( 'triggered()' ), &method( :previous_tab )
|
@@ -42,51 +42,51 @@ class Browser < Qt::Widget
|
|
42
42
|
# dump model for current tab
|
43
43
|
@layout.action_dump.visible = $options[:debug]
|
44
44
|
@layout.action_dump.connect SIGNAL( 'triggered()' ), &method( :dump )
|
45
|
-
|
45
|
+
|
46
46
|
tables_tab.connect SIGNAL( 'currentChanged(int)' ), &method( :current_changed )
|
47
|
-
|
47
|
+
|
48
48
|
load_views
|
49
49
|
update_menus
|
50
50
|
main_window.window_title = [database_name, 'Clevic'].compact.join ' '
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# Set the main window title to the name of the database, if we can find it.
|
54
54
|
def database_name
|
55
55
|
table_view.model.entity_class.db.url rescue ''
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
def update_menus
|
59
59
|
# update edit menu
|
60
60
|
@layout.menu_edit.clear
|
61
|
-
|
61
|
+
|
62
62
|
# do the model-specific menu items first
|
63
63
|
table_view.model_actions.each do |action|
|
64
64
|
@layout.menu_edit.add_action( action )
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
# now do the generic edit items
|
68
68
|
table_view.edit_actions.each do |action|
|
69
69
|
@layout.menu_edit.add_action( action )
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
# update search menu
|
73
73
|
@layout.menu_search.clear
|
74
74
|
table_view.search_actions.each do |action|
|
75
75
|
@layout.menu_search.add_action( action )
|
76
76
|
end
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
# activated by Ctrl-Shift-D for debugging
|
80
80
|
def dump
|
81
81
|
puts "table_view.model: #{table_view.model.inspect}"
|
82
82
|
puts "table_view.model.entity_class: #{table_view.model.entity_class.inspect}"
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
# return the Clevic::TableView object in the currently displayed tab
|
86
86
|
def table_view
|
87
87
|
tables_tab.current_widget
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
# slot to handle Ctrl-Tab and move to next tab, or wrap around
|
91
91
|
def next_tab
|
92
92
|
tables_tab.current_index =
|
@@ -106,14 +106,14 @@ class Browser < Qt::Widget
|
|
106
106
|
tables_tab.current_index - 1
|
107
107
|
end
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
# slot to handle the currentChanged signal from tables_tab, and
|
111
111
|
# set focus on the grid
|
112
112
|
def current_changed( current_tab_index )
|
113
113
|
update_menus
|
114
114
|
tables_tab.current_widget.set_focus
|
115
115
|
end
|
116
|
-
|
116
|
+
|
117
117
|
# shortcut for the Qt translate call
|
118
118
|
def translate( st )
|
119
119
|
Qt::Application.translate("Browser", st, nil, Qt::Application::UnicodeUTF8)
|
@@ -124,26 +124,26 @@ class Browser < Qt::Widget
|
|
124
124
|
def load_views
|
125
125
|
views = Clevic::View.order.uniq
|
126
126
|
Kernel.raise "no views to display" if views.empty?
|
127
|
-
|
127
|
+
|
128
128
|
# Add all existing model objects as tabs, one each
|
129
129
|
views.each do |view_class|
|
130
130
|
begin
|
131
131
|
view = view_class.new
|
132
|
-
|
132
|
+
|
133
133
|
# This will raise an exception if we can't talk to the
|
134
134
|
# table. Returns nil if there is an empty table, which is
|
135
135
|
# also fine.
|
136
136
|
view.entity_class.first
|
137
|
-
|
137
|
+
|
138
138
|
# create the the table_view and the table_model for the entity_class
|
139
139
|
tab = Clevic::TableView.new( view )
|
140
|
-
|
140
|
+
|
141
141
|
# show status messages
|
142
142
|
tab.connect( SIGNAL( 'status_text_signal(QString)' ) ) { |msg| @layout.statusbar.show_message( msg, 10000 ) }
|
143
|
-
|
143
|
+
|
144
144
|
# add a new tab
|
145
145
|
tables_tab.add_tab( tab, translate( tab.title ) )
|
146
|
-
|
146
|
+
|
147
147
|
# add the table to the Table menu
|
148
148
|
action = Qt::Action.new( @layout.menu_model )
|
149
149
|
action.text = translate( tab.title )
|
@@ -151,7 +151,7 @@ class Browser < Qt::Widget
|
|
151
151
|
tables_tab.current_widget = tab
|
152
152
|
end
|
153
153
|
@layout.menu_model.add_action( action )
|
154
|
-
|
154
|
+
|
155
155
|
# handle filter status changed, so we can provide a visual indication
|
156
156
|
tab.connect SIGNAL( 'filter_status_signal(bool)' ) do |status|
|
157
157
|
# update the tab, so there's a visual indication of filtering
|
@@ -166,12 +166,12 @@ class Browser < Qt::Widget
|
|
166
166
|
end
|
167
167
|
end
|
168
168
|
end
|
169
|
-
|
169
|
+
|
170
170
|
# make sure all outstanding records are saved
|
171
171
|
def save_all
|
172
172
|
tables_tab.tabs.each {|x| x.save_row( x.current_index ) }
|
173
173
|
end
|
174
|
-
|
174
|
+
|
175
175
|
def self.run( args )
|
176
176
|
# load model files
|
177
177
|
raise "no model definition file specified" if args.empty?
|
data/lib/clevic/qt/clipboard.rb
CHANGED
@@ -7,23 +7,23 @@ module Clevic
|
|
7
7
|
def system
|
8
8
|
Qt::Application::clipboard
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def text=( value )
|
12
12
|
system.text = value
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def text
|
16
16
|
system.text
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def text?
|
20
20
|
system.mime_data.has_text
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def html?
|
24
24
|
system.mime_data.has_html
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
# TODO figure out why Qt never has anything other than text.
|
28
28
|
# Could be because the event loop isn't running when testing
|
29
29
|
# from irb.
|
@@ -19,7 +19,7 @@ class ComboDelegate < Clevic::Delegate
|
|
19
19
|
end
|
20
20
|
hs
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def dump_editor_state( editor )
|
24
24
|
if $options[:debug]
|
25
25
|
puts "#{self.class.name}"
|
@@ -33,23 +33,23 @@ class ComboDelegate < Clevic::Delegate
|
|
33
33
|
puts
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
# open the combo box, just like if f4 was pressed
|
38
38
|
def full_edit
|
39
39
|
editor.show_popup if is_combo?( editor )
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def is_combo?( editor )
|
43
43
|
editor.is_a?( Qt::ComboBox )
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
def create_combo_box( *args )
|
47
47
|
Qt::ComboBox.new( parent ).tap do |combo|
|
48
48
|
# all combos are editable so that prefix matching will work
|
49
49
|
combo.editable = true
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# Override the Qt method. Create a ComboBox widget and fill it with the possible values.
|
54
54
|
def createEditor( parent_widget, style_option_view_item, model_index )
|
55
55
|
self.parent = parent_widget
|
@@ -62,7 +62,7 @@ class ComboDelegate < Clevic::Delegate
|
|
62
62
|
def line_editor( edit_value )
|
63
63
|
@line_editor ||= Qt::LineEdit.new( edit_value, parent )
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def framework_setup( *args )
|
67
67
|
# don't need to do anything here
|
68
68
|
# might need to once prefix-matching is implemented
|
@@ -71,7 +71,7 @@ class ComboDelegate < Clevic::Delegate
|
|
71
71
|
# Override the Qt::ItemDelegate method.
|
72
72
|
def updateEditorGeometry( editor, style_option_view_item, model_index )
|
73
73
|
rect = style_option_view_item.rect
|
74
|
-
|
74
|
+
|
75
75
|
# ask the editor for how much space it wants, and set the editor
|
76
76
|
# to that size when it displays in the table
|
77
77
|
rect.set_width( [editor.size_hint.width,rect.width].max ) if is_combo?( editor )
|
@@ -87,19 +87,19 @@ class ComboDelegate < Clevic::Delegate
|
|
87
87
|
editor.text = model_index.edit_value
|
88
88
|
end
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
# This translates the text from the editor into something that is
|
92
92
|
# stored in an underlying model. Intended to be overridden by subclasses.
|
93
93
|
def translate_from_editor_text( editor, text )
|
94
94
|
index = editor.find_text( text )
|
95
|
-
|
95
|
+
|
96
96
|
if index == -1
|
97
97
|
text unless restricted?
|
98
98
|
else
|
99
99
|
editor.item_data( index ).value
|
100
100
|
end
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
# Send the data from the editor to the model. The data will
|
104
104
|
# be translated by translate_from_editor_text,
|
105
105
|
def setModelData( editor, abstract_item_model, model_index )
|
@@ -116,11 +116,11 @@ class ComboDelegate < Clevic::Delegate
|
|
116
116
|
# there is a matching completion, so use it
|
117
117
|
editor.completer.current_completion
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
if value != nil
|
121
121
|
model_index.attribute_value = translate_from_editor_text( editor, value )
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
else
|
125
125
|
model_index.attribute_value = editor.text
|
126
126
|
end
|
data/lib/clevic/qt/extensions.rb
CHANGED
@@ -7,7 +7,7 @@ require 'clevic/qt/accept_reject'
|
|
7
7
|
# convenience methods
|
8
8
|
module Qt
|
9
9
|
PasteRole = UserRole + 1 unless defined?( PasteRole )
|
10
|
-
|
10
|
+
|
11
11
|
class AbstractItemDelegate
|
12
12
|
# overridden in EntryDelegate subclasses
|
13
13
|
def full_edit
|
@@ -26,7 +26,7 @@ module Qt
|
|
26
26
|
class ModelIndex
|
27
27
|
include Clevic::TableIndex
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
class ItemSelectionModel
|
31
31
|
# return an array of integer indexes for currently selected rows
|
32
32
|
def row_indexes
|
@@ -40,12 +40,12 @@ module Qt
|
|
40
40
|
def ranges
|
41
41
|
selection
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def single_cell?
|
45
45
|
ranges.size == 1 && ranges.first.single_cell?
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
# implement accepted? and rejected? for TableView#confirm_dialog and friends
|
50
50
|
class MessageBox
|
51
51
|
include Clevic::AcceptReject
|