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
@@ -14,11 +14,11 @@ module ActionBuilder
14
14
  collect_actions << action
15
15
  end
16
16
  end
17
-
17
+
18
18
  def create_action( &block )
19
19
  Action.new( self ).tap( &block )
20
20
  end
21
-
21
+
22
22
  # set up the code to be executed when an action is triggered,
23
23
  def action_method_or_block( action, options, &block )
24
24
  # connect the action to some code
@@ -6,18 +6,18 @@ module Clevic
6
6
  def init_component( cell_editor )
7
7
  editor.selected = attribute_value
8
8
  end
9
-
9
+
10
10
  def editor
11
11
  @editor ||= javax.swing.JCheckBox.new.tap do |e|
12
12
  # TODO this is common to all delegates
13
13
  e.horizontal_alignment = field.swing_alignment
14
14
  end
15
15
  end
16
-
16
+
17
17
  def value
18
18
  editor.selected
19
19
  end
20
-
20
+
21
21
  def native
22
22
  java.lang.Boolean
23
23
  end
@@ -10,31 +10,31 @@ in Clevic::View.order. DefaultView classes created by Clevic::Record are include
10
10
  =end
11
11
  class Browser < javax.swing.JFrame
12
12
  attr_reader :menu_edit, :menu_search, :menu_table
13
-
13
+
14
14
  def initialize
15
15
  super
16
-
16
+
17
17
  # set OSX application title
18
18
  java.lang.System.setProperty( "com.apple.mrj.application.apple.menu.about.name", title_string )
19
19
 
20
20
  self.jmenu_bar = menu_bar
21
21
  self.icon_image = icon
22
-
22
+
23
23
  # add the tables tab
24
24
  add( tables_tab, java.awt.BorderLayout::CENTER )
25
-
25
+
26
26
  # add the status bar
27
27
  add( status_bar, java.awt.BorderLayout::SOUTH )
28
-
28
+
29
29
  load_views
30
30
  update_menus
31
31
  self.title = title_string
32
32
  end
33
-
33
+
34
34
  def title_string
35
35
  [database_name, 'Clevic'].compact.join ' '
36
36
  end
37
-
37
+
38
38
  def menu_bar
39
39
  javax.swing.JMenuBar.new.tap do |menu_bar|
40
40
  menu_bar << javax.swing.JMenu.new( 'File' ).tap do |menu|
@@ -42,13 +42,13 @@ class Browser < javax.swing.JFrame
42
42
  menu << "Open"
43
43
  menu << "Close"
44
44
  end
45
-
45
+
46
46
  @menu_edit = javax.swing.JMenu.new( 'Edit' ).tap {|m| m.mnemonic = java.awt.event.KeyEvent::VK_E}
47
47
  menu_bar << menu_edit
48
-
48
+
49
49
  @menu_search = javax.swing.JMenu.new( 'Search' ).tap {|m| m.mnemonic = java.awt.event.KeyEvent::VK_S}
50
50
  menu_bar << menu_search
51
-
51
+
52
52
  @menu_table = javax.swing.JMenu.new( 'Table' ).tap do |menu|
53
53
  menu.mnemonic = java.awt.event.KeyEvent::VK_T
54
54
  menu << Action.new( self ) do |action|
@@ -60,7 +60,7 @@ class Browser < javax.swing.JFrame
60
60
  next_tab
61
61
  end
62
62
  end
63
-
63
+
64
64
  menu << Action.new( self ) do |action|
65
65
  action.name = :previous_tab
66
66
  action.text = "&Previous"
@@ -70,7 +70,7 @@ class Browser < javax.swing.JFrame
70
70
  previous_tab
71
71
  end
72
72
  end
73
-
73
+
74
74
  if $options[:debug]
75
75
  menu << Action.new( self ) do |action|
76
76
  action.name = :dump
@@ -85,7 +85,7 @@ class Browser < javax.swing.JFrame
85
85
  menu_bar << @menu_table
86
86
  end
87
87
  end
88
-
88
+
89
89
  def icon
90
90
  @icon ||=
91
91
  begin
@@ -94,12 +94,12 @@ class Browser < javax.swing.JFrame
94
94
  javax.swing.ImageIcon.new( icon_path.realpath.to_s ).image
95
95
  end
96
96
  end
97
-
97
+
98
98
  def tables_tab
99
99
  @tables_tab ||= javax.swing.JTabbedPane.new.tap do |tables_tab|
100
100
  # tell tab to not take focus
101
101
  tables_tab.focusable = false
102
-
102
+
103
103
  # tab navigation
104
104
  tables_tab.add_change_listener do |change_event|
