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/qt/table_view.rb
CHANGED
@@ -14,31 +14,31 @@ module Clevic
|
|
14
14
|
# TODO not sure if we still need override_next_index and friends
|
15
15
|
class TableView < Qt::TableView
|
16
16
|
include ActionBuilder
|
17
|
-
|
17
|
+
|
18
18
|
# status_text is emitted when this object was to display something in the status bar
|
19
19
|
# filter_status is emitted when the filtering changes. Param is true for filtered, false for not filtered.
|
20
20
|
signals 'status_text_signal(QString)', 'filter_status_signal(bool)'
|
21
|
-
|
21
|
+
|
22
22
|
def emit_filter_status( bool )
|
23
23
|
emit filter_status_signal( bool )
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def emit_status_text( string )
|
27
27
|
emit status_text_signal( string )
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
# arg is:
|
31
31
|
# - an instance of Clevic::View
|
32
32
|
# - an instance of TableModel
|
33
33
|
def initialize( arg, parent = nil, &block )
|
34
34
|
# need the empty block here, otherwise Qt bindings grab &block
|
35
35
|
super( parent ) {}
|
36
|
-
|
36
|
+
|
37
37
|
framework_init( arg, &block )
|
38
|
-
|
38
|
+
|
39
39
|
# see closeEditor
|
40
40
|
@next_index = nil
|
41
|
-
|
41
|
+
|
42
42
|
# set some Qt things
|
43
43
|
self.horizontal_header.movable = false
|
44
44
|
# TODO might be useful to allow movable vertical rows,
|
@@ -46,7 +46,7 @@ class TableView < Qt::TableView
|
|
46
46
|
self.vertical_header.movable = false
|
47
47
|
self.vertical_header.default_alignment = Qt::AlignTop | Qt::AlignRight
|
48
48
|
self.sorting_enabled = false
|
49
|
-
|
49
|
+
|
50
50
|
# set fonts
|
51
51
|
# TODO leave this here, but commented so we can see how to do it
|
52
52
|
# properly later.
|
@@ -54,10 +54,10 @@ class TableView < Qt::TableView
|
|
54
54
|
#~ self.font = fnt
|
55
55
|
#~ self.horizontal_header.font = fnt
|
56
56
|
#~ end
|
57
|
-
|
57
|
+
|
58
58
|
self.context_menu_policy = Qt::ActionsContextMenu
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
def connect_view_signals( entity_view )
|
62
62
|
model.connect SIGNAL( 'dataChanged ( const QModelIndex &, const QModelIndex & )' ) do |top_left, bottom_right|
|
63
63
|
begin
|
@@ -69,7 +69,7 @@ class TableView < Qt::TableView
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
# return a collection of collections of TableIndex objects
|
74
74
|
# indicating the indices of the current selection
|
75
75
|
def selected_rows
|
@@ -83,22 +83,22 @@ class TableView < Qt::TableView
|
|
83
83
|
end
|
84
84
|
rows
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
def status_text( msg )
|
88
88
|
emit status_text( msg )
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
def open_editor
|
92
92
|
edit( current_index )
|
93
93
|
delegate = item_delegate( current_index )
|
94
94
|
delegate.full_edit
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
def itemDelegate( model_index )
|
98
98
|
@pre_delegate_index = model_index
|
99
99
|
super
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
# set the size of the column from the sample
|
103
103
|
def auto_size_column( col, sample )
|
104
104
|
self.set_column_width( col, column_size( col, sample ).width )
|
@@ -107,72 +107,72 @@ class TableView < Qt::TableView
|
|
107
107
|
def metrics
|
108
108
|
@metrics = Qt::FontMetrics.new( font )
|
109
109
|
end
|
110
|
-
|
110
|
+
|
111
111
|
# set the size of the column from the string value of the data
|
112
112
|
# mostly copied from qheaderview.cpp:2301
|
113
113
|
def column_size( col, data )
|
114
114
|
opt = Qt::StyleOptionHeader.new
|
115
|
-
|
115
|
+
|
116
116
|
# fetch font size
|
117
117
|
opt.fontMetrics = metrics
|
118
118
|
opt.rect = opt.fontMetrics.bounding_rect( data.to_s )
|
119
|
-
|
119
|
+
|
120
120
|
# set data
|
121
121
|
opt.text = data.to_s
|
122
|
-
|
122
|
+
|
123
123
|
opt.section =
|
124
124
|
case
|
125
125
|
when col == 0
|
126
126
|
Qt::StyleOptionHeader::Beginning
|
127
|
-
|
127
|
+
|
128
128
|
when col > 0 && col < model.fields.size - 1
|
129
129
|
Qt::StyleOptionHeader::Middle
|
130
|
-
|
130
|
+
|
131
131
|
when col == model.fields.size - 1
|
132
132
|
Qt::StyleOptionHeader::End
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
size = Qt::Size.new( opt.fontMetrics.width( data.to_s ), opt.fontMetrics.height )
|
136
|
-
|
136
|
+
|
137
137
|
# final parameter could be header section
|
138
138
|
style.sizeFromContents( Qt::Style::CT_HeaderSection, opt, size )
|
139
139
|
end
|
140
|
-
|
140
|
+
|
141
141
|
# make sure row size is correct
|
142
142
|
# show error messages for data
|
143
143
|
def setModel( model )
|
144
144
|
# must do this otherwise model gets garbage collected
|
145
145
|
@model = model
|
146
|
-
|
146
|
+
|
147
147
|
# make sure we get nice spacing
|
148
148
|
vertical_header.default_section_size = metrics.height
|
149
149
|
vertical_header.minimum_section_size = metrics.height
|
150
150
|
super
|
151
|
-
|
151
|
+
|
152
152
|
# set delegates
|
153
153
|
model.fields.each_with_index do |field, index|
|
154
154
|
set_item_delegate_for_column( index, field.delegate )
|
155
155
|
end
|
156
|
-
|
156
|
+
|
157
157
|
# data errors
|
158
158
|
model.connect( SIGNAL( 'data_error(QModelIndex, QVariant, QString)' ) ) do |index,variant,msg|
|
159
159
|
show_error( "Incorrect value '#{variant.value}' entered for field [#{index.attribute.to_s}].\nMessage was: #{msg}" )
|
160
160
|
end
|
161
161
|
end
|
162
|
-
|
162
|
+
|
163
163
|
def show_error( msg )
|
164
164
|
error_message = Qt::ErrorMessage.new( self )
|
165
165
|
error_message.show_message( msg )
|
166
166
|
error_message.show
|
167
167
|
end
|
168
|
-
|
168
|
+
|
169
169
|
# and override this because the Qt bindings don't call
|
170
170
|
# setModel otherwise
|
171
171
|
def model=( model )
|
172
172
|
setModel( model )
|
173
173
|
resize_columns
|
174
174
|
end
|
175
|
-
|
175
|
+
|
176
176
|
def moveCursor( cursor_action, modifiers )
|
177
177
|
# TODO use this as a preload indicator
|
178
178
|
super
|
@@ -190,12 +190,12 @@ class TableView < Qt::TableView
|
|
190
190
|
msg.exec
|
191
191
|
msg
|
192
192
|
end
|
193
|
-
|
193
|
+
|
194
194
|
def keyPressEvent( event )
|
195
195
|
handle_key_press( event )
|
196
196
|
super
|
197
197
|
end
|
198
|
-
|
198
|
+
|
199
199
|
def set_model_data( table_index, value )
|
200
200
|
model.setData( table_index, value.to_variant, Qt::PasteRole )
|
201
201
|
end
|
@@ -208,7 +208,7 @@ class TableView < Qt::TableView
|
|
208
208
|
error_message.show_message( msg )
|
209
209
|
error_message.show
|
210
210
|
end
|
211
|
-
|
211
|
+
|
212
212
|
# work around situation where an ItemDelegate is open
|
213
213
|
# when the surrouding tab is changed, but the right events
|
214
214
|
# don't arrive.
|
@@ -217,7 +217,7 @@ class TableView < Qt::TableView
|
|
217
217
|
# super
|
218
218
|
@hiding = true
|
219
219
|
end
|
220
|
-
|
220
|
+
|
221
221
|
# work around situation where an ItemDelegate is open
|
222
222
|
# when the surrouding tab is changed, but the right events
|
223
223
|
# don't arrive.
|
@@ -225,12 +225,12 @@ class TableView < Qt::TableView
|
|
225
225
|
super
|
226
226
|
@hiding = false
|
227
227
|
end
|
228
|
-
|
228
|
+
|
229
229
|
def focusOutEvent( event )
|
230
230
|
super
|
231
231
|
#~ save_current_row
|
232
232
|
end
|
233
|
-
|
233
|
+
|
234
234
|
# this is the only method that is called when an itemDelegate is open
|
235
235
|
# and the tabs are changed.
|
236
236
|
# Work around situation where an ItemDelegate is open
|
@@ -244,7 +244,7 @@ class TableView < Qt::TableView
|
|
244
244
|
puts $!.backtrace
|
245
245
|
show_error "Error saving data from #{editor.inspect}: #{$!.message}"
|
246
246
|
end
|
247
|
-
|
247
|
+
|
248
248
|
# bool QAbstractItemView::edit ( const QModelIndex & index, EditTrigger trigger, QEvent * event )
|
249
249
|
def edit( model_index, trigger = nil, event = nil )
|
250
250
|
self.before_edit_index = model_index
|
@@ -256,11 +256,11 @@ class TableView < Qt::TableView
|
|
256
256
|
else
|
257
257
|
super( model_index, trigger, event )
|
258
258
|
end
|
259
|
-
|
259
|
+
|
260
260
|
rescue Exception => e
|
261
261
|
raise RuntimeError, "#{model.entity_view.class.name}.#{model_index.field.id}: #{e.message}", e.backtrace
|
262
262
|
end
|
263
|
-
|
263
|
+
|
264
264
|
attr_accessor :before_edit_index
|
265
265
|
attr_reader :next_index
|
266
266
|
def next_index=( other_index )
|
@@ -272,14 +272,14 @@ class TableView < Qt::TableView
|
|
272
272
|
end
|
273
273
|
@next_index = other_index
|
274
274
|
end
|
275
|
-
|
275
|
+
|
276
276
|
# set and move to index. Leave index value in next_index
|
277
277
|
# so that it's not overridden later.
|
278
278
|
# TODO All this next_index stuff is becoming a horrible hack.
|
279
279
|
def next_index!( model_index )
|
280
280
|
self.current_index = self.next_index = model_index
|
281
281
|
end
|
282
|
-
|
282
|
+
|
283
283
|
# override to prevent tab pressed from editing next field
|
284
284
|
# also takes into account that override_next_index may have been called
|
285
285
|
def closeEditor( editor, end_edit_hint )
|
@@ -287,22 +287,22 @@ class TableView < Qt::TableView
|
|
287
287
|
puts "end_edit_hint: #{Qt::AbstractItemDelegate.constants.find {|x| Qt::AbstractItemDelegate.const_get(x) == end_edit_hint } }"
|
288
288
|
puts "next_index: #{next_index.inspect}"
|
289
289
|
end
|
290
|
-
|
290
|
+
|
291
291
|
subsequent_index =
|
292
292
|
case end_edit_hint
|
293
293
|
when Qt::AbstractItemDelegate.EditNextItem
|
294
294
|
super( editor, Qt::AbstractItemDelegate.NoHint )
|
295
295
|
before_edit_index.choppy { |i| i.column += 1 }
|
296
|
-
|
296
|
+
|
297
297
|
when Qt::AbstractItemDelegate.EditPreviousItem
|
298
298
|
super( editor, Qt::AbstractItemDelegate.NoHint )
|
299
299
|
before_edit_index.choppy { |i| i.column -= 1 }
|
300
|
-
|
300
|
+
|
301
301
|
else
|
302
302
|
super
|
303
303
|
nil
|
304
304
|
end
|
305
|
-
|
305
|
+
|
306
306
|
unless subsequent_index.nil?
|
307
307
|
puts "subsequent_index: #{subsequent_index.inspect}" if $options[:debug]
|
308
308
|
# TODO all this really does is reset next_index
|
@@ -310,7 +310,7 @@ class TableView < Qt::TableView
|
|
310
310
|
self.before_edit_index = nil
|
311
311
|
end
|
312
312
|
end
|
313
|
-
|
313
|
+
|
314
314
|
# find the TableView instance for the given entity_view
|
315
315
|
# or entity_model. Return nil if no match found.
|
316
316
|
# TODO doesn't really belong here because TableView will not always
|
@@ -322,7 +322,7 @@ class TableView < Qt::TableView
|
|
322
322
|
end
|
323
323
|
end
|
324
324
|
end
|
325
|
-
|
325
|
+
|
326
326
|
# execute the block with the TableView instance
|
327
327
|
# currently handling the entity_model_or_view.
|
328
328
|
# Don't execute the block if nothing is found.
|
@@ -334,7 +334,7 @@ class TableView < Qt::TableView
|
|
334
334
|
tv = find_table_view( entity_model_or_view )
|
335
335
|
yield( tv ) unless tv.nil?
|
336
336
|
end
|
337
|
-
|
337
|
+
|
338
338
|
# make this window visible if it's in a TabWidget
|
339
339
|
# TODO doesn't really belong here because TableView will not always
|
340
340
|
# be in a TabWidget context. Should emit a signal which is a request to raise
|
@@ -3,12 +3,12 @@ require 'clevic/qt/delegate.rb'
|
|
3
3
|
module Clevic
|
4
4
|
|
5
5
|
class TextDelegate < Delegate
|
6
|
-
|
6
|
+
|
7
7
|
# Doesn't do anything useful yet, but I'm leaving
|
8
8
|
# it here so I don't have to change other code.
|
9
9
|
class TextEditor < Qt::PlainTextEdit
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
# this is overridden in Qt::ItemDelegate, but that
|
13
13
|
# always catches the return key. Which we want for text editing.
|
14
14
|
# Instead, we use Ctrl-Enter to save the edited text.
|
@@ -23,7 +23,7 @@ module Clevic
|
|
23
23
|
emit commitData( object )
|
24
24
|
emit closeEditor( object )
|
25
25
|
true
|
26
|
-
|
26
|
+
|
27
27
|
# send an enter or return to the text editor
|
28
28
|
when event.enter? || event.return?
|
29
29
|
object.event( event )
|
@@ -32,12 +32,12 @@ module Clevic
|
|
32
32
|
end
|
33
33
|
retval || super
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
# maybe open in a separate window?
|
37
37
|
def full_edit
|
38
38
|
puts "#{self.class.name} full_edit"
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
# Override the Qt method
|
42
42
|
def createEditor( parent_widget, style_option_view_item, model_index )
|
43
43
|
if false && model_index.edit_value.count("\n") == 0
|
@@ -49,16 +49,16 @@ module Clevic
|
|
49
49
|
end
|
50
50
|
@editor
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# Override the Qt::ItemDelegate method.
|
54
54
|
def updateEditorGeometry( editor, style_option_view_item, model_index )
|
55
55
|
rect = Qt::Rect.new( style_option_view_item.rect.top_left, style_option_view_item.rect.size )
|
56
|
-
|
56
|
+
|
57
57
|
# ask the editor for how much space it wants, and set the editor
|
58
58
|
# to that size when it displays in the table
|
59
59
|
rect.set_width( [editor.size_hint.width,rect.width].max )
|
60
60
|
rect.set_height( editor.size_hint.height )
|
61
|
-
|
61
|
+
|
62
62
|
unless editor.parent.rect.contains( rect )
|
63
63
|
# 46 because TableView returns an incorrect bottom.
|
64
64
|
# And I can't find out how to get the correct value.
|
@@ -71,7 +71,7 @@ module Clevic
|
|
71
71
|
def setEditorData( editor, model_index )
|
72
72
|
editor.plain_text = model_index.edit_value
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
# Send the data from the editor to the model. The data will
|
76
76
|
# be translated by translate_from_editor_text,
|
77
77
|
def setModelData( editor, abstract_item_model, model_index )
|
@@ -20,7 +20,7 @@ def load_rails_models( root, config, models )
|
|
20
20
|
Rails::Initializer.run do |config|
|
21
21
|
config.frameworks -= [ :action_mailer, :action_pack, :active_resource ]
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# load lib/ files for the rails project
|
25
25
|
$: << ( root / 'lib' ).realpath.to_s
|
26
26
|
( root / 'lib' ).children.each do |filename|
|
@@ -33,7 +33,7 @@ def load_rails_models( root, config, models )
|
|
33
33
|
rescue NameError
|
34
34
|
ActiveRecord::Base.send(:include, ActiveRecord::Dirty)
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
# load models
|
38
38
|
models.find do |dir_entry|
|
39
39
|
# don't load directory entries
|
@@ -47,7 +47,7 @@ def load_rails_models( root, config, models )
|
|
47
47
|
puts e.backtrace
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
# include the Clevic::Record module in each descendant of
|
52
52
|
# the entity class so that the default views will be created.
|
53
53
|
subclasses( Clevic.base_entity_class ).each do |model|
|
data/lib/clevic/record.rb
CHANGED
@@ -14,7 +14,7 @@ module Clevic
|
|
14
14
|
def default_view_class_name
|
15
15
|
"::Clevic::Default#{name.gsub('::','')}View"
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def create_view_class
|
19
19
|
# create the default view class
|
20
20
|
# Don't use Class.new because even if you assign
|
@@ -26,31 +26,31 @@ module Clevic
|
|
26
26
|
end
|
27
27
|
EOF
|
28
28
|
eval st, nil, __FILE__, line
|
29
|
-
|
29
|
+
|
30
30
|
# keep track of the order in which views are
|
31
31
|
# defined, so that can be used as the default ordering
|
32
32
|
# of the views.
|
33
33
|
Clevic::View.order << eval( default_view_class_name )
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def default_view_class
|
37
37
|
@default_view_class ||= eval( default_view_class_name )
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
# Need to defer the execution of the view definition block
|
41
41
|
# until related models have been defined.
|
42
42
|
def define_ui( &block )
|
43
43
|
default_view_class.define_ui_block( &block )
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def self.included( base )
|
49
49
|
base.extend( ClassMethods )
|
50
|
-
|
50
|
+
|
51
51
|
# create the default view class
|
52
52
|
base.create_view_class
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
end
|