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
@@ -19,7 +19,7 @@ module Clevic
19
19
  # TODO make sure Delegates use the correct copy routines.
20
20
  class ClevicTable < javax.swing.JTable
21
21
  attr_accessor :table_view
22
-
22
+
23
23
  def processKeyBinding( key_stroke, key_event, condition, pressed )
24
24
  # don't auto-start if it's a Ctrl, or Alt-modified key
25
25
  # or a function key. Hopefully this doesn't get checked
@@ -28,7 +28,7 @@ class ClevicTable < javax.swing.JTable
28
28
  if key_event.alt? || key_event.ctrl? || key_event.meta? || key_event.fx? || key_event.del? || key_event.esc?
29
29
  put_client_property( "JTable.autoStartsEdit", false )
30
30
  end
31
-
31
+
32
32
  # do what JTable normally does with keys
33
33
  super
34
34
  rescue Exception => e
@@ -42,7 +42,7 @@ class ClevicTable < javax.swing.JTable
42
42
  # override to make things simpler
43
43
  def getCellEditor( row_index, column_index )
44
44
  index = table_view.model.create_index( row_index, column_index )
45
-
45
+
46
46
  # Basically, this is for boolean editing. Number of mouse
47
47
  # clicks and so on is horribly complicated, so just let the
48
48
  # code in javax.swing.whatever handle it.
@@ -79,7 +79,7 @@ class ClevicTable < javax.swing.JTable
79
79
  else
80
80
  true
81
81
  end
82
-
82
+
83
83
  # must call superclass here to do the edit rather than
84
84
  # just returning whether it should be edited. Java. tsk tsk.
85
85
  if edit_ok
@@ -102,69 +102,69 @@ class TableView < javax.swing.JScrollPane
102
102
  def initialize( arg, &block )
103
103
  super( @jtable = ClevicTable.new )
104
104
  @jtable.table_view = self
105
-
105
+
106
106
  # seems like this MUST go after the super call (or maybe the
107
107
  # ClevicTable constructor), otherwise Swing throws an error
108
108
  # somewhere deep inside something. It's not clear right now.
109
-
109
+
110
110
  # This should theoretically close editors when focus is lost
111
111
  # saving whatever values are in there
112
112
  jtable.put_client_property( "terminateEditOnFocusLost", true )
113
-
113
+
114
114
  # cell editors get focus immediately on editor start
115
115
  jtable.surrendersFocusOnKeystroke = true
116
-
116
+
117
117
  # no auto-resizing of columns
118
118
  jtable.auto_resize_mode = javax.swing.JTable::AUTO_RESIZE_OFF
119
-
119
+
120
120
  # selection of all kinds allowed
121
121
  jtable.selection_mode = javax.swing.ListSelectionModel::MULTIPLE_INTERVAL_SELECTION
122
122
  jtable.row_selection_allowed = true
123
123
  jtable.column_selection_allowed = true
124
124
  jtable.cell_selection_enabled = true
125
-
125
+
126
126
  # appearance
127
127
  jtable.font = Clevic.tahoma
128
128
  self.font = Clevic.tahoma
129
-
129
+
130
130
  # make sure grid shows, even on mac
131
131
  jtable.show_grid = true
132
132
  # because OSX sets this to the same color as the foreground. Duh.
133
133
  jtable.grid_color = java.awt.SystemColor.controlHighlight
134
-
134
+
135
135
  jtable.setDefaultRenderer( java.lang.Object, CellRenderer.new( self ) )
136
-
136
+
137
137
  fix_input_map
138
-
138
+
139
139
  framework_init( arg, &block )
140
-
140
+
141
141
  # this must go after framework_init, because it needs the actions
142
142
  # which are set up in there
143
143
  jtable.component_popup_menu = popup_menu
144
-
144
+
145
145
  # add the row header
146
146
  RowHeader.new( self )
147
-
147
+
148
148
  # make sure focus goes to the right place
149
149
  self.focus_traversal_policy = TableViewFocus.new( self )
150
150
  end
151
-
151
+
152
152
  class EmptyAction < javax.swing.AbstractAction
153
153
  def actionPerformed( action_event ); end
154
154
  end
155
-
155
+
156
156
  def empty_action
157
157
  @empty_action ||= EmptyAction.new
158
158
  end
159
-
159
+
160
160
  def add_map( key_string, action = empty_action )
