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