105
105
  current_changed
@@ -107,7 +107,7 @@ class Browser < javax.swing.JFrame
107
107
  end
108
108
  end
109
109
  end
110
-
110
+
111
111
  def status_bar
112
112
  @status_bar ||= javax.swing.JLabel.new.tap do |status_bar|
113
113
  status_bar.horizontal_alignment = javax.swing.SwingConstants::RIGHT
@@ -115,7 +115,7 @@ class Browser < javax.swing.JFrame
115
115
  status_bar.text = "Welcome to Clevic"
116
116
  end
117
117
  end
118
-
118
+
119
119
  def status_bar_timer
120
120
  @status_bar_timer ||= javax.swing.Timer.new( 15000, nil ).tap do |timer|
121
121
  timer.repeats = false
@@ -127,46 +127,46 @@ class Browser < javax.swing.JFrame
127
127
  end
128
128
  end
129
129
  end
130
-
130
+
131
131
  # Set the main window title to the name of the database, if we can find it.
132
132
  def database_name
133
133
  table_view.model.entity_class.db.url rescue ''
134
134
  end
135
-
135
+
136
136
  # called by current_changed to update the Edit menu to the menus
137
137
  # defined by the currently selected view
138
138
  def update_menus
139
139
  # update edit menu
140
140
  menu_edit.remove_all
141
-
141
+
142
142
  # do the model-specific menu items first
143
143
  table_view.model_actions.each do |action|
144
144
  menu_edit << action
145
145
  end
146
-
146
+
147
147
  # now do the generic edit items
148
148
  table_view.edit_actions.each do |action|
149
149
  menu_edit << action
150
150
  end
151
-
151
+
152
152
  # update search menu
153
153
  menu_search.remove_all
154
154
  table_view.search_actions.each do |action|
155
155
  menu_search << action
156
156
  end
157
157
  end
158
-
158
+
159
159
  # activated by Ctrl-Shift-D for debugging
160
160
  def dump
161
161
  puts "table_view.model: #{table_view.model.inspect}"
162
162
  puts "table_view.model.entity_class: #{table_view.model.entity_class.inspect}"
163
163
  end
164
-
164
+
165
165
  # return the Clevic::TableView object in the currently displayed tab
166
166
  def table_view
167
167
  tables_tab.selected_component
168
168
  end
169
-
169
+
170
170
  # slot to handle Ctrl-Tab and move to next tab, or wrap around
171
171
  def next_tab
172
172
  tables_tab.selected_index =
@@ -186,20 +186,20 @@ class Browser < javax.swing.JFrame
186
186
  tables_tab.selected_index - 1
187
187
  end
188
188
  end
189
-
189
+
190
190
  # slot to handle the currentChanged signal from tables_tab, and
191
191
  # set focus on the grid
192
192
  def current_changed
193
193
  update_menus
194
194
  table_view.request_focus
195
195
  end
196
-
196
+
197
197
  # Create the tabs, each with a collection for a particular entity class.
198
198
  # views come from Clevic::View.order
199
199
  def load_views
200
200
  views = Clevic::View.views
201
201
  Kernel.raise "no views to display" if views.empty?
202
-
202
+
203
203
  # Add all existing model objects as tabs, one each
204
204
  views.each do |view_class|
205
205
  begin
@@ -208,13 +208,13 @@ class Browser < javax.swing.JFrame
208
208
  puts "Browser::load_views: No table for #{view.entity_class.inspect}"
209
209
  next
210
210
  end
211
-
211
+
212
212
  # create the the table_view and the table_model for the entity_class
213
213
  tab = Clevic::TableView.new( view )
214
-
214
+
215
215
  # add a new tab
216
216
  tables_tab.add( tab.title, tab )
217
-
217
+
218
218
  # add the table to the Table menu
219
219
  menu_table << Action.new( self ) do |action|
220
220
  action.text = tab.title
@@ -222,7 +222,7 @@ class Browser < javax.swing.JFrame
222
222
  tables_tab.current = tab
223
223
  end
224
224
  end
225
-
225
+
226
226
  init_connections( tab )
227
227
  rescue Exception => e
228
228
  puts "UI from #{view} will not be available: #{e.message}"
@@ -230,14 +230,14 @@ class Browser < javax.swing.JFrame
230
230
  end
231
231
  end
232
232
  end
233
-
233
+
234
234
  def init_connections( tab )
235
235
  tab.emit_status_text do |msg|
236
236
  status_bar.text = msg
237
237
  # hide the message after a while.
238
238
  status_bar_timer.start
239
239
  end
240
-
240
+
241
241
  # handle filter status changed, so we can provide a visual indication
242
242
  tab.emit_filter_status do |status|
243
243
  # update the tab, so there's a visual indication of filtering
@@ -246,12 +246,12 @@ class Browser < javax.swing.JFrame
246
246
  tables_tab.set_tool_tip_text_at( tables_tab.selected_index, tab.filter_message )
247
247
  end
248
248
  end
249
-
249
+
250
250
  # make sure all outstanding records are saved
251
251
  def save_all
252
252
  tables_tab.each {|x| x.save_row( x.current_index ) }
253
253
  end
254
-
254
+
255
255
  def self.run( args )
256
256
  # make it more appley
257
257
  java.lang.System.setProperty( "apple.laf.useScreenMenuBar", "true" )
@@ -261,7 +261,7 @@ class Browser < javax.swing.JFrame
261
261
  args.each do |arg|
262
262
  load_models( Pathname.new( arg ) )
263
263
  end
264
-
264
+
265
265
  # make top-level UI
266
266
  browser = Browser.new
267
267
  browser.default_close_operation = javax.swing.JFrame::EXIT_ON_CLOSE
@@ -7,20 +7,20 @@ module Clevic
7
7
  # when the editing starts
8
8
  class CellEditor < javax.swing.JComponent
9
9
  include javax.swing.table.TableCellEditor
10
-
10
+
11
11
  def initialize( table_view )
12
12
  super()
13
13
  @table_view = table_view
14
14
  @listeners = []
15
15
  end
16
-
16
+
17
17
  attr_accessor :listeners
18
18
  attr_reader :index
19
-
19
+
20
20
  def delegate
21
21
  index.field.delegate
22
22
  end
23
-
23
+
24
24
  # override TableCellEditor methods
25
25
  # basically, initialize a component to send back to the JTable, and store
26
26
  # a bunch of state information
@@ -28,7 +28,7 @@ class CellEditor < javax.swing.JComponent
28
28
  # remember index for later. The delegate and the editor and the value
29
29
  # all come from it.
30
30
  @index = @table_view.model.create_index( row_index, column_index )
31
-
31
+
32
32
  # use the delegate's component. It actually comes from the index, which
33
33
  # is a bit weird. But anyway.
34
34
  delegate.entity = @index.entity
@@ -41,46 +41,46 @@ class CellEditor < javax.swing.JComponent
41
41
  def addCellEditorListener(cell_editor_listener)
42
42
  listeners << cell_editor_listener
43
43
  end
44
-
44
+
45
45
  def change_event
46
46
  @change_event ||= javax.swing.event.ChangeEvent.new( self )
47
47
  end
48
-
48
+
49
49
  # Tells the editor to cancel editing and not accept any partially edited value.
50
50
  def cancelCellEditing
51
51
  listeners.each do |listener|
52
52
  listener.editingCancelled( change_event )
53
53
  end
54
54
  end
55
-
55
+
56
56
  # Returns the value contained in the editor.
57
57
  def getCellEditorValue
58
58
  delegate.value
59
59
  end
60
-
60
+
61
61
  # Asks the editor if it can start editing using anEvent.
62
62
  def isCellEditable(event_object)
63
63
  true
64
64
  end
65
-
65
+
66
66
  # Removes a listener from the list that's notified
67
67
  def removeCellEditorListener(cell_editor_listener)
68
68
  listeners.delete cell_editor_listener
69
69
  end
70
-
70
+
71
71
  # Docs say not used, as of Java-1.2. But it is used. Not sure
72
72
  # what to do with it, really.
73
73
  def shouldSelectCell(event_object)
74
74
  true
75
75
  end
76
-
76
+
77
77
  # Tells the editor to stop editing and accept any partially edited value as the value of the editor
78
78
  # true if editing was stopped, false otherwise
79
79
  def stopCellEditing
80
80
  listeners.each do |listener|
81
81
  listener.editingStopped( change_event )
82
82
  end
83
-
83
+
84
84
  # can return false here if editing should not stop
85
85
  # for some reason, ie validation didn't succeed
86
86
  true
@@ -5,33 +5,33 @@ class CellRenderer < javax.swing.table.DefaultTableCellRenderer
5
5
  super()
6
6
  @table_view = table_view
7
7
  end
8
-
8
+
9
9
  def getTableCellRendererComponent( table, value, selected, has_focus, row_index, column_index )
10
10
  index = table.model.create_index( row_index, column_index )
11
11
  component = super( table, index.display_value, selected, has_focus, row_index, column_index )
12
-
12
+
13
13
  # set alignment
14
14
  component.horizontal_alignment = index.field.swing_alignment
15
-
15
+
16
16
  # set text colour
17
17
  component.foreground =
18
18
  case
19
19
  # read-only
20
20
  when index.field.read_only? || index.entity.andand.readonly? || @table_view.model.read_only?
21
21
  java.awt.Color.lightGray
22
-
22
+
23
23
  # errors
24
24
  when index.entity.errors.has_key?( index.field.id )
25
25
  java.awt.Color.red
26
-
26
+
27
27
  # whatever the view says
28
28
  else
29
29
  index.field.foreground_for( index.entity )
30
30
  end
31
-
31
+
32
32
  # set tooltip
33
33
  component.tool_tip_text = index.tooltip
34
-
34
+
35
35
  component
36
36
  rescue
37
37
  puts $!.backtrace
@@ -7,7 +7,7 @@ module Java
7
7
  def inspect
8
8
  "#<DataFlavor #{mime_type}>"
9
9
  end
10
-
10
+
11
11
  def simple_type
12
12
  mime_type.split('; ').first
13
13
  end
@@ -29,7 +29,7 @@ module Clevic
29
29
  def unbuffered_read( length )
30
30
  nex = @input_stream.read
31
31
  raise EOFError if nex == -1
32
-
32
+
33
33
  begin
34
34
  (0...length).inject([nex]) do |buf,i|
35
35
  nex = @input_stream.read
@@ -44,7 +44,7 @@ module Clevic
44
44
  end
45
45
  end
46
46
  end
47
-
47
+
48
48
  # Wrapper for framework-specigfic clipboard code. Used by TableView.
49
49
  #
50
50
  # could also use a javax.activation.DataHandler
@@ -57,42 +57,42 @@ module Clevic
57
57
  def system
58
58
  @system ||= java.awt.Toolkit.default_toolkit.system_clipboard
59
59
  end
60
-
60
+
61
61
  def flavours
62
62
  system.available_data_flavors.to_a
63
63
  end
64
-
64
+
65
65
  def text?
66
66
  mime_types.include?( 'text/plain' )
67
67
  end
68
-
68
+
69
69
  def text; contents('text/plain'); end
70
-
70
+
71
71
  def text=( value )
72
72
  transferable = java.awt.datatransfer.StringSelection.new( value )
73
73
  system.setContents( transferable, transferable )
74
74
  end
75
-
75
+
76
76
  def html?
77
77
  mime_types.include?( 'text/html' )
78
78
  end
79
-
79
+
80
80
  def html; contents('text/html'); end
81
-
81
+
82
82
  def mime_types
83
83
  flavours.map( &:simple_type ).sort.uniq
84
84
  end
85
-
85
+
86
86
  def full_mime_types
87
87
  flavours.map( &:mime_type )
88
88
  end
89
-
89
+
90
90
  # matcher is either a string or a regex, ie something
91
91
  # that can be passed to Array#grep
92
92
  def has?( matcher )
93
93
  !full_mime_types.grep( matcher ).empty?
94
94
  end
95
-
95
+
96
96
  # try a bunch of encodings for the given mime_type, and give
97
97
  # back a String containing the result
98
98
  def contents( mime_type )
@@ -100,29 +100,29 @@ module Clevic
100
100
  # try UTF-8 first because it seems more robust
101
101
  when has?( %r{#{mime_type}.*String.*utf-8}i )
102
102
  data "#{mime_type}; class=java.lang.String; charset=UTF-8"
103
-
103
+
104
104
  # now string Unicode, just in case
105
105
  when has?( %r{#{mime_type}.*String.*unicode}i )
106
106
  data "#{mime_type}; class=java.lang.String; charset=unicode"
107
-
107
+
108
108
  # This is to handle clevic-clevic pastes
109
109
  when has?( %r{#{mime_type}.*Stream.*unicode}i )
110
110
  stream( "#{mime_type}; class=java.io.InputStream; charset=unicode" ).read
111
-
111
+
112
112
  else
113
113
  raise "Don't know how to get #{mime_type}"
114
114
  end
115
115
  end
116
-
116
+
117
117
  def data( full_mime_type )
118
118
  flavor = java.awt.datatransfer.DataFlavor.new( full_mime_type )
119
119
  system.getData( flavor )
120
120
  end
121
-
121
+
122
122
  def stream( full_mime_type )
123
123
  Stream.new( data( full_mime_type ) )
124
124
  end
125
-
125
+
126
126
  def []( mime_type )
127
127
  contents( mime_type ).unpack('U*').inject([]) do |collect,byte|
128
128
  # ignore BOM