161
161
  map.put( javax.swing.KeyStroke.getKeyStroke( key_string ), action )
162
162
  end
163
-
163
+
164
164
  def map
165
165
  @map ||= jtable.getInputMap( javax.swing.JComponent::WHEN_ANCESTOR_OF_FOCUSED_COMPONENT )
166
166
  end
167
-
167
+
168
168
  # This puts empty actions in the local keyboard map so that the
169
169
  # generic keyboard map doesn't catch them and prevent our menu actions
170
170
  # from being triggered
@@ -176,40 +176,40 @@ class TableView < javax.swing.JScrollPane
176
176
  add_map 'ctrl pressed X'
177
177
  add_map 'pressed DEL'
178
178
  end
179
-
179
+
180
180
  def popup_menu
181
181
  @popup_menu ||= javax.swing.JPopupMenu.new.tap do |menu|
182
182
  model_actions.each do |action|
183
183
  menu << action.clone.tap{|a| a.shortcut = nil}
184
184
  end
185
-
185
+
186
186
  # now do the generic edit items
187
187
  edit_actions.each do |action|
188
188
  menu << action.clone.tap{|a| a.shortcut = nil}
189
189
  end
190
-
190
+
191
191
  menu.pack
192
192
  end
193
193
  end
194
-
194
+
195
195
  attr_reader :jtable
196
-
196
+
197
197
  def connect_view_signals( entity_view )
198
198
  # pick up model changes and pass them to the Clevic::View object
199
199
  model.addTableModelListener do |table_model_event|
200
200
  begin
201
201
  # pass changed events to view definitions
202
202
  return unless table_model_event.updated?
203
-
203
+
204
204
  # unlikely to be useful to models, and in fact causes a very very long
205
205
  # calculation. So don't pass it on.
206
206
  return if table_model_event.all_rows?
207
-
207
+
208
208
  top_left = model.create_index( table_model_event.first_row, table_model_event.column )
209
209
  bottom_right = model.create_index( table_model_event.last_row, table_model_event.column )
210
-
210
+
211
211
  entity_view.notify_data_changed( self, top_left, bottom_right )
212
-
212
+
213
213
  to_next_index
214
214
  rescue Exception => e
215
215
  show_error e.message
@@ -217,13 +217,13 @@ class TableView < javax.swing.JScrollPane
217
217
  end
218
218
  end
219
219
  end
220
-
220
+
221
221
  # kind-of override of requestFocus, but it will probably only
222
222
  # work from Ruby
223
223
  def request_focus
224
224
  @jtable.request_focus
225
225
  end
226
-
226
+
227
227
  # return a collection of collections of SwingTableIndex objects
228
228
  # indicating the indices of the current selection
229
229
  def selected_rows
@@ -233,18 +233,18 @@ class TableView < javax.swing.JScrollPane
233
233
  end
234
234
  end
235
235
  end
236
-
236
+
237
237
  # called from the framework-independent part to edit a cell
238
238
  def edit( table_index )
239
239
  # TODO keyboard focus doesn't seem to be reassigned to combo
240
240
  # when editing is started this way.
241
241
  @jtable.editCellAt( table_index.row, table_index.column )
242
242
  end
243
-
243
+
244
244
  def status_text_listeners
245
245
  @status_text_listeners ||= Set.new
246
246
  end
247
-
247
+
248
248
  # If msg is provided, yield to stored block.
249
249
  # If block is provided, store it for later.
250
250
  def emit_status_text( msg = nil, &notifier_block )
@@ -256,11 +256,11 @@ class TableView < javax.swing.JScrollPane
256
256
  end
257
257
  end
258
258
  end
259
-
259
+
260
260
  def filter_status_listeners
261
261
  @filter_status_listeners ||= Set.new
262
262
  end
263
-
263
+
264
264
  # emit whether the view is filtered or not
265
265
  def emit_filter_status( bool = nil, &notifier_block )
266
266
  if block_given?
@@ -271,7 +271,7 @@ class TableView < javax.swing.JScrollPane
271
271
  end
272
272
  end
273
273
  end
274
-
274
+
275
275
  def confirm_dialog( question, title )
276
276
  cd = ConfirmDialog.new do |dialog|
277
277
  dialog.parent = self
@@ -282,7 +282,7 @@ class TableView < javax.swing.JScrollPane
282
282
  end
283
283
  cd.show
284
284
  end
285
-
285
+
286
286
  # set the size of the column from the sample
287
287
  def auto_size_column( col, sample )
288
288
  @jtable.column_model.column( col ).preferred_width = column_width( col, sample )
@@ -292,7 +292,7 @@ class TableView < javax.swing.JScrollPane
292
292
  def column_width( col, data )
293
293
  @jtable.getFontMetrics( @jtable.font ).stringWidth( data.to_s ) + 5
294
294
  end
295
-
295
+
296
296
  def trim_middle( value, max = 40 )
297
297
  if value && value.length > max
298
298
  "#{value[0..(max/2-2)]}...#{value[-(max/2-2)..-1]}"
@@ -300,7 +300,7 @@ class TableView < javax.swing.JScrollPane
300
300
  value
301
301
  end
302
302
  end
303
-
303
+
304
304
  # forward to @jtable
305
305
  # also handle model#emit_data_error
306
306
  def model=( model )
@@ -312,11 +312,11 @@ class TableView < javax.swing.JScrollPane
312
312
  @jtable.model.emit_data_error( &emitter_block ) if @jtable.model.respond_to? :emit_data_error
313
313
  resize_columns
314
314
  end
315
-
315
+
316
316
  def model
317
317
  @jtable.model
318
318
  end
319
-
319
+
320
320
  def show_error( msg, title = "Error" )
321
321
  @pane ||= javax.swing.JOptionPane.new(
322
322
  '',
@@ -326,38 +326,38 @@ class TableView < javax.swing.JScrollPane
326
326
  @pane.message = msg
327
327
  @pane.create_dialog( self, title ).show
328
328
  end
329
-
329
+
330
330
  def selection_model
331
331
  SelectionModel.new( self )
332
332
  end
333
-
333
+
334
334
  # move the cursor & selection to the specified table_index
335
335
  def current_index=( table_index )
336
336
  @jtable.selection_model.clear_selection
337
337
  @jtable.setColumnSelectionInterval( table_index.column, table_index.column )
338
338
  @jtable.setRowSelectionInterval( table_index.row, table_index.row )
339
-
339
+
340
340
  # x position. Should be sum of widths of all columns up to the beginning of this one
341
341
  # ie not including this one, hence the -1
342
342
  xpos = (0..table_index.column-1).inject(0) do |sum,column_index|
343
343
  sum + @jtable.column_model.getColumn( column_index ).width
344
344
  end
345
-
345
+
346
346
  rect = java.awt.Rectangle.new(
347
347
  xpos,
348
-
348
+
349
349
  # y position
350
350
  @jtable.row_height * table_index.row,
351
-
351
+
352
352
  # width of this column
353
353
  @jtable.column_model.getColumn( table_index.column ).width,
354
-
354
+
355
355
  # height
356
356
  @jtable.row_height
357
357
  )
358
358
  @jtable.scrollRectToVisible( rect )
359
359
  end
360
-
360
+
361
361
  # return a SwingTableIndex for the current cursor position
362
362
  # TODO optimise so we don't keep creating a new index, only if a selection
363
363
  # changed event has occurred
@@ -368,7 +368,7 @@ class TableView < javax.swing.JScrollPane
368
368
  def wait_cursor
369
369
  @wait_cursor ||= java.awt.Cursor.new( java.awt.Cursor::WAIT_CURSOR )
370
370
  end
371
-
371
+
372
372
  # show a busy cursor, do the block, back to normal cursor
373
373
  # return value of block
374
374
  def busy_cursor( &block )
@@ -379,7 +379,7 @@ class TableView < javax.swing.JScrollPane
379
379
  self.cursor = save_cursor
380
380
  rv
381
381
  end
382
-
382
+
383
383
  # collect actions for the popup menu
384
384
  def add_action( action )
385
385
  ( @context_actions ||= [] ) << action
@@ -6,7 +6,7 @@ module Clevic
6
6
  @table_view = table_view
7
7
  @table_view.focus_cycle_root = true
8
8
  end
9
-
9
+
10
10
  # Returns the Component that should receive the focus after aComponent.
11
11
  # def getComponentAfter(Container aContainer, Component aComponent)
12
12
  def getComponentAfter(container, component)
@@ -30,18 +30,18 @@ module Clevic
30
30
  def getFirstComponent(container)
31
31
  @table_view.jtable
32
32
  end
33
-
33
+
34
34
  # Returns the Component that should receive the focus when a Window is made visible for the first time.
35
35
  # Component getInitialComponent(Window window)
36
36
  def getInitialComponent(window)
37
37
  @table_view.jtable
38
38
  end
39
-
39
+
40
40
  # Returns the last Component in the traversal cycle.
41
41
  # def getLastComponent(Container aContainer)
42
42
  def getLastComponent(container)
43
43
  @table_view.jtable
44
44
  end
45
45
  end
46
-
46
+
47
47
  end
@@ -13,33 +13,33 @@ class TagDelegate < Delegate
13
13
  # This should be a collection of entities from the related table
14
14
  @items = attribute_value
15
15
  end
16
-
16
+
17
17
  # Return the GUI component / widget that is displayed when editing.
18
18
  # Usually this will be a combo box widget, but it can be a text editor
19
19
  # in some cases.
20
20
  attr_reader :editor
21
-
21
+
22
22
  # the cell must be selected before the edit can be clicked
23
23
  def needs_pre_selection?
24
24
  true
25
25
  end
26
-
26
+
27
27
  # Return a string to be shown to the user.
28
28
  # model_value is an item stored in the combo box model.
29
29
  def display_for( model_value )
30
30
  field.transform_attribute( model_value )
31
31
  end
32
-
32
+
33
33
  def line_editor( value = nil )
34
34
  @line_editor ||= javax.swing.JTextField.new( value ).tap do |line|
35
35
  line.font = Clevic.tahoma
36
36
  end
37
37
  end
38
-
38
+
39
39
  def editor
40
40
  line_editor
41
41
  end
42
-
42
+
43
43
  # Recreate the model and fill it with anything in population that
44
44
  # matches the prefix first, followed by anything in the population that
45
45
  # doesn't match the prefix.
@@ -52,7 +52,7 @@ class TagDelegate < Delegate
52
52
  # save text and popup
53
53
  save_item = editor.editor.item
54
54
  dropdown_visible = editor.popup_visible?
55
-
55
+
56
56
  # repopulate based on the prefix
57
57
  prefix ||= editor.editor.item
58
58
  editor.model = editor.model.class.new
@@ -60,13 +60,13 @@ class TagDelegate < Delegate
60
60
  matching, non_matching = population.partition{ |item| display_for( item ) =~ /^#{prefix}/i }
61
61
  matching.each {|item| editor << item}
62
62
  non_matching.each {|item| editor << item}
63
-
63
+
64
64
  # restore text and popup
65
65
  editor.editor.item = text || save_item
66
66
  editor.popup_visible = dropdown_visible
67
67
  end
68
68
  end
69
-
69
+
70
70
  # make sure we don't react to document change events
71
71
  # while we're doing autocompletion. Reentrant
72
72
  def autocomplete( &block )
@@ -75,7 +75,7 @@ class TagDelegate < Delegate
75
75
  ensure
76
76
  @autocompleting = false
77
77
  end
78
-
78
+
79
79
  # http://www.drdobbs.com/184404457 for autocompletion steps
80
80
  def filter_prefix( prefix )
81
81
  # search for matching item in the UI display_for for the items in the combo model
@@ -86,7 +86,7 @@ class TagDelegate < Delegate
86
86
  autocomplete do
87
87
  # set the shortlist, and the text editor value
88
88
  repopulate prefix, candidate
89
-
89
+
90
90
  # set the suggestion selection
91
91
  editor.editor.editor_component.with do |text_edit|
92
92
  # highlight the suggested match, and leave caret
@@ -98,7 +98,7 @@ class TagDelegate < Delegate
98
98
  end
99
99
  end
100
100
  end
101
-
101
+
102
102
  # open the combo box, just like if F4 was pressed
103
103
  # big trouble here with JComboBox firing an comboEdited action
104
104
  # (probably) on focusGained
@@ -112,11 +112,11 @@ class TagDelegate < Delegate
112
112
  editor.show_popup
113
113
  end
114
114
  end
115
-
115
+
116
116
  # open the text editor component
117
117
  #~ def minimal_edit
118
118
  #~ end
119
-
119
+
120
120
  # return an array of related entity objects, to be
121
121
  # passed into the attribute setter
122
122
  